{-# LANGUAGE TypeOperators, FlexibleContexts, DataKinds, TypeFamilies,
ScopedTypeVariables, ConstraintKinds, GeneralizedNewtypeDeriving,
MultiParamTypeClasses, FlexibleInstances, InstanceSigs, CPP #-}
#if __GLASGOW_HASKELL__ >= 711
{-# OPTIONS_GHC -Wno-redundant-constraints #-}
#endif
module Data.Metrology.Linear (
zeroV, (|^+^|), (|^-^|), qNegateV, qSumV,
(|*^|), (|^*|), (|^/|), (*^|), (|^*), (|^/), (|.|),
qBasis, qBasisFor, qScaled, qOuter, qUnit,
qQuadrance, qNorm, qSignorm, qProject, qCross,
(|.-.|), (|.+^|), (|.-^|), qQd, qDistance, qQdA, qDistanceA,
numInV, (^#), quOfV, (^%), showInV,
convertV, constantV,
) where
import Data.Metrology.Qu
import Data.Metrology.LCSU
import Data.Metrology.Validity
import Data.Metrology.Factor
import Data.Metrology.Z as Z
import Data.Metrology.Units
import Linear
import Linear.Affine hiding (P)
import qualified Control.Lens as Lens
import Data.Proxy
import Data.Foldable as F
#if __GLASGOW_HASKELL__ < 709
import Data.Traversable ( Traversable )
#endif
zeroV :: (Additive f, Num a) => Qu d l (f a)
zeroV = Qu Linear.zero
infixl 6 |^+^|
(|^+^|) :: (d1 @~ d2, Additive f, Num a)
=> Qu d1 l (f a) -> Qu d2 l (f a) -> Qu d1 l (f a)
(Qu a) |^+^| (Qu b) = Qu (a ^+^ b)
qNegateV :: (Additive f, Num a) => Qu d l (f a) -> Qu d l (f a)
qNegateV (Qu x) = Qu (negated x)
infixl 6 |^-^|
(|^-^|) :: (d1 @~ d2, Additive f, Num a)
=> Qu d1 l (f a) -> Qu d2 l (f a) -> Qu d1 l (f a)
(Qu a) |^-^| (Qu b) = Qu (a ^-^ b)
qSumV :: (Foldable t, Additive f, Num a) => t (Qu d l (f a)) -> Qu d l (f a)
qSumV = F.foldr (|^+^|) zeroV
infixl 7 |*^|, |^*|, |^/|
(|*^|) :: (Functor f, Num a)
=> Qu d1 l a -> Qu d2 l (f a) -> Qu (Normalize (d1 @+ d2)) l (f a)
(Qu a) |*^| (Qu b) = Qu (a *^ b)
(|^*|) :: (Functor f, Num a)
=> Qu d1 l (f a) -> Qu d2 l a -> Qu (Normalize (d1 @+ d2)) l (f a)
(Qu a) |^*| (Qu b) = Qu (a ^* b)
(|^/|) :: (Functor f, Fractional a)
=> Qu d1 l (f a) -> Qu d2 l a -> Qu (Normalize (d1 @- d2)) l (f a)
(Qu a) |^/| (Qu b) = Qu (a ^/ b)
infixl 7 |^/
(|^/) :: (Functor f, Fractional a) => Qu d l (f a) -> a -> Qu d l (f a)
(Qu a) |^/ b = Qu (a ^/ b)
infixl 7 *^| , |^*
(*^|) :: (Functor f, Num a) => a -> Qu b l (f a) -> Qu b l (f a)
a *^| (Qu b) = Qu (a *^ b)
(|^*) :: (Functor f, Num a) => Qu b l (f a) -> a -> Qu b l (f a)
(Qu a) |^* b = Qu (a ^* b)
qBasis :: ( ValidDLU dim lcsu unit
, Additive f
, Traversable f
, Fractional a )
=> unit -> [Qu dim lcsu (f a)]
qBasis u = map (^% u) basis
qBasisFor :: ( ValidDLU dim lcsu unit
, Additive f
, Traversable f
, Fractional a )
=> unit -> Qu dim lcsu (f b) -> [Qu dim lcsu (f a)]
qBasisFor u (Qu vec) = map (^% u) (basisFor vec)
qScaled :: (Traversable f, Num a)
=> Qu dim lcsu (f a) -> Qu dim lcsu (f (f a))
qScaled (Qu vec) = Qu (scaled vec)
qOuter :: (Functor f, Functor g, Num a)
=> Qu d1 l (f a) -> Qu d2 l (g a) -> Qu (Normalize (d1 @+ d2)) l (f (g a))
qOuter (Qu a) (Qu b) = Qu (a `outer` b)
qUnit :: (ValidDLU dim lcsu unit, Additive t, Fractional a)
=> Lens.ASetter' (t a) a -> unit -> Qu dim lcsu (t a)
qUnit setter u = unit setter ^% u
infixl 7 |.|
(|.|) :: (Metric f, Num a) => Qu d1 l (f a) -> Qu d2 l (f a) -> Qu (Normalize (d1 @+ d2)) l a
(Qu a) |.| (Qu b) = Qu (a `dot` b)
qQuadrance :: (Metric f, Num a) => Qu d l (f a) -> Qu (d @* Z.Two) l a
qQuadrance (Qu x) = Qu (quadrance x)
qNorm :: (Metric f, Floating a) => Qu d l (f a) -> Qu d l a
qNorm (Qu x) = Qu (norm x)
qSignorm :: (Metric f, Floating a)
=> Qu d l (f a) -> Qu '[] l (f a)
qSignorm (Qu x) = Qu (signorm x)
qProject :: (Metric f, Fractional a)
=> Qu d2 l (f a) -> Qu d1 l (f a) -> Qu d1 l (f a)
qProject (Qu u) (Qu v) = Qu (u `project` v)
qCross :: Num a
=> Qu d1 l (V3 a) -> Qu d2 l (V3 a) -> Qu (Normalize (d1 @+ d2)) l (V3 a)
qCross (Qu x) (Qu y) = Qu (x `cross` y)
qQd :: (d1 @~ d2, Metric f, Metric (Diff f), Num a)
=> Qu d1 l (f a) -> Qu d2 l (f a) -> Qu (d1 @* Z.Two) l a
qQd (Qu a) (Qu b) = Qu (a `qd` b)
qDistance :: (d1 @~ d2, Metric f, Metric (Diff f), Floating a)
=> Qu d1 l (f a) -> Qu d2 l (f a) -> Qu d1 l a
qDistance (Qu a) (Qu b) = Qu (a `distance` b)
(|.-.|) :: (d1 @~ d2, Affine f, Num a) => Qu d1 l (f a) -> Qu d2 l (f a) -> Qu d1 l (Diff f a)
(Qu a) |.-.| (Qu b) = Qu (a .-. b)
(|.+^|) :: (d1 @~ d2, Affine f, Num a) => Qu d1 l (f a) -> Qu d2 l (Diff f a) -> Qu d1 l (f a)
(Qu a) |.+^| (Qu b) = Qu (a .+^ b)
(|.-^|) :: (d1 @~ d2, Affine f, Num a) => Qu d1 l (f a) -> Qu d2 l (Diff f a) -> Qu d1 l (f a)
(Qu a) |.-^| (Qu b) = Qu (a .-^ b)
qQdA :: (d1 @~ d2, Affine f, Foldable (Diff f), Num a)
=> Qu d1 l (f a) -> Qu d2 l (f a) -> Qu (d1 @* Z.Two) l a
qQdA (Qu a) (Qu b) = Qu (a `qdA` b)
qDistanceA :: (d1 @~ d2, Affine f, Foldable (Diff f), Floating a)
=> Qu d1 l (f a) -> Qu d2 l (f a) -> Qu d1 l a
qDistanceA (Qu a) (Qu b) = Qu (a `distanceA` b)
numInV :: forall unit dim lcsu f a.
( ValidDLU dim lcsu unit
, Functor f
, Fractional a )
=> Qu dim lcsu (f a) -> unit -> (f a)
numInV (Qu val) u
= val ^* fromRational
(canonicalConvRatioSpec (Proxy :: Proxy (LookupList dim lcsu))
/ canonicalConvRatio u)
infix 5 ^#
(^#) :: ( ValidDLU dim lcsu unit
, Functor f
, Fractional a )
=> Qu dim lcsu (f a) -> unit -> (f a)
(^#) = numInV
quOfV :: forall unit dim lcsu f a.
( ValidDLU dim lcsu unit
, Functor f
, Fractional a )
=> (f a) -> unit -> Qu dim lcsu (f a)
quOfV d u
= Qu (d ^* fromRational
(canonicalConvRatio u
/ canonicalConvRatioSpec (Proxy :: Proxy (LookupList dim lcsu))))
infixr 9 ^%
(^%) :: ( ValidDLU dim lcsu unit
, Functor f
, Fractional a )
=> (f a) -> unit -> Qu dim lcsu (f a)
(^%) = quOfV
convertV :: forall d l1 l2 f a.
( ConvertibleLCSUs d l1 l2
, Functor f
, Fractional a )
=> Qu d l1 (f a) -> Qu d l2 (f a)
convertV (Qu x) = Qu $ x ^* fromRational (
canonicalConvRatioSpec (Proxy :: Proxy (LookupList d l1))
/ canonicalConvRatioSpec (Proxy :: Proxy (LookupList d l2)))
constantV :: ( d @~ e
, ConvertibleLCSUs e DefaultLCSU l
, Functor f
, Fractional a )
=> Qu d DefaultLCSU (f a) -> Qu e l (f a)
constantV = convertV . redim
infix 1 `showInV`
showInV :: ( ValidDLU dim lcsu unit
, Functor f
, Fractional a
, Show unit
, Show a
, Show (f a) )
=> Qu dim lcsu (f a) -> unit -> String
showInV x u = show (x ^# u) ++ " " ++ show u