-- 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)