summaryrefslogtreecommitdiff
path: root/lib/Data/Packed/Matrix.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Data/Packed/Matrix.hs')
-rw-r--r--lib/Data/Packed/Matrix.hs59
1 files changed, 45 insertions, 14 deletions
diff --git a/lib/Data/Packed/Matrix.hs b/lib/Data/Packed/Matrix.hs
index bd7cb69..912e1c6 100644
--- a/lib/Data/Packed/Matrix.hs
+++ b/lib/Data/Packed/Matrix.hs
@@ -44,28 +44,59 @@ import Text.Printf(printf)
44-- | creates a matrix from a vertical list of matrices 44-- | creates a matrix from a vertical list of matrices
45joinVert :: Element t => [Matrix t] -> Matrix t 45joinVert :: Element t => [Matrix t] -> Matrix t
46joinVert ms = case common cols ms of 46joinVert ms = case common cols ms of
47 Nothing -> error "joinVert on matrices with different number of columns" 47 Nothing -> error "(impossible) joinVert on matrices with different number of columns"
48 Just c -> reshape c $ join (map flatten ms) 48 Just c -> reshape c $ join (map flatten ms)
49 49
50-- | creates a matrix from a horizontal list of matrices 50-- | creates a matrix from a horizontal list of matrices
51joinHoriz :: Element t => [Matrix t] -> Matrix t 51joinHoriz :: Element t => [Matrix t] -> Matrix t
52joinHoriz ms = trans. joinVert . map trans $ ms 52joinHoriz ms = trans. joinVert . map trans $ ms
53 53
54{- | Creates a matrix from blocks given as a list of lists of matrices: 54{- | Creates a matrix from blocks given as a list of lists of matrices.
55 55
56@\> let a = 'diag' $ 'fromList' [5,7,2] 56Single row/column components are automatically expanded to match the
57\> let b = 'reshape' 4 $ 'constant' (-1) 12 57corresponding common row and column:
58\> fromBlocks [[a,b],[b,a]] 58
59(6><7) 59@\> let disp = putStr . dispf 2
60 [ 5.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0 60\> let vector xs = fromList xs :: Vector Double
61 , 0.0, 7.0, 0.0, -1.0, -1.0, -1.0, -1.0 61\> let diagl = diag . vector
62 , 0.0, 0.0, 2.0, -1.0, -1.0, -1.0, -1.0 62\> let rowm = asRow . vector
63 , -1.0, -1.0, -1.0, -1.0, 5.0, 0.0, 0.0 63\> disp $ fromBlocks [[ident 5, 7, rowm[10,20]], [3, diagl[1,2,3], 0]]
64 , -1.0, -1.0, -1.0, -1.0, 0.0, 7.0, 0.0 648x10
65 , -1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 2.0 ]@ 651 0 0 0 0 7 7 7 10 20
660 1 0 0 0 7 7 7 10 20
670 0 1 0 0 7 7 7 10 20
680 0 0 1 0 7 7 7 10 20
690 0 0 0 1 7 7 7 10 20
703 3 3 3 3 1 0 0 0 0
713 3 3 3 3 0 2 0 0 0
723 3 3 3 3 0 0 3 0 0@
66-} 73-}
67fromBlocks :: Element t => [[Matrix t]] -> Matrix t 74fromBlocks :: Element t => [[Matrix t]] -> Matrix t
68fromBlocks = joinVert . map joinHoriz 75fromBlocks = fromBlocksRaw . adaptBlocks
76
77fromBlocksRaw mms = joinVert . map joinHoriz $ mms
78
79adaptBlocks ms = ms' where
80 bc = case common length ms of
81 Just c -> c
82 Nothing -> error "fromBlocks requires rectangular [[Matrix]]"
83 rs = map (compatdim . map rows) ms
84 cs = map (compatdim . map cols) (transpose ms)
85 szs = sequence [rs,cs]
86 ms' = partit bc $ zipWith g szs (concat ms)
87
88 g [Just nr,Just nc] m
89 | nr == r && nc == c = m
90 | r == 1 && c == 1 = reshape nc (constant x (nr*nc))
91 | r == 1 = fromRows (replicate nr (flatten m))
92 | otherwise = fromColumns (replicate nc (flatten m))
93 where
94 r = rows m
95 c = cols m
96 x = m@@>(0,0)
97 g _ _ = error "inconsistent dimensions in fromBlocks"
98
99-----------------------------------------------------------
69 100
70-- | Reverse rows 101-- | Reverse rows
71flipud :: Element t => Matrix t -> Matrix t 102flipud :: Element t => Matrix t -> Matrix t