{-# LANGUAGE PostfixOperators #-}
{-# OPTIONS_HADDOCK hide #-}
-----------------------------------------------------------------------------
-- |
-- Module      :  ForSyDe.Atom.Skel.Vector.Core
-- Copyright   :  (c) George Ungureanu, KTH/ICT/ESY 2016
-- License     :  BSD-style (see the file LICENSE)
-- 
-- Maintainer  :  ugeorge@kth.se
-- Stability   :  experimental
-- Portability :  portable
--
-- The library for the 'Vector' type. Contains the main skeletons.
-----------------------------------------------------------------------------
module ForSyDe.Atom.Skel.Vector.Lib where

import Data.Maybe
import ForSyDe.Atom.Skel as S
import ForSyDe.Atom.Skel.Vector.Core
import ForSyDe.Atom.Utility.Tuple

import Prelude hiding (null, last, init, tail, map, reverse, length, concat, take, drop, filter, takeWhile, iterate, generate)

------- DOCTEST SETUP -------

-- $setup
-- >>> import ForSyDe.Atom.MoC.SY.Core as SY
-- >>> import ForSyDe.Atom.MoC.SY.Lib
-- >>> import ForSyDe.Atom.Skel hiding (farm21)

-------------------------
-- Functional networks --
-------------------------

------- FARM -------

-- | @farm@ is simply the 'Vector' instance of the skeletom @farm@
-- pattern (see 'ForSyDe.Atom.Skel.farm22'). If the function taken
-- as argument is a process, then it creates a farm network of data
-- parallel processes.
--
-- Constructors: @farm[1-4][1-4]@.
--
-- >>> let v1 = vector [1,2,3,4,5]
-- >>> S.farm21 (+) v1 v1
-- <2,4,6,8,10>
-- >>> let s1 = SY.signal [1,2,3,4,5]
-- >>> let v2 = vector [s1,s1,s1]
-- >>> S.farm11 (comb11 (+1)) v2
-- <{2,3,4,5,6},{2,3,4,5,6},{2,3,4,5,6}>
-- >>> S.farm21 (\x -> comb11 (+x)) v1 v2
-- <{2,3,4,5,6},{3,4,5,6,7},{4,5,6,7,8}>
--
-- <<fig/eqs-skel-vector-farm.png>>
--
-- <<fig/skel-vector-func-farm.png>>
-- <<fig/skel-vector-func-farm-net.png>>
farm22 :: (a1 -> a2 -> (b1, b2)) -- ^ function (e.g. process)
       -> Vector a1              -- ^ first input vector
       -> Vector a2              -- ^ second input vector
       -> (Vector b1, Vector b2) -- ^ two output vectors
farm11 :: (a1 -> b1)
       -> Vector a1
       -> Vector b1
farm12 :: (a1 -> (b1, b2))
       -> Vector a1
       -> (Vector b1, Vector b2)
farm13 :: (a1 -> (b1, b2, b3))
       -> Vector a1
       -> (Vector b1, Vector b2, Vector b3)
farm14 :: (a1 -> (b1, b2, b3, b4))
       -> Vector a1
       -> (Vector b1, Vector b2, Vector b3, Vector b4)
farm21 :: (a1 -> a2 -> b1)
       -> Vector a1 -> Vector a2
       -> Vector b1
farm23 :: (a1 -> a2 -> (b1, b2, b3))
       -> Vector a1 -> Vector a2
       -> (Vector b1, Vector b2, Vector b3)
farm24 :: (a1 -> a2 -> (b1, b2, b3, b4))
       -> Vector a1 -> Vector a2
       -> (Vector b1, Vector b2, Vector b3, Vector b4)
farm31 :: (a1 -> a2 -> a3 -> b1)
       -> Vector a1 -> Vector a2 -> Vector a3
       -> Vector b1
farm32 :: (a1 -> a2 -> a3 -> (b1, b2))
       -> Vector a1 -> Vector a2 -> Vector a3
       -> (Vector b1, Vector b2)
farm33 :: (a1 -> a2 -> a3 -> (b1, b2, b3))
       -> Vector a1 -> Vector a2 -> Vector a3
       -> (Vector b1, Vector b2, Vector b3)
farm34 :: (a1 -> a2 -> a3 -> (b1, b2, b3, b4))
       -> Vector a1 -> Vector a2 -> Vector a3
       -> (Vector b1, Vector b2, Vector b3, Vector b4)
farm41 :: (a1 -> a2 -> a3 -> a4 -> b1)
       -> Vector a1 -> Vector a2 -> Vector a3 -> Vector a4
       -> Vector b1
farm42 :: (a1 -> a2 -> a3 -> a4 -> (b1, b2))
       -> Vector a1 -> Vector a2 -> Vector a3 -> Vector a4
       -> (Vector b1, Vector b2)
farm43 :: (a1 -> a2 -> a3 -> a4 -> (b1, b2, b3))
       -> Vector a1 -> Vector a2 -> Vector a3 -> Vector a4
       -> (Vector b1, Vector b2, Vector b3)
farm44 :: (a1 -> a2 -> a3 -> a4 -> (b1, b2, b3, b4))
       -> Vector a1 -> Vector a2 -> Vector a3 -> Vector a4
       -> (Vector b1, Vector b2, Vector b3, Vector b4)

farm11 :: (a1 -> b1) -> Vector a1 -> Vector b1
farm11 = (a1 -> b1) -> Vector a1 -> Vector b1
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11
farm21 :: (a1 -> a2 -> b1) -> Vector a1 -> Vector a2 -> Vector b1
farm21 = (a1 -> a2 -> b1) -> Vector a1 -> Vector a2 -> Vector b1
forall (c :: * -> *) a1 a2 b.
Skeleton c =>
(a1 -> a2 -> b) -> c a1 -> c a2 -> c b
S.farm21
farm31 :: (a1 -> a2 -> a3 -> b1)
-> Vector a1 -> Vector a2 -> Vector a3 -> Vector b1
farm31 = (a1 -> a2 -> a3 -> b1)
-> Vector a1 -> Vector a2 -> Vector a3 -> Vector b1
forall (c :: * -> *) a1 a2 a3 b.
Skeleton c =>
(a1 -> a2 -> a3 -> b) -> c a1 -> c a2 -> c a3 -> c b
S.farm31
farm41 :: (a1 -> a2 -> a3 -> a4 -> b1)
-> Vector a1 -> Vector a2 -> Vector a3 -> Vector a4 -> Vector b1
farm41 = (a1 -> a2 -> a3 -> a4 -> b1)
-> Vector a1 -> Vector a2 -> Vector a3 -> Vector a4 -> Vector b1
forall (c :: * -> *) a1 a2 a3 a4 b.
Skeleton c =>
(a1 -> a2 -> a3 -> a4 -> b) -> c a1 -> c a2 -> c a3 -> c a4 -> c b
S.farm41
farm12 :: (a1 -> (b1, b2)) -> Vector a1 -> (Vector b1, Vector b2)
farm12 = (a1 -> (b1, b2)) -> Vector a1 -> (Vector b1, Vector b2)
forall (f :: * -> *) a a1 b.
Skeleton f =>
(a -> (a1, b)) -> f a -> (f a1, f b)
S.farm12
farm22 :: (a1 -> a2 -> (b1, b2))
-> Vector a1 -> Vector a2 -> (Vector b1, Vector b2)
farm22 = (a1 -> a2 -> (b1, b2))
-> Vector a1 -> Vector a2 -> (Vector b1, Vector b2)
forall (c :: * -> *) a1 a2 b1 b2.
Skeleton c =>
(a1 -> a2 -> (b1, b2)) -> c a1 -> c a2 -> (c b1, c b2)
S.farm22
farm32 :: (a1 -> a2 -> a3 -> (b1, b2))
-> Vector a1 -> Vector a2 -> Vector a3 -> (Vector b1, Vector b2)
farm32 = (a1 -> a2 -> a3 -> (b1, b2))
-> Vector a1 -> Vector a2 -> Vector a3 -> (Vector b1, Vector b2)
forall (f :: * -> *) a1 a2 a3 a4 b.
Skeleton f =>
(a1 -> a2 -> a3 -> (a4, b)) -> f a1 -> f a2 -> f a3 -> (f a4, f b)
S.farm32
farm42 :: (a1 -> a2 -> a3 -> a4 -> (b1, b2))
-> Vector a1
-> Vector a2
-> Vector a3
-> Vector a4
-> (Vector b1, Vector b2)
farm42 = (a1 -> a2 -> a3 -> a4 -> (b1, b2))
-> Vector a1
-> Vector a2
-> Vector a3
-> Vector a4
-> (Vector b1, Vector b2)
forall (f :: * -> *) a1 a2 a3 a4 a5 b.
Skeleton f =>
(a1 -> a2 -> a3 -> a4 -> (a5, b))
-> f a1 -> f a2 -> f a3 -> f a4 -> (f a5, f b)
S.farm42
farm13 :: (a1 -> (b1, b2, b3))
-> Vector a1 -> (Vector b1, Vector b2, Vector b3)
farm13 = (a1 -> (b1, b2, b3))
-> Vector a1 -> (Vector b1, Vector b2, Vector b3)
forall (f :: * -> *) a1 a2 b1 b2.
Skeleton f =>
(a1 -> (a2, b1, b2)) -> f a1 -> (f a2, f b1, f b2)
S.farm13
farm23 :: (a1 -> a2 -> (b1, b2, b3))
-> Vector a1 -> Vector a2 -> (Vector b1, Vector b2, Vector b3)
farm23 = (a1 -> a2 -> (b1, b2, b3))
-> Vector a1 -> Vector a2 -> (Vector b1, Vector b2, Vector b3)
forall (f :: * -> *) a1 a2 a3 b1 b2.
Skeleton f =>
(a1 -> a2 -> (a3, b1, b2)) -> f a1 -> f a2 -> (f a3, f b1, f b2)
S.farm23
farm33 :: (a1 -> a2 -> a3 -> (b1, b2, b3))
-> Vector a1
-> Vector a2
-> Vector a3
-> (Vector b1, Vector b2, Vector b3)
farm33 = (a1 -> a2 -> a3 -> (b1, b2, b3))
-> Vector a1
-> Vector a2
-> Vector a3
-> (Vector b1, Vector b2, Vector b3)
forall (f :: * -> *) a1 a2 a3 a4 b1 b2.
Skeleton f =>
(a1 -> a2 -> a3 -> (a4, b1, b2))
-> f a1 -> f a2 -> f a3 -> (f a4, f b1, f b2)
S.farm33
farm43 :: (a1 -> a2 -> a3 -> a4 -> (b1, b2, b3))
-> Vector a1
-> Vector a2
-> Vector a3
-> Vector a4
-> (Vector b1, Vector b2, Vector b3)
farm43 = (a1 -> a2 -> a3 -> a4 -> (b1, b2, b3))
-> Vector a1
-> Vector a2
-> Vector a3
-> Vector a4
-> (Vector b1, Vector b2, Vector b3)
forall (f :: * -> *) a1 a2 a3 a4 a5 b1 b2.
Skeleton f =>
(a1 -> a2 -> a3 -> a4 -> (a5, b1, b2))
-> f a1 -> f a2 -> f a3 -> f a4 -> (f a5, f b1, f b2)
S.farm43
farm14 :: (a1 -> (b1, b2, b3, b4))
-> Vector a1 -> (Vector b1, Vector b2, Vector b3, Vector b4)
farm14 = (a1 -> (b1, b2, b3, b4))
-> Vector a1 -> (Vector b1, Vector b2, Vector b3, Vector b4)
forall (f :: * -> *) a1 a2 b1 c b2.
Skeleton f =>
(a1 -> (a2, b1, c, b2)) -> f a1 -> (f a2, f b1, f c, f b2)
S.farm14
farm24 :: (a1 -> a2 -> (b1, b2, b3, b4))
-> Vector a1
-> Vector a2
-> (Vector b1, Vector b2, Vector b3, Vector b4)
farm24 = (a1 -> a2 -> (b1, b2, b3, b4))
-> Vector a1
-> Vector a2
-> (Vector b1, Vector b2, Vector b3, Vector b4)
forall (f :: * -> *) a1 a2 a3 b1 c b2.
Skeleton f =>
(a1 -> a2 -> (a3, b1, c, b2))
-> f a1 -> f a2 -> (f a3, f b1, f c, f b2)
S.farm24
farm34 :: (a1 -> a2 -> a3 -> (b1, b2, b3, b4))
-> Vector a1
-> Vector a2
-> Vector a3
-> (Vector b1, Vector b2, Vector b3, Vector b4)
farm34 = (a1 -> a2 -> a3 -> (b1, b2, b3, b4))
-> Vector a1
-> Vector a2
-> Vector a3
-> (Vector b1, Vector b2, Vector b3, Vector b4)
forall (f :: * -> *) a1 a2 a3 a4 b1 c b2.
Skeleton f =>
(a1 -> a2 -> a3 -> (a4, b1, c, b2))
-> f a1 -> f a2 -> f a3 -> (f a4, f b1, f c, f b2)
S.farm34
farm44 :: (a1 -> a2 -> a3 -> a4 -> (b1, b2, b3, b4))
-> Vector a1
-> Vector a2
-> Vector a3
-> Vector a4
-> (Vector b1, Vector b2, Vector b3, Vector b4)
farm44 = (a1 -> a2 -> a3 -> a4 -> (b1, b2, b3, b4))
-> Vector a1
-> Vector a2
-> Vector a3
-> Vector a4
-> (Vector b1, Vector b2, Vector b3, Vector b4)
forall (f :: * -> *) a1 a2 a3 a4 a5 b1 c b2.
Skeleton f =>
(a1 -> a2 -> a3 -> a4 -> (a5, b1, c, b2))
-> f a1 -> f a2 -> f a3 -> f a4 -> (f a5, f b1, f c, f b2)
S.farm44


------- REDUCE -------

-- | As the name suggests, it reduces a vector to an element based on
-- an associative function. If the function is not associative, it can be treated like a pipeline.
--
-- 'Vector' instantiates the skeletons for both
-- 'ForSyDe.Atom.Skel.reduce' and 'ForSyDe.Atom.Skel.reducei'.
--
-- >>> let v1 = vector [1,2,3,4,5]
-- >>> S.reduce (+) v1
-- 15
-- >>> let s1 = SY.signal [1,2,3,4,5]
-- >>> let s2 = SY.signal [10,10,10,10,10]
-- >>> let v2 = vector [s1,s1,s1]
-- >>> S.reduce (comb21 (+)) v2
-- {3,6,9,12,15}
-- >>> S.reducei (comb21 (+)) s2 v2
-- {13,16,19,22,25}
--
-- <<fig/skel-vector-func-reducei.png>>
-- <<fig/skel-vector-func-reducei-net.png>>
reduce  :: (a -> a -> a) -> Vector a -> a
reducei :: (a -> a -> a) -> a -> Vector a -> a
reduce :: (a -> a -> a) -> Vector a -> a
reduce  = (a -> a -> a) -> Vector a -> a
forall (c :: * -> *) a. Skeleton c => (a -> a -> a) -> c a -> a
S.reduce
reducei :: (a -> a -> a) -> a -> Vector a -> a
reducei = (a -> a -> a) -> a -> Vector a -> a
forall (c :: * -> *) a.
Skeleton c =>
(a -> a -> a) -> a -> c a -> a
S.reducei

reduce1 :: (a1 -> a -> a -> a) -> Vector a1 -> Vector a -> a
reduce1  p :: a1 -> a -> a -> a
p   v1 :: Vector a1
v1 vs :: Vector a
vs       = (a1 -> a -> a -> a) -> Vector a1 -> Vector a -> Vector (a -> a)
forall (c :: * -> *) a1 a2 b.
Skeleton c =>
(a1 -> a2 -> b) -> c a1 -> c a2 -> c b
S.farm21 a1 -> a -> a -> a
p Vector a1
v1 (Vector a -> Vector a
forall a. Vector a -> Vector a
init Vector a
vs) Vector (a -> a) -> a -> a
forall (c :: * -> *) a. Skeleton c => c (a -> a) -> a -> a
=<<= Vector a -> a
forall (c :: * -> *) a. Skeleton c => c a -> a
S.last Vector a
vs
reduce2 :: (a1 -> a2 -> a -> a -> a)
-> Vector a1 -> Vector a2 -> Vector a -> a
reduce2  p :: a1 -> a2 -> a -> a -> a
p   v1 :: Vector a1
v1 v2 :: Vector a2
v2 vs :: Vector a
vs    = (a1 -> a2 -> a -> a -> a)
-> Vector a1 -> Vector a2 -> Vector a -> Vector (a -> a)
forall (c :: * -> *) a1 a2 a3 b.
Skeleton c =>
(a1 -> a2 -> a3 -> b) -> c a1 -> c a2 -> c a3 -> c b
S.farm31 a1 -> a2 -> a -> a -> a
p Vector a1
v1 Vector a2
v2 (Vector a -> Vector a
forall a. Vector a -> Vector a
init Vector a
vs) Vector (a -> a) -> a -> a
forall (c :: * -> *) a. Skeleton c => c (a -> a) -> a -> a
=<<= Vector a -> a
forall (c :: * -> *) a. Skeleton c => c a -> a
S.last Vector a
vs
reduce3 :: (a1 -> a2 -> a3 -> a -> a -> a)
-> Vector a1 -> Vector a2 -> Vector a3 -> Vector a -> a
reduce3  p :: a1 -> a2 -> a3 -> a -> a -> a
p   v1 :: Vector a1
v1 v2 :: Vector a2
v2 v3 :: Vector a3
v3 vs :: Vector a
vs = (a1 -> a2 -> a3 -> a -> a -> a)
-> Vector a1
-> Vector a2
-> Vector a3
-> Vector a
-> Vector (a -> a)
forall (c :: * -> *) a1 a2 a3 a4 b.
Skeleton c =>
(a1 -> a2 -> a3 -> a4 -> b) -> c a1 -> c a2 -> c a3 -> c a4 -> c b
S.farm41 a1 -> a2 -> a3 -> a -> a -> a
p Vector a1
v1 Vector a2
v2 Vector a3
v3 (Vector a -> Vector a
forall a. Vector a -> Vector a
init Vector a
vs) Vector (a -> a) -> a -> a
forall (c :: * -> *) a. Skeleton c => c (a -> a) -> a -> a
=<<= Vector a -> a
forall (c :: * -> *) a. Skeleton c => c a -> a
S.last Vector a
vs
reducei1 :: (a1 -> a2 -> a -> a) -> a -> c a1 -> c a2 -> a
reducei1 p :: a1 -> a2 -> a -> a
p i :: a
i v1 :: c a1
v1 vs :: c a2
vs       = (a1 -> a2 -> a -> a) -> c a1 -> c a2 -> c (a -> a)
forall (c :: * -> *) a1 a2 b.
Skeleton c =>
(a1 -> a2 -> b) -> c a1 -> c a2 -> c b
S.farm21 a1 -> a2 -> a -> a
p c a1
v1 c a2
vs c (a -> a) -> a -> a
forall (c :: * -> *) a. Skeleton c => c (a -> a) -> a -> a
=<<= a
i
reducei2 :: (a1 -> a2 -> a3 -> a -> a) -> a -> c a1 -> c a2 -> c a3 -> a
reducei2 p :: a1 -> a2 -> a3 -> a -> a
p i :: a
i v1 :: c a1
v1 v2 :: c a2
v2 vs :: c a3
vs    = (a1 -> a2 -> a3 -> a -> a) -> c a1 -> c a2 -> c a3 -> c (a -> a)
forall (c :: * -> *) a1 a2 a3 b.
Skeleton c =>
(a1 -> a2 -> a3 -> b) -> c a1 -> c a2 -> c a3 -> c b
S.farm31 a1 -> a2 -> a3 -> a -> a
p c a1
v1 c a2
v2 c a3
vs c (a -> a) -> a -> a
forall (c :: * -> *) a. Skeleton c => c (a -> a) -> a -> a
=<<= a
i
reducei3 :: (a1 -> a2 -> a3 -> a4 -> a -> a)
-> a -> c a1 -> c a2 -> c a3 -> c a4 -> a
reducei3 p :: a1 -> a2 -> a3 -> a4 -> a -> a
p i :: a
i v1 :: c a1
v1 v2 :: c a2
v2 v3 :: c a3
v3 vs :: c a4
vs = (a1 -> a2 -> a3 -> a4 -> a -> a)
-> c a1 -> c a2 -> c a3 -> c a4 -> c (a -> a)
forall (c :: * -> *) a1 a2 a3 a4 b.
Skeleton c =>
(a1 -> a2 -> a3 -> a4 -> b) -> c a1 -> c a2 -> c a3 -> c a4 -> c b
S.farm41 a1 -> a2 -> a3 -> a4 -> a -> a
p c a1
v1 c a2
v2 c a3
v3 c a4
vs c (a -> a) -> a -> a
forall (c :: * -> *) a. Skeleton c => c (a -> a) -> a -> a
=<<= a
i


------- PREFIX -------

-- | @prefix@ peforms the /parallel prefix/ operation on a vector.
-- Equivalent process networks are constructed if processes are passed
-- as arguments.
--
-- Similar to 'reduce' and 'reducei', two versions 'prefix' and
-- @prefixi@ are provided.
--
-- >>> let v1 = vector [1,2,3,4,5]
-- >>> prefix (+) v1
-- <15,14,12,9,5>
-- >>> let s1 = SY.signal [1,2,3,4,5]
-- >>> let s2 = SY.signal [10,10,10,10,10]
-- >>> let v2 = vector [s1,s1,s1]
-- >>> prefix (comb21 (+)) v2
-- <{3,6,9,12,15},{2,4,6,8,10},{1,2,3,4,5}>
-- >>> prefixi (comb21 (+)) s2 v2
-- <{13,16,19,22,25},{12,14,16,18,20},{11,12,13,14,15}>
--
-- <<fig/eqs-skel-vector-prefix.png>>
--
-- <<fig/skel-vector-func-prefix.png>>
-- <<fig/skel-vector-func-prefix-net.png>>
--
-- <<fig/skel-vector-func-prefixi.png>>
-- <<fig/skel-vector-func-prefixi-net.png>>

prefix :: (b -> b -> b) -> Vector b -> Vector b
prefix  p :: b -> b -> b
p   = (Vector b -> b) -> Vector (Vector b) -> Vector b
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 ((b -> b -> b) -> Vector b -> b
forall (c :: * -> *) a. Skeleton c => (a -> a -> a) -> c a -> a
S.reduce b -> b -> b
p) (Vector (Vector b) -> Vector b)
-> (Vector b -> Vector (Vector b)) -> Vector b -> Vector b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector b -> Vector (Vector b)
forall a. Vector a -> Vector (Vector a)
tails
prefixi :: (b -> b -> b) -> b -> Vector b -> Vector b
prefixi p :: b -> b -> b
p i :: b
i = (Vector b -> b) -> Vector (Vector b) -> Vector b
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 ((b -> b -> b) -> b -> Vector b -> b
forall (c :: * -> *) a.
Skeleton c =>
(a -> a -> a) -> a -> c a -> a
S.reducei b -> b -> b
p b
i) (Vector (Vector b) -> Vector b)
-> (Vector b -> Vector (Vector b)) -> Vector b -> Vector b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector b -> Vector (Vector b)
forall a. Vector a -> Vector (Vector a)
tails

-- prefix1 p v1 vs
--   = S.farm21 (reduce1 p) (tails v1) (tails vs)
-- prefix2 p v1 v2 vs
--   = S.farm31 (reduce2 p) (tails v1) (tails v2) (tails vs)
-- prefix3 p v1 v2 v3 vs
--   = S.farm41 (reduce3 p) (tails v1) (tails v2) (tails v3) (tails vs)
-- prefixi1 p i v1 vs
--   = S.farm21 (reducei1 p i) (tails v1) (tails vs)
-- prefixi2 p i v1 v2 vs
--   = S.farm31 (reducei2 p i) (tails v1) (tails v2) (tails vs)
-- prefixi3 p i v1 v2 v3 vs
--   = S.farm41 (reducei3 p i) (tails v1) (tails v2) (tails v3) (tails vs)

    
------- SUFFIX -------

-- | @suffix@ peforms the /parallel suffix/ operation on a vector.
-- Equivalent process networks are constructed if processes are passed
-- as arguments.
--
-- Similar to 'reduce' and 'reducei', two versions 'suffix' and
-- @suffixi@ are provided.
--
-- >>> let v1 = vector [1,2,3,4,5]
-- >>> suffix (+) v1
-- <1,3,6,10,15>
-- >>> let s1 = SY.signal [1,2,3,4,5]
-- >>> let s2 = SY.signal [10,10,10,10,10]
-- >>> let v2 = vector [s1,s1,s1]
-- >>> suffix (comb21 (+)) v2
-- <{1,2,3,4,5},{2,4,6,8,10},{3,6,9,12,15}>
-- >>> suffixi (comb21 (+)) s2 v2
-- <{11,12,13,14,15},{12,14,16,18,20},{13,16,19,22,25}>
--
-- <<fig/eqs-skel-vector-suffix.png>>
--
-- <<fig/skel-vector-func-suffix.png>>
-- <<fig/skel-vector-func-suffix-net.png>>
--
-- <<fig/skel-vector-func-suffixi.png>>
-- <<fig/skel-vector-func-suffixi-net.png>>

suffix :: (b -> b -> b) -> Vector b -> Vector b
suffix p :: b -> b -> b
p    = (Vector b -> b) -> Vector (Vector b) -> Vector b
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 ((b -> b -> b) -> Vector b -> b
forall (c :: * -> *) a. Skeleton c => (a -> a -> a) -> c a -> a
S.reduce b -> b -> b
p) (Vector (Vector b) -> Vector b)
-> (Vector b -> Vector (Vector b)) -> Vector b -> Vector b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector b -> Vector (Vector b)
forall a. Vector a -> Vector (Vector a)
inits
suffixi :: (b -> b -> b) -> b -> Vector b -> Vector b
suffixi p :: b -> b -> b
p i :: b
i = (Vector b -> b) -> Vector (Vector b) -> Vector b
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 ((b -> b -> b) -> b -> Vector b -> b
forall (c :: * -> *) a.
Skeleton c =>
(a -> a -> a) -> a -> c a -> a
S.reducei b -> b -> b
p b
i) (Vector (Vector b) -> Vector b)
-> (Vector b -> Vector (Vector b)) -> Vector b -> Vector b
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector b -> Vector (Vector b)
forall a. Vector a -> Vector (Vector a)
inits

-- suffix1 p v1 vs
--   = S.farm21 (reduce1 p) (inits v1) (inits vs)
-- suffix2 p v1 v2 vs
--   = S.farm31 (reduce2 p) (fanout v1) (fanout v2) (inits vs)
-- suffix3 p v1 v2 v3 vs
--   = S.farm41 (reduce3 p) (fanout v1) (fanout v2) (fanout v3) (inits vs)
-- suffixi1 p i v1 vs
--   = S.farm21 (reducei1 p i) (tails v1) (inits vs)
-- suffixi2 p i v1 v2 vs
--   = S.farm31 (reducei2 p i) (fanout v1) (fanout v2) (inits vs)
-- suffixi3 p i v1 v2 v3 vs
--   = S.farm41 (reducei3 p i) (fanout v1) (fanout v2) (fanout v3) (inits vs)


------- PIPE -------

-- | @pipe@ creates a pipeline of functions from a vector. 'pipe'
--  simply instantiates the '=<<=' atom whereas @pipeX@ instantiate
--  their omologi from the "ForSyDe.Atom.Skel" module (see
--  'ForSyDe.Atom.Skeletom.pipe2').
--
-- __OBS:__ the pipelining is done in the order dictated by the
-- function composition operator: from right to left.
--
-- Constructors: @pipe[1-4]@.
--
-- >>> let v1 = vector [(+1),(+1),(+1)]
-- >>> S.pipe v1 1
-- 4
-- >>> let s1 = SY.signal [1,2,3,4]
-- >>> let v2 = vector [1,2,3,4]
-- >>> S.pipe1 (\x -> comb11 (+x)) v2 s1
-- {11,12,13,14}
--
-- <<fig/skel-vector-func-pipe.png>>
-- <<fig/skel-vector-func-pipe-net.png>>
pipe :: Vector (a -> a) -- ^ vector of functions
      -> a               -- ^ input
      -> a               -- ^ output
pipe1 :: (a1 -> a -> a)
      -> Vector a1
      -> a -> a
pipe2 :: (a1 -> a2 -> a -> a)
      -> Vector a1 -> Vector a2
      -> a -> a
pipe3 :: (a1 -> a2 -> a3 -> a -> a)
      -> Vector a1 -> Vector a2 -> Vector a3
      -> a -> a
pipe4 :: (a1 -> a2 -> a3 -> a4 -> a -> a)
      -> Vector a1 -> Vector a2 -> Vector a3 -> Vector a4
      -> a -> a

pipe :: Vector (a -> a) -> a -> a
pipe = Vector (a -> a) -> a -> a
forall (c :: * -> *) a. Skeleton c => c (a -> a) -> a -> a
S.pipe
pipe1 :: (a1 -> a -> a) -> Vector a1 -> a -> a
pipe1 = (a1 -> a -> a) -> Vector a1 -> a -> a
forall (c :: * -> *) a1 a2.
Skeleton c =>
(a1 -> a2 -> a2) -> c a1 -> a2 -> a2
S.pipe1
pipe2 :: (a1 -> a2 -> a -> a) -> Vector a1 -> Vector a2 -> a -> a
pipe2 = (a1 -> a2 -> a -> a) -> Vector a1 -> Vector a2 -> a -> a
forall (c :: * -> *) a1 a2 a.
Skeleton c =>
(a1 -> a2 -> a -> a) -> c a1 -> c a2 -> a -> a
S.pipe2
pipe3 :: (a1 -> a2 -> a3 -> a -> a)
-> Vector a1 -> Vector a2 -> Vector a3 -> a -> a
pipe3 = (a1 -> a2 -> a3 -> a -> a)
-> Vector a1 -> Vector a2 -> Vector a3 -> a -> a
forall (c :: * -> *) a1 a2 a3 a4.
Skeleton c =>
(a1 -> a2 -> a3 -> a4 -> a4) -> c a1 -> c a2 -> c a3 -> a4 -> a4
S.pipe3
pipe4 :: (a1 -> a2 -> a3 -> a4 -> a -> a)
-> Vector a1 -> Vector a2 -> Vector a3 -> Vector a4 -> a -> a
pipe4 = (a1 -> a2 -> a3 -> a4 -> a -> a)
-> Vector a1 -> Vector a2 -> Vector a3 -> Vector a4 -> a -> a
forall (c :: * -> *) a1 a2 a3 a4 a5.
Skeleton c =>
(a1 -> a2 -> a3 -> a4 -> a5 -> a5)
-> c a1 -> c a2 -> c a3 -> c a4 -> a5 -> a5
S.pipe4


------- RECUR -------

-- | @recur@ creates a systolic array from a vector of
-- functions. Just like 'pipe' and @pipeX@, there exists a raw
-- 'recur' version with an infix operator '=/=', and the enhanced
-- @recurX@ which is meant for systematic partial application of a
-- function on an arbitrary number of vectors until the desired vector
-- of functions is obtained.
--
-- Constructors: @(=/=)@, @recur@, @recuri@, @recur[1-4][1-4]@.
--
-- >>> let v1 = vector [(+1),(+1),(+1)]
-- >>> recur v1 1
-- <4,3,2>
-- >>> recuri v1 1
-- <4,3,2,1>
-- >>> let s1 = SY.signal [1,2,3,4]
-- >>> let v2 = vector [1,2,3,4]
-- >>> recur1 (\x -> comb11 (+x)) v2 s1
-- <{11,12,13,14},{10,11,12,13},{8,9,10,11},{5,6,7,8}>
--
-- <<fig/eqs-skel-vector-recur.png>>
--
-- <<fig/skel-vector-func-recur.png>>
-- <<fig/skel-vector-func-recur-net.png>>
recur :: Vector (a -> a) -- ^ vector of functions
      -> a               -- ^ input
      -> Vector a        -- ^ output 

infixl 2 =/=
-- | Infix operator for 'recur'.
=/= :: Vector (a -> a) -> a -> Vector a
(=/=) = Vector (a -> a) -> a -> Vector a
forall a. Vector (a -> a) -> a -> Vector a
recur
recur :: Vector (a -> a) -> a -> Vector a
recur  ps :: Vector (a -> a)
ps s :: a
s              = (Vector (a -> a) -> a) -> Vector (Vector (a -> a)) -> Vector a
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 (Vector (a -> a) -> a -> a
forall (c :: * -> *) a. Skeleton c => c (a -> a) -> a -> a
=<<= a
s) (Vector (a -> a) -> Vector (Vector (a -> a))
forall a. Vector a -> Vector (Vector a)
tails Vector (a -> a)
ps)
recuri :: Vector (b -> b) -> b -> Vector b
recuri ps :: Vector (b -> b)
ps s :: b
s              = (Vector (b -> b) -> b) -> Vector (Vector (b -> b)) -> Vector b
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 (Vector (b -> b) -> b -> b
forall (c :: * -> *) a. Skeleton c => c (a -> a) -> a -> a
=<<= b
s) (Vector (b -> b) -> Vector (Vector (b -> b))
forall a. Vector a -> Vector (Vector a)
tails (Vector (b -> b) -> Vector (Vector (b -> b)))
-> Vector (b -> b) -> Vector (Vector (b -> b))
forall a b. (a -> b) -> a -> b
$ Vector (b -> b)
ps Vector (b -> b) -> (b -> b) -> Vector (b -> b)
forall a. Vector a -> a -> Vector a
<: b -> b
forall a. a -> a
id)
recur1 :: (a -> a -> a) -> Vector a -> a -> Vector a
recur1 p :: a -> a -> a
p v1 :: Vector a
v1 s :: a
s            = (a -> a -> a) -> Vector a -> Vector (a -> a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 a -> a -> a
p Vector a
v1 Vector (a -> a) -> a -> Vector a
forall a. Vector (a -> a) -> a -> Vector a
=/= a
s
recur2 :: (a1 -> a2 -> a -> a) -> Vector a1 -> Vector a2 -> a -> Vector a
recur2 p :: a1 -> a2 -> a -> a
p v1 :: Vector a1
v1 v2 :: Vector a2
v2 s :: a
s         = (a1 -> a2 -> a -> a) -> Vector a1 -> Vector a2 -> Vector (a -> a)
forall (c :: * -> *) a1 a2 b.
Skeleton c =>
(a1 -> a2 -> b) -> c a1 -> c a2 -> c b
S.farm21 a1 -> a2 -> a -> a
p Vector a1
v1 Vector a2
v2 Vector (a -> a) -> a -> Vector a
forall a. Vector (a -> a) -> a -> Vector a
=/= a
s
recur3 :: (a1 -> a2 -> a3 -> a -> a)
-> Vector a1 -> Vector a2 -> Vector a3 -> a -> Vector a
recur3 p :: a1 -> a2 -> a3 -> a -> a
p v1 :: Vector a1
v1 v2 :: Vector a2
v2 v3 :: Vector a3
v3 s :: a
s      = (a1 -> a2 -> a3 -> a -> a)
-> Vector a1 -> Vector a2 -> Vector a3 -> Vector (a -> a)
forall (c :: * -> *) a1 a2 a3 b.
Skeleton c =>
(a1 -> a2 -> a3 -> b) -> c a1 -> c a2 -> c a3 -> c b
S.farm31 a1 -> a2 -> a3 -> a -> a
p Vector a1
v1 Vector a2
v2 Vector a3
v3 Vector (a -> a) -> a -> Vector a
forall a. Vector (a -> a) -> a -> Vector a
=/= a
s
recur4 :: (a1 -> a2 -> a3 -> a4 -> a -> a)
-> Vector a1
-> Vector a2
-> Vector a3
-> Vector a4
-> a
-> Vector a
recur4 p :: a1 -> a2 -> a3 -> a4 -> a -> a
p v1 :: Vector a1
v1 v2 :: Vector a2
v2 v3 :: Vector a3
v3 v4 :: Vector a4
v4 s :: a
s   = (a1 -> a2 -> a3 -> a4 -> a -> a)
-> Vector a1
-> Vector a2
-> Vector a3
-> Vector a4
-> Vector (a -> a)
forall (c :: * -> *) a1 a2 a3 a4 b.
Skeleton c =>
(a1 -> a2 -> a3 -> a4 -> b) -> c a1 -> c a2 -> c a3 -> c a4 -> c b
S.farm41 a1 -> a2 -> a3 -> a4 -> a -> a
p Vector a1
v1 Vector a2
v2 Vector a3
v3 Vector a4
v4 Vector (a -> a) -> a -> Vector a
forall a. Vector (a -> a) -> a -> Vector a
=/= a
s
recuri1 :: (a -> b -> b) -> Vector a -> b -> Vector b
recuri1 p :: a -> b -> b
p v1 :: Vector a
v1 s :: b
s            = (a -> b -> b) -> Vector a -> Vector (b -> b)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 a -> b -> b
p Vector a
v1 Vector (b -> b) -> b -> Vector b
forall a. Vector (a -> a) -> a -> Vector a
`recuri` b
s
recuri2 :: (a1 -> a2 -> b -> b) -> Vector a1 -> Vector a2 -> b -> Vector b
recuri2 p :: a1 -> a2 -> b -> b
p v1 :: Vector a1
v1 v2 :: Vector a2
v2 s :: b
s         = (a1 -> a2 -> b -> b) -> Vector a1 -> Vector a2 -> Vector (b -> b)
forall (c :: * -> *) a1 a2 b.
Skeleton c =>
(a1 -> a2 -> b) -> c a1 -> c a2 -> c b
S.farm21 a1 -> a2 -> b -> b
p Vector a1
v1 Vector a2
v2 Vector (b -> b) -> b -> Vector b
forall a. Vector (a -> a) -> a -> Vector a
`recuri` b
s
recuri3 :: (a1 -> a2 -> a3 -> b -> b)
-> Vector a1 -> Vector a2 -> Vector a3 -> b -> Vector b
recuri3 p :: a1 -> a2 -> a3 -> b -> b
p v1 :: Vector a1
v1 v2 :: Vector a2
v2 v3 :: Vector a3
v3 s :: b
s      = (a1 -> a2 -> a3 -> b -> b)
-> Vector a1 -> Vector a2 -> Vector a3 -> Vector (b -> b)
forall (c :: * -> *) a1 a2 a3 b.
Skeleton c =>
(a1 -> a2 -> a3 -> b) -> c a1 -> c a2 -> c a3 -> c b
S.farm31 a1 -> a2 -> a3 -> b -> b
p Vector a1
v1 Vector a2
v2 Vector a3
v3 Vector (b -> b) -> b -> Vector b
forall a. Vector (a -> a) -> a -> Vector a
`recuri` b
s
recuri4 :: (a1 -> a2 -> a3 -> a4 -> b -> b)
-> Vector a1
-> Vector a2
-> Vector a3
-> Vector a4
-> b
-> Vector b
recuri4 p :: a1 -> a2 -> a3 -> a4 -> b -> b
p v1 :: Vector a1
v1 v2 :: Vector a2
v2 v3 :: Vector a3
v3 v4 :: Vector a4
v4 s :: b
s   = (a1 -> a2 -> a3 -> a4 -> b -> b)
-> Vector a1
-> Vector a2
-> Vector a3
-> Vector a4
-> Vector (b -> b)
forall (c :: * -> *) a1 a2 a3 a4 b.
Skeleton c =>
(a1 -> a2 -> a3 -> a4 -> b) -> c a1 -> c a2 -> c a3 -> c a4 -> c b
S.farm41 a1 -> a2 -> a3 -> a4 -> b -> b
p Vector a1
v1 Vector a2
v2 Vector a3
v3 Vector a4
v4 Vector (b -> b) -> b -> Vector b
forall a. Vector (a -> a) -> a -> Vector a
`recuri` b
s



------- CASCADE -------

-- | @cascade@ creates a \"cascading mesh\" as a result of piping a
-- vector into a vector of recur arrays. 
--
-- Constructors: @cascade@, @cascade[1-4]@.
--
-- >>> let v1 = vector [1,2,3,4]
-- >>> cascade (+) v1 v1
-- <238,119,49,14>
-- >>> let s1 = SY.signal [1,2,3,4]
-- >>> let vs = vector [s1, s1, s1]
-- >>> cascade (comb21 (+)) vs vs
-- <{20,40,60,80},{10,20,30,40},{4,8,12,16}>
-- >>> let vv = vector [vector [1,-1,1], vector [-1,1,-1], vector [1,-1,1] ]
-- >>> cascade1 (\x -> comb21 (\y z-> x*(y+z))) vv vs vs
-- <{16,32,48,64},{8,16,24,32},{-2,-4,-6,-8}>
--
-- <<fig/eqs-skel-vector-cascade.png>>
--
-- <<fig/skel-vector-func-cascade.png>>
-- <<fig/skel-vector-func-cascade-net.png>>
cascade2 :: (a2 -> a1 -> a -> a -> a)
         -- ^ @function41@ which needs to be applied to @function21@
         -> Vector (Vector a2)
         -- ^ fills in the first argument in the function above
         -> Vector (Vector a1)
         -- ^ fills in the second argument in the function above
         -> Vector a
         -- ^ first input vector (e.g. of signals)
         -> Vector a
         -- ^ second input vector (e.g. of signals)
         -> Vector a
         -- ^ output

cascade :: (a -> a -> a) -> Vector a -> c a -> Vector a
cascade  p :: a -> a -> a
p vs1 :: Vector a
vs1 vs2 :: c a
vs2
  = (a -> Vector a -> Vector a) -> c a -> c (Vector a -> Vector a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 (\s2 :: a
s2 s1 :: Vector a
s1 -> (a -> a -> a) -> Vector a -> Vector (a -> a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 a -> a -> a
p Vector a
s1 Vector (a -> a) -> a -> Vector a
forall a. Vector (a -> a) -> a -> Vector a
=/= a
s2)
    c a
vs2 c (Vector a -> Vector a) -> Vector a -> Vector a
forall (c :: * -> *) a. Skeleton c => c (a -> a) -> a -> a
=<<= Vector a
vs1
cascade1 :: (a1 -> a2 -> a2 -> a2)
-> c (Vector a1) -> Vector a2 -> c a2 -> Vector a2
cascade1 p :: a1 -> a2 -> a2 -> a2
p vv1 :: c (Vector a1)
vv1 vs1 :: Vector a2
vs1 vs2 :: c a2
vs2
  = (Vector a1 -> a2 -> Vector a2 -> Vector a2)
-> c (Vector a1) -> c a2 -> c (Vector a2 -> Vector a2)
forall (c :: * -> *) a1 a2 b.
Skeleton c =>
(a1 -> a2 -> b) -> c a1 -> c a2 -> c b
S.farm21 (\v1 :: Vector a1
v1 s2 :: a2
s2 s1 :: Vector a2
s1 -> (a1 -> a2 -> a2 -> a2)
-> Vector a1 -> Vector a2 -> Vector (a2 -> a2)
forall (c :: * -> *) a1 a2 b.
Skeleton c =>
(a1 -> a2 -> b) -> c a1 -> c a2 -> c b
S.farm21 a1 -> a2 -> a2 -> a2
p Vector a1
v1 Vector a2
s1 Vector (a2 -> a2) -> a2 -> Vector a2
forall a. Vector (a -> a) -> a -> Vector a
=/= a2
s2)
    c (Vector a1)
vv1 c a2
vs2 c (Vector a2 -> Vector a2) -> Vector a2 -> Vector a2
forall (c :: * -> *) a. Skeleton c => c (a -> a) -> a -> a
=<<= Vector a2
vs1
cascade2 :: (a2 -> a1 -> a -> a -> a)
-> Vector (Vector a2)
-> Vector (Vector a1)
-> Vector a
-> Vector a
-> Vector a
cascade2 p :: a2 -> a1 -> a -> a -> a
p vv1 :: Vector (Vector a2)
vv1 vv2 :: Vector (Vector a1)
vv2 vs1 :: Vector a
vs1 vs2 :: Vector a
vs2
  = (Vector a2 -> Vector a1 -> a -> Vector a -> Vector a)
-> Vector (Vector a2)
-> Vector (Vector a1)
-> Vector a
-> Vector (Vector a -> Vector a)
forall (c :: * -> *) a1 a2 a3 b.
Skeleton c =>
(a1 -> a2 -> a3 -> b) -> c a1 -> c a2 -> c a3 -> c b
S.farm31 (\v1 :: Vector a2
v1 v2 :: Vector a1
v2 s2 :: a
s2 s1 :: Vector a
s1 -> (a2 -> a1 -> a -> a -> a)
-> Vector a2 -> Vector a1 -> Vector a -> Vector (a -> a)
forall (c :: * -> *) a1 a2 a3 b.
Skeleton c =>
(a1 -> a2 -> a3 -> b) -> c a1 -> c a2 -> c a3 -> c b
S.farm31 a2 -> a1 -> a -> a -> a
p Vector a2
v1 Vector a1
v2 Vector a
s1 Vector (a -> a) -> a -> Vector a
forall a. Vector (a -> a) -> a -> Vector a
=/= a
s2)
    Vector (Vector a2)
vv1 Vector (Vector a1)
vv2 Vector a
vs2 Vector (Vector a -> Vector a) -> Vector a -> Vector a
forall (c :: * -> *) a. Skeleton c => c (a -> a) -> a -> a
=<<= Vector a
vs1
cascade3 :: (a1 -> a2 -> a3 -> a4 -> a4 -> a4)
-> c (Vector a1)
-> c (Vector a2)
-> c (Vector a3)
-> Vector a4
-> c a4
-> Vector a4
cascade3 p :: a1 -> a2 -> a3 -> a4 -> a4 -> a4
p vv1 :: c (Vector a1)
vv1 vv2 :: c (Vector a2)
vv2 vv3 :: c (Vector a3)
vv3 vs1 :: Vector a4
vs1 vs2 :: c a4
vs2
  = (Vector a1
 -> Vector a2 -> Vector a3 -> a4 -> Vector a4 -> Vector a4)
-> c (Vector a1)
-> c (Vector a2)
-> c (Vector a3)
-> c a4
-> c (Vector a4 -> Vector a4)
forall (c :: * -> *) a1 a2 a3 a4 b.
Skeleton c =>
(a1 -> a2 -> a3 -> a4 -> b) -> c a1 -> c a2 -> c a3 -> c a4 -> c b
S.farm41 (\v1 :: Vector a1
v1 v2 :: Vector a2
v2 v3 :: Vector a3
v3 s2 :: a4
s2 s1 :: Vector a4
s1 -> (a1 -> a2 -> a3 -> a4 -> a4 -> a4)
-> Vector a1
-> Vector a2
-> Vector a3
-> Vector a4
-> Vector (a4 -> a4)
forall (c :: * -> *) a1 a2 a3 a4 b.
Skeleton c =>
(a1 -> a2 -> a3 -> a4 -> b) -> c a1 -> c a2 -> c a3 -> c a4 -> c b
S.farm41 a1 -> a2 -> a3 -> a4 -> a4 -> a4
p Vector a1
v1 Vector a2
v2 Vector a3
v3 Vector a4
s1 Vector (a4 -> a4) -> a4 -> Vector a4
forall a. Vector (a -> a) -> a -> Vector a
=/= a4
s2)
    c (Vector a1)
vv1 c (Vector a2)
vv2 c (Vector a3)
vv3 c a4
vs2 c (Vector a4 -> Vector a4) -> Vector a4 -> Vector a4
forall (c :: * -> *) a. Skeleton c => c (a -> a) -> a -> a
=<<= Vector a4
vs1
cascade4 :: (a1 -> a2 -> a3 -> a4 -> a5 -> a5 -> a5)
-> c (Vector a1)
-> c (Vector a2)
-> c (Vector a3)
-> c (Vector a4)
-> Vector a5
-> c a5
-> Vector a5
cascade4 p :: a1 -> a2 -> a3 -> a4 -> a5 -> a5 -> a5
p vv1 :: c (Vector a1)
vv1 vv2 :: c (Vector a2)
vv2 vv3 :: c (Vector a3)
vv3 vv4 :: c (Vector a4)
vv4 vs1 :: Vector a5
vs1 vs2 :: c a5
vs2
  = (Vector a1
 -> Vector a2
 -> Vector a3
 -> Vector a4
 -> a5
 -> Vector a5
 -> Vector a5)
-> c (Vector a1)
-> c (Vector a2)
-> c (Vector a3)
-> c (Vector a4)
-> c a5
-> c (Vector a5 -> Vector a5)
forall (c :: * -> *) a1 a2 a3 a4 a5 b.
Skeleton c =>
(a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> c a1 -> c a2 -> c a3 -> c a4 -> c a5 -> c b
S.farm51 (\v1 :: Vector a1
v1 v2 :: Vector a2
v2 v3 :: Vector a3
v3 v4 :: Vector a4
v4 s2 :: a5
s2 s1 :: Vector a5
s1 -> (a1 -> a2 -> a3 -> a4 -> a5 -> a5 -> a5)
-> Vector a1
-> Vector a2
-> Vector a3
-> Vector a4
-> Vector a5
-> Vector (a5 -> a5)
forall (c :: * -> *) a1 a2 a3 a4 a5 b.
Skeleton c =>
(a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> c a1 -> c a2 -> c a3 -> c a4 -> c a5 -> c b
S.farm51 a1 -> a2 -> a3 -> a4 -> a5 -> a5 -> a5
p Vector a1
v1 Vector a2
v2 Vector a3
v3 Vector a4
v4 Vector a5
s1 Vector (a5 -> a5) -> a5 -> Vector a5
forall a. Vector (a -> a) -> a -> Vector a
=/= a5
s2)
    c (Vector a1)
vv1 c (Vector a2)
vv2 c (Vector a3)
vv3 c (Vector a4)
vv4 c a5
vs2 c (Vector a5 -> Vector a5) -> Vector a5 -> Vector a5
forall (c :: * -> *) a. Skeleton c => c (a -> a) -> a -> a
=<<= Vector a5
vs1



------- MESH -------

-- | @mesh@ creates a 2D systolic array as a result of piping a vector
-- into a vector of 1D systolic arrays.
--
-- Constructors: @mesh@, @mesh[1-4]@.
--
-- >>> let v1 = vector [1,2,3,4]
-- >>> mesh (+) v1 v1
-- <<238,119,49,14>,<119,70,35,13>,<49,35,22,11>,<14,13,11,8>>
-- >>> let s1 = SY.signal [1,2,3,4]
-- >>> let vs = vector [s1, s1, s1]
-- >>> mesh (comb21 (+)) vs vs
-- <<{20,40,60,80},{10,20,30,40},{4,8,12,16}>,<{10,20,30,40},{6,12,18,24},{3,6,9,12}>,<{4,8,12,16},{3,6,9,12},{2,4,6,8}>>
-- >>> let vv = vector [vector [1,-1,1], vector [-1,1,-1], vector [1,-1,1]]
-- >>> mesh1 (\x -> comb21 (\y z-> x*(y+z))) vv vs vs
-- <<{16,32,48,64},{8,16,24,32},{-2,-4,-6,-8}>,<{8,16,24,32},{-6,-12,-18,-24},{-3,-6,-9,-12}>,<{-2,-4,-6,-8},{-3,-6,-9,-12},{2,4,6,8}>>
--
-- <<fig/eqs-skel-vector-mesh.png>>
--
-- <<fig/skel-vector-func-mesh.png>>
-- <<fig/skel-vector-func-mesh-net.png>>
mesh2 :: (a2 -> a1 -> a -> a -> a)
      -- ^ @function41@ which needs to be applied to @function21@
      -> Vector (Vector a2)
      -- ^ fills in the first argument in the function above
      -> Vector (Vector a1)
      -- ^ fills in the second argument in the function above
      -> Vector a
      -- ^ first input vector (e.g. of signals)
      -> Vector a
      -- ^ second input vector (e.g. of signals)
      -> Vector (Vector a)
      -- ^ output, a 2D vector

mesh :: (a -> a -> a) -> Vector a -> Vector a -> Vector (Vector a)
mesh  p :: a -> a -> a
p vs1 :: Vector a
vs1 vs2 :: Vector a
vs2
  = (a -> Vector a -> Vector a)
-> Vector a -> Vector (Vector a -> Vector a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 (\ s2 :: a
s2 s1 :: Vector a
s1 -> (a -> a -> a) -> Vector a -> Vector (a -> a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 a -> a -> a
p Vector a
s1 Vector (a -> a) -> a -> Vector a
forall a. Vector (a -> a) -> a -> Vector a
=/= a
s2)
    Vector a
vs2 Vector (Vector a -> Vector a) -> Vector a -> Vector (Vector a)
forall a. Vector (a -> a) -> a -> Vector a
=/= Vector a
vs1
mesh1 :: (a1 -> a2 -> a2 -> a2)
-> Vector (Vector a1)
-> Vector a2
-> Vector a2
-> Vector (Vector a2)
mesh1 p :: a1 -> a2 -> a2 -> a2
p vv1 :: Vector (Vector a1)
vv1 vs1 :: Vector a2
vs1 vs2 :: Vector a2
vs2
  = (Vector a1 -> a2 -> Vector a2 -> Vector a2)
-> Vector (Vector a1)
-> Vector a2
-> Vector (Vector a2 -> Vector a2)
forall (c :: * -> *) a1 a2 b.
Skeleton c =>
(a1 -> a2 -> b) -> c a1 -> c a2 -> c b
S.farm21 (\v1 :: Vector a1
v1 s2 :: a2
s2 s1 :: Vector a2
s1 -> (a1 -> a2 -> a2 -> a2)
-> Vector a1 -> Vector a2 -> Vector (a2 -> a2)
forall (c :: * -> *) a1 a2 b.
Skeleton c =>
(a1 -> a2 -> b) -> c a1 -> c a2 -> c b
S.farm21 a1 -> a2 -> a2 -> a2
p Vector a1
v1 Vector a2
s1 Vector (a2 -> a2) -> a2 -> Vector a2
forall a. Vector (a -> a) -> a -> Vector a
=/= a2
s2)
    Vector (Vector a1)
vv1 Vector a2
vs2 Vector (Vector a2 -> Vector a2) -> Vector a2 -> Vector (Vector a2)
forall a. Vector (a -> a) -> a -> Vector a
=/= Vector a2
vs1
mesh2 :: (a2 -> a1 -> a -> a -> a)
-> Vector (Vector a2)
-> Vector (Vector a1)
-> Vector a
-> Vector a
-> Vector (Vector a)
mesh2 p :: a2 -> a1 -> a -> a -> a
p vv1 :: Vector (Vector a2)
vv1 vv2 :: Vector (Vector a1)
vv2 vs1 :: Vector a
vs1 vs2 :: Vector a
vs2
  = (Vector a2 -> Vector a1 -> a -> Vector a -> Vector a)
-> Vector (Vector a2)
-> Vector (Vector a1)
-> Vector a
-> Vector (Vector a -> Vector a)
forall (c :: * -> *) a1 a2 a3 b.
Skeleton c =>
(a1 -> a2 -> a3 -> b) -> c a1 -> c a2 -> c a3 -> c b
S.farm31 (\v1 :: Vector a2
v1 v2 :: Vector a1
v2 s2 :: a
s2 s1 :: Vector a
s1 -> (a2 -> a1 -> a -> a -> a)
-> Vector a2 -> Vector a1 -> Vector a -> Vector (a -> a)
forall (c :: * -> *) a1 a2 a3 b.
Skeleton c =>
(a1 -> a2 -> a3 -> b) -> c a1 -> c a2 -> c a3 -> c b
S.farm31 a2 -> a1 -> a -> a -> a
p Vector a2
v1 Vector a1
v2 Vector a
s1 Vector (a -> a) -> a -> Vector a
forall a. Vector (a -> a) -> a -> Vector a
=/= a
s2)
    Vector (Vector a2)
vv1 Vector (Vector a1)
vv2 Vector a
vs2 Vector (Vector a -> Vector a) -> Vector a -> Vector (Vector a)
forall a. Vector (a -> a) -> a -> Vector a
=/= Vector a
vs1
mesh3 :: (a1 -> a2 -> a3 -> a4 -> a4 -> a4)
-> Vector (Vector a1)
-> Vector (Vector a2)
-> Vector (Vector a3)
-> Vector a4
-> Vector a4
-> Vector (Vector a4)
mesh3 p :: a1 -> a2 -> a3 -> a4 -> a4 -> a4
p vv1 :: Vector (Vector a1)
vv1 vv2 :: Vector (Vector a2)
vv2 vv3 :: Vector (Vector a3)
vv3 vs1 :: Vector a4
vs1 vs2 :: Vector a4
vs2
  = (Vector a1
 -> Vector a2 -> Vector a3 -> a4 -> Vector a4 -> Vector a4)
-> Vector (Vector a1)
-> Vector (Vector a2)
-> Vector (Vector a3)
-> Vector a4
-> Vector (Vector a4 -> Vector a4)
forall (c :: * -> *) a1 a2 a3 a4 b.
Skeleton c =>
(a1 -> a2 -> a3 -> a4 -> b) -> c a1 -> c a2 -> c a3 -> c a4 -> c b
S.farm41 (\v1 :: Vector a1
v1 v2 :: Vector a2
v2 v3 :: Vector a3
v3 s2 :: a4
s2 s1 :: Vector a4
s1 -> (a1 -> a2 -> a3 -> a4 -> a4 -> a4)
-> Vector a1
-> Vector a2
-> Vector a3
-> Vector a4
-> Vector (a4 -> a4)
forall (c :: * -> *) a1 a2 a3 a4 b.
Skeleton c =>
(a1 -> a2 -> a3 -> a4 -> b) -> c a1 -> c a2 -> c a3 -> c a4 -> c b
S.farm41 a1 -> a2 -> a3 -> a4 -> a4 -> a4
p Vector a1
v1 Vector a2
v2 Vector a3
v3 Vector a4
s1 Vector (a4 -> a4) -> a4 -> Vector a4
forall a. Vector (a -> a) -> a -> Vector a
=/= a4
s2)
    Vector (Vector a1)
vv1 Vector (Vector a2)
vv2 Vector (Vector a3)
vv3 Vector a4
vs2 Vector (Vector a4 -> Vector a4) -> Vector a4 -> Vector (Vector a4)
forall a. Vector (a -> a) -> a -> Vector a
=/= Vector a4
vs1
mesh4 :: (a1 -> a2 -> a3 -> a4 -> a5 -> a5 -> a5)
-> Vector (Vector a1)
-> Vector (Vector a2)
-> Vector (Vector a3)
-> Vector (Vector a4)
-> Vector a5
-> Vector a5
-> Vector (Vector a5)
mesh4 p :: a1 -> a2 -> a3 -> a4 -> a5 -> a5 -> a5
p vv1 :: Vector (Vector a1)
vv1 vv2 :: Vector (Vector a2)
vv2 vv3 :: Vector (Vector a3)
vv3 vv4 :: Vector (Vector a4)
vv4 vs1 :: Vector a5
vs1 vs2 :: Vector a5
vs2
  = (Vector a1
 -> Vector a2
 -> Vector a3
 -> Vector a4
 -> a5
 -> Vector a5
 -> Vector a5)
-> Vector (Vector a1)
-> Vector (Vector a2)
-> Vector (Vector a3)
-> Vector (Vector a4)
-> Vector a5
-> Vector (Vector a5 -> Vector a5)
forall (c :: * -> *) a1 a2 a3 a4 a5 b.
Skeleton c =>
(a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> c a1 -> c a2 -> c a3 -> c a4 -> c a5 -> c b
S.farm51 (\v1 :: Vector a1
v1 v2 :: Vector a2
v2 v3 :: Vector a3
v3 v4 :: Vector a4
v4 s2 :: a5
s2 s1 :: Vector a5
s1 -> (a1 -> a2 -> a3 -> a4 -> a5 -> a5 -> a5)
-> Vector a1
-> Vector a2
-> Vector a3
-> Vector a4
-> Vector a5
-> Vector (a5 -> a5)
forall (c :: * -> *) a1 a2 a3 a4 a5 b.
Skeleton c =>
(a1 -> a2 -> a3 -> a4 -> a5 -> b)
-> c a1 -> c a2 -> c a3 -> c a4 -> c a5 -> c b
S.farm51 a1 -> a2 -> a3 -> a4 -> a5 -> a5 -> a5
p Vector a1
v1 Vector a2
v2 Vector a3
v3 Vector a4
v4 Vector a5
s1 Vector (a5 -> a5) -> a5 -> Vector a5
forall a. Vector (a -> a) -> a -> Vector a
=/= a5
s2)
    Vector (Vector a1)
vv1 Vector (Vector a2)
vv2 Vector (Vector a3)
vv3 Vector (Vector a4)
vv4 Vector a5
vs2 Vector (Vector a5 -> Vector a5) -> Vector a5 -> Vector (Vector a5)
forall a. Vector (a -> a) -> a -> Vector a
=/= Vector a5
vs1

-------------
-- Queries --
-------------

-- | returns the number of elements in a value.
--
-- >>> length $ vector [1,2,3,4,5]
-- 5
--
-- <<fig/eqs-skel-vector-length.png>>
length :: Vector a -> p
length Null = 0
length v :: Vector a
v    = (p -> p -> p) -> Vector p -> p
forall (c :: * -> *) a. Skeleton c => (a -> a -> a) -> c a -> a
S.reduce p -> p -> p
forall a. Num a => a -> a -> a
(+) (Vector p -> p) -> (Vector a -> Vector p) -> Vector a -> p
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> p) -> Vector a -> Vector p
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 (\_ -> 1) (Vector a -> p) -> Vector a -> p
forall a b. (a -> b) -> a -> b
$ Vector a
v

-- | returns a vector with the indexes from another vector.
--
-- >>> index $ vector [1,1,1,1,1,1,1]
-- <1,2,3,4,5,6,7>
index :: Vector a2 -> Vector Int
index = (Int -> a2 -> Int) -> Vector Int -> Vector a2 -> Vector Int
forall (c :: * -> *) a1 a2 b.
Skeleton c =>
(a1 -> a2 -> b) -> c a1 -> c a2 -> c b
S.farm21 (\x :: Int
x _ -> Int
x) Vector Int
indexes


-- ----------------
-- -- Generators --
-- ----------------

-- | 'fanout' repeats an element. As a process network it distributes
-- the same value or signal to all the connected processes down the
-- line. Depending on the target platform and the refinement decisions
-- involved, it may be interpreted in the following implementations:
--
--  * global or shared memory in case of a massively parallel platform
--  (e.g. GPU)
--  * a (static) memory or cache location in memory-driven
--  architectures (e.g. CPU)
--  * a fanout in case of a HDL system
--  * a broadcast in case of a distributed system

-- For reasons of efficiency, this skeleton is defined recursively,
-- but can be proven that it is a catamorphism, because:
--
-- > first . fanout = id
fanout :: t -> Vector t
fanout x :: t
x = t
x t -> Vector t -> Vector t
forall a. a -> Vector a -> Vector a
:> t -> Vector t
fanout t
x

-- | 'fanoutn' is the same as 'fanout', but the length of the result
-- is also provided.
--
-- >>> fanoutn 5 1
-- <1,1,1,1,1>
fanoutn :: t -> a -> Vector a
fanoutn n :: t
n x :: a
x | t
n t -> t -> Bool
forall a. Ord a => a -> a -> Bool
<= 0    = Vector a
forall a. Vector a
Null
            | Bool
otherwise = a
x a -> Vector a -> Vector a
forall a. a -> Vector a -> Vector a
:> t -> a -> Vector a
fanoutn (t
nt -> t -> t
forall a. Num a => a -> a -> a
-1) a
x

-- | 'generate' creates a vector based on a kernel function. It is
-- just a restricted version of 'recur'.
--
-- >>> generate 5 (+1) 1
-- <6,5,4,3,2>
--
-- <<fig/eqs-skel-vector-generate.png>>
generate :: t -> (a -> a) -> a -> Vector a
generate n :: t
n f :: a -> a
f i :: a
i | t
n t -> t -> Bool
forall a. Ord a => a -> a -> Bool
<= 0    = Vector a
forall a. Vector a
Null
               | Bool
otherwise = t -> (a -> a) -> Vector (a -> a)
forall t a. (Ord t, Num t) => t -> a -> Vector a
fanoutn t
n a -> a
f Vector (a -> a) -> a -> Vector a
forall a. Vector (a -> a) -> a -> Vector a
=/= a
i

-- | 'iterate' is a version of 'generate' which keeps the initial
-- element as well. It is a restricted version of @recuri@.
--
-- >>> iterate 5 (+1) 1
-- <5,4,3,2,1>
iterate :: t -> (a -> a) -> a -> Vector a
iterate n :: t
n f :: a -> a
f i :: a
i | t
n t -> t -> Bool
forall a. Ord a => a -> a -> Bool
<= 0     = Vector a
forall a. Vector a
Null
              | Bool
otherwise = t -> (a -> a) -> Vector (a -> a)
forall t a. (Ord t, Num t) => t -> a -> Vector a
fanoutn (t
nt -> t -> t
forall a. Num a => a -> a -> a
-1) a -> a
f Vector (a -> a) -> a -> Vector a
forall a. Vector (a -> a) -> a -> Vector a
`recuri` a
i


---------------
-- Selectors --
---------------

first' :: Vector (Vector a) -> Vector a
first' Null = Vector a
forall a. Vector a
Null
first' xs :: Vector (Vector a)
xs   = Vector (Vector a) -> Vector a
forall (c :: * -> *) a. Skeleton c => c a -> a
S.first Vector (Vector a)
xs
last' :: Vector (Vector a) -> Vector a
last'  Null = Vector a
forall a. Vector a
Null
last'  xs :: Vector (Vector a)
xs   = Vector (Vector a) -> Vector a
forall (c :: * -> *) a. Skeleton c => c a -> a
S.last Vector (Vector a)
xs
init' :: Vector a -> Vector a
init'  Null = Vector a
forall a. Vector a
Null
init'  xs :: Vector a
xs   = Vector a -> Vector a
forall a. Vector a -> Vector a
init Vector a
xs
tail' :: Vector a -> Vector a
tail'  Null = Vector a
forall a. Vector a
Null
tail'  xs :: Vector a
xs   = Vector a -> Vector a
forall a. Vector a -> Vector a
tail Vector a
xs

-- | Instance of 'ForSyDe.Atom.Skel.first'
--
-- >>> S.first $ vector [1,2,3,4,5]
-- 1
first :: Vector a -> a
first :: Vector a -> a
first = Vector a -> a
forall (c :: * -> *) a. Skeleton c => c a -> a
S.first

-- | Instance of 'ForSyDe.Atom.Skel.last'
--
-- >>> S.last $ vector [1,2,3,4,5]
-- 5
last  :: Vector a -> a
last :: Vector a -> a
last  = Vector a -> a
forall (c :: * -> *) a. Skeleton c => c a -> a
S.last

-- | Returns the tail of a vector.
--
-- >>> tail $ vector [1,2,3,4,5]
-- <2,3,4,5>
--
-- <<fig/eqs-skel-vector-tail.png>>
tail :: Vector a -> Vector a
tail Null   = [Char] -> Vector a
forall a. HasCallStack => [Char] -> a
error "[Skel.Vector] cannot return tail of empty vector"
tail (x :: a
x:>xs :: Vector a
xs)= Vector a
xs
-- tail     = (<@!> 2) . tails

-- | Returns the initial segment of a vector.
--
-- >>> init $ vector [1,2,3,4,5]
-- <1,2,3,4>
--
-- <<fig/eqs-skel-vector-init.png>>
init :: Vector a -> Vector a
init Null      = [Char] -> Vector a
forall a. HasCallStack => [Char] -> a
error "init: Vector is empty"
init (_:>Null) = Vector a
forall a. Vector a
Null
init (v :: a
v:>vs :: Vector a
vs)   = a
v a -> Vector a -> Vector a
forall a. a -> Vector a -> Vector a
:> Vector a -> Vector a
init Vector a
vs
-- init      = (<@!> 2) . reverse . inits

-- | concatenates a vector of vectors.
--
-- >>> concat $ vector [vector[1,2,3,4], vector[5,6,7]]
-- <1,2,3,4,5,6,7>
--
-- <<fig/eqs-skel-vector-concat.png>>
concat :: Vector (Vector a) -> Vector a
concat Null = Vector a
forall a. Vector a
Null
concat v :: Vector (Vector a)
v    = Vector a -> Vector a -> Vector a
forall a. Vector a -> Vector a -> Vector a
(<++>) (Vector a -> Vector a -> Vector a) -> Vector (Vector a) -> Vector a
forall (c :: * -> *) a. Skeleton c => (a -> a -> a) -> c a -> a
=\= Vector (Vector a)
v

-- | reverses the elements in a vector.
--
-- >>> reverse $ vector [1,2,3,4,5]
-- <5,4,3,2,1>
--
-- <<fig/eqs-skel-vector-reverse.png>>
--
-- <<fig/skel-vector-comm-reverse.png>>
-- <<fig/skel-vector-comm-reverse-net.png>>
reverse :: Vector a -> Vector a
reverse Null = Vector a
forall a. Vector a
Null
reverse v :: Vector a
v    = (Vector a -> Vector a -> Vector a) -> Vector (Vector a) -> Vector a
forall (c :: * -> *) a. Skeleton c => (a -> a -> a) -> c a -> a
S.reduce (\x :: Vector a
x y :: Vector a
y -> Vector a
y Vector a -> Vector a -> Vector a
forall a. Vector a -> Vector a -> Vector a
<++> Vector a
x) (Vector (Vector a) -> Vector a)
-> (Vector a -> Vector (Vector a)) -> Vector a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Vector a) -> Vector a -> Vector (Vector a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 a -> Vector a
forall a. a -> Vector a
unit (Vector a -> Vector a) -> Vector a -> Vector a
forall a b. (a -> b) -> a -> b
$ Vector a
v

-- | creates a vector of all the initial segments in a vector.
--
-- >>> inits $ vector [1,2,3,4,5]
-- <<1>,<1,2>,<1,2,3>,<1,2,3,4>,<1,2,3,4,5>>
--
-- <<fig/eqs-skel-vector-inits.png>>
--
-- <<fig/skel-vector-comm-inits.png>>
-- <<fig/skel-vector-comm-inits-net.png>>
inits :: Vector a -> Vector (Vector a)
inits Null = [Char] -> Vector (Vector a)
forall a. HasCallStack => [Char] -> a
error "inits: null vector"
inits v :: Vector a
v    = (Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a))
-> Vector (Vector (Vector a)) -> Vector (Vector a)
forall (c :: * -> *) a. Skeleton c => (a -> a -> a) -> c a -> a
S.reduce Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a)
forall a.
Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a)
sel (Vector (Vector (Vector a)) -> Vector (Vector a))
-> (Vector a -> Vector (Vector (Vector a)))
-> Vector a
-> Vector (Vector a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Vector (Vector a)) -> Vector a -> Vector (Vector (Vector a))
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 (Vector a -> Vector (Vector a)
forall a. a -> Vector a
unit (Vector a -> Vector (Vector a))
-> (a -> Vector a) -> a -> Vector (Vector a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Vector a
forall a. a -> Vector a
unit) (Vector a -> Vector (Vector a)) -> Vector a -> Vector (Vector a)
forall a b. (a -> b) -> a -> b
$ Vector a
v
  where sel :: Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a)
sel x :: Vector (Vector a)
x y :: Vector (Vector a)
y = Vector (Vector a)
x Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a)
forall a. Vector a -> Vector a -> Vector a
<++> (Vector a -> Vector a) -> Vector (Vector a) -> Vector (Vector a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 (Vector (Vector a) -> Vector a
forall (c :: * -> *) a. Skeleton c => c a -> a
S.last  Vector (Vector a)
x Vector a -> Vector a -> Vector a
forall a. Vector a -> Vector a -> Vector a
<++>) Vector (Vector a)
y

-- | creates a vector of all the final segments in a vector.
--
-- >>> tails $ vector [1,2,3,4,5]
-- <<1,2,3,4,5>,<2,3,4,5>,<3,4,5>,<4,5>,<5>>
--
-- <<fig/eqs-skel-vector-tails.png>>
--
-- <<fig/skel-vector-comm-tails.png>>
-- <<fig/skel-vector-comm-tails-net.png>>
tails :: Vector a -> Vector (Vector a)
tails Null = [Char] -> Vector (Vector a)
forall a. HasCallStack => [Char] -> a
error "inits: null vector"
tails v :: Vector a
v    = (Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a))
-> Vector (Vector (Vector a)) -> Vector (Vector a)
forall (c :: * -> *) a. Skeleton c => (a -> a -> a) -> c a -> a
S.reduce Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a)
forall a.
Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a)
sel (Vector (Vector (Vector a)) -> Vector (Vector a))
-> (Vector a -> Vector (Vector (Vector a)))
-> Vector a
-> Vector (Vector a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Vector (Vector a)) -> Vector a -> Vector (Vector (Vector a))
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 (Vector a -> Vector (Vector a)
forall a. a -> Vector a
unit (Vector a -> Vector (Vector a))
-> (a -> Vector a) -> a -> Vector (Vector a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Vector a
forall a. a -> Vector a
unit) (Vector a -> Vector (Vector a)) -> Vector a -> Vector (Vector a)
forall a b. (a -> b) -> a -> b
$ Vector a
v
  where sel :: Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a)
sel x :: Vector (Vector a)
x y :: Vector (Vector a)
y = (Vector a -> Vector a) -> Vector (Vector a) -> Vector (Vector a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 (Vector a -> Vector a -> Vector a
forall a. Vector a -> Vector a -> Vector a
<++> Vector (Vector a) -> Vector a
forall (c :: * -> *) a. Skeleton c => c a -> a
S.first Vector (Vector a)
y) Vector (Vector a)
x Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a)
forall a. Vector a -> Vector a -> Vector a
<++> Vector (Vector a)
y
    
-- | returns the /n/-th element in a vector, or @Nothing@ if /n > l/.
--
-- >>> get 3 $ vector [1,2,3,4,5]
-- Just 3
--
-- <<fig/eqs-skel-vector-get.png>>
get :: Int -> Vector a -> Maybe a
get _ Null = Maybe a
forall a. Maybe a
Nothing
get n :: Int
n v :: Vector a
v    = (Int -> Maybe a -> Maybe a -> Maybe a)
-> Maybe a -> Vector Int -> Vector (Maybe a) -> Maybe a
forall (c :: * -> *) a1 a2 a.
Skeleton c =>
(a1 -> a2 -> a -> a) -> a -> c a1 -> c a2 -> a
reducei1 Int -> Maybe a -> Maybe a -> Maybe a
forall p. Int -> p -> p -> p
sel Maybe a
forall a. Maybe a
Nothing Vector Int
indexes (Vector (Maybe a) -> Maybe a)
-> (Vector a -> Vector (Maybe a)) -> Vector a -> Maybe a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Maybe a) -> Vector a -> Vector (Maybe a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 a -> Maybe a
forall a. a -> Maybe a
Just (Vector a -> Maybe a) -> Vector a -> Maybe a
forall a b. (a -> b) -> a -> b
$ Vector a
v
  where sel :: Int -> p -> p -> p
sel i :: Int
i x :: p
x y :: p
y = if Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
n then p
x else p
y

-- | takes the first /n/ elements of a vector.
--
-- >>> take 5 $ vector [1,2,3,4,5,6,7,8,9]
-- <1,2,3,4,5>
--
-- <<fig/eqs-skel-vector-take.png>>
take :: Int -> Vector a -> Vector a
take _ Null = Vector a
forall a. Vector a
Null
take n :: Int
n v :: Vector a
v    = (Int -> Vector a -> Vector a -> Vector a)
-> Vector a -> Vector Int -> Vector (Vector a) -> Vector a
forall (c :: * -> *) a1 a2 a.
Skeleton c =>
(a1 -> a2 -> a -> a) -> a -> c a1 -> c a2 -> a
reducei1 Int -> Vector a -> Vector a -> Vector a
forall a. Int -> Vector a -> Vector a -> Vector a
sel Vector a
forall a. Vector a
Null Vector Int
indexes (Vector (Vector a) -> Vector a)
-> (Vector a -> Vector (Vector a)) -> Vector a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Vector a) -> Vector a -> Vector (Vector a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 a -> Vector a
forall a. a -> Vector a
unit (Vector a -> Vector a) -> Vector a -> Vector a
forall a b. (a -> b) -> a -> b
$ Vector a
v
  where sel :: Int -> Vector a -> Vector a -> Vector a
sel i :: Int
i x :: Vector a
x y :: Vector a
y = if Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< Int
n then Vector a
x Vector a -> Vector a -> Vector a
forall a. Vector a -> Vector a -> Vector a
<++> Vector a
y else Vector a
x

-- | drops the first /n/ elements of a vector.
--
-- >>> drop 5 $ vector [1,2,3,4,5,6,7,8,9]
-- <6,7,8,9>
--
-- <<fig/eqs-skel-vector-drop.png>>
drop :: Int -> Vector a -> Vector a
drop _ Null = Vector a
forall a. Vector a
Null
drop n :: Int
n v :: Vector a
v    = (Int -> Vector a -> Vector a -> Vector a)
-> Vector a -> Vector Int -> Vector (Vector a) -> Vector a
forall (c :: * -> *) a1 a2 a.
Skeleton c =>
(a1 -> a2 -> a -> a) -> a -> c a1 -> c a2 -> a
reducei1 Int -> Vector a -> Vector a -> Vector a
forall a. Int -> Vector a -> Vector a -> Vector a
sel Vector a
forall a. Vector a
Null Vector Int
indexes (Vector (Vector a) -> Vector a)
-> (Vector a -> Vector (Vector a)) -> Vector a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Vector a) -> Vector a -> Vector (Vector a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 a -> Vector a
forall a. a -> Vector a
unit (Vector a -> Vector a) -> Vector a -> Vector a
forall a b. (a -> b) -> a -> b
$ Vector a
v
  where sel :: Int -> Vector a -> Vector a -> Vector a
sel i :: Int
i x :: Vector a
x y :: Vector a
y = if Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> Int
n then Vector a
x Vector a -> Vector a -> Vector a
forall a. Vector a -> Vector a -> Vector a
<++> Vector a
y else Vector a
y

-- | returns a vector containing only the elements of another vector
-- whose index satisfies a predicate.
--
-- >>> filterIdx (\x -> x `mod` 3 == 0) $ vector [0,1,2,3,4,5,6,7,8,9]
-- <2,5,8>
--
-- <<fig/eqs-skel-vector-filteridx.png>>
--
-- <<fig/skel-vector-comm-filteridx.png>>
-- <<fig/skel-vector-comm-filteridx-net.png>>
filterIdx :: (Int -> Bool) -> Vector a -> Vector a
filterIdx _ Null = Vector a
forall a. Vector a
Null
filterIdx f :: Int -> Bool
f v :: Vector a
v    = (Int -> Vector a -> Vector a -> Vector a)
-> Vector a -> Vector Int -> Vector (Vector a) -> Vector a
forall (c :: * -> *) a1 a2 a.
Skeleton c =>
(a1 -> a2 -> a -> a) -> a -> c a1 -> c a2 -> a
reducei1 Int -> Vector a -> Vector a -> Vector a
forall a. Int -> Vector a -> Vector a -> Vector a
sel Vector a
forall a. Vector a
Null Vector Int
indexes (Vector (Vector a) -> Vector a)
-> (Vector a -> Vector (Vector a)) -> Vector a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Vector a) -> Vector a -> Vector (Vector a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 a -> Vector a
forall a. a -> Vector a
unit (Vector a -> Vector a) -> Vector a -> Vector a
forall a b. (a -> b) -> a -> b
$ Vector a
v
  where sel :: Int -> Vector a -> Vector a -> Vector a
sel i :: Int
i x :: Vector a
x y :: Vector a
y = if Int -> Bool
f Int
i   then Vector a
x Vector a -> Vector a -> Vector a
forall a. Vector a -> Vector a -> Vector a
<++> Vector a
y else Vector a
y
    
-- | replaces the /n/-th element in a vector with another.
--
-- >>> replace 5 15 $ vector [1,2,3,4,5,6,7,8,9]
-- <1,2,3,4,15,6,7,8,9>
--
-- <<fig/eqs-skel-vector-replace.png>>
--
-- <<fig/skel-vector-comm-replace.png>>
-- <<fig/skel-vector-comm-replace-net.png>>
replace :: Int -> a -> Vector a -> Vector a
replace _ _ Null = Vector a
forall a. Vector a
Null
replace n :: Int
n r :: a
r v :: Vector a
v    = (Int -> Vector a -> Vector a -> Vector a)
-> Vector a -> Vector Int -> Vector (Vector a) -> Vector a
forall (c :: * -> *) a1 a2 a.
Skeleton c =>
(a1 -> a2 -> a -> a) -> a -> c a1 -> c a2 -> a
reducei1 Int -> Vector a -> Vector a -> Vector a
sel Vector a
forall a. Vector a
Null Vector Int
indexes (Vector (Vector a) -> Vector a)
-> (Vector a -> Vector (Vector a)) -> Vector a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Vector a) -> Vector a -> Vector (Vector a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 a -> Vector a
forall a. a -> Vector a
unit (Vector a -> Vector a) -> Vector a -> Vector a
forall a b. (a -> b) -> a -> b
$ Vector a
v
  where sel :: Int -> Vector a -> Vector a -> Vector a
sel i :: Int
i x :: Vector a
x y :: Vector a
y = if Int
i Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== Int
n then a
r a -> Vector a -> Vector a
forall a. a -> Vector a -> Vector a
:> Vector a
y else Vector a
x Vector a -> Vector a -> Vector a
forall a. Vector a -> Vector a -> Vector a
<++> Vector a
y

-- | takes the first elements in a vector until the first element that
-- does not fulfill a predicate.
--
-- >>> takeWhile (<5) $ vector [1,2,3,4,5,6,7,8,9]
-- <1,2,3,4>
--
-- <<fig/eqs-skel-vector-takewhile.png>>
takeWhile :: (a -> Bool) -> Vector a -> Vector a
takeWhile _ Null = Vector a
forall a. Vector a
Null
takeWhile f :: a -> Bool
f v :: Vector a
v    = Vector (Vector a) -> Vector a
forall a. Vector (Vector a) -> Vector a
concat (Vector (Vector a) -> Vector a)
-> (Vector a -> Vector (Vector a)) -> Vector a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a))
-> Vector (Vector (Vector a)) -> Vector (Vector a)
forall (c :: * -> *) a. Skeleton c => (a -> a -> a) -> c a -> a
S.reduce Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a)
sel (Vector (Vector (Vector a)) -> Vector (Vector a))
-> (Vector a -> Vector (Vector (Vector a)))
-> Vector a
-> Vector (Vector a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Vector (Vector a)) -> Vector a -> Vector (Vector (Vector a))
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 (Vector a -> Vector (Vector a)
forall a. a -> Vector a
unit (Vector a -> Vector (Vector a))
-> (a -> Vector a) -> a -> Vector (Vector a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Vector a
forall a. a -> Vector a
unit) (Vector a -> Vector a) -> Vector a -> Vector a
forall a b. (a -> b) -> a -> b
$ Vector a
v
  where sel :: Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a)
