diff options
Diffstat (limited to 'lib/Numeric/Container.hs')
-rw-r--r-- | lib/Numeric/Container.hs | 152 |
1 files changed, 123 insertions, 29 deletions
diff --git a/lib/Numeric/Container.hs b/lib/Numeric/Container.hs index 010235f..a0e489b 100644 --- a/lib/Numeric/Container.hs +++ b/lib/Numeric/Container.hs | |||
@@ -19,11 +19,13 @@ | |||
19 | ----------------------------------------------------------------------------- | 19 | ----------------------------------------------------------------------------- |
20 | 20 | ||
21 | module Numeric.Container ( | 21 | module Numeric.Container ( |
22 | Container(..), RealElement, Precision, NumericContainer(..), comp, | 22 | Linear(..), |
23 | Convert(..), AutoReal(..), | 23 | Container(..), RealElement, Precision(..), NumericContainer(..), comp, |
24 | RealOf, ComplexOf, SingleOf, DoubleOf, | 24 | -- Complexable(..), Precisionable(..), |
25 | Convert(..), --AutoReal(..), | ||
26 | RealOf, ComplexOf, SingleOf, DoubleOf, | ||
25 | 27 | ||
26 | -- ElementOf, | 28 | -- ElementOf, |
27 | 29 | ||
28 | IndexOf, | 30 | IndexOf, |
29 | 31 | ||
@@ -33,11 +35,10 @@ module Numeric.Container ( | |||
33 | import Data.Packed.Vector | 35 | import Data.Packed.Vector |
34 | import Data.Packed.Matrix | 36 | import Data.Packed.Matrix |
35 | import Data.Packed.Internal.Vector | 37 | import Data.Packed.Internal.Vector |
36 | import Data.Packed.Internal.Matrix | 38 | --import Data.Packed.Internal.Matrix |
37 | --import qualified Data.Packed.ST as ST | 39 | --import qualified Data.Packed.ST as ST |
38 | 40 | ||
39 | import Control.Arrow((***)) | 41 | --import Control.Arrow((***)) |
40 | |||
41 | import Data.Complex | 42 | import Data.Complex |
42 | 43 | ||
43 | ------------------------------------------------------------------- | 44 | ------------------------------------------------------------------- |
@@ -71,7 +72,7 @@ class NumericContainer c where | |||
71 | fromComplex :: (RealElement e) => c (Complex e) -> (c e, c e) | 72 | fromComplex :: (RealElement e) => c (Complex e) -> (c e, c e) |
72 | complex' :: (RealElement e) => c e -> c (Complex e) | 73 | complex' :: (RealElement e) => c e -> c (Complex e) |
73 | conj :: (RealElement e) => c (Complex e) -> c (Complex e) | 74 | conj :: (RealElement e) => c (Complex e) -> c (Complex e) |
74 | cmap :: (Element a, Element b) => (a -> b) -> c a -> c b | 75 | -- cmap :: (Element a, Element b) => (a -> b) -> c a -> c b |
75 | single' :: Precision a b => c b -> c a | 76 | single' :: Precision a b => c b -> c a |
76 | double' :: Precision a b => c a -> c b | 77 | double' :: Precision a b => c a -> c b |
77 | 78 | ||
@@ -79,25 +80,6 @@ class NumericContainer c where | |||
79 | comp :: (NumericContainer c, RealElement e) => c e -> c (Complex e) | 80 | comp :: (NumericContainer c, RealElement e) => c e -> c (Complex e) |
80 | comp x = complex' x | 81 | comp x = complex' x |
81 | 82 | ||
82 | instance NumericContainer Vector where | ||
83 | toComplex = toComplexV | ||
84 | fromComplex = fromComplexV | ||
85 | complex' v = toComplex (v,constantD 0 (dim v)) | ||
86 | conj = conjV | ||
87 | cmap = mapVector | ||
88 | single' = double2FloatG | ||
89 | double' = float2DoubleG | ||
90 | |||
91 | instance NumericContainer Matrix where | ||
92 | toComplex = uncurry $ liftMatrix2 $ curry toComplex | ||
93 | fromComplex z = (reshape c *** reshape c) . fromComplex . flatten $ z | ||
94 | where c = cols z | ||
95 | complex' = liftMatrix complex' | ||
96 | conj = liftMatrix conj | ||
97 | cmap f = liftMatrix (cmap f) | ||
98 | single' = liftMatrix single' | ||
99 | double' = liftMatrix double' | ||
100 | |||
101 | ------------------------------------------------------------------- | 83 | ------------------------------------------------------------------- |
102 | 84 | ||
103 | type family RealOf x | 85 | type family RealOf x |
@@ -141,14 +123,78 @@ type instance IndexOf Vector = Int | |||
141 | type instance IndexOf Matrix = (Int,Int) | 123 | type instance IndexOf Matrix = (Int,Int) |
142 | 124 | ||
143 | ------------------------------------------------------------------- | 125 | ------------------------------------------------------------------- |
126 | {- | ||
127 | -- | Supported single-double precision type pairs | ||
128 | class (Element e) => V_Precision e where | ||
129 | v_double2FloatG :: Vector e -> Vector (SingleOf e) | ||
130 | v_float2DoubleG :: Vector (SingleOf e) -> Vector e | ||
131 | {- | ||
132 | instance V_Precision Float where | ||
133 | v_double2FloatG = double2FloatV | ||
134 | v_float2DoubleG = float2DoubleV | ||
135 | -} | ||
136 | instance V_Precision Double where | ||
137 | v_double2FloatG = double2FloatV | ||
138 | v_float2DoubleG = float2DoubleV | ||
139 | {- | ||
140 | instance V_Precision (Complex Float) where | ||
141 | v_double2FloatG = asComplex . double2FloatV . asReal | ||
142 | v_float2DoubleG = asComplex . float2DoubleV . asReal | ||
143 | -} | ||
144 | instance V_Precision (Complex Double) where | ||
145 | v_double2FloatG = asComplex . double2FloatV . asReal | ||
146 | v_float2DoubleG = asComplex . float2DoubleV . asReal | ||
147 | -} | ||
148 | ------------------------------------------------------------------- | ||
149 | {- | ||
150 | -- | converting to/from complex containers | ||
151 | class RealElement t => Complexable c t where | ||
152 | v_toComplex :: (c t, c t) -> c (Complex t) | ||
153 | v_fromComplex :: c (Complex t) -> (c t, c t) | ||
154 | v_complex' :: c t -> c (Complex t) | ||
155 | v_conj :: c (Complex t) -> c (Complex t) | ||
156 | |||
157 | -- | converting to/from single/double precision numbers | ||
158 | class (Element (SingleOf t), Element t, RealElement (RealOf t)) => Precisionable c t where | ||
159 | v_single' :: (V_Precision (DoubleOf t)) => c t -> c (SingleOf t) | ||
160 | v_double' :: (V_Precision (DoubleOf t)) => c t -> c (DoubleOf t) | ||
144 | 161 | ||
145 | -- | generic conversion functions | 162 | -- | generic conversion functions |
146 | class Convert t where | 163 | class (Element t, RealElement (RealOf t)) => V_Convert t where |
164 | -- | real/complex | ||
165 | v_real :: Complexable c (RealOf t) => c (RealOf t) -> c t -- from the instances, this looks like it turns a real object into a complex object WHEN the context is a complex object | ||
166 | v_complex :: Complexable c (RealOf t) => c t -> c (ComplexOf t) | ||
167 | -- | single/double | ||
168 | v_single :: Precisionable c t => c t -> c (SingleOf t) | ||
169 | v_double :: Precisionable c t => c t -> c (DoubleOf t) | ||
170 | -} | ||
171 | ------------------------------------------------------------------- | ||
172 | {- | ||
173 | instance Precisionable Vector Float where | ||
174 | v_single' = id | ||
175 | v_double' = float2DoubleG | ||
176 | |||
177 | instance Precisionable Vector Double where | ||
178 | v_single' = double2FloatG | ||
179 | v_double' = id | ||
180 | |||
181 | instance Precisionable Vector (Complex Float) where | ||
182 | v_single' = id | ||
183 | v_double' = float2DoubleG | ||
184 | |||
185 | instance Precisionable Vector (Complex Double) where | ||
186 | v_single' = double2FloatG | ||
187 | v_double' = id | ||
188 | -} | ||
189 | ------------------------------------------------------------------- | ||
190 | |||
191 | class (Element t, Element (RealOf t)) => Convert t where | ||
147 | real :: NumericContainer c => c (RealOf t) -> c t | 192 | real :: NumericContainer c => c (RealOf t) -> c t |
148 | complex :: NumericContainer c => c t -> c (ComplexOf t) | 193 | complex :: NumericContainer c => c t -> c (ComplexOf t) |
149 | single :: NumericContainer c => c t -> c (SingleOf t) | 194 | single :: NumericContainer c => c t -> c (SingleOf t) |
150 | double :: NumericContainer c => c t -> c (DoubleOf t) | 195 | double :: NumericContainer c => c t -> c (DoubleOf t) |
151 | 196 | ||
197 | |||
152 | instance Convert Double where | 198 | instance Convert Double where |
153 | real = id | 199 | real = id |
154 | complex = complex' | 200 | complex = complex' |
@@ -180,6 +226,7 @@ class Convert t => AutoReal t where | |||
180 | real'' :: NumericContainer c => c Double -> c t | 226 | real'' :: NumericContainer c => c Double -> c t |
181 | complex'' :: NumericContainer c => c t -> c (Complex Double) | 227 | complex'' :: NumericContainer c => c t -> c (Complex Double) |
182 | 228 | ||
229 | |||
183 | instance AutoReal Double where | 230 | instance AutoReal Double where |
184 | real'' = real | 231 | real'' = real |
185 | complex'' = complex | 232 | complex'' = complex |
@@ -198,13 +245,60 @@ instance AutoReal (Complex Float) where | |||
198 | 245 | ||
199 | ------------------------------------------------------------------- | 246 | ------------------------------------------------------------------- |
200 | 247 | ||
201 | -- | Basic element-by-element functions. | 248 | -- | Basic element-by-element functions for numeric containers |
202 | class (Element e) => Container c e where | 249 | class (Element e) => Container c e where |
250 | {- | ||
251 | -- | create a structure with a single element | ||
252 | scalar :: e -> c e | ||
253 | -- | multiply every element by a scalar | ||
254 | scale :: e -> c e -> c e | ||
255 | -- | scale the element by element reciprocal of the object: | ||
256 | -- | ||
257 | -- @scaleRecip 2 (fromList [5,i]) == 2 |> [0.4 :+ 0.0,0.0 :+ (-2.0)]@ | ||
258 | scaleRecip :: e -> c e -> c e | ||
259 | -- | add a constant to each element | ||
260 | addConstant :: e -> c e -> c e | ||
261 | add :: c e -> c e -> c e | ||
262 | sub :: c e -> c e -> c e | ||
263 | -- | element by element multiplication | ||
264 | mul :: c e -> c e -> c e | ||
265 | -- | element by element division | ||
266 | divide :: c e -> c e -> c e | ||
267 | equal :: c e -> c e -> Bool | ||
268 | -} | ||
269 | -- | cannot implement instance Functor because of Element class constraint | ||
270 | cmap :: (Element a, Element b) => (a -> b) -> c a -> c b | ||
271 | -- | ||
272 | -- | indexing function | ||
273 | atIndex :: c e -> IndexOf c -> e | ||
274 | -- | index of min/max element | ||
203 | minIndex :: c e -> IndexOf c | 275 | minIndex :: c e -> IndexOf c |
204 | maxIndex :: c e -> IndexOf c | 276 | maxIndex :: c e -> IndexOf c |
277 | -- | value of min/max element | ||
205 | minElement :: c e -> e | 278 | minElement :: c e -> e |
206 | maxElement :: c e -> e | 279 | maxElement :: c e -> e |
280 | -- the C functions sumX/prodX are twice as fast as using foldVector | ||
281 | -- | the sum/product of elements (faster than using @fold@ | ||
282 | sumElements :: c e -> e | ||
283 | prodElements :: c e -> e | ||
207 | 284 | ||
285 | -- | Basic element-by-element functions. | ||
286 | class (Element e, Container c e) => Linear c e where | ||
287 | -- | create a structure with a single element | ||
288 | scalar :: e -> c e | ||
289 | scale :: e -> c e -> c e | ||
290 | -- | scale the element by element reciprocal of the object: | ||
291 | -- | ||
292 | -- @scaleRecip 2 (fromList [5,i]) == 2 |> [0.4 :+ 0.0,0.0 :+ (-2.0)]@ | ||
293 | scaleRecip :: e -> c e -> c e | ||
294 | addConstant :: e -> c e -> c e | ||
295 | add :: c e -> c e -> c e | ||
296 | sub :: c e -> c e -> c e | ||
297 | -- | element by element multiplication | ||
298 | mul :: c e -> c e -> c e | ||
299 | -- | element by element division | ||
300 | divide :: c e -> c e -> c e | ||
301 | equal :: c e -> c e -> Bool | ||
208 | 302 | ||
209 | 303 | ||
210 | 304 | ||