summaryrefslogtreecommitdiff
path: root/lib/Numeric/LinearAlgebra/LAPACK.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/Numeric/LinearAlgebra/LAPACK.hs
parent768f08d4134a066d773d56a9c03ae688e3850352 (diff)
LinearAlgebra and GSL moved to Numeric
Diffstat (limited to 'lib/Numeric/LinearAlgebra/LAPACK.hs')
-rw-r--r--lib/Numeric/LinearAlgebra/LAPACK.hs335
1 files changed, 335 insertions, 0 deletions
diff --git a/lib/Numeric/LinearAlgebra/LAPACK.hs b/lib/Numeric/LinearAlgebra/LAPACK.hs
new file mode 100644
index 0000000..648e59f
--- /dev/null
+++ b/lib/Numeric/LinearAlgebra/LAPACK.hs
@@ -0,0 +1,335 @@
1{-# OPTIONS_GHC -fglasgow-exts #-}
2-----------------------------------------------------------------------------
3-- |
4-- Module : Numeric.LinearAlgebra.LAPACK
5-- Copyright : (c) Alberto Ruiz 2006-7
6-- License : GPL-style
7--
8-- Maintainer : Alberto Ruiz (aruiz at um dot es)
9-- Stability : provisional
10-- Portability : portable (uses FFI)
11--
12-- Wrappers for a few LAPACK functions (<http://www.netlib.org/lapack>).
13--
14-----------------------------------------------------------------------------
15
16module Numeric.LinearAlgebra.LAPACK (
17 svdR, svdRdd, svdC,
18 eigC, eigR, eigS, eigH, eigS', eigH',
19 linearSolveR, linearSolveC,
20 linearSolveLSR, linearSolveLSC,
21 linearSolveSVDR, linearSolveSVDC,
22 cholS, cholH,
23 qrR, qrC
24) where
25
26import Data.Packed.Internal
27import Data.Packed.Internal.Vector
28import Data.Packed.Internal.Matrix
29import Data.Packed.Vector
30import Data.Packed.Matrix
31import Numeric.GSL.Vector(vectorMapValR, FunCodeSV(Scale))
32import Complex
33import Foreign
34
35-----------------------------------------------------------------------------
36foreign import ccall "LAPACK/lapack-aux.h svd_l_R" dgesvd :: TMMVM
37
38-- | Wrapper for LAPACK's /dgesvd/, which computes the full svd decomposition of a real matrix.
39--
40-- @(u,s,v)=full svdR m@ so that @m=u \<\> s \<\> 'trans' v@.
41svdR :: Matrix Double -> (Matrix Double, Vector Double, Matrix Double)
42svdR x = unsafePerformIO $ do
43 u <- createMatrix ColumnMajor r r
44 s <- createVector (min r c)
45 v <- createMatrix ColumnMajor c c
46 dgesvd // mat fdat x // mat dat u // vec s // mat dat v // check "svdR" [fdat x]
47 return (u,s,trans v)
48 where r = rows x
49 c = cols x
50-----------------------------------------------------------------------------
51foreign import ccall "LAPACK/lapack-aux.h svd_l_Rdd" dgesdd :: TMMVM
52
53-- | Wrapper for LAPACK's /dgesvd/, which computes the full svd decomposition of a real matrix.
54--
55-- @(u,s,v)=full svdRdd m@ so that @m=u \<\> s \<\> 'trans' v@.
56svdRdd :: Matrix Double -> (Matrix Double, Vector Double, Matrix Double)
57svdRdd x = unsafePerformIO $ do
58 u <- createMatrix ColumnMajor r r
59 s <- createVector (min r c)
60 v <- createMatrix ColumnMajor c c
61 dgesdd // mat fdat x // mat dat u // vec s // mat dat v // check "svdRdd" [fdat x]
62 return (u,s,trans v)
63 where r = rows x
64 c = cols x
65
66-----------------------------------------------------------------------------
67foreign import ccall "LAPACK/lapack-aux.h svd_l_C" zgesvd :: TCMCMVCM
68
69-- | Wrapper for LAPACK's /zgesvd/, which computes the full svd decomposition of a complex matrix.
70--
71-- @(u,s,v)=full svdC m@ so that @m=u \<\> comp s \<\> 'trans' v@.
72svdC :: Matrix (Complex Double) -> (Matrix (Complex Double), Vector Double, Matrix (Complex Double))
73svdC x = unsafePerformIO $ do
74 u <- createMatrix ColumnMajor r r
75 s <- createVector (min r c)
76 v <- createMatrix ColumnMajor c c
77 zgesvd // mat fdat x // mat dat u // vec s // mat dat v // check "svdC" [fdat x]
78 return (u,s,trans v)
79 where r = rows x
80 c = cols x
81
82
83-----------------------------------------------------------------------------
84foreign import ccall "LAPACK/lapack-aux.h eig_l_C" zgeev :: TCMCMCVCM
85
86-- | Wrapper for LAPACK's /zgeev/, which computes the eigenvalues and right eigenvectors of a general complex matrix:
87--
88-- if @(l,v)=eigC m@ then @m \<\> v = v \<\> diag l@.
89--
90-- The eigenvectors are the columns of v.
91-- The eigenvalues are not sorted.
92eigC :: Matrix (Complex Double) -> (Vector (Complex Double), Matrix (Complex Double))
93eigC m
94 | r == 1 = (fromList [cdat m `at` 0], singleton 1)
95 | otherwise = unsafePerformIO $ do
96 l <- createVector r
97 v <- createMatrix ColumnMajor r r
98 dummy <- createMatrix ColumnMajor 1 1
99 zgeev // mat fdat m // mat dat dummy // vec l // mat dat v // check "eigC" [fdat m]
100 return (l,v)
101 where r = rows m
102
103-----------------------------------------------------------------------------
104foreign import ccall "LAPACK/lapack-aux.h eig_l_R" dgeev :: TMMCVM
105
106-- | Wrapper for LAPACK's /dgeev/, which computes the eigenvalues and right eigenvectors of a general real matrix:
107--
108-- if @(l,v)=eigR m@ then @m \<\> v = v \<\> diag l@.
109--
110-- The eigenvectors are the columns of v.
111-- The eigenvalues are not sorted.
112eigR :: Matrix Double -> (Vector (Complex Double), Matrix (Complex Double))
113eigR m = (s', v'')
114 where (s,v) = eigRaux m
115 s' = toComplex (subVector 0 r (asReal s), subVector r r (asReal s))
116 v' = toRows $ trans v
117 v'' = fromColumns $ fixeig (toList s') v'
118 r = rows m
119
120eigRaux :: Matrix Double -> (Vector (Complex Double), Matrix Double)
121eigRaux m
122 | r == 1 = (fromList [(cdat m `at` 0):+0], singleton 1)
123 | otherwise = unsafePerformIO $ do
124 l <- createVector r
125 v <- createMatrix ColumnMajor r r
126 dummy <- createMatrix ColumnMajor 1 1
127 dgeev // mat fdat m // mat dat dummy // vec l // mat dat v // check "eigR" [fdat m]
128 return (l,v)
129 where r = rows m
130
131fixeig [] _ = []
132fixeig [r] [v] = [comp v]
133fixeig ((r1:+i1):(r2:+i2):r) (v1:v2:vs)
134 | r1 == r2 && i1 == (-i2) = toComplex (v1,v2) : toComplex (v1,scale (-1) v2) : fixeig r vs
135 | otherwise = comp v1 : fixeig ((r2:+i2):r) (v2:vs)
136 where scale = vectorMapValR Scale
137
138-----------------------------------------------------------------------------
139foreign import ccall "LAPACK/lapack-aux.h eig_l_S" dsyev :: TMVM
140
141-- | Wrapper for LAPACK's /dsyev/, which computes the eigenvalues and right eigenvectors of a symmetric real matrix:
142--
143-- if @(l,v)=eigSl m@ then @m \<\> v = v \<\> diag l@.
144--
145-- The eigenvectors are the columns of v.
146-- The eigenvalues are sorted in descending order (use eigS' for ascending order).
147eigS :: Matrix Double -> (Vector Double, Matrix Double)
148eigS m = (s', fliprl v)
149 where (s,v) = eigS' m
150 s' = fromList . reverse . toList $ s
151
152eigS' m
153 | r == 1 = (fromList [cdat m `at` 0], singleton 1)
154 | otherwise = unsafePerformIO $ do
155 l <- createVector r
156 v <- createMatrix ColumnMajor r r
157 dsyev // mat fdat m // vec l // mat dat v // check "eigS" [fdat m]
158 return (l,v)
159 where r = rows m
160
161-----------------------------------------------------------------------------
162foreign import ccall "LAPACK/lapack-aux.h eig_l_H" zheev :: TCMVCM
163
164-- | Wrapper for LAPACK's /zheev/, which computes the eigenvalues and right eigenvectors of a hermitian complex matrix:
165--
166-- if @(l,v)=eigH m@ then @m \<\> s v = v \<\> diag l@.
167--
168-- The eigenvectors are the columns of v.
169-- The eigenvalues are sorted in descending order (use eigH' for ascending order).
170eigH :: Matrix (Complex Double) -> (Vector Double, Matrix (Complex Double))
171eigH m = (s', fliprl v)
172 where (s,v) = eigH' m
173 s' = fromList . reverse . toList $ s
174
175eigH' m
176 | r == 1 = (fromList [realPart (cdat m `at` 0)], singleton 1)
177 | otherwise = unsafePerformIO $ do
178 l <- createVector r
179 v <- createMatrix ColumnMajor r r
180 zheev // mat fdat m // vec l // mat dat v // check "eigH" [fdat m]
181 return (l,v)
182 where r = rows m
183
184-----------------------------------------------------------------------------
185foreign import ccall "LAPACK/lapack-aux.h linearSolveR_l" dgesv :: TMMM
186
187-- | Wrapper for LAPACK's /dgesv/, which solves a general real linear system (for several right-hand sides) internally using the lu decomposition.
188linearSolveR :: Matrix Double -> Matrix Double -> Matrix Double
189linearSolveR a b
190 | n1==n2 && n1==r = unsafePerformIO $ do
191 s <- createMatrix ColumnMajor r c
192 dgesv // mat fdat a // mat fdat b // mat dat s // check "linearSolveR" [fdat a, fdat b]
193 return s
194 | otherwise = error "linearSolveR of nonsquare matrix"
195 where n1 = rows a
196 n2 = cols a
197 r = rows b
198 c = cols b
199
200-----------------------------------------------------------------------------
201foreign import ccall "LAPACK/lapack-aux.h linearSolveC_l" zgesv :: TCMCMCM
202
203-- | Wrapper for LAPACK's /zgesv/, which solves a general complex linear system (for several right-hand sides) internally using the lu decomposition.
204linearSolveC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double)
205linearSolveC a b
206 | n1==n2 && n1==r = unsafePerformIO $ do
207 s <- createMatrix ColumnMajor r c
208 zgesv // mat fdat a // mat fdat b // mat dat s // check "linearSolveC" [fdat a, fdat b]
209 return s
210 | otherwise = error "linearSolveC of nonsquare matrix"
211 where n1 = rows a
212 n2 = cols a
213 r = rows b
214 c = cols b
215
216-----------------------------------------------------------------------------------
217foreign import ccall "LAPACK/lapack-aux.h linearSolveLSR_l" dgels :: TMMM
218
219-- | Wrapper for LAPACK's /dgels/, which obtains the least squared error solution of an overconstrained real linear system or the minimum norm solution of an underdetermined system, for several right-hand sides. For rank deficient systems use 'linearSolveSVDR'.
220linearSolveLSR :: Matrix Double -> Matrix Double -> Matrix Double
221linearSolveLSR a b = subMatrix (0,0) (cols a, cols b) $ linearSolveLSR_l a b
222
223linearSolveLSR_l a b = unsafePerformIO $ do
224 r <- createMatrix ColumnMajor (max m n) nrhs
225 dgels // mat fdat a // mat fdat b // mat dat r // check "linearSolveLSR" [fdat a, fdat b]
226 return r
227 where m = rows a
228 n = cols a
229 nrhs = cols b
230
231-----------------------------------------------------------------------------------
232foreign import ccall "LAPACK/lapack-aux.h linearSolveLSC_l" zgels :: TCMCMCM
233
234-- | Wrapper for LAPACK's /zgels/, which obtains the least squared error solution of an overconstrained complex linear system or the minimum norm solution of an underdetermined system, for several right-hand sides. For rank deficient systems use 'linearSolveSVDC'.
235linearSolveLSC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double)
236linearSolveLSC a b = subMatrix (0,0) (cols a, cols b) $ linearSolveLSC_l a b
237
238linearSolveLSC_l a b = unsafePerformIO $ do
239 r <- createMatrix ColumnMajor (max m n) nrhs
240 zgels // mat fdat a // mat fdat b // mat dat r // check "linearSolveLSC" [fdat a, fdat b]
241 return r
242 where m = rows a
243 n = cols a
244 nrhs = cols b
245
246-----------------------------------------------------------------------------------
247foreign import ccall "LAPACK/lapack-aux.h linearSolveSVDR_l" dgelss :: Double -> TMMM
248
249-- | Wrapper for LAPACK's /dgelss/, which obtains the minimum norm solution to a real linear least squares problem Ax=B using the svd, for several right-hand sides. Admits rank deficient systems but it is slower than 'linearSolveLSR'. The effective rank of A is determined by treating as zero those singular valures which are less than rcond times the largest singular value. If rcond == Nothing machine precision is used.
250linearSolveSVDR :: Maybe Double -- ^ rcond
251 -> Matrix Double -- ^ coefficient matrix
252 -> Matrix Double -- ^ right hand sides (as columns)
253 -> Matrix Double -- ^ solution vectors (as columns)
254linearSolveSVDR (Just rcond) a b = subMatrix (0,0) (cols a, cols b) $ linearSolveSVDR_l rcond a b
255linearSolveSVDR Nothing a b = linearSolveSVDR (Just (-1)) a b
256
257linearSolveSVDR_l rcond a b = unsafePerformIO $ do
258 r <- createMatrix ColumnMajor (max m n) nrhs
259 dgelss rcond // mat fdat a // mat fdat b // mat dat r // check "linearSolveSVDR" [fdat a, fdat b]
260 return r
261 where m = rows a
262 n = cols a
263 nrhs = cols b
264
265-----------------------------------------------------------------------------------
266foreign import ccall "LAPACK/lapack-aux.h linearSolveSVDC_l" zgelss :: Double -> TCMCMCM
267
268-- | Wrapper for LAPACK's /zgelss/, which obtains the minimum norm solution to a complex linear least squares problem Ax=B using the svd, for several right-hand sides. Admits rank deficient systems but it is slower than 'linearSolveLSC'. The effective rank of A is determined by treating as zero those singular valures which are less than rcond times the largest singular value. If rcond == Nothing machine precision is used.
269linearSolveSVDC :: Maybe Double -- ^ rcond
270 -> Matrix (Complex Double) -- ^ coefficient matrix
271 -> Matrix (Complex Double) -- ^ right hand sides (as columns)
272 -> Matrix (Complex Double) -- ^ solution vectors (as columns)
273linearSolveSVDC (Just rcond) a b = subMatrix (0,0) (cols a, cols b) $ linearSolveSVDC_l rcond a b
274linearSolveSVDC Nothing a b = linearSolveSVDC (Just (-1)) a b
275
276linearSolveSVDC_l rcond a b = unsafePerformIO $ do
277 r <- createMatrix ColumnMajor (max m n) nrhs
278 zgelss rcond // mat fdat a // mat fdat b // mat dat r // check "linearSolveSVDC" [fdat a, fdat b]
279 return r
280 where m = rows a
281 n = cols a
282 nrhs = cols b
283
284-----------------------------------------------------------------------------------
285foreign import ccall "LAPACK/lapack-aux.h chol_l_H" zpotrf :: TCMCM
286
287-- | Wrapper for LAPACK's /zpotrf/,which computes the Cholesky factorization of a
288-- complex Hermitian positive definite matrix.
289cholH :: Matrix (Complex Double) -> Matrix (Complex Double)
290cholH a = unsafePerformIO $ do
291 r <- createMatrix ColumnMajor n n
292 zpotrf // mat fdat a // mat dat r // check "cholH" [fdat a]
293 return r
294 where n = rows a
295
296-----------------------------------------------------------------------------------
297foreign import ccall "LAPACK/lapack-aux.h chol_l_S" dpotrf :: TMM
298
299-- | Wrapper for LAPACK's /dpotrf/,which computes the Cholesky factorization of a
300-- real symmetric positive definite matrix.
301cholS :: Matrix Double -> Matrix Double
302cholS a = unsafePerformIO $ do
303 r <- createMatrix ColumnMajor n n
304 dpotrf // mat fdat a // mat dat r // check "cholS" [fdat a]
305 return r
306 where n = rows a
307
308-----------------------------------------------------------------------------------
309foreign import ccall "LAPACK/lapack-aux.h qr_l_R" dgeqr2 :: TMVM
310
311-- | Wrapper for LAPACK's /dgeqr2/,which computes a QR factorization of a real matrix.
312qrR :: Matrix Double -> (Matrix Double, Vector Double)
313qrR a = unsafePerformIO $ do
314 r <- createMatrix ColumnMajor m n
315 tau <- createVector mn
316 dgeqr2 // mat fdat a // vec tau // mat dat r // check "qrR" [fdat a]
317 return (r,tau)
318 where m = rows a
319 n = cols a
320 mn = min m n
321
322-----------------------------------------------------------------------------------
323foreign import ccall "LAPACK/lapack-aux.h qr_l_C" zgeqr2 :: TCMCVCM
324
325-- | Wrapper for LAPACK's /zgeqr2/,which computes a QR factorization of a complex matrix.
326qrC :: Matrix (Complex Double) -> (Matrix (Complex Double), Vector (Complex Double))
327qrC a = unsafePerformIO $ do
328 r <- createMatrix ColumnMajor m n
329 tau <- createVector mn
330 zgeqr2 // mat fdat a // vec tau // mat dat r // check "qrC" [fdat a]
331 return (r,tau)
332 where m = rows a
333 n = cols a
334 mn = min m n
335