diff options
Diffstat (limited to 'lib/Numeric/LinearAlgebra/Algorithms.hs')
-rw-r--r-- | lib/Numeric/LinearAlgebra/Algorithms.hs | 38 |
1 files changed, 36 insertions, 2 deletions
diff --git a/lib/Numeric/LinearAlgebra/Algorithms.hs b/lib/Numeric/LinearAlgebra/Algorithms.hs index 9395176..e115ec3 100644 --- a/lib/Numeric/LinearAlgebra/Algorithms.hs +++ b/lib/Numeric/LinearAlgebra/Algorithms.hs | |||
@@ -22,7 +22,7 @@ module Numeric.LinearAlgebra.Algorithms ( | |||
22 | -- * Linear Systems | 22 | -- * Linear Systems |
23 | linearSolve, | 23 | linearSolve, |
24 | inv, pinv, | 24 | inv, pinv, |
25 | pinvTol, det, | 25 | pinvTol, det, rank, |
26 | -- * Matrix factorizations | 26 | -- * Matrix factorizations |
27 | -- ** Singular value decomposition | 27 | -- ** Singular value decomposition |
28 | svd, | 28 | svd, |
@@ -37,6 +37,9 @@ module Numeric.LinearAlgebra.Algorithms ( | |||
37 | hess, | 37 | hess, |
38 | -- ** Schur | 38 | -- ** Schur |
39 | schur, | 39 | schur, |
40 | -- * Matrix functions | ||
41 | expm, | ||
42 | matFunc, | ||
40 | -- * Nullspace | 43 | -- * Nullspace |
41 | nullspacePrec, | 44 | nullspacePrec, |
42 | nullVector, | 45 | nullVector, |
@@ -62,7 +65,7 @@ import Numeric.LinearAlgebra.Linear | |||
62 | import Data.List(foldl1') | 65 | import Data.List(foldl1') |
63 | 66 | ||
64 | -- | Auxiliary typeclass used to define generic computations for both real and complex matrices. | 67 | -- | Auxiliary typeclass used to define generic computations for both real and complex matrices. |
65 | class (Linear Matrix t) => GenMat t where | 68 | class (Normed (Matrix t), Linear Matrix t) => GenMat t where |
66 | -- | Singular value decomposition using lapack's dgesvd or zgesvd. | 69 | -- | Singular value decomposition using lapack's dgesvd or zgesvd. |
67 | svd :: Matrix t -> (Matrix t, Vector Double, Matrix t) | 70 | svd :: Matrix t -> (Matrix t, Vector Double, Matrix t) |
68 | lu :: Matrix t -> (Matrix t, Matrix t, [Int], t) | 71 | lu :: Matrix t -> (Matrix t, Matrix t, [Int], t) |
@@ -98,6 +101,9 @@ class (Linear Matrix t) => GenMat t where | |||
98 | schur :: Matrix t -> (Matrix t, Matrix t) | 101 | schur :: Matrix t -> (Matrix t, Matrix t) |
99 | -- | Conjugate transpose. | 102 | -- | Conjugate transpose. |
100 | ctrans :: Matrix t -> Matrix t | 103 | ctrans :: Matrix t -> Matrix t |
104 | -- | Matrix exponential (currently implemented only for diagonalizable matrices). | ||
105 | expm :: Matrix t -> Matrix t | ||
106 | |||
101 | 107 | ||
102 | instance GenMat Double where | 108 | instance GenMat Double where |
103 | svd = svdR | 109 | svd = svdR |
@@ -111,6 +117,7 @@ instance GenMat Double where | |||
111 | qr = GSL.unpackQR . qrR | 117 | qr = GSL.unpackQR . qrR |
112 | hess = unpackHess hessR | 118 | hess = unpackHess hessR |
113 | schur = schurR | 119 | schur = schurR |
120 | expm = fst . fromComplex . expm' . comp | ||
114 | 121 | ||
115 | instance GenMat (Complex Double) where | 122 | instance GenMat (Complex Double) where |
116 | svd = svdC | 123 | svd = svdC |
@@ -124,6 +131,7 @@ instance GenMat (Complex Double) where | |||
124 | qr = unpackQR . qrC | 131 | qr = unpackQR . qrC |
125 | hess = unpackHess hessC | 132 | hess = unpackHess hessC |
126 | schur = schurC | 133 | schur = schurC |
134 | expm = expm' | ||
127 | 135 | ||
128 | -- | Eigenvalues and Eigenvectors of a complex hermitian or real symmetric matrix using lapack's dsyev or zheev. | 136 | -- | Eigenvalues and Eigenvectors of a complex hermitian or real symmetric matrix using lapack's dsyev or zheev. |
129 | -- | 137 | -- |
@@ -346,3 +354,29 @@ uH (pq, tau) = (p,h) | |||
346 | vs = zipWith zh [2..mn] cs | 354 | vs = zipWith zh [2..mn] cs |
347 | hs = zipWith haussholder (toList tau) vs | 355 | hs = zipWith haussholder (toList tau) vs |
348 | p = foldl1' mXm hs | 356 | p = foldl1' mXm hs |
357 | |||
358 | -------------------------------------------------------------------------- | ||
359 | |||
360 | -- | Number of linearly independent rows or columns. | ||
361 | rank :: GenMat t => Matrix t -> Int | ||
362 | rank m | pnorm PNorm1 m < eps = 0 | ||
363 | | otherwise = dim s where (_,s,_) = economy svd m | ||
364 | |||
365 | expm' m = case diagonalize (complex m) of | ||
366 | Just (l,v) -> v `mXm` diag (exp l) `mXm` inv v | ||
367 | Nothing -> error "Sorry, expm not yet implemented for non-diagonalizable matrices" | ||
368 | where exp = vectorMapC Exp | ||
369 | |||
370 | diagonalize m = if rank v == n | ||
371 | then Just (l,v) | ||
372 | else Nothing | ||
373 | where n = rows m | ||
374 | (l,v) = if m `equal` ctrans m | ||
375 | then let (l',v') = eigSH m in (real l', v') | ||
376 | else eig m | ||
377 | |||
378 | -- | Generic matrix functions for diagonalizable matrices. | ||
379 | matFunc :: GenMat t => (Complex Double -> Complex Double) -> Matrix t -> Matrix (Complex Double) | ||
380 | matFunc f m = case diagonalize (complex m) of | ||
381 | Just (l,v) -> v `mXm` diag (liftVector f l) `mXm` inv v | ||
382 | Nothing -> error "Sorry, matFunc requieres a diagonalizable matrix" | ||