summaryrefslogtreecommitdiff
path: root/lib/Numeric/LinearAlgebra
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Numeric/LinearAlgebra')
-rw-r--r--lib/Numeric/LinearAlgebra/Algorithms.hs24
-rw-r--r--lib/Numeric/LinearAlgebra/LAPACK.hs85
-rw-r--r--lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c41
-rw-r--r--lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.h4
-rw-r--r--lib/Numeric/LinearAlgebra/Tests.hs4
-rw-r--r--lib/Numeric/LinearAlgebra/Tests/Properties.hs8
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'
129linearSolveSVD :: Field t => Matrix t -> Matrix t -> Matrix t 132linearSolveSVD :: Field t => Matrix t -> Matrix t -> Matrix t
130linearSolveSVD = linearSolveSVD' 133linearSolveSVD = 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@
135eig :: Field t => Matrix t -> (Vector (Complex Double), Matrix (Complex Double)) 138eig :: Field t => Matrix t -> (Vector (Complex Double), Matrix (Complex Double))
136eig = eig' 139eig = eig'
137 140
141-- | Eigenvalues of a general square matrix.
142eigenvalues :: Field t => Matrix t -> Vector (Complex Double)
143eigenvalues = 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.
139eigSH' :: Field t => Matrix t -> (Vector Double, Matrix t) 146eigSH' :: Field t => Matrix t -> (Vector Double, Matrix t)
140eigSH' = eigSH'' 147eigSH' = eigSH''
141 148
149-- | Similar to 'eigenvaluesSH' without checking that the input matrix is hermitian or symmetric.
150eigenvaluesSH' :: Field t => Matrix t -> Vector Double
151eigenvaluesSH' = 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.
143cholSH :: Field t => Matrix t -> Matrix t 154cholSH :: Field t => Matrix t -> Matrix t
144cholSH = cholSH' 155cholSH = 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@
217eigSH :: Field t => Matrix t -> (Vector Double, Matrix t) 232eigSH :: Field t => Matrix t -> (Vector Double, Matrix t)
218eigSH m | m `equal` ctrans m = eigSH' m 233eigSH 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.
237eigenvaluesSH :: Field t => Matrix t -> Vector Double
238eigenvaluesSH 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
199foreign import ccall "LAPACK/lapack-aux.h eig_l_R" dgeev :: TMMCVM 200foreign import ccall "LAPACK/lapack-aux.h eig_l_R" dgeev :: TMMCVM
200foreign import ccall "LAPACK/lapack-aux.h eig_l_C" zgeev :: TCMCMCVCM 201foreign import ccall "LAPACK/lapack-aux.h eig_l_C" zgeev :: TCMCMCVCM
201foreign import ccall "LAPACK/lapack-aux.h eig_l_S" dsyev :: TMVM 202foreign import ccall "LAPACK/lapack-aux.h eig_l_S" dsyev :: CInt -> TMVM
202foreign import ccall "LAPACK/lapack-aux.h eig_l_H" zheev :: TCMVCM 203foreign import ccall "LAPACK/lapack-aux.h eig_l_H" zheev :: CInt -> TCMVCM
203 204
204eigAux f st m 205eigAux 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
217eigC :: Matrix (Complex Double) -> (Vector (Complex Double), Matrix (Complex Double)) 216eigC :: Matrix (Complex Double) -> (Vector (Complex Double), Matrix (Complex Double))
218eigC = eigAux zgeev "eigC" . fmat 217eigC = eigAux zgeev "eigC" . fmat
219 218
219eigOnlyAux 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.
228eigOnlyC :: Matrix (Complex Double) -> Vector (Complex Double)
229eigOnlyC = 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.
222eigR :: Matrix Double -> (Vector (Complex Double), Matrix (Complex Double)) 233eigR :: Matrix Double -> (Vector (Complex Double), Matrix (Complex Double))
223eigR m = (s', v'') 234eigR 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
230eigRaux :: Matrix Double -> (Vector (Complex Double), Matrix Double) 241eigRaux :: Matrix Double -> (Vector (Complex Double), Matrix Double)
231eigRaux m 242eigRaux 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
250fixeig1 s = toComplex (subVector 0 r (asReal s), subVector r r (asReal s))
251 where r = dim s
240 252
241fixeig [] _ = [] 253fixeig [] _ = []
242fixeig [_] [v] = [comp v] 254fixeig [_] [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
247fixeig _ _ = error "fixeig with impossible inputs" 259fixeig _ _ = 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.
264eigOnlyR :: Matrix Double -> Vector (Complex Double)
265eigOnlyR = fixeig1 . eigOnlyAux dgeev "eigOnlyR" . fmat
266
267
249----------------------------------------------------------------------------- 268-----------------------------------------------------------------------------
250 269
270eigSHAux 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
260eigS' :: Matrix Double -> (Vector Double, Matrix Double) 286eigS' :: Matrix Double -> (Vector Double, Matrix Double)
261eigS' m 287eigS' = 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
281eigH' :: Matrix (Complex Double) -> (Vector Double, Matrix (Complex Double)) 298eigH' :: Matrix (Complex Double) -> (Vector Double, Matrix (Complex Double))
282eigH' m 299eigH' = 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" 304eigOnlyS :: Matrix Double -> Vector Double
288 return (l,v) 305eigOnlyS = 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.
309eigOnlyH :: Matrix (Complex Double) -> Vector Double
310eigOnlyH = vrev . fst. eigSHAux (zheev 1) "eigH'" . fmat
311
312vrev = flatten . flipud . reshape 1
290 313
291----------------------------------------------------------------------------- 314-----------------------------------------------------------------------------
292foreign import ccall "LAPACK/lapack-aux.h linearSolveR_l" dgesv :: TMMM 315foreign 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
277int eig_l_C(KCMAT(a),CMAT(u), CVEC(s),CMAT(v)) { 277int 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
326int eig_l_R(KDMAT(a),DMAT(u), CVEC(s),DMAT(v)) { 327int 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
369int eig_l_S(KDMAT(a),DVEC(s),DMAT(v)) { 372int 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
402int eig_l_H(KCMAT(a),DVEC(s),CMAT(v)) { 406int 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));
68int eig_l_C(KCMAT(a),CMAT(u),CVEC(s),CMAT(v)); 68int eig_l_C(KCMAT(a),CMAT(u),CVEC(s),CMAT(v));
69int eig_l_R(KDMAT(a),DMAT(u),CVEC(s),DMAT(v)); 69int eig_l_R(KDMAT(a),DMAT(u),CVEC(s),DMAT(v));
70 70
71int eig_l_S(KDMAT(a),DVEC(s),DMAT(v)); 71int eig_l_S(int,KDMAT(a),DVEC(s),DMAT(v));
72int eig_l_H(KCMAT(a),DVEC(s),CMAT(v)); 72int eig_l_H(int,KCMAT(a),DVEC(s),CMAT(v));
73 73
74int linearSolveR_l(KDMAT(a),KDMAT(b),DMAT(x)); 74int linearSolveR_l(KDMAT(a),KDMAT(b),DMAT(x));
75int linearSolveC_l(KCMAT(a),KCMAT(b),CMAT(x)); 75int 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
195eigProp2 m = fst (eig m) |~| eigenvalues m
196
197eigSHProp2 m = fst (eigSH m) |~| eigenvaluesSH m
198
199------------------------------------------------------------------
200
195qrProp m = q <> r |~| m && unitary q && upperTriang r 201qrProp m = q <> r |~| m && unitary q && upperTriang r
196 where (q,r) = qr m 202 where (q,r) = qr m
197 203