forked from chris-taylor/Classical-Mechanics
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathBasis.hs
81 lines (59 loc) · 2.12 KB
/
Basis.hs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
{-# LANGUAGE TypeFamilies, FlexibleContexts #-}
module Basis
( decompose'
, recompose'
, recompose
, toCoords
, fromCoords
, dim
, HasBasis(..)
, Enumerable(..)
) where
import Trio
import Enumerable
import VectorSpace
class (VectorSpace v, Enumerable (Basis v)) => HasBasis v where
type Basis v
basisValue :: Basis v -> v
decompose :: v -> Basis v -> Scalar v
decompose' :: (HasBasis v) => v -> [(Basis v, Scalar v)]
decompose' v = [ (e, decompose v e) | e <- enumerate ]
recompose :: (HasBasis v) => (Basis v -> Scalar v) -> v
recompose f = recompose' [ (e, f e) | e <- enumerate ]
recompose' :: (HasBasis v) => [(Basis v,Scalar v)] -> v
recompose' ps = sumV [ s *> basisValue e | (e, s) <- ps ]
toCoords :: (HasBasis v) => v -> [Scalar v]
toCoords v = map snd (decompose' v)
fromCoords :: (HasBasis v) => [Scalar v] -> v
fromCoords vs = recompose' (zip enumerate vs)
dim :: (HasBasis v) => v -> Int
dim v = length (toCoords v)
-- Numeric instances
instance HasBasis Int where
type Basis Int = ()
basisValue () = 1
decompose s () = s
instance HasBasis Integer where
type Basis Integer = ()
basisValue () = 1
decompose s () = s
instance HasBasis Float where
type Basis Float = ()
basisValue () = 1
decompose s () = s
instance HasBasis Double where
type Basis Double = ()
basisValue () = 1
decompose s () = s
-- Tuple instances
instance (HasBasis u, HasBasis v, Scalar u ~ Scalar v) => HasBasis (u,v) where
type Basis (u,v) = Either (Basis u) (Basis v)
basisValue (Left a) = (basisValue a, zeroV)
basisValue (Right b) = (zeroV, basisValue b)
decompose (u,v) = either (decompose u) (decompose v)
instance (HasBasis u, HasBasis v, HasBasis w, Scalar u ~ Scalar v, Scalar v ~ Scalar w) => HasBasis (u,v,w) where
type Basis (u,v,w) = Trio (Basis u) (Basis v) (Basis w)
basisValue (First a) = (basisValue a, zeroV, zeroV)
basisValue (Second b) = (zeroV, basisValue b, zeroV)
basisValue (Third c) = (zeroV, zeroV, basisValue c)
decompose (u,v,w) = trio (decompose u) (decompose v) (decompose w)