diff options
-rw-r--r-- | CHANGES | 16 | ||||
-rw-r--r-- | THANKS | 2 | ||||
-rw-r--r-- | examples/monadic.hs | 40 | ||||
-rw-r--r-- | hmatrix.cabal | 26 | ||||
-rw-r--r-- | lib/Data/Packed/Vector.hs | 54 | ||||
-rw-r--r-- | lib/Numeric/LinearAlgebra/Tests.hs | 58 |
6 files changed, 118 insertions, 78 deletions
@@ -1,18 +1,20 @@ | |||
1 | 0.10.0.0 | 1 | 0.10.0.0 |
2 | ======== | 2 | ======== |
3 | 3 | ||
4 | - diagRect admits diagonal vectors of any length without producing an error, | 4 | - Module reorganization |
5 | and takes an additional argument for the off-diagonal elements. | ||
6 | 5 | ||
7 | - optimiseMult | 6 | - Support for Float and Complex Float elements (excluding LAPACK computations) |
8 | 7 | ||
9 | - module reorganization, introducing Numeric.Container | 8 | - Binary instances for Vector and Matrix |
10 | 9 | ||
11 | - vectorMapM, unzipVectorWith | 10 | - optimiseMult |
12 | 11 | ||
13 | - Support for Float and Complex Float elements (excluding LAPACK computations) | 12 | - mapVectorM, mapVectorWithIndexM, unzipVectorWith, and related functions. |
14 | 13 | ||
15 | - Binary instances for Vector and Matrix | 14 | - diagRect admits diagonal vectors of any length without producing an error, |
15 | and takes an additional argument for the off-diagonal elements. | ||
16 | |||
17 | - different signatures in some functions | ||
16 | 18 | ||
17 | 0.9.3.0 | 19 | 0.9.3.0 |
18 | ======= | 20 | ======= |
@@ -4,7 +4,7 @@ and all the people in the Haskell mailing lists for their help. | |||
4 | I am particularly grateful to Vivian McPhail for his excellent | 4 | I am particularly grateful to Vivian McPhail for his excellent |
5 | contributions: improved configure.hs, Binary instances for | 5 | contributions: improved configure.hs, Binary instances for |
6 | Vector and Matrix, support for Float and Complex Float elements, | 6 | Vector and Matrix, support for Float and Complex Float elements, |
7 | Vectors typeclass, monadic vectorMapM, and many other improvements. | 7 | module reorganization, monadic mapVectorM, and many other improvements. |
8 | 8 | ||
9 | - Nico Mahlo discovered a bug in the eigendecomposition wrapper. | 9 | - Nico Mahlo discovered a bug in the eigendecomposition wrapper. |
10 | 10 | ||
diff --git a/examples/monadic.hs b/examples/monadic.hs index b933de9..7c6e0f4 100644 --- a/examples/monadic.hs +++ b/examples/monadic.hs | |||
@@ -1,18 +1,17 @@ | |||
1 | -- monadic computations | 1 | -- monadic computations |
2 | -- (contributed by Vivian McPhail) | 2 | -- (contributed by Vivian McPhail) |
3 | 3 | ||
4 | import Numeric.Container | 4 | import Numeric.LinearAlgebra |
5 | import Control.Monad.State | 5 | import Control.Monad.State.Strict |
6 | import Control.Monad.Maybe | 6 | import Control.Monad.Maybe |
7 | import Foreign.Storable(Storable) | ||
8 | import System.Random(randomIO) | ||
7 | 9 | ||
8 | ------------------------------------------- | 10 | ------------------------------------------- |
9 | 11 | ||
10 | -- an instance of MonadIO, a monad transformer | 12 | -- an instance of MonadIO, a monad transformer |
11 | type VectorMonadT = StateT Int IO | 13 | type VectorMonadT = StateT Int IO |
12 | 14 | ||
13 | v :: Vector Int | ||
14 | v = 10 |> [0..] | ||
15 | |||
16 | test1 :: Vector Int -> IO (Vector Int) | 15 | test1 :: Vector Int -> IO (Vector Int) |
17 | test1 = mapVectorM $ \x -> do | 16 | test1 = mapVectorM $ \x -> do |
18 | putStr $ (show x) ++ " " | 17 | putStr $ (show x) ++ " " |
@@ -69,10 +68,34 @@ isMonotoneIncreasing v = | |||
69 | Nothing -> False | 68 | Nothing -> False |
70 | Just _ -> True | 69 | Just _ -> True |
71 | 70 | ||
72 | w = fromList ([1..10]++[10,9..1]) :: Vector Double | ||
73 | 71 | ||
74 | ------------------------------------------- | 72 | ------------------------------------------- |
75 | 73 | ||
74 | -- | apply a test to successive elements of a vector, evaluates to true iff test passes for all pairs | ||
75 | successive_ :: Storable a => (a -> a -> Bool) -> Vector a -> Bool | ||
76 | successive_ t v = maybe False (\_ -> True) $ evalState (runMaybeT (mapVectorM_ step (subVector 1 (dim v - 1) v))) (v @> 0) | ||
77 | where step e = do | ||
78 | ep <- lift $ get | ||
79 | if t e ep | ||
80 | then lift $ put e | ||
81 | else (fail "successive_ test failed") | ||
82 | |||
83 | -- | operate on successive elements of a vector and return the resulting vector, whose length 1 less than that of the input | ||
84 | successive :: (Storable a, Storable b) => (a -> a -> b) -> Vector a -> Vector b | ||
85 | successive f v = evalState (mapVectorM step (subVector 1 (dim v - 1) v)) (v @> 0) | ||
86 | where step e = do | ||
87 | ep <- get | ||
88 | put e | ||
89 | return $ f ep e | ||
90 | |||
91 | ------------------------------------------- | ||
92 | |||
93 | v :: Vector Int | ||
94 | v = 10 |> [0..] | ||
95 | |||
96 | w = fromList ([1..10]++[10,9..1]) :: Vector Double | ||
97 | |||
98 | |||
76 | main = do | 99 | main = do |
77 | v' <- test1 v | 100 | v' <- test1 v |
78 | putStrLn "" | 101 | putStrLn "" |
@@ -84,7 +107,12 @@ main = do | |||
84 | putStrLn "" | 107 | putStrLn "" |
85 | evalStateT (indexPlusSum v) 0 | 108 | evalStateT (indexPlusSum v) 0 |
86 | putStrLn "-----------------------" | 109 | putStrLn "-----------------------" |
110 | mapVectorM_ print v | ||
111 | print =<< (mapVectorM (const randomIO) v :: IO (Vector Double)) | ||
112 | print =<< (mapVectorM (\a -> fmap (+a) randomIO) (5|>[0,100..1000]) :: IO (Vector Double)) | ||
113 | putStrLn "-----------------------" | ||
87 | print $ isMonotoneIncreasing w | 114 | print $ isMonotoneIncreasing w |
88 | print $ isMonotoneIncreasing (subVector 0 7 w) | 115 | print $ isMonotoneIncreasing (subVector 0 7 w) |
89 | print $ successive_ (>) v | 116 | print $ successive_ (>) v |
90 | print $ successive_ (>) w | 117 | print $ successive_ (>) w |
118 | print $ successive (+) v | ||
diff --git a/hmatrix.cabal b/hmatrix.cabal index fb5ed05..a98d984 100644 --- a/hmatrix.cabal +++ b/hmatrix.cabal | |||
@@ -11,11 +11,22 @@ Description: Purely functional interface to basic linear algebra | |||
11 | and other numerical computations, internally implemented using | 11 | and other numerical computations, internally implemented using |
12 | GSL, BLAS and LAPACK. | 12 | GSL, BLAS and LAPACK. |
13 | . | 13 | . |
14 | See also hmatrix-special and hmatrix-glpk. | 14 | The Linear Algebra API is organized as follows: |
15 | . | ||
16 | - "Data.Packed": structure manipulation | ||
17 | . | ||
18 | - "Numeric.Container": simple numeric functions | ||
19 | . | ||
20 | - "Numeric.LinearAlgebra.Algorithms": matrix computations | ||
21 | . | ||
22 | - "Numeric.LinearAlgebra": everything + instances of standard Haskell numeric classes | ||
23 | . | ||
24 | See also @hmatrix-special@ for GSL special functions | ||
25 | and @hmatrix-glpk@ for linear programming (simplex). | ||
15 | Category: Math | 26 | Category: Math |
16 | tested-with: GHC ==6.10.4, GHC ==6.12.1 | 27 | tested-with: GHC ==6.10.4, GHC ==6.12.1 |
17 | 28 | ||
18 | cabal-version: >=1.2 | 29 | cabal-version: >=1.6 |
19 | 30 | ||
20 | build-type: Custom | 31 | build-type: Custom |
21 | 32 | ||
@@ -45,7 +56,7 @@ extra-source-files: examples/tests.hs | |||
45 | examples/devel/ej2/functions.c | 56 | examples/devel/ej2/functions.c |
46 | examples/Real.hs | 57 | examples/Real.hs |
47 | examples/vector.hs | 58 | examples/vector.hs |
48 | examples/vector-map.hs | 59 | examples/monadic.hs |
49 | 60 | ||
50 | extra-source-files: lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.h, | 61 | extra-source-files: lib/Numeric/LinearAlgebra/LAPACK/lapack-aux.h, |
51 | lib/Numeric/LinearAlgebra/LAPACK/clapack.h | 62 | lib/Numeric/LinearAlgebra/LAPACK/clapack.h |
@@ -120,7 +131,7 @@ library | |||
120 | lib/Numeric/GSL/gsl-aux.c | 131 | lib/Numeric/GSL/gsl-aux.c |
121 | 132 | ||
122 | if flag(vector) | 133 | if flag(vector) |
123 | Build-Depends: vector | 134 | Build-Depends: vector >= 0.7 |
124 | cpp-options: -DVECTOR | 135 | cpp-options: -DVECTOR |
125 | 136 | ||
126 | if flag(tests) | 137 | if flag(tests) |
@@ -165,7 +176,6 @@ library | |||
165 | extra-libraries: | 176 | extra-libraries: |
166 | extra-lib-dirs: | 177 | extra-lib-dirs: |
167 | 178 | ||
168 | source-repository head | 179 | source-repository head |
169 | type: darcs | 180 | type: darcs |
170 | location: http://code.haskell.org/hmatrix | 181 | location: http://code.haskell.org/hmatrix |
171 | |||
diff --git a/lib/Data/Packed/Vector.hs b/lib/Data/Packed/Vector.hs index e79e237..8b1e813 100644 --- a/lib/Data/Packed/Vector.hs +++ b/lib/Data/Packed/Vector.hs | |||
@@ -22,8 +22,7 @@ module Data.Packed.Vector ( | |||
22 | subVector, takesV, join, | 22 | subVector, takesV, join, |
23 | mapVector, zipVector, zipVectorWith, unzipVector, unzipVectorWith, | 23 | mapVector, zipVector, zipVectorWith, unzipVector, unzipVectorWith, |
24 | mapVectorM, mapVectorM_, mapVectorWithIndexM, mapVectorWithIndexM_, | 24 | mapVectorM, mapVectorM_, mapVectorWithIndexM, mapVectorWithIndexM_, |
25 | foldLoop, foldVector, foldVectorG, foldVectorWithIndex, | 25 | foldLoop, foldVector, foldVectorG, foldVectorWithIndex |
26 | successive_, successive | ||
27 | ) where | 26 | ) where |
28 | 27 | ||
29 | import Data.Packed.Internal.Vector | 28 | import Data.Packed.Internal.Vector |
@@ -84,54 +83,3 @@ unzipVector :: (Storable a, Storable b, Storable (a,b)) => Vector (a,b) -> (Vect | |||
84 | unzipVector = unzipVectorWith id | 83 | unzipVector = unzipVectorWith id |
85 | 84 | ||
86 | ------------------------------------------------------------------- | 85 | ------------------------------------------------------------------- |
87 | |||
88 | newtype State s a = State { runState :: s -> (a,s) } | ||
89 | |||
90 | instance Monad (State s) where | ||
91 | return a = State $ \s -> (a,s) | ||
92 | m >>= f = State $ \s -> let (a,s') = runState m s | ||
93 | in runState (f a) s' | ||
94 | |||
95 | state_get :: State s s | ||
96 | state_get = State $ \s -> (s,s) | ||
97 | |||
98 | state_put :: s -> State s () | ||
99 | state_put s = State $ \_ -> ((),s) | ||
100 | |||
101 | evalState :: State s a -> s -> a | ||
102 | evalState m s = let (a,s') = runState m s | ||
103 | in seq s' a | ||
104 | |||
105 | newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) } | ||
106 | |||
107 | instance Monad m => Monad (MaybeT m) where | ||
108 | return a = MaybeT $ return $ Just a | ||
109 | m >>= f = MaybeT $ do | ||
110 | res <- runMaybeT m | ||
111 | case res of | ||
112 | Nothing -> return Nothing | ||
113 | Just r -> runMaybeT (f r) | ||
114 | fail _ = MaybeT $ return Nothing | ||
115 | |||
116 | lift_maybe m = MaybeT $ do | ||
117 | res <- m | ||
118 | return $ Just res | ||
119 | |||
120 | -- | apply a test to successive elements of a vector, evaluates to true iff test passes for all pairs | ||
121 | successive_ :: Storable a => (a -> a -> Bool) -> Vector a -> Bool | ||
122 | successive_ t v = maybe False (\_ -> True) $ evalState (runMaybeT (mapVectorM_ step (subVector 1 (dim v - 1) v))) (v @> 0) | ||
123 | where step e = do | ||
124 | ep <- lift_maybe $ state_get | ||
125 | if t e ep | ||
126 | then lift_maybe $ state_put e | ||
127 | else (fail "successive_ test failed") | ||
128 | |||
129 | -- | operate on successive elements of a vector and return the resulting vector, whose length 1 less than that of the input | ||
130 | successive :: (Storable a, Storable b) => (a -> a -> b) -> Vector a -> Vector b | ||
131 | successive f v = evalState (mapVectorM step (subVector 1 (dim v - 1) v)) (v @> 0) | ||
132 | where step e = do | ||
133 | ep <- state_get | ||
134 | state_put e | ||
135 | return $ f ep e | ||
136 | |||
137 | ------------------------------------------------------------------- | ||
diff --git a/lib/Numeric/LinearAlgebra/Tests.hs b/lib/Numeric/LinearAlgebra/Tests.hs index 630ba91..093e4ef 100644 --- a/lib/Numeric/LinearAlgebra/Tests.hs +++ b/lib/Numeric/LinearAlgebra/Tests.hs | |||
@@ -26,7 +26,7 @@ import Numeric.LinearAlgebra | |||
26 | import Numeric.LinearAlgebra.LAPACK | 26 | import Numeric.LinearAlgebra.LAPACK |
27 | import Numeric.LinearAlgebra.Tests.Instances | 27 | import Numeric.LinearAlgebra.Tests.Instances |
28 | import Numeric.LinearAlgebra.Tests.Properties | 28 | import Numeric.LinearAlgebra.Tests.Properties |
29 | import Test.HUnit hiding ((~:),test,Testable) | 29 | import Test.HUnit hiding ((~:),test,Testable,State) |
30 | import System.Info | 30 | import System.Info |
31 | import Data.List(foldl1') | 31 | import Data.List(foldl1') |
32 | import Numeric.GSL | 32 | import Numeric.GSL |
@@ -300,8 +300,60 @@ conjuTest m = mapVector conjugate (flatten (trans m)) == flatten (ctrans m) | |||
300 | 300 | ||
301 | --------------------------------------------------------------------- | 301 | --------------------------------------------------------------------- |
302 | 302 | ||
303 | succTest = utest "successive" $ successive_ (>) (fromList [1 :: Double,2,3,4]) == True | 303 | newtype State s a = State { runState :: s -> (a,s) } |
304 | && successive_ (<) (fromList [1 :: Double,3,2,4]) == False | 304 | |
305 | instance Monad (State s) where | ||
306 | return a = State $ \s -> (a,s) | ||
307 | m >>= f = State $ \s -> let (a,s') = runState m s | ||
308 | in runState (f a) s' | ||
309 | |||
310 | state_get :: State s s | ||
311 | state_get = State $ \s -> (s,s) | ||
312 | |||
313 | state_put :: s -> State s () | ||
314 | state_put s = State $ \_ -> ((),s) | ||
315 | |||
316 | evalState :: State s a -> s -> a | ||
317 | evalState m s = let (a,s') = runState m s | ||
318 | in seq s' a | ||
319 | |||
320 | newtype MaybeT m a = MaybeT { runMaybeT :: m (Maybe a) } | ||
321 | |||
322 | instance Monad m => Monad (MaybeT m) where | ||
323 | return a = MaybeT $ return $ Just a | ||
324 | m >>= f = MaybeT $ do | ||
325 | res <- runMaybeT m | ||
326 | case res of | ||
327 | Nothing -> return Nothing | ||
328 | Just r -> runMaybeT (f r) | ||
329 | fail _ = MaybeT $ return Nothing | ||
330 | |||
331 | lift_maybe m = MaybeT $ do | ||
332 | res <- m | ||
333 | return $ Just res | ||
334 | |||
335 | -- | apply a test to successive elements of a vector, evaluates to true iff test passes for all pairs | ||
336 | --successive_ :: Storable a => (a -> a -> Bool) -> Vector a -> Bool | ||
337 | successive_ t v = maybe False (\_ -> True) $ evalState (runMaybeT (mapVectorM_ step (subVector 1 (dim v - 1) v))) (v @> 0) | ||
338 | where step e = do | ||
339 | ep <- lift_maybe $ state_get | ||
340 | if t e ep | ||
341 | then lift_maybe $ state_put e | ||
342 | else (fail "successive_ test failed") | ||
343 | |||
344 | -- | operate on successive elements of a vector and return the resulting vector, whose length 1 less than that of the input | ||
345 | --successive :: (Storable a, Storable b) => (a -> a -> b) -> Vector a -> Vector b | ||
346 | successive f v = evalState (mapVectorM step (subVector 1 (dim v - 1) v)) (v @> 0) | ||
347 | where step e = do | ||
348 | ep <- state_get | ||
349 | state_put e | ||
350 | return $ f ep e | ||
351 | |||
352 | |||
353 | succTest = utest "successive" $ | ||
354 | successive_ (>) (fromList [1 :: Double,2,3,4]) == True | ||
355 | && successive_ (>) (fromList [1 :: Double,3,2,4]) == False | ||
356 | && successive (+) (fromList [1..10 :: Double]) == 9 |> [3,5,7,9,11,13,15,17,19] | ||
305 | 357 | ||
306 | --------------------------------------------------------------------- | 358 | --------------------------------------------------------------------- |
307 | 359 | ||