comfort-array-0.5.5: Arrays where the index type is a function of the shape type
Safe HaskellNone
LanguageHaskell98

Data.Array.Comfort.Storable.Dim2

Synopsis

Documentation

type Array2 sh0 sh1 = Array (sh0, sh1) Source #

singleRow :: Array width a -> Array2 () width a Source #

flattenRow :: Array2 () width a -> Array width a Source #

singleColumn :: Array height a -> Array2 height () a Source #

flattenColumn :: Array2 height () a -> Array height a Source #

takeRow :: (Indexed sh0, C sh1, Storable a) => Array2 sh0 sh1 a -> Index sh0 -> Array sh1 a Source #

:{

QC.forAll genNonEmptyArray2 $ xs -> QC.forAll (QC.elements $ Shape.indices $ Array.shape xs) $ (ix0,ix1) -> Array2.takeRow xs ix0 ! ix1 == xs!(ix0,ix1) :}

toRowArray :: (C sh0, C sh1, Storable a) => Array2 sh0 sh1 a -> Array sh0 (Array sh1 a) Source #

fromRowArray :: (C sh0, C sh1, Eq sh1, Storable a) => sh1 -> Array sh0 (Array sh1 a) -> Array2 sh0 sh1 a Source #

It is a checked error if a row width differs from the result array width.

:{

QC.forAll genArray2 $ xs -> xs == Array2.fromRowArray (snd $ Array.shape xs) (Array2.toRowArray xs) :}

above :: (C heightA, C heightB, C width, Eq width, Storable a) => Array2 heightA width a -> Array2 heightB width a -> Array2 (heightA ::+ heightB) width a infixr 2 Source #

:{

QC.forAll genArray2 $ xs -> let (Shape.ZeroBased m, width) = Array.shape xs in QC.forAll (QC.choose (0, m)) $ k -> let ys = Array.reshape (Shape.ZeroBased k ::+ Shape.ZeroBased (m-k), width) xs in ys == Array2.above (Array2.takeTop ys) (Array2.takeBottom ys) :}

beside :: (C height, Eq height, C widthA, C widthB, Storable a) => Array2 height widthA a -> Array2 height widthB a -> Array2 height (widthA ::+ widthB) a infixr 3 Source #

:{

QC.forAll genArray2 $ xs -> let (height, Shape.ZeroBased n) = Array.shape xs in QC.forAll (QC.choose (0, n)) $ k -> let ys = Array.reshape (height, Shape.ZeroBased k ::+ Shape.ZeroBased (n-k)) xs in ys == Array2.beside (Array2.takeLeft ys) (Array2.takeRight ys) :}

takeTop :: (C heightA, C heightB, C width, Storable a) => Array2 (heightA ::+ heightB) width a -> Array2 heightA width a Source #

takeBottom :: (C heightA, C heightB, C width, Storable a) => Array2 (heightA ::+ heightB) width a -> Array2 heightB width a Source #

takeLeft :: (C height, C widthA, C widthB, Storable a) => Array2 height (widthA ::+ widthB) a -> Array2 height widthA a Source #

takeRight :: (C height, C widthA, C widthB, Storable a) => Array2 height (widthA ::+ widthB) a -> Array2 height widthB a Source #

fromNonEmptyBlockArray :: (Ord row, C height, Eq height, Ord column, C width, Eq width, Storable a) => Array (Set row, Set column) (Array2 height width a) -> Array2 (Map row height) (Map column width) a Source #

Only the outer BoxedArray need to be non-empty.