sel x :: Vector (Vector a)
x y :: Vector (Vector a)
y = if Vector (Vector a) -> Vector (Vector a) -> Bool
forall (c :: * -> *) (c :: * -> *) (c :: * -> *) a.
(Skeleton c, Skeleton c, Skeleton c) =>
c (Vector a) -> c (c a) -> Bool
end Vector (Vector a)
x Vector (Vector a)
y then Vector (Vector a)
x Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a)
forall a. Vector a -> Vector a -> Vector a
<++> Vector (Vector a)
y else Vector (Vector a)
x
        end :: c (Vector a) -> c (c a) -> Bool
end x :: c (Vector a)
x y :: c (c a)
y = (a -> Bool
f (a -> Bool) -> (c (c a) -> a) -> c (c a) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. c a -> a
forall (c :: * -> *) a. Skeleton c => c a -> a
S.first (c a -> a) -> (c (c a) -> c a) -> c (c a) -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. c (c a) -> c a
forall (c :: * -> *) a. Skeleton c => c a -> a
S.first) c (c a)
y Bool -> Bool -> Bool
&&
                  (Bool -> Bool
not (Bool -> Bool) -> (c (Vector a) -> Bool) -> c (Vector a) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Vector a -> Bool
forall a. Vector a -> Bool
isNull (Vector a -> Bool)
-> (c (Vector a) -> Vector a) -> c (Vector a) -> Bool
forall b c a. (b -> c) -> (a -> b) -> a -> c
. c (Vector a) -> Vector a
forall (c :: * -> *) a. Skeleton c => c a -> a
S.last) c (Vector a)
x

