diff options
Diffstat (limited to 'lib/Data/Packed/Matrix.hs')
-rw-r--r-- | lib/Data/Packed/Matrix.hs | 44 |
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 |
106 | joinVert :: Element t => [Matrix t] -> Matrix t | 106 | joinVert :: Element t => [Matrix t] -> Matrix t |
107 | joinVert [] = emptyM 0 0 | ||
107 | joinVert ms = case common cols ms of | 108 | joinVert 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 | |||
173 | 0 0 0 0 0 0 0 5 | 174 | 0 0 0 0 0 0 0 5 |
174 | 0 0 0 0 0 0 0 7 | 175 | 0 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 | -} |
177 | diagBlock :: (Element t, Num t) => [Matrix t] -> Matrix t | 183 | diagBlock :: (Element t, Num t) => [Matrix t] -> Matrix t |
178 | diagBlock ms = fromBlocks $ zipWith f ms [0..] | 184 | diagBlock 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 |
188 | flipud :: Element t => Matrix t -> Matrix t | 194 | flipud :: Element t => Matrix t -> Matrix t |
189 | flipud m = fromRows . reverse . toRows $ m | 195 | flipud m = extractRows [r-1,r-2 .. 0] $ m |
196 | where | ||
197 | r = rows m | ||
190 | 198 | ||
191 | -- | Reverse columns | 199 | -- | Reverse columns |
192 | fliprl :: Element t => Matrix t -> Matrix t | 200 | fliprl :: Element t => Matrix t -> Matrix t |
193 | fliprl m = fromColumns . reverse . toColumns $ m | 201 | fliprl 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. |
329 | extractRows :: Element t => [Int] -> Matrix t -> Matrix t | 339 | extractRows :: Element t => [Int] -> Matrix t -> Matrix t |
340 | extractRows [] m = emptyM 0 (cols m) | ||
330 | extractRows l m = fromRows $ extract (toRows m) l | 341 | extractRows 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. | ||
350 | extractColumns :: Element t => [Int] -> Matrix t -> Matrix t | ||
351 | extractColumns 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 | -} |
343 | repmat :: (Element t) => Matrix t -> Int -> Int -> Matrix t | 370 | repmat :: (Element t) => Matrix t -> Int -> Int -> Matrix t |
344 | repmat m r c = fromBlocks $ splitEvery c $ replicate (r*c) m | 371 | repmat 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. |
347 | liftMatrix2Auto :: (Element t, Element a, Element b) => (Vector a -> Vector b -> Vector t) -> Matrix a -> Matrix b -> Matrix t | 376 | liftMatrix2Auto :: (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. |
392 | toBlocksEvery :: (Element t) => Int -> Int -> Matrix t -> [[Matrix t]] | 421 | toBlocksEvery :: (Element t) => Int -> Int -> Matrix t -> [[Matrix t]] |
393 | toBlocksEvery r c m = toBlocks rs cs m where | 422 | toBlocksEvery 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 [] |