diff options
Diffstat (limited to 'lib/Data')
-rw-r--r-- | lib/Data/Packed/Internal/Vector.hs | 6 | ||||
-rw-r--r-- | lib/Data/Packed/Matrix.hs | 166 |
2 files changed, 117 insertions, 55 deletions
diff --git a/lib/Data/Packed/Internal/Vector.hs b/lib/Data/Packed/Internal/Vector.hs index 652b980..ac2d0d7 100644 --- a/lib/Data/Packed/Internal/Vector.hs +++ b/lib/Data/Packed/Internal/Vector.hs | |||
@@ -71,11 +71,11 @@ data Vector t = | |||
71 | , fptr :: {-# UNPACK #-} !(ForeignPtr t) -- ^ foreign pointer to the memory block | 71 | , fptr :: {-# UNPACK #-} !(ForeignPtr t) -- ^ foreign pointer to the memory block |
72 | } | 72 | } |
73 | 73 | ||
74 | unsafeToForeignPtr :: Vector a -> (ForeignPtr a, Int, Int) | 74 | unsafeToForeignPtr :: Storable a => Vector a -> (ForeignPtr a, Int, Int) |
75 | unsafeToForeignPtr v = (fptr v, ioff v, idim v) | 75 | unsafeToForeignPtr v = (fptr v, ioff v, idim v) |
76 | 76 | ||
77 | -- | Same convention as in Roman Leshchinskiy's vector package. | 77 | -- | Same convention as in Roman Leshchinskiy's vector package. |
78 | unsafeFromForeignPtr :: ForeignPtr a -> Int -> Int -> Vector a | 78 | unsafeFromForeignPtr :: Storable a => ForeignPtr a -> Int -> Int -> Vector a |
79 | unsafeFromForeignPtr fp i n | n > 0 = V {ioff = i, idim = n, fptr = fp} | 79 | unsafeFromForeignPtr fp i n | n > 0 = V {ioff = i, idim = n, fptr = fp} |
80 | | otherwise = error "unsafeFromForeignPtr with dim < 1" | 80 | | otherwise = error "unsafeFromForeignPtr with dim < 1" |
81 | 81 | ||
@@ -266,13 +266,11 @@ takesV ms w | sum ms > dim w = error $ "takesV " ++ show ms ++ " on dim = " ++ ( | |||
266 | 266 | ||
267 | -- | transforms a complex vector into a real vector with alternating real and imaginary parts | 267 | -- | transforms a complex vector into a real vector with alternating real and imaginary parts |
268 | asReal :: (RealFloat a, Storable a) => Vector (Complex a) -> Vector a | 268 | asReal :: (RealFloat a, Storable a) => Vector (Complex a) -> Vector a |
269 | --asReal v = V { ioff = 2*ioff v, idim = 2*dim v, fptr = castForeignPtr (fptr v) } | ||
270 | asReal v = unsafeFromForeignPtr (castForeignPtr fp) (2*i) (2*n) | 269 | asReal v = unsafeFromForeignPtr (castForeignPtr fp) (2*i) (2*n) |
271 | where (fp,i,n) = unsafeToForeignPtr v | 270 | where (fp,i,n) = unsafeToForeignPtr v |
272 | 271 | ||
273 | -- | transforms a real vector into a complex vector with alternating real and imaginary parts | 272 | -- | transforms a real vector into a complex vector with alternating real and imaginary parts |
274 | asComplex :: (RealFloat a, Storable a) => Vector a -> Vector (Complex a) | 273 | asComplex :: (RealFloat a, Storable a) => Vector a -> Vector (Complex a) |
275 | --asComplex v = V { ioff = ioff v `div` 2, idim = dim v `div` 2, fptr = castForeignPtr (fptr v) } | ||
276 | asComplex v = unsafeFromForeignPtr (castForeignPtr fp) (i `div` 2) (n `div` 2) | 274 | asComplex v = unsafeFromForeignPtr (castForeignPtr fp) (i `div` 2) (n `div` 2) |
277 | where (fp,i,n) = unsafeToForeignPtr v | 275 | where (fp,i,n) = unsafeToForeignPtr v |
278 | 276 | ||
diff --git a/lib/Data/Packed/Matrix.hs b/lib/Data/Packed/Matrix.hs index d5a287d..8aa1693 100644 --- a/lib/Data/Packed/Matrix.hs +++ b/lib/Data/Packed/Matrix.hs | |||
@@ -1,4 +1,6 @@ | |||
1 | {-# LANGUAGE MultiParamTypeClasses, FlexibleInstances, FlexibleContexts #-} | 1 | {-# LANGUAGE TypeFamilies #-} |
2 | {-# LANGUAGE FlexibleContexts #-} | ||
3 | {-# LANGUAGE FlexibleInstances #-} | ||
2 | ----------------------------------------------------------------------------- | 4 | ----------------------------------------------------------------------------- |
3 | -- | | 5 | -- | |
4 | -- Module : Data.Packed.Matrix | 6 | -- Module : Data.Packed.Matrix |
@@ -14,7 +16,8 @@ | |||
14 | ----------------------------------------------------------------------------- | 16 | ----------------------------------------------------------------------------- |
15 | 17 | ||
16 | module Data.Packed.Matrix ( | 18 | module Data.Packed.Matrix ( |
17 | Element, Container(..), | 19 | Element, Scalar, Container(..), Convert(..), |
20 | RealOf, ComplexOf, SingleOf, DoubleOf, ElementOf, AutoReal(..), | ||
18 | Matrix,rows,cols, | 21 | Matrix,rows,cols, |
19 | (><), | 22 | (><), |
20 | trans, | 23 | trans, |
@@ -47,6 +50,8 @@ import Data.Complex | |||
47 | import Data.Binary | 50 | import Data.Binary |
48 | import Foreign.Storable | 51 | import Foreign.Storable |
49 | import Control.Monad(replicateM) | 52 | import Control.Monad(replicateM) |
53 | import Control.Arrow((***)) | ||
54 | import GHC.Float(double2Float,float2Double) | ||
50 | 55 | ||
51 | ------------------------------------------------------------------- | 56 | ------------------------------------------------------------------- |
52 | 57 | ||
@@ -462,62 +467,121 @@ toBlocksEvery r c m = toBlocks rs cs m where | |||
462 | ------------------------------------------------------------------- | 467 | ------------------------------------------------------------------- |
463 | 468 | ||
464 | -- | conversion utilities | 469 | -- | conversion utilities |
465 | class (Element e) => Container c e where | ||
466 | toComplex :: RealFloat e => (c e, c e) -> c (Complex e) | ||
467 | fromComplex :: RealFloat e => c (Complex e) -> (c e, c e) | ||
468 | comp :: RealFloat e => c e -> c (Complex e) | ||
469 | conj :: RealFloat e => c (Complex e) -> c (Complex e) | ||
470 | -- these next two are now weird given we have Floats as well | ||
471 | real :: c Double -> c e | ||
472 | complex :: c e -> c (Complex Double) | ||
473 | |||
474 | instance Container Vector Float where | ||
475 | toComplex = toComplexV | ||
476 | fromComplex = fromComplexV | ||
477 | comp v = toComplex (v,constantD 0 (dim v)) | ||
478 | conj = conjV | ||
479 | real = mapVector realToFrac | ||
480 | complex = (mapVector (\(r :+ i) -> (realToFrac r :+ realToFrac i))) . comp | ||
481 | 470 | ||
482 | instance Container Vector Double where | 471 | class (Element t, Element (Complex t), Fractional t, RealFloat t) => Scalar t |
472 | |||
473 | instance Scalar Double | ||
474 | instance Scalar Float | ||
475 | |||
476 | class Container c where | ||
477 | toComplex :: (Scalar e) => (c e, c e) -> c (Complex e) | ||
478 | fromComplex :: (Scalar e) => c (Complex e) -> (c e, c e) | ||
479 | comp :: (Scalar e) => c e -> c (Complex e) | ||
480 | conj :: (Scalar e) => c (Complex e) -> c (Complex e) | ||
481 | cmap :: (Element a, Element b) => (a -> b) -> c a -> c b | ||
482 | |||
483 | instance Container Vector where | ||
483 | toComplex = toComplexV | 484 | toComplex = toComplexV |
484 | fromComplex = fromComplexV | 485 | fromComplex = fromComplexV |
485 | comp v = toComplex (v,constantD 0 (dim v)) | 486 | comp v = toComplex (v,constantD 0 (dim v)) |
486 | conj = conjV | 487 | conj = conjV |
487 | real = id | 488 | cmap = mapVector |
488 | complex = comp | 489 | |
489 | 490 | instance Container Matrix where | |
490 | instance Container Vector (Complex Float) where | ||
491 | toComplex = undefined -- can't match | ||
492 | fromComplex = undefined | ||
493 | comp = undefined | ||
494 | conj = undefined | ||
495 | real = comp . mapVector realToFrac | ||
496 | complex = mapVector (\(r :+ i) -> realToFrac r :+ realToFrac i) | ||
497 | |||
498 | instance Container Vector (Complex Double) where | ||
499 | toComplex = undefined -- can't match | ||
500 | fromComplex = undefined | ||
501 | comp = undefined | ||
502 | conj = undefined | ||
503 | real = comp | ||
504 | complex = id | ||
505 | |||
506 | instance Container Matrix Double where | ||
507 | toComplex = uncurry $ liftMatrix2 $ curry toComplex | 491 | toComplex = uncurry $ liftMatrix2 $ curry toComplex |
508 | fromComplex z = (reshape c r, reshape c i) | 492 | fromComplex z = (reshape c *** reshape c) . fromComplex . flatten $ z |
509 | where (r,i) = fromComplex (flatten z) | 493 | where c = cols z |
510 | c = cols z | ||
511 | comp = liftMatrix comp | 494 | comp = liftMatrix comp |
512 | conj = liftMatrix conj | 495 | conj = liftMatrix conj |
513 | real = id | 496 | cmap f = liftMatrix (cmap f) |
514 | complex = comp | 497 | |
498 | ------------------------------------------------------------------- | ||
499 | |||
500 | type family RealOf x | ||
501 | |||
502 | type instance RealOf Double = Double | ||
503 | type instance RealOf (Complex Double) = Double | ||
504 | |||
505 | type instance RealOf Float = Float | ||
506 | type instance RealOf (Complex Float) = Float | ||
507 | |||
508 | type family ComplexOf x | ||
509 | |||
510 | type instance ComplexOf Double = Complex Double | ||
511 | type instance ComplexOf (Complex Double) = Complex Double | ||
512 | |||
513 | type instance ComplexOf Float = Complex Float | ||
514 | type instance ComplexOf (Complex Float) = Complex Float | ||
515 | |||
516 | type family SingleOf x | ||
517 | |||
518 | type instance SingleOf Double = Float | ||
519 | type instance SingleOf Float = Float | ||
520 | |||
521 | type instance SingleOf (Complex a) = Complex (SingleOf a) | ||
522 | |||
523 | type family DoubleOf x | ||
524 | |||
525 | type instance DoubleOf Double = Double | ||
526 | type instance DoubleOf Float = Double | ||
527 | |||
528 | type instance DoubleOf (Complex a) = Complex (DoubleOf a) | ||
529 | |||
530 | type family ElementOf c | ||
531 | |||
532 | type instance ElementOf (Vector a) = a | ||
533 | type instance ElementOf (Matrix a) = a | ||
534 | |||
535 | ------------------------------------------------------------------- | ||
536 | |||
537 | class Convert t where | ||
538 | real' :: Container c => c (RealOf t) -> c t | ||
539 | complex' :: Container c => c t -> c (ComplexOf t) | ||
540 | single :: Container c => c t -> c (SingleOf t) | ||
541 | double :: Container c => c t -> c (DoubleOf t) | ||
542 | |||
543 | instance Convert Double where | ||
544 | real' = id | ||
545 | complex' = comp | ||
546 | single = cmap double2Float | ||
547 | double = id | ||
548 | |||
549 | instance Convert Float where | ||
550 | real' = id | ||
551 | complex' = comp | ||
552 | single = id | ||
553 | double = cmap float2Double | ||
554 | |||
555 | instance Convert (Complex Double) where | ||
556 | real' = comp | ||
557 | complex' = id | ||
558 | single = toComplex . (single *** single) . fromComplex | ||
559 | double = id | ||
560 | |||
561 | instance Convert (Complex Float) where | ||
562 | real' = comp | ||
563 | complex' = id | ||
564 | single = id | ||
565 | double = toComplex . (double *** double) . fromComplex | ||
566 | |||
567 | ------------------------------------------------------------------- | ||
568 | |||
569 | class AutoReal t where | ||
570 | real :: Container c => c Double -> c t | ||
571 | complex :: Container c => c t -> c (Complex Double) | ||
572 | |||
573 | instance AutoReal Double where | ||
574 | real = real' | ||
575 | complex = complex' | ||
576 | |||
577 | instance AutoReal (Complex Double) where | ||
578 | real = real' | ||
579 | complex = complex' | ||
515 | 580 | ||
516 | instance Container Matrix (Complex Double) where | 581 | instance AutoReal Float where |
517 | toComplex = undefined | 582 | real = real' . single |
518 | fromComplex = undefined | 583 | complex = double . complex' |
519 | comp = undefined | ||
520 | conj = undefined | ||
521 | real = comp | ||
522 | complex = id | ||
523 | 584 | ||
585 | instance AutoReal (Complex Float) where | ||
586 | real = real' . single | ||
587 | complex = double . complex' | ||