-- | does a stride-selection on a vector.
--
-- >>> stride 1 3 $ vector [1,2,3,4,5,6,7,8,9]
-- <1,4,7>
--
-- <<fig/eqs-skel-vector-stride.png>>
--
-- <<fig/skel-vector-comm-inits.png>>
-- <<fig/skel-vector-comm-inits-net.png>>
stride :: Int -- ^ first index
       -> Int -- ^ stride length
       -> Vector a -> Vector a
stride :: Int -> Int -> Vector a -> Vector a
stride _ _ Null = Vector a
forall a. Vector a
Null
stride f :: Int
f s :: Int
s v :: Vector a
v = (Int -> Vector a -> Vector a -> Vector a)
-> Vector a -> Vector Int -> Vector (Vector a) -> Vector a
forall (c :: * -> *) a1 a2 a.
Skeleton c =>
(a1 -> a2 -> a -> a) -> a -> c a1 -> c a2 -> a
reducei1 Int -> Vector a -> Vector a -> Vector a
forall a. Int -> Vector a -> Vector a -> Vector a
sel Vector a
forall a. Vector a
Null Vector Int
indexes (Vector (Vector a) -> Vector a)
-> (Vector a -> Vector (Vector a)) -> Vector a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Vector a) -> Vector a -> Vector (Vector a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 a -> Vector a
forall a. a -> Vector a
unit (Vector a -> Vector a) -> Vector a -> Vector a
forall a b. (a -> b) -> a -> b
$ Vector a
v
  where sel :: Int -> Vector a -> Vector a -> Vector a
sel i :: Int
i x :: Vector a
x y :: Vector a
y | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
>= Int
f Bool -> Bool -> Bool
&& (Int
iInt -> Int -> Int
forall a. Num a => a -> a -> a
-Int
f) Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
s Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0 = Vector a
x Vector a -> Vector a -> Vector a
forall a. Vector a -> Vector a -> Vector a
<++> Vector a
y
                  | Bool
otherwise                    = Vector a
y
                 
-- | groups a vector into sub-vectors of /n/ elements.
--
-- >>> group 3 $ vector [1,2,3,4,5,6,7,8]
-- <<1,2,3>,<4,5,6>,<7,8>>
--
-- <<fig/eqs-skel-vector-group.png>>
--
-- <<fig/skel-vector-comm-group.png>>
-- <<fig/skel-vector-comm-group-net.png>>
group :: Int -> Vector a -> Vector (Vector a)
group _ Null = Vector a -> Vector (Vector a)
forall a. a -> Vector a
unit Vector a
forall a. Vector a
Null
group n :: Int
n v :: Vector a
v = (Int
 -> Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a))
