summaryrefslogtreecommitdiff
path: root/lib/Data/Packed/Matrix.hs
diff options
context:
space:
mode:
authorAlberto Ruiz <aruiz@um.es>2014-05-06 08:50:50 +0200
committerAlberto Ruiz <aruiz@um.es>2014-05-06 08:50:50 +0200
commitc9914d694d3b86ece46fa0c76e0466c6cd394d14 (patch)
tree7fa1c5a95b204912f5d560c843ae6045ee8d2780 /lib/Data/Packed/Matrix.hs
parent4078cf44c98b42960be27843782f6983bb66017f (diff)
extend conformability to empty arrays
Diffstat (limited to 'lib/Data/Packed/Matrix.hs')
-rw-r--r--lib/Data/Packed/Matrix.hs44
1 files changed, 38 insertions, 6 deletions
diff --git a/lib/Data/Packed/Matrix.hs b/lib/Data/Packed/Matrix.hs
index b92d60f..d94d167 100644
--- a/lib/Data/Packed/Matrix.hs
+++ b/lib/Data/Packed/Matrix.hs
@@ -35,7 +35,7 @@ module Data.Packed.Matrix (
35 repmat, 35 repmat,
36 flipud, fliprl, 36 flipud, fliprl,
37 subMatrix, takeRows, dropRows, takeColumns, dropColumns, 37 subMatrix, takeRows, dropRows, takeColumns, dropColumns,
38 extractRows, 38 extractRows, extractColumns,
39 diagRect, takeDiag, 39 diagRect, takeDiag,
40 mapMatrix, mapMatrixWithIndex, mapMatrixWithIndexM, mapMatrixWithIndexM_, 40 mapMatrix, mapMatrixWithIndex, mapMatrixWithIndexM, mapMatrixWithIndexM_,
41 liftMatrix, liftMatrix2, liftMatrix2Auto,fromArray2D 41 liftMatrix, liftMatrix2, liftMatrix2Auto,fromArray2D
@@ -104,6 +104,7 @@ breakAt c l = (a++[c],tail b) where
104 104
105-- | creates a matrix from a vertical list of matrices 105-- | creates a matrix from a vertical list of matrices
106joinVert :: Element t => [Matrix t] -> Matrix t 106joinVert :: Element t => [Matrix t] -> Matrix t
107joinVert [] = emptyM 0 0
107joinVert ms = case common cols ms of 108joinVert ms = case common cols ms of
108 Nothing -> error "(impossible) joinVert on matrices with different number of columns" 109 Nothing -> error "(impossible) joinVert on matrices with different number of columns"
109 Just c -> matrixFromVector RowMajor (sum (map rows ms)) c $ vjoin (map flatten ms) 110 Just c -> matrixFromVector RowMajor (sum (map rows ms)) c $ vjoin (map flatten ms)
@@ -173,6 +174,11 @@ adaptBlocks ms = ms' where
1730 0 0 0 0 0 0 5 1740 0 0 0 0 0 0 5
1740 0 0 0 0 0 0 7 1750 0 0 0 0 0 0 7
175 176
177>>> diagBlock [(0><4)[], konst 2 (2,3)] :: Matrix Double
178(2><7)
179 [ 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 2.0
180 , 0.0, 0.0, 0.0, 0.0, 2.0, 2.0, 2.0 ]
181
176-} 182-}
177diagBlock :: (Element t, Num t) => [Matrix t] -> Matrix t 183diagBlock :: (Element t, Num t) => [Matrix t] -> Matrix t
178diagBlock ms = fromBlocks $ zipWith f ms [0..] 184diagBlock ms = fromBlocks $ zipWith f ms [0..]
@@ -186,11 +192,15 @@ diagBlock ms = fromBlocks $ zipWith f ms [0..]
186 192
187-- | Reverse rows 193-- | Reverse rows
188flipud :: Element t => Matrix t -> Matrix t 194flipud :: Element t => Matrix t -> Matrix t
189flipud m = fromRows . reverse . toRows $ m 195flipud m = extractRows [r-1,r-2 .. 0] $ m
196 where
197 r = rows m
190 198
191-- | Reverse columns 199-- | Reverse columns
192fliprl :: Element t => Matrix t -> Matrix t 200fliprl :: Element t => Matrix t -> Matrix t
193fliprl m = fromColumns . reverse . toColumns $ m 201fliprl m = extractColumns [c-1,c-2 .. 0] $ m
202 where
203 c = cols m
194 204
195------------------------------------------------------------ 205------------------------------------------------------------
196 206
@@ -327,8 +337,25 @@ fromArray2D m = (r><c) (elems m)
327 337
328-- | rearranges the rows of a matrix according to the order given in a list of integers. 338-- | rearranges the rows of a matrix according to the order given in a list of integers.
329extractRows :: Element t => [Int] -> Matrix t -> Matrix t 339extractRows :: Element t => [Int] -> Matrix t -> Matrix t
340extractRows [] m = emptyM 0 (cols m)
330extractRows l m = fromRows $ extract (toRows m) l 341extractRows l m = fromRows $ extract (toRows m) l
331 where extract l' is = [l'!!i |i<-is] 342 where
343 extract l' is = [l'!!i | i<- map verify is]
344 verify k
345 | k >= 0 && k < rows m = k
346 | otherwise = error $ "can't extract row "
347 ++show k++" in list " ++ show l ++ " from matrix " ++ shSize m
348
349-- | rearranges the rows of a matrix according to the order given in a list of integers.
350extractColumns :: Element t => [Int] -> Matrix t -> Matrix t
351extractColumns l m = trans . extractRows (map verify l) . trans $ m
352 where
353 verify k
354 | k >= 0 && k < cols m = k
355 | otherwise = error $ "can't extract column "
356 ++show k++" in list " ++ show l ++ " from matrix " ++ shSize m
357
358
332 359
333{- | creates matrix by repetition of a matrix a given number of rows and columns 360{- | creates matrix by repetition of a matrix a given number of rows and columns
334 361
@@ -341,7 +368,9 @@ extractRows l m = fromRows $ extract (toRows m) l
341 368
342-} 369-}
343repmat :: (Element t) => Matrix t -> Int -> Int -> Matrix t 370repmat :: (Element t) => Matrix t -> Int -> Int -> Matrix t
344repmat m r c = fromBlocks $ splitEvery c $ replicate (r*c) m 371repmat m r c
372 | r == 0 || c == 0 = emptyM (r*rows m) (c*cols m)
373 | otherwise = fromBlocks $ replicate r $ replicate c $ m
345 374
346-- | A version of 'liftMatrix2' which automatically adapt matrices with a single row or column to match the dimensions of the other matrix. 375-- | A version of 'liftMatrix2' which automatically adapt matrices with a single row or column to match the dimensions of the other matrix.
347liftMatrix2Auto :: (Element t, Element a, Element b) => (Vector a -> Vector b -> Vector t) -> Matrix a -> Matrix b -> Matrix t 376liftMatrix2Auto :: (Element t, Element a, Element b) => (Vector a -> Vector b -> Vector t) -> Matrix a -> Matrix b -> Matrix t
@@ -390,7 +419,10 @@ toBlocks rs cs m = map (toBlockCols cs) . toBlockRows rs $ m
390-- | Fully partition a matrix into blocks of the same size. If the dimensions are not 419-- | Fully partition a matrix into blocks of the same size. If the dimensions are not
391-- a multiple of the given size the last blocks will be smaller. 420-- a multiple of the given size the last blocks will be smaller.
392toBlocksEvery :: (Element t) => Int -> Int -> Matrix t -> [[Matrix t]] 421toBlocksEvery :: (Element t) => Int -> Int -> Matrix t -> [[Matrix t]]
393toBlocksEvery r c m = toBlocks rs cs m where 422toBlocksEvery r c m
423 | r < 1 || c < 1 = error $ "toBlocksEvery expects block sizes > 0, given "++show r++" and "++ show c
424 | otherwise = toBlocks rs cs m
425 where
394 (qr,rr) = rows m `divMod` r 426 (qr,rr) = rows m `divMod` r
395 (qc,rc) = cols m `divMod` c 427 (qc,rc) = cols m `divMod` c
396 rs = replicate qr r ++ if rr > 0 then [rr] else [] 428 rs = replicate qr r ++ if rr > 0 then [rr] else []