module Data.Function.Affine (
Affine(..)
) where
import Data.List
import Data.Maybe
import Data.Semigroup
import Data.VectorSpace
import Data.LinearMap
import Data.LinearMap.HerMetric
import Data.MemoTrie (HasTrie(..))
import Data.AffineSpace
import Data.Basis
import Data.Void
import Data.Tagged
import Data.Manifold.Types.Primitive
import Data.Manifold.PseudoAffine
import Data.CoNat
import Data.VectorSpace.FiniteDimensional
import qualified Prelude
import qualified Control.Applicative as Hask
import Control.Category.Constrained.Prelude hiding ((^))
import Control.Arrow.Constrained
import Control.Monad.Constrained
import Data.Foldable.Constrained
data Affine s d c
= Affine { affineCoOffset :: d
, affineOffset :: c
, affineSlope :: Needle d :-* Needle c
}
instance (RealDimension s) => EnhancedCat (->) (Affine s) where
arr (Affine co ao sl) x = ao .+~^ lapply sl (x.-.co)
instance (MetricScalar s) => Category (Affine s) where
type Object (Affine s) o = WithField s LinearManifold o
id = Affine zeroV zeroV idL
Affine cof aof slf . Affine cog aog slg
= Affine cog (aof .+~^ lapply slf (aog.-.cof)) (slf*.*slg)
linearAffine :: ( AdditiveGroup d, AdditiveGroup c
, HasBasis (Needle d), HasTrie (Basis (Needle d)) )
=> (Needle d -> Needle c) -> Affine s d c
linearAffine = Affine zeroV zeroV . linear
instance (MetricScalar s) => Cartesian (Affine s) where
type UnitObject (Affine s) = ZeroDim s
swap = linearAffine swap
attachUnit = linearAffine (, Origin)
detachUnit = linearAffine fst
regroup = linearAffine regroup
regroup' = linearAffine regroup'
instance (MetricScalar s) => Morphism (Affine s) where
Affine cof aof slf *** Affine cog aog slg
= Affine (cof,cog) (aof,aog) (linear $ lapply slf *** lapply slg)
instance (MetricScalar s) => PreArrow (Affine s) where
terminal = linearAffine $ const Origin
fst = linearAffine fst
snd = linearAffine snd
Affine cof aof slf &&& Affine cog aog slg
= Affine zeroV (aof.-^lapply slf cof, aog.-^lapply slg cog)
(linear $ lapply slf &&& lapply slg)
instance (MetricScalar s) => WellPointed (Affine s) where
unit = Tagged Origin
globalElement x = Affine zeroV x zeroV
const x = Affine zeroV x zeroV
type AffinFuncValue s = GenericAgent (Affine s)
instance (MetricScalar s) => HasAgent (Affine s) where
alg = genericAlg
($~) = genericAgentMap
instance (MetricScalar s) => CartesianAgent (Affine s) where
alg1to2 = genericAlg1to2
alg2to1 = genericAlg2to1
alg2to2 = genericAlg2to2
instance (MetricScalar s)
=> PointAgent (AffinFuncValue s) (Affine s) a x where
point = genericPoint
instance (WithField s LinearManifold v, WithField s LinearManifold a)
=> AdditiveGroup (AffinFuncValue s a v) where
zeroV = GenericAgent $ Affine zeroV zeroV zeroV
GenericAgent (Affine cof aof slf) ^+^ GenericAgent (Affine cog aog slg)
= GenericAgent $ Affine (cof^+^cog) (aof^+^aog) (slf^+^slg)
negateV (GenericAgent (Affine co ao sl))
= GenericAgent $ Affine (negateV co) (negateV ao) (negateV sl)