-> Vector (Vector a)
-> Vector Int
-> Vector (Vector (Vector a))
-> Vector (Vector a)
forall (c :: * -> *) a1 a2 a.
Skeleton c =>
(a1 -> a2 -> a -> a) -> a -> c a1 -> c a2 -> a
reducei1 Int -> Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a)
forall a.
Int -> Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a)
sel Vector (Vector a)
forall a. Vector a
Null Vector Int
indexes (Vector (Vector (Vector a)) -> Vector (Vector a))
-> (Vector a -> Vector (Vector (Vector a)))
-> Vector a
-> Vector (Vector a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Vector (Vector a)) -> Vector a -> Vector (Vector (Vector a))
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 (Vector a -> Vector (Vector a)
forall a. a -> Vector a
unit (Vector a -> Vector (Vector a))
-> (a -> Vector a) -> a -> Vector (Vector a)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. a -> Vector a
forall a. a -> Vector a
unit) (Vector a -> Vector (Vector a)) -> Vector a -> Vector (Vector a)
forall a b. (a -> b) -> a -> b
$ Vector a
v
  where sel :: Int -> Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a)
sel i :: Int
i x :: Vector (Vector a)
x y :: Vector (Vector a)
y
          | Int
i Int -> Int -> Int
forall a. Integral a => a -> a -> a
`mod` Int
n Int -> Int -> Bool
forall a. Eq a => a -> a -> Bool
== 0 = Vector (Vector a)
x Vector (Vector a) -> Vector (Vector a) -> Vector (Vector a)
forall a. Vector a -> Vector a -> Vector a
<++> Vector (Vector a)
y
          | Bool
