clifford-0.1.0.14: src/Numeric/Clifford/ClassicalMechanics.lhs
\documentclass{article}
%include polycode.fmt
\usepackage{fontspec}
\usepackage{amsmath}
\usepackage{unicode-math}
\usepackage{lualatex-math}
\setmainfont{latinmodern-math.otf}
\setmathfont{latinmodern-math.otf}
\usepackage{verbatim}
\author{Sophie Taylor}
\title{haskell-clifford: A Haskell Clifford algebra dynamics library}
\begin{document}
This is the classical mechanics portion of the library.
\begin{code}
{-# LANGUAGE NoImplicitPrelude, FlexibleContexts, RankNTypes, ScopedTypeVariables, DeriveDataTypeable #-}
{-# LANGUAGE NoMonomorphismRestriction, UnicodeSyntax, GADTs, KindSignatures, DataKinds #-}
{-# LANGUAGE FlexibleInstances, TypeOperators #-}
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# OPTIONS_HADDOCK show-extensions #-}
\end{code}
%if False
\begin{code}
\end{code}
%endif
\begin{code}
module Numeric.Clifford.ClassicalMechanics where
import Numeric.Clifford.Multivector as MV
import Numeric.Clifford.Blade
import GHC.TypeLits
import Data.Proxy
import NumericPrelude hiding (iterate, head, map, tail, reverse, scanl, zipWith, drop, (++), filter, null, length, foldr, foldl1, zip, foldl, concat, (!!), concatMap,any, repeat, replicate, elem, replicate, all, (.) )
import Algebra.Absolute
import Algebra.Algebraic
import Algebra.Additive
import Algebra.Ring
import Algebra.ToInteger
import Algebra.Module
import Algebra.Field
import Data.List.Stream
import Numeric.Natural
import qualified Data.Vector as V
import NumericPrelude.Numeric (sum)
import qualified NumericPrelude.Numeric as NPN
import Test.QuickCheck
import Math.Sequence.Converge (convergeBy)
import Number.Ratio hiding (scale)
import Algebra.ToRational
import Control.Lens hiding (indices)
import Control.Exception (assert)
import Data.Maybe
import Data.DeriveTH
import Data.Word
import Numeric.Clifford.Internal
import Numeric.Clifford.LinearOperators
import Control.Applicative
import Data.Monoid
import Control.Category
nonEqualFrames = "Non-equal reference frames! Insert code here to translate between them! :) Should really make reference frames as types and then have type families to convert between them :v :v :v"
data EnergyMethod (p::Nat) (q::Nat) f = Hamiltonian{ _dqs :: [DynamicSystem p q f -> Multivector p q f], _dps :: [DynamicSystem p q f -> Multivector p q f]}
data DynamicSystem (p::Nat) (q::Nat) f = DynamicSystem {_time :: f, coordinates :: [Multivector p q f], _momenta :: [Multivector p q f], _energyFunction :: EnergyMethod p q f, _projector :: DynamicSystem p q f -> DynamicSystem p q f}
makeLenses ''EnergyMethod
makeLenses ''DynamicSystem
--evaluateDerivative s = dq++ dp where
-- dq = (s&energyFunction.dqs) -- s
-- dp = (s&energyFunction.dps) -- s
-- dq = map ($ s) ((dqs $ energyFunction) s) --s&energyFunction.dqs.traverse--map ($ s) ((dqs . energyFunction) s)
-- dp = map ($ s) ((dps $ energyFunction) s)
\end{code}
Now to make a physical object.
\begin{code}
data ReferenceFrame (p::Nat) (q::Nat) t = RelativeFrame {frameName :: String, euclideanMove :: EuclideanMove p q t, velocityRelToParentFrame :: Multivector p q t, angularVelocityRelToParentFrame :: Multivector p q t, parent :: ReferenceFrame p q t}
|GlobalAbsoluteFrame deriving (Eq, Show)
getRigidDisplacementRelToInertial :: (Algebra.Field.C t, Ord t, SingI p, SingI q) => ReferenceFrame p q t -> EuclideanMove p q t
getRigidDisplacementRelToInertial GlobalAbsoluteFrame = mempty
--getRigidDisplacementRelToInertial (RelativeFrame _ displacement mother) = displacement <> (getRigidDisplacementRelToInertial mother)
getFrameTransformation :: forall (p::Nat) (q::Nat) t . (Algebra.Field.C t, Ord t, SingI p, SingI q) => ReferenceFrame p q t -> ReferenceFrame p q t -> EuclideanMove p q t
getFrameTransformation r' r = undefined
{-data InertialFrame (p::Nat) (q::Nat) f t = InertialFrame {objects :: t, changeFrame :: t -> EuclideanMove p q f -> t, frame :: ReferenceFrame p q f}
instance Functor (InertialFrame p q f) where
fmap func (InertialFrame objs changeFrame frame) = InertialFrame (func objs) (changeFrame . func) frame
instance (SingI p, SingI q) => Applicative (InertialFrame p q f) where
pure a = InertialFrame a GlobalAbsoluteFrame where
(<*>) (InertialFrame func trans1 frame1) (InertialFrame objs trans2 frame2) = if (name frame1)==(name frame2)
then InertialFrame (func objs) frame1
else InertialFrame (trans2 (func objs) (getFrameTransformation frame2 frame1)) trans2 frame1
instance (SingI p, SingI q, Algebra.Field.C f, Ord f) => Monad (InertialFrame p q f) where
return = pure
(>>=) (InertialFrame objA changeFrameA frameA) func = undefined where
(InertialFrame objB changeFrameB frameB) = func objA
-}
a `cross` b = (negate psuedoScalar) * (a ∧ b)
data PhysicalVector (p::Nat) (q::Nat) t = PhysicalVector {r :: Multivector p q t, referenceFrame :: ReferenceFrame p q t}
data RigidBody (p::Nat) (q::Nat) f where
RigidBody:: (Algebra.Field.C f, Algebra.Module.C f (Multivector p q f)) => {bodyName::String, frame::ReferenceFrame p q f, mass :: f, inertia :: Multivector p q f, position :: Multivector p q f, attitude :: Multivector p q f, velocity :: Multivector p q f, angularVelocity :: Multivector p q f
} -> RigidBody p q f
--makeLenses ''RigidBody doesn't actually work
{- Things to do:
4. create a 1-form type
5. figure a way to take exterior product of 1 forms at a type level so i can just go like: omega = df1 ^ df2 ^ df ; omega a b c
-}
\end{code}
\bibliographystyle{IEEEtran}
\bibliography{biblio.bib}
\end{document}