diff options
Diffstat (limited to 'lib/Numeric/GSL/ODE.hs')
-rw-r--r-- | lib/Numeric/GSL/ODE.hs | 47 |
1 files changed, 36 insertions, 11 deletions
diff --git a/lib/Numeric/GSL/ODE.hs b/lib/Numeric/GSL/ODE.hs index d4f83aa..c243f4b 100644 --- a/lib/Numeric/GSL/ODE.hs +++ b/lib/Numeric/GSL/ODE.hs | |||
@@ -29,7 +29,7 @@ main = mplot (ts : toColumns sol)@ | |||
29 | ----------------------------------------------------------------------------- | 29 | ----------------------------------------------------------------------------- |
30 | 30 | ||
31 | module Numeric.GSL.ODE ( | 31 | module Numeric.GSL.ODE ( |
32 | odeSolve, odeSolveV, ODEMethod(..) | 32 | odeSolve, odeSolveV, ODEMethod(..), Jacobian |
33 | ) where | 33 | ) where |
34 | 34 | ||
35 | import Data.Packed.Internal | 35 | import Data.Packed.Internal |
@@ -41,18 +41,21 @@ import System.IO.Unsafe(unsafePerformIO) | |||
41 | 41 | ||
42 | ------------------------------------------------------------------------- | 42 | ------------------------------------------------------------------------- |
43 | 43 | ||
44 | type Jacobian = Double -> Vector Double -> Matrix Double | ||
45 | |||
44 | -- | Stepping functions | 46 | -- | Stepping functions |
45 | data ODEMethod = RK2 -- ^ Embedded Runge-Kutta (2, 3) method. | 47 | data ODEMethod = RK2 -- ^ Embedded Runge-Kutta (2, 3) method. |
46 | | RK4 -- ^ 4th order (classical) Runge-Kutta. The error estimate is obtained by halving the step-size. For more efficient estimate of the error, use 'RKf45'. | 48 | | RK4 -- ^ 4th order (classical) Runge-Kutta. The error estimate is obtained by halving the step-size. For more efficient estimate of the error, use the embedded methods. |
47 | | RKf45 -- ^ Embedded Runge-Kutta-Fehlberg (4, 5) method. This method is a good general-purpose integrator. | 49 | | RKf45 -- ^ Embedded Runge-Kutta-Fehlberg (4, 5) method. This method is a good general-purpose integrator. |
48 | | RKck -- ^ Embedded Runge-Kutta Cash-Karp (4, 5) method. | 50 | | RKck -- ^ Embedded Runge-Kutta Cash-Karp (4, 5) method. |
49 | | RK8pd -- ^ Embedded Runge-Kutta Prince-Dormand (8,9) method. | 51 | | RK8pd -- ^ Embedded Runge-Kutta Prince-Dormand (8,9) method. |
50 | | RK2imp -- ^ Implicit 2nd order Runge-Kutta at Gaussian points. | 52 | | RK2imp Jacobian -- ^ Implicit 2nd order Runge-Kutta at Gaussian points. |
51 | | RK4imp -- ^ Implicit 4th order Runge-Kutta at Gaussian points. | 53 | | RK4imp Jacobian -- ^ Implicit 4th order Runge-Kutta at Gaussian points. |
52 | | BSimp -- ^ Implicit Bulirsch-Stoer method of Bader and Deuflhard. This algorithm requires the Jacobian. | 54 | | BSimp Jacobian -- ^ Implicit Bulirsch-Stoer method of Bader and Deuflhard. The method is generally suitable for stiff problems. |
53 | | MSAdams -- ^ A variable-coefficient linear multistep Adams method in Nordsieck form. | 55 | | RK1imp Jacobian -- ^ Implicit Gaussian first order Runge-Kutta. Also known as implicit Euler or backward Euler method. Error estimation is carried out by the step doubling method. |
54 | | MSBDF -- ^ A variable-coefficient linear multistep backward differentiation formula (BDF) method in Nordsieck form. | 56 | | MSAdams -- ^ A variable-coefficient linear multistep Adams method in Nordsieck form. This stepper uses explicit Adams-Bashforth (predictor) and implicit Adams-Moulton (corrector) methods in P(EC)^m functional iteration mode. Method order varies dynamically between 1 and 12. |
55 | deriving (Enum,Eq,Show,Bounded) | 57 | | MSBDF Jacobian -- ^ A variable-coefficient linear multistep backward differentiation formula (BDF) method in Nordsieck form. This stepper uses the explicit BDF formula as predictor and implicit BDF formula as corrector. A modified Newton iteration method is used to solve the system of non-linear equations. Method order varies dynamically between 1 and 5. The method is generally suitable for stiff problems. |
58 | |||
56 | 59 | ||
57 | -- | A version of 'odeSolveV' with reasonable default parameters and system of equations defined using lists. | 60 | -- | A version of 'odeSolveV' with reasonable default parameters and system of equations defined using lists. |
58 | odeSolve | 61 | odeSolve |
@@ -60,7 +63,7 @@ odeSolve | |||
60 | -> [Double] -- ^ initial conditions | 63 | -> [Double] -- ^ initial conditions |
61 | -> Vector Double -- ^ desired solution times | 64 | -> Vector Double -- ^ desired solution times |
62 | -> Matrix Double -- ^ solution | 65 | -> Matrix Double -- ^ solution |
63 | odeSolve xdot xi ts = odeSolveV RKf45 hi epsAbs epsRel (l2v xdot) Nothing (fromList xi) ts | 66 | odeSolve xdot xi ts = odeSolveV RKf45 hi epsAbs epsRel (l2v xdot) (fromList xi) ts |
64 | where hi = (ts@>1 - ts@>0)/100 | 67 | where hi = (ts@>1 - ts@>0)/100 |
65 | epsAbs = 1.49012e-08 | 68 | epsAbs = 1.49012e-08 |
66 | epsRel = 1.49012e-08 | 69 | epsRel = 1.49012e-08 |
@@ -73,11 +76,33 @@ odeSolveV | |||
73 | -> Double -- ^ absolute tolerance for the state vector | 76 | -> Double -- ^ absolute tolerance for the state vector |
74 | -> Double -- ^ relative tolerance for the state vector | 77 | -> Double -- ^ relative tolerance for the state vector |
75 | -> (Double -> Vector Double -> Vector Double) -- ^ xdot(t,x) | 78 | -> (Double -> Vector Double -> Vector Double) -- ^ xdot(t,x) |
79 | -> Vector Double -- ^ initial conditions | ||
80 | -> Vector Double -- ^ desired solution times | ||
81 | -> Matrix Double -- ^ solution | ||
82 | odeSolveV RK2 = odeSolveV' 0 Nothing | ||
83 | odeSolveV RK4 = odeSolveV' 1 Nothing | ||
84 | odeSolveV RKf45 = odeSolveV' 2 Nothing | ||
85 | odeSolveV RKck = odeSolveV' 3 Nothing | ||
86 | odeSolveV RK8pd = odeSolveV' 4 Nothing | ||
87 | odeSolveV (RK2imp jac) = odeSolveV' 5 (Just jac) | ||
88 | odeSolveV (RK4imp jac) = odeSolveV' 6 (Just jac) | ||
89 | odeSolveV (BSimp jac) = odeSolveV' 7 (Just jac) | ||
90 | odeSolveV (RK1imp jac) = odeSolveV' 8 (Just jac) | ||
91 | odeSolveV MSAdams = odeSolveV' 9 Nothing | ||
92 | odeSolveV (MSBDF jac) = odeSolveV' 10 (Just jac) | ||
93 | |||
94 | |||
95 | odeSolveV' | ||
96 | :: CInt | ||
76 | -> Maybe (Double -> Vector Double -> Matrix Double) -- ^ optional jacobian | 97 | -> Maybe (Double -> Vector Double -> Matrix Double) -- ^ optional jacobian |
98 | -> Double -- ^ initial step size | ||
99 | -> Double -- ^ absolute tolerance for the state vector | ||
100 | -> Double -- ^ relative tolerance for the state vector | ||
101 | -> (Double -> Vector Double -> Vector Double) -- ^ xdot(t,x) | ||
77 | -> Vector Double -- ^ initial conditions | 102 | -> Vector Double -- ^ initial conditions |
78 | -> Vector Double -- ^ desired solution times | 103 | -> Vector Double -- ^ desired solution times |
79 | -> Matrix Double -- ^ solution | 104 | -> Matrix Double -- ^ solution |
80 | odeSolveV method h epsAbs epsRel f mbjac xiv ts = unsafePerformIO $ do | 105 | odeSolveV' method mbjac h epsAbs epsRel f xiv ts = unsafePerformIO $ do |
81 | let n = dim xiv | 106 | let n = dim xiv |
82 | fp <- mkDoubleVecVecfun (\t -> aux_vTov (checkdim1 n . f t)) | 107 | fp <- mkDoubleVecVecfun (\t -> aux_vTov (checkdim1 n . f t)) |
83 | jp <- case mbjac of | 108 | jp <- case mbjac of |
@@ -86,7 +111,7 @@ odeSolveV method h epsAbs epsRel f mbjac xiv ts = unsafePerformIO $ do | |||
86 | sol <- vec xiv $ \xiv' -> | 111 | sol <- vec xiv $ \xiv' -> |
87 | vec (checkTimes ts) $ \ts' -> | 112 | vec (checkTimes ts) $ \ts' -> |
88 | createMIO (dim ts) n | 113 | createMIO (dim ts) n |
89 | (ode_c (fi (fromEnum method)) h epsAbs epsRel fp jp // xiv' // ts' ) | 114 | (ode_c (method) h epsAbs epsRel fp jp // xiv' // ts' ) |
90 | "ode" | 115 | "ode" |
91 | freeHaskellFunPtr fp | 116 | freeHaskellFunPtr fp |
92 | return sol | 117 | return sol |