otherwise      = (Vector (Vector a) -> Vector a
forall (c :: * -> *) a. Skeleton c => c a -> a
S.first Vector (Vector a)
x Vector a -> Vector a -> Vector a
forall a. Vector a -> Vector a -> Vector a
<++> Vector (Vector a) -> Vector a
forall a. Vector (Vector a) -> Vector a
first' Vector (Vector a)
y) Vector a -> Vector (Vector a) -> Vector (Vector a)
forall a. a -> Vector a -> Vector a
:> Vector (Vector a) -> Vector (Vector a)
forall a. Vector a -> Vector a
tail' Vector (Vector a)
y

-- | right-shifts a vector with an element.
--
-- >>> vector [1,2,3,4] `shiftr` 8
-- <8,1,2,3>
--
-- <<fig/skel-vector-comm-shiftr.png>>
-- <<fig/skel-vector-comm-shiftr-net.png>>
shiftr :: Vector a -> a -> Vector a
shiftr vs :: Vector a
vs v :: a
v = a
v a -> Vector a -> Vector a
forall a. a -> Vector a -> Vector a
:> Vector a -> Vector a
forall a. Vector a -> Vector a
init Vector a
vs

-- | left-shifts a vector with an element.
--
-- >>> vector [1,2,3,4] `shiftl` 8
-- <2,3,4,8>
--
-- <<fig/skel-vector-comm-shiftl.png>>
-- <<fig/skel-vector-comm-shiftl-net.png>>
shiftl :: Vector a -> a -> Vector a
shiftl vs :: Vector a
vs v :: a
v = Vector a -> Vector a
forall a. Vector a -> Vector a
tail Vector a
vs Vector a -> a -> Vector a
forall a. Vector a -> a -> Vector a
<: a
v

