summaryrefslogtreecommitdiff
path: root/packages/base/src/Numeric/LinearAlgebra
diff options
context:
space:
mode:
authorAlberto Ruiz <aruiz@um.es>2014-05-16 13:35:35 +0200
committerAlberto Ruiz <aruiz@um.es>2014-05-16 13:35:35 +0200
commit1838c4248679b7476bb8716a76171712dc3cd335 (patch)
treee3909ac3354eaf917bb1ebc5a7366412b6ab8f0f /packages/base/src/Numeric/LinearAlgebra
parenta2d99e7d0e83fcedf3a856cdb927309e28a8eddd (diff)
linear algebra moved
Diffstat (limited to 'packages/base/src/Numeric/LinearAlgebra')
-rw-r--r--packages/base/src/Numeric/LinearAlgebra/LAPACK.hs2
-rw-r--r--packages/base/src/Numeric/LinearAlgebra/Util.hs291
-rw-r--r--packages/base/src/Numeric/LinearAlgebra/Util/Convolution.hs115
3 files changed, 408 insertions, 0 deletions
diff --git a/packages/base/src/Numeric/LinearAlgebra/LAPACK.hs b/packages/base/src/Numeric/LinearAlgebra/LAPACK.hs
index af0c744..9cb67d4 100644
--- a/packages/base/src/Numeric/LinearAlgebra/LAPACK.hs
+++ b/packages/base/src/Numeric/LinearAlgebra/LAPACK.hs
@@ -10,6 +10,8 @@
10-- Functional interface to selected LAPACK functions (<http://www.netlib.org/lapack>). 10-- Functional interface to selected LAPACK functions (<http://www.netlib.org/lapack>).
11-- 11--
12----------------------------------------------------------------------------- 12-----------------------------------------------------------------------------
13{-# OPTIONS_HADDOCK hide #-}
14
13 15
14module Numeric.LinearAlgebra.LAPACK ( 16module Numeric.LinearAlgebra.LAPACK (
15 -- * Matrix product 17 -- * Matrix product
diff --git a/packages/base/src/Numeric/LinearAlgebra/Util.hs b/packages/base/src/Numeric/LinearAlgebra/Util.hs
new file mode 100644
index 0000000..533c54b
--- /dev/null
+++ b/packages/base/src/Numeric/LinearAlgebra/Util.hs
@@ -0,0 +1,291 @@
1{-# LANGUAGE FlexibleContexts #-}
2-----------------------------------------------------------------------------
3{- |
4Module : Numeric.LinearAlgebra.Util
5Copyright : (c) Alberto Ruiz 2013
6License : GPL
7
8Maintainer : Alberto Ruiz (aruiz at um dot es)
9Stability : provisional
10
11-}
12-----------------------------------------------------------------------------
13{-# OPTIONS_HADDOCK hide #-}
14
15module Numeric.LinearAlgebra.Util(
16
17 -- * Convenience functions
18 size, disp,
19 zeros, ones,
20 diagl,
21 row,
22 col,
23 (&), (¦), (——), (#),
24 (?), (¿),
25 cross,
26 norm,
27 unitary,
28 mt,
29 pairwiseD2,
30 meanCov,
31 rowOuters,
32 null1,
33 null1sym,
34 -- * Convolution
35 -- ** 1D
36 corr, conv, corrMin,
37 -- ** 2D
38 corr2, conv2, separable,
39 -- * Tools for the Kronecker product
40 --
41 -- | (see A. Fusiello, A matter of notation: Several uses of the Kronecker product in
42 -- 3d computer vision, Pattern Recognition Letters 28 (15) (2007) 2127-2132)
43
44 --
45 -- | @`vec` (a \<> x \<> b) == ('trans' b ` 'kronecker' ` a) \<> 'vec' x@
46 vec,
47 vech,
48 dup,
49 vtrans,
50{- -- * Plot
51 mplot,
52 plot, parametricPlot,
53 splot, mesh, meshdom,
54 matrixToPGM, imshow,
55 gnuplotX, gnuplotpdf, gnuplotWin
56-}
57) where
58
59import Numeric.Container
60import Data.Packed.IO
61import Numeric.LinearAlgebra.Algorithms hiding (i)
62import Numeric.Matrix()
63import Numeric.Vector()
64
65import Numeric.LinearAlgebra.Util.Convolution
66--import Graphics.Plot
67
68
69{- | print a real matrix with given number of digits after the decimal point
70
71>>> disp 5 $ ident 2 / 3
722x2
730.33333 0.00000
740.00000 0.33333
75
76-}
77disp :: Int -> Matrix Double -> IO ()
78
79disp n = putStrLn . dispf n
80
81
82{- | create a real diagonal matrix from a list
83
84>>> diagl [1,2,3]
85(3><3)
86 [ 1.0, 0.0, 0.0
87 , 0.0, 2.0, 0.0
88 , 0.0, 0.0, 3.0 ]
89
90-}
91diagl :: [Double] -> Matrix Double
92diagl = diag . fromList
93
94-- | a real matrix of zeros
95zeros :: Int -- ^ rows
96 -> Int -- ^ columns
97 -> Matrix Double
98zeros r c = konst 0 (r,c)
99
100-- | a real matrix of ones
101ones :: Int -- ^ rows
102 -> Int -- ^ columns
103 -> Matrix Double
104ones r c = konst 1 (r,c)
105
106-- | concatenation of real vectors
107infixl 3 &
108(&) :: Vector Double -> Vector Double -> Vector Double
109a & b = vjoin [a,b]
110
111{- | horizontal concatenation of real matrices
112
113 (unicode 0x00a6, broken bar)
114
115>>> ident 3 ¦ konst 7 (3,4)
116(3><7)
117 [ 1.0, 0.0, 0.0, 7.0, 7.0, 7.0, 7.0
118 , 0.0, 1.0, 0.0, 7.0, 7.0, 7.0, 7.0
119 , 0.0, 0.0, 1.0, 7.0, 7.0, 7.0, 7.0 ]
120
121-}
122infixl 3 ¦
123(¦) :: Matrix Double -> Matrix Double -> Matrix Double
124a ¦ b = fromBlocks [[a,b]]
125
126-- | vertical concatenation of real matrices
127--
128-- (unicode 0x2014, em dash)
129(——) :: Matrix Double -> Matrix Double -> Matrix Double
130infixl 2 ——
131a —— b = fromBlocks [[a],[b]]
132
133(#) :: Matrix Double -> Matrix Double -> Matrix Double
134infixl 2 #
135a # b = fromBlocks [[a],[b]]
136
137-- | create a single row real matrix from a list
138row :: [Double] -> Matrix Double
139row = asRow . fromList
140
141-- | create a single column real matrix from a list
142col :: [Double] -> Matrix Double
143col = asColumn . fromList
144
145{- | extract rows
146
147>>> (20><4) [1..] ? [2,1,1]
148(3><4)
149 [ 9.0, 10.0, 11.0, 12.0
150 , 5.0, 6.0, 7.0, 8.0
151 , 5.0, 6.0, 7.0, 8.0 ]
152
153-}
154infixl 9 ?
155(?) :: Element t => Matrix t -> [Int] -> Matrix t
156(?) = flip extractRows
157
158{- | extract columns
159
160(unicode 0x00bf, inverted question mark, Alt-Gr ?)
161
162>>> (3><4) [1..] ¿ [3,0]
163(3><2)
164 [ 4.0, 1.0
165 , 8.0, 5.0
166 , 12.0, 9.0 ]
167
168-}
169infixl 9 ¿
170(¿) :: Element t => Matrix t -> [Int] -> Matrix t
171(¿)= flip extractColumns
172
173
174cross :: Vector Double -> Vector Double -> Vector Double
175-- ^ cross product (for three-element real vectors)
176cross x y | dim x == 3 && dim y == 3 = fromList [z1,z2,z3]
177 | otherwise = error $ "cross ("++show x++") ("++show y++")"
178 where
179 [x1,x2,x3] = toList x
180 [y1,y2,y3] = toList y
181 z1 = x2*y3-x3*y2
182 z2 = x3*y1-x1*y3
183 z3 = x1*y2-x2*y1
184
185norm :: Vector Double -> Double
186-- ^ 2-norm of real vector
187norm = pnorm PNorm2
188
189
190-- | Obtains a vector in the same direction with 2-norm=1
191unitary :: Vector Double -> Vector Double
192unitary v = v / scalar (norm v)
193
194-- | ('rows' &&& 'cols')
195size :: Matrix t -> (Int, Int)
196size m = (rows m, cols m)
197
198-- | trans . inv
199mt :: Matrix Double -> Matrix Double
200mt = trans . inv
201
202--------------------------------------------------------------------------------
203
204{- | Compute mean vector and covariance matrix of the rows of a matrix.
205
206>>> meanCov $ gaussianSample 666 1000 (fromList[4,5]) (diagl[2,3])
207(fromList [4.010341078059521,5.0197204699640405],
208(2><2)
209 [ 1.9862461923890056, -1.0127225830525157e-2
210 , -1.0127225830525157e-2, 3.0373954915729318 ])
211
212-}
213meanCov :: Matrix Double -> (Vector Double, Matrix Double)
214meanCov x = (med,cov) where
215 r = rows x
216 k = 1 / fromIntegral r
217 med = konst k r `vXm` x
218 meds = konst 1 r `outer` med
219 xc = x `sub` meds
220 cov = scale (recip (fromIntegral (r-1))) (trans xc `mXm` xc)
221
222--------------------------------------------------------------------------------
223
224-- | Matrix of pairwise squared distances of row vectors
225-- (using the matrix product trick in blog.smola.org)
226pairwiseD2 :: Matrix Double -> Matrix Double -> Matrix Double
227pairwiseD2 x y | ok = x2 `outer` oy + ox `outer` y2 - 2* x <> trans y
228 | otherwise = error $ "pairwiseD2 with different number of columns: "
229 ++ show (size x) ++ ", " ++ show (size y)
230 where
231 ox = one (rows x)
232 oy = one (rows y)
233 oc = one (cols x)
234 one k = constant 1 k
235 x2 = x * x <> oc
236 y2 = y * y <> oc
237 ok = cols x == cols y
238
239--------------------------------------------------------------------------------
240
241-- | outer products of rows
242rowOuters :: Matrix Double -> Matrix Double -> Matrix Double
243rowOuters a b = a' * b'
244 where
245 a' = kronecker a (ones 1 (cols b))
246 b' = kronecker (ones 1 (cols a)) b
247
248--------------------------------------------------------------------------------
249
250-- | solution of overconstrained homogeneous linear system
251null1 :: Matrix Double -> Vector Double
252null1 = last . toColumns . snd . rightSV
253
254-- | solution of overconstrained homogeneous symmetric linear system
255null1sym :: Matrix Double -> Vector Double
256null1sym = last . toColumns . snd . eigSH'
257
258--------------------------------------------------------------------------------
259
260vec :: Element t => Matrix t -> Vector t
261-- ^ stacking of columns
262vec = flatten . trans
263
264
265vech :: Element t => Matrix t -> Vector t
266-- ^ half-vectorization (of the lower triangular part)
267vech m = vjoin . zipWith f [0..] . toColumns $ m
268 where
269 f k v = subVector k (dim v - k) v
270
271
272dup :: (Num t, Num (Vector t), Element t) => Int -> Matrix t
273-- ^ duplication matrix (@'dup' k \<> 'vech' m == 'vec' m@, for symmetric m of 'dim' k)
274dup k = trans $ fromRows $ map f es
275 where
276 rs = zip [0..] (toRows (ident (k^(2::Int))))
277 es = [(i,j) | j <- [0..k-1], i <- [0..k-1], i>=j ]
278 f (i,j) | i == j = g (k*j + i)
279 | otherwise = g (k*j + i) + g (k*i + j)
280 g j = v
281 where
282 Just v = lookup j rs
283
284
285vtrans :: Element t => Int -> Matrix t -> Matrix t
286-- ^ generalized \"vector\" transposition: @'vtrans' 1 == 'trans'@, and @'vtrans' ('rows' m) m == 'asColumn' ('vec' m)@
287vtrans p m | r == 0 = fromBlocks . map (map asColumn . takesV (replicate q p)) . toColumns $ m
288 | otherwise = error $ "vtrans " ++ show p ++ " of matrix with " ++ show (rows m) ++ " rows"
289 where
290 (q,r) = divMod (rows m) p
291
diff --git a/packages/base/src/Numeric/LinearAlgebra/Util/Convolution.hs b/packages/base/src/Numeric/LinearAlgebra/Util/Convolution.hs
new file mode 100644
index 0000000..d04c46b
--- /dev/null
+++ b/packages/base/src/Numeric/LinearAlgebra/Util/Convolution.hs
@@ -0,0 +1,115 @@
1{-# LANGUAGE FlexibleContexts #-}
2-----------------------------------------------------------------------------
3{- |
4Module : Numeric.LinearAlgebra.Util.Convolution
5Copyright : (c) Alberto Ruiz 2012
6License : GPL
7
8Maintainer : Alberto Ruiz (aruiz at um dot es)
9Stability : provisional
10
11-}
12-----------------------------------------------------------------------------
13{-# OPTIONS_HADDOCK hide #-}
14
15module Numeric.LinearAlgebra.Util.Convolution(
16 corr, conv, corrMin,
17 corr2, conv2, separable
18) where
19
20import Numeric.LinearAlgebra
21
22
23vectSS :: Element t => Int -> Vector t -> Matrix t
24vectSS n v = fromRows [ subVector k n v | k <- [0 .. dim v - n] ]
25
26
27corr :: Product t => Vector t -- ^ kernel
28 -> Vector t -- ^ source
29 -> Vector t
30{- ^ correlation
31
32>>> corr (fromList[1,2,3]) (fromList [1..10])
33fromList [14.0,20.0,26.0,32.0,38.0,44.0,50.0,56.0]
34
35-}
36corr ker v | dim ker <= dim v = vectSS (dim ker) v <> ker
37 | otherwise = error $ "corr: dim kernel ("++show (dim ker)++") > dim vector ("++show (dim v)++")"
38
39
40conv :: (Product t, Num t) => Vector t -> Vector t -> Vector t
41{- ^ convolution ('corr' with reversed kernel and padded input, equivalent to polynomial product)
42
43>>> conv (fromList[1,1]) (fromList [-1,1])
44fromList [-1.0,0.0,1.0]
45
46-}
47conv ker v = corr ker' v'
48 where
49 ker' = (flatten.fliprl.asRow) ker
50 v' | dim ker > 1 = vjoin [z,v,z]
51 | otherwise = v
52 z = constant 0 (dim ker -1)
53
54corrMin :: (Container Vector t, RealElement t, Product t)
55 => Vector t
56 -> Vector t
57 -> Vector t
58-- ^ similar to 'corr', using 'min' instead of (*)
59corrMin ker v = minEvery ss (asRow ker) <> ones
60 where
61 minEvery a b = cond a b a a b
62 ss = vectSS (dim ker) v
63 ones = konst 1 (dim ker)
64
65
66
67matSS :: Element t => Int -> Matrix t -> [Matrix t]
68matSS dr m = map (reshape c) [ subVector (k*c) n v | k <- [0 .. r - dr] ]
69 where
70 v = flatten m
71 c = cols m
72 r = rows m
73 n = dr*c
74
75
76corr2 :: Product a => Matrix a -> Matrix a -> Matrix a
77-- ^ 2D correlation
78corr2 ker mat = dims
79 . concatMap (map (udot ker' . flatten) . matSS c . trans)
80 . matSS r $ mat
81 where
82 r = rows ker
83 c = cols ker
84 ker' = flatten (trans ker)
85 rr = rows mat - r + 1
86 rc = cols mat - c + 1
87 dims | rr > 0 && rc > 0 = (rr >< rc)
88 | otherwise = error $ "corr2: dim kernel ("++sz ker++") > dim matrix ("++sz mat++")"
89 sz m = show (rows m)++"x"++show (cols m)
90
91conv2 :: (Num a, Product a, Container Vector a) => Matrix a -> Matrix a -> Matrix a
92-- ^ 2D convolution
93conv2 k m = corr2 (fliprl . flipud $ k) pm
94 where
95 pm | r == 0 && c == 0 = m
96 | r == 0 = fromBlocks [[z3,m,z3]]
97 | c == 0 = fromBlocks [[z2],[m],[z2]]
98 | otherwise = fromBlocks [[z1,z2,z1]
99 ,[z3, m,z3]
100 ,[z1,z2,z1]]
101 r = rows k - 1
102 c = cols k - 1
103 h = rows m
104 w = cols m
105 z1 = konst 0 (r,c)
106 z2 = konst 0 (r,w)
107 z3 = konst 0 (h,c)
108
109-- TODO: could be simplified using future empty arrays
110
111
112separable :: Element t => (Vector t -> Vector t) -> Matrix t -> Matrix t
113-- ^ matrix computation implemented as separated vector operations by rows and columns.
114separable f = fromColumns . map f . toColumns . fromRows . map f . toRows
115