diff options
Diffstat (limited to 'lib/Numeric')
-rw-r--r-- | lib/Numeric/LinearAlgebra/Algorithms.hs | 24 | ||||
-rw-r--r-- | lib/Numeric/LinearAlgebra/LAPACK.hs | 85 | ||||
-rw-r--r-- | lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c | 41 | ||||
-rw-r--r-- | lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.h | 4 | ||||
-rw-r--r-- | lib/Numeric/LinearAlgebra/Tests.hs | 4 | ||||
-rw-r--r-- | lib/Numeric/LinearAlgebra/Tests/Properties.hs | 8 |
6 files changed, 112 insertions, 54 deletions
diff --git a/lib/Numeric/LinearAlgebra/Algorithms.hs b/lib/Numeric/LinearAlgebra/Algorithms.hs index 1544d7c..3d4a209 100644 --- a/lib/Numeric/LinearAlgebra/Algorithms.hs +++ b/lib/Numeric/LinearAlgebra/Algorithms.hs | |||
@@ -40,6 +40,7 @@ module Numeric.LinearAlgebra.Algorithms ( | |||
40 | leftSV, rightSV, | 40 | leftSV, rightSV, |
41 | -- ** Eigensystems | 41 | -- ** Eigensystems |
42 | eig, eigSH, eigSH', | 42 | eig, eigSH, eigSH', |
43 | eigenvalues, eigenvaluesSH, eigenvaluesSH', | ||
43 | -- ** QR | 44 | -- ** QR |
44 | qr, | 45 | qr, |
45 | -- ** Cholesky | 46 | -- ** Cholesky |
@@ -92,6 +93,8 @@ class (Normed (Matrix t), Linear Vector t, Linear Matrix t) => Field t where | |||
92 | linearSolveSVD' :: Matrix t -> Matrix t -> Matrix t | 93 | linearSolveSVD' :: Matrix t -> Matrix t -> Matrix t |
93 | eig' :: Matrix t -> (Vector (Complex Double), Matrix (Complex Double)) | 94 | eig' :: Matrix t -> (Vector (Complex Double), Matrix (Complex Double)) |
94 | eigSH'' :: Matrix t -> (Vector Double, Matrix t) | 95 | eigSH'' :: Matrix t -> (Vector Double, Matrix t) |
96 | eigOnly :: Matrix t -> Vector (Complex Double) | ||
97 | eigOnlySH :: Matrix t -> Vector Double | ||
95 | cholSH' :: Matrix t -> Matrix t | 98 | cholSH' :: Matrix t -> Matrix t |
96 | qr' :: Matrix t -> (Matrix t, Matrix t) | 99 | qr' :: Matrix t -> (Matrix t, Matrix t) |
97 | hess' :: Matrix t -> (Matrix t, Matrix t) | 100 | hess' :: Matrix t -> (Matrix t, Matrix t) |
@@ -129,16 +132,24 @@ linearSolve = linearSolve' | |||
129 | linearSolveSVD :: Field t => Matrix t -> Matrix t -> Matrix t | 132 | linearSolveSVD :: Field t => Matrix t -> Matrix t -> Matrix t |
130 | linearSolveSVD = linearSolveSVD' | 133 | linearSolveSVD = linearSolveSVD' |
131 | 134 | ||
132 | -- | Eigenvalues and eigenvectors of a general square matrix using lapack's dgeev or zgeev. | 135 | -- | Eigenvalues and eigenvectors of a general square matrix. |
133 | -- | 136 | -- |
134 | -- If @(s,v) = eig m@ then @m \<> v == v \<> diag s@ | 137 | -- If @(s,v) = eig m@ then @m \<> v == v \<> diag s@ |
135 | eig :: Field t => Matrix t -> (Vector (Complex Double), Matrix (Complex Double)) | 138 | eig :: Field t => Matrix t -> (Vector (Complex Double), Matrix (Complex Double)) |
136 | eig = eig' | 139 | eig = eig' |
137 | 140 | ||
141 | -- | Eigenvalues of a general square matrix. | ||
142 | eigenvalues :: Field t => Matrix t -> Vector (Complex Double) | ||
143 | eigenvalues = eigOnly | ||
144 | |||
138 | -- | Similar to 'eigSH' without checking that the input matrix is hermitian or symmetric. | 145 | -- | Similar to 'eigSH' without checking that the input matrix is hermitian or symmetric. |
139 | eigSH' :: Field t => Matrix t -> (Vector Double, Matrix t) | 146 | eigSH' :: Field t => Matrix t -> (Vector Double, Matrix t) |
140 | eigSH' = eigSH'' | 147 | eigSH' = eigSH'' |
141 | 148 | ||
149 | -- | Similar to 'eigenvaluesSH' without checking that the input matrix is hermitian or symmetric. | ||
150 | eigenvaluesSH' :: Field t => Matrix t -> Vector Double | ||
151 | eigenvaluesSH' = eigOnlySH | ||
152 | |||
142 | -- | Similar to 'chol' without checking that the input matrix is hermitian or symmetric. | 153 | -- | Similar to 'chol' without checking that the input matrix is hermitian or symmetric. |
143 | cholSH :: Field t => Matrix t -> Matrix t | 154 | cholSH :: Field t => Matrix t -> Matrix t |
144 | cholSH = cholSH' | 155 | cholSH = cholSH' |
@@ -187,6 +198,8 @@ instance Field Double where | |||
187 | ctrans' = trans | 198 | ctrans' = trans |
188 | eig' = eigR | 199 | eig' = eigR |
189 | eigSH'' = eigS | 200 | eigSH'' = eigS |
201 | eigOnly = eigOnlyR | ||
202 | eigOnlySH = eigOnlyS | ||
190 | cholSH' = cholS | 203 | cholSH' = cholS |
191 | qr' = unpackQR . qrR | 204 | qr' = unpackQR . qrR |
192 | hess' = unpackHess hessR | 205 | hess' = unpackHess hessR |
@@ -203,7 +216,9 @@ instance Field (Complex Double) where | |||
203 | linearSolveSVD' = linearSolveSVDC Nothing | 216 | linearSolveSVD' = linearSolveSVDC Nothing |
204 | ctrans' = conj . trans | 217 | ctrans' = conj . trans |
205 | eig' = eigC | 218 | eig' = eigC |
219 | eigOnly = eigOnlyC | ||
206 | eigSH'' = eigH | 220 | eigSH'' = eigH |
221 | eigOnlySH = eigOnlyH | ||
207 | cholSH' = cholH | 222 | cholSH' = cholH |
208 | qr' = unpackQR . qrC | 223 | qr' = unpackQR . qrC |
209 | hess' = unpackHess hessC | 224 | hess' = unpackHess hessC |
@@ -211,13 +226,18 @@ instance Field (Complex Double) where | |||
211 | multiply' = multiplyC | 226 | multiply' = multiplyC |
212 | 227 | ||
213 | 228 | ||
214 | -- | Eigenvalues and Eigenvectors of a complex hermitian or real symmetric matrix using lapack's dsyev or zheev. | 229 | -- | Eigenvalues and Eigenvectors of a complex hermitian or real symmetric matrix. |
215 | -- | 230 | -- |
216 | -- If @(s,v) = eigSH m@ then @m == v \<> diag s \<> ctrans v@ | 231 | -- If @(s,v) = eigSH m@ then @m == v \<> diag s \<> ctrans v@ |
217 | eigSH :: Field t => Matrix t -> (Vector Double, Matrix t) | 232 | eigSH :: Field t => Matrix t -> (Vector Double, Matrix t) |
218 | eigSH m | m `equal` ctrans m = eigSH' m | 233 | eigSH m | m `equal` ctrans m = eigSH' m |
219 | | otherwise = error "eigSH requires complex hermitian or real symmetric matrix" | 234 | | otherwise = error "eigSH requires complex hermitian or real symmetric matrix" |
220 | 235 | ||
236 | -- | Eigenvalues of a complex hermitian or real symmetric matrix. | ||
237 | eigenvaluesSH :: Field t => Matrix t -> Vector Double | ||
238 | eigenvaluesSH m | m `equal` ctrans m = eigenvaluesSH' m | ||
239 | | otherwise = error "eigenvaluesSH requires complex hermitian or real symmetric matrix" | ||
240 | |||
221 | -- | Cholesky factorization of a positive definite hermitian or symmetric matrix using lapack's dpotrf or zportrf. | 241 | -- | Cholesky factorization of a positive definite hermitian or symmetric matrix using lapack's dpotrf or zportrf. |
222 | -- | 242 | -- |
223 | -- If @c = chol m@ then @m == ctrans c \<> c@. | 243 | -- If @c = chol m@ then @m == ctrans c \<> c@. |
diff --git a/lib/Numeric/LinearAlgebra/LAPACK.hs b/lib/Numeric/LinearAlgebra/LAPACK.hs index 2eae9b7..a1ac1cf 100644 --- a/lib/Numeric/LinearAlgebra/LAPACK.hs +++ b/lib/Numeric/LinearAlgebra/LAPACK.hs | |||
@@ -27,6 +27,7 @@ module Numeric.LinearAlgebra.LAPACK ( | |||
27 | rightSVR, rightSVC, leftSVR, leftSVC, | 27 | rightSVR, rightSVC, leftSVR, leftSVC, |
28 | -- * Eigensystems | 28 | -- * Eigensystems |
29 | eigR, eigC, eigS, eigS', eigH, eigH', | 29 | eigR, eigC, eigS, eigS', eigH, eigH', |
30 | eigOnlyR, eigOnlyC, eigOnlyS, eigOnlyH, | ||
30 | -- * LU | 31 | -- * LU |
31 | luR, luC, | 32 | luR, luC, |
32 | -- * Cholesky | 33 | -- * Cholesky |
@@ -198,18 +199,16 @@ leftSVAux f st x = unsafePerformIO $ do | |||
198 | 199 | ||
199 | foreign import ccall "LAPACK/lapack-aux.h eig_l_R" dgeev :: TMMCVM | 200 | foreign import ccall "LAPACK/lapack-aux.h eig_l_R" dgeev :: TMMCVM |
200 | foreign import ccall "LAPACK/lapack-aux.h eig_l_C" zgeev :: TCMCMCVCM | 201 | foreign import ccall "LAPACK/lapack-aux.h eig_l_C" zgeev :: TCMCMCVCM |
201 | foreign import ccall "LAPACK/lapack-aux.h eig_l_S" dsyev :: TMVM | 202 | foreign import ccall "LAPACK/lapack-aux.h eig_l_S" dsyev :: CInt -> TMVM |
202 | foreign import ccall "LAPACK/lapack-aux.h eig_l_H" zheev :: TCMVCM | 203 | foreign import ccall "LAPACK/lapack-aux.h eig_l_H" zheev :: CInt -> TCMVCM |
203 | 204 | ||
204 | eigAux f st m | 205 | eigAux f st m = unsafePerformIO $ do |
205 | | r == 1 = (fromList [flatten m `at` 0], singleton 1) | ||
206 | | otherwise = unsafePerformIO $ do | ||
207 | l <- createVector r | 206 | l <- createVector r |
208 | v <- createMatrix ColumnMajor r r | 207 | v <- createMatrix ColumnMajor r r |
209 | dummy <- createMatrix ColumnMajor 1 1 | 208 | app3 g mat m vec l mat v st |
210 | app4 f mat m mat dummy vec l mat v st | ||
211 | return (l,v) | 209 | return (l,v) |
212 | where r = rows m | 210 | where r = rows m |
211 | g ra ca pa = f ra ca pa 0 0 nullPtr | ||
213 | 212 | ||
214 | 213 | ||
215 | -- | Eigenvalues and right eigenvectors of a general complex matrix, using LAPACK's /zgeev/. | 214 | -- | Eigenvalues and right eigenvectors of a general complex matrix, using LAPACK's /zgeev/. |
@@ -217,26 +216,39 @@ eigAux f st m | |||
217 | eigC :: Matrix (Complex Double) -> (Vector (Complex Double), Matrix (Complex Double)) | 216 | eigC :: Matrix (Complex Double) -> (Vector (Complex Double), Matrix (Complex Double)) |
218 | eigC = eigAux zgeev "eigC" . fmat | 217 | eigC = eigAux zgeev "eigC" . fmat |
219 | 218 | ||
219 | eigOnlyAux f st m = unsafePerformIO $ do | ||
220 | l <- createVector r | ||
221 | app2 g mat m vec l st | ||
222 | return l | ||
223 | where r = rows m | ||
224 | g ra ca pa nl pl = f ra ca pa 0 0 nullPtr nl pl 0 0 nullPtr | ||
225 | |||
226 | -- | Eigenvalues of a general complex matrix, using LAPACK's /zgeev/ with jobz == \'N\'. | ||
227 | -- The eigenvalues are not sorted. | ||
228 | eigOnlyC :: Matrix (Complex Double) -> Vector (Complex Double) | ||
229 | eigOnlyC = eigOnlyAux zgeev "eigOnlyC" . fmat | ||
230 | |||
220 | -- | Eigenvalues and right eigenvectors of a general real matrix, using LAPACK's /dgeev/. | 231 | -- | Eigenvalues and right eigenvectors of a general real matrix, using LAPACK's /dgeev/. |
221 | -- The eigenvectors are the columns of v. The eigenvalues are not sorted. | 232 | -- The eigenvectors are the columns of v. The eigenvalues are not sorted. |
222 | eigR :: Matrix Double -> (Vector (Complex Double), Matrix (Complex Double)) | 233 | eigR :: Matrix Double -> (Vector (Complex Double), Matrix (Complex Double)) |
223 | eigR m = (s', v'') | 234 | eigR m = (s', v'') |
224 | where (s,v) = eigRaux (fmat m) | 235 | where (s,v) = eigRaux (fmat m) |
225 | s' = toComplex (subVector 0 r (asReal s), subVector r r (asReal s)) | 236 | s' = fixeig1 s |
226 | v' = toRows $ trans v | 237 | v' = toRows $ trans v |
227 | v'' = fromColumns $ fixeig (toList s') v' | 238 | v'' = fromColumns $ fixeig (toList s') v' |
228 | r = rows m | 239 | r = rows m |
229 | 240 | ||
230 | eigRaux :: Matrix Double -> (Vector (Complex Double), Matrix Double) | 241 | eigRaux :: Matrix Double -> (Vector (Complex Double), Matrix Double) |
231 | eigRaux m | 242 | eigRaux m = unsafePerformIO $ do |
232 | | r == 1 = (fromList [(flatten m `at` 0):+0], singleton 1) | ||
233 | | otherwise = unsafePerformIO $ do | ||
234 | l <- createVector r | 243 | l <- createVector r |
235 | v <- createMatrix ColumnMajor r r | 244 | v <- createMatrix ColumnMajor r r |
236 | dummy <- createMatrix ColumnMajor 1 1 | 245 | app3 g mat m vec l mat v "eigR" |
237 | app4 dgeev mat m mat dummy vec l mat v "eigR" | ||
238 | return (l,v) | 246 | return (l,v) |
239 | where r = rows m | 247 | where r = rows m |
248 | g ra ca pa = dgeev ra ca pa 0 0 nullPtr | ||
249 | |||
250 | fixeig1 s = toComplex (subVector 0 r (asReal s), subVector r r (asReal s)) | ||
251 | where r = dim s | ||
240 | 252 | ||
241 | fixeig [] _ = [] | 253 | fixeig [] _ = [] |
242 | fixeig [_] [v] = [comp v] | 254 | fixeig [_] [v] = [comp v] |
@@ -246,8 +258,22 @@ fixeig ((r1:+i1):(r2:+i2):r) (v1:v2:vs) | |||
246 | where scale = vectorMapValR Scale | 258 | where scale = vectorMapValR Scale |
247 | fixeig _ _ = error "fixeig with impossible inputs" | 259 | fixeig _ _ = error "fixeig with impossible inputs" |
248 | 260 | ||
261 | |||
262 | -- | Eigenvalues of a general real matrix, using LAPACK's /dgeev/ with jobz == \'N\'. | ||
263 | -- The eigenvalues are not sorted. | ||
264 | eigOnlyR :: Matrix Double -> Vector (Complex Double) | ||
265 | eigOnlyR = fixeig1 . eigOnlyAux dgeev "eigOnlyR" . fmat | ||
266 | |||
267 | |||
249 | ----------------------------------------------------------------------------- | 268 | ----------------------------------------------------------------------------- |
250 | 269 | ||
270 | eigSHAux f st m = unsafePerformIO $ do | ||
271 | l <- createVector r | ||
272 | v <- createMatrix ColumnMajor r r | ||
273 | app3 f mat m vec l mat v st | ||
274 | return (l,v) | ||
275 | where r = rows m | ||
276 | |||
251 | -- | Eigenvalues and right eigenvectors of a symmetric real matrix, using LAPACK's /dsyev/. | 277 | -- | Eigenvalues and right eigenvectors of a symmetric real matrix, using LAPACK's /dsyev/. |
252 | -- The eigenvectors are the columns of v. | 278 | -- The eigenvectors are the columns of v. |
253 | -- The eigenvalues are sorted in descending order (use 'eigS'' for ascending order). | 279 | -- The eigenvalues are sorted in descending order (use 'eigS'' for ascending order). |
@@ -258,16 +284,7 @@ eigS m = (s', fliprl v) | |||
258 | 284 | ||
259 | -- | 'eigS' in ascending order | 285 | -- | 'eigS' in ascending order |
260 | eigS' :: Matrix Double -> (Vector Double, Matrix Double) | 286 | eigS' :: Matrix Double -> (Vector Double, Matrix Double) |
261 | eigS' m | 287 | eigS' = eigSHAux (dsyev 1) "eigS'" . fmat |
262 | | r == 1 = (fromList [flatten m `at` 0], singleton 1) | ||
263 | | otherwise = unsafePerformIO $ do | ||
264 | l <- createVector r | ||
265 | v <- createMatrix ColumnMajor r r | ||
266 | app3 dsyev mat m vec l mat v "eigS" | ||
267 | return (l,v) | ||
268 | where r = rows m | ||
269 | |||
270 | ----------------------------------------------------------------------------- | ||
271 | 288 | ||
272 | -- | Eigenvalues and right eigenvectors of a hermitian complex matrix, using LAPACK's /zheev/. | 289 | -- | Eigenvalues and right eigenvectors of a hermitian complex matrix, using LAPACK's /zheev/. |
273 | -- The eigenvectors are the columns of v. | 290 | -- The eigenvectors are the columns of v. |
@@ -279,14 +296,20 @@ eigH m = (s', fliprl v) | |||
279 | 296 | ||
280 | -- | 'eigH' in ascending order | 297 | -- | 'eigH' in ascending order |
281 | eigH' :: Matrix (Complex Double) -> (Vector Double, Matrix (Complex Double)) | 298 | eigH' :: Matrix (Complex Double) -> (Vector Double, Matrix (Complex Double)) |
282 | eigH' m | 299 | eigH' = eigSHAux (zheev 1) "eigH'" . fmat |
283 | | r == 1 = (fromList [realPart (flatten m `at` 0)], singleton 1) | 300 | |
284 | | otherwise = unsafePerformIO $ do | 301 | |
285 | l <- createVector r | 302 | -- | Eigenvalues of a symmetric real matrix, using LAPACK's /dsyev/ with jobz == \'N\'. |
286 | v <- createMatrix ColumnMajor r r | 303 | -- The eigenvalues are sorted in descending order. |
287 | app3 zheev mat m vec l mat v "eigH" | 304 | eigOnlyS :: Matrix Double -> Vector Double |
288 | return (l,v) | 305 | eigOnlyS = vrev . fst. eigSHAux (dsyev 0) "eigS'" . fmat |
289 | where r = rows m | 306 | |
307 | -- | Eigenvalues of a hermitian complex matrix, using LAPACK's /zheev/ with jobz == \'N\'. | ||
308 | -- The eigenvalues are sorted in descending order. | ||
309 | eigOnlyH :: Matrix (Complex Double) -> Vector Double | ||
310 | eigOnlyH = vrev . fst. eigSHAux (zheev 1) "eigH'" . fmat | ||
311 | |||
312 | vrev = flatten . flipud . reshape 1 | ||
290 | 313 | ||
291 | ----------------------------------------------------------------------------- | 314 | ----------------------------------------------------------------------------- |
292 | foreign import ccall "LAPACK/lapack-aux.h linearSolveR_l" dgesv :: TMMM | 315 | foreign import ccall "LAPACK/lapack-aux.h linearSolveR_l" dgesv :: TMMM |
diff --git a/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c b/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c index db94cc6..06c2479 100644 --- a/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c +++ b/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c | |||
@@ -274,19 +274,20 @@ int svd_l_Cdd(KCMAT(a),CMAT(u), DVEC(s),CMAT(v)) { | |||
274 | 274 | ||
275 | //////////////////// general complex eigensystem //////////// | 275 | //////////////////// general complex eigensystem //////////// |
276 | 276 | ||
277 | int eig_l_C(KCMAT(a),CMAT(u), CVEC(s),CMAT(v)) { | 277 | int eig_l_C(KCMAT(a), CMAT(u), CVEC(s),CMAT(v)) { |
278 | integer n = ar; | 278 | integer n = ar; |
279 | REQUIRES(n>=2 && ac==n && (ur==1 || (ur==n && uc==n)) && sn==n && (vr==1 || (vr==n && vc==n)),BAD_SIZE); | 279 | REQUIRES(ac==n && sn==n, BAD_SIZE); |
280 | REQUIRES(up==NULL || ur==n && uc==n, BAD_SIZE); | ||
281 | char jobvl = up==NULL?'N':'V'; | ||
282 | REQUIRES(vp==NULL || vr==n && vc==n, BAD_SIZE); | ||
283 | char jobvr = vp==NULL?'N':'V'; | ||
280 | DEBUGMSG("eig_l_C"); | 284 | DEBUGMSG("eig_l_C"); |
281 | double *B = (double*)malloc(2*n*n*sizeof(double)); | 285 | doublecomplex *B = (doublecomplex*)malloc(n*n*sizeof(doublecomplex)); |
282 | CHECK(!B,MEM); | 286 | CHECK(!B,MEM); |
283 | memcpy(B,ap,n*n*2*sizeof(double)); | 287 | memcpy(B,ap,n*n*sizeof(doublecomplex)); |
284 | |||
285 | double *rwork = (double*) malloc(2*n*sizeof(double)); | 288 | double *rwork = (double*) malloc(2*n*sizeof(double)); |
286 | CHECK(!rwork,MEM); | 289 | CHECK(!rwork,MEM); |
287 | integer lwork = -1; | 290 | integer lwork = -1; |
288 | char jobvl = ur==1?'N':'V'; | ||
289 | char jobvr = vr==1?'N':'V'; | ||
290 | integer res; | 291 | integer res; |
291 | // ask for optimal lwork | 292 | // ask for optimal lwork |
292 | doublecomplex ans; | 293 | doublecomplex ans; |
@@ -301,7 +302,7 @@ int eig_l_C(KCMAT(a),CMAT(u), CVEC(s),CMAT(v)) { | |||
301 | &res); | 302 | &res); |
302 | lwork = ceil(ans.r); | 303 | lwork = ceil(ans.r); |
303 | //printf("ans = %d\n",lwork); | 304 | //printf("ans = %d\n",lwork); |
304 | doublecomplex * work = (doublecomplex*)malloc(lwork*2*sizeof(double)); | 305 | doublecomplex * work = (doublecomplex*)malloc(lwork*sizeof(doublecomplex)); |
305 | CHECK(!work,MEM); | 306 | CHECK(!work,MEM); |
306 | //printf("zgeev\n"); | 307 | //printf("zgeev\n"); |
307 | zgeev_ (&jobvl,&jobvr, | 308 | zgeev_ (&jobvl,&jobvr, |
@@ -325,14 +326,16 @@ int eig_l_C(KCMAT(a),CMAT(u), CVEC(s),CMAT(v)) { | |||
325 | 326 | ||
326 | int eig_l_R(KDMAT(a),DMAT(u), CVEC(s),DMAT(v)) { | 327 | int eig_l_R(KDMAT(a),DMAT(u), CVEC(s),DMAT(v)) { |
327 | integer n = ar; | 328 | integer n = ar; |
328 | REQUIRES(n>=2 && ac == n && (ur==1 || (ur==n && uc==n)) && sn==n && (vr==1 || (vr==n && vc==n)),BAD_SIZE); | 329 | REQUIRES(ac==n && sn==n, BAD_SIZE); |
330 | REQUIRES(up==NULL || ur==n && uc==n, BAD_SIZE); | ||
331 | char jobvl = up==NULL?'N':'V'; | ||
332 | REQUIRES(vp==NULL || vr==n && vc==n, BAD_SIZE); | ||
333 | char jobvr = vp==NULL?'N':'V'; | ||
329 | DEBUGMSG("eig_l_R"); | 334 | DEBUGMSG("eig_l_R"); |
330 | double *B = (double*)malloc(n*n*sizeof(double)); | 335 | double *B = (double*)malloc(n*n*sizeof(double)); |
331 | CHECK(!B,MEM); | 336 | CHECK(!B,MEM); |
332 | memcpy(B,ap,n*n*sizeof(double)); | 337 | memcpy(B,ap,n*n*sizeof(double)); |
333 | integer lwork = -1; | 338 | integer lwork = -1; |
334 | char jobvl = ur==1?'N':'V'; | ||
335 | char jobvr = vr==1?'N':'V'; | ||
336 | integer res; | 339 | integer res; |
337 | // ask for optimal lwork | 340 | // ask for optimal lwork |
338 | double ans; | 341 | double ans; |
@@ -366,13 +369,14 @@ int eig_l_R(KDMAT(a),DMAT(u), CVEC(s),DMAT(v)) { | |||
366 | //////////////////// symmetric real eigensystem //////////// | 369 | //////////////////// symmetric real eigensystem //////////// |
367 | 370 | ||
368 | 371 | ||
369 | int eig_l_S(KDMAT(a),DVEC(s),DMAT(v)) { | 372 | int eig_l_S(int wantV,KDMAT(a),DVEC(s),DMAT(v)) { |
370 | integer n = ar; | 373 | integer n = ar; |
371 | REQUIRES(n>=2 && ac == n && sn==n && (vr==1 || (vr==n && vc==n)),BAD_SIZE); | 374 | REQUIRES(ac==n && sn==n, BAD_SIZE); |
375 | REQUIRES(vr==n && vc==n, BAD_SIZE); | ||
376 | char jobz = wantV?'V':'N'; | ||
372 | DEBUGMSG("eig_l_S"); | 377 | DEBUGMSG("eig_l_S"); |
373 | memcpy(vp,ap,n*n*sizeof(double)); | 378 | memcpy(vp,ap,n*n*sizeof(double)); |
374 | integer lwork = -1; | 379 | integer lwork = -1; |
375 | char jobz = vr==1?'N':'V'; | ||
376 | char uplo = 'U'; | 380 | char uplo = 'U'; |
377 | integer res; | 381 | integer res; |
378 | // ask for optimal lwork | 382 | // ask for optimal lwork |
@@ -399,15 +403,16 @@ int eig_l_S(KDMAT(a),DVEC(s),DMAT(v)) { | |||
399 | 403 | ||
400 | //////////////////// hermitian complex eigensystem //////////// | 404 | //////////////////// hermitian complex eigensystem //////////// |
401 | 405 | ||
402 | int eig_l_H(KCMAT(a),DVEC(s),CMAT(v)) { | 406 | int eig_l_H(int wantV,KCMAT(a),DVEC(s),CMAT(v)) { |
403 | integer n = ar; | 407 | integer n = ar; |
404 | REQUIRES(n>=2 && ac==n && sn==n && (vr==1 || (vr==n && vc==n)),BAD_SIZE); | 408 | REQUIRES(ac==n && sn==n, BAD_SIZE); |
409 | REQUIRES(vr==n && vc==n, BAD_SIZE); | ||
410 | char jobz = wantV?'V':'N'; | ||
405 | DEBUGMSG("eig_l_H"); | 411 | DEBUGMSG("eig_l_H"); |
406 | memcpy(vp,ap,2*n*n*sizeof(double)); | 412 | memcpy(vp,ap,2*n*n*sizeof(double)); |
407 | double *rwork = (double*) malloc((3*n-2)*sizeof(double)); | 413 | double *rwork = (double*) malloc((3*n-2)*sizeof(double)); |
408 | CHECK(!rwork,MEM); | 414 | CHECK(!rwork,MEM); |
409 | integer lwork = -1; | 415 | integer lwork = -1; |
410 | char jobz = vr==1?'N':'V'; | ||
411 | char uplo = 'U'; | 416 | char uplo = 'U'; |
412 | integer res; | 417 | integer res; |
413 | // ask for optimal lwork | 418 | // ask for optimal lwork |
@@ -421,7 +426,7 @@ int eig_l_H(KCMAT(a),DVEC(s),CMAT(v)) { | |||
421 | &res); | 426 | &res); |
422 | lwork = ceil(ans.r); | 427 | lwork = ceil(ans.r); |
423 | //printf("ans = %d\n",lwork); | 428 | //printf("ans = %d\n",lwork); |
424 | doublecomplex * work = (doublecomplex*)malloc(lwork*2*sizeof(double)); | 429 | doublecomplex * work = (doublecomplex*)malloc(lwork*sizeof(doublecomplex)); |
425 | CHECK(!work,MEM); | 430 | CHECK(!work,MEM); |
426 | zheev_ (&jobz,&uplo, | 431 | zheev_ (&jobz,&uplo, |
427 | &n,(doublecomplex*)vp,&n, | 432 | &n,(doublecomplex*)vp,&n, |
diff --git a/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.h b/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.h index dc7a98f..adf096e 100644 --- a/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.h +++ b/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.h | |||
@@ -68,8 +68,8 @@ int svd_l_C(KCMAT(a),CMAT(u),DVEC(s),CMAT(v)); | |||
68 | int eig_l_C(KCMAT(a),CMAT(u),CVEC(s),CMAT(v)); | 68 | int eig_l_C(KCMAT(a),CMAT(u),CVEC(s),CMAT(v)); |
69 | int eig_l_R(KDMAT(a),DMAT(u),CVEC(s),DMAT(v)); | 69 | int eig_l_R(KDMAT(a),DMAT(u),CVEC(s),DMAT(v)); |
70 | 70 | ||
71 | int eig_l_S(KDMAT(a),DVEC(s),DMAT(v)); | 71 | int eig_l_S(int,KDMAT(a),DVEC(s),DMAT(v)); |
72 | int eig_l_H(KCMAT(a),DVEC(s),CMAT(v)); | 72 | int eig_l_H(int,KCMAT(a),DVEC(s),CMAT(v)); |
73 | 73 | ||
74 | int linearSolveR_l(KDMAT(a),KDMAT(b),DMAT(x)); | 74 | int linearSolveR_l(KDMAT(a),KDMAT(b),DMAT(x)); |
75 | int linearSolveC_l(KCMAT(a),KCMAT(b),CMAT(x)); | 75 | int linearSolveC_l(KCMAT(a),KCMAT(b),CMAT(x)); |
diff --git a/lib/Numeric/LinearAlgebra/Tests.hs b/lib/Numeric/LinearAlgebra/Tests.hs index efc8c40..7284cd9 100644 --- a/lib/Numeric/LinearAlgebra/Tests.hs +++ b/lib/Numeric/LinearAlgebra/Tests.hs | |||
@@ -210,6 +210,10 @@ runTests n = do | |||
210 | test (eigSHProp . cHer) | 210 | test (eigSHProp . cHer) |
211 | test (eigProp . rSq) | 211 | test (eigProp . rSq) |
212 | test (eigProp . cSq) | 212 | test (eigProp . cSq) |
213 | test (eigSHProp2 . rHer) | ||
214 | test (eigSHProp2 . cHer) | ||
215 | test (eigProp2 . rSq) | ||
216 | test (eigProp2 . cSq) | ||
213 | putStrLn "------ nullSpace" | 217 | putStrLn "------ nullSpace" |
214 | test (nullspaceProp . rM) | 218 | test (nullspaceProp . rM) |
215 | test (nullspaceProp . cM) | 219 | test (nullspaceProp . cM) |
diff --git a/lib/Numeric/LinearAlgebra/Tests/Properties.hs b/lib/Numeric/LinearAlgebra/Tests/Properties.hs index d4dff34..7bb914f 100644 --- a/lib/Numeric/LinearAlgebra/Tests/Properties.hs +++ b/lib/Numeric/LinearAlgebra/Tests/Properties.hs | |||
@@ -31,7 +31,7 @@ module Numeric.LinearAlgebra.Tests.Properties ( | |||
31 | nullspaceProp, | 31 | nullspaceProp, |
32 | svdProp1, svdProp1a, svdProp2, svdProp3, svdProp4, | 32 | svdProp1, svdProp1a, svdProp2, svdProp3, svdProp4, |
33 | svdProp5a, svdProp5b, svdProp6a, svdProp6b, svdProp7, | 33 | svdProp5a, svdProp5b, svdProp6a, svdProp6b, svdProp7, |
34 | eigProp, eigSHProp, | 34 | eigProp, eigSHProp, eigProp2, eigSHProp2, |
35 | qrProp, | 35 | qrProp, |
36 | hessProp, | 36 | hessProp, |
37 | schurProp1, schurProp2, | 37 | schurProp1, schurProp2, |
@@ -192,6 +192,12 @@ eigSHProp m = m <> v |~| v <> real (diag s) | |||
192 | && m |~| v <> real (diag s) <> ctrans v | 192 | && m |~| v <> real (diag s) <> ctrans v |
193 | where (s, v) = eigSH m | 193 | where (s, v) = eigSH m |
194 | 194 | ||
195 | eigProp2 m = fst (eig m) |~| eigenvalues m | ||
196 | |||
197 | eigSHProp2 m = fst (eigSH m) |~| eigenvaluesSH m | ||
198 | |||
199 | ------------------------------------------------------------------ | ||
200 | |||
195 | qrProp m = q <> r |~| m && unitary q && upperTriang r | 201 | qrProp m = q <> r |~| m && unitary q && upperTriang r |
196 | where (q,r) = qr m | 202 | where (q,r) = qr m |
197 | 203 | ||