{-# LANGUAGE FlexibleInstances, FlexibleContexts, TypeOperators
, TypeFamilies, TypeSynonymInstances
, UndecidableInstances #-}
{-# OPTIONS_GHC -Wall #-}
module Data.Cross
(
HasNormal(..), normal
, One, Two, Three
, HasCross2(..), HasCross3(..)
) where
import Data.VectorSpace
import Data.MemoTrie
import Data.Basis
import Data.Derivative
class HasNormal v where normalVec :: v -> v
normal :: (HasNormal v, InnerSpace v, Floating (Scalar v)) => v -> v
normal :: v -> v
normal = v -> v
forall v s. (InnerSpace v, s ~ Scalar v, Floating s) => v -> v
normalized (v -> v) -> (v -> v) -> v -> v
forall b c a. (b -> c) -> (a -> b) -> a -> c
. v -> v
forall v. HasNormal v => v -> v
normalVec
type One s = s
type Two s = (s,s)
type Three s = (s,s,s)
class HasCross2 v where cross2 :: v -> v
instance AdditiveGroup u => HasCross2 (u,u) where
cross2 :: (u, u) -> (u, u)
cross2 (u
x,u
y) = (u -> u
forall v. AdditiveGroup v => v -> v
negateV u
y,u
x)
instance (HasTrie (Basis a), HasCross2 v) => HasCross2 (a:>v) where
cross2 :: (a :> v) -> a :> v
cross2 = (v -> v) -> (a :> v) -> a :> v
forall a b c. HasTrie (Basis a) => (b -> c) -> (a :> b) -> a :> c
fmapD v -> v
forall v. HasCross2 v => v -> v
cross2
instance (HasBasis s, HasTrie (Basis s), Basis s ~ ()) =>
HasNormal (One s :> Two s) where
normalVec :: (One s :> Two (One s)) -> One s :> Two (One s)
normalVec One s :> Two (One s)
v = (One s :> Two (One s)) -> One s :> Two (One s)
forall v. HasCross2 v => v -> v
cross2 (One s :> Two (One s)
v (One s :> Two (One s)) -> Basis (One s) -> One s :> Two (One s)
forall a b.
(HasTrie (Basis a), HasBasis a, AdditiveGroup b) =>
(a :> b) -> Basis a -> a :> b
`derivAtBasis` ())
instance (VectorSpace s, HasBasis s, HasTrie (Basis s), Basis s ~ ())
=> HasNormal (Two (One s :> s)) where
normalVec :: Two (One s :> One s) -> Two (One s :> One s)
normalVec = (One s :> (One s, One s)) -> Two (One s :> One s)
forall a b c.
HasTrie (Basis a) =>
(a :> (b, c)) -> (a :> b, a :> c)
unpairD ((One s :> (One s, One s)) -> Two (One s :> One s))
-> (Two (One s :> One s) -> One s :> (One s, One s))
-> Two (One s :> One s)
-> Two (One s :> One s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (One s :> (One s, One s)) -> One s :> (One s, One s)
forall v. HasNormal v => v -> v
normalVec ((One s :> (One s, One s)) -> One s :> (One s, One s))
-> (Two (One s :> One s) -> One s :> (One s, One s))
-> Two (One s :> One s)
-> One s :> (One s, One s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Two (One s :> One s) -> One s :> (One s, One s)
forall a b c.
(HasBasis a, HasTrie (Basis a), VectorSpace b, VectorSpace c) =>
(a :> b, a :> c) -> a :> (b, c)
pairD
class HasCross3 v where cross3 :: v -> v -> v
instance Num s => HasCross3 (s,s,s) where
(s
ax,s
ay,s
az) cross3 :: (s, s, s) -> (s, s, s) -> (s, s, s)
`cross3` (s
bx,s
by,s
bz) = ( s
ay s -> s -> s
forall a. Num a => a -> a -> a
* s
bz s -> s -> s
forall a. Num a => a -> a -> a
- s
az s -> s -> s
forall a. Num a => a -> a -> a
* s
by
, s
az s -> s -> s
forall a. Num a => a -> a -> a
* s
bx s -> s -> s
forall a. Num a => a -> a -> a
- s
ax s -> s -> s
forall a. Num a => a -> a -> a
* s
bz
, s
ax s -> s -> s
forall a. Num a => a -> a -> a
* s
by s -> s -> s
forall a. Num a => a -> a -> a
- s
ay s -> s -> s
forall a. Num a => a -> a -> a
* s
bx )
instance (HasBasis a, HasTrie (Basis a), VectorSpace v, HasCross3 v) => HasCross3 (a:>v) where
cross3 :: (a :> v) -> (a :> v) -> a :> v
cross3 = (v -> v -> v) -> (a :> v) -> (a :> v) -> a :> v
forall a b c u.
(HasBasis a, HasTrie (Basis a), AdditiveGroup u) =>
(b -> c -> u) -> (a :> b) -> (a :> c) -> a :> u
distrib v -> v -> v
forall v. HasCross3 v => v -> v -> v
cross3
instance (Num s, HasTrie (Basis (s, s)), HasBasis s, Basis s ~ ()) =>
HasNormal (Two s :> Three s) where
normalVec :: (Two s :> Three s) -> Two s :> Three s
normalVec Two s :> Three s
v = Basis (Two s) -> Two s :> Three s
d (() -> Either () ()
forall a b. a -> Either a b
Left ()) (Two s :> Three s) -> (Two s :> Three s) -> Two s :> Three s
forall v. HasCross3 v => v -> v -> v
`cross3` Basis (Two s) -> Two s :> Three s
d (() -> Either () ()
forall a b. b -> Either a b
Right ())
where
d :: Basis (Two s) -> Two s :> Three s
d = (Two s :> Three s) -> Basis (Two s) -> Two s :> Three s
forall a b.
(HasTrie (Basis a), HasBasis a, AdditiveGroup b) =>
(a :> b) -> Basis a -> a :> b
derivAtBasis Two s :> Three s
v
instance ( VectorSpace s, HasBasis s, HasTrie (Basis s)
, HasNormal (Two s :> Three s) )
=> HasNormal (Three (Two s :> s)) where
normalVec :: Three (Two s :> s) -> Three (Two s :> s)
normalVec = (Two s :> Three s) -> Three (Two s :> s)
forall a b c d.
HasTrie (Basis a) =>
(a :> (b, c, d)) -> (a :> b, a :> c, a :> d)
untripleD ((Two s :> Three s) -> Three (Two s :> s))
-> (Three (Two s :> s) -> Two s :> Three s)
-> Three (Two s :> s)
-> Three (Two s :> s)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Two s :> Three s) -> Two s :> Three s
forall v. HasNormal v => v -> v
normalVec ((Two s :> Three s) -> Two s :> Three s)
-> (Three (Two s :> s) -> Two s :> Three s)
-> Three (Two s :> s)
-> Two s :> Three s
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Three (Two s :> s) -> Two s :> Three s
forall a b c d.
(HasBasis a, HasTrie (Basis a), VectorSpace b, VectorSpace c,
VectorSpace d) =>
(a :> b, a :> c, a :> d) -> a :> (b, c, d)
tripleD