0 | module Data.VectorSpace
 1 |
 2 | import Data.Vect
 3 |
 4 | export infixr 9 *^
 5 | export infixl 9 ^/
 6 | export infixl 6 ^+^, ^-^
 7 | export infix 7 `dot`
 8 |
 9 | public export
10 | interface VectorSpace v where
11 |   ||| Vector with no magnitude (unit for addition).
12 |   zeroVector : v
13 |
14 |   ||| Multiplication by a scalar.
15 |   (*^) : Double -> v -> v
16 |
17 |   ||| Division by a scalar.
18 |   (^/) : v -> Double -> v
19 |
20 |   ||| Vector addition
21 |   (^+^) : v -> v -> v
22 |
23 |   ||| Vector subtraction
24 |   (^-^) : v -> v -> v
25 |
26 |   ||| Vector negation. Addition with a negated vector should
27 |   ||| be same as subtraction.
28 |   negateVector : v -> v
29 |   negateVector v = zeroVector ^-^ v
30 |
31 |   ||| Dot product (also known as scalar or inner product).
32 |   ||| For two vectors, mathematically represented as a = a1,a2,...,an and b = b1,b2,...,bn,
33 |   ||| the dot product is a . b = a1*b1 + a2*b2 + ... + an*bn.
34 |   dot : v -> v -> Double
35 |
36 |   ||| Vector's norm (also known as magnitude).
37 |   ||| For a vector represented mathematically
38 |   ||| as a = a1,a2,...,an, the norm is the square root of a1^2 + a2^2 + ... + an^2.
39 |   norm : v -> Double
40 |   norm v = sqrt $ dot v v
41 |
42 |   ||| Return a vector with the same origin and orientation (angle),
43 |   ||| but such that the norm is one (the unit for multiplication by a scalar).
44 |   normalize : v -> v
45 |   normalize v = let n = norm v in if n == 0 then v else v ^/ n
46 |
47 | --------------------------------------------------------------------------------
48 | --          Implementations
49 | --------------------------------------------------------------------------------
50 |
51 | public export
52 | VectorSpace Double where
53 |   zeroVector = 0.0
54 |   (^-^) = (-)
55 |   (^+^) = (+)
56 |   (^/)  = (/)
57 |   (*^)  = (*)
58 |   dot   = (*)
59 |
60 | public export
61 | {n : _} -> VectorSpace (Vect n Double) where
62 |   zeroVector = replicate n 0.0
63 |   (^-^)   = zipWith (-)
64 |   (^+^)   = zipWith (+)
65 |   v ^/ s  = map (/ s) v
66 |   s *^ v  = map (* s) v
67 |   dot a b = sum $ zipWith (*) a b
68 |