summaryrefslogtreecommitdiff
path: root/lib/Numeric/LinearAlgebra/Algorithms.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Numeric/LinearAlgebra/Algorithms.hs')
-rw-r--r--lib/Numeric/LinearAlgebra/Algorithms.hs38
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
62import Data.List(foldl1') 65import 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.
65class (Linear Matrix t) => GenMat t where 68class (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
102instance GenMat Double where 108instance 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
115instance GenMat (Complex Double) where 122instance 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.
361rank :: GenMat t => Matrix t -> Int
362rank m | pnorm PNorm1 m < eps = 0
363 | otherwise = dim s where (_,s,_) = economy svd m
364
365expm' 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
370diagonalize 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.
379matFunc :: GenMat t => (Complex Double -> Complex Double) -> Matrix t -> Matrix (Complex Double)
380matFunc 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"