git.iko.soy/rowtype-yoga/purescript-linear-algebra
on master help sign in
Added basic operation of vector
commite0d0295e8c3ba58f4131b5c7bd63bab0ff28fa4e authorklangner <klangner@gmail.com> dateTue 25 Apr 2017, 11:22 (9 years ago) parent8a35a1a
5 files changed+100−6
bower.json+1 src/LinearAlgebra/Vector.purs+59−1 test/Main.purs+4−2 test/Test/LinearAlgebra/Vector.purs+33 test/Test/LinearAlgebra/Benchmarks.purs → test/Test/PerfTest.purs+3−3
bower.json+1
@@ -16,6 +16,7 @@
1616 "dependencies": {
1717 "purescript-prelude": "^3.0.0",
1818 "purescript-arrays": "^4.0.1",
19+ "purescript-globals": "^3.0.0",
1920 "purescript-tuples": "^4.0.0"
2021 },
2122 "devDependencies": {
src/LinearAlgebra/Vector.purs+59−1
@@ -1,8 +1,66 @@
11module LinearAlgebra.Vector
22 ( Vector
3+ , add
4+ , argmax
5+ , argmin
6+ , diff
7+ , dot
8+ , sum
39 ) where
410
11+import Prelude
12+import Global (infinity)
13+import Data.Array as A
14+import Data.Maybe (Maybe(..))
15+import Data.Tuple (Tuple(..), fst, snd)
16+
517
618-- | Dense Vector implementation
719type Vector = Array
8−
20+
21+
22+-- | Difference between 2 vectors.
23+-- | Vector have to have the same size
24+diff :: Vector Number -> Vector Number -> Maybe (Vector Number)
25+diff xs ys
26+ | (A.length xs) /= (A.length ys) = Nothing
27+ | otherwise = Just $ A.zipWith (-) xs ys
28+
29+
30+-- | Add 2 vectors.
31+-- | Vector have to have the same size
32+add :: ∀ a. Semiring a => Vector a -> Vector a -> Maybe (Vector a)
33+add xs ys
34+ | (A.length xs) /= (A.length ys) = Nothing
35+ | otherwise = Just $ A.zipWith (+) xs ys
36+
37+
38+-- | Dot product between 2 vectors
39+-- | https://en.wikipedia.org/wiki/Dot_product
40+dot :: ∀ a. Semiring a => Vector a -> Vector a -> Maybe a
41+dot xs ys
42+ | (A.length xs) /= (A.length ys) = Nothing
43+ | otherwise = Just $ sum (A.zipWith (*) xs ys)
44+
45+
46+-- | Sum vector elements
47+sum :: ∀ a. Semiring a => Vector a -> a
48+sum xs = A.foldl (+) zero xs
49+
50+
51+-- | Return index of the first maximum value
52+-- | This function will return 0 index for empty vector
53+argmax :: Vector Number -> Int
54+argmax vs = fst $ A.foldl f (Tuple 0 (-infinity)) xs
55+ where
56+ xs = A.mapWithIndex Tuple vs
57+ f tu tv = if (snd tv) > (snd tu) then tv else tu
58+
59+
60+-- | Return index of the first minimum value
61+-- | This function will return 0 index for empty vector
62+argmin :: Vector Number -> Int
63+argmin vs = fst $ A.foldl f (Tuple 0 infinity) xs
64+ where
65+ xs = A.mapWithIndex Tuple vs
66+ f tu tv = if (snd tv) < (snd tu) then tv else tu
test/Main.purs+4−2
@@ -7,11 +7,13 @@ import Control.Monad.Eff.Console (CONSOLE)
77import Test.Assert (ASSERT)
88
99import Test.LinearAlgebra.Matrix (testMatrix)
10−import Test.LinearAlgebra.Benchmarks (benchmarks)
10+import Test.LinearAlgebra.Vector (testVector)
11+import Test.PerfTest (perfTests)
1112
1213
1314main :: ∀ eff. Eff (console :: CONSOLE, assert :: ASSERT | eff) Unit
1415main = do
1516 testMatrix
16− benchmarks
17+ testVector
18+ perfTests
1719
test/Test/LinearAlgebra/Vector.pursnew file+33
@@ -0,0 +1,33 @@
1+module Test.LinearAlgebra.Vector (testVector) where
2+
3+import Prelude
4+import Control.Monad.Eff (Eff)
5+import Control.Monad.Eff.Console (log, CONSOLE)
6+import Data.Maybe (Maybe(..))
7+import Test.Assert (assert, ASSERT)
8+
9+import LinearAlgebra.Vector as V
10+
11+
12+testVector :: forall eff. Eff (console :: CONSOLE, assert :: ASSERT | eff) Unit
13+testVector = do
14+
15+ log "\n#Vector tests"
16+
17+ log "Add vectors"
18+ assert $ V.add [1.0, 2.0, -3.0] [1.0, 1.0, 1.0, 5.0] == Nothing
19+ assert $ V.add [1.0, 2.0, -3.0] [1.0, 1.0, 1.0] == Just [2.0, 3.0, -2.0]
20+
21+ log "Difference"
22+ assert $ V.diff [1.0, 2.0, -3.0] [1.0, 1.0, 1.0, 5.0] == Nothing
23+ assert $ V.diff [1.0, 2.0, -3.0] [1.0, 1.0, 1.0] == Just [0.0, 1.0, -4.0]
24+
25+ log "Dot product"
26+ assert $ V.dot [1.0, 2.0, -3.0] [1.0, 2.0, 1.0] == Just (2.0)
27+
28+ log "argmax"
29+ assert $ V.argmax [1.0, 2.0, -3.0, 1.0, 2.0, 1.0] == 1
30+
31+ log "argmin"
32+ assert $ V.argmin [1.0, 2.0, -3.0, 1.0, 2.0, 1.0] == 2
33+
test/Test/LinearAlgebra/Benchmarks.purs → test/Test/PerfTest.pursrenamed+3−3
@@ -1,4 +1,4 @@
1−module Test.LinearAlgebra.Benchmarks (benchmarks) where
1+module Test.PerfTest (perfTests) where
22
33import Prelude
44import Control.Monad.Eff (Eff)
@@ -10,8 +10,8 @@ import Partial.Unsafe (unsafePartial)
1010import LinearAlgebra.Matrix as M
1111
1212
13−benchmarks :: forall eff. Eff (console :: CONSOLE, assert :: ASSERT | eff) Unit
14−benchmarks = do
13+perfTests :: forall eff. Eff (console :: CONSOLE, assert :: ASSERT | eff) Unit
14+perfTests = do
1515
1616 log "\n# Run Benchmarks"
1717