diff options
author | Alberto Ruiz <aruiz@um.es> | 2010-04-07 07:18:41 +0000 |
---|---|---|
committer | Alberto Ruiz <aruiz@um.es> | 2010-04-07 07:18:41 +0000 |
commit | bc854c679c77cbdc97ee2e24383322550109118d (patch) | |
tree | 903f8cce6d3dfbca8a7f6ca80fbe3b080102c046 /lib/Numeric/LinearAlgebra | |
parent | 2e48ffd1a395817288b8271299eebd0e483407af (diff) |
mbCholSH
Diffstat (limited to 'lib/Numeric/LinearAlgebra')
-rw-r--r-- | lib/Numeric/LinearAlgebra/Algorithms.hs | 14 | ||||
-rw-r--r-- | lib/Numeric/LinearAlgebra/LAPACK.hs | 24 | ||||
-rw-r--r-- | lib/Numeric/LinearAlgebra/Tests.hs | 9 |
3 files changed, 35 insertions, 12 deletions
diff --git a/lib/Numeric/LinearAlgebra/Algorithms.hs b/lib/Numeric/LinearAlgebra/Algorithms.hs index aa18d37..60f5971 100644 --- a/lib/Numeric/LinearAlgebra/Algorithms.hs +++ b/lib/Numeric/LinearAlgebra/Algorithms.hs | |||
@@ -46,7 +46,7 @@ module Numeric.LinearAlgebra.Algorithms ( | |||
46 | -- ** QR | 46 | -- ** QR |
47 | qr, rq, | 47 | qr, rq, |
48 | -- ** Cholesky | 48 | -- ** Cholesky |
49 | chol, cholSH, | 49 | chol, cholSH, mbCholSH, |
50 | -- ** Hessenberg | 50 | -- ** Hessenberg |
51 | hess, | 51 | hess, |
52 | -- ** Schur | 52 | -- ** Schur |
@@ -100,6 +100,7 @@ class (Normed (Matrix t), Linear Vector t, Linear Matrix t) => Field t where | |||
100 | eigOnly :: Matrix t -> Vector (Complex Double) | 100 | eigOnly :: Matrix t -> Vector (Complex Double) |
101 | eigOnlySH :: Matrix t -> Vector Double | 101 | eigOnlySH :: Matrix t -> Vector Double |
102 | cholSH' :: Matrix t -> Matrix t | 102 | cholSH' :: Matrix t -> Matrix t |
103 | mbCholSH' :: Matrix t -> Maybe (Matrix t) | ||
103 | qr' :: Matrix t -> (Matrix t, Matrix t) | 104 | qr' :: Matrix t -> (Matrix t, Matrix t) |
104 | hess' :: Matrix t -> (Matrix t, Matrix t) | 105 | hess' :: Matrix t -> (Matrix t, Matrix t) |
105 | schur' :: Matrix t -> (Matrix t, Matrix t) | 106 | schur' :: Matrix t -> (Matrix t, Matrix t) |
@@ -123,6 +124,7 @@ instance Field Double where | |||
123 | eigOnly = eigOnlyR | 124 | eigOnly = eigOnlyR |
124 | eigOnlySH = eigOnlyS | 125 | eigOnlySH = eigOnlyS |
125 | cholSH' = cholS | 126 | cholSH' = cholS |
127 | mbCholSH' = mbCholS | ||
126 | qr' = unpackQR . qrR | 128 | qr' = unpackQR . qrR |
127 | hess' = unpackHess hessR | 129 | hess' = unpackHess hessR |
128 | schur' = schurR | 130 | schur' = schurR |
@@ -149,6 +151,7 @@ instance Field (Complex Double) where | |||
149 | eigSH'' = eigH | 151 | eigSH'' = eigH |
150 | eigOnlySH = eigOnlyH | 152 | eigOnlySH = eigOnlyH |
151 | cholSH' = cholH | 153 | cholSH' = cholH |
154 | mbCholSH' = mbCholH | ||
152 | qr' = unpackQR . qrC | 155 | qr' = unpackQR . qrC |
153 | hess' = unpackHess hessC | 156 | hess' = unpackHess hessC |
154 | schur' = schurC | 157 | schur' = schurC |
@@ -263,11 +266,11 @@ eig = eig' | |||
263 | eigenvalues :: Field t => Matrix t -> Vector (Complex Double) | 266 | eigenvalues :: Field t => Matrix t -> Vector (Complex Double) |
264 | eigenvalues = eigOnly | 267 | eigenvalues = eigOnly |
265 | 268 | ||
266 | -- | Similar to 'eigSH' without checking that the input matrix is hermitian or symmetric. | 269 | -- | Similar to 'eigSH' without checking that the input matrix is hermitian or symmetric. It works with the upper triangular part. |
267 | eigSH' :: Field t => Matrix t -> (Vector Double, Matrix t) | 270 | eigSH' :: Field t => Matrix t -> (Vector Double, Matrix t) |
268 | eigSH' = eigSH'' | 271 | eigSH' = eigSH'' |
269 | 272 | ||
270 | -- | Similar to 'eigenvaluesSH' without checking that the input matrix is hermitian or symmetric. | 273 | -- | Similar to 'eigenvaluesSH' without checking that the input matrix is hermitian or symmetric. It works with the upper triangular part. |
271 | eigenvaluesSH' :: Field t => Matrix t -> Vector Double | 274 | eigenvaluesSH' :: Field t => Matrix t -> Vector Double |
272 | eigenvaluesSH' = eigOnlySH | 275 | eigenvaluesSH' = eigOnlySH |
273 | 276 | ||
@@ -328,8 +331,11 @@ ctrans = ctrans' | |||
328 | multiply :: Field t => Matrix t -> Matrix t -> Matrix t | 331 | multiply :: Field t => Matrix t -> Matrix t -> Matrix t |
329 | multiply = multiply' | 332 | multiply = multiply' |
330 | 333 | ||
334 | -- | Similar to 'cholSH', but instead of an error (e.g., caused by a matrix not positive definite) it returns 'Nothing'. | ||
335 | mbCholSH :: Field t => Matrix t -> Maybe (Matrix t) | ||
336 | mbCholSH = mbCholSH' | ||
331 | 337 | ||
332 | -- | Similar to 'chol' without checking that the input matrix is hermitian or symmetric. | 338 | -- | Similar to 'chol', without checking that the input matrix is hermitian or symmetric. It works with the upper triangular part. |
333 | cholSH :: Field t => Matrix t -> Matrix t | 339 | cholSH :: Field t => Matrix t -> Matrix t |
334 | cholSH = cholSH' | 340 | cholSH = cholSH' |
335 | 341 | ||
diff --git a/lib/Numeric/LinearAlgebra/LAPACK.hs b/lib/Numeric/LinearAlgebra/LAPACK.hs index 5d4eb0d..539ffb9 100644 --- a/lib/Numeric/LinearAlgebra/LAPACK.hs +++ b/lib/Numeric/LinearAlgebra/LAPACK.hs | |||
@@ -32,7 +32,7 @@ module Numeric.LinearAlgebra.LAPACK ( | |||
32 | -- * LU | 32 | -- * LU |
33 | luR, luC, | 33 | luR, luC, |
34 | -- * Cholesky | 34 | -- * Cholesky |
35 | cholS, cholH, | 35 | cholS, cholH, mbCholS, mbCholH, |
36 | -- * QR | 36 | -- * QR |
37 | qrR, qrC, | 37 | qrR, qrC, |
38 | -- * Hessenberg | 38 | -- * Hessenberg |
@@ -392,19 +392,27 @@ linearSolveSVDC Nothing a b = linearSolveSVDC (Just (-1)) (fmat a) (fmat b) | |||
392 | foreign import ccall "LAPACK/lapack-aux.h chol_l_H" zpotrf :: TCMCM | 392 | foreign import ccall "LAPACK/lapack-aux.h chol_l_H" zpotrf :: TCMCM |
393 | foreign import ccall "LAPACK/lapack-aux.h chol_l_S" dpotrf :: TMM | 393 | foreign import ccall "LAPACK/lapack-aux.h chol_l_S" dpotrf :: TMM |
394 | 394 | ||
395 | cholAux f st a = do | ||
396 | r <- createMatrix ColumnMajor n n | ||
397 | app2 f mat a mat r st | ||
398 | return r | ||
399 | where n = rows a | ||
400 | |||
395 | -- | Cholesky factorization of a complex Hermitian positive definite matrix, using LAPACK's /zpotrf/. | 401 | -- | Cholesky factorization of a complex Hermitian positive definite matrix, using LAPACK's /zpotrf/. |
396 | cholH :: Matrix (Complex Double) -> Matrix (Complex Double) | 402 | cholH :: Matrix (Complex Double) -> Matrix (Complex Double) |
397 | cholH = cholAux zpotrf "cholH" . fmat | 403 | cholH = unsafePerformIO . cholAux zpotrf "cholH" . fmat |
398 | 404 | ||
399 | -- | Cholesky factorization of a real symmetric positive definite matrix, using LAPACK's /dpotrf/. | 405 | -- | Cholesky factorization of a real symmetric positive definite matrix, using LAPACK's /dpotrf/. |
400 | cholS :: Matrix Double -> Matrix Double | 406 | cholS :: Matrix Double -> Matrix Double |
401 | cholS = cholAux dpotrf "cholS" . fmat | 407 | cholS = unsafePerformIO . cholAux dpotrf "cholS" . fmat |
402 | 408 | ||
403 | cholAux f st a = unsafePerformIO $ do | 409 | -- | Cholesky factorization of a complex Hermitian positive definite matrix, using LAPACK's /zpotrf/ ('Maybe' version). |
404 | r <- createMatrix ColumnMajor n n | 410 | mbCholH :: Matrix (Complex Double) -> Maybe (Matrix (Complex Double)) |
405 | app2 f mat a mat r st | 411 | mbCholH = unsafePerformIO . mbCatch . cholAux zpotrf "cholH" . fmat |
406 | return r | 412 | |
407 | where n = rows a | 413 | -- | Cholesky factorization of a real symmetric positive definite matrix, using LAPACK's /dpotrf/ ('Maybe' version). |
414 | mbCholS :: Matrix Double -> Maybe (Matrix Double) | ||
415 | mbCholS = unsafePerformIO . mbCatch . cholAux dpotrf "cholS" . fmat | ||
408 | 416 | ||
409 | ----------------------------------------------------------------------------------- | 417 | ----------------------------------------------------------------------------------- |
410 | foreign import ccall "LAPACK/lapack-aux.h qr_l_R" dgeqr2 :: TMVM | 418 | foreign import ccall "LAPACK/lapack-aux.h qr_l_R" dgeqr2 :: TMVM |
diff --git a/lib/Numeric/LinearAlgebra/Tests.hs b/lib/Numeric/LinearAlgebra/Tests.hs index 60c60e6..ac26466 100644 --- a/lib/Numeric/LinearAlgebra/Tests.hs +++ b/lib/Numeric/LinearAlgebra/Tests.hs | |||
@@ -161,6 +161,14 @@ fittingTest = utest "levmar" (ok1 && ok2) | |||
161 | ok1 = and (zipWith f sols [5,0.1,1]) where f (x,d) r = abs (x-r)<2*d | 161 | ok1 = and (zipWith f sols [5,0.1,1]) where f (x,d) r = abs (x-r)<2*d |
162 | ok2 = pnorm PNorm2 (fromList (map fst sols) - fromList sol) < 1E-5 | 162 | ok2 = pnorm PNorm2 (fromList (map fst sols) - fromList sol) < 1E-5 |
163 | 163 | ||
164 | ----------------------------------------------------- | ||
165 | |||
166 | mbCholTest = utest "mbCholTest" (ok1 && ok2) where | ||
167 | m1 = (2><2) [2,5,5,8 :: Double] | ||
168 | m2 = (2><2) [3,5,5,9 :: Complex Double] | ||
169 | ok1 = mbCholSH m1 == Nothing | ||
170 | ok2 = mbCholSH m2 == Just (chol m2) | ||
171 | |||
164 | --------------------------------------------------------------------- | 172 | --------------------------------------------------------------------- |
165 | 173 | ||
166 | randomTestGaussian = c :~1~: snd (meanCov dat) where | 174 | randomTestGaussian = c :~1~: snd (meanCov dat) where |
@@ -325,6 +333,7 @@ runTests n = do | |||
325 | , utest "block" $ fromBlocks [[ident 3,0],[0,ident 4]] == (ident 7 :: CM) | 333 | , utest "block" $ fromBlocks [[ident 3,0],[0,ident 4]] == (ident 7 :: CM) |
326 | , odeTest | 334 | , odeTest |
327 | , fittingTest | 335 | , fittingTest |
336 | , mbCholTest | ||
328 | ] | 337 | ] |
329 | return () | 338 | return () |
330 | 339 | ||