summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/Data/Packed/Internal/Vector.hs6
-rw-r--r--lib/Data/Packed/Matrix.hs166
-rw-r--r--lib/Numeric/LinearAlgebra/Algorithms.hs22
-rw-r--r--lib/Numeric/LinearAlgebra/Linear.hs6
-rw-r--r--lib/Numeric/LinearAlgebra/Tests.hs19
-rw-r--r--lib/Numeric/LinearAlgebra/Tests/Instances.hs11
6 files changed, 166 insertions, 64 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
74unsafeToForeignPtr :: Vector a -> (ForeignPtr a, Int, Int) 74unsafeToForeignPtr :: Storable a => Vector a -> (ForeignPtr a, Int, Int)
75unsafeToForeignPtr v = (fptr v, ioff v, idim v) 75unsafeToForeignPtr 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.
78unsafeFromForeignPtr :: ForeignPtr a -> Int -> Int -> Vector a 78unsafeFromForeignPtr :: Storable a => ForeignPtr a -> Int -> Int -> Vector a
79unsafeFromForeignPtr fp i n | n > 0 = V {ioff = i, idim = n, fptr = fp} 79unsafeFromForeignPtr 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
268asReal :: (RealFloat a, Storable a) => Vector (Complex a) -> Vector a 268asReal :: (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) }
270asReal v = unsafeFromForeignPtr (castForeignPtr fp) (2*i) (2*n) 269asReal 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
274asComplex :: (RealFloat a, Storable a) => Vector a -> Vector (Complex a) 273asComplex :: (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) }
276asComplex v = unsafeFromForeignPtr (castForeignPtr fp) (i `div` 2) (n `div` 2) 274asComplex 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
16module Data.Packed.Matrix ( 18module 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
47import Data.Binary 50import Data.Binary
48import Foreign.Storable 51import Foreign.Storable
49import Control.Monad(replicateM) 52import Control.Monad(replicateM)
53import Control.Arrow((***))
54import 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
465class (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
474instance 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
482instance Container Vector Double where 471class (Element t, Element (Complex t), Fractional t, RealFloat t) => Scalar t
472
473instance Scalar Double
474instance Scalar Float
475
476class 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
483instance 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 490instance Container Matrix where
490instance 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
498instance 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
506instance 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
500type family RealOf x
501
502type instance RealOf Double = Double
503type instance RealOf (Complex Double) = Double
504
505type instance RealOf Float = Float
506type instance RealOf (Complex Float) = Float
507
508type family ComplexOf x
509
510type instance ComplexOf Double = Complex Double
511type instance ComplexOf (Complex Double) = Complex Double
512
513type instance ComplexOf Float = Complex Float
514type instance ComplexOf (Complex Float) = Complex Float
515
516type family SingleOf x
517
518type instance SingleOf Double = Float
519type instance SingleOf Float = Float
520
521type instance SingleOf (Complex a) = Complex (SingleOf a)
522
523type family DoubleOf x
524
525type instance DoubleOf Double = Double
526type instance DoubleOf Float = Double
527
528type instance DoubleOf (Complex a) = Complex (DoubleOf a)
529
530type family ElementOf c
531
532type instance ElementOf (Vector a) = a
533type instance ElementOf (Matrix a) = a
534
535-------------------------------------------------------------------
536
537class 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
543instance Convert Double where
544 real' = id
545 complex' = comp
546 single = cmap double2Float
547 double = id
548
549instance Convert Float where
550 real' = id
551 complex' = comp
552 single = id
553 double = cmap float2Double
554
555instance Convert (Complex Double) where
556 real' = comp
557 complex' = id
558 single = toComplex . (single *** single) . fromComplex
559 double = id
560
561instance Convert (Complex Float) where
562 real' = comp
563 complex' = id
564 single = id
565 double = toComplex . (double *** double) . fromComplex
566
567-------------------------------------------------------------------
568
569class AutoReal t where
570 real :: Container c => c Double -> c t
571 complex :: Container c => c t -> c (Complex Double)
572
573instance AutoReal Double where
574 real = real'
575 complex = complex'
576
577instance AutoReal (Complex Double) where
578 real = real'
579 complex = complex'
515 580
516instance Container Matrix (Complex Double) where 581instance 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
585instance AutoReal (Complex Float) where
586 real = real' . single
587 complex = double . complex'
diff --git a/lib/Numeric/LinearAlgebra/Algorithms.hs b/lib/Numeric/LinearAlgebra/Algorithms.hs
index 1109296..f4b7ee9 100644
--- a/lib/Numeric/LinearAlgebra/Algorithms.hs
+++ b/lib/Numeric/LinearAlgebra/Algorithms.hs
@@ -1,4 +1,4 @@
1{-# OPTIONS_GHC -XFlexibleContexts -XFlexibleInstances #-} 1{-# LANGUAGE FlexibleContexts, FlexibleInstances #-}
2{-# LANGUAGE CPP #-} 2{-# LANGUAGE CPP #-}
3----------------------------------------------------------------------------- 3-----------------------------------------------------------------------------
4{- | 4{- |
@@ -85,7 +85,6 @@ import Numeric.LinearAlgebra.Linear
85import Data.List(foldl1') 85import Data.List(foldl1')
86import Data.Array 86import Data.Array
87 87
88
89-- | Auxiliary typeclass used to define generic computations for both real and complex matrices. 88-- | Auxiliary typeclass used to define generic computations for both real and complex matrices.
90class (Normed (Matrix t), Linear Vector t, Linear Matrix t) => Field t where 89class (Normed (Matrix t), Linear Vector t, Linear Matrix t) => Field t where
91 svd' :: Matrix t -> (Matrix t, Vector Double, Matrix t) 90 svd' :: Matrix t -> (Matrix t, Vector Double, Matrix t)
@@ -397,6 +396,10 @@ ranksv teps maxdim s = k where
397eps :: Double 396eps :: Double
398eps = 2.22044604925031e-16 397eps = 2.22044604925031e-16
399 398
399peps :: RealFloat x => x -> x
400peps x = 2.0**(fromIntegral $ 1-floatDigits x)
401
402
400-- | The imaginary unit: @i = 0.0 :+ 1.0@ 403-- | The imaginary unit: @i = 0.0 :+ 1.0@
401i :: Complex Double 404i :: Complex Double
402i = 0:+1 405i = 0:+1
@@ -467,6 +470,21 @@ instance Normed (Matrix (Complex Double)) where
467 pnorm = pnormCM 470 pnorm = pnormCM
468 471
469----------------------------------------------------------------------- 472-----------------------------------------------------------------------
473-- to be optimized
474
475instance Normed (Vector Float) where
476 pnorm t = pnorm t . double
477
478instance Normed (Vector (Complex Float)) where
479 pnorm t = pnorm t . double
480
481instance Normed (Matrix Float) where
482 pnorm t = pnorm t . double
483
484instance Normed (Matrix (Complex Float)) where
485 pnorm t = pnorm t . double
486
487-----------------------------------------------------------------------
470 488
471-- | The nullspace of a matrix from its SVD decomposition. 489-- | The nullspace of a matrix from its SVD decomposition.
472nullspaceSVD :: Field t 490nullspaceSVD :: Field t
diff --git a/lib/Numeric/LinearAlgebra/Linear.hs b/lib/Numeric/LinearAlgebra/Linear.hs
index 9a7e65f..51e93fb 100644
--- a/lib/Numeric/LinearAlgebra/Linear.hs
+++ b/lib/Numeric/LinearAlgebra/Linear.hs
@@ -17,7 +17,7 @@ Basic optimized operations on vectors and matrices.
17 17
18module Numeric.LinearAlgebra.Linear ( 18module Numeric.LinearAlgebra.Linear (
19 -- * Linear Algebra Typeclasses 19 -- * Linear Algebra Typeclasses
20 Vectors(..), 20 Vectors(..),
21 Linear(..), 21 Linear(..),
22 -- * Creation of numeric vectors 22 -- * Creation of numeric vectors
23 constant, linspace 23 constant, linspace
@@ -86,7 +86,7 @@ instance Vectors Vector (Complex Double) where
86---------------------------------------------------- 86----------------------------------------------------
87 87
88-- | Basic element-by-element functions. 88-- | Basic element-by-element functions.
89class (Container c e) => Linear c e where 89class (Element e, AutoReal e, Convert e, Container c) => Linear c e where
90 -- | create a structure with a single element 90 -- | create a structure with a single element
91 scalar :: e -> c e 91 scalar :: e -> c e
92 scale :: e -> c e -> c e 92 scale :: e -> c e -> c e
@@ -148,7 +148,7 @@ instance Linear Vector (Complex Float) where
148 equal u v = dim u == dim v && vectorMax (mapVector magnitude (sub u v)) == 0.0 148 equal u v = dim u == dim v && vectorMax (mapVector magnitude (sub u v)) == 0.0
149 scalar x = fromList [x] 149 scalar x = fromList [x]
150 150
151instance (Linear Vector a, Container Matrix a) => (Linear Matrix a) where 151instance (Linear Vector a, Container Matrix) => (Linear Matrix a) where
152 scale x = liftMatrix (scale x) 152 scale x = liftMatrix (scale x)
153 scaleRecip x = liftMatrix (scaleRecip x) 153 scaleRecip x = liftMatrix (scaleRecip x)
154 addConstant x = liftMatrix (addConstant x) 154 addConstant x = liftMatrix (addConstant x)
diff --git a/lib/Numeric/LinearAlgebra/Tests.hs b/lib/Numeric/LinearAlgebra/Tests.hs
index 5c5135c..e3b6e1f 100644
--- a/lib/Numeric/LinearAlgebra/Tests.hs
+++ b/lib/Numeric/LinearAlgebra/Tests.hs
@@ -45,6 +45,8 @@ a ~~ b = fromList a |~| fromList b
45 45
46feye n = flipud (ident n) :: Matrix Double 46feye n = flipud (ident n) :: Matrix Double
47 47
48-----------------------------------------------------------
49
48detTest1 = det m == 26 50detTest1 = det m == 26
49 && det mc == 38 :+ (-3) 51 && det mc == 38 :+ (-3)
50 && det (feye 2) == -1 52 && det (feye 2) == -1
@@ -314,17 +316,27 @@ runTests n = do
314 test (expmDiagProp . cSqWC) 316 test (expmDiagProp . cSqWC)
315 putStrLn "------ fft" 317 putStrLn "------ fft"
316 test (\v -> ifft (fft v) |~| v) 318 test (\v -> ifft (fft v) |~| v)
317 putStrLn "------ vector operations" 319 putStrLn "------ vector operations - Double"
318 test (\u -> sin u ^ 2 + cos u ^ 2 |~| (1::RM)) 320 test (\u -> sin u ^ 2 + cos u ^ 2 |~| (1::RM))
319 test $ (\u -> sin u ^ 2 + cos u ^ 2 |~| (1::CM)) . liftMatrix makeUnitary 321 test $ (\u -> sin u ^ 2 + cos u ^ 2 |~| (1::CM)) . liftMatrix makeUnitary
320 test (\u -> sin u ** 2 + cos u ** 2 |~| (1::RM)) 322 test (\u -> sin u ** 2 + cos u ** 2 |~| (1::RM))
321 test (\u -> cos u * tan u |~| sin (u::RM)) 323 test (\u -> cos u * tan u |~| sin (u::RM))
322 test $ (\u -> cos u * tan u |~| sin (u::CM)) . liftMatrix makeUnitary 324 test $ (\u -> cos u * tan u |~| sin (u::CM)) . liftMatrix makeUnitary
325 putStrLn "------ vector operations - Float"
326 test (\u -> sin u ^ 2 + cos u ^ 2 |~~| (1::FM))
327 test $ (\u -> sin u ^ 2 + cos u ^ 2 |~~| (1::ZM)) . liftMatrix makeUnitary
328 test (\u -> sin u ** 2 + cos u ** 2 |~~| (1::FM))
329 test (\u -> cos u * tan u |~~| sin (u::FM))
330 test $ (\u -> cos u * tan u |~~| sin (u::ZM)) . liftMatrix makeUnitary
323 putStrLn "------ read . show" 331 putStrLn "------ read . show"
324 test (\m -> (m::RM) == read (show m)) 332 test (\m -> (m::RM) == read (show m))
325 test (\m -> (m::CM) == read (show m)) 333 test (\m -> (m::CM) == read (show m))
326 test (\m -> toRows (m::RM) == read (show (toRows m))) 334 test (\m -> toRows (m::RM) == read (show (toRows m)))
327 test (\m -> toRows (m::CM) == read (show (toRows m))) 335 test (\m -> toRows (m::CM) == read (show (toRows m)))
336 test (\m -> (m::FM) == read (show m))
337 test (\m -> (m::ZM) == read (show m))
338 test (\m -> toRows (m::FM) == read (show (toRows m)))
339 test (\m -> toRows (m::ZM) == read (show (toRows m)))
328 putStrLn "------ some unit tests" 340 putStrLn "------ some unit tests"
329 _ <- runTestTT $ TestList 341 _ <- runTestTT $ TestList
330 [ utest "1E5 rots" rotTest 342 [ utest "1E5 rots" rotTest
@@ -358,6 +370,11 @@ runTests n = do
358 ] 370 ]
359 return () 371 return ()
360 372
373
374-- single precision approximate equality
375infixl 4 |~~|
376a |~~| b = a :~6~: b
377
361makeUnitary v | realPart n > 1 = v / scalar n 378makeUnitary v | realPart n > 1 = v / scalar n
362 | otherwise = v 379 | otherwise = v
363 where n = sqrt (conj v <.> v) 380 where n = sqrt (conj v <.> v)
diff --git a/lib/Numeric/LinearAlgebra/Tests/Instances.hs b/lib/Numeric/LinearAlgebra/Tests/Instances.hs
index bfe6871..ad59b25 100644
--- a/lib/Numeric/LinearAlgebra/Tests/Instances.hs
+++ b/lib/Numeric/LinearAlgebra/Tests/Instances.hs
@@ -22,12 +22,11 @@ module Numeric.LinearAlgebra.Tests.Instances(
22 SqWC(..), rSqWC, cSqWC, 22 SqWC(..), rSqWC, cSqWC,
23 PosDef(..), rPosDef, cPosDef, 23 PosDef(..), rPosDef, cPosDef,
24 Consistent(..), rConsist, cConsist, 24 Consistent(..), rConsist, cConsist,
25 RM,CM, rM,cM 25 RM,CM, rM,cM,
26 FM,ZM, fM,zM
26) where 27) where
27 28
28 29
29
30
31import Numeric.LinearAlgebra 30import Numeric.LinearAlgebra
32import Control.Monad(replicateM) 31import Control.Monad(replicateM)
33#include "quickCheckCompat.h" 32#include "quickCheckCompat.h"
@@ -212,9 +211,15 @@ instance (Field a, Arbitrary a) => Arbitrary (Consistent a) where
212 211
213type RM = Matrix Double 212type RM = Matrix Double
214type CM = Matrix (Complex Double) 213type CM = Matrix (Complex Double)
214type FM = Matrix Float
215type ZM = Matrix (Complex Float)
216
215 217
216rM m = m :: RM 218rM m = m :: RM
217cM m = m :: CM 219cM m = m :: CM
220fM m = m :: FM
221zM m = m :: ZM
222
218 223
219rHer (Her m) = m :: RM 224rHer (Her m) = m :: RM
220cHer (Her m) = m :: CM 225cHer (Her m) = m :: CM