diff options
author | Dominic Steinitz <dominic@steinitz.org> | 2018-04-05 18:28:56 +0100 |
---|---|---|
committer | Dominic Steinitz <dominic@steinitz.org> | 2018-04-05 18:28:56 +0100 |
commit | 59a0413a83a9bcee93e3f0761cae6fdda2a98933 (patch) | |
tree | d706524e98e62bae13283af05385d126bfb6890c /packages/sundials/src | |
parent | 6fcc1b01cecc88f1a8eb1608667368c7e72048aa (diff) |
Get closer to the hmatrix-gsl interface
Diffstat (limited to 'packages/sundials/src')
-rw-r--r-- | packages/sundials/src/Main.hs | 41 | ||||
-rw-r--r-- | packages/sundials/src/Numeric/Sundials/ARKode/ODE.hs | 42 |
2 files changed, 51 insertions, 32 deletions
diff --git a/packages/sundials/src/Main.hs b/packages/sundials/src/Main.hs index eef8148..b950036 100644 --- a/packages/sundials/src/Main.hs +++ b/packages/sundials/src/Main.hs | |||
@@ -115,36 +115,49 @@ main = do | |||
115 | -- \end{array} | 115 | -- \end{array} |
116 | -- $$ | 116 | -- $$ |
117 | 117 | ||
118 | let res = btGet (SDIRK_2_1_2 undefined) | 118 | -- let res = btGet (SDIRK_2_1_2 undefined) |
119 | putStrLn $ show res | 119 | -- putStrLn $ show res |
120 | putStrLn $ butcherTableauTex res | 120 | -- putStrLn $ butcherTableauTex res |
121 | 121 | ||
122 | let res = btGet (KVAERNO_4_2_3 undefined) | 122 | -- let res = btGet (KVAERNO_4_2_3 undefined) |
123 | putStrLn $ show res | 123 | -- putStrLn $ show res |
124 | putStrLn $ butcherTableauTex res | 124 | -- putStrLn $ butcherTableauTex res |
125 | 125 | ||
126 | let res = btGet (SDIRK_5_3_4 undefined) | 126 | -- let res = btGet (SDIRK_5_3_4 undefined) |
127 | putStrLn $ show res | 127 | -- putStrLn $ show res |
128 | putStrLn $ butcherTableauTex res | 128 | -- putStrLn $ butcherTableauTex res |
129 | 129 | ||
130 | let res1 = odeSolve' (KVAERNO_4_2_3 undefined) brussJac brusselator [1.2, 3.1, 3.0] (fromList [0.0, 0.1 .. 10.0]) | 130 | let res1 = odeSolve' (SDIRK_5_3_4 brussJac) brusselator [1.2, 3.1, 3.0] (fromList [0.0, 0.1 .. 100.0]) |
131 | putStrLn $ show res1 | ||
132 | renderRasterific "diagrams/brusselator.png" | 131 | renderRasterific "diagrams/brusselator.png" |
133 | (D.dims2D 500.0 500.0) | 132 | (D.dims2D 500.0 500.0) |
134 | (renderAxis $ lSaxis $ [0.0, 0.1 .. 10.0]:(toLists $ tr res1)) | 133 | (renderAxis $ lSaxis $ [0.0, 0.1 .. 100.0]:(toLists $ tr res1)) |
135 | 134 | ||
135 | let res1a = odeSolve' (SDIRK_5_3_4') brusselator [1.2, 3.1, 3.0] (fromList [0.0, 0.1 .. 100.0]) | ||
136 | renderRasterific "diagrams/brusselatorA.png" | ||
137 | (D.dims2D 500.0 500.0) | ||
138 | (renderAxis $ lSaxis $ [0.0, 0.1 .. 100.0]:(toLists $ tr res1a)) | ||
136 | 139 | ||
137 | let res2 = odeSolve' (KVAERNO_4_2_3 undefined) stiffJac stiffish [0.0] (fromList [0.0, 0.1 .. 10.0]) | 140 | let res2 = odeSolve' (SDIRK_5_3_4 stiffJac) stiffish [0.0] (fromList [0.0, 0.1 .. 10.0]) |
138 | putStrLn $ show res2 | 141 | putStrLn $ show res2 |
139 | renderRasterific "diagrams/stiffish.png" | 142 | renderRasterific "diagrams/stiffish.png" |
140 | (D.dims2D 500.0 500.0) | 143 | (D.dims2D 500.0 500.0) |
141 | (renderAxis $ kSaxis $ zip [0.0, 0.1 .. 10.0] (concat $ toLists res2)) | 144 | (renderAxis $ kSaxis $ zip [0.0, 0.1 .. 10.0] (concat $ toLists res2)) |
142 | 145 | ||
143 | let res3 = odeSolve' (KVAERNO_4_2_3 undefined) lorenzJac lorenz [-5.0, -5.0, 1.0] (fromList [0.0, 0.01 .. 30.0]) | 146 | let res3 = odeSolve' (SDIRK_5_3_4 lorenzJac) lorenz [-5.0, -5.0, 1.0] (fromList [0.0, 0.01 .. 1000.0]) |
147 | putStrLn $ show $ last ((toLists $ tr res3)!!0) | ||
148 | |||
149 | let res3 = odeSolve' (SDIRK_5_3_4') lorenz [-5.0, -5.0, 1.0] (fromList [0.0, 0.01 .. 1000.0]) | ||
150 | putStrLn $ show $ last ((toLists $ tr res3)!!0) | ||
151 | |||
144 | renderRasterific "diagrams/lorenz.png" | 152 | renderRasterific "diagrams/lorenz.png" |
145 | (D.dims2D 500.0 500.0) | 153 | (D.dims2D 500.0 500.0) |
146 | (renderAxis $ kSaxis $ zip ((toLists $ tr res3)!!0) ((toLists $ tr res3)!!1)) | 154 | (renderAxis $ kSaxis $ zip ((toLists $ tr res3)!!0) ((toLists $ tr res3)!!1)) |
147 | 155 | ||
156 | let res3a = odeSolve' (SDIRK_5_3_4') lorenz [-5.0, -5.0, 1.0] (fromList [0.0, 0.01 .. 30.0]) | ||
157 | renderRasterific "diagrams/lorenzA.png" | ||
158 | (D.dims2D 500.0 500.0) | ||
159 | (renderAxis $ kSaxis $ zip ((toLists $ tr res3)!!0) ((toLists $ tr res3a)!!1)) | ||
160 | |||
148 | renderRasterific "diagrams/lorenz1.png" | 161 | renderRasterific "diagrams/lorenz1.png" |
149 | (D.dims2D 500.0 500.0) | 162 | (D.dims2D 500.0 500.0) |
150 | (renderAxis $ kSaxis $ zip ((toLists $ tr res3)!!0) ((toLists $ tr res3)!!2)) | 163 | (renderAxis $ kSaxis $ zip ((toLists $ tr res3)!!0) ((toLists $ tr res3)!!2)) |
diff --git a/packages/sundials/src/Numeric/Sundials/ARKode/ODE.hs b/packages/sundials/src/Numeric/Sundials/ARKode/ODE.hs index 0973c82..4270a13 100644 --- a/packages/sundials/src/Numeric/Sundials/ARKode/ODE.hs +++ b/packages/sundials/src/Numeric/Sundials/ARKode/ODE.hs | |||
@@ -185,14 +185,22 @@ data SundialsDiagnostics = SundialsDiagnostics { | |||
185 | type Jacobian = Double -> Vector Double -> Matrix Double | 185 | type Jacobian = Double -> Vector Double -> Matrix Double |
186 | 186 | ||
187 | -- | Stepping functions | 187 | -- | Stepping functions |
188 | data ODEMethod = SDIRK_2_1_2 Jacobian | 188 | data ODEMethod = SDIRK_2_1_2 Jacobian |
189 | | KVAERNO_4_2_3 Jacobian | 189 | | KVAERNO_4_2_3 Jacobian |
190 | | SDIRK_5_3_4 Jacobian | 190 | | SDIRK_5_3_4 Jacobian |
191 | | SDIRK_5_3_4' | ||
191 | 192 | ||
192 | getMethod :: ODEMethod -> Int | 193 | getMethod :: ODEMethod -> Int |
193 | getMethod (SDIRK_2_1_2 _) = sDIRK_2_1_2 | 194 | getMethod (SDIRK_2_1_2 _) = sDIRK_2_1_2 |
194 | getMethod (KVAERNO_4_2_3 _) = kVAERNO_4_2_3 | 195 | getMethod (KVAERNO_4_2_3 _) = kVAERNO_4_2_3 |
195 | getMethod (SDIRK_5_3_4 _) = sDIRK_5_3_4 | 196 | getMethod (SDIRK_5_3_4 _) = sDIRK_5_3_4 |
197 | getMethod (SDIRK_5_3_4' ) = sDIRK_5_3_4 | ||
198 | |||
199 | getJacobian :: ODEMethod -> Maybe Jacobian | ||
200 | getJacobian (SDIRK_2_1_2 j) = Just j | ||
201 | getJacobian (KVAERNO_4_2_3 j) = Just j | ||
202 | getJacobian (SDIRK_5_3_4 j) = Just j | ||
203 | getJacobian (SDIRK_5_3_4' ) = Nothing | ||
196 | 204 | ||
197 | -- | A version of 'odeSolveVWith' with reasonable default step control. | 205 | -- | A version of 'odeSolveVWith' with reasonable default step control. |
198 | odeSolveV | 206 | odeSolveV |
@@ -215,7 +223,7 @@ odeSolve :: (Double -> [Double] -> [Double]) -- ^ The RHS of the system \(\dot{y | |||
215 | -> Vector Double -- ^ desired solution times | 223 | -> Vector Double -- ^ desired solution times |
216 | -> Matrix Double -- ^ solution | 224 | -> Matrix Double -- ^ solution |
217 | odeSolve f y0 ts = | 225 | odeSolve f y0 ts = |
218 | case odeSolveVWith (SDIRK_5_3_4 undefined) Nothing 1.0e-6 1.0e-10 g (V.fromList y0) (V.fromList $ toList ts) of | 226 | case odeSolveVWith SDIRK_5_3_4' 1.0e-6 1.0e-10 g (V.fromList y0) (V.fromList $ toList ts) of |
219 | Left c -> error $ show c -- FIXME | 227 | Left c -> error $ show c -- FIXME |
220 | Right (v, d) -> trace (show d) $ (nR >< nC) (V.toList v) | 228 | Right (v, d) -> trace (show d) $ (nR >< nC) (V.toList v) |
221 | where | 229 | where |
@@ -225,13 +233,12 @@ odeSolve f y0 ts = | |||
225 | g t x0 = V.fromList $ f t (V.toList x0) | 233 | g t x0 = V.fromList $ f t (V.toList x0) |
226 | 234 | ||
227 | odeSolve' :: ODEMethod | 235 | odeSolve' :: ODEMethod |
228 | -> (Double -> Vector Double -> Matrix Double) | ||
229 | -> (Double -> [Double] -> [Double]) -- ^ The RHS of the system \(\dot{y} = f(t,y)\) | 236 | -> (Double -> [Double] -> [Double]) -- ^ The RHS of the system \(\dot{y} = f(t,y)\) |
230 | -> [Double] -- ^ initial conditions | 237 | -> [Double] -- ^ initial conditions |
231 | -> Vector Double -- ^ desired solution times | 238 | -> Vector Double -- ^ desired solution times |
232 | -> Matrix Double -- ^ solution | 239 | -> Matrix Double -- ^ solution |
233 | odeSolve' method jac f y0 ts = | 240 | odeSolve' method f y0 ts = |
234 | case odeSolveVWith method (pure jac') 1.0e-6 1.0e-10 g (V.fromList y0) (V.fromList $ toList ts) of | 241 | case odeSolveVWith method 1.0e-6 1.0e-10 g (V.fromList y0) (V.fromList $ toList ts) of |
235 | Left c -> error $ show c -- FIXME | 242 | Left c -> error $ show c -- FIXME |
236 | Right (v, d) -> trace (show d) $ (nR >< nC) (V.toList v) | 243 | Right (v, d) -> trace (show d) $ (nR >< nC) (V.toList v) |
237 | where | 244 | where |
@@ -239,30 +246,29 @@ odeSolve' method jac f y0 ts = | |||
239 | nR = length us | 246 | nR = length us |
240 | nC = length y0 | 247 | nC = length y0 |
241 | g t x0 = V.fromList $ f t (V.toList x0) | 248 | g t x0 = V.fromList $ f t (V.toList x0) |
242 | jac' t v = foo $ jac t (V.fromList $ toList v) | ||
243 | foo m = T.SunMatrix { T.rows = nr, T.cols = nc, T.vals = vs } | ||
244 | where | ||
245 | nr = fromIntegral $ rows m | ||
246 | nc = fromIntegral $ cols m | ||
247 | vs = V.fromList $ map coerce $ concat $ toLists m | ||
248 | 249 | ||
249 | odeSolveVWith :: | 250 | odeSolveVWith :: |
250 | ODEMethod | 251 | ODEMethod |
251 | -> (Maybe (Double -> V.Vector Double -> T.SunMatrix)) | ||
252 | -> Double | 252 | -> Double |
253 | -> Double | 253 | -> Double |
254 | -> (Double -> V.Vector Double -> V.Vector Double) -- ^ The RHS of the system \(\dot{y} = f(t,y)\) | 254 | -> (Double -> V.Vector Double -> V.Vector Double) -- ^ The RHS of the system \(\dot{y} = f(t,y)\) |
255 | -> V.Vector Double -- ^ Initial conditions | 255 | -> V.Vector Double -- ^ Initial conditions |
256 | -> V.Vector Double -- ^ Desired solution times | 256 | -> V.Vector Double -- ^ Desired solution times |
257 | -> Either Int ((V.Vector Double), SundialsDiagnostics) -- ^ Error code or solution | 257 | -> Either Int ((V.Vector Double), SundialsDiagnostics) -- ^ Error code or solution |
258 | odeSolveVWith method jac relTol absTol f y0 tt = | 258 | odeSolveVWith method relTol absTol f y0 tt = |
259 | case solveOdeC (fromIntegral $ getMethod method) jacH (CDouble relTol) (CDouble absTol) | 259 | case solveOdeC (fromIntegral $ getMethod method) jacH (CDouble relTol) (CDouble absTol) |
260 | (coerce f) (coerce y0) (coerce tt) of | 260 | (coerce f) (coerce y0) (coerce tt) of |
261 | Left c -> Left $ fromIntegral c | 261 | Left c -> Left $ fromIntegral c |
262 | Right (v, d) -> Right (coerce v, d) | 262 | Right (v, d) -> Right (coerce v, d) |
263 | where | 263 | where |
264 | jacH :: Maybe (CDouble -> V.Vector CDouble -> T.SunMatrix) | 264 | -- FIXME: Can we do better than going via a list? |
265 | jacH = fmap (\g -> (\t v -> g (coerce t) (coerce v))) jac | 265 | jacH = fmap (\g t v -> matrixToSunMatrix $ g (coerce t) (coerce $ V.fromList $ toList v)) $ |
266 | getJacobian method | ||
267 | matrixToSunMatrix m = T.SunMatrix { T.rows = nr, T.cols = nc, T.vals = vs } | ||
268 | where | ||
269 | nr = fromIntegral $ rows m | ||
270 | nc = fromIntegral $ cols m | ||
271 | vs = V.fromList $ map coerce $ concat $ toLists m | ||
266 | 272 | ||
267 | solveOdeC :: | 273 | solveOdeC :: |
268 | CInt -> | 274 | CInt -> |