diff options
Diffstat (limited to 'lib/LAPACK/Internal.hs')
-rw-r--r-- | lib/LAPACK/Internal.hs | 262 |
1 files changed, 0 insertions, 262 deletions
diff --git a/lib/LAPACK/Internal.hs b/lib/LAPACK/Internal.hs deleted file mode 100644 index ec46b66..0000000 --- a/lib/LAPACK/Internal.hs +++ /dev/null | |||
@@ -1,262 +0,0 @@ | |||
1 | {-# OPTIONS_GHC -fglasgow-exts #-} | ||
2 | ----------------------------------------------------------------------------- | ||
3 | -- | | ||
4 | -- Module : LAPACK.Internal | ||
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 | |||
16 | module LAPACK.Internal where | ||
17 | |||
18 | import Data.Packed.Internal.Vector | ||
19 | import Data.Packed.Internal.Matrix | ||
20 | import Complex | ||
21 | import Foreign | ||
22 | import Foreign.C.Types | ||
23 | import Foreign.C.String | ||
24 | |||
25 | ----------------------------------------------------------------------------- | ||
26 | -- dgesvd | ||
27 | foreign import ccall "lapack-aux.h svd_l_R" | ||
28 | dgesvd :: Double ::> Double ::> (Double :> Double ::> IO Int) | ||
29 | |||
30 | -- | Wrapper for LAPACK's /dgesvd/, which computes the full svd decomposition of a real matrix. | ||
31 | -- | ||
32 | -- @(u,s,v)=svdR m@ so that @m=u \<\> s \<\> 'trans' v@. | ||
33 | svdR :: Matrix Double -> (Matrix Double, Matrix Double , Matrix Double) | ||
34 | svdR x@M {rows = r, cols = c} = (u, diagRect s r c, v) where (u,s,v) = svdR' x | ||
35 | |||
36 | svdR' x@M {rows = r, cols = c} = unsafePerformIO $ do | ||
37 | u <- createMatrix ColumnMajor r r | ||
38 | s <- createVector (min r c) | ||
39 | v <- createMatrix ColumnMajor c c | ||
40 | dgesvd // mat fdat x // mat dat u // vec s // mat dat v // check "svdR" [fdat x] | ||
41 | return (u,s,trans v) | ||
42 | |||
43 | ----------------------------------------------------------------------------- | ||
44 | -- dgesdd | ||
45 | foreign import ccall "lapack-aux.h svd_l_Rdd" | ||
46 | dgesdd :: Double ::> Double ::> (Double :> Double ::> IO Int) | ||
47 | |||
48 | ----------------------------------------------------------------------------- | ||
49 | -- zgesvd | ||
50 | foreign import ccall "lapack-aux.h svd_l_C" | ||
51 | zgesvd :: (Complex Double) ::> (Complex Double) ::> (Double :> (Complex Double) ::> IO Int) | ||
52 | |||
53 | -- | Wrapper for LAPACK's /zgesvd/, which computes the full svd decomposition of a complex matrix. | ||
54 | -- | ||
55 | -- @(u,s,v)=svdC m@ so that @m=u \<\> s \<\> 'trans' v@. | ||
56 | svdC :: Matrix (Complex Double) | ||
57 | -> (Matrix (Complex Double), Matrix Double, Matrix (Complex Double)) | ||
58 | svdC x@M {rows = r, cols = c} = (u, diagRect s r c, v) where (u,s,v) = svdC' x | ||
59 | |||
60 | svdC' x@M {rows = r, cols = c} = unsafePerformIO $ do | ||
61 | u <- createMatrix ColumnMajor r r | ||
62 | s <- createVector (min r c) | ||
63 | v <- createMatrix ColumnMajor c c | ||
64 | zgesvd // mat fdat x // mat dat u // vec s // mat dat v // check "svdC" [fdat x] | ||
65 | return (u,s,trans v) | ||
66 | |||
67 | ----------------------------------------------------------------------------- | ||
68 | -- zgeev | ||
69 | foreign import ccall "lapack-aux.h eig_l_C" | ||
70 | zgeev :: (Complex Double) ::> (Complex Double) ::> ((Complex Double) :> (Complex Double) ::> IO Int) | ||
71 | |||
72 | -- | Wrapper for LAPACK's /zgeev/, which computes the eigenvalues and right eigenvectors of a general complex matrix: | ||
73 | -- | ||
74 | -- if @(l,v)=eigC m@ then @m \<\> v = v \<\> diag l@. | ||
75 | -- | ||
76 | -- The eigenvectors are the columns of v. | ||
77 | -- The eigenvalues are not sorted. | ||
78 | eigC :: Matrix (Complex Double) -> (Vector (Complex Double), Matrix (Complex Double)) | ||
79 | eigC (m@M {rows = r}) | ||
80 | | r == 1 = (fromList [cdat m `at` 0], singleton 1) | ||
81 | | otherwise = unsafePerformIO $ do | ||
82 | l <- createVector r | ||
83 | v <- createMatrix ColumnMajor r r | ||
84 | dummy <- createMatrix ColumnMajor 1 1 | ||
85 | zgeev // mat fdat m // mat dat dummy // vec l // mat dat v // check "eigC" [fdat m] | ||
86 | return (l,v) | ||
87 | |||
88 | ----------------------------------------------------------------------------- | ||
89 | -- dgeev | ||
90 | foreign import ccall "lapack-aux.h eig_l_R" | ||
91 | dgeev :: Double ::> Double ::> ((Complex Double) :> Double ::> IO Int) | ||
92 | |||
93 | -- | Wrapper for LAPACK's /dgeev/, which computes the eigenvalues and right eigenvectors of a general real matrix: | ||
94 | -- | ||
95 | -- if @(l,v)=eigR m@ then @m \<\> v = v \<\> diag l@. | ||
96 | -- | ||
97 | -- The eigenvectors are the columns of v. | ||
98 | -- The eigenvalues are not sorted. | ||
99 | eigR :: Matrix Double -> (Vector (Complex Double), Matrix (Complex Double)) | ||
100 | eigR (m@M {rows = r}) = (s', v'') | ||
101 | where (s,v) = eigRaux m | ||
102 | s' = toComplex (subVector 0 r (asReal s), subVector r r (asReal s)) | ||
103 | v' = toRows $ trans v | ||
104 | v'' = fromColumns $ fixeig (toList s') v' | ||
105 | |||
106 | eigRaux :: Matrix Double -> (Vector (Complex Double), Matrix Double) | ||
107 | eigRaux (m@M {rows = r}) | ||
108 | | r == 1 = (fromList [(cdat m `at` 0):+0], singleton 1) | ||
109 | | otherwise = unsafePerformIO $ do | ||
110 | l <- createVector r | ||
111 | v <- createMatrix ColumnMajor r r | ||
112 | dummy <- createMatrix ColumnMajor 1 1 | ||
113 | dgeev // mat fdat m // mat dat dummy // vec l // mat dat v // check "eigR" [fdat m] | ||
114 | return (l,v) | ||
115 | |||
116 | fixeig [] _ = [] | ||
117 | fixeig [r] [v] = [comp v] | ||
118 | fixeig ((r1:+i1):(r2:+i2):r) (v1:v2:vs) | ||
119 | | r1 == r2 && i1 == (-i2) = toComplex (v1,v2) : toComplex (v1,scale (-1) v2) : fixeig r vs | ||
120 | | otherwise = comp v1 : fixeig ((r2:+i2):r) (v2:vs) | ||
121 | |||
122 | scale r v = fromList [r] `outer` v | ||
123 | |||
124 | ----------------------------------------------------------------------------- | ||
125 | -- dsyev | ||
126 | foreign import ccall "lapack-aux.h eig_l_S" | ||
127 | dsyev :: Double ::> (Double :> Double ::> IO Int) | ||
128 | |||
129 | -- | Wrapper for LAPACK's /dsyev/, which computes the eigenvalues and right eigenvectors of a symmetric real matrix: | ||
130 | -- | ||
131 | -- if @(l,v)=eigSl m@ then @m \<\> v = v \<\> diag l@. | ||
132 | -- | ||
133 | -- The eigenvectors are the columns of v. | ||
134 | -- The eigenvalues are sorted in descending order (use eigS' for ascending order). | ||
135 | eigS :: Matrix Double -> (Vector Double, Matrix Double) | ||
136 | eigS m = (s', fliprl v) | ||
137 | where (s,v) = eigS' m | ||
138 | s' = fromList . reverse . toList $ s | ||
139 | |||
140 | eigS' (m@M {rows = r}) | ||
141 | | r == 1 = (fromList [cdat m `at` 0], singleton 1) | ||
142 | | otherwise = unsafePerformIO $ do | ||
143 | l <- createVector r | ||
144 | v <- createMatrix ColumnMajor r r | ||
145 | dsyev // mat fdat m // vec l // mat dat v // check "eigS" [fdat m] | ||
146 | return (l,v) | ||
147 | |||
148 | ----------------------------------------------------------------------------- | ||
149 | -- zheev | ||
150 | foreign import ccall "lapack-aux.h eig_l_H" | ||
151 | zheev :: (Complex Double) ::> (Double :> (Complex Double) ::> IO Int) | ||
152 | |||
153 | -- | Wrapper for LAPACK's /zheev/, which computes the eigenvalues and right eigenvectors of a hermitian complex matrix: | ||
154 | -- | ||
155 | -- if @(l,v)=eigH m@ then @m \<\> s v = v \<\> diag l@. | ||
156 | -- | ||
157 | -- The eigenvectors are the columns of v. | ||
158 | -- The eigenvalues are sorted in descending order. | ||
159 | eigH :: Matrix (Complex Double) -> (Vector Double, Matrix (Complex Double)) | ||
160 | eigH m = (s', fliprl v) | ||
161 | where (s,v) = eigH' m | ||
162 | s' = fromList . reverse . toList $ s | ||
163 | |||
164 | eigH' (m@M {rows = r}) | ||
165 | | r == 1 = (fromList [realPart (cdat m `at` 0)], singleton 1) | ||
166 | | otherwise = unsafePerformIO $ do | ||
167 | l <- createVector r | ||
168 | v <- createMatrix ColumnMajor r r | ||
169 | zheev // mat fdat m // vec l // mat dat v // check "eigH" [fdat m] | ||
170 | return (l,v) | ||
171 | |||
172 | ----------------------------------------------------------------------------- | ||
173 | -- dgesv | ||
174 | foreign import ccall "lapack-aux.h linearSolveR_l" | ||
175 | dgesv :: Double ::> Double ::> Double ::> IO Int | ||
176 | |||
177 | -- | Wrapper for LAPACK's /dgesv/, which solves a general real linear system (for several right-hand sides) internally using the lu decomposition. | ||
178 | linearSolveR :: Matrix Double -> Matrix Double -> Matrix Double | ||
179 | linearSolveR a@(M {rows = n1, cols = n2}) b@(M {rows = r, cols = c}) | ||
180 | | n1==n2 && n1==r = unsafePerformIO $ do | ||
181 | s <- createMatrix ColumnMajor r c | ||
182 | dgesv // mat fdat a // mat fdat b // mat dat s // check "linearSolveR" [fdat a, fdat b] | ||
183 | return s | ||
184 | | otherwise = error "linearSolveR of nonsquare matrix" | ||
185 | |||
186 | ----------------------------------------------------------------------------- | ||
187 | -- zgesv | ||
188 | foreign import ccall "lapack-aux.h linearSolveC_l" | ||
189 | zgesv :: (Complex Double) ::> (Complex Double) ::> (Complex Double) ::> IO Int | ||
190 | |||
191 | -- | Wrapper for LAPACK's /zgesv/, which solves a general complex linear system (for several right-hand sides) internally using the lu decomposition. | ||
192 | linearSolveC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double) | ||
193 | linearSolveC a@(M {rows = n1, cols = n2}) b@(M {rows = r, cols = c}) | ||
194 | | n1==n2 && n1==r = unsafePerformIO $ do | ||
195 | s <- createMatrix ColumnMajor r c | ||
196 | zgesv // mat fdat a // mat fdat b // mat dat s // check "linearSolveC" [fdat a, fdat b] | ||
197 | return s | ||
198 | | otherwise = error "linearSolveC of nonsquare matrix" | ||
199 | |||
200 | ----------------------------------------------------------------------------------- | ||
201 | -- dgels | ||
202 | foreign import ccall "lapack-aux.h linearSolveLSR_l" | ||
203 | dgels :: Double ::> Double ::> Double ::> IO Int | ||
204 | |||
205 | -- | 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'. | ||
206 | linearSolveLSR :: Matrix Double -> Matrix Double -> Matrix Double | ||
207 | linearSolveLSR a b = subMatrix (0,0) (cols a, cols b) $ linearSolveLSR_l a b | ||
208 | |||
209 | linearSolveLSR_l a@(M {rows = m, cols = n}) b@(M {cols = nrhs}) = unsafePerformIO $ do | ||
210 | r <- createMatrix ColumnMajor (max m n) nrhs | ||
211 | dgels // mat fdat a // mat fdat b // mat dat r // check "linearSolveLSR" [fdat a, fdat b] | ||
212 | return r | ||
213 | |||
214 | ----------------------------------------------------------------------------------- | ||
215 | -- zgels | ||
216 | foreign import ccall "lapack-aux.h linearSolveLSC_l" | ||
217 | zgels :: (Complex Double) ::> (Complex Double) ::> (Complex Double) ::> IO Int | ||
218 | |||
219 | -- | 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'. | ||
220 | linearSolveLSC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double) | ||
221 | linearSolveLSC a b = subMatrix (0,0) (cols a, cols b) $ linearSolveLSC_l a b | ||
222 | |||
223 | linearSolveLSC_l a@(M {rows = m, cols = n}) b@(M {cols = nrhs}) = unsafePerformIO $ do | ||
224 | r <- createMatrix ColumnMajor (max m n) nrhs | ||
225 | zgels // mat fdat a // mat fdat b // mat dat r // check "linearSolveLSC" [fdat a, fdat b] | ||
226 | return r | ||
227 | |||
228 | ----------------------------------------------------------------------------------- | ||
229 | -- dgelss | ||
230 | foreign import ccall "lapack-aux.h linearSolveSVDR_l" | ||
231 | dgelss :: Double -> Double ::> Double ::> Double ::> IO Int | ||
232 | |||
233 | -- | 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. | ||
234 | linearSolveSVDR :: Maybe Double -- ^ rcond | ||
235 | -> Matrix Double -- ^ coefficient matrix | ||
236 | -> Matrix Double -- ^ right hand sides (as columns) | ||
237 | -> Matrix Double -- ^ solution vectors (as columns) | ||
238 | linearSolveSVDR (Just rcond) a b = subMatrix (0,0) (cols a, cols b) $ linearSolveSVDR_l rcond a b | ||
239 | linearSolveSVDR Nothing a b = linearSolveSVDR (Just (-1)) a b | ||
240 | |||
241 | linearSolveSVDR_l rcond a@(M {rows = m, cols = n}) b@(M {cols = nrhs}) = unsafePerformIO $ do | ||
242 | r <- createMatrix ColumnMajor (max m n) nrhs | ||
243 | dgelss rcond // mat fdat a // mat fdat b // mat dat r // check "linearSolveSVDR" [fdat a, fdat b] | ||
244 | return r | ||
245 | |||
246 | ----------------------------------------------------------------------------------- | ||
247 | -- zgelss | ||
248 | foreign import ccall "lapack-aux.h linearSolveSVDC_l" | ||
249 | zgelss :: Double -> (Complex Double) ::> (Complex Double) ::> (Complex Double) ::> IO Int | ||
250 | |||
251 | -- | 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. | ||
252 | linearSolveSVDC :: Maybe Double -- ^ rcond | ||
253 | -> Matrix (Complex Double) -- ^ coefficient matrix | ||
254 | -> Matrix (Complex Double) -- ^ right hand sides (as columns) | ||
255 | -> Matrix (Complex Double) -- ^ solution vectors (as columns) | ||
256 | linearSolveSVDC (Just rcond) a b = subMatrix (0,0) (cols a, cols b) $ linearSolveSVDC_l rcond a b | ||
257 | linearSolveSVDC Nothing a b = linearSolveSVDC (Just (-1)) a b | ||
258 | |||
259 | linearSolveSVDC_l rcond a@(M {rows = m, cols = n}) b@(M {cols = nrhs}) = unsafePerformIO $ do | ||
260 | r <- createMatrix ColumnMajor (max m n) nrhs | ||
261 | zgelss rcond // mat fdat a // mat fdat b // mat dat r // check "linearSolveSVDC" [fdat a, fdat b] | ||
262 | return r | ||