summaryrefslogtreecommitdiff
path: root/lib/GSL/Matrix.hs
diff options
context:
space:
mode:
authorAlberto Ruiz <aruiz@um.es>2007-10-01 15:04:16 +0000
committerAlberto Ruiz <aruiz@um.es>2007-10-01 15:04:16 +0000
commitc99b8fd6e3f8a2fb365ec12baf838f864b118ece (patch)
tree11b5b8515861fe88d547253ae10c2182d5fadaf2 /lib/GSL/Matrix.hs
parent768f08d4134a066d773d56a9c03ae688e3850352 (diff)
LinearAlgebra and GSL moved to Numeric
Diffstat (limited to 'lib/GSL/Matrix.hs')
-rw-r--r--lib/GSL/Matrix.hs301
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
15module GSL.Matrix(
16 eigSg, eigHg,
17 svdg,
18 qr,
19 cholR, -- cholC,
20 luSolveR, luSolveC,
21 luR, luC
22) where
23
24import Data.Packed.Internal
25import Data.Packed.Matrix(fromLists,ident,takeDiag)
26import GSL.Vector
27import Foreign
28import 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-}
45eigSg :: Matrix Double -> (Vector Double, Matrix Double)
46eigSg 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
54foreign 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-}
76eigHg :: Matrix (Complex Double)-> (Vector Double, Matrix (Complex Double))
77eigHg 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
85foreign 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
930.310 -0.951
940.951 0.310
95\
96\> s
978.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-}
109svdg :: Matrix Double -> (Matrix Double, Vector Double, Matrix Double)
110svdg x = if rows x >= cols x
111 then svd' x
112 else (v, s, u) where (u,s,v) = svd' (trans x)
113
114svd' 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
122foreign 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
1371.000 3.000 5.000 7.000
1382.000 0. -2.000 4.000@
139
140-}
141qr :: Matrix Double -> (Matrix Double, Matrix Double)
142qr 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
149foreign 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-}
160cholR :: Matrix Double -> Matrix Double
161cholR 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
166foreign import ccall "gsl-aux.h cholR" c_cholR :: TMM
167
168cholC :: Matrix (Complex Double) -> Matrix (Complex Double)
169cholC 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
174foreign 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-}
181luSolveR :: Matrix Double -> Matrix Double -> Matrix Double
182luSolveR 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
192foreign import ccall "gsl-aux.h luSolveR" c_luSolveR :: TMMM
193
194{- -| efficient multiplication by the inverse of a matrix (for complex matrices).
195-}
196luSolveC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double)
197luSolveC 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
207foreign 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-}
211luRaux :: Matrix Double -> Vector Double
212luRaux 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
218foreign 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-}
222luCaux :: Matrix (Complex Double) -> Vector (Complex Double)
223luCaux 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
229foreign 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
236L is the lower triangular:
237
238@\> l
239 1. 0. 0.
2400.154-0.231i 1. 0.
2410.154-0.231i 0.624-0.522i 1.@
242
243U is the upper triangular:
244
245@\> u
2462.+3.i -7. 0.
247 0. 3.077-1.615i -3.
248 0. 0. 1.873+0.433i@
249
250p is a permutation:
251
252@\> p
253[1,0,2]@
254
255L \* 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
267s 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 -}
275luR :: Matrix Double -> (Matrix Double, Matrix Double, [Int], Double)
276luR 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'.
287luC :: Matrix (Complex Double) -> (Matrix (Complex Double), Matrix (Complex Double), [Int], Complex Double)
288luC 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-}
300triang 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