comfort-array-0.5.5: Arrays where the index type is a function of the shape type
Safe HaskellSafe-Inferred
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 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 #