{-# LANGUAGE TypeOperators, FlexibleContexts, DataKinds, TypeFamilies, CPP,
ScopedTypeVariables, ConstraintKinds, GeneralizedNewtypeDeriving #-}
#if __GLASGOW_HASKELL__ >= 711
{-# OPTIONS_GHC -Wno-redundant-constraints #-}
#endif
module Data.Metrology.Vector (
zero, (|+|), (|-|), qSum, qNegate,
(|*|), (|/|), (/|),
(*|), (|*), (|/),
(|*^|), (|^*|), (|^/|), (|.|),
(|^), (|^^), qNthRoot,
qSq, qCube, qSqrt, qCubeRoot,
qMagnitudeSq, qMagnitude, qNormalized, qProject, qCross2, qCross3,
Point(..), QPoint, (|.-.|), (|.+^|), (|.-^|), qDistanceSq, qDistance,
pointNumIn, (.#), quOfPoint, (%.),
qCompare, (|<|), (|>|), (|<=|), (|>=|), (|==|), (|/=|),
qApprox, qNapprox,
numIn, (#), quOf, (%), showIn,
unity, redim, convert,
defaultLCSU, constant,
(:*)(..), (:/)(..), (:^)(..), (:@)(..),
UnitPrefix(..),
type (%*), type (%/), type (%^),
Qu, MkQu_D, MkQu_DLN, MkQu_U, MkQu_ULN,
Dimension,
Unit(type BaseUnit, type DimOfUnit, conversionRatio),
Canonical,
Dimensionless(..), Number(..), Count, quantity,
MkLCSU, LCSU(DefaultLCSU), DefaultUnitOfDim,
CompatibleUnit, CompatibleDim, ConvertibleLCSUs_D,
DefaultConvertibleLCSU_D, DefaultConvertibleLCSU_U,
MultDimFactors, MultUnitFactors, UnitOfDimFactors,
Z(..), Succ, Pred, type (#+), type (#-), type (#*), type (#/), Negate,
One, Two, Three, Four, Five, MOne, MTwo, MThree, MFour, MFive,
sZero, sOne, sTwo, sThree, sFour, sFive,
sMOne, sMTwo, sMThree, sMFour, sMFive,
sSucc, sPred, sNegate,
module Data.Metrology.Internal
) 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 Data.Metrology.Combinators
import Data.Metrology.Dimensions
import Data.Metrology.Internal
import Data.AffineSpace
import Data.VectorSpace
import Data.Cross hiding ( One, Two, Three )
import Data.Proxy
import Data.Coerce
import Data.Foldable as F
zero :: AdditiveGroup n => Qu dimspec l n
zero = Qu zeroV
infixl 6 |+|
(|+|) :: (d1 @~ d2, AdditiveGroup n) => Qu d1 l n -> Qu d2 l n -> Qu d1 l n
(Qu a) |+| (Qu b) = Qu (a ^+^ b)
qNegate :: AdditiveGroup n => Qu d l n -> Qu d l n
qNegate (Qu x) = Qu (negateV x)
infixl 6 |-|
(|-|) :: (d1 @~ d2, AdditiveGroup n) => Qu d1 l n -> Qu d2 l n -> Qu d1 l n
a |-| b = a |+| qNegate b
qSum :: (Foldable f, AdditiveGroup n) => f (Qu d l n) -> Qu d l n
qSum = F.foldr (|+|) zero
infixl 7 |*^|, |^*|, |^/|
(|*^|) :: VectorSpace n => Qu d1 l (Scalar n) -> Qu d2 l n -> Qu (Normalize (d1 @+ d2)) l n
(Qu a) |*^| (Qu b) = Qu (a *^ b)
(|^*|) :: VectorSpace n => Qu d1 l n -> Qu d2 l (Scalar n) -> Qu (Normalize (d1 @+ d2)) l n
(Qu a) |^*| (Qu b) = Qu (a ^* b)
(|^/|) :: (VectorSpace n, Fractional (Scalar n))
=> Qu d1 l n -> Qu d2 l (Scalar n) -> Qu (Normalize (d1 @- d2)) l n
(Qu a) |^/| (Qu b) = Qu (a ^/ b)
infixl 7 |/
(|/) :: (VectorSpace n, Fractional (Scalar n)) => Qu a l n -> Scalar n -> Qu a l n
(Qu a) |/ b = Qu (a ^/ b)
infixl 7 *| , |*
(*|) :: VectorSpace n => Scalar n -> Qu b l n -> Qu b l n
a *| (Qu b) = Qu (a *^ b)
(|*) :: VectorSpace n => Qu a l n -> Scalar n -> Qu a l n
(Qu a) |* b = Qu (a ^* b)
infixl 7 |.|
(|.|) :: InnerSpace n => Qu d1 l n -> Qu d2 l n -> Qu (Normalize (d1 @+ d2)) l (Scalar n)
(Qu a) |.| (Qu b) = Qu (a <.> b)
qMagnitudeSq :: InnerSpace n => Qu d l n -> Qu (d @* Z.Two) l (Scalar n)
qMagnitudeSq (Qu x) = Qu (magnitudeSq x)
qMagnitude :: (InnerSpace n, Floating (Scalar n)) => Qu d l n -> Qu d l (Scalar n)
qMagnitude (Qu x) = Qu (magnitude x)
qNormalized :: (InnerSpace n, Floating (Scalar n)) => Qu d l n -> Qu '[] l n
qNormalized (Qu x) = Qu (normalized x)
qProject :: (InnerSpace n, Floating (Scalar n)) => Qu d2 l n -> Qu d1 l n -> Qu d1 l n
qProject (Qu u) (Qu v) = Qu (u `project` v)
qCross2 :: HasCross2 n => Qu d l n -> Qu d l n
qCross2 (Qu x) = Qu (cross2 x)
qCross3 :: HasCross3 n => Qu d1 l n -> Qu d2 l n -> Qu (Normalize (d1 @+ d2)) l n
qCross3 (Qu x) (Qu y) = Qu (x `cross3` y)
newtype Point n = Point n
deriving (Show, Eq, Enum, Bounded)
type family QPoint n where
QPoint (Qu d l n) = Qu d l (Point n)
instance AdditiveGroup n => AffineSpace (Point n) where
type Diff (Point n) = n
(.-.) = coerce ((^-^) :: n -> n -> n)
(.+^) = coerce ((^+^) :: n -> n -> n)
quOfPoint :: forall dim lcsu unit n.
( ValidDLU dim lcsu unit
, VectorSpace n
, Fractional (Scalar n) )
=> n -> unit -> Qu dim lcsu (Point n)
quOfPoint n unit = Qu (Point x)
where Qu x = quOf n unit :: Qu dim lcsu n
infix 5 %.
(%.) :: ( ValidDLU dim lcsu unit
, VectorSpace n
, Fractional (Scalar n) )
=> n -> unit -> Qu dim lcsu (Point n)
(%.) = quOfPoint
pointNumIn :: forall unit dim lcsu n.
( ValidDLU dim lcsu unit
, VectorSpace n
, Fractional (Scalar n) )
=> Qu dim lcsu (Point n) -> unit -> n
pointNumIn (Qu (Point n)) unit = numIn (Qu n :: Qu dim lcsu n) unit
infix 5 .#
(.#) :: (ValidDLU dim lcsu unit, VectorSpace n, Fractional (Scalar n))
=> Qu dim lcsu (Point n) -> unit -> n
(.#) = pointNumIn
infixl 6 |.-.|, |.+^|, |.-^|
(|.-.|) :: (d1 @~ d2, AffineSpace n) => Qu d1 l n -> Qu d2 l n -> Qu d1 l (Diff n)
(Qu a) |.-.| (Qu b) = Qu (a .-. b)
(|.+^|) :: (d1 @~ d2, AffineSpace n) => Qu d1 l n -> Qu d2 l (Diff n) -> Qu d1 l n
(Qu a) |.+^| (Qu b) = Qu (a .+^ b)
(|.-^|) :: (d1 @~ d2, AffineSpace n) => Qu d1 l n -> Qu d2 l (Diff n) -> Qu d1 l n
(Qu a) |.-^| (Qu b) = Qu (a .-^ b)
qDistanceSq :: (d1 @~ d2, AffineSpace n, InnerSpace (Diff n))
=> Qu d1 l n -> Qu d2 l n -> Qu (d1 @* Z.Two) l (Scalar (Diff n))
qDistanceSq (Qu a) (Qu b) = Qu (a `distanceSq` b)
qDistance :: (d1 @~ d2, AffineSpace n, InnerSpace (Diff n), Floating (Scalar (Diff n)))
=> Qu d1 l n -> Qu d2 l n -> Qu d1 l (Scalar (Diff n))
qDistance (Qu a) (Qu b) = Qu (a `distance` b)
numIn :: forall unit dim lcsu n.
( ValidDLU dim lcsu unit
, VectorSpace n
, Fractional (Scalar n) )
=> Qu dim lcsu n -> unit -> n
numIn (Qu val) u
= val ^* fromRational
(canonicalConvRatioSpec (Proxy :: Proxy (LookupList dim lcsu))
/ canonicalConvRatio u)
infix 5 #
(#) :: ( ValidDLU dim lcsu unit
, VectorSpace n
, Fractional (Scalar n) )
=> Qu dim lcsu n -> unit -> n
(#) = numIn
quOf :: forall unit dim lcsu n.
( ValidDLU dim lcsu unit
, VectorSpace n
, Fractional (Scalar n) )
=> n -> unit -> Qu dim lcsu n
quOf d u
= Qu (d ^* fromRational
(canonicalConvRatio u
/ canonicalConvRatioSpec (Proxy :: Proxy (LookupList dim lcsu))))
infix 5 %
(%) :: ( ValidDLU dim lcsu unit
, VectorSpace n
, Fractional (Scalar n) )
=> n -> unit -> Qu dim lcsu n
(%) = quOf
convert :: forall d l1 l2 n.
( ConvertibleLCSUs d l1 l2
, VectorSpace n
, Fractional (Scalar n) )
=> Qu d l1 n -> Qu d l2 n
convert (Qu x) = Qu $ x ^* fromRational (
canonicalConvRatioSpec (Proxy :: Proxy (LookupList d l1))
/ canonicalConvRatioSpec (Proxy :: Proxy (LookupList d l2)))
constant :: ( d @~ e
, ConvertibleLCSUs e DefaultLCSU l
, VectorSpace n
, Fractional (Scalar n) )
=> Qu d DefaultLCSU n -> Qu e l n
constant = convert . redim
infix 1 `showIn`
showIn :: ( ValidDLU dim lcsu unit
, VectorSpace n
, Fractional (Scalar n)
, Show unit
, Show n )
=> Qu dim lcsu n -> unit -> String
showIn x u = show (x # u) ++ " " ++ show u