diff options
author | Alberto Ruiz <aruiz@um.es> | 2007-09-15 17:55:50 +0000 |
---|---|---|
committer | Alberto Ruiz <aruiz@um.es> | 2007-09-15 17:55:50 +0000 |
commit | e0528e1a1e9ada67a39a0494f7dfccc2b6aefcad (patch) | |
tree | 7ee028012294a6d48b800c7d00d1e583833a7241 /lib/LinearAlgebra | |
parent | f901d49d1392327c79f1d4c63932fa350cfb506a (diff) |
code refactoring
Diffstat (limited to 'lib/LinearAlgebra')
-rw-r--r-- | lib/LinearAlgebra/Instances.hs | 140 | ||||
-rw-r--r-- | lib/LinearAlgebra/Linear.hs | 29 |
2 files changed, 168 insertions, 1 deletions
diff --git a/lib/LinearAlgebra/Instances.hs b/lib/LinearAlgebra/Instances.hs new file mode 100644 index 0000000..3dbe5a7 --- /dev/null +++ b/lib/LinearAlgebra/Instances.hs | |||
@@ -0,0 +1,140 @@ | |||
1 | {-# OPTIONS_GHC -fglasgow-exts -fallow-undecidable-instances #-} | ||
2 | ----------------------------------------------------------------------------- | ||
3 | {- | | ||
4 | Module : LinearAlgebra.Instances | ||
5 | Copyright : (c) Alberto Ruiz 2006 | ||
6 | License : GPL-style | ||
7 | |||
8 | Maintainer : Alberto Ruiz (aruiz at um dot es) | ||
9 | Stability : provisional | ||
10 | Portability : portable | ||
11 | |||
12 | Numeric instances for Vector and Matrix. | ||
13 | |||
14 | In the context of the standard numeric operators, one-component vectors and matrices automatically expand to match the dimensions of the other operand. | ||
15 | |||
16 | -} | ||
17 | ----------------------------------------------------------------------------- | ||
18 | |||
19 | module LinearAlgebra.Instances( | ||
20 | ) where | ||
21 | |||
22 | import LinearAlgebra.Linear | ||
23 | import GSL.Vector | ||
24 | import Data.Packed.Matrix | ||
25 | import Data.Packed.Vector | ||
26 | import Complex | ||
27 | |||
28 | adaptScalar f1 f2 f3 x y | ||
29 | | dim x == 1 = f1 (x@>0) y | ||
30 | | dim y == 1 = f3 x (y@>0) | ||
31 | | otherwise = f2 x y | ||
32 | |||
33 | liftMatrix2' :: (Field t, Field a, Field b) => (Vector a -> Vector b -> Vector t) -> Matrix a -> Matrix b -> Matrix t | ||
34 | liftMatrix2' f m1 m2 | compat' m1 m2 = reshape (max (cols m1) (cols m2)) (f (flatten m1) (flatten m2)) | ||
35 | | otherwise = error "nonconformant matrices in liftMatrix2'" | ||
36 | |||
37 | compat' :: Matrix a -> Matrix b -> Bool | ||
38 | compat' m1 m2 = rows m1 == 1 && cols m1 == 1 | ||
39 | || rows m2 == 1 && cols m2 == 1 | ||
40 | || rows m1 == rows m2 && cols m1 == cols m2 | ||
41 | |||
42 | instance (Eq a, Field a) => Eq (Vector a) where | ||
43 | a == b = dim a == dim b && toList a == toList b | ||
44 | |||
45 | instance (Linear Vector a) => Num (Vector a) where | ||
46 | (+) = adaptScalar addConstant add (flip addConstant) | ||
47 | negate = scale (-1) | ||
48 | (*) = adaptScalar scale mul (flip scale) | ||
49 | signum = liftVector signum | ||
50 | abs = liftVector abs | ||
51 | fromInteger = fromList . return . fromInteger | ||
52 | |||
53 | instance (Eq a, Field a) => Eq (Matrix a) where | ||
54 | a == b = cols a == cols b && flatten a == flatten b | ||
55 | |||
56 | instance (Linear Vector a) => Num (Matrix a) where | ||
57 | (+) = liftMatrix2' (+) | ||
58 | (-) = liftMatrix2' (-) | ||
59 | negate = liftMatrix negate | ||
60 | (*) = liftMatrix2' (*) | ||
61 | signum = liftMatrix signum | ||
62 | abs = liftMatrix abs | ||
63 | fromInteger = (1><1) . return . fromInteger | ||
64 | |||
65 | --------------------------------------------------- | ||
66 | |||
67 | instance (Linear Vector a) => Fractional (Vector a) where | ||
68 | fromRational n = fromList [fromRational n] | ||
69 | (/) = adaptScalar f divide g where | ||
70 | r `f` v = scaleRecip r v | ||
71 | v `g` r = scale (recip r) v | ||
72 | |||
73 | ------------------------------------------------------- | ||
74 | |||
75 | instance (Linear Vector a, Fractional (Vector a)) => Fractional (Matrix a) where | ||
76 | fromRational n = (1><1) [fromRational n] | ||
77 | (/) = liftMatrix2' (/) | ||
78 | |||
79 | --------------------------------------------------------- | ||
80 | |||
81 | instance Floating (Vector Double) where | ||
82 | sin = vectorMapR Sin | ||
83 | cos = vectorMapR Cos | ||
84 | tan = vectorMapR Tan | ||
85 | asin = vectorMapR ASin | ||
86 | acos = vectorMapR ACos | ||
87 | atan = vectorMapR ATan | ||
88 | sinh = vectorMapR Sinh | ||
89 | cosh = vectorMapR Cosh | ||
90 | tanh = vectorMapR Tanh | ||
91 | asinh = vectorMapR ASinh | ||
92 | acosh = vectorMapR ACosh | ||
93 | atanh = vectorMapR ATanh | ||
94 | exp = vectorMapR Exp | ||
95 | log = vectorMapR Log | ||
96 | sqrt = vectorMapR Sqrt | ||
97 | (**) = adaptScalar (vectorMapValR PowSV) (vectorZipR Pow) (flip (vectorMapValR PowVS)) | ||
98 | pi = fromList [pi] | ||
99 | |||
100 | ------------------------------------------------------------- | ||
101 | |||
102 | instance Floating (Vector (Complex Double)) where | ||
103 | sin = vectorMapC Sin | ||
104 | cos = vectorMapC Cos | ||
105 | tan = vectorMapC Tan | ||
106 | asin = vectorMapC ASin | ||
107 | acos = vectorMapC ACos | ||
108 | atan = vectorMapC ATan | ||
109 | sinh = vectorMapC Sinh | ||
110 | cosh = vectorMapC Cosh | ||
111 | tanh = vectorMapC Tanh | ||
112 | asinh = vectorMapC ASinh | ||
113 | acosh = vectorMapC ACosh | ||
114 | atanh = vectorMapC ATanh | ||
115 | exp = vectorMapC Exp | ||
116 | log = vectorMapC Log | ||
117 | sqrt = vectorMapC Sqrt | ||
118 | (**) = adaptScalar (vectorMapValC PowSV) (vectorZipC Pow) (flip (vectorMapValC PowVS)) | ||
119 | pi = fromList [pi] | ||
120 | |||
121 | ----------------------------------------------------------- | ||
122 | |||
123 | instance (Linear Vector a, Floating (Vector a)) => Floating (Matrix a) where | ||
124 | sin = liftMatrix sin | ||
125 | cos = liftMatrix cos | ||
126 | tan = liftMatrix tan | ||
127 | asin = liftMatrix asin | ||
128 | acos = liftMatrix acos | ||
129 | atan = liftMatrix atan | ||
130 | sinh = liftMatrix sinh | ||
131 | cosh = liftMatrix cosh | ||
132 | tanh = liftMatrix tanh | ||
133 | asinh = liftMatrix asinh | ||
134 | acosh = liftMatrix acosh | ||
135 | atanh = liftMatrix atanh | ||
136 | exp = liftMatrix exp | ||
137 | log = liftMatrix log | ||
138 | (**) = liftMatrix2' (**) | ||
139 | sqrt = liftMatrix sqrt | ||
140 | pi = (1><1) [pi] | ||
diff --git a/lib/LinearAlgebra/Linear.hs b/lib/LinearAlgebra/Linear.hs index a2071ed..148bbd3 100644 --- a/lib/LinearAlgebra/Linear.hs +++ b/lib/LinearAlgebra/Linear.hs | |||
@@ -15,7 +15,8 @@ Portability : uses ffi | |||
15 | 15 | ||
16 | module LinearAlgebra.Linear ( | 16 | module LinearAlgebra.Linear ( |
17 | Linear(..), | 17 | Linear(..), |
18 | multiply, dot, outer | 18 | dot, outer, |
19 | Mul(..) | ||
19 | ) where | 20 | ) where |
20 | 21 | ||
21 | 22 | ||
@@ -27,10 +28,12 @@ import Complex | |||
27 | 28 | ||
28 | class (Field e) => Linear c e where | 29 | class (Field e) => Linear c e where |
29 | scale :: e -> c e -> c e | 30 | scale :: e -> c e -> c e |
31 | scaleRecip :: e -> c e -> c e | ||
30 | addConstant :: e -> c e -> c e | 32 | addConstant :: e -> c e -> c e |
31 | add :: c e -> c e -> c e | 33 | add :: c e -> c e -> c e |
32 | sub :: c e -> c e -> c e | 34 | sub :: c e -> c e -> c e |
33 | mul :: c e -> c e -> c e | 35 | mul :: c e -> c e -> c e |
36 | divide :: c e -> c e -> c e | ||
34 | toComplex :: RealFloat e => (c e, c e) -> c (Complex e) | 37 | toComplex :: RealFloat e => (c e, c e) -> c (Complex e) |
35 | fromComplex :: RealFloat e => c (Complex e) -> (c e, c e) | 38 | fromComplex :: RealFloat e => c (Complex e) -> (c e, c e) |
36 | comp :: RealFloat e => c e -> c (Complex e) | 39 | comp :: RealFloat e => c e -> c (Complex e) |
@@ -38,10 +41,12 @@ class (Field e) => Linear c e where | |||
38 | 41 | ||
39 | instance Linear Vector Double where | 42 | instance Linear Vector Double where |
40 | scale = vectorMapValR Scale | 43 | scale = vectorMapValR Scale |
44 | scaleRecip = vectorMapValR Recip | ||
41 | addConstant = vectorMapValR AddConstant | 45 | addConstant = vectorMapValR AddConstant |
42 | add = vectorZipR Add | 46 | add = vectorZipR Add |
43 | sub = vectorZipR Sub | 47 | sub = vectorZipR Sub |
44 | mul = vectorZipR Mul | 48 | mul = vectorZipR Mul |
49 | divide = vectorZipR Div | ||
45 | toComplex = Data.Packed.Internal.toComplex | 50 | toComplex = Data.Packed.Internal.toComplex |
46 | fromComplex = Data.Packed.Internal.fromComplex | 51 | fromComplex = Data.Packed.Internal.fromComplex |
47 | comp = Data.Packed.Internal.comp | 52 | comp = Data.Packed.Internal.comp |
@@ -49,10 +54,12 @@ instance Linear Vector Double where | |||
49 | 54 | ||
50 | instance Linear Vector (Complex Double) where | 55 | instance Linear Vector (Complex Double) where |
51 | scale = vectorMapValC Scale | 56 | scale = vectorMapValC Scale |
57 | scaleRecip = vectorMapValC Recip | ||
52 | addConstant = vectorMapValC AddConstant | 58 | addConstant = vectorMapValC AddConstant |
53 | add = vectorZipC Add | 59 | add = vectorZipC Add |
54 | sub = vectorZipC Sub | 60 | sub = vectorZipC Sub |
55 | mul = vectorZipC Mul | 61 | mul = vectorZipC Mul |
62 | divide = vectorZipC Div | ||
56 | toComplex = undefined -- can't match | 63 | toComplex = undefined -- can't match |
57 | fromComplex = undefined | 64 | fromComplex = undefined |
58 | comp = undefined | 65 | comp = undefined |
@@ -60,10 +67,12 @@ instance Linear Vector (Complex Double) where | |||
60 | 67 | ||
61 | instance Linear Matrix Double where | 68 | instance Linear Matrix Double where |
62 | scale x = liftMatrix (scale x) | 69 | scale x = liftMatrix (scale x) |
70 | scaleRecip x = liftMatrix (scaleRecip x) | ||
63 | addConstant x = liftMatrix (addConstant x) | 71 | addConstant x = liftMatrix (addConstant x) |
64 | add = liftMatrix2 add | 72 | add = liftMatrix2 add |
65 | sub = liftMatrix2 sub | 73 | sub = liftMatrix2 sub |
66 | mul = liftMatrix2 mul | 74 | mul = liftMatrix2 mul |
75 | divide = liftMatrix2 divide | ||
67 | toComplex = uncurry $ liftMatrix2 $ curry LinearAlgebra.Linear.toComplex | 76 | toComplex = uncurry $ liftMatrix2 $ curry LinearAlgebra.Linear.toComplex |
68 | fromComplex z = (reshape c r, reshape c i) | 77 | fromComplex z = (reshape c r, reshape c i) |
69 | where (r,i) = LinearAlgebra.Linear.fromComplex (cdat z) | 78 | where (r,i) = LinearAlgebra.Linear.fromComplex (cdat z) |
@@ -73,10 +82,12 @@ instance Linear Matrix Double where | |||
73 | 82 | ||
74 | instance Linear Matrix (Complex Double) where | 83 | instance Linear Matrix (Complex Double) where |
75 | scale x = liftMatrix (scale x) | 84 | scale x = liftMatrix (scale x) |
85 | scaleRecip x = liftMatrix (scaleRecip x) | ||
76 | addConstant x = liftMatrix (addConstant x) | 86 | addConstant x = liftMatrix (addConstant x) |
77 | add = liftMatrix2 add | 87 | add = liftMatrix2 add |
78 | sub = liftMatrix2 sub | 88 | sub = liftMatrix2 sub |
79 | mul = liftMatrix2 mul | 89 | mul = liftMatrix2 mul |
90 | divide = liftMatrix2 divide | ||
80 | toComplex = undefined | 91 | toComplex = undefined |
81 | fromComplex = undefined | 92 | fromComplex = undefined |
82 | comp = undefined | 93 | comp = undefined |
@@ -102,3 +113,19 @@ dot u v = dat (multiply r c) `at` 0 | |||
102 | -} | 113 | -} |
103 | outer :: (Field t) => Vector t -> Vector t -> Matrix t | 114 | outer :: (Field t) => Vector t -> Vector t -> Matrix t |
104 | outer u v = asColumn u `multiply` asRow v | 115 | outer u v = asColumn u `multiply` asRow v |
116 | |||
117 | |||
118 | class Mul a b c | a b -> c where | ||
119 | infixl 7 <> | ||
120 | -- | matrix product | ||
121 | (<>) :: Field t => a t -> b t -> c t | ||
122 | |||
123 | instance Mul Matrix Matrix Matrix where | ||
124 | (<>) = multiply | ||
125 | |||
126 | instance Mul Matrix Vector Vector where | ||
127 | (<>) m v = flatten $ m <> (asColumn v) | ||
128 | |||
129 | instance Mul Vector Matrix Vector where | ||
130 | (<>) v m = flatten $ (asRow v) <> m | ||
131 | |||