>>> :{
   let shapeR0 = shapeInt 2; shapeR1 = shapeInt 3 in
   let shapeC0 = shapeInt 3; shapeC1 = shapeInt 2 in
   let block sh a = Array.replicate sh (a::Word16) in
   Array2.fromBlockArray
      (Map.singleton 'A' shapeR0 <> Map.singleton 'B' shapeR1)
      (Map.singleton '1' shapeC0 <> Map.singleton '2' shapeC1) $
   BoxedArray.fromList (Set.fromList "AB", Set.fromList "12")
      [block (shapeR0,shapeC0) 0, block (shapeR0,shapeC1) 1,
       block (shapeR1,shapeC0) 2, block (shapeR1,shapeC1) 3]
:}
StorableArray.fromList (fromList [('A',ZeroBased {... 2}),('B',ZeroBased {... 3})],fromList [('1',ZeroBased {... 3}),('2',ZeroBased {... 2})]) [0,0,0,1,1,0,0,0,1,1,2,2,2,3,3,2,2,2,3,3,2,2,2,3,3]
:{

QC.forAll genArray2 $ blockA1 -> QC.forAll genArray2 $ blockB2 -> let shapeR0 = fst $ Array.shape blockA1 in let shapeC0 = snd $ Array.shape blockA1 in let shapeR1 = fst $ Array.shape blockB2 in let shapeC1 = snd $ Array.shape blockB2 in QC.forAll (genArrayForShape (shapeR0, shapeC1)) $ blockA2 -> QC.forAll (genArrayForShape (shapeR1, shapeC0)) $ blockB1 -> let blocked = BoxedArray.fromList (Set.fromList AB, Set.fromList "12") [blockA1, blockA2, blockB1, blockB2] in

transpose (Array2.fromNonEmptyBlockArray blocked) QC.=== Array2.fromNonEmptyBlockArray (TestBoxedArray.transpose (fmap transpose blocked)) :}

:{

QC.forAll genArray2 $ blockA1 -> QC.forAll genArray2 $ blockB2 -> QC.forAll genArray2 $ blockC3 -> let shapeR0 = fst $ Array.shape blockA1 in let shapeC0 = snd $ Array.shape blockA1 in let shapeR1 = fst $ Array.shape blockB2 in let shapeC1 = snd $ Array.shape blockB2 in let shapeR2 = fst $ Array.shape blockC3 in let shapeC2 = snd $ Array.shape blockC3 in QC.forAll (genArrayForShape (shapeR0, shapeC1)) $ blockA2 -> QC.forAll (genArrayForShape (shapeR0, shapeC2)) $ blockA3 -> QC.forAll (genArrayForShape (shapeR1, shapeC0)) $ blockB1 -> QC.forAll (genArrayForShape (shapeR1, shapeC2)) $ blockB3 -> QC.forAll (genArrayForShape (shapeR2, shapeC0)) $ blockC1 -> QC.forAll (genArrayForShape (shapeR2, shapeC1)) $ blockC2 -> let blocked = BoxedArray.fromList (Set.fromList ABC, Set.fromList "123") [blockA1, blockA2, blockA3, blockB1, blockB2, blockB3, blockC1, blockC2, blockC3] in

transpose (Array2.fromNonEmptyBlockArray blocked) QC.=== Array2.fromNonEmptyBlockArray (TestBoxedArray.transpose (fmap transpose blocked)) :}

fromBlockArray :: (Ord row, C height, Eq height, Ord column, C width, Eq width, Storable a) => Map row height -> Map column width -> Array (Set row, Set column) (Array2 height width a) -> Array2 (Map row height) (Map column width) a Source #

Explicit parameters for the shape of the result matrix allow for working with arrays of zero rows or columns.

>>> :{
   (id :: Id (array (height, Map Char ShapeInt) Word16)) $
   Array2.fromBlockArray
      (Map.singleton 'A' (shapeInt 2) <> Map.singleton 'B' (shapeInt 3))
      Map.empty $
   BoxedArray.fromList (Set.fromList "AB", Set.empty) []
:}
StorableArray.fromList (fromList [('A',ZeroBased {... 2}),('B',ZeroBased {... 3})],fromList []) []
:{

QC.forAll genArray2 $ block -> let height = Map.singleton A $ fst $ Array.shape block in let width = Map.singleton '1' $ snd $ Array.shape block in

Array.reshape (height,width) block QC.=== Array2.fromBlockArray height width (BoxedArray.replicate (Set.singleton A, Set.singleton '1') block) :}

fromBlocks :: (ShapeSequence height, ShapeSequence width, Storable a) => height -> width -> Proxy a -> BlockFunction height width a (Array2 height width a) Source #

