summaryrefslogtreecommitdiff
path: root/lib/LinearAlgebra/Algorithms.hs
diff options
context:
space:
mode:
Diffstat (limited to 'lib/LinearAlgebra/Algorithms.hs')
-rw-r--r--lib/LinearAlgebra/Algorithms.hs125
1 files changed, 55 insertions, 70 deletions
diff --git a/lib/LinearAlgebra/Algorithms.hs b/lib/LinearAlgebra/Algorithms.hs
index 162426f..a67f822 100644
--- a/lib/LinearAlgebra/Algorithms.hs
+++ b/lib/LinearAlgebra/Algorithms.hs
@@ -9,106 +9,114 @@ Maintainer : Alberto Ruiz (aruiz at um dot es)
9Stability : provisional 9Stability : provisional
10Portability : uses ffi 10Portability : uses ffi
11 11
12A simple interface to the available matrix computations. We have defined some generic functions 12A generic interface for a number of essential functions. Using it some higher level algorithms
13on both real and complex matrices in such a way that higher level algorithms and 13and testing properties can be written for both real and complex matrices.
14testing properties are valid for both base types.
15 14
16In any case the specific functions for particular base types can also be explicitly 15In any case, the specific functions for particular base types can also be explicitly
17imported from the LAPACK and GSL.Matrix modules. 16imported from the LAPACK and GSL.Matrix modules.
18 17
19-} 18-}
20----------------------------------------------------------------------------- 19-----------------------------------------------------------------------------
21 20
22module LinearAlgebra.Algorithms ( 21module LinearAlgebra.Algorithms (
23-- * Basic Linear Algebra 22-- * Linear Systems
24 scale, 23 linearSolve,
25 add, 24 inv, pinv,
26 multiply, dot, outer, 25 pinvTol, det,
27 linearSolve, linearSolveSVD,
28-- * Matrix factorizations 26-- * Matrix factorizations
29 svd, lu, eig, eigSH, 27-- ** Singular value decomposition
30 qr, chol, 28 svd,
31-- * Utilities 29 full, economy,
32 Normed(..), NormType(..), 30-- ** Eigensystems
33 det,inv,pinv,full,economy, 31 eig, LinearAlgebra.Algorithms.eigS, LinearAlgebra.Algorithms.eigH,
34 pinvTol, 32-- ** Other
35-- pinvTolg, 33 LinearAlgebra.Algorithms.qr, chol,
34-- * Nullspace
36 nullspacePrec, 35 nullspacePrec,
37 nullVector, 36 nullVector,
38-- * Conversions
39 toComplex, fromComplex,
40 comp, real, complex,
41 conj, ctrans,
42-- * Misc 37-- * Misc
43 eps, i, 38 eps, i,
44 scaleRecip, 39 ctrans,
45 addConstant, 40 Normed(..), NormType(..),
46 sub, 41 GenMat(linearSolveSVD,lu,eigSH)
47 mul,
48 divide,
49) where 42) where
50 43
51 44
52import Data.Packed.Internal hiding (fromComplex, toComplex, comp, conj) 45import Data.Packed.Internal hiding (fromComplex, toComplex, comp, conj)
53import Data.Packed.Matrix 46import Data.Packed
54import GSL.Matrix 47import GSL.Matrix
55import GSL.Vector 48import GSL.Vector
56import LAPACK 49import LAPACK
57import Complex 50import Complex
58import LinearAlgebra.Linear 51import LinearAlgebra.Linear
59 52
60-- | Base types for which some optimized matrix computations are available 53-- | matrix computations available for both real and complex matrices
61class (Linear Matrix t) => Optimized t where 54class (Linear Matrix t) => GenMat t where
62 svd :: Matrix t -> (Matrix t, Vector Double, Matrix t) 55 svd :: Matrix t -> (Matrix t, Vector Double, Matrix t)
63 lu :: Matrix t -> (Matrix t, Matrix t, [Int], t) 56 lu :: Matrix t -> (Matrix t, Matrix t, [Int], t)
64 linearSolve :: Matrix t -> Matrix t -> Matrix t 57 linearSolve :: Matrix t -> Matrix t -> Matrix t
65 linearSolveSVD :: Matrix t -> Matrix t -> Matrix t 58 linearSolveSVD :: Matrix t -> Matrix t -> Matrix t
66 ctrans :: Matrix t -> Matrix t
67 eig :: Matrix t -> (Vector (Complex Double), Matrix (Complex Double)) 59 eig :: Matrix t -> (Vector (Complex Double), Matrix (Complex Double))
68 eigSH :: Matrix t -> (Vector Double, Matrix t) 60 eigSH :: Matrix t -> (Vector Double, Matrix t)
69 chol :: Matrix t -> Matrix t 61 chol :: Matrix t -> Matrix t
62 -- | conjugate transpose
63 ctrans :: Matrix t -> Matrix t
70 64
71instance Optimized Double where 65instance GenMat Double where
72 svd = svdR 66 svd = svdR
73 lu = luR 67 lu = luR
74 linearSolve = linearSolveR 68 linearSolve = linearSolveR
75 linearSolveSVD = linearSolveSVDR Nothing 69 linearSolveSVD = linearSolveSVDR Nothing
76 ctrans = trans 70 ctrans = trans
77 eig = eigR 71 eig = eigR
78 eigSH = eigS 72 eigSH = LAPACK.eigS
79 chol = cholR 73 chol = cholR
80 74
81instance Optimized (Complex Double) where 75instance GenMat (Complex Double) where
82 svd = svdC 76 svd = svdC
83 lu = luC 77 lu = luC
84 linearSolve = linearSolveC 78 linearSolve = linearSolveC
85 linearSolveSVD = linearSolveSVDC Nothing 79 linearSolveSVD = linearSolveSVDC Nothing
86 ctrans = conjTrans 80 ctrans = conjTrans
87 eig = eigC 81 eig = eigC
88 eigSH = eigH 82 eigSH = LAPACK.eigH
89 chol = error "cholC not yet implemented" -- waiting for GSL-1.10 83 chol = error "cholC not yet implemented" -- waiting for GSL-1.10
90 84
85-- | eigensystem of a symmetric matrix
86eigS :: Matrix Double -> (Vector Double, Matrix Double)
87eigS = LAPACK.eigS
88
89-- | eigensystem of a hermitian matrix
90eigH :: Matrix (Complex Double) -> (Vector Double, Matrix (Complex Double))
91eigH = LAPACK.eigH
92
93qr :: Matrix Double -> (Matrix Double, Matrix Double)
94qr = GSL.Matrix.qr
95
91square m = rows m == cols m 96square m = rows m == cols m
92 97
93det :: Optimized t => Matrix t -> t 98det :: GenMat t => Matrix t -> t
94det m | square m = s * (product $ toList $ takeDiag $ u) 99det m | square m = s * (product $ toList $ takeDiag $ u)
95 | otherwise = error "det of nonsquare matrix" 100 | otherwise = error "det of nonsquare matrix"
96 where (_,u,_,s) = lu m 101 where (_,u,_,s) = lu m
97 102
98inv :: Optimized t => Matrix t -> Matrix t 103inv :: GenMat t => Matrix t -> Matrix t
99inv m | square m = m `linearSolve` ident (rows m) 104inv m | square m = m `linearSolve` ident (rows m)
100 | otherwise = error "inv of nonsquare matrix" 105 | otherwise = error "inv of nonsquare matrix"
101 106
102pinv :: Optimized t => Matrix t -> Matrix t 107pinv :: GenMat t => Matrix t -> Matrix t
103pinv m = linearSolveSVD m (ident (rows m)) 108pinv m = linearSolveSVD m (ident (rows m))
104 109
105 110full :: Field t
111 => (Matrix t -> (Matrix t, Vector Double, Matrix t)) -> Matrix t -> (Matrix t, Matrix Double, Matrix t)
106full svd m = (u, d ,v) where 112full svd m = (u, d ,v) where
107 (u,s,v) = svd m 113 (u,s,v) = svd m
108 d = diagRect s r c 114 d = diagRect s r c
109 r = rows m 115 r = rows m
110 c = cols m 116 c = cols m
111 117
118economy :: Field t
119 => (Matrix t -> (Matrix t, Vector Double, Matrix t)) -> Matrix t -> (Matrix t, Vector Double, Matrix t)
112economy svd m = (u', subVector 0 d s, v') where 120economy svd m = (u', subVector 0 d s, v') where
113 (u,s,v) = svd m 121 (u,s,v) = svd m
114 sl@(g:_) = toList (complex s) 122 sl@(g:_) = toList (complex s)
@@ -123,39 +131,25 @@ economy svd m = (u', subVector 0 d s, v') where
123 v' = takeColumns d v 131 v' = takeColumns d v
124 132
125 133
126{- | Machine precision of a Double. 134-- | The machine precision of a Double: @eps == 2.22044604925031e-16@ (the value used by GNU-Octave).
127
128>> eps
129> 2.22044604925031e-16
130
131(The value used by GNU-Octave)
132
133-}
134eps :: Double 135eps :: Double
135eps = 2.22044604925031e-16 136eps = 2.22044604925031e-16
136 137
137{- | The imaginary unit 138-- | The imaginary unit: @i == 0.0 :+ 1.0@
138
139@> 'ident' 3 \<\> i
1401.i 0. 0.
141 0. 1.i 0.
142 0. 0. 1.i@
143
144-}
145i :: Complex Double 139i :: Complex Double
146i = 0:+1 140i = 0:+1
147 141
148 142
149-- | matrix product 143-- | matrix product
150mXm :: (Num t, Optimized t) => Matrix t -> Matrix t -> Matrix t 144mXm :: (Num t, GenMat t) => Matrix t -> Matrix t -> Matrix t
151mXm = multiply 145mXm = multiply
152 146
153-- | matrix - vector product 147-- | matrix - vector product
154mXv :: (Num t, Optimized t) => Matrix t -> Vector t -> Vector t 148mXv :: (Num t, GenMat t) => Matrix t -> Vector t -> Vector t
155mXv m v = flatten $ m `mXm` (asColumn v) 149mXv m v = flatten $ m `mXm` (asColumn v)
156 150
157-- | vector - matrix product 151-- | vector - matrix product
158vXm :: (Num t, Optimized t) => Vector t -> Matrix t -> Vector t 152vXm :: (Num t, GenMat t) => Vector t -> Matrix t -> Vector t
159vXm v m = flatten $ (asRow v) `mXm` m 153vXm v m = flatten $ (asRow v) `mXm` m
160 154
161 155
@@ -167,15 +161,6 @@ norm2 = toScalarR Norm2
167norm1 :: Vector Double -> Double 161norm1 :: Vector Double -> Double
168norm1 = toScalarR AbsSum 162norm1 = toScalarR AbsSum
169 163
170vectorMax :: Vector Double -> Double
171vectorMax = toScalarR Max
172vectorMin :: Vector Double -> Double
173vectorMin = toScalarR Min
174vectorMaxIndex :: Vector Double -> Int
175vectorMaxIndex = round . toScalarR MaxIdx
176vectorMinIndex :: Vector Double -> Int
177vectorMinIndex = round . toScalarR MinIdx
178
179data NormType = Infinity | PNorm1 | PNorm2 -- PNorm Int 164data NormType = Infinity | PNorm1 | PNorm2 -- PNorm Int
180 165
181pnormRV PNorm2 = norm2 166pnormRV PNorm2 = norm2
@@ -199,7 +184,7 @@ pnormCM Infinity m = vectorMax $ liftMatrix (liftVector magnitude) m `mXv` const
199--pnormCM _ _ = error "p norm not yet defined" 184--pnormCM _ _ = error "p norm not yet defined"
200 185
201-- -- | computes the p-norm of a matrix or vector (with the same definitions as GNU-octave). pnorm 0 denotes \\inf-norm. See also 'norm'. 186-- -- | computes the p-norm of a matrix or vector (with the same definitions as GNU-octave). pnorm 0 denotes \\inf-norm. See also 'norm'.
202--pnorm :: (Container t, Optimized a) => Int -> t a -> Double 187--pnorm :: (Container t, GenMat a) => Int -> t a -> Double
203--pnorm = pnormG 188--pnorm = pnormG
204 189
205class Normed t where 190class Normed t where
@@ -222,7 +207,7 @@ instance Normed (Matrix (Complex Double)) where
222----------------------------------------------------------------------- 207-----------------------------------------------------------------------
223 208
224-- | The nullspace of a matrix from its SVD decomposition. 209-- | The nullspace of a matrix from its SVD decomposition.
225nullspacePrec :: Optimized t 210nullspacePrec :: GenMat t
226 => Double -- ^ relative tolerance in 'eps' units 211 => Double -- ^ relative tolerance in 'eps' units
227 -> Matrix t -- ^ input matrix 212 -> Matrix t -- ^ input matrix
228 -> [Vector t] -- ^ list of unitary vectors spanning the nullspace 213 -> [Vector t] -- ^ list of unitary vectors spanning the nullspace
@@ -235,12 +220,12 @@ nullspacePrec t m = ns where
235 ns = drop rank $ toRows $ ctrans v 220 ns = drop rank $ toRows $ ctrans v
236 221
237-- | The nullspace of a matrix, assumed to be one-dimensional, with default tolerance (shortcut for @last . nullspacePrec 1@). 222-- | The nullspace of a matrix, assumed to be one-dimensional, with default tolerance (shortcut for @last . nullspacePrec 1@).
238nullVector :: Optimized t => Matrix t -> Vector t 223nullVector :: GenMat t => Matrix t -> Vector t
239nullVector = last . nullspacePrec 1 224nullVector = last . nullspacePrec 1
240 225
241------------------------------------------------------------------------ 226------------------------------------------------------------------------
242 227
243{- | Pseudoinverse of a real matrix with the desired tolerance, expressed as a 228{- Pseudoinverse of a real matrix with the desired tolerance, expressed as a
244multiplicative factor of the default tolerance used by GNU-Octave (see 'pinv'). 229multiplicative factor of the default tolerance used by GNU-Octave (see 'pinv').
245 230
246@\> let m = 'fromLists' [[1,0, 0] 231@\> let m = 'fromLists' [[1,0, 0]
@@ -258,7 +243,7 @@ multiplicative factor of the default tolerance used by GNU-Octave (see 'pinv').
2580. 0. 1.@ 2430. 0. 1.@
259 244
260-} 245-}
261pinvTol :: Double -> Matrix Double -> Matrix Double 246--pinvTol :: Double -> Matrix Double -> Matrix Double
262pinvTol t m = v' `mXm` diag s' `mXm` trans u' where 247pinvTol t m = v' `mXm` diag s' `mXm` trans u' where
263 (u,s,v) = svdR m 248 (u,s,v) = svdR m
264 sl@(g:_) = toList s 249 sl@(g:_) = toList s