summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/Numeric/LinearAlgebra/Algorithms.hs10
-rw-r--r--lib/Numeric/LinearAlgebra/LAPACK.hs16
-rw-r--r--lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c36
-rw-r--r--lib/Numeric/LinearAlgebra/Tests.hs3
4 files changed, 62 insertions, 3 deletions
diff --git a/lib/Numeric/LinearAlgebra/Algorithms.hs b/lib/Numeric/LinearAlgebra/Algorithms.hs
index 6b0fb08..0f2ccef 100644
--- a/lib/Numeric/LinearAlgebra/Algorithms.hs
+++ b/lib/Numeric/LinearAlgebra/Algorithms.hs
@@ -27,6 +27,7 @@ module Numeric.LinearAlgebra.Algorithms (
27-- * Linear Systems 27-- * Linear Systems
28 linearSolve, 28 linearSolve,
29 luSolve, 29 luSolve,
30 cholSolve,
30 linearSolveLS, 31 linearSolveLS,
31 linearSolveSVD, 32 linearSolveSVD,
32 inv, pinv, 33 inv, pinv,
@@ -91,6 +92,7 @@ class (Normed (Matrix t), Linear Vector t, Linear Matrix t) => Field t where
91 luPacked' :: Matrix t -> (Matrix t, [Int]) 92 luPacked' :: Matrix t -> (Matrix t, [Int])
92 luSolve' :: (Matrix t, [Int]) -> Matrix t -> Matrix t 93 luSolve' :: (Matrix t, [Int]) -> Matrix t -> Matrix t
93 linearSolve' :: Matrix t -> Matrix t -> Matrix t 94 linearSolve' :: Matrix t -> Matrix t -> Matrix t
95 cholSolve' :: Matrix t -> Matrix t -> Matrix t
94 linearSolveSVD' :: Matrix t -> Matrix t -> Matrix t 96 linearSolveSVD' :: Matrix t -> Matrix t -> Matrix t
95 linearSolveLS' :: Matrix t -> Matrix t -> Matrix t 97 linearSolveLS' :: Matrix t -> Matrix t -> Matrix t
96 eig' :: Matrix t -> (Vector (Complex Double), Matrix (Complex Double)) 98 eig' :: Matrix t -> (Vector (Complex Double), Matrix (Complex Double))
@@ -112,6 +114,7 @@ instance Field Double where
112 luPacked' = luR 114 luPacked' = luR
113 luSolve' (l_u,perm) = lusR l_u perm 115 luSolve' (l_u,perm) = lusR l_u perm
114 linearSolve' = linearSolveR -- (luSolve . luPacked) ?? 116 linearSolve' = linearSolveR -- (luSolve . luPacked) ??
117 cholSolve' = cholSolveR
115 linearSolveLS' = linearSolveLSR 118 linearSolveLS' = linearSolveLSR
116 linearSolveSVD' = linearSolveSVDR Nothing 119 linearSolveSVD' = linearSolveSVDR Nothing
117 ctrans' = trans 120 ctrans' = trans
@@ -132,6 +135,7 @@ instance Field (Complex Double) where
132 luPacked' = luC 135 luPacked' = luC
133 luSolve' (l_u,perm) = lusC l_u perm 136 luSolve' (l_u,perm) = lusC l_u perm
134 linearSolve' = linearSolveC 137 linearSolve' = linearSolveC
138 cholSolve' = cholSolveC
135 linearSolveLS' = linearSolveLSC 139 linearSolveLS' = linearSolveLSC
136 linearSolveSVD' = linearSolveSVDC Nothing 140 linearSolveSVD' = linearSolveSVDC Nothing
137 ctrans' = conj . trans 141 ctrans' = conj . trans
@@ -229,6 +233,10 @@ luSolve = luSolve'
229linearSolve :: Field t => Matrix t -> Matrix t -> Matrix t 233linearSolve :: Field t => Matrix t -> Matrix t -> Matrix t
230linearSolve = linearSolve' 234linearSolve = linearSolve'
231 235
236-- | Solve a symmetric or Hermitian positive definite linear system using a precomputed Cholesky decomposition obtained by 'chol'.
237cholSolve :: Field t => Matrix t -> Matrix t -> Matrix t
238cholSolve = cholSolve'
239
232-- | Minimum norm solution of a general linear least squares problem Ax=B using the SVD. Admits rank-deficient systems but it is slower than 'linearSolveLS'. The effective rank of A is determined by treating as zero those singular valures which are less than 'eps' times the largest singular value. 240-- | Minimum norm solution of a general linear least squares problem Ax=B using the SVD. Admits rank-deficient systems but it is slower than 'linearSolveLS'. The effective rank of A is determined by treating as zero those singular valures which are less than 'eps' times the largest singular value.
233linearSolveSVD :: Field t => Matrix t -> Matrix t -> Matrix t 241linearSolveSVD :: Field t => Matrix t -> Matrix t -> Matrix t
234linearSolveSVD = linearSolveSVD' 242linearSolveSVD = linearSolveSVD'
@@ -322,7 +330,7 @@ cholSH = cholSH'
322 330
323-- | Cholesky factorization of a positive definite hermitian or symmetric matrix. 331-- | Cholesky factorization of a positive definite hermitian or symmetric matrix.
324-- 332--
325-- If @c = chol m@ then @m == ctrans c \<> c@. 333-- If @c = chol m@ then @c@ is upper triangular and @m == ctrans c \<> c@.
326chol :: Field t => Matrix t -> Matrix t 334chol :: Field t => Matrix t -> Matrix t
327chol m | exactHermitian m = cholSH m 335chol m | exactHermitian m = cholSH m
328 | otherwise = error "chol requires positive definite complex hermitian or real symmetric matrix" 336 | otherwise = error "chol requires positive definite complex hermitian or real symmetric matrix"
diff --git a/lib/Numeric/LinearAlgebra/LAPACK.hs b/lib/Numeric/LinearAlgebra/LAPACK.hs
index a1ac1cf..5d4eb0d 100644
--- a/lib/Numeric/LinearAlgebra/LAPACK.hs
+++ b/lib/Numeric/LinearAlgebra/LAPACK.hs
@@ -18,6 +18,7 @@ module Numeric.LinearAlgebra.LAPACK (
18 -- * Linear systems 18 -- * Linear systems
19 linearSolveR, linearSolveC, 19 linearSolveR, linearSolveC,
20 lusR, lusC, 20 lusR, lusC,
21 cholSolveR, cholSolveC,
21 linearSolveLSR, linearSolveLSC, 22 linearSolveLSR, linearSolveLSC,
22 linearSolveSVDR, linearSolveSVDC, 23 linearSolveSVDR, linearSolveSVDC,
23 -- * SVD 24 -- * SVD
@@ -312,8 +313,10 @@ eigOnlyH = vrev . fst. eigSHAux (zheev 1) "eigH'" . fmat
312vrev = flatten . flipud . reshape 1 313vrev = flatten . flipud . reshape 1
313 314
314----------------------------------------------------------------------------- 315-----------------------------------------------------------------------------
315foreign import ccall "LAPACK/lapack-aux.h linearSolveR_l" dgesv :: TMMM 316foreign import ccall "linearSolveR_l" dgesv :: TMMM
316foreign import ccall "LAPACK/lapack-aux.h linearSolveC_l" zgesv :: TCMCMCM 317foreign import ccall "linearSolveC_l" zgesv :: TCMCMCM
318foreign import ccall "cholSolveR_l" dpotrs :: TMMM
319foreign import ccall "cholSolveC_l" zpotrs :: TCMCMCM
317 320
318linearSolveSQAux f st a b 321linearSolveSQAux f st a b
319 | n1==n2 && n1==r = unsafePerformIO $ do 322 | n1==n2 && n1==r = unsafePerformIO $ do
@@ -334,6 +337,15 @@ linearSolveR a b = linearSolveSQAux dgesv "linearSolveR" (fmat a) (fmat b)
334linearSolveC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double) 337linearSolveC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double)
335linearSolveC a b = linearSolveSQAux zgesv "linearSolveC" (fmat a) (fmat b) 338linearSolveC a b = linearSolveSQAux zgesv "linearSolveC" (fmat a) (fmat b)
336 339
340
341-- | Solves a symmetric positive definite system of linear equations using a precomputed Cholesky factorization obtained by 'cholS'.
342cholSolveR :: Matrix Double -> Matrix Double -> Matrix Double
343cholSolveR a b = linearSolveSQAux dpotrs "cholSolveR" (fmat a) (fmat b)
344
345-- | Solves a Hermitian positive definite system of linear equations using a precomputed Cholesky factorization obtained by 'cholH'.
346cholSolveC :: Matrix (Complex Double) -> Matrix (Complex Double) -> Matrix (Complex Double)
347cholSolveC a b = linearSolveSQAux zpotrs "cholSolveC" (fmat a) (fmat b)
348
337----------------------------------------------------------------------------------- 349-----------------------------------------------------------------------------------
338foreign import ccall "LAPACK/lapack-aux.h linearSolveLSR_l" dgels :: TMMM 350foreign import ccall "LAPACK/lapack-aux.h linearSolveLSR_l" dgels :: TMMM
339foreign import ccall "LAPACK/lapack-aux.h linearSolveLSC_l" zgels :: TCMCMCM 351foreign import ccall "LAPACK/lapack-aux.h linearSolveLSC_l" zgels :: TCMCMCM
diff --git a/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c b/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c
index 06c2479..fd840e3 100644
--- a/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c
+++ b/lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.c
@@ -492,6 +492,42 @@ int linearSolveC_l(KCMAT(a),KCMAT(b),CMAT(x)) {
492 OK 492 OK
493} 493}
494 494
495//////// symmetric positive definite real linear system using Cholesky ////////////
496
497int cholSolveR_l(KDMAT(a),KDMAT(b),DMAT(x)) {
498 integer n = ar;
499 integer nhrs = bc;
500 REQUIRES(n>=1 && ar==ac && ar==br,BAD_SIZE);
501 DEBUGMSG("cholSolveR_l");
502 memcpy(xp,bp,n*nhrs*sizeof(double));
503 integer res;
504 dpotrs_ ("U",
505 &n,&nhrs,
506 (double*)ap, &n,
507 xp, &n,
508 &res);
509 CHECK(res,res);
510 OK
511}
512
513//////// Hermitian positive definite real linear system using Cholesky ////////////
514
515int cholSolveC_l(KCMAT(a),KCMAT(b),CMAT(x)) {
516 integer n = ar;
517 integer nhrs = bc;
518 REQUIRES(n>=1 && ar==ac && ar==br,BAD_SIZE);
519 DEBUGMSG("cholSolveC_l");
520 memcpy(xp,bp,2*n*nhrs*sizeof(double));
521 integer res;
522 zpotrs_ ("U",
523 &n,&nhrs,
524 (doublecomplex*)ap, &n,
525 (doublecomplex*)xp, &n,
526 &res);
527 CHECK(res,res);
528 OK
529}
530
495//////////////////// least squares real linear system //////////// 531//////////////////// least squares real linear system ////////////
496 532
497int linearSolveLSR_l(KDMAT(a),KDMAT(b),DMAT(x)) { 533int linearSolveLSR_l(KDMAT(a),KDMAT(b),DMAT(x)) {
diff --git a/lib/Numeric/LinearAlgebra/Tests.hs b/lib/Numeric/LinearAlgebra/Tests.hs
index f8f8bd5..36efab6 100644
--- a/lib/Numeric/LinearAlgebra/Tests.hs
+++ b/lib/Numeric/LinearAlgebra/Tests.hs
@@ -208,6 +208,9 @@ runTests n = do
208 putStrLn "------ luSolve" 208 putStrLn "------ luSolve"
209 test (linearSolveProp (luSolve.luPacked) . rSqWC) 209 test (linearSolveProp (luSolve.luPacked) . rSqWC)
210 test (linearSolveProp (luSolve.luPacked) . cSqWC) 210 test (linearSolveProp (luSolve.luPacked) . cSqWC)
211 putStrLn "------ cholSolve"
212 test (linearSolveProp (cholSolve.chol) . rPosDef)
213 test (linearSolveProp (cholSolve.chol) . cPosDef)
211 putStrLn "------ luSolveLS" 214 putStrLn "------ luSolveLS"
212 test (linearSolveProp linearSolveLS . rSqWC) 215 test (linearSolveProp linearSolveLS . rSqWC)
213 test (linearSolveProp linearSolveLS . cSqWC) 216 test (linearSolveProp linearSolveLS . cSqWC)