:{

QC.forAll genArray2 $ blockA1 -> QC.forAll genArray2 $ blockB2 -> let shapeR0 = fst $ Array.shape blockA1 in let shapeC0 = snd $ Array.shape blockA1 in let shapeR1 = fst $ Array.shape blockB2 in let shapeC1 = snd $ Array.shape blockB2 in let shapeR = shapeR0::+shapeR1::+Shape.Zero in let shapeC = shapeC0::+shapeC1::+Shape.Zero in QC.forAll (genArrayForShape (shapeR0, shapeC1)) $ blockA2 -> QC.forAll (genArrayForShape (shapeR1, shapeC0)) $ blockB1 -> let blocked = BoxedArray.fromList (Set.fromList AB, Set.fromList "12") [blockA1, blockA2, blockB1, blockB2] in

Array.reshape (shapeR, shapeC) (Array2.fromNonEmptyBlockArray blocked) QC.=== Array2.fromBlocks shapeR shapeC Proxy blockA1 blockA2 blockB1 blockB2 :}

type family BlockFunction heights widths a r Source #

Instances

Instances details
type BlockFunction Zero widths a r Source # 
Instance details

Defined in Data.Array.Comfort.Storable.Dim2

type BlockFunction Zero widths a r = r
type BlockFunction (height ::+ heights) widths a r Source # 
Instance details

Defined in Data.Array.Comfort.Storable.Dim2

type BlockFunction (height ::+ heights) widths a r = RowFunction height widths a (BlockFunction heights widths a r)

type family RowFunction height widths a r Source #

Instances

Instances details
type RowFunction height Zero a r Source # 
Instance details

Defined in Data.Array.Comfort.Storable.Dim2

type RowFunction height Zero a r = r
type RowFunction height (width ::+ widths) a r Source # 
Instance details

Defined in Data.Array.Comfort.Storable.Dim2

type RowFunction height (width ::+ widths) a r = Array2 height width a -> RowFunction height widths a r

class C sh => ShapeSequence sh where Source #

Methods

switchSequence :: f Zero -> (forall sh0 shs. (C sh0, Eq sh0, ShapeSequence shs) => f (sh0 ::+ shs)) -> f sh Source #

Instances

Instances details
ShapeSequence Zero Source # 
Instance details

Defined in Data.Array.Comfort.Storable.Dim2

Methods

switchSequence :: f Zero -> (forall sh0 shs. (C sh0, Eq sh0, ShapeSequence shs) => f (sh0 ::+ shs)) -> f Zero Source #

(C sh, Eq sh, ShapeSequence shs) => ShapeSequence (sh ::+ shs) Source # 
Instance details

Defined in Data.Array.Comfort.Storable.Dim2

Methods

switchSequence :: f Zero -> (forall sh0 shs0. (C sh0, Eq sh0, ShapeSequence shs0) => f (sh0 ::+ shs0)) -> f (sh ::+ shs) Source #

data BlockArray shape a Source #

Instances

Instances details
Block BlockArray Source # 
Instance details

Defined in Data.Array.Comfort.Storable.Dim2

Methods

blockPrivate :: (C height, C width, Storable a) => BlockArray (height, width) a -> BlockMatrix height width a

type BlockMatrix height width = BlockArray (height, width) Source #

class Block (block :: Type -> Type -> Type) Source #

Minimal complete definition

blockPrivate

Instances

Instances details
Block BlockArray Source # 
Instance details

Defined in Data.Array.Comfort.Storable.Dim2

Methods

blockPrivate :: (C height, C width, Storable a) => BlockArray (height, width) a -> BlockMatrix height width a

Block Array Source # 
Instance details

Defined in Data.Array.Comfort.Storable.Dim2

Methods

blockPrivate :: (C height, C width, Storable a) => Array (height, width) a -> BlockMatrix height width a

fromBlockMatrix :: (C height, C width, Storable a) => BlockMatrix height width a -> Array2 height width a Source #