-- | rotates a vector to the left.
--
-- >>> rotl $ vector [1,2,3,4]
-- <2,3,4,1>
--
-- <<fig/skel-vector-comm-rotl.png>>
-- <<fig/skel-vector-comm-rotl-net.png>>
rotl :: Vector a -> Vector a
rotl   Null = Vector a
forall a. Vector a
Null
rotl   vs :: Vector a
vs   = Vector a -> Vector a
forall a. Vector a -> Vector a
tail Vector a
vs Vector a -> a -> Vector a
forall a. Vector a -> a -> Vector a
<: Vector a -> a
forall (c :: * -> *) a. Skeleton c => c a -> a
S.first Vector a
vs

-- | rotates a vector to the right.
--
-- >>> rotr $ vector [1,2,3,4]
-- <4,1,2,3>
--
-- <<fig/skel-vector-comm-rotr.png>>
-- <<fig/skel-vector-comm-rotr-net.png>>
rotr :: Vector a -> Vector a
rotr   Null = Vector a
forall a. Vector a
Null
rotr   vs :: Vector a
vs   = Vector a -> a
forall (c :: * -> *) a. Skeleton c => c a -> a
S.last Vector a
vs a -> Vector a -> Vector a
forall a. a -> Vector a -> Vector a
:> Vector a -> Vector a
forall a. Vector a -> Vector a
init Vector a
vs

