1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
|
-----------------------------------------------------------------------------
-- |
-- Module : Data.Packed.Matrix
-- Copyright : (c) Alberto Ruiz 2007
-- License : GPL-style
--
-- Maintainer : Alberto Ruiz <aruiz@um.es>
-- Stability : provisional
-- Portability : portable
--
-- Matrices
--
-----------------------------------------------------------------------------
module Data.Packed.Matrix (
Matrix(rows,cols),
fromLists, toLists, (><), (>|<), (@@>),
trans, conjTrans,
reshape, flatten, asRow, asColumn,
fromRows, toRows, fromColumns, toColumns, fromBlocks,
joinVert, joinHoriz,
flipud, fliprl,
liftMatrix, liftMatrix2,
multiply,
outer,
subMatrix,
takeRows, dropRows, takeColumns, dropColumns,
diag, takeDiag, diagRect, ident
) where
import Data.Packed.Internal
import Foreign(Storable)
import Complex
import Data.Packed.Vector
-- | creates a matrix from a vertical list of matrices
joinVert :: Field t => [Matrix t] -> Matrix t
joinVert ms = case common cols ms of
Nothing -> error "joinVert on matrices with different number of columns"
Just c -> reshape c $ join (map cdat ms)
-- | creates a matrix from a horizontal list of matrices
joinHoriz :: Field t => [Matrix t] -> Matrix t
joinHoriz ms = trans. joinVert . map trans $ ms
{- | Creates a matrix from blocks given as a list of lists of matrices:
@\> let a = 'diag' $ 'fromList' [5,7,2]
\> let b = 'reshape' 4 $ 'constant' (-1) 12
\> fromBlocks [[a,b],[b,a]]
(6><7)
[ 5.0, 0.0, 0.0, -1.0, -1.0, -1.0, -1.0
, 0.0, 7.0, 0.0, -1.0, -1.0, -1.0, -1.0
, 0.0, 0.0, 2.0, -1.0, -1.0, -1.0, -1.0
, -1.0, -1.0, -1.0, -1.0, 5.0, 0.0, 0.0
, -1.0, -1.0, -1.0, -1.0, 0.0, 7.0, 0.0
, -1.0, -1.0, -1.0, -1.0, 0.0, 0.0, 2.0 ]@
-}
fromBlocks :: Field t => [[Matrix t]] -> Matrix t
fromBlocks = joinVert . map joinHoriz
-- | Reverse rows
flipud :: Field t => Matrix t -> Matrix t
flipud m = fromRows . reverse . toRows $ m
-- | Reverse columns
fliprl :: Field t => Matrix t -> Matrix t
fliprl m = fromColumns . reverse . toColumns $ m
------------------------------------------------------------
diagRect :: (Field t, Num t) => Vector t -> Int -> Int -> Matrix t
diagRect s r c
| dim s < min r c = error "diagRect"
| r == c = diag s
| r < c = trans $ diagRect s c r
| r > c = joinVert [diag s , zeros (r-c,c)]
where zeros (r,c) = reshape c $ constant 0 (r*c)
takeDiag :: (Storable t) => Matrix t -> Vector t
takeDiag m = fromList [cdat m `at` (k*cols m+k) | k <- [0 .. min (rows m) (cols m) -1]]
ident :: (Num t, Field t) => Int -> Matrix t
ident n = diag (constant 1 n)
(><) :: (Field a) => Int -> Int -> [a] -> Matrix a
r >< c = f where
f l | dim v == r*c = matrixFromVector RowMajor c v
| otherwise = error $ "inconsistent list size = "
++show (dim v) ++"in ("++show r++"><"++show c++")"
where v = fromList l
(>|<) :: (Field a) => Int -> Int -> [a] -> Matrix a
r >|< c = f where
f l | dim v == r*c = matrixFromVector ColumnMajor c v
| otherwise = error $ "inconsistent list size = "
++show (dim v) ++"in ("++show r++"><"++show c++")"
where v = fromList l
----------------------------------------------------------------
-- | Creates a matrix with the first n rows of another matrix
takeRows :: Field t => Int -> Matrix t -> Matrix t
takeRows n mat = subMatrix (0,0) (n, cols mat) mat
-- | Creates a copy of a matrix without the first n rows
dropRows :: Field t => Int -> Matrix t -> Matrix t
dropRows n mat = subMatrix (n,0) (rows mat - n, cols mat) mat
-- |Creates a matrix with the first n columns of another matrix
takeColumns :: Field t => Int -> Matrix t -> Matrix t
takeColumns n mat = subMatrix (0,0) (rows mat, n) mat
-- | Creates a copy of a matrix without the first n columns
dropColumns :: Field t => Int -> Matrix t -> Matrix t
dropColumns n mat = subMatrix (0,n) (rows mat, cols mat - n) mat
----------------------------------------------------------------
{- | Creates a vector by concatenation of rows
@\> flatten ('ident' 3)
9 # [1.0,0.0,0.0,0.0,1.0,0.0,0.0,0.0,1.0]@
-}
flatten :: Matrix t -> Vector t
flatten = cdat
-- | Creates a 'Matrix' from a list of lists (considered as rows).
fromLists :: Field t => [[t]] -> Matrix t
fromLists = fromRows . map fromList
conjTrans :: Matrix (Complex Double) -> Matrix (Complex Double)
conjTrans = trans . liftMatrix conj
asRow :: Field a => Vector a -> Matrix a
asRow v = reshape (dim v) v
asColumn :: Field a => Vector a -> Matrix a
asColumn v = reshape 1 v
|