-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathForTrevor.hs
145 lines (125 loc) · 4.37 KB
/
ForTrevor.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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
{-# OPTIONS_GHC -Wall #-}
{-# OPTIONS_GHC -fno-warn-type-defaults #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE TypeOperators #-}
{-# LANGUAGE TypeFamilies #-}
import Prelude as P
import Data.Array.Accelerate as A hiding ((^))
import Data.Array.Accelerate.LLVM.Native as CPU
import Data.Array.Accelerate.LLVM.PTX as GPU
import Data.Array.Accelerate.Linear hiding (trace)
import Data.Array.Accelerate.Control.Lens
import qualified Linear as L
e, q10, q20, p10, p20 :: Double
e = 0.6
q10 = 1 - e
q20 = 0.0
p10 = 0.0
p20 = sqrt ((1 + e) / (1 - e))
h :: Double
h = 0.01
oneStep2 :: Double -> Exp (V2 Double, V2 Double) -> Exp (V2 Double, V2 Double)
oneStep2 hh prev = lift (qNew, pNew)
where
h2 = hh / 2
hhs = lift ((pure hh) :: V2 Double)
hh2s = (lift ((pure h2) :: V2 Double))
pp2 = psPrev - hh2s * nablaQ' qsPrev
qNew = qsPrev + hhs * nablaP' pp2
pNew = pp2 - hh2s * nablaQ' qNew
qsPrev = A.fst prev
psPrev = A.snd prev
nablaQ' :: Exp (V2 Double) -> Exp (V2 Double)
nablaQ' qs = lift (V2 (qq1 / r) (qq2 / r))
where
qq1 = qs ^. _x
qq2 = qs ^. _y
r = (qq1 ^ 2 + qq2 ^ 2) ** (3/2)
nablaP' :: Exp (V2 Double) -> Exp (V2 Double)
nablaP' ps = ps
oneStepH98 :: Double -> V2 (V2 Double) -> V2 (V2 Double)
oneStepH98 hh prev = V2 qNew pNew
where
h2 = hh / 2
hhs = V2 hh hh
hh2s = V2 h2 h2
pp2 = psPrev - hh2s * nablaQ' qsPrev
qNew = qsPrev + hhs * nablaP' pp2
pNew = pp2 - hh2s * nablaQ' qNew
qsPrev = prev ^. L._x
psPrev = prev ^. L._y
nablaQ' qs = V2 (qq1 / r) (qq2 / r)
where
qq1 = qs ^. L._x
qq2 = qs ^. L._y
r = (qq1 ^ 2 + qq2 ^ 2) ** (3/2)
nablaP' ps = ps
-- oneStep :: Double -> Exp (V2 (V2 Double)) -> Exp (V2 (V2 Double))
-- oneStep h prev = lift $ V2 qNew pNew
-- where
-- hs = lift (V2 h h)
-- h2s = lift (V2 h2 h2) where h2 = h / 2
-- qsPrev = prev ^. _x
-- psPrev = prev ^. _y
-- nablaQ qs = lift (V2 (qq1 / r) (qq2 / r))
-- where
-- qq1 = qs ^. _x
-- qq2 = qs ^. _y
-- r = (qq1 ^ 2 + qq2 ^ 2) ** (3/2)
-- nablaP ps = ps
-- p2 = psPrev - h2s * nablaQ qsPrev
-- qNew = qsPrev + hs * nablaP p2
-- pNew = p2 - h2s * nablaQ qNew
-- nSteps :: Int
-- nSteps = 100
dummyStart :: Exp (V2 Double, V2 Double)
dummyStart = lift (V2 q10 q20, V2 p10 p20)
dummyStart98 :: V2 (V2 Double)
dummyStart98 = V2 (V2 q10 q20) (V2 p10 p20)
-- dummyInputs :: Acc (Array DIM1 (V2 Double, V2 Double))
-- dummyInputs = A.use $ A.fromList (Z :. nSteps) $
-- P.replicate nSteps (pure 0.0 :: V2 Double, pure 0.0 :: V2 Double)
-- runSteps :: Acc (Array DIM1 (V2 Double, V2 Double))
-- runSteps = A.scanl (\s _x -> (oneStep2 h s)) dummyStart dummyInputs
nSteps :: Int
nSteps = 80000000 -- 100000000
runSteps' :: Exp (V2 Double, V2 Double) -> Exp (V2 Double, V2 Double)
runSteps' = A.iterate (lift nSteps) (oneStep2 h)
myIterate :: Int -> (a -> a) -> a -> a
myIterate n f x | n P.<= 0 = x
| otherwise = myIterate (n-1) f $! f x
-- myIterate 0 _ a = a
-- myIterate n f a = myIterate (n-1) f (f a)
-- myIterate n f a = P.last $ P.take n $ P.iterate f a
runSteps98' :: V2 (V2 Double) -> V2 (V2 Double)
runSteps98' = myIterate nSteps (oneStepH98 h)
reallyRunSteps' :: (Array DIM1 (V2 Double, V2 Double))
reallyRunSteps' = CPU.run $
A.scanl (\s _x -> runSteps' s) dummyStart
(A.use $ A.fromList (Z :. 1) [(V2 0.0 0.0, V2 0.0 0.0)])
main :: IO ()
main = do
putStrLn $ show $ reallyRunSteps'
-- putStrLn $ show $ runSteps98' dummyStart98
-- Onesteph98 :: Double -> (V2 Double, V2 Double) -> (V2 Double, V2 Double)
-- oneStepH98 h prev = (qNew, pNew)
-- where
-- h2 = h / 2
-- hhs = pure h
-- hs = pure h2
-- p2 = psPrev - hs * nablaQ qsPrev
-- qNew = qsPrev + hhs * nablaP p2
-- pNew = p2 - hs * nablaQ qNew
-- qsPrev = P.fst prev
-- psPrev = P.snd prev
-- nablaQ qs = V2 (q1 / r) (q2 / r)
-- where
-- q1 = qs ^. L._x
-- q2 = qs ^. L._y
-- r = (q1 ^ 2 + q2 ^ 2) ** (3/2)
-- nablaP ps = ps
-- bigH2BodyH98 :: (V2 Double, V2 Double) -> Double
-- bigH2BodyH98 x = ke + pe
-- where
-- pe = let V2 q1 q2 = P.fst x in negate $ recip (sqrt (q1^2 + q2^2))
-- ke = let V2 p1 p2 = P.snd x in 0.5 * (p1^2 + p2^2)