-- | rotates a vector to the left or to the right depending on the index:
--
-- * @(> 0)@ : rotates the vector right with the corresponding number
-- of positions.
-- 
-- * @(= 0)@ : does not modify the vector.
-- 
-- * @(< 0)@ : rotates the vector left with the corresponding number
-- of positions.
rotate :: Int -> Vector a -> Vector a
rotate :: Int -> Vector a -> Vector a
rotate i :: Int
i | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
< 0 = (Vector a -> Vector a) -> Int -> Vector a -> Vector a
forall t a. (Ord t, Num t) => (a -> a) -> t -> a -> a
doPipe Vector a -> Vector a
forall a. Vector a -> Vector a
rotl (-Int
i)
         | Int
i Int -> Int -> Bool
forall a. Ord a => a -> a -> Bool
> 0 = (Vector a -> Vector a) -> Int -> Vector a -> Vector a
forall t a. (Ord t, Num t) => (a -> a) -> t -> a -> a
doPipe Vector a -> Vector a
forall a. Vector a -> Vector a
rotr Int
i
         | Bool
otherwise = Vector a -> Vector a
forall a. a -> a
id
  where doPipe :: (a -> a) -> t -> a -> a
doPipe f :: a -> a
f i :: t
i = Vector (a -> a) -> a -> a
forall a. Vector (a -> a) -> a -> a
ForSyDe.Atom.Skel.Vector.Lib.pipe (t -> (a -> a) -> Vector (a -> a)
forall t a. (Ord t, Num t) => t -> a -> Vector a
fanoutn t
i a -> a
f)

-- | the same as 'get' but with flipped arguments.
v :: Vector a
v <@ :: Vector a -> Int -> Maybe a
<@  ix :: Int
ix = Int -> Vector a -> Maybe a
forall a. Int -> Vector a -> Maybe a
get Int
ix Vector a
v

-- | unsafe version of '<@'. Throws an exception if /n > l/.
v :: Vector p
v <@! :: Vector p -> Int -> p
<@! ix :: Int
ix | Maybe p -> Bool
forall a. Maybe a -> Bool
isNothing Maybe p
e = [Char] -> p
forall a. HasCallStack => [Char] -> a
error "get!: index out of bounds"
         | Bool
otherwise   = Maybe p -> p
forall a. HasCallStack => Maybe a -> a
fromJust Maybe p
e
  where e :: Maybe p
e = Int -> Vector p -> Maybe p
forall a. Int -> Vector a -> Maybe a
get Int
ix Vector p
v

