-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Ode solvers -- -- Some ode solvers, e.g., Störmer-Verlet @package numeric-ode @version 0.0.0.0 module Math.Integrators.StormerVerletAlt oneStepH98 :: (Applicative f, Num (f a), Fractional a) => a -> (f a -> f a) -> (f a -> f a) -> V2 (f a) -> V2 (f a) nablaQ' :: V2 Double -> V2 Double nablaP' :: V2 Double -> V2 Double e :: Double q10 :: Double q20 :: Double p10 :: Double p20 :: Double inits :: V2 (V2 Double) -- | Störmer-Verlet is an order 2 symplectic method. This means it will -- preserve the Hamiltonian for the system the differential equations -- describe, for example, important for modelling planetary motion; the -- application of something like the much-loved Runge-Kutta 4th order -- method would either model the planet spiralling toward or away from -- the Sun! -- -- Here's a diagram showing the orbit of Jupiter around the Sun. -- -- -- To create this, consider the <math>-body problem. The -- Hamiltonian is -- -- <math> -- -- Apply Hamilton's equations will gives <math> first order -- equations. To use stormerVerlet2 this needs to be <math> -- second order equations. In this case, the Lagrangian is easy -- -- <math> -- -- Applying Lagrange's equation -- -- <math> -- -- gives -- -- <math> -- -- For <math> this gives -- -- <math> -- --
--   {-# LANGUAGE NegativeLiterals      #-}
--   {-# LANGUAGE TypeFamilies          #-}
--   {-# LANGUAGE FlexibleContexts      #-}
--   {-# LANGUAGE MultiParamTypeClasses #-}
--   
--   import qualified Data.Vector as V
--   import Control.Monad.ST
--   
--   import Math.Integrators.StormerVerlet
--   import Math.Integrators
--   
--   import qualified Linear as L
--   import Linear.V
--   import Data.Maybe ( fromJust )
--   
--   import Diagrams.Prelude
--   
--   import Control.Monad
--   import Control.Monad.State.Class
--   
--   import Plots
--   
--   -- First some constants describing the system
--   
--   gConst :: Double
--   gConst = 6.67384e-11
--   
--   nStepsTwoPlanets :: Int
--   nStepsTwoPlanets = 44
--   
--   -- A step size of 100 days!
--   
--   stepTwoPlanets :: Double
--   stepTwoPlanets = 24 * 60 * 60 * 100
--   
--   sunMass, jupiterMass :: Double
--   sunMass     = 1.9889e30
--   jupiterMass = 1.8986e27
--   
--   jupiterPerihelion :: Double
--   jupiterPerihelion = 7.405736e11
--   
--   jupiterV :: L.V3 Double
--   jupiterV = L.V3 (-1.0965244901087316e02) (-1.3710001990210707e04) 0.0
--   
--   jupiterQ :: L.V3 Double
--   jupiterQ = L.V3 (-jupiterPerihelion) 0.0 0.0
--   
--   sunV :: L.V3 Double
--   sunV = L.V3 0.0 0.0 0.0
--   
--   sunQ :: L.V3 Double
--   sunQ =  L.V3 0.0 0.0 0.0
--   
--   -- The right hand side of the second order differential equation system.
--   
--   kepler :: L.V2 (L.V3 Double) -> L.V2 (L.V3 Double)
--   kepler (L.V2 q1 q2) =
--       let r  = q2 L.^-^ q1
--           ri = r `L.dot` r
--           rr = ri * (sqrt ri)
--           q1' = pure gConst * r / pure rr
--           q2' = negate q1'
--           q1'' = q1' * pure sunMass
--           q2'' = q2' * pure jupiterMass
--       in L.V2 q1'' q2''
--   
--   -- Initial values
--   
--   initPQs :: L.V2 (L.V2 (L.V3 Double))
--   initPQs = L.V2 (L.V2 jupiterV sunV) (L.V2 jupiterQ sunQ)
--   
--   -- Steps at which to evolve the system
--   
--   tm :: V.Vector Double
--   tm = V.enumFromStepN 0 stepTwoPlanets nStepsTwoPlanets
--   
--   -- The results
--   
--   result1 :: V.Vector (L.V2 (L.V2 (L.V3 Double)))
--   result1 = runST $ integrateV (\h -> stormerVerlet2 kepler (pure h)) initPQs tm
--   
--   preMorePts :: [(Double, Double)]
--   preMorePts = map (\(L.V2 _ (L.V2 (L.V3 x y _z) _)) -> (x,y))  (V.toList result1)
--   
--   morePts :: [P2 Double]
--   morePts = map p2 $ preMorePts
--   
--   -- Finally plot the results
--   
--   addPoint :: (Plotable (Diagram B) b, MonadState (Axis b V2 Double) m) =>
--               Double -> (Double, Double) -> m ()
--   addPoint o (x, y) = addPlotable'
--                       ((circle 1e11 :: Diagram B) #
--                        fc brown #
--                        opacity o #
--                        translate (r2 (x, y)))
--   
--   jSaxis :: Axis B V2 Double
--   jSaxis = r2Axis &~ do
--     addPlotable' ((circle 1e11 :: Diagram B) # fc yellow)
--     let l = length preMorePts
--     let os = [0.05,0.1..]
--     let ps = take (l `div` 4) [0,4..]
--     zipWithM_ addPoint os (map (preMorePts!!) ps)
--     linePlot' $ map unp2 $ take 200 morePts
--   
--   jupiterOrbit = renderAxis jSaxis # bg ivory
--   
module Math.Integrators.StormerVerlet -- | Störmer-Verlet integration scheme for systems of the form <math> stormerVerlet2H :: (Applicative f, Num (f a), Fractional a) => a -> (f a -> f a) -> (f a -> f a) -> V2 (f a) -> V2 (f a) -- | Störmer-Verlet integration scheme for system: <math> stormerVerlet2 :: (Applicative f, Num (f a), Fractional a) => (f a -> f a) -> a -> V2 (f a) -> V2 (f a) module Math.Integrators.RK.Types -- | type implicit solver data ImplicitRkType a FixedPoint :: (Int -> a -> a -> Bool) -> ImplicitRkType a NewtonIteration :: ImplicitRkType a module Math.Integrators.RK.Internal -- | Internal type that users by data MExp Delimeter :: MExp Row :: (Maybe Double, [Double]) -> MExp isExplicit :: [MExp] -> Bool instance GHC.Classes.Eq Math.Integrators.RK.Internal.MExp instance GHC.Show.Show Math.Integrators.RK.Internal.MExp module Math.Integrators.RK.Parser readMatrixTable :: String -> [MExp] module Math.Integrators.RK.Template qrk :: QuasiQuoter jv :: Name -> Maybe Exp jv' :: Name -> Maybe ExpQ jld :: Integer -> Maybe Exp ld :: Integer -> Exp plus :: Exp vplus :: Exp vmult :: Exp mult :: Exp ld' :: Double -> ExpQ plus' :: ExpQ vplus' :: ExpQ vmult' :: ExpQ mult' :: ExpQ vN :: String -> ExpQ foldOp :: Foldable t => ExpQ -> t ExpQ -> ExpQ realToFracN :: ExpQ zeroVN :: ExpQ f :: Name t :: Name h :: Name y :: Name tpy :: Name rk :: [MExp] -> Q Exp test :: [MExp] irk :: [MExp] -> Q Exp fpointRun :: [MExp] -> Q Exp fpoint :: [MExp] -> Q [DecQ] -- | Runge-Kutta module TODO: add description and history notes add -- informations about methods properties module Math.Integrators.RK module Math.Integrators.Internal -- | Integrator function - Phi [h] |-> y_0 -> y_1 type Integrator a = Double Step -> a Initial value -> a Next value -- | Helpers for implicit integration methods -- -- TODO: add possibility to make function to create initial value TODO: -- add possibility to break on step TODO: add possibility to add -- different initial value based on y0, f TODO: add seq-pseq to make this -- stuff strict TODO: add Newton iterations module Math.Integrators.Implicit -- | Implicit solver type type ImplicitSolver a = (a -> a) implicit method -> (Int -> a -> a -> Bool) breakRule -> a initial value -> a final value -- | Fixed point method it iterates function f until it will break "" will -- be reached then it returns one but last iteration fixedPointSolver :: ImplicitSolver a fixedPoint :: (a -> a) -> (a -> a -> Bool) -> a -> a -- | simple break rule that will break evaluatioin when value less then Eps breakNormR :: Double -> Double -> Bool -- | same as breakNormR but assume that inner type is an instance -- of InnerField, so it's possible to use innerproduct to find norm N.B -- function uses $||v||^2 < eps$, so epsilon should be pre evaluated breakNormIR :: (Metric f, Floating a, Ord a, Num (f a)) => f a -> a -> Bool module Math.Integrators.ImplicitEuler implicitEuler :: (Metric f, Ord a, Additive f, Num (f a), Floating a) => (f a -> f a) -> a -> f a -> f a module Math.Integrators.ImplicitMidpointRule imr :: (Metric f, Num (f a), Floating a, Ord a) => (f a -> f a) -> a -> f a -> f a module Math.Integrators.SympleticEuler eps :: Floating a => a sympleticEuler1 :: (Metric f, Num (f a), Floating a, Ord a) => (f a -> f a -> f a) -> (f a -> f a -> f a) -> a -> V2 (f a) -> V2 (f a) -- | Basic integrator using Euler method. It has following properies: * -- allows to solve systems of the first order * this method is not -- symplectic and tends to loose energy module Math.Integrators.ExplicitEuler -- | Integrator of form -- -- <math> explicitEuler :: (Num (f a), Floating a, Additive f) => (f a -> f a) -> a -> f a -> f a -- | Math integrators if a high level module for different ODE integrators -- This module provides high-level wrappers over different integration -- methods module Math.Integrators -- | Integrate ODE equation using fixed steps set by a vector, and returns -- a vector of solutions corrensdonded to times that was requested. It -- takes Vector of time points as a parameter and returns a vector of -- results integrateV :: PrimMonad m => Integrator a -> a -> Vector Double -> m (Vector a)