diff options
author | Alberto Ruiz <aruiz@um.es> | 2010-01-20 12:05:34 +0000 |
---|---|---|
committer | Alberto Ruiz <aruiz@um.es> | 2010-01-20 12:05:34 +0000 |
commit | 408997ea02dec897934b176fe57115bdb4f60f63 (patch) | |
tree | 3a9a4a86328ec36d5c6ad31eb8e6609cfb7a05ea /lib | |
parent | 102d6b19beadd76b28d32e1aa40844fad19af756 (diff) |
more defined fromRows/fromColumns/fromBlocks
Diffstat (limited to 'lib')
-rw-r--r-- | lib/Data/Packed/Internal/Common.hs | 8 | ||||
-rw-r--r-- | lib/Data/Packed/Internal/Matrix.hs | 11 | ||||
-rw-r--r-- | lib/Data/Packed/Matrix.hs | 59 |
3 files changed, 60 insertions, 18 deletions
diff --git a/lib/Data/Packed/Internal/Common.hs b/lib/Data/Packed/Internal/Common.hs index 629016d..972cd7d 100644 --- a/lib/Data/Packed/Internal/Common.hs +++ b/lib/Data/Packed/Internal/Common.hs | |||
@@ -18,7 +18,7 @@ module Data.Packed.Internal.Common( | |||
18 | Adapt, | 18 | Adapt, |
19 | app1, app2, app3, app4, | 19 | app1, app2, app3, app4, |
20 | (//), check, | 20 | (//), check, |
21 | partit, common, | 21 | partit, common, compatdim, |
22 | fi | 22 | fi |
23 | ) where | 23 | ) where |
24 | 24 | ||
@@ -41,6 +41,12 @@ common f = commonval . map f where | |||
41 | commonval [a] = Just a | 41 | commonval [a] = Just a |
42 | commonval (a:b:xs) = if a==b then commonval (b:xs) else Nothing | 42 | commonval (a:b:xs) = if a==b then commonval (b:xs) else Nothing |
43 | 43 | ||
44 | -- | common value with \"adaptable\" 1 | ||
45 | compatdim :: [Int] -> Maybe Int | ||
46 | compatdim [] = Nothing | ||
47 | compatdim [a] = Just a | ||
48 | compatdim (a:b:xs) = if a==b || a==1 || b==1 then compatdim (max a b:xs) else Nothing | ||
49 | |||
44 | -- | postfix function application (@flip ($)@) | 50 | -- | postfix function application (@flip ($)@) |
45 | (//) :: x -> (x -> y) -> y | 51 | (//) :: x -> (x -> y) -> y |
46 | infixl 0 // | 52 | infixl 0 // |
diff --git a/lib/Data/Packed/Internal/Matrix.hs b/lib/Data/Packed/Internal/Matrix.hs index a220f1a..33c9324 100644 --- a/lib/Data/Packed/Internal/Matrix.hs +++ b/lib/Data/Packed/Internal/Matrix.hs | |||
@@ -135,11 +135,16 @@ type Mt t s = Int -> Int -> Ptr t -> s | |||
135 | toLists :: (Element t) => Matrix t -> [[t]] | 135 | toLists :: (Element t) => Matrix t -> [[t]] |
136 | toLists m = partit (cols m) . toList . flatten $ m | 136 | toLists m = partit (cols m) . toList . flatten $ m |
137 | 137 | ||
138 | -- | creates a Matrix from a list of vectors | 138 | -- | Create a matrix from a list of vectors. |
139 | -- All vectors must have the same dimension, | ||
140 | -- or dimension 1, which is are automatically expanded. | ||
139 | fromRows :: Element t => [Vector t] -> Matrix t | 141 | fromRows :: Element t => [Vector t] -> Matrix t |
140 | fromRows vs = case common dim vs of | 142 | fromRows vs = case compatdim (map dim vs) of |
141 | Nothing -> error "fromRows applied to [] or to vectors with different sizes" | 143 | Nothing -> error "fromRows applied to [] or to vectors with different sizes" |
142 | Just c -> reshape c (join vs) | 144 | Just c -> reshape c . join . map (adapt c) $ vs |
145 | where | ||
146 | adapt c v | dim v == c = v | ||
147 | | otherwise = constantD (v@>0) c | ||
143 | 148 | ||
144 | -- | extracts the rows of a matrix as a list of vectors | 149 | -- | extracts the rows of a matrix as a list of vectors |
145 | toRows :: Element t => Matrix t -> [Vector t] | 150 | toRows :: Element t => Matrix t -> [Vector t] |
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 |
45 | joinVert :: Element t => [Matrix t] -> Matrix t | 45 | joinVert :: Element t => [Matrix t] -> Matrix t |
46 | joinVert ms = case common cols ms of | 46 | joinVert 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 |
51 | joinHoriz :: Element t => [Matrix t] -> Matrix t | 51 | joinHoriz :: Element t => [Matrix t] -> Matrix t |
52 | joinHoriz ms = trans. joinVert . map trans $ ms | 52 | joinHoriz 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] | 56 | Single row/column components are automatically expanded to match the |
57 | \> let b = 'reshape' 4 $ 'constant' (-1) 12 | 57 | corresponding 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 | 64 | 8x10 |
65 | , -1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 2.0 ]@ | 65 | 1 0 0 0 0 7 7 7 10 20 |
66 | 0 1 0 0 0 7 7 7 10 20 | ||
67 | 0 0 1 0 0 7 7 7 10 20 | ||
68 | 0 0 0 1 0 7 7 7 10 20 | ||
69 | 0 0 0 0 1 7 7 7 10 20 | ||
70 | 3 3 3 3 3 1 0 0 0 0 | ||
71 | 3 3 3 3 3 0 2 0 0 0 | ||
72 | 3 3 3 3 3 0 0 3 0 0@ | ||
66 | -} | 73 | -} |
67 | fromBlocks :: Element t => [[Matrix t]] -> Matrix t | 74 | fromBlocks :: Element t => [[Matrix t]] -> Matrix t |
68 | fromBlocks = joinVert . map joinHoriz | 75 | fromBlocks = fromBlocksRaw . adaptBlocks |
76 | |||
77 | fromBlocksRaw mms = joinVert . map joinHoriz $ mms | ||
78 | |||
79 | adaptBlocks 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 |
71 | flipud :: Element t => Matrix t -> Matrix t | 102 | flipud :: Element t => Matrix t -> Matrix t |