:{

QC.forAll genArray2 $ blockA1 -> QC.forAll genArray2 $ blockB3 -> QC.forAll (liftA2 (char0 char1 -> Shape.Range (min char0 char1) (max char0 char1)) (QC.choose (a,k)) (QC.choose (a,k))) $ shapeC1 -> let shapeR0 = fst $ Array.shape blockA1 in let shapeC0 = snd $ Array.shape blockA1 in let shapeR1 = fst $ Array.shape blockB3 in let shapeC2 = snd $ Array.shape blockB3 in QC.forAll (genArrayForShape (shapeR0, shapeC1)) $ blockA2 -> QC.forAll (genArrayForShape (shapeR0, shapeC2)) $ blockA3 -> QC.forAll (genArrayForShape (shapeR1, shapeC0)) $ blockB1 -> QC.forAll (genArrayForShape (shapeR1, shapeC1)) $ blockB2 ->

Array2.fromBlockMatrix (blockA1 &||| Array2.beside blockA2 blockA3 &=== blockB1 &||| blockB2 &||| blockB3) QC.=== Array.reshape (shapeR0::+shapeR1, shapeC0::+shapeC1::+shapeC2) (Array2.fromBlocks (shapeR0::+shapeR1::+Shape.Zero) (shapeC0::+shapeC1::+shapeC2::+Shape.Zero) Proxy blockA1 blockA2 blockA3 blockB1 blockB2 blockB3) :}

:{

QC.forAll (liftA2 (char0 char1 -> Shape.Range (min char0 char1) (max char0 char1)) (QC.choose (a,k)) (QC.choose (a,k))) $ shapeR0 -> QC.forAll (liftA2 Shape.Shifted (QC.choose (-10,10)) (QC.choose (0,10::Int))) $ shapeR1 -> let shapeR2 = () in QC.forAll (fmap Shape.ZeroBased (QC.choose (0,10::Int))) $ shapeC0 -> QC.forAll (fmap Shape.OneBased (QC.choose (0,10::Int))) $ shapeC1 -> let shapeC2 :: Shape.Enumeration Ordering shapeC2 = Shape.Enumeration in

QC.forAll (genArrayForShape (shapeR0, shapeC0)) $ blockA1 -> QC.forAll (genArrayForShape (shapeR0, shapeC1)) $ blockA2 -> QC.forAll (genArrayForShape (shapeR0, shapeC2)) $ blockA3 -> QC.forAll (genArrayForShape (shapeR1, shapeC0)) $ blockB1 -> QC.forAll (genArrayForShape (shapeR1, shapeC1)) $ blockB2 -> QC.forAll (genArrayForShape (shapeR1, shapeC2)) $ blockB3 -> QC.forAll (genArrayForShape (shapeR2, shapeC0)) $ blockC1 -> QC.forAll (genArrayForShape (shapeR2, shapeC1)) $ blockC2 -> QC.forAll (genArrayForShape (shapeR2, shapeC2)) $ blockC3 ->

Array2.fromBlockMatrix (blockA1 &||| blockA2 &||| blockA3 &=== blockB1 &||| blockB2 &||| blockB3 &=== blockC1 &||| blockC2 &||| blockC3) QC.=== Array2.beside (Array2.above blockA1 $ Array2.above blockB1 blockC1) (Array2.above (Array2.beside blockA2 blockA3) (Array2.beside (Array2.above blockB2 blockC2) (Array2.above blockB3 blockC3))) :}

block :: (Block block, C height, C width, Storable a) => block (height, width) a -> BlockMatrix height width a Source #

blockAbove :: Eq width => BlockMatrix heightA width a -> BlockMatrix heightB width a -> BlockMatrix (heightA ::+ heightB) width a Source #

blockBeside :: Eq height => BlockMatrix height widthA a -> BlockMatrix height widthB a -> BlockMatrix height (widthA ::+ widthB) a Source #

(&===) :: (Block blockA, Block blockB, C heightA, C heightB, C width, Eq width, Storable a) => blockA (heightA, width) a -> blockB (heightB, width) a -> BlockMatrix (heightA ::+ heightB) width a infixr 2 Source #

(&|||) :: (Block blockA, Block blockB, C height, Eq height, C widthA, C widthB, Storable a) => blockA (height, widthA) a -> blockB (height, widthB) a -> BlockMatrix height (widthA ::+ widthB) a infixr 3 Source #