diff options
author | Alberto Ruiz <aruiz@um.es> | 2007-10-01 15:04:16 +0000 |
---|---|---|
committer | Alberto Ruiz <aruiz@um.es> | 2007-10-01 15:04:16 +0000 |
commit | c99b8fd6e3f8a2fb365ec12baf838f864b118ece (patch) | |
tree | 11b5b8515861fe88d547253ae10c2182d5fadaf2 /lib/GSL/Matrix.hs | |
parent | 768f08d4134a066d773d56a9c03ae688e3850352 (diff) |
LinearAlgebra and GSL moved to Numeric
Diffstat (limited to 'lib/GSL/Matrix.hs')
-rw-r--r-- | lib/GSL/Matrix.hs | 301 |
1 files changed, 0 insertions, 301 deletions
diff --git a/lib/GSL/Matrix.hs b/lib/GSL/Matrix.hs deleted file mode 100644 index 3a54226..0000000 --- a/lib/GSL/Matrix.hs +++ /dev/null | |||
@@ -1,301 +0,0 @@ | |||
1 | ----------------------------------------------------------------------------- | ||
2 | -- | | ||
3 | -- Module : GSL.Matrix | ||
4 | -- Copyright : (c) Alberto Ruiz 2007 | ||
5 | -- License : GPL-style | ||
6 | -- | ||
7 | -- Maintainer : Alberto Ruiz <aruiz@um.es> | ||
8 | -- Stability : provisional | ||
9 | -- Portability : portable (uses FFI) | ||
10 | -- | ||
11 | -- A few linear algebra computations based on the GSL (<http://www.gnu.org/software/gsl>). | ||
12 | -- | ||
13 | ----------------------------------------------------------------------------- | ||
14 | |||
15 | module GSL.Matrix( | ||
16 | eigSg, eigHg, | ||
17 | svdg, | ||
18 | qr, | ||
19 | cholR, -- cholC, | ||
20 | luSolveR, luSolveC, | ||
21 | luR, luC | ||
22 | ) where | ||
23 | |||
24 | import Data.Packed.Internal | ||
25 | import Data.Packed.Matrix(fromLists,ident,takeDiag) | ||
26 | import GSL.Vector | ||
27 | import Foreign | ||
28 | import Complex | ||
29 | |||
30 | {- | eigendecomposition of a real symmetric matrix using /gsl_eigen_symmv/. | ||
31 | |||
32 | > > let (l,v) = eigS $ 'fromLists' [[1,2],[2,1]] | ||
33 | > > l | ||
34 | > 3.000 -1.000 | ||
35 | > | ||
36 | > > v | ||
37 | > 0.707 -0.707 | ||
38 | > 0.707 0.707 | ||
39 | > | ||
40 | > > v <> diag l <> trans v | ||
41 | > 1.000 2.000 | ||
42 | > 2.000 1.000 | ||
43 | |||
44 | -} | ||
45 | eigSg :: Matrix Double -> (Vector Double, Matrix Double) | ||
46 | eigSg m | ||
47 | | r == 1 = (fromList [cdat m `at` 0], singleton 1) | ||
48 | | otherwise = unsafePerformIO $ do | ||
49 | l <- createVector r | ||
50 | v <- createMatrix RowMajor r r | ||
51 | c_eigS // mat cdat m // vec l // mat dat v // check "eigSg" [cdat m] | ||
52 | return (l,v) | ||
53 | where r = rows m | ||
54 | foreign import ccall "gsl-aux.h eigensystemR" c_eigS :: TMVM | ||
55 | |||
56 | ------------------------------------------------------------------ | ||
57 | |||
58 | |||
59 | |||
60 | {- | eigendecomposition of a complex hermitian matrix using /gsl_eigen_hermv/ | ||
61 | |||
62 | > > let (l,v) = eigH $ 'fromLists' [[1,2+i],[2-i,3]] | ||
63 | > | ||
64 | > > l | ||
65 | > 4.449 -0.449 | ||
66 | > | ||
67 | > > v | ||
68 | > -0.544 0.839 | ||
69 | > (-0.751,0.375) (-0.487,0.243) | ||
70 | > | ||
71 | > > v <> diag l <> (conjTrans) v | ||
72 | > 1.000 (2.000,1.000) | ||
73 | > (2.000,-1.000) 3.000 | ||
74 | |||
75 | -} | ||
76 | eigHg :: Matrix (Complex Double)-> (Vector Double, Matrix (Complex Double)) | ||
77 | eigHg m | ||
78 | | r == 1 = (fromList [realPart $ cdat m `at` 0], singleton 1) | ||
79 | | otherwise = unsafePerformIO $ do | ||
80 | l <- createVector r | ||
81 | v <- createMatrix RowMajor r r | ||
82 | c_eigH // mat cdat m // vec l // mat dat v // check "eigHg" [cdat m] | ||
83 | return (l,v) | ||
84 | where r = rows m | ||
85 | foreign import ccall "gsl-aux.h eigensystemC" c_eigH :: TCMVCM | ||
86 | |||
87 | |||
88 | {- | Singular value decomposition of a real matrix, using /gsl_linalg_SV_decomp_mod/: | ||
89 | |||
90 | @\> let (u,s,v) = svdg $ 'fromLists' [[1,2,3],[-4,1,7]] | ||
91 | \ | ||
92 | \> u | ||
93 | 0.310 -0.951 | ||
94 | 0.951 0.310 | ||
95 | \ | ||
96 | \> s | ||
97 | 8.497 2.792 | ||
98 | \ | ||
99 | \> v | ||
100 | -0.411 -0.785 | ||
101 | 0.185 -0.570 | ||
102 | 0.893 -0.243 | ||
103 | \ | ||
104 | \> u \<\> 'diag' s \<\> 'trans' v | ||
105 | 1. 2. 3. | ||
106 | -4. 1. 7.@ | ||
107 | |||
108 | -} | ||
109 | svdg :: Matrix Double -> (Matrix Double, Vector Double, Matrix Double) | ||
110 | svdg x = if rows x >= cols x | ||
111 | then svd' x | ||
112 | else (v, s, u) where (u,s,v) = svd' (trans x) | ||
113 | |||
114 | svd' x = unsafePerformIO $ do | ||
115 | u <- createMatrix RowMajor r c | ||
116 | s <- createVector c | ||
117 | v <- createMatrix RowMajor c c | ||
118 | c_svd // mat cdat x // mat dat u // vec s // mat dat v // check "svdg" [cdat x] | ||
119 | return (u,s,v) | ||
120 | where r = rows x | ||
121 | c = cols x | ||
122 | foreign import ccall "gsl-aux.h svd" c_svd :: TMMVM | ||
123 | |||
124 | {- | QR decomposition of a real matrix using /gsl_linalg_QR_decomp/ and /gsl_linalg_QR_unpack/. | ||
125 | |||
126 | @\> let (q,r) = qr $ 'fromLists' [[1,3,5,7],[2,0,-2,4]] | ||
127 | \ | ||
128 | \> q | ||
129 | -0.447 -0.894 | ||
130 | -0.894 0.447 | ||
131 | \ | ||
132 | \> r | ||
133 | -2.236 -1.342 -0.447 -6.708 | ||
134 | 0. -2.683 -5.367 -4.472 | ||
135 | \ | ||
136 | \> q \<\> r | ||
137 | 1.000 3.000 5.000 7.000 | ||
138 | 2.000 0. -2.000 4.000@ | ||
139 | |||
140 | -} | ||
141 | qr :: Matrix Double -> (Matrix Double, Matrix Double) | ||
142 | qr x = unsafePerformIO $ do | ||
143 | q <- createMatrix RowMajor r r | ||
144 | rot <- createMatrix RowMajor r c | ||
145 | c_qr // mat cdat x // mat dat q // mat dat rot // check "qr" [cdat x] | ||
146 | return (q,rot) | ||
147 | where r = rows x | ||
148 | c = cols x | ||
149 | foreign import ccall "gsl-aux.h QR" c_qr :: TMMM | ||
150 | |||
151 | {- | Cholesky decomposition of a symmetric positive definite real matrix using /gsl_linalg_cholesky_decomp/. | ||
152 | |||
153 | @\> chol $ (2><2) [1,2, | ||
154 | 2,9::Double] | ||
155 | (2><2) | ||
156 | [ 1.0, 0.0 | ||
157 | , 2.0, 2.23606797749979 ]@ | ||
158 | |||
159 | -} | ||
160 | cholR :: Matrix Double -> Matrix Double | ||
161 | cholR x = unsafePerformIO $ do | ||
162 | res <- createMatrix RowMajor r r | ||
163 | c_cholR // mat cdat x // mat dat res // check "cholR" [cdat x] | ||
164 | return res | ||
165 | where r = rows x | ||
166 | foreign import ccall "gsl-aux.h cholR" c_cholR :: TMM | ||
167 | |||
168 | cholC :: Matrix (Complex Double) -> Matrix (Complex Double) | ||
169 | cholC x = unsafePerformIO $ do | ||
170 | res <- createMatrix RowMajor r r | ||
171 | c_cholC // mat cdat x // mat dat res // check "cholC" [cdat x] | ||
172 | return res | ||
173 | where r = rows x | ||
174 | foreign import ccall "gsl-aux.h cholC" c_cholC :: TCMCM | ||
175 | |||
176 | |||
177 | -------------------------------------------------------- | ||
178 | |||
179 | {- -| efficient multiplication by the inverse of a matrix (for real matrices) | ||
180 | -} | ||
181 | luSolveR :: Matrix Double -> Matrix Double -> Matrix Double | ||
182 | luSolveR a b | ||
183 | | n1==n2 && n1==r = unsafePerformIO $ do | ||
184 | s <- createMatrix RowMajor r c | ||
185 | c_luSolveR // mat cdat a // mat cdat b // mat dat s // check "luSolveR" [cdat a, cdat b] | ||
186 | return s | ||
187 | | otherwise = error "luSolveR of nonsquare matrix" | ||
188 | where n1 = rows a | ||
189 | n2 = cols a | ||
190 | r = rows b | ||
191 | c = cols b | ||
192 | foreign import ccall "gsl-aux.h luSolveR" c_luSolveR :: TMMM | ||
193 | |||
194 | {- -| efficient multiplication by the inverse of a matrix (for complex matrices). | ||
195 | -} | ||
196 | luSolveC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double) | ||
197 | luSolveC a b | ||
198 | | n1==n2 && n1==r = unsafePerformIO $ do | ||
199 | s <- createMatrix RowMajor r c | ||
200 | c_luSolveC // mat cdat a // mat cdat b // mat dat s // check "luSolveC" [cdat a, cdat b] | ||
201 | return s | ||
202 | | otherwise = error "luSolveC of nonsquare matrix" | ||
203 | where n1 = rows a | ||
204 | n2 = cols a | ||
205 | r = rows b | ||
206 | c = cols b | ||
207 | foreign import ccall "gsl-aux.h luSolveC" c_luSolveC :: TCMCMCM | ||
208 | |||
209 | {- | lu decomposition of real matrix (packed as a vector including l, u, the permutation and sign) | ||
210 | -} | ||
211 | luRaux :: Matrix Double -> Vector Double | ||
212 | luRaux x = unsafePerformIO $ do | ||
213 | res <- createVector (r*r+r+1) | ||
214 | c_luRaux // mat cdat x // vec res // check "luRaux" [cdat x] | ||
215 | return res | ||
216 | where r = rows x | ||
217 | c = cols x | ||
218 | foreign import ccall "gsl-aux.h luRaux" c_luRaux :: TMV | ||
219 | |||
220 | {- | lu decomposition of complex matrix (packed as a vector including l, u, the permutation and sign) | ||
221 | -} | ||
222 | luCaux :: Matrix (Complex Double) -> Vector (Complex Double) | ||
223 | luCaux x = unsafePerformIO $ do | ||
224 | res <- createVector (r*r+r+1) | ||
225 | c_luCaux // mat cdat x // vec res // check "luCaux" [cdat x] | ||
226 | return res | ||
227 | where r = rows x | ||
228 | c = cols x | ||
229 | foreign import ccall "gsl-aux.h luCaux" c_luCaux :: TCMCV | ||
230 | |||
231 | {- | The LU decomposition of a square matrix. Is based on /gsl_linalg_LU_decomp/ and /gsl_linalg_complex_LU_decomp/ as described in <http://www.gnu.org/software/gsl/manual/gsl-ref_13.html#SEC223>. | ||
232 | |||
233 | @\> let m = 'fromLists' [[1,2,-3],[2+3*i,-7,0],[1,-i,2*i]] | ||
234 | \> let (l,u,p,s) = luR m@ | ||
235 | |||
236 | L is the lower triangular: | ||
237 | |||
238 | @\> l | ||
239 | 1. 0. 0. | ||
240 | 0.154-0.231i 1. 0. | ||
241 | 0.154-0.231i 0.624-0.522i 1.@ | ||
242 | |||
243 | U is the upper triangular: | ||
244 | |||
245 | @\> u | ||
246 | 2.+3.i -7. 0. | ||
247 | 0. 3.077-1.615i -3. | ||
248 | 0. 0. 1.873+0.433i@ | ||
249 | |||
250 | p is a permutation: | ||
251 | |||
252 | @\> p | ||
253 | [1,0,2]@ | ||
254 | |||
255 | L \* U obtains a permuted version of the original matrix: | ||
256 | |||
257 | @\> extractRows p m | ||
258 | 2.+3.i -7. 0. | ||
259 | 1. 2. -3. | ||
260 | 1. -1.i 2.i | ||
261 | \ | ||
262 | \> l \<\> u | ||
263 | 2.+3.i -7. 0. | ||
264 | 1. 2. -3. | ||
265 | 1. -1.i 2.i@ | ||
266 | |||
267 | s is the sign of the permutation, required to obtain sign of the determinant: | ||
268 | |||
269 | @\> s * product ('toList' $ 'takeDiag' u) | ||
270 | (-18.0) :+ (-16.000000000000004) | ||
271 | \> 'LinearAlgebra.Algorithms.det' m | ||
272 | (-18.0) :+ (-16.000000000000004)@ | ||
273 | |||
274 | -} | ||
275 | luR :: Matrix Double -> (Matrix Double, Matrix Double, [Int], Double) | ||
276 | luR m = (l,u,p, fromIntegral s') where | ||
277 | r = rows m | ||
278 | v = luRaux m | ||
279 | lu = reshape r $ subVector 0 (r*r) v | ||
280 | s':p = map round . toList . subVector (r*r) (r+1) $ v | ||
281 | u = triang r r 0 1`mul` lu | ||
282 | l = (triang r r 0 0 `mul` lu) `add` ident r | ||
283 | add = liftMatrix2 $ vectorZipR Add | ||
284 | mul = liftMatrix2 $ vectorZipR Mul | ||
285 | |||
286 | -- | Complex version of 'luR'. | ||
287 | luC :: Matrix (Complex Double) -> (Matrix (Complex Double), Matrix (Complex Double), [Int], Complex Double) | ||
288 | luC m = (l,u,p, fromIntegral s') where | ||
289 | r = rows m | ||
290 | v = luCaux m | ||
291 | lu = reshape r $ subVector 0 (r*r) v | ||
292 | s':p = map (round.realPart) . toList . subVector (r*r) (r+1) $ v | ||
293 | u = triang r r 0 1 `mul` lu | ||
294 | l = (triang r r 0 0 `mul` lu) `add` liftMatrix comp (ident r) | ||
295 | add = liftMatrix2 $ vectorZipC Add | ||
296 | mul = liftMatrix2 $ vectorZipC Mul | ||
297 | |||
298 | {- auxiliary function to get triangular matrices | ||
299 | -} | ||
300 | triang r c h v = reshape c $ fromList [el i j | i<-[0..r-1], j<-[0..c-1]] | ||
301 | where el i j = if j-i>=h then v else 1 - v | ||