{-# LANGUAGE TypeFamilies, FlexibleContexts #-}
{-# OPTIONS_GHC -Wall #-}
{-# LANGUAGE Safe #-}
module Physics.Learn.Curve
(
Curve(..)
, normalizeCurve
, concatCurves
, concatenateCurves
, reverseCurve
, evalCurve
, shiftCurve
, straightLine
, simpleLineIntegral
, dottedLineIntegral
, crossedLineIntegral
, compositeTrapezoidDottedLineIntegral
, compositeTrapezoidCrossedLineIntegral
, compositeSimpsonDottedLineIntegral
, compositeSimpsonCrossedLineIntegral
)
where
import Data.VectorSpace
( VectorSpace
, InnerSpace
, Scalar
)
import Physics.Learn.CarrotVec
( Vec
, (><)
, (<.>)
, sumV
, (^*)
, (^/)
, (^+^)
, (^-^)
, (*^)
, magnitude
, zeroV
, negateV
)
import Physics.Learn.Position
( Position
, Displacement
, displacement
, Field
, VectorField
, shiftPosition
)
data Curve = Curve { Curve -> R -> Position
curveFunc :: Double -> Position
, Curve -> R
startingCurveParam :: Double
, Curve -> R
endingCurveParam :: Double
}
dottedLineIntegral
:: Int
-> VectorField
-> Curve
-> Double
dottedLineIntegral :: Int -> VectorField -> Curve -> R
dottedLineIntegral = Int -> VectorField -> Curve -> R
compositeSimpsonDottedLineIntegral
crossedLineIntegral
:: Int
-> VectorField
-> Curve
-> Vec
crossedLineIntegral :: Int -> VectorField -> Curve -> Vec
crossedLineIntegral = Int -> VectorField -> Curve -> Vec
compositeSimpsonCrossedLineIntegral
compositeTrapezoidDottedLineIntegral
:: Int
-> VectorField
-> Curve
-> Double
compositeTrapezoidDottedLineIntegral :: Int -> VectorField -> Curve -> R
compositeTrapezoidDottedLineIntegral Int
n VectorField
vf (Curve R -> Position
f R
a R
b)
= forall (t :: * -> *) a. (Foldable t, Num a) => t a -> a
sum forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall v. InnerSpace v => v -> v -> Scalar v
(<.>) [Vec]
aveVecs [Vec]
dls
where
dt :: R
dt = (R
b forall a. Num a => a -> a -> a
- R
a) forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n
pts :: [Position]
pts = [R -> Position
f R
t | R
t <- [R
a,R
aforall a. Num a => a -> a -> a
+R
dt..R
b]]
vecs :: [Vec]
vecs = [VectorField
vf Position
pt | Position
pt <- [Position]
pts]
aveVecs :: [Vec]
aveVecs = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall v. (VectorSpace v, Scalar v ~ R) => v -> v -> v
average [Vec]
vecs (forall a. [a] -> [a]
tail [Vec]
vecs)
dls :: [Vec]
dls = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Position -> VectorField
displacement [Position]
pts (forall a. [a] -> [a]
tail [Position]
pts)
compositeTrapezoidCrossedLineIntegral
:: Int
-> VectorField
-> Curve
-> Vec
compositeTrapezoidCrossedLineIntegral :: Int -> VectorField -> Curve -> Vec
compositeTrapezoidCrossedLineIntegral Int
n VectorField
vf (Curve R -> Position
f R
a R
b)
= forall (f :: * -> *) v. (Foldable f, AdditiveGroup v) => f v -> v
sumV forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Vec -> Vec -> Vec
(><) [Vec]
aveVecs [Vec]
dls
where
dt :: R
dt = (R
b forall a. Num a => a -> a -> a
- R
a) forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n
pts :: [Position]
pts = [R -> Position
f R
t | R
t <- [R
a,R
aforall a. Num a => a -> a -> a
+R
dt..R
b]]
vecs :: [Vec]
vecs = [VectorField
vf Position
pt | Position
pt <- [Position]
pts]
aveVecs :: [Vec]
aveVecs = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall v. (VectorSpace v, Scalar v ~ R) => v -> v -> v
average [Vec]
vecs (forall a. [a] -> [a]
tail [Vec]
vecs)
dls :: [Vec]
dls = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Position -> VectorField
displacement [Position]
pts (forall a. [a] -> [a]
tail [Position]
pts)
simpleLineIntegral
:: (InnerSpace v, Scalar v ~ Double)
=> Int
-> Field v
-> Curve
-> v
simpleLineIntegral :: forall v.
(InnerSpace v, Scalar v ~ R) =>
Int -> Field v -> Curve -> v
simpleLineIntegral Int
n Field v
vf (Curve R -> Position
f R
a R
b)
= forall (f :: * -> *) v. (Foldable f, AdditiveGroup v) => f v -> v
sumV forall a b. (a -> b) -> a -> b
$ forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall v s. (VectorSpace v, s ~ Scalar v) => v -> s -> v
(^*) [v]
aveVecs (forall a b. (a -> b) -> [a] -> [b]
map forall v s. (InnerSpace v, s ~ Scalar v, Floating s) => v -> s
magnitude [Vec]
dls)
where
dt :: R
dt = (R
b forall a. Num a => a -> a -> a
- R
a) forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n
pts :: [Position]
pts = [R -> Position
f R
t | R
t <- [R
a,R
aforall a. Num a => a -> a -> a
+R
dt..R
b]]
vecs :: [v]
vecs = [Field v
vf Position
pt | Position
pt <- [Position]
pts]
aveVecs :: [v]
aveVecs = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith forall v. (VectorSpace v, Scalar v ~ R) => v -> v -> v
average [v]
vecs (forall a. [a] -> [a]
tail [v]
vecs)
dls :: [Vec]
dls = forall a b c. (a -> b -> c) -> [a] -> [b] -> [c]
zipWith Position -> VectorField
displacement [Position]
pts (forall a. [a] -> [a]
tail [Position]
pts)
normalizeCurve :: Curve -> Curve
normalizeCurve :: Curve -> Curve
normalizeCurve (Curve R -> Position
f R
a R
b)
= (R -> Position) -> R -> R -> Curve
Curve (R -> Position
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. R -> R
scl) R
0 R
1
where
scl :: R -> R
scl R
t = R
a forall a. Num a => a -> a -> a
+ (R
b forall a. Num a => a -> a -> a
- R
a) forall a. Num a => a -> a -> a
* R
t
concatCurves :: Curve
-> Curve
-> Curve
concatCurves :: Curve -> Curve -> Curve
concatCurves Curve
c1 Curve
c2
= Curve -> Curve
normalizeCurve forall a b. (a -> b) -> a -> b
$ (R -> Position) -> R -> R -> Curve
Curve R -> Position
f R
0 R
2
where
(Curve R -> Position
f1 R
_ R
_) = Curve -> Curve
normalizeCurve Curve
c1
(Curve R -> Position
f2 R
_ R
_) = Curve -> Curve
normalizeCurve Curve
c2
f :: R -> Position
f R
t | R
t forall a. Ord a => a -> a -> Bool
<= R
1 = R -> Position
f1 R
t
| Bool
otherwise = R -> Position
f2 (R
tforall a. Num a => a -> a -> a
-R
1)
concatenateCurves :: [Curve] -> Curve
concatenateCurves :: [Curve] -> Curve
concatenateCurves [] = forall a. HasCallStack => [Char] -> a
error [Char]
"concatenateCurves: cannot concatenate empty list"
concatenateCurves [Curve]
cs = Curve -> Curve
normalizeCurve forall a b. (a -> b) -> a -> b
$ (R -> Position) -> R -> R -> Curve
Curve R -> Position
f R
0 (forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
n)
where
n :: Int
n = forall (t :: * -> *) a. Foldable t => t a -> Int
length [Curve]
cs
ncs :: [Curve]
ncs = forall a b. (a -> b) -> [a] -> [b]
map Curve -> Curve
normalizeCurve [Curve]
cs
f :: R -> Position
f R
t = Curve -> R -> Position
evalCurve ([Curve]
ncs forall a. [a] -> Int -> a
!! Int
m) (R
t forall a. Num a => a -> a -> a
- forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
m)
where m :: Int
m = forall a. Ord a => a -> a -> a
min (Int
nforall a. Num a => a -> a -> a
-Int
1) (forall a b. (RealFrac a, Integral b) => a -> b
floor R
t)
reverseCurve :: Curve -> Curve
reverseCurve :: Curve -> Curve
reverseCurve (Curve R -> Position
f R
a R
b)
= (R -> Position) -> R -> R -> Curve
Curve (R -> Position
f forall b c a. (b -> c) -> (a -> b) -> a -> c
. R -> R
rev) R
a R
b
where
rev :: R -> R
rev R
t = R
a forall a. Num a => a -> a -> a
+ R
b forall a. Num a => a -> a -> a
- R
t
evalCurve :: Curve
-> Double
-> Position
evalCurve :: Curve -> R -> Position
evalCurve (Curve R -> Position
f R
_ R
_) R
t = R -> Position
f R
t
shiftCurve :: Displacement
-> Curve
-> Curve
shiftCurve :: Vec -> Curve -> Curve
shiftCurve Vec
d (Curve R -> Position
f R
sl R
su)
= (R -> Position) -> R -> R -> Curve
Curve (Vec -> Position -> Position
shiftPosition Vec
d forall b c a. (b -> c) -> (a -> b) -> a -> c
. R -> Position
f) R
sl R
su
straightLine :: Position
-> Position
-> Curve
straightLine :: Position -> Position -> Curve
straightLine Position
r1 Position
r2 = (R -> Position) -> R -> R -> Curve
Curve R -> Position
f R
0 R
1
where
f :: R -> Position
f R
t = Vec -> Position -> Position
shiftPosition (R
t forall v. VectorSpace v => Scalar v -> v -> v
*^ Vec
d) Position
r1
d :: Vec
d = Position -> VectorField
displacement Position
r1 Position
r2
average :: (VectorSpace v, Scalar v ~ Double) => v -> v -> v
average :: forall v. (VectorSpace v, Scalar v ~ R) => v -> v -> v
average v
v1 v
v2 = (v
v1 forall v. AdditiveGroup v => v -> v -> v
^+^ v
v2) forall v s.
(VectorSpace v, s ~ Scalar v, Fractional s) =>
v -> s -> v
^/ R
2
dottedSimp :: (InnerSpace v, Fractional (Scalar v)) =>
v
-> v
-> v
-> v
-> v
-> Scalar v
dottedSimp :: forall v.
(InnerSpace v, Fractional (Scalar v)) =>
v -> v -> v -> v -> v -> Scalar v
dottedSimp v
f0 v
f1 v
f2 v
g10 v
g21
= ((v
g21 forall v. AdditiveGroup v => v -> v -> v
^+^ v
g10) forall v s.
(VectorSpace v, s ~ Scalar v, Fractional s) =>
v -> s -> v
^/ Scalar v
6) forall v. InnerSpace v => v -> v -> Scalar v
<.> (v
f0 forall v. AdditiveGroup v => v -> v -> v
^+^ Scalar v
4 forall v. VectorSpace v => Scalar v -> v -> v
*^ v
f1 forall v. AdditiveGroup v => v -> v -> v
^+^ v
f2)
forall a. Num a => a -> a -> a
+ ((v
g21 forall v. AdditiveGroup v => v -> v -> v
^-^ v
g10) forall v s.
(VectorSpace v, s ~ Scalar v, Fractional s) =>
v -> s -> v
^/ Scalar v
3) forall v. InnerSpace v => v -> v -> Scalar v
<.> (v
f2 forall v. AdditiveGroup v => v -> v -> v
^-^ v
f0)
compositeSimpsonDottedLineIntegral
:: Int
-> VectorField
-> Curve
-> Double
compositeSimpsonDottedLineIntegral :: Int -> VectorField -> Curve -> R
compositeSimpsonDottedLineIntegral Int
n VectorField
vf (Curve R -> Position
c R
a R
b)
= let nEven :: Int
nEven = Int
2 forall a. Num a => a -> a -> a
* forall a. Integral a => a -> a -> a
div Int
n Int
2
dt :: R
dt = (R
b forall a. Num a => a -> a -> a
- R
a) forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nEven
ts :: [R]
ts = [R
a forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
m forall a. Num a => a -> a -> a
* R
dt | Int
m <- [Int
0..Int
nEven]]
pairs :: [(Position, Vec)]
pairs = [(Position
ct,VectorField
vf Position
ct) | R
t <- [R]
ts, let ct :: Position
ct = R -> Position
c R
t]
combine :: [(Position, Vec)] -> R
combine [] = forall a. HasCallStack => [Char] -> a
error [Char]
"compositeSimpson: odd number of half-intervals"
combine [(Position, Vec)
_] = forall v. AdditiveGroup v => v
zeroV
combine ((Position, Vec)
_:(Position, Vec)
_:[]) = forall a. HasCallStack => [Char] -> a
error [Char]
"compositeSimpson: odd number of half-intervals"
combine ((Position
c0,Vec
f0):(Position
c1,Vec
f1):(Position
c2,Vec
f2):[(Position, Vec)]
ps)
= forall v.
(InnerSpace v, Fractional (Scalar v)) =>
v -> v -> v -> v -> v -> Scalar v
dottedSimp Vec
f0 Vec
f1 Vec
f2 (Position -> VectorField
displacement Position
c0 Position
c1) (Position -> VectorField
displacement Position
c1 Position
c2)
forall v. AdditiveGroup v => v -> v -> v
^+^ [(Position, Vec)] -> R
combine ((Position
c2,Vec
f2)forall a. a -> [a] -> [a]
:[(Position, Vec)]
ps)
in [(Position, Vec)] -> R
combine [(Position, Vec)]
pairs
crossedSimp :: Vec
-> Vec
-> Vec
-> Vec
-> Vec
-> Vec
crossedSimp :: Vec -> Vec -> Vec -> Vec -> Vec -> Vec
crossedSimp Vec
f0 Vec
f1 Vec
f2 Vec
g10 Vec
g21
= forall v. AdditiveGroup v => v -> v
negateV forall a b. (a -> b) -> a -> b
$
((Vec
g21 forall v. AdditiveGroup v => v -> v -> v
^+^ Vec
g10) forall v s.
(VectorSpace v, s ~ Scalar v, Fractional s) =>
v -> s -> v
^/ R
6) Vec -> Vec -> Vec
>< (Vec
f0 forall v. AdditiveGroup v => v -> v -> v
^+^ R
4 forall v. VectorSpace v => Scalar v -> v -> v
*^ Vec
f1 forall v. AdditiveGroup v => v -> v -> v
^+^ Vec
f2)
forall v. AdditiveGroup v => v -> v -> v
^+^ ((Vec
g21 forall v. AdditiveGroup v => v -> v -> v
^-^ Vec
g10) forall v s.
(VectorSpace v, s ~ Scalar v, Fractional s) =>
v -> s -> v
^/ R
3) Vec -> Vec -> Vec
>< (Vec
f2 forall v. AdditiveGroup v => v -> v -> v
^-^ Vec
f0)
compositeSimpsonCrossedLineIntegral
:: Int
-> VectorField
-> Curve
-> Vec
compositeSimpsonCrossedLineIntegral :: Int -> VectorField -> Curve -> Vec
compositeSimpsonCrossedLineIntegral Int
n VectorField
vf (Curve R -> Position
c R
a R
b)
= let nEven :: Int
nEven = Int
2 forall a. Num a => a -> a -> a
* forall a. Integral a => a -> a -> a
div Int
n Int
2
dt :: R
dt = (R
b forall a. Num a => a -> a -> a
- R
a) forall a. Fractional a => a -> a -> a
/ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
nEven
ts :: [R]
ts = [R
a forall a. Num a => a -> a -> a
+ forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
m forall a. Num a => a -> a -> a
* R
dt | Int
m <- [Int
0..Int
nEven]]
pairs :: [(Position, Vec)]
pairs = [(Position
ct,VectorField
vf Position
ct) | R
t <- [R]
ts, let ct :: Position
ct = R -> Position
c R
t]
combine :: [(Position, Vec)] -> Vec
combine [] = forall a. HasCallStack => [Char] -> a
error [Char]
"compositeSimpson: odd number of half-intervals"
combine [(Position, Vec)
_] = forall v. AdditiveGroup v => v
zeroV
combine ((Position, Vec)
_:(Position, Vec)
_:[]) = forall a. HasCallStack => [Char] -> a
error [Char]
"compositeSimpson: odd number of half-intervals"
combine ((Position
c0,Vec
f0):(Position
c1,Vec
f1):(Position
c2,Vec
f2):[(Position, Vec)]
ps)
= Vec -> Vec -> Vec -> Vec -> Vec -> Vec
crossedSimp Vec
f0 Vec
f1 Vec
f2 (Position -> VectorField
displacement Position
c0 Position
c1) (Position -> VectorField
displacement Position
c1 Position
c2)
forall v. AdditiveGroup v => v -> v -> v
^+^ [(Position, Vec)] -> Vec
combine ((Position
c2,Vec
f2)forall a. a -> [a] -> [a]
:[(Position, Vec)]
ps)
in [(Position, Vec)] -> Vec
combine [(Position, Vec)]
pairs