-- | <<fig/eqs-skel-vector-odds.png>>
odds :: Vector a -> Vector a
odds      = (Int -> Bool) -> Vector a -> Vector a
forall a. (Int -> Bool) -> Vector a -> Vector a
filterIdx Int -> Bool
forall a. Integral a => a -> Bool
odd

-- | <<fig/eqs-skel-vector-evens.png>>
evens :: Vector a -> Vector a
evens     = (Int -> Bool) -> Vector a -> Vector a
forall a. (Int -> Bool) -> Vector a -> Vector a
filterIdx Int -> Bool
forall a. Integral a => a -> Bool
even

-- | selects the elements in a vector at the incexes contained by another vector.
--
-- The following versions of this skeleton are available, the number
-- suggesting how many nested vectors it is operating upon: @gather[1-5]@
--
-- >>> let ix = vector [vector [1,3,4], vector [3,5,1], vector [5,8,9]]
-- >>> let v = vector [11,12,13,14,15]
-- >>> gather2 ix v
-- <<Just 11,Just 13,Just 14>,<Just 13,Just 15,Just 11>,<Just 15,Nothing,Nothing>>
--
-- <<fig/eqs-skel-vector-gather.png>>
--
-- <<fig/skel-vector-comm-gather.png>>
-- <<fig/skel-vector-comm-gather-net.png>>
gather1 :: Vector Int -- ^ vector of indexes
       -> Vector a       -- ^ input vector
       -> Vector (Maybe a)
gather1 :: Vector Int -> Vector a -> Vector (Maybe a)
gather1 ix :: Vector Int
ix v :: Vector a
v     =  (Int -> Maybe a) -> Vector Int -> Vector (Maybe a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11                       (Vector a
v Vector a -> Int -> Maybe a
forall a. Vector a -> Int -> Maybe a
<@) Vector Int
ix
gather2 :: c (c Int) -> Vector a -> c (c (Maybe a))
gather2 ix :: c (c Int)
ix vv :: Vector a
vv    = ((c Int -> c (Maybe a)) -> c (c Int) -> c (c (Maybe a))
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
(=.=)((c Int -> c (Maybe a)) -> c (c Int) -> c (c (Maybe a)))
-> ((Int -> Maybe a) -> c Int -> c (Maybe a))
-> (Int -> Maybe a)
-> c (c Int)
-> c (c (Maybe a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Int -> Maybe a) -> c Int -> c (Maybe a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
(=.=))                   (Vector a
vv Vector a -> Int -> Maybe a
forall a. Vector a -> Int -> Maybe a
<@) c (c Int)
ix
gather3 :: c (c (c Int)) -> Vector a -> c (c (c (Maybe a)))
gather3 ix :: c (c (c Int))
ix vvv :: Vector a
vvv   = ((c (c Int) -> c (c (Maybe a)))
-> c (c (c Int)) -> c (c (c (Maybe a)))
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
(=.=)((c (c Int) -> c (c (Maybe a)))
 -> c (c (c Int)) -> c (c (c (Maybe a))))
-> ((Int -> Maybe a) -> c (c Int) -> c (c (Maybe a)))
-> (Int -> Maybe a)
-> c (c (c Int))
-> c (c (c (Maybe a)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(c Int -> c (Maybe a)) -> c (c Int) -> c (c (Maybe a))
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
(=.=)((c Int -> c (Maybe a)) -> c (c Int) -> c (c (Maybe a)))
-> ((Int -> Maybe a) -> c Int -> c (Maybe a))
-> (Int -> Maybe a)
-> c (c Int)
-> c (c (Maybe a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Int -> Maybe a) -> c Int -> c (Maybe a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
(=.=))             (Vector a
vvv Vector a -> Int -> Maybe a
forall a. Vector a -> Int -> Maybe a
<@) c (c (c Int))
ix
gather4 :: c (c (c (c Int))) -> Vector a -> c (c (c (c (Maybe a))))
gather4 ix :: c (c (c (c Int)))
ix vvvv :: Vector a
vvvv  = ((c (c (c Int)) -> c (c (c (Maybe a))))
-> c (c (c (c Int))) -> c (c (c (c (Maybe a))))
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
(=.=)((c (c (c Int)) -> c (c (c (Maybe a))))
 -> c (c (c (c Int))) -> c (c (c (c (Maybe a)))))
-> ((Int -> Maybe a) -> c (c (c Int)) -> c (c (c (Maybe a))))
-> (Int -> Maybe a)
-> c (c (c (c Int)))
-> c (c (c (c (Maybe a))))
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(c (c Int) -> c (c (Maybe a)))
-> c (c (c Int)) -> c (c (c (Maybe a)))
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
(=.=)((c (c Int) -> c (c (Maybe a)))
 -> c (c (c Int)) -> c (c (c (Maybe a))))
-> ((Int -> Maybe a) -> c (c Int) -> c (c (Maybe a)))
-> (Int -> Maybe a)
-> c (c (c Int))
-> c (c (c (Maybe a)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(c Int -> c (Maybe a)) -> c (c Int) -> c (c (Maybe a))
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
(=.=)((c Int -> c (Maybe a)) -> c (c Int) -> c (c (Maybe a)))
-> ((Int -> Maybe a) -> c Int -> c (Maybe a))
-> (Int -> Maybe a)
-> c (c Int)
-> c (c (Maybe a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Int -> Maybe a) -> c Int -> c (Maybe a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
(=.=))       (Vector a
vvvv Vector a -> Int -> Maybe a
forall a. Vector a -> Int -> Maybe a
<@) c (c (c (c Int)))
ix
gather5 :: c (c (c (c (c Int)))) -> Vector a -> c (c (c (c (c (Maybe a)))))
gather5 ix :: c (c (c (c (c Int))))
ix vvvvv :: Vector a
vvvvv = ((c (c (c (c Int))) -> c (c (c (c (Maybe a)))))
-> c (c (c (c (c Int)))) -> c (c (c (c (c (Maybe a)))))
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
(=.=)((c (c (c (c Int))) -> c (c (c (c (Maybe a)))))
 -> c (c (c (c (c Int)))) -> c (c (c (c (c (Maybe a))))))
-> ((Int -> Maybe a)
    -> c (c (c (c Int))) -> c (c (c (c (Maybe a)))))
-> (Int -> Maybe a)
-> c (c (c (c (c Int))))
-> c (c (c (c (c (Maybe a)))))
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(c (c (c Int)) -> c (c (c (Maybe a))))
-> c (c (c (c Int))) -> c (c (c (c (Maybe a))))
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
(=.=)((c (c (c Int)) -> c (c (c (Maybe a))))
 -> c (c (c (c Int))) -> c (c (c (c (Maybe a)))))
-> ((Int -> Maybe a) -> c (c (c Int)) -> c (c (c (Maybe a))))
-> (Int -> Maybe a)
-> c (c (c (c Int)))
-> c (c (c (c (Maybe a))))
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(c (c Int) -> c (c (Maybe a)))
-> c (c (c Int)) -> c (c (c (Maybe a)))
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
(=.=)((c (c Int) -> c (c (Maybe a)))
 -> c (c (c Int)) -> c (c (c (Maybe a))))
-> ((Int -> Maybe a) -> c (c Int) -> c (c (Maybe a)))
-> (Int -> Maybe a)
-> c (c (c Int))
-> c (c (c (Maybe a)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(c Int -> c (Maybe a)) -> c (c Int) -> c (c (Maybe a))
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
(=.=)((c Int -> c (Maybe a)) -> c (c Int) -> c (c (Maybe a)))
-> ((Int -> Maybe a) -> c Int -> c (Maybe a))
-> (Int -> Maybe a)
-> c (c Int)
-> c (c (Maybe a))
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Int -> Maybe a) -> c Int -> c (Maybe a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
(=.=)) (Vector a
vvvvv Vector a -> Int -> Maybe a
forall a. Vector a -> Int -> Maybe a
<@) c (c (c (c (c Int))))
ix

-- | the same as 'gather1' but with flipped arguments
--
-- The following versions of this skeleton are available, the number
-- suggesting how many nested vectors it is operating upon.
--
-- > (<@>), (<<@>>), (<<<@>>>), (<<<<@>>>>), (<<<<<@>>>>>),
(<@>) :: Vector a        -- ^ input vector
       -> Vector Int  -- ^ vector of indexes
       -> Vector (Maybe a)
v :: Vector a
v     <@> :: Vector a -> Vector Int -> Vector (Maybe a)
<@>     ix :: Vector Int
ix = Vector Int -> Vector a -> Vector (Maybe a)
forall a. Vector Int -> Vector a -> Vector (Maybe a)
gather1 Vector Int
ix Vector a
v
v :: Vector a
v    <<@>> :: Vector a -> c (c Int) -> c (c (Maybe a))
<<@>>    ix :: c (c Int)
ix = c (c Int) -> Vector a -> c (c (Maybe a))
forall (c :: * -> *) (c :: * -> *) a.
(Skeleton c, Skeleton c) =>
c (c Int) -> Vector a -> c (c (Maybe a))
gather2 c (c Int)
ix Vector a
v    
v :: Vector a
v   <<<@>>> :: Vector a -> c (c (c Int)) -> c (c (c (Maybe a)))
<<<@>>>   ix :: c (c (c Int))
ix = c (c (c Int)) -> Vector a -> c (c (c (Maybe a)))
forall (c :: * -> *) (c :: * -> *) (c :: * -> *) a.
(Skeleton c, Skeleton c, Skeleton c) =>
c (c (c Int)) -> Vector a -> c (c (c (Maybe a)))
gather3 c (c (c Int))
ix Vector a
v   
v :: Vector a
v  <<<<@>>>> :: Vector a -> c (c (c (c Int))) -> c (c (c (c (Maybe a))))
<<<<@>>>>  ix :: c (c (c (c Int)))
ix = c (c (c (c Int))) -> Vector a -> c (c (c (c (Maybe a))))
forall (c :: * -> *) (c :: * -> *) (c :: * -> *) (c :: * -> *) a.
(Skeleton c, Skeleton c, Skeleton c, Skeleton c) =>
c (c (c (c Int))) -> Vector a -> c (c (c (c (Maybe a))))
gather4 c (c (c (c Int)))
ix Vector a
v  
v :: Vector a
v <<<<<@>>>>> :: Vector a -> c (c (c (c (c Int)))) -> c (c (c (c (c (Maybe a)))))
<<<<<@>>>>> ix :: c (c (c (c (c Int))))
ix = c (c (c (c (c Int)))) -> Vector a -> c (c (c (c (c (Maybe a)))))
forall (c :: * -> *) (c :: * -> *) (c :: * -> *) (c :: * -> *)
       (c :: * -> *) a.
(Skeleton c, Skeleton c, Skeleton c, Skeleton c, Skeleton c) =>
c (c (c (c (c Int)))) -> Vector a -> c (c (c (c (c (Maybe a)))))
gather5 c (c (c (c (c Int))))
ix Vector a
v 


-- | scatters the elements in a vector based on the indexes contained by another vector.
--
-- >>> scatter (vector [2,4,5]) (vector [0,0,0,0,0,0,0,0]) (vector [1,1,1])
-- <0,1,0,1,1,0,0,0>
--
-- <<fig/eqs-skel-vector-scatter.png>>
--
-- <<fig/skel-vector-comm-scatter.png>>
-- <<fig/skel-vector-comm-scatter-net.png>>
scatter :: Vector Int -> Vector a -> Vector a -> Vector a
scatter Null hv :: Vector a
hv _    = Vector a
hv
scatter _    hv :: Vector a
hv Null = Vector a
hv
scatter ix :: Vector Int
ix   hv :: Vector a
hv v :: Vector a
v    = (Int -> Vector a -> Vector a -> Vector a)
-> Vector a -> Vector Int -> Vector (Vector a) -> Vector a
forall (c :: * -> *) a1 a2 a.
Skeleton c =>
(a1 -> a2 -> a -> a) -> a -> c a1 -> c a2 -> a
reducei1 Int -> Vector a -> Vector a -> Vector a
forall (c :: * -> *) a.
Skeleton c =>
Int -> c a -> Vector a -> Vector a
sel Vector a
hv Vector Int
ix (Vector (Vector a) -> Vector a)
-> (Vector a -> Vector (Vector a)) -> Vector a -> Vector a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (a -> Vector a) -> Vector a -> Vector (Vector a)
forall (c :: * -> *) a b. Skeleton c => (a -> b) -> c a -> c b
S.farm11 a -> Vector a
forall a. a -> Vector a
unit (Vector a -> Vector a) -> Vector a -> Vector a
forall a b. (a -> b) -> a -> b
$ Vector a
v
  where sel :: Int -> c a -> Vector a -> Vector a
sel i :: Int
i r :: c a
r h :: Vector a
h = Int -> a -> Vector a -> Vector a
forall a. Int -> a -> Vector a -> Vector a
replace Int
i (c a -> a
forall (c :: * -> *) a. Skeleton c => c a -> a
S.first c a
r) Vector a
h



-- filter f = reduce1' (\x y -> if f (first x) then x <++> y else y) Null . map unit

-- group n v = map (take n) $ prefix1 dropseries v
--   where dropseries = unit id <++> fanoutn nstages (drop n)
--         nstages    = ceiling $ fromIntegral (length v) / fromIntegral n - 1


-- map  :: (a -> b) -> Vector a -> Vector b
-- red  :: (a -> a -> a) -> Vector a -> a
-- pipe :: Vector (a -> a) -> a -> a
-- scan :: Vector (a -> a) -> a -> Vector a
-- map  = (=.=)
-- red  = (=\=)
-- pipe = (=<<=)
-- scan  ps s = map (=<<= s) (inits ps)
-- scan' ps s = map (=<<= s) (inits $ unit id <++> ps)