packages feed

manifolds 0.1.6.3 → 0.2.0.1

raw patch · 12 files changed

+1136/−967 lines, 12 filesdep +trivial-constraintdep ~constrained-categoriesbinary-addedPVP ok

version bump matches the API change (PVP)

Dependencies added: trivial-constraint

Dependency ranges changed: constrained-categories

API changes (from Hackage documentation)

- Data.LinearMap.HerMetric: class (FiniteDimensional v, FiniteDimensional (DualSpace v), VectorSpace (DualSpace v), HasBasis (DualSpace v), MetricScalar (Scalar v), Scalar v ~ Scalar (DualSpace v), Basis v ~ Basis (DualSpace v)) => HasMetric' v where type family DualSpace v :: * DualSpace v = v
- Data.LinearMap.HerMetric: data HerMetric v
- Data.LinearMap.HerMetric: data HerMetric' v
- Data.Manifold: (.:) :: (c -> d) -> (a -> b -> c) -> a -> b -> d
- Data.Manifold: (^) :: Num a => a -> Int -> a
- Data.Manifold: (^.) :: s -> (forall f. Functor f => (a -> f a) -> s -> f s) -> a
- Data.Manifold: (|*^) :: MetricSpace v => Metric v -> v -> v
- Data.Manifold: CD¹ :: !Double -> !x -> CD¹ x
- Data.Manifold: Chart :: v :--> m -> (m -> Maybe (m :--> v)) -> ChartKind -> Chart m
- Data.Manifold: CntnFuncConst :: c -> CntnFuncValue d c
- Data.Manifold: CntnFuncValue :: d :--> c -> CntnFuncValue d c
- Data.Manifold: Continuous :: (Chart d -> v -> (Chart c, u, ε -> Option δ)) -> d :--> c
- Data.Manifold: Cℝay :: !Double -> !x -> Cℝay x
- Data.Manifold: DensTensProd :: Matrix (Scalar y) -> (⊗) x y
- Data.Manifold: D² :: !Double -> !Double -> D²
- Data.Manifold: D¹ :: Double -> D¹
- Data.Manifold: GraphWindowSpec :: Double -> Int -> GraphWindowSpec
- Data.Manifold: IdChart :: Chart v
- Data.Manifold: LandlockedChart :: ChartKind
- Data.Manifold: NegativeHalfSphere :: S⁰
- Data.Manifold: Origin :: ZeroDim k
- Data.Manifold: PositiveHalfSphere :: S⁰
- Data.Manifold: RimChart :: ChartKind
- Data.Manifold: S² :: !Double -> !Double -> S²
- Data.Manifold: S¹ :: Double -> S¹
- Data.Manifold: [chartInMap] :: Chart m -> v :--> m
- Data.Manifold: [chartKind] :: Chart m -> ChartKind
- Data.Manifold: [chartOutMap] :: Chart m -> m -> Maybe (m :--> v)
- Data.Manifold: [getDensTensProd] :: (⊗) x y -> Matrix (Scalar y)
- Data.Manifold: [hParamCD¹] :: CD¹ x -> !Double
- Data.Manifold: [hParamCℝay] :: Cℝay x -> !Double
- Data.Manifold: [lBound, rBound, bBound, tBound] :: GraphWindowSpec -> Double
- Data.Manifold: [pParamCD¹] :: CD¹ x -> !x
- Data.Manifold: [pParamCℝay] :: Cℝay x -> !x
- Data.Manifold: [rParamD²] :: D² -> !Double
- Data.Manifold: [rParamℝP²] :: ℝP² -> !Double
- Data.Manifold: [runCntnFuncValue] :: CntnFuncValue d c -> d :--> c
- Data.Manifold: [runContinuous] :: d :--> c -> Chart d -> v -> (Chart c, u, ε -> Option δ)
- Data.Manifold: [xParamD¹] :: D¹ -> Double
- Data.Manifold: [xResolution, yResolution] :: GraphWindowSpec -> Int
- Data.Manifold: [φParamD²] :: D² -> !Double
- Data.Manifold: [φParamS²] :: S² -> !Double
- Data.Manifold: [φParamS¹] :: S¹ -> Double
- Data.Manifold: [φParamℝP²] :: ℝP² -> !Double
- Data.Manifold: [ϑParamS²] :: S² -> !Double
- Data.Manifold: asinh__ :: CntnRealFunction
- Data.Manifold: atan__ :: CntnRealFunction
- Data.Manifold: class (MetricSpace (TangentSpace m), Metric (TangentSpace m) ~ ℝ) => Manifold m where type family TangentSpace m :: * TangentSpace m = m
- Data.Manifold: class (RealFloat (Metric v), InnerSpace v) => MetricSpace v where type family Metric v :: * Metric v = ℝ metric = sqrt . metricSq metricSq = (^ 2) . metric μ |*^ v = metricToScalar v μ *^ v
- Data.Manifold: class NaturallyEmbedded m v
- Data.Manifold: cntnFnValsCombine :: (FlatManifold c, FlatManifold c', FlatManifold c'', Manifold d, ε ~ Metric c, ε' ~ Metric c', ε'' ~ Metric c'', ε ~ ε', ε ~ ε'') => (c' -> c'' -> (c, ε -> (ε', (ε', ε''), ε''))) -> CntnFuncValue d c' -> CntnFuncValue d c'' -> CntnFuncValue d c
- Data.Manifold: cntnFnValsFunc :: (FlatManifold c, FlatManifold c', Manifold d, ε ~ Metric c, ε ~ Metric c') => (c' -> (c, ε -> Option ε)) -> CntnFuncValue d c' -> CntnFuncValue d c
- Data.Manifold: cntnFuncsCombine :: (FlatManifold c, FlatManifold c', FlatManifold c'', ε ~ Metric c, ε' ~ Metric c', ε'' ~ Metric c'', ε ~ ε', ε ~ ε'') => (c' -> c'' -> (c, ε -> (ε', ε''))) -> (d :--> c') -> (d :--> c'') -> d :--> c
- Data.Manifold: coEmbed :: NaturallyEmbedded m v => v -> m
- Data.Manifold: const__ :: (Manifold c, Manifold d) => c -> d :--> c
- Data.Manifold: continuousFlatFunction :: (FlatManifold d, FlatManifold c, ε ~ Metric c, δ ~ Metric d) => (d -> (c, ε -> Option δ)) -> d :--> c
- Data.Manifold: continuous_id' :: Manifold m => m :--> m
- Data.Manifold: cos__ :: CntnRealFunction
- Data.Manifold: cosh__ :: CntnRealFunction
- Data.Manifold: data (:-->) domain codomain
- Data.Manifold: data CD¹ x
- Data.Manifold: data Chart :: * -> *
- Data.Manifold: data ChartKind
- Data.Manifold: data CntnFuncValue d c
- Data.Manifold: data Cℝay x
- Data.Manifold: data D²
- Data.Manifold: data GraphWindowSpec
- Data.Manifold: data S²
- Data.Manifold: data S⁰
- Data.Manifold: data ZeroDim k
- Data.Manifold: data ℝP²
- Data.Manifold: embed :: NaturallyEmbedded m v => m -> v
- Data.Manifold: empty :: Alternative f => forall a. f a
- Data.Manifold: exp__ :: CntnRealFunction
- Data.Manifold: finiteGraphContinℝtoℝ :: GraphWindowSpec -> (Double :--> Double) -> [(Double, Double)]
- Data.Manifold: finiteGraphContinℝtoℝ² :: GraphWindowSpec -> (Double :--> (Double, Double)) -> [[(Double, Double)]]
- Data.Manifold: flatContinuous :: (FlatManifold v, FlatManifold w, δ ~ Metric v, ε ~ Metric w) => (v -> (w, ε -> Option δ)) -> (v :--> w)
- Data.Manifold: instance (Data.Manifold.FlatManifold v, Data.Manifold.Manifold d) => Data.AdditiveGroup.AdditiveGroup (Data.Manifold.CntnFuncValue d v)
- Data.Manifold: instance (Data.Manifold.FlatManifold v, Data.Manifold.MetricSpace v, Data.Manifold.Metric v ~ Data.Manifold.Types.Primitive.ℝ, Data.Manifold.FlatManifold (Data.VectorSpace.Scalar v), Data.Manifold.MetricSpace (Data.VectorSpace.Scalar v), Data.Manifold.Metric (Data.VectorSpace.Scalar v) ~ Data.Manifold.Types.Primitive.ℝ, Data.Manifold.Manifold d) => Data.VectorSpace.VectorSpace (Data.Manifold.CntnFuncValue d v)
- Data.Manifold: instance (Data.Manifold.FlatManifold v₁, Data.Manifold.FlatManifold v₂, Data.VectorSpace.Scalar v₁ ~ Data.VectorSpace.Scalar v₂, Data.Manifold.MetricSpace (Data.VectorSpace.Scalar v₁), Data.Manifold.Metric (Data.VectorSpace.Scalar v₁) ~ Data.Manifold.Types.Primitive.ℝ, Data.VectorSpace.VectorSpace (v₁, v₂), Data.VectorSpace.Scalar (v₁, v₂) ~ Data.VectorSpace.Scalar v₁) => Data.Manifold.Manifold (v₁, v₂)
- Data.Manifold: instance (Data.Manifold.MetricSpace v, Data.Manifold.MetricSpace (Data.VectorSpace.Scalar v), Data.Manifold.MetricSpace w, Data.VectorSpace.Scalar v ~ Data.VectorSpace.Scalar w, Data.Manifold.Metric v ~ Data.Manifold.Metric (Data.VectorSpace.Scalar v), Data.Manifold.Metric w ~ Data.Manifold.Metric v, Data.Manifold.Metric (Data.VectorSpace.Scalar w) ~ Data.Manifold.Metric v, GHC.Float.RealFloat (Data.Manifold.Metric v)) => Data.Manifold.MetricSpace (v, w)
- Data.Manifold: instance (Data.Manifold.Representsℝ r, Data.Manifold.Manifold d) => GHC.Float.Floating (Data.Manifold.CntnFuncValue d r)
- Data.Manifold: instance (Data.Manifold.Representsℝ r, Data.Manifold.Manifold d) => GHC.Num.Num (Data.Manifold.CntnFuncValue d r)
- Data.Manifold: instance (Data.Manifold.Representsℝ r, Data.Manifold.Manifold d) => GHC.Real.Fractional (Data.Manifold.CntnFuncValue d r)
- Data.Manifold: instance (GHC.Float.RealFloat r, Data.Manifold.MetricSpace r, Data.VectorSpace.Scalar (Data.Complex.Complex r) ~ Data.Manifold.Metric r) => Data.Manifold.MetricSpace (Data.Complex.Complex r)
- Data.Manifold: instance Control.Arrow.Constrained.CartesianAgent (Data.Manifold.:-->)
- Data.Manifold: instance Control.Arrow.Constrained.EnhancedCat (->) (Data.Manifold.:-->)
- Data.Manifold: instance Control.Arrow.Constrained.Morphism (Data.Manifold.:-->)
- Data.Manifold: instance Control.Arrow.Constrained.PointAgent Data.Manifold.CntnFuncValue (Data.Manifold.:-->) d c
- Data.Manifold: instance Control.Arrow.Constrained.PreArrow (Data.Manifold.:-->)
- Data.Manifold: instance Control.Category.Constrained.Cartesian (Data.Manifold.:-->)
- Data.Manifold: instance Control.Category.Constrained.Category (Data.Manifold.:-->)
- Data.Manifold: instance Control.Category.Constrained.HasAgent (Data.Manifold.:-->)
- Data.Manifold: instance Data.Manifold.Manifold ()
- Data.Manifold: instance Data.Manifold.Manifold GHC.Types.Double
- Data.Manifold: instance Data.Manifold.MetricSpace ()
- Data.Manifold: instance Data.Manifold.MetricSpace Data.Manifold.Types.Primitive.ℝ
- Data.Manifold: isInUpperHemi :: EuclidSpace v => v -> Bool
- Data.Manifold: isoAttachZeroDim :: (WellPointed c, UnitObject c ~ (), ObjectPair c a (), Object c (ZeroDim k), ObjectPair c a (ZeroDim k), PointObject c (ZeroDim k)) => Isomorphism c a (a, ZeroDim k)
- Data.Manifold: just :: a -> Option a
- Data.Manifold: localAtlas :: Manifold m => m -> Atlas m
- Data.Manifold: metric :: MetricSpace v => v -> Metric v
- Data.Manifold: metricSq :: MetricSpace v => v -> Metric v
- Data.Manifold: metricToScalar :: MetricSpace v => v -> Metric v -> Scalar v
- Data.Manifold: midBetween :: (VectorSpace v, Fractional (Scalar v)) => [v] -> v
- Data.Manifold: newtype (⊗) x y
- Data.Manifold: newtype D¹
- Data.Manifold: newtype S¹
- Data.Manifold: nothing :: Option a
- Data.Manifold: otherHalfSphere :: S⁰ -> S⁰
- Data.Manifold: runFlatContinuous :: (FlatManifold v, FlatManifold w, δ ~ Metric v, ε ~ Metric w) => (v :--> w) -> v -> (w, ε -> Option δ)
- Data.Manifold: sin__ :: CntnRealFunction
- Data.Manifold: sinh__ :: CntnRealFunction
- Data.Manifold: tanh__ :: CntnRealFunction
- Data.Manifold: type Atlas m = [Chart m]
- Data.Manifold: type Cone = CD¹
- Data.Manifold: type Disk1 = D¹
- Data.Manifold: type Disk2 = D²
- Data.Manifold: type Endomorphism a = a -> a
- Data.Manifold: type EqFloating f = (Eq f, Ord f, Floating f)
- Data.Manifold: type EuclidSpace v = (HasBasis v, EqFloating (Scalar v), Eq v)
- Data.Manifold: type FlatManifold v = (MetricSpace v, Manifold v, v ~ TangentSpace v)
- Data.Manifold: type OpenCone = Cℝay
- Data.Manifold: type Projective1 = ℝP¹
- Data.Manifold: type Projective2 = ℝP²
- Data.Manifold: type Real0 = ℝ⁰
- Data.Manifold: type Real1 = ℝ
- Data.Manifold: type Real2 = ℝ²
- Data.Manifold: type Real3 = ℝ³
- Data.Manifold: type RealPlus = ℝay
- Data.Manifold: type Representsℝ r = (EqFloating r, FlatManifold r, r ~ Scalar r, r ~ Metric r)
- Data.Manifold: type Sphere0 = S⁰
- Data.Manifold: type Sphere1 = S¹
- Data.Manifold: type Sphere2 = S²
- Data.Manifold: type CntnRealFunction = Representsℝ r => r :--> r
- Data.Manifold: type ℝ = Double
- Data.Manifold: type ℝP¹ = S¹
- Data.Manifold: type ℝay = Cℝay ℝ⁰
- Data.Manifold: type ℝ² = (ℝ, ℝ)
- Data.Manifold: type ℝ³ = (ℝ², ℝ)
- Data.Manifold: type ℝ⁰ = ZeroDim ℝ
- Data.Manifold: vectorSpaceAtlas :: FlatManifold v => v -> Atlas v
- Data.Manifold: ℝP² :: !Double -> !Double -> ℝP²
+ Data.LinearMap.HerMetric: HerMetric :: Maybe (Linear (Scalar v) v (DualSpace v)) -> HerMetric v
+ Data.LinearMap.HerMetric: HerMetric' :: Maybe (Linear (Scalar v) (DualSpace v) v) -> HerMetric' v
+ Data.LinearMap.HerMetric: [metricMatrix'] :: HerMetric' v -> Maybe (Linear (Scalar v) (DualSpace v) v)
+ Data.LinearMap.HerMetric: [metricMatrix] :: HerMetric v -> Maybe (Linear (Scalar v) v (DualSpace v))
+ Data.LinearMap.HerMetric: applyLinMapMetric :: (HasMetric v, HasMetric w, Scalar v ~ ℝ, Scalar w ~ ℝ) => HerMetric (Linear ℝ v w) -> DualSpace v -> HerMetric w
+ Data.LinearMap.HerMetric: applyLinMapMetric' :: (HasMetric v, HasMetric w, Scalar v ~ ℝ, Scalar w ~ ℝ) => HerMetric' (Linear ℝ v w) -> v -> HerMetric' w
+ Data.LinearMap.HerMetric: basisInDual :: HasMetric' v => Tagged v (Basis v -> Basis (DualSpace v))
+ Data.LinearMap.HerMetric: class (FiniteDimensional v, FiniteDimensional (DualSpace v), VectorSpace (DualSpace v), HasBasis (DualSpace v), MetricScalar (Scalar v), Scalar v ~ Scalar (DualSpace v)) => HasMetric' v where type family DualSpace v :: * DualSpace v = v basisInDual = bid where bid :: forall v. HasMetric' v => Tagged v (Basis v -> Basis (DualSpace v)) bid = Tagged $ bi >>> ib' where Tagged bi = basisIndex :: Tagged v (Basis v -> Int) Tagged ib' = indexBasis :: Tagged (DualSpace v) (Int -> Basis (DualSpace v))
+ Data.LinearMap.HerMetric: fromDualWith :: HasMetric v => HerMetric' v -> DualSpace v -> v
+ Data.LinearMap.HerMetric: imitateMetricSpanChange :: (HasMetric v, Scalar v ~ ℝ) => HerMetric v -> HerMetric' v -> Linear ℝ v v
+ Data.LinearMap.HerMetric: instance (Data.LinearMap.HerMetric.HasMetric v, Data.LinearMap.HerMetric.HasMetric w, s ~ Data.VectorSpace.Scalar v, s ~ Data.VectorSpace.Scalar w) => Data.LinearMap.HerMetric.HasMetric' (Data.LinearMap.Category.Linear s v w)
+ Data.LinearMap.HerMetric: newtype HerMetric v
+ Data.LinearMap.HerMetric: newtype HerMetric' v
+ Data.LinearMap.HerMetric: toDualWith :: HasMetric v => HerMetric v -> v -> DualSpace v
+ Data.Manifold.PseudoAffine: instance (Data.LinearMap.HerMetric.HasMetric a, Data.VectorSpace.FiniteDimensional.FiniteDimensional b, Data.VectorSpace.Scalar a ~ s, Data.VectorSpace.Scalar b ~ s) => Data.Manifold.PseudoAffine.PseudoAffine (Data.LinearMap.Category.Linear s a b)
+ Data.Manifold.PseudoAffine: instance (Data.LinearMap.HerMetric.HasMetric a, Data.VectorSpace.FiniteDimensional.FiniteDimensional b, Data.VectorSpace.Scalar a ~ s, Data.VectorSpace.Scalar b ~ s) => Data.Manifold.PseudoAffine.Semimanifold (Data.LinearMap.Category.Linear s a b)
+ Data.Manifold.PseudoAffine: type LocalAffine x y = (Needle y, LocalLinear x y)
+ Data.Manifold.PseudoAffine: type LocalLinear x y = Linear (Scalar (Needle x)) (Needle x) (Needle y)
+ Data.Manifold.TreeCover: WithAny :: y -> !x -> WithAny x y
+ Data.Manifold.TreeCover: [_topological] :: WithAny x y -> !x
+ Data.Manifold.TreeCover: [_untopological] :: WithAny x y -> y
+ Data.Manifold.TreeCover: class IsShade shade
+ Data.Manifold.TreeCover: completeTopShading :: (WithField ℝ Manifold x, WithField ℝ Manifold y) => x `Shaded` y -> [Shade' (x, y)]
+ Data.Manifold.TreeCover: data WithAny x y
+ Data.Manifold.TreeCover: factoriseShade :: (IsShade shade, Manifold x, RealDimension (Scalar (Needle x)), Manifold y, RealDimension (Scalar (Needle y))) => shade (x, y) -> (shade x, shade y)
+ Data.Manifold.TreeCover: filterDEqnSolution_static :: (WithField ℝ Manifold x, WithField ℝ Manifold y) => DifferentialEqn x y -> x `Shaded` y -> Option (x `Shaded` y)
+ Data.Manifold.TreeCover: flexTwigsShading :: (WithField ℝ Manifold x, WithField ℝ Manifold y, Applicative f) => (Shade' (x, y) -> f (x, (Shade' y, LocalLinear x y))) -> x `Shaded` y -> f (x `Shaded` y)
+ Data.Manifold.TreeCover: instance (Control.DeepSeq.NFData x, Control.DeepSeq.NFData y) => Control.DeepSeq.NFData (Data.Manifold.TreeCover.WithAny x y)
+ Data.Manifold.TreeCover: instance (Control.DeepSeq.NFData x, Data.Foldable.Foldable c, Data.Foldable.Foldable b) => Control.DeepSeq.NFData (Data.Manifold.TreeCover.GenericTree c b x)
+ Data.Manifold.TreeCover: instance (Data.Foldable.Foldable c, Data.Foldable.Foldable b) => Data.Foldable.Foldable (Data.Manifold.TreeCover.GenericTree c b)
+ Data.Manifold.TreeCover: instance (Data.Traversable.Traversable c, Data.Traversable.Traversable b) => Data.Traversable.Traversable (Data.Manifold.TreeCover.GenericTree c b)
+ Data.Manifold.TreeCover: instance (GHC.Show.Show x, GHC.Show.Show (Data.LinearMap.HerMetric.DualSpace (Data.Manifold.PseudoAffine.Needle x)), Data.Manifold.PseudoAffine.WithField Data.Manifold.Types.Primitive.ℝ Data.Manifold.PseudoAffine.Manifold x) => GHC.Show.Show (Data.Manifold.TreeCover.Shade' x)
+ Data.Manifold.TreeCover: instance (GHC.Show.Show x, GHC.Show.Show (Data.Manifold.PseudoAffine.Needle x), Data.Manifold.PseudoAffine.WithField Data.Manifold.Types.Primitive.ℝ Data.Manifold.PseudoAffine.Manifold x) => GHC.Show.Show (Data.Manifold.TreeCover.Shade x)
+ Data.Manifold.TreeCover: instance (GHC.Show.Show x, GHC.Show.Show y) => GHC.Show.Show (Data.Manifold.TreeCover.WithAny x y)
+ Data.Manifold.TreeCover: instance GHC.Base.Applicative f => GHC.Base.Applicative (Data.Manifold.TreeCover.OuterMaybeT f)
+ Data.Manifold.TreeCover: instance GHC.Base.Functor f => GHC.Base.Functor (Data.Manifold.TreeCover.OuterMaybeT f)
+ Data.Manifold.TreeCover: instance GHC.Generics.Constructor Data.Manifold.TreeCover.C1_0GenericTree
+ Data.Manifold.TreeCover: instance GHC.Generics.Constructor Data.Manifold.TreeCover.C1_0WithAny
+ Data.Manifold.TreeCover: instance GHC.Generics.Datatype Data.Manifold.TreeCover.D1GenericTree
+ Data.Manifold.TreeCover: instance GHC.Generics.Datatype Data.Manifold.TreeCover.D1WithAny
+ Data.Manifold.TreeCover: instance GHC.Generics.Generic (Data.Manifold.TreeCover.GenericTree c b x)
+ Data.Manifold.TreeCover: instance GHC.Generics.Generic (Data.Manifold.TreeCover.WithAny x y)
+ Data.Manifold.TreeCover: instance GHC.Generics.Selector Data.Manifold.TreeCover.S1_0_0GenericTree
+ Data.Manifold.TreeCover: instance GHC.Generics.Selector Data.Manifold.TreeCover.S1_0_0WithAny
+ Data.Manifold.TreeCover: instance GHC.Generics.Selector Data.Manifold.TreeCover.S1_0_1WithAny
+ Data.Manifold.TreeCover: intersectShade's :: WithField ℝ Manifold y => [Shade' y] -> Option (Shade' y)
+ Data.Manifold.TreeCover: occlusion :: (IsShade shade, Manifold x, s ~ (Scalar (Needle x)), RealDimension s) => shade x -> x -> s
+ Data.Manifold.TreeCover: spanShading :: (WithField ℝ Manifold x, WithField ℝ Manifold y) => (Shade x -> Shade y) -> ShadeTree x -> x `Shaded` y
+ Data.Manifold.TreeCover: stiAsIntervalMapping :: (x ~ ℝ, y ~ ℝ) => x `Shaded` y -> [(x, ((y, Diff y), Linear ℝ x y))]
+ Data.Manifold.TreeCover: twigsWithEnvirons :: WithField ℝ Manifold x => ShadeTree x -> [(ShadeTree x, [ShadeTree x])]
+ Data.Manifold.TreeCover: type DifferentialEqn x y = Shade' (x, y) -> Shade' (LocalLinear x y)
+ Data.Manifold.TreeCover: type Shaded x y = ShadeTree (x `WithAny` y)
+ Data.Manifold.Types: data Linear s a b
+ Data.Manifold.Types: denseLinear :: (FiniteDimensional v, FiniteDimensional w, Scalar w ~ s) => (v -> w) -> Linear s v w
- Data.LinearMap.HerMetric: adjoint :: (HasMetric v, HasMetric w, Scalar w ~ Scalar v) => (v :-* w) -> DualSpace w :-* DualSpace v
+ Data.LinearMap.HerMetric: adjoint :: (HasMetric v, HasMetric w, s ~ Scalar v, s ~ Scalar w) => (Linear s v w) -> Linear s (DualSpace w) (DualSpace v)
- Data.LinearMap.HerMetric: covariance :: (HasMetric v, HasMetric w, Scalar v ~ ℝ, Scalar w ~ ℝ) => HerMetric' (v, w) -> Option (v :-* w)
+ Data.LinearMap.HerMetric: covariance :: (HasMetric v, HasMetric w, Scalar v ~ ℝ, Scalar w ~ ℝ) => HerMetric' (v, w) -> Option (Linear ℝ v w)
- Data.LinearMap.HerMetric: dualCoCoProduct :: (HasMetric v, HasMetric w, Scalar v ~ Scalar w) => (w :-* v) -> (w :-* v) -> HerMetric w
+ Data.LinearMap.HerMetric: dualCoCoProduct :: (HasMetric v, HasMetric w, Scalar v ~ s, Scalar w ~ s) => Linear s w v -> Linear s w v -> HerMetric w
- Data.LinearMap.HerMetric: transformMetric :: (HasMetric v, HasMetric w, Scalar v ~ Scalar w) => (w :-* v) -> HerMetric v -> HerMetric w
+ Data.LinearMap.HerMetric: transformMetric :: (HasMetric v, HasMetric w, Scalar v ~ s, Scalar w ~ s) => Linear s w v -> HerMetric v -> HerMetric w
- Data.LinearMap.HerMetric: transformMetric' :: (HasMetric v, HasMetric w, Scalar v ~ Scalar w) => (v :-* w) -> HerMetric' v -> HerMetric' w
+ Data.LinearMap.HerMetric: transformMetric' :: (HasMetric v, HasMetric w, Scalar v ~ s, Scalar w ~ s) => Linear s v w -> HerMetric' v -> HerMetric' w

Files

Data/Function/Affine.hs view
@@ -19,6 +19,8 @@ {-# LANGUAGE TupleSections            #-} {-# LANGUAGE ConstraintKinds          #-} {-# LANGUAGE PatternGuards            #-}+{-# LANGUAGE PatternSynonyms          #-}+{-# LANGUAGE ViewPatterns             #-} {-# LANGUAGE TypeOperators            #-} {-# LANGUAGE UnicodeSyntax            #-} {-# LANGUAGE MultiWayIf               #-}@@ -28,7 +30,9 @@   module Data.Function.Affine (-              Affine(..)+              Affine+            , linearAffine+            , toOffsetSlope, toOffset'Slope              ) where      @@ -54,7 +58,9 @@ import qualified Prelude import qualified Control.Applicative as Hask +import Data.Constraint.Trivial import Control.Category.Constrained.Prelude hiding ((^))+import Control.Category.Constrained.Reified import Control.Arrow.Constrained import Control.Monad.Constrained import Data.Foldable.Constrained@@ -62,54 +68,343 @@   -data Affine s d c-   = Affine { affineCoOffset :: d-            , affineOffset :: c-            , affineSlope :: Needle d :-* Needle c-            }+data Affine s d c where+   Subtract :: AffineManifold α => Affine s (α,α) (Needle α)+   AddTo :: Affine s (α, Needle α) α+   ScaleWith :: (LinearManifold α, LinearManifold β) => (α:-*β) -> Affine s α β+   ReAffine :: ReWellPointed (Affine s) α β -> Affine s α β -instance (RealDimension s) => EnhancedCat (->) (Affine s) where-  arr (Affine co ao sl) x = ao .+~^ lapply sl (x.-.co)+reAffine :: ReWellPointed (Affine s) α β -> Affine s α β+reAffine (ReWellPointed f) = f+reAffine f = ReAffine f +pattern Specific f = ReWellPointed f+pattern Id = ReAffine WellPointedId+infixr 1 :>>>, :<<<+pattern f :>>> g <- ReAffine (WellPointedCompo (reAffine -> f) (reAffine -> g))+pattern g :<<< f <- ReAffine (WellPointedCompo (reAffine -> f) (reAffine -> g))+pattern Swap = ReAffine WellPointedSwap+pattern AttachUnit = ReAffine WellPointedAttachUnit+pattern DetachUnit = ReAffine WellPointedDetachUnit+pattern Regroup = ReAffine WellPointedRegroup+pattern Regroup' = ReAffine WellPointedRegroup_+pattern Terminal = ReAffine WellPointedTerminal+pattern Fst = ReAffine WellPointedFst+pattern Snd = ReAffine WellPointedSnd+infixr 3 :***, :&&&+pattern f :*** g <- ReAffine (WellPointedPar (reAffine -> f) (reAffine -> g))+pattern f :&&& g <- ReAffine (WellPointedFanout (reAffine -> f) (reAffine -> g))+pattern Const c = ReAffine (WellPointedConst c) -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+toOffsetSlope :: (MetricScalar s, WithField s LinearManifold d+                                 , WithField s AffineManifold c )+                      => Affine s d c -> (c, Needle d :-* Needle c)+toOffsetSlope f = toOffset'Slope f zeroV +-- | Basically evaluates an affine function as a generic differentiable one,+--   yielding at a given reference point the result and Jacobian. Unlike with+--   'Data.Function.Differentiable.Differentiable', the induced 1st-order Taylor+--   series is equal to the function!+toOffset'Slope :: ( MetricScalar s, WithField s AffineManifold d+                                   , WithField s AffineManifold c )+                      => Affine s d c -> d -> (c, Needle d :-* Needle c)+toOffset'Slope Subtract (a,b) = (a.-.b, linear $ uncurry(^-^))+toOffset'Slope AddTo (p,v) = (p.+^v, linear $ uncurry(^+^))+toOffset'Slope (ScaleWith q) ref = (lapply q ref, q)+toOffset'Slope Id ref = (ref, linear id)+toOffset'Slope (f :>>> g) ref = case toOffset'Slope f ref of+                  (cf,sf) -> case toOffset'Slope g cf of+                     (cg,sg)     -> (cg, sg*.*sf)+toOffset'Slope Swap ref = (swap ref, linear swap)+toOffset'Slope AttachUnit ref = ((ref,Origin), linear (,Origin))+toOffset'Slope DetachUnit ref = (fst ref, linear fst)+toOffset'Slope Regroup ref = (regroup ref, linear regroup)+toOffset'Slope Regroup' ref = (regroup' ref, linear regroup')+toOffset'Slope (f:***g) ref = case ( toOffset'Slope f (fst ref)+                                 , toOffset'Slope g (snd ref) ) of+                  ((cf, sf), (cg, sg)) -> ((cf,cg), linear $ lapply sf *** lapply sg)+toOffset'Slope Terminal ref = (Origin, zeroV)+toOffset'Slope Fst ref = (fst ref, linear fst)+toOffset'Slope Snd ref = (snd ref, linear snd)+toOffset'Slope (f:&&&g) ref = case ( toOffset'Slope (arr f) ref+                                  , toOffset'Slope (arr g) ref ) of+                  ((cf, sf), (cg, sg)) -> ((cf,cg), linear $ lapply sf &&& lapply sg)+toOffset'Slope (Const c) ref = (c, zeroV)+            +coOffsetForm :: ( MetricScalar s, WithField s AffineManifold d+                                , WithField s AffineManifold c )+                      => Affine s d c -> Affine s d c+coOffsetForm (ScaleWith q) = id&&&const zeroV >>> Subtract >>> ScaleWith q+coOffsetForm ((coOffsetForm -> Id:&&&Const cof :>>> Subtract :>>> f) :>>> g)+                    = id&&&const cof >>> Subtract >>> (f >>> g)+coOffsetForm ( (coOffsetForm -> Id:&&&Const cof :>>> Subtract :>>> f)+          :*** (coOffsetForm -> Id:&&&Const cog :>>> Subtract :>>> g) )+     = id&&&const(cof,cog) >>> Subtract >>> (f***g)+coOffsetForm (Id:&&&Const cof :>>> Subtract)+           = (Id&&&Const cof >>> ReAffine (ReWellPointed Subtract`WellPointedCompo`WellPointedId))+coOffsetForm f = f++pattern PreSubtract c f <- (coOffsetForm -> Id:&&&Const c :>>> Subtract :>>> f)++preSubtract :: ( MetricScalar s, WithField s AffineManifold d+                               , WithField s AffineManifold c )+               => c -> Affine s (Diff c) d -> Affine s c d+-- The specialised clauses may not actually be useful here.+preSubtract _ (Const d) = const d+preSubtract _ Terminal = Terminal+preSubtract c (f:>>>g) = preSubtract c f >>>! g+-- preSubtract t (f:***g) | (c,d)<-t = preSubtract c f *** preSubtract d g+preSubtract c (f:&&&g) = preSubtract c f &&& preSubtract c g+preSubtract c f = id&&&const c >>>! Subtract >>>! f+   +pattern PostAdd c f <- f:&&&Const c :>>> AddTo+pattern PostAdd' c f <- Const c:&&&f :>>> AddTo++postAdd :: (MetricScalar s, WithField s AffineManifold d, WithField s AffineManifold c)+               => Diff d -> Affine s c d -> Affine s c d+postAdd c f = f&&&const c >>>! AddTo+postAdd' :: (MetricScalar s, WithField s AffineManifold d, WithField s AffineManifold c)+               => d -> Affine s c (Diff d) -> Affine s c d+postAdd' c f = const c&&&f >>>! AddTo++instance (MetricScalar s) => EnhancedCat (->) (Affine s) where+  arr f = fst . toOffset'Slope f++instance (MetricScalar s) => EnhancedCat (Affine s) (ReWellPointed (Affine s)) where+  arr (Specific c) = c+  arr c = ReAffine c++instance (MetricScalar s, WithField s AffineManifold d, WithField s AffineManifold c)+                  => AffineSpace (Affine s d c) where+  type Diff (Affine s d c) = Affine s d (Diff c)+  +  ScaleWith q .-. ScaleWith r = ScaleWith $ q^-^r+  (PostAdd c (ScaleWith q)) .-. g = let (d, r) = toOffsetSlope g+                                    in postAdd (c.-.d) $ ScaleWith (q^-^r)+  f .-. (PostAdd d (ScaleWith r)) = let (c, q) = toOffsetSlope f+                                    in postAdd (c.-.d) $ ScaleWith (q^-^r)+  (PostAdd' c (ScaleWith q)) .-. g = let (d, r) = toOffsetSlope g+                                     in postAdd (c.-.d) $ ScaleWith (q^-^r)+  f .-. (PostAdd' d (ScaleWith r)) = let (c, q) = toOffsetSlope f+                                     in postAdd (c.-.d) $ ScaleWith (q^-^r)+  +  Id .-. Id = const zeroV+  Fst .-. Fst = const zeroV+  Snd .-. Snd = const zeroV+  Swap .-. Swap = const zeroV+  AttachUnit .-. AttachUnit = const zeroV+  DetachUnit .-. DetachUnit = const zeroV+  Terminal .-. _ = Terminal+  _ .-. Terminal = Terminal+  Subtract .-. Subtract = const zeroV+  AddTo .-. AddTo = const zeroV+  +  Const c .-. Const d = Const $ c.-.d+  +  Fst .-. Snd = Subtract++  (f:***g) .-. (h:***i) = f.-.h *** g.-.i+  (f:***g) .-. Const (c,d) = f.-.const c *** g.-.const d+  ζ .-. (f:***g) | Const (c,d) <- ζ = const c.-.f *** const d.-.g+  (f:&&&g) .-. (h:&&&i) = f.-.h &&& g.-.i+  (f:&&&_) .-. AttachUnit = f.-.id >>>! AttachUnit+  (f:&&&g) .-. Const (c,d) = f.-.const c &&& g.-.const d+  ζ .-. (f:&&&g) | Const (c,d) <- ζ = const c.-.f &&& const d.-.g++  ScaleWith q .-. f = let (c, r) = toOffset'Slope f zeroV+                      in postAdd (negateV c) $ ScaleWith (q^-^r)+  f .-. ScaleWith q = let (c, r) = toOffset'Slope f zeroV+                      in postAdd c $ ScaleWith (r^-^q)+  +  PreSubtract b f .-. g = let (c, q) = toOffsetSlope f+                              (d, r) = toOffset'Slope g b+                          in preSubtract b . postAdd (c.-.d) $ ScaleWith (q^-^r)+      -- f x = q·x + c+      -- g x = r·x + w+      -- d = r·b + w+      -- (q−r)·(x−b) = q·x − q⋅b − r⋅x + r⋅b+      -- s x = f (x−b) − g x+      --     = q⋅(x−b) + c − r⋅x − w+      --     = q⋅x − q⋅b + c − r⋅x − w+      --     = (q−r)·(x−b) + c − r⋅b − w+      --     = (q−r)·(x−b) + c − d+  +  -- According to GHC, this clause overlaps with the above. Hm...+  f .-. PreSubtract b g = let (c, q) = toOffset'Slope f b+                              (d, r) = toOffsetSlope g+                          in preSubtract b $ postAdd (c.-.d) $ ScaleWith (q^-^r)+      -- f x = q·x + v+      -- g x = r·x + d+      -- c = q·b + v+      -- (q−r)·(x−b) = q·x − q⋅b − r⋅x + r⋅b+      -- s x = f x − g (x−b)+      --     = q⋅x + v − r⋅(x−b) − d+      --     = q⋅x + v − r⋅x + r⋅b − d+      --     = (q−r)·(x−b) + q⋅b + v − d+      --     = (q−r)·(x−b) + c − d+  +  f .-. g = f&&&g >>> Subtract+  +  +  ScaleWith q .+^ ScaleWith r = ScaleWith $ q^+^r+  (PostAdd c (ScaleWith q)) .+^ g = let (d, r) = toOffsetSlope g+                                    in postAdd (c.+^d) $ ScaleWith (q^+^r)+  f .+^ (PostAdd d (ScaleWith r)) = let (c, q) = toOffsetSlope f+                                    in postAdd' (c.+^d) $ ScaleWith (q^+^r)+  (PostAdd' c (ScaleWith q)) .+^ g = let (d, r) = toOffsetSlope g+                                     in postAdd' (c.+^d) $ ScaleWith (q^+^r)+  f .+^ (PostAdd' d (ScaleWith r)) = let (c, q) = toOffsetSlope f+                                     in postAdd' (c.+^d) $ ScaleWith (q^+^r)+  (f:***g) .+^ (h:***i) = f.+^h *** g.+^i+  (f:&&&g) .+^ (h:&&&i) = f.+^h &&& g.+^i+  +  Const c .+^ Const c' = const (c.+^c')++  Terminal .+^ _ = Terminal+  Const c .+^ Terminal = Const c+  Const c .+^ f = const c&&&f >>> AddTo+  +  Id .+^ Id = Id >>> ScaleWith (linear (^*2))+  Fst .+^ Fst = Fst >>> ScaleWith (linear (^*2))+  Snd .+^ Snd = Snd >>> ScaleWith (linear (^*2))+  Fst .+^ Snd = AddTo+  Swap .+^ Swap = Swap >>> ScaleWith (linear (^*2))+  +  f .+^ Id = let (c,q) = toOffset'Slope f zeroV+             in const c&&&ScaleWith (q^+^idL) >>>! AddTo+  f .+^ AttachUnit = let (c,q) = toOffset'Slope f zeroV+                     in postAdd' c $ ScaleWith (q^+^linear(,Origin))+  f .+^ DetachUnit = let (c,q) = toOffset'Slope f zeroV+                     in postAdd' c $ ScaleWith (q^+^linear fst)+  f .+^ Swap = let (c,q) = toOffset'Slope f zeroV+               in postAdd' c $ ScaleWith (q^+^linear swap)+  +  PreSubtract b f .+^ g = let (c, q) = toOffsetSlope f+                              (d, r) = toOffset'Slope g b+                          in preSubtract b . postAdd' (c.+^d) $ ScaleWith (q^+^r)+      -- f x = q·x + c+      -- g x = r·x + w+      -- d = r·b + w+      -- (q+r)·(x−b) = q·x − q⋅b + r⋅x − r⋅b+      -- s x = f (x−b) + g x+      --     = q⋅(x−b) + c + r⋅x + w+      --     = q⋅x − q⋅b + c + r⋅x + w+      --     = (q+r)·(x−b) + c + r⋅b + w+      --     = (q−r)·(x−b) + c + d+  +  f .+^ PreSubtract b g = let (c, q) = toOffset'Slope f b+                              (d, r) = toOffsetSlope g+                          in preSubtract b . postAdd' (c.+^d) $ ScaleWith (q^+^r)+      -- f x = q·x + v+      -- g x = r·x + d+      -- c = q·b + v+      -- (q+r)·(x−b) = q·x − q⋅b + r⋅x − r⋅b+      -- s x = f x + g (x−b)+      --     = q⋅x + v + r⋅(x−b) + d+      --     = q⋅x + v + r⋅x − r⋅b + d+      --     = (q+r)·(x−b) + q⋅b + v + d+      --     = (q+r)·(x−b) + c + d+  +  f .+^ g = f&&&g >>> AddTo++++instance (MetricScalar s, WithField s AffineManifold d, WithField s LinearManifold c)+                  => AdditiveGroup (Affine s d c) where+  zeroV = const zeroV+  +  negateV (Const c) = const $ negateV c+  negateV Terminal = Terminal+  negateV (ScaleWith ϕ) = ScaleWith $ negateV ϕ+  negateV (f:***g) = negateV f *** negateV g+  negateV (f:&&&g) = negateV f &&& negateV g+  negateV (f:>>>AddTo) = negateV f >>> AddTo+  negateV (f:>>>Subtract) = (f>>>swap) >>>! Subtract+  negateV (f:>>>ScaleWith ϕ) = negateV f >>>! ScaleWith ϕ+  negateV (f:>>>g) = f >>>! negateV g+  negateV AttachUnit = ScaleWith $ linear (negateV >>> (,Origin))+  negateV Subtract = Swap >>>! Subtract+  negateV f = f >>>! ScaleWith (linear negateV)+  +  (^+^) = (.+^)+  (^-^) = (.-.)+  ++infixr 1 >>>!, <<<!+-- | Affine composition using only the reified skeleton, without trying to be+--   clever in any way.+(>>>!) :: ( MetricScalar s, WithField s AffineManifold α+          , WithField s AffineManifold β, WithField s AffineManifold γ )+      => Affine s α β -> Affine s β γ -> Affine s α γ+ReAffine f >>>! ReAffine g = ReAffine $ f >>> g+f >>>! ReAffine g = ReAffine $ ReWellPointed f >>> g+ReAffine f >>>! g = ReAffine $ f >>> ReWellPointed g+f >>>! g = ReAffine $ ReWellPointed f >>> ReWellPointed g++(<<<!) :: ( MetricScalar s, WithField s AffineManifold α+          , WithField s AffineManifold β, WithField s AffineManifold γ )+      => Affine s β γ -> Affine s α β -> Affine s α γ+(<<<!) = flip (>>>!)++instance (MetricScalar s) => Category (Affine s) where+  type Object (Affine s) o = WithField s AffineManifold o+  +  id = ReAffine id+  +  ScaleWith ϕ . ScaleWith ψ = ScaleWith $ ϕ*.*ψ+  g . ScaleWith ψ = let (d, ϕ) = toOffsetSlope g+                    in postAdd' d $ ScaleWith (ϕ*.*ψ)+  (f:***g) . (h:***i) = f.h *** g.i+  (f:***g) . (h:&&&i) = f.h &&& g.i+  g . (PostAdd' c f) = let (d, ϕ) = toOffset'Slope g c+                      in postAdd' d $ ScaleWith ϕ . f+  +  f . g = f <<<! g+ 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'+  swap = ReAffine swap+  attachUnit = ReAffine attachUnit+  detachUnit = ReAffine detachUnit+  regroup = ReAffine regroup+  regroup' = ReAffine 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)+  Const c *** Const c' = const (c,c')+  Terminal *** Terminal = const (mempty, mempty)+  ReAffine f *** ReAffine g = ReAffine $ f *** g+  f *** ReAffine g = ReAffine $ ReWellPointed f *** g+  ReAffine f *** g = ReAffine $ f *** ReWellPointed g+  f *** g = ReAffine $ ReWellPointed f *** ReWellPointed g  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)+  terminal = ReAffine terminal+  fst = ReAffine fst+  snd = ReAffine snd+  Const c &&& Const c' = const (c,c')+  Terminal &&& Terminal = const (mempty, mempty)+  ReAffine f &&& ReAffine g = ReAffine $ f &&& g+  f &&& ReAffine g = ReAffine $ ReWellPointed f &&& g+  ReAffine f &&& g = ReAffine $ f &&& ReWellPointed g+  f &&& g = ReAffine $ ReWellPointed f &&& ReWellPointed g+        +--   Affine cof aof slf &&& Affine cog aog slg+--       = Affine coh (aof.-^lapply slf rco, aog.+^lapply slg rco)+--                  (linear $ lapply slf &&& lapply slg)+--    where rco = (cog.-.cof)^/2+--          coh = cof .+^ rco  instance (MetricScalar s) => WellPointed (Affine s) where   unit = Tagged Origin-  globalElement x = Affine zeroV x zeroV-  const x = Affine zeroV x zeroV+  const = ReAffine . const  +linearAffine :: (MetricScalar s, WithField s LinearManifold α, WithField s LinearManifold β)+            => (α:-*β) -> Affine s α β+linearAffine = ScaleWith + type AffinFuncValue s = GenericAgent (Affine s)  instance (MetricScalar s) => HasAgent (Affine s) where@@ -127,11 +422,9 @@  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)+  zeroV = GenericAgent zeroV+  GenericAgent f ^+^ GenericAgent g = GenericAgent $ f ^+^ g+  negateV (GenericAgent f) = GenericAgent $ negateV f   
Data/Function/Differentiable.hs view
@@ -55,10 +55,12 @@ import Data.Maybe import Data.Semigroup import Data.Function (on)+import Data.Embedding import Data.Fixed  import Data.VectorSpace import Data.LinearMap+import Data.LinearMap.Category import Data.LinearMap.HerMetric import Data.MemoTrie (HasTrie(..)) import Data.AffineSpace@@ -240,7 +242,8 @@                   = (map (id&&&ivimg) domsL, map (id&&&ivimg) domsR)  where (domsL, domsR) = continuityRanges nLim mx f        ivimg (xl,xr) = go xl 1 i₀ ∪ go xr (-1) i₀-        where (_, Option (Just fdd@(Differentiable fddd))) = fd xc+        where (_, Option (Just fdd@(Differentiable fddd)))+                    = second (fmap genericiseDifferentiable) $ fd xc               xc = (xl+xr)/2               i₀ = minimum&&&maximum $ [fdd$xl, fdd$xc, fdd$xr]               go x dir (a,b)@@ -306,8 +309,9 @@  genericiseDifferentiable :: (LocallyScalable s d, LocallyScalable s c)                     => Differentiable s d c -> Differentiable s d c-genericiseDifferentiable (AffinDiffable (Affine x₀ y₀ f))-     = Differentiable $ \x -> (y₀ .+^ lapply f (x.-.x₀), f, const zeroV)+genericiseDifferentiable (AffinDiffable _ af)+     = Differentiable $ \x -> let (y₀, ϕ) = toOffset'Slope af x+                              in (y₀, ϕ, const zeroV) genericiseDifferentiable f = f  @@ -316,21 +320,23 @@   id = Differentiable $ \x -> (x, idL, const zeroV)   Differentiable f . Differentiable g = Differentiable $      \x -> let (y, g', devg) = g x+               jg = convertLinear $->$ g'                (z, f', devf) = f y-               devfg δz = let δy = transformMetric f' δz+               jf = convertLinear $->$ f'+               devfg δz = let δy = transformMetric jf δz                               εy = devf δz-                          in transformMetric g' εy ^+^ devg δy ^+^ devg εy+                          in transformMetric jg εy ^+^ devg δy ^+^ devg εy            in (z, f'*.*g', devfg)-  AffinDiffable f . AffinDiffable g = AffinDiffable $ f . g+  AffinDiffable ef f . AffinDiffable eg g = AffinDiffable (ef . eg) (f . g)   f . g = genericiseDifferentiable f . genericiseDifferentiable g   -- instance (RealDimension s) => EnhancedCat (Differentiable s) (Affine s) where---   arr (Affine co ao sl) = actuallyAffine (ao .-^ lapply sl co) sl+--   arr (Affine co ao sl) = actuallyAffineEndo (ao .-^ lapply sl co) sl    instance (RealDimension s) => EnhancedCat (->) (Differentiable s) where   arr (Differentiable f) x = let (y,_,_) = f x in y-  arr (AffinDiffable f) x = f $ x+  arr (AffinDiffable _ f) x = f $ x  instance (MetricScalar s) => Cartesian (Differentiable s) where   type UnitObject (Differentiable s) = ZeroDim s@@ -351,14 +357,14 @@    where h (x,y) = ((fx, gy), lPar, devfg)           where (fx, f', devf) = f x                 (gy, g', devg) = g y-                devfg δs = transformMetric lfst δx -                           ^+^ transformMetric lsnd δy-                  where δx = devf $ transformMetric lcofst δs-                        δy = devg $ transformMetric lcosnd δs+                devfg δs = transformMetric fst δx +                           ^+^ transformMetric snd δy+                  where δx = devf $ transformMetric (id&&&zeroV) δs+                        δy = devg $ transformMetric (zeroV&&&id) δs                 lPar = linear $ lapply f'***lapply g'-         lfst = linear fst; lsnd = linear snd-         lcofst = linear (,zeroV); lcosnd = linear (zeroV,)-  AffinDiffable f *** AffinDiffable g = AffinDiffable $ f *** g+  AffinDiffable IsDiffableEndo f *** AffinDiffable IsDiffableEndo g+         = AffinDiffable IsDiffableEndo $ f *** g+  AffinDiffable _ f *** AffinDiffable _ g = AffinDiffable NotDiffableEndo $ f *** g   f *** g = genericiseDifferentiable f *** genericiseDifferentiable g  @@ -372,10 +378,9 @@    where h x = ((fx, gx), lFanout, devfg)           where (fx, f', devf) = f x                 (gx, g', devg) = g x-                devfg δs = (devf $ transformMetric lcofst δs)-                           ^+^ (devg $ transformMetric lcosnd δs)+                devfg δs = (devf $ transformMetric (id&&&zeroV) δs)+                           ^+^ (devg $ transformMetric (zeroV&&&id) δs)                 lFanout = linear $ lapply f'&&&lapply g'-         lcofst = linear (,zeroV); lcosnd = linear (zeroV,)   f &&& g = genericiseDifferentiable f &&& genericiseDifferentiable g  @@ -401,16 +406,22 @@   -actuallyLinear :: ( WithField s LinearManifold x, WithField s LinearManifold y, x~y )+actuallyLinearEndo :: WithField s LinearManifold x+            => (x:-*x) -> Differentiable s x x+actuallyLinearEndo = AffinDiffable IsDiffableEndo . linearAffine++actuallyAffineEndo :: WithField s LinearManifold x+            => x -> (x:-*x) -> Differentiable s x x+actuallyAffineEndo y₀ f = AffinDiffable IsDiffableEndo $ const y₀ .+^ linearAffine f++actuallyLinear :: ( WithField s LinearManifold x, WithField s LinearManifold y )             => (x:-*y) -> Differentiable s x y-actuallyLinear f = actuallyAffine zeroV f+actuallyLinear = AffinDiffable NotDiffableEndo . linearAffine  actuallyAffine :: ( WithField s LinearManifold x-                  , WithField s LinearManifold y -- Really, this should only need `AffineManifold`.-                  , x~y-                  )+                  , WithField s AffineManifold y )             => y -> (x:-*Diff y) -> Differentiable s x y-actuallyAffine y₀ f = AffinDiffable $ Affine zeroV y₀ f+actuallyAffine y₀ f = AffinDiffable NotDiffableEndo $ const y₀ .+^ linearAffine f   -- affinPoint :: (WithField s LinearManifold c, WithField s LinearManifold d)@@ -435,20 +446,21 @@                       (GenericAgent (Differentiable g))      = GenericAgent . Differentiable $         \d -> let (c', f', devf) = f d+                  jf = convertLinear$->$f'                   (c'', g', devg) = g d+                  jg = convertLinear$->$g'                   (c, h', devh) = cmb c' c''-                  h'l = h' *.* lcofst; h'r = h' *.* lcosnd+                  jh = convertLinear$->$h'+                  jhl = jh . (id&&&zeroV); jhr = jh . (zeroV&&&id)               in ( c                  , h' *.* linear (lapply f' &&& lapply g')-                 , \εc -> let εc' = transformMetric h'l εc-                              εc'' = transformMetric h'r εc+                 , \εc -> let εc' = transformMetric jhl εc+                              εc'' = transformMetric jhr εc                               (δc',δc'') = devh εc                            in devf εc' ^+^ devg εc''-                               ^+^ transformMetric f' δc'-                               ^+^ transformMetric g' δc''+                               ^+^ transformMetric jf δc'+                               ^+^ transformMetric jg δc''                  )- where lcofst = linear(,zeroV)-       lcosnd = linear(zeroV,)  dfblFnValsCombine cmb (GenericAgent fa) (GenericAgent ga)           = dfblFnValsCombine cmb (GenericAgent $ genericiseDifferentiable fa)                                  (GenericAgent $ genericiseDifferentiable ga)@@ -460,14 +472,12 @@ instance (WithField s LinearManifold v, LocallyScalable s a, Floating s)     => AdditiveGroup (DfblFuncValue s a v) where   zeroV = point zeroV-  GenericAgent (AffinDiffable f) ^+^ GenericAgent (AffinDiffable g)-       = let (GenericAgent h) = GenericAgent f ^+^ GenericAgent g-         in GenericAgent $ AffinDiffable h+  GenericAgent (AffinDiffable ef f) ^+^ GenericAgent (AffinDiffable eg g)+         = GenericAgent $ AffinDiffable (ef<>eg) (f^+^g)   α^+^β = dfblFnValsCombine (\a b -> (a^+^b, lPlus, const zeroV)) α β       where lPlus = linear $ uncurry (^+^)-  negateV (GenericAgent (AffinDiffable f))-       = let (GenericAgent h) = negateV $ GenericAgent f-         in GenericAgent $ AffinDiffable h+  negateV (GenericAgent (AffinDiffable ef f))+         = GenericAgent $ AffinDiffable ef (negateV f)   negateV α = dfblFnValsFunc (\a -> (negateV a, lNegate, const zeroV)) α       where lNegate = linear negateV   @@ -527,7 +537,7 @@                                ^+^ transformMetric δj d )         where (fx, jf, devf) = f x               (gx, jg, devg) = g x-              δj = jf ^-^ jg+              δj = convertLinear $->$ jf ^-^ jg   postEndo :: ∀ c a b . (HasAgent c, Object c a, Object c b)@@ -620,7 +630,7 @@               xp1² = xp1 ^ 2 negativePreRegion' = PreRegion $ ppr . ngt  where PreRegion ppr = positivePreRegion'-       ngt = actuallyLinear $ linear negate+       ngt = actuallyLinearEndo $ linear negate  preRegionToInfFrom, preRegionFromMinInfTo :: RealDimension s => s -> PreRegion s s preRegionToInfFrom = RealSubray PositiveHalfSphere@@ -629,10 +639,10 @@ preRegionToInfFrom', preRegionFromMinInfTo' :: RealDimension s => s -> PreRegion s s preRegionToInfFrom' xs = PreRegion $ ppr . trl  where PreRegion ppr = positivePreRegion'-       trl = actuallyAffine (-xs) idL+       trl = actuallyAffineEndo (-xs) idL preRegionFromMinInfTo' xe = PreRegion $ ppr . flp  where PreRegion ppr = positivePreRegion'-       flp = actuallyAffine xe (linear negate)+       flp = actuallyAffineEndo xe (linear negate)  intervalPreRegion :: RealDimension s => (s,s) -> PreRegion s s intervalPreRegion (lb,rb) = PreRegion $ Differentiable prr@@ -656,28 +666,29 @@   id = RWDiffable $ \x -> (GlobalRegion, pure id)   RWDiffable f . RWDiffable g = RWDiffable h where    h x₀ = case g x₀ of-           ( rg, Option (Just gr'@(AffinDiffable gr@(Affine cog aog slg))) )-            -> let y₀ = gr $ x₀+           ( rg, Option (Just gr'@(AffinDiffable IsDiffableEndo gr)) )+            -> let (y₀, ϕg) = toOffset'Slope gr x₀                in case f y₀ of-                   (GlobalRegion, Option (Just (AffinDiffable fr)))-                         -> (rg, Option (Just (AffinDiffable (fr.gr))))+                   (GlobalRegion, Option (Just (AffinDiffable fe fr)))+                         -> (rg, Option (Just (AffinDiffable fe (fr.gr))))                    (GlobalRegion, fhr)                          -> (rg, fmap (. gr') fhr)                    (RealSubray diry yl, fhr)                       -> let hhr = fmap (. gr') fhr-                         in case lapply slg 1 of+                         in case lapply ϕg 1 of                               y' | y'>0 -> ( unsafePreRegionIntersect rg-                                                  $ RealSubray diry (cog + (yl-aog)/y')-                                   -- aog + y' * (xl − cog) = yl-                                   -- xl = cog + (yl − aog)/y'+                                                  $ RealSubray diry (x₀ + (yl-y₀)/y')+                                   -- y'⋅(xl−x₀) + y₀ ≝ yl                                            , hhr )                                  | y'<0 -> ( unsafePreRegionIntersect rg                                                   $ RealSubray (otherHalfSphere diry)-                                                               (cog + (yl-aog)/y')+                                                               (x₀ + (yl-y₀)/y')                                            , hhr )                                  | otherwise -> (rg, hhr)                    (PreRegion ry, fhr)                          -> ( PreRegion $ ry . gr', fmap (. gr') fhr )+           ( rg, Option (Just gr'@(AffinDiffable _ gr)) )+            -> error "( rg, Option (Just gr'@(AffinDiffable gr)) )"            (GlobalRegion, Option (Just gr@(Differentiable grd)))             -> let (y₀,_,_) = grd x₀                in case f y₀ of@@ -717,6 +728,7 @@                          -> ( PreRegion $ minDblfuncs (ry . gr) rx                             , notDefinedHere )                    (r, Option (Just fr)) | PreRegion ry <- genericisePreRegion r+                          -> ( PreRegion $ minDblfuncs (ry . gr) rx                             , pure (fr . gr) )            (r, Option Nothing)@@ -816,21 +828,22 @@                       (Option(Just(Differentiable f)), Option(Just(Differentiable g))) ->                         pure . Differentiable $ \d                          -> let (c', f', devf) = f d+                                jf = convertLinear $->$ f'                                 (c'',g', devg) = g d+                                jg = convertLinear $->$ g'                                 (c, h', devh) = cmb c' c''-                                h'l = h' *.* lcofst; h'r = h' *.* lcosnd+                                jh = convertLinear $->$ h'+                                jhl = jh . (id&&&zeroV); jhr = jh . (zeroV&&&id)                             in ( c                                , h' *.* linear (lapply f' &&& lapply g')-                               , \εc -> let εc' = transformMetric h'l εc-                                            εc'' = transformMetric h'r εc+                               , \εc -> let εc' = transformMetric jhl εc+                                            εc'' = transformMetric jhr εc                                             (δc',δc'') = devh εc                                          in devf εc' ^+^ devg εc''-                                             ^+^ transformMetric f' δc'-                                             ^+^ transformMetric g' δc''+                                             ^+^ transformMetric jf δc'+                                             ^+^ transformMetric jg δc''                                )                       _ -> notDefinedHere- where lcofst = linear(,zeroV)-       lcosnd = linear(zeroV,)  grwDfblFnValsCombine cmb fv gv         = grwDfblFnValsCombine cmb (genericiseRWDFV fv) (genericiseRWDFV gv) @@ -849,18 +862,18 @@                  where hd x = (fx^+^gx, jf^+^jg, \ε -> δf(ε^*4) ^+^ δg(ε^*4))                         where (fx, jf, δf) = fd x                               (gx, jg, δg) = gd x-                fgplus (Differentiable fd) (AffinDiffable ga@(Affine cog aog slg))+                fgplus (Differentiable fd) (AffinDiffable _ ga)                                  = Differentiable hd-                 where hd x = (fx^+^gx, jf^+^slg, δf)+                 where hd x = (fx^+^gx, jf^+^ϕg, δf)                         where (fx, jf, δf) = fd x-                              gx = ga $ x-                fgplus (AffinDiffable fa@(Affine cof aof slf)) (Differentiable gd)+                              (gx, ϕg) = toOffset'Slope ga x+                fgplus (AffinDiffable _ fa) (Differentiable gd)                                  = Differentiable hd-                 where hd x = (fx^+^gx, slf^+^jg, δg)+                 where hd x = (fx^+^gx, ϕf^+^jg, δg)                         where (gx, jg, δg) = gd x-                              fx = fa $ x-                fgplus (AffinDiffable fa) (AffinDiffable ga) = AffinDiffable ha-                 where (GenericAgent ha) = GenericAgent fa ^+^ GenericAgent ga+                              (fx, ϕf) = toOffset'Slope fa x+                fgplus (AffinDiffable fe fa) (AffinDiffable ge ga)+                           = AffinDiffable (fe<>ge) (fa^+^ga)  rwDfbl_negateV :: ∀ s a v .         ( WithField s EuclidSpace v, AdditiveGroup v, v ~ Needle (Interior (Needle v))@@ -873,8 +886,7 @@                 fneg (Differentiable fd) = Differentiable hd                  where hd x = (negateV fx, negateV jf, δf)                         where (fx, jf, δf) = fd x-                fneg (AffinDiffable (Affine cof aof slf))-                        = AffinDiffable $ Affine (negateV cof) (negateV aof) (negateV slf)+                fneg (AffinDiffable ef af) = AffinDiffable ef $ negateV af  postCompRW :: ( RealDimension s               , LocallyScalable s a, LocallyScalable s b, LocallyScalable s c )@@ -891,16 +903,17 @@   zeroV = point zeroV   ConstRWDFV c₁ ^+^ ConstRWDFV c₂ = ConstRWDFV (c₁^+^c₂)   ConstRWDFV c₁ ^+^ RWDFV_IdVar = GenericRWDFV $-                               globalDiffable' (actuallyAffine c₁ idL)+                               globalDiffable' (actuallyAffineEndo c₁ idL)   RWDFV_IdVar ^+^ ConstRWDFV c₂ = GenericRWDFV $-                               globalDiffable' (actuallyAffine c₂ idL)+                               globalDiffable' (actuallyAffineEndo c₂ idL)   ConstRWDFV c₁ ^+^ GenericRWDFV g = GenericRWDFV $-                               globalDiffable' (actuallyAffine c₁ idL) . g+                               globalDiffable' (actuallyAffineEndo c₁ idL) . g   GenericRWDFV f ^+^ ConstRWDFV c₂ = GenericRWDFV $-                                  globalDiffable' (actuallyAffine c₂ idL) . f-  GenericRWDFV f ^+^ GenericRWDFV g = GenericRWDFV $ rwDfbl_plus f g+                                  globalDiffable' (actuallyAffineEndo c₂ idL) . f+  fa^+^ga | GenericRWDFV f <- genericiseRWDFV fa+          , GenericRWDFV g <- genericiseRWDFV ga = GenericRWDFV $ rwDfbl_plus f g   negateV (ConstRWDFV c) = ConstRWDFV (negateV c)-  negateV RWDFV_IdVar = GenericRWDFV $ globalDiffable' (actuallyLinear $ linear negateV)+  negateV RWDFV_IdVar = GenericRWDFV $ globalDiffable' (actuallyLinearEndo $ linear negateV)   negateV (GenericRWDFV f) = GenericRWDFV $ rwDfbl_negateV f  instance (RealDimension n, LocallyScalable n a)@@ -909,13 +922,13 @@   (+) = (^+^)   ConstRWDFV c₁ * ConstRWDFV c₂ = ConstRWDFV (c₁*c₂)   ConstRWDFV c₁ * RWDFV_IdVar = GenericRWDFV $-                               globalDiffable' (actuallyLinear $ linear (c₁*))+                               globalDiffable' (actuallyLinearEndo $ linear (c₁*))   RWDFV_IdVar * ConstRWDFV c₂ = GenericRWDFV $-                               globalDiffable' (actuallyLinear $ linear (*c₂))+                               globalDiffable' (actuallyLinearEndo $ linear (*c₂))   ConstRWDFV c₁ * GenericRWDFV g = GenericRWDFV $-                               globalDiffable' (actuallyLinear $ linear (c₁*)) . g+                               globalDiffable' (actuallyLinearEndo $ linear (c₁*)) . g   GenericRWDFV f * ConstRWDFV c₂ = GenericRWDFV $-                                  globalDiffable' (actuallyLinear $ linear (*c₂)) . f+                                  globalDiffable' (actuallyLinearEndo $ linear (*c₂)) . f   f*g = genericiseRWDFV f ⋅ genericiseRWDFV g    where (⋅) :: ∀ n a . (RealDimension n, LocallyScalable n a)            => RWDfblFuncValue n a n -> RWDfblFuncValue n a n -> RWDfblFuncValue n a n @@ -925,19 +938,26 @@                           (rc₂,gmay) = gpcs d₀                       in (unsafePreRegionIntersect rc₁ rc₂, mulDi <$> fmay <*> gmay)           where mulDi :: Differentiable n a n -> Differentiable n a n -> Differentiable n a n-                mulDi (AffinDiffable f@(Affine _ _ slf)) (AffinDiffable g@(Affine _ _ slg))-                   = let f' = lapply slf 1; g' = lapply slg 1+                mulDi f@(AffinDiffable ef af) g@(AffinDiffable eg ag) = case ef<>eg of+                   IsDiffableEndo ->+                  {- let f' = lapply slf 1; g' = lapply slg 1                      in case f'*g' of-                          0 -> AffinDiffable undefined-                          f'g' -> Differentiable $-                           \d -> let c₁ = f $ d; c₂ = g $ d-                                 in ( c₁*c₂-                                    , linear.(*)$ c₁*g' + c₂*f'-                                    , unsafe_dev_ε_δ "*" $ sqrt . (/f'g') )+                          0 -> AffinDiffableEndo $ const (aof*aog)+                          f'g' -> -} Differentiable $+                           \d -> let (fd,ϕf) = toOffset'Slope af d+                                     (gd,ϕg) = toOffset'Slope ag d+                                     f' = lapply ϕf 1; g' = lapply ϕg 1+                                     invf'g' = recip $ f'*g'+                                 in ( fd*gd+                                    , linear.(*)$ fd*g' + gd*f'+                                    , unsafe_dev_ε_δ "*" $ sqrt . (*invf'g') )+                   _ -> mulDi (genericiseDifferentiable f) (genericiseDifferentiable g)                 mulDi (Differentiable f) (Differentiable g)                    = Differentiable $                        \d -> let (c₁, slf, devf) = f d+                                 jf = convertLinear$->$slf                                  (c₂, slg, devg) = g d+                                 jg = convertLinear$->$slg                                  c = c₁*c₂; c₁² = c₁^2; c₂² = c₂^2                                  h' = c₁*^slg ^+^ c₂*^slf                                  in ( c@@ -945,7 +965,7 @@                                     , \εc -> let rε² = metric εc 1                                                  c₁worst² = c₁² + recip(1 + c₂²*rε²)                                                  c₂worst² = c₂² + recip(1 + c₁²*rε²)-                                             in (4*rε²) *^ dualCoCoProduct slf slg+                                             in (4*rε²) *^ dualCoCoProduct jf jg                                                 ^+^ devf (εc^*(4*c₂worst²))                                                 ^+^ devg (εc^*(4*c₁worst²))                     -- TODO: add formal proof for this (or, if necessary, the correct form)@@ -957,8 +977,8 @@    where absPW a₀           | a₀<0       = (negativePreRegion, pure desc)           | otherwise  = (positivePreRegion, pure asc)-         desc = actuallyLinear $ linear negate-         asc = actuallyLinear idL+         desc = actuallyLinearEndo $ linear negate+         asc = actuallyLinearEndo idL   signum = (RWDiffable sgnPW $~)    where sgnPW a₀           | a₀<0       = (negativePreRegion, pure (const $ -1))@@ -1049,7 +1069,7 @@                     -- Safety margins for overlap between quadratic and cubic model                     -- (these aren't naturally compatible to be used both together)                       -  cos = sin . (globalDiffable' (actuallyAffine (pi/2) idL) $~)+  cos = sin . (globalDiffable' (actuallyAffineEndo (pi/2) idL) $~)      sinh x = (exp x - exp (-x))/2     {- = grwDfblFnValsFunc sinhDfb@@ -1179,7 +1199,7 @@  positiveRegionalId :: RealDimension n => RWDiffable n n n positiveRegionalId = RWDiffable $ \x₀ ->-       if x₀ > 0 then (positivePreRegion, pure . AffinDiffable $ id)+       if x₀ > 0 then (positivePreRegion, pure . AffinDiffable IsDiffableEndo $ id)                  else (negativePreRegion, notDefinedHere)  infixl 5 ?> , ?<@@ -1196,10 +1216,12 @@ (?<) :: (RealDimension n, LocallyScalable n a)            => RWDfblFuncValue n a n -> RWDfblFuncValue n a n -> RWDfblFuncValue n a n ConstRWDFV a ?< RWDFV_IdVar = GenericRWDFV . RWDiffable $-       \x₀ -> if a < x₀ then (preRegionToInfFrom a, pure . AffinDiffable $ id)+       \x₀ -> if a < x₀ then ( preRegionToInfFrom a+                             , pure . AffinDiffable IsDiffableEndo $ id)                         else (preRegionFromMinInfTo a, notDefinedHere) RWDFV_IdVar ?< ConstRWDFV a = GenericRWDFV . RWDiffable $-       \x₀ -> if x₀ < a then (preRegionFromMinInfTo a, pure . AffinDiffable $ const a)+       \x₀ -> if x₀ < a then ( preRegionFromMinInfTo a+                             , pure . AffinDiffable IsDiffableEndo $ const a)                         else (preRegionToInfFrom a, notDefinedHere) a ?< b = (positiveRegionalId $~ b-a) ?-> b @@ -1238,6 +1260,18 @@                 (rf, q@(Option (Just _))) -> (rf, q)                 (rf, Option Nothing) | (rg, q) <- g x₀                         -> (unsafePreRegionIntersect rf rg, q)++++++-- | Like 'Data.VectorSpace.lerp', but gives a differentiable function+--   instead of a Hask one.+lerp_diffable :: (WithField s LinearManifold m, RealDimension s)+      => m -> m -> Differentiable s s m+lerp_diffable a b = actuallyAffine a $ linear (*^(b.-.a))++   
Data/Function/Differentiable/Data.hs view
@@ -12,8 +12,10 @@ import Data.Manifold.Types.Primitive import Data.Manifold.PseudoAffine +import qualified Control.Category.Constrained as CC  + type LinDevPropag d c = Metric c -> Metric d  @@ -38,18 +40,19 @@ --   and actually be sure you get /all/ solutions correctly, not just /some/ that are --   (hopefully) the closest to some reference point you'd need to laborously define! -- ---   Unfortunately however, this also prevents doing any serious algebra etc. with the---   category, because even something as simple as division necessary introduces singularities---   where the derivatives must diverge.---   Not to speak of many trigonometric e.g. trigonometric functions that---   are undefined on whole regions. The 'PWDiffable' and 'RWDiffable' categories have explicit+--   Unfortunately however, this also prevents doing any serious algebra with the+--   category, because even something as simple as division necessary introduces+--   singularities where the derivatives must diverge.+--   Not to speak of many e.g. trigonometric functions that are undefined+--   on whole regions. The 'PWDiffable' and 'RWDiffable' categories have explicit --   handling for those issues built in; you may simply use these categories even when --   you know the result will be smooth in your relevant domain (or must be, for e.g. --   physics reasons). --   ---   &#xb9;(The implementation does not deal with /&#x3b5;/ and /&#x3b4;/ as difference-bounding---   reals, but rather as metric tensors that define a boundary by prohibiting the---   overlap from exceeding one; this makes the concept actually work on general manifolds.)+--   &#xb9;(The implementation does not deal with /&#x3b5;/ and /&#x3b4;/ as+--   difference-bounding reals, but rather as metric tensors which define a+--   boundary by prohibiting the overlap from exceeding one.+--   This makes the category actually work on general manifolds.) data Differentiable s d c where    Differentiable :: ( d -> ( c   -- function value                             , Needle d :-* Needle c -- Jacobian@@ -59,16 +62,26 @@                                                -- some error margin                               ) )                   -> Differentiable s d c-   AffinDiffable :: LinearManifold d-               => Affine s d d -> Differentiable s d d-                      -- This should ideally map between two general affine spaces,-                      -- but since the special case of affine functions is mostly relevant-                      -- to optimise the propagation of real intervals, we don't do that.+   AffinDiffable :: (AffineManifold d, AffineManifold c)+               => DiffableEndoProof d c -> Affine s d c -> Differentiable s d c    +data DiffableEndoProof d c where+  IsDiffableEndo :: DiffableEndoProof d d+  NotDiffableEndo :: DiffableEndoProof d c +instance Semigroup (DiffableEndoProof d c) where+  IsDiffableEndo <> _ = IsDiffableEndo+  _ <> IsDiffableEndo = IsDiffableEndo+  _ <> _ = NotDiffableEndo+  ++instance CC.Category DiffableEndoProof where+  id = IsDiffableEndo+  IsDiffableEndo . IsDiffableEndo = IsDiffableEndo+  _ . _ = NotDiffableEndo   -- | A pathwise connected subset of a manifold @m@, whose tangent space has scalar @s@.
Data/LinearMap/Category.hs view
@@ -35,6 +35,7 @@  import Data.MemoTrie import Data.VectorSpace+import Data.LinearMap import Data.VectorSpace.FiniteDimensional import Data.AffineSpace import Data.Basis@@ -59,12 +60,27 @@       -- | A linear mapping between finite-dimensional spaces, implemeted as a dense matrix.-data Linear s a b = DenseLinear { getDenseMatrix :: HMat.Matrix s }+--  +--   Note that this is equivalent to the tensor product @'DualSpace' a ⊗ b@. One+--   of the types should be deprecated in the future, or either implemented in+--   terms of the other.+newtype Linear s a b = DenseLinear { getDenseMatrix :: HMat.Matrix s }  identMat :: forall v w . FiniteDimensional v => Linear (Scalar v) w v identMat = DenseLinear $ HMat.ident n  where (Tagged n) = dimension :: Tagged v Int +convertLinear :: ∀ v w s . ( FiniteDimensional v, FiniteDimensional w+                           , Scalar v ~ s, Scalar w ~ s )+                   => Isomorphism (->) (v:-*w) (Linear s v w)+convertLinear = Isomorphism (asPackedMatrix >>> DenseLinear)+                            (fromPackedMatrix<<<getDenseMatrix)++denseLinear :: ∀ v w s . (FiniteDimensional v, FiniteDimensional w, Scalar w ~ s)+                   => (v->w) -> Linear s v w+denseLinear f = DenseLinear . HMat.fromColumns $ (asPackedVector . f . basisValue) <$> cbv+ where Tagged cbv = completeBasis :: Tagged v [Basis v]+ instance (SmoothScalar s) => Category (Linear s) where   type Object (Linear s) v = (FiniteDimensional v, Scalar v~s)   id = identMat@@ -118,6 +134,100 @@ instance (SmoothScalar s) => EnhancedCat (->) (Linear s) where   arr (DenseLinear mat) = fromPackedVector . HMat.app mat . asPackedVector +type DenseLinearFuncValue s = GenericAgent (Linear s)++instance (SmoothScalar s) => HasAgent (Linear s) where+  alg = genericAlg+  ($~) = genericAgentMap+instance (SmoothScalar s) => CartesianAgent (Linear s) where+  alg1to2 = genericAlg1to2+  alg2to1 = genericAlg2to1+  alg2to2 = genericAlg2to2+++instance (FiniteDimensional v, Scalar v~s, FiniteDimensional w, Scalar w~s, SmoothScalar s)+                     => AffineSpace (Linear s v w) where+  type Diff (Linear s v w) = Linear s v w+  DenseLinear m.-.DenseLinear n = DenseLinear (m-n)+  DenseLinear m.+^DenseLinear n = DenseLinear (m+n)++instance (FiniteDimensional v, Scalar v~s, FiniteDimensional w, Scalar w~s, SmoothScalar s)+                       => AdditiveGroup (Linear s v w) where+  zeroV = zx+   where zx :: ∀ v w . (FiniteDimensional v, FiniteDimensional w) => Linear s v w+         zx = DenseLinear $ HMat.konst 0 (dw,dv)+          where Tagged dv = dimension :: Tagged v Int+                Tagged dw = dimension :: Tagged w Int+  negateV (DenseLinear m) = DenseLinear $ negate m+  DenseLinear m^+^DenseLinear n = DenseLinear (m+n)+  DenseLinear m^-^DenseLinear n = DenseLinear (m-n)++instance (FiniteDimensional v, Scalar v~s, FiniteDimensional w, Scalar w~s, SmoothScalar s)+             => VectorSpace (Linear s v w) where+  type Scalar (Linear s v w) = s+  μ *^ DenseLinear m = DenseLinear $ HMat.scale μ m++instance (FiniteDimensional v, Scalar v~s, FiniteDimensional w, Scalar w~s, SmoothScalar s)+             => HasBasis (Linear s v w) where+  type Basis (Linear s v w) = (Basis v, Basis w)+  basisValue = bx+   where bx :: ∀ v w . (FiniteDimensional v, FiniteDimensional w)+                          => (Basis v, Basis w)->Linear s v w+         bx = \(bv,bw) -> DenseLinear $ HMat.assoc (dw,dv) 0 [((biw bw, biv bv),1)]+          where Tagged dv = dimension :: Tagged v Int+                Tagged dw = dimension :: Tagged w Int+                Tagged biv = basisIndex :: Tagged v (Basis v->Int)+                Tagged biw = basisIndex :: Tagged w (Basis w->Int)+  decompose = dc+   where dc :: ∀ s v w . ( FiniteDimensional v, Scalar v ~ s+                         , FiniteDimensional w, Scalar w ~ s )+                 => Linear s v w -> [((Basis v, Basis w), s)]+         dc lm = map (id &&& decompose' lm) cb+          where Tagged cb = completeBasis :: Tagged (Linear s v w) [(Basis v, Basis w)]+  decompose' = dc+   where dc :: ∀ s v w . (FiniteDimensional v, FiniteDimensional w, Scalar w ~ s)+               => Linear s v w -> (Basis v, Basis w) -> s+         dc (DenseLinear m) = \(bv,bw) -> m HMat.! biw bw HMat.! biv bv+          where Tagged biv = basisIndex :: Tagged v (Basis v->Int)+                Tagged biw = basisIndex :: Tagged w (Basis w->Int)++instance (FiniteDimensional v, Scalar v ~ s, FiniteDimensional w, Scalar w ~ s)+                => FiniteDimensional (Linear s v w) where+  dimension = d+   where d :: ∀ s v w . (FiniteDimensional v, FiniteDimensional w)+               => Tagged (Linear s v w) Int+         d = Tagged (dv*dw)+          where Tagged dv = dimension::Tagged v Int; Tagged dw = dimension::Tagged w Int+  basisIndex = bi+   where bi :: ∀ s v w . (FiniteDimensional v, FiniteDimensional w)+               => Tagged (Linear s v w) ((Basis v, Basis w) -> Int)+         bi = Tagged $ \(bv,bw) -> dv * biv bv + biw bw where +          Tagged dv=dimension::Tagged v Int; Tagged biv=basisIndex::Tagged v (Basis v->Int)+          Tagged biw = basisIndex :: Tagged w (Basis w -> Int)+  indexBasis = ib+   where ib :: ∀ s v w . (FiniteDimensional v, FiniteDimensional w)+               => Tagged (Linear s v w) (Int -> (Basis v, Basis w))+         ib = Tagged $ (`divMod`dv) >>> \(iv,iw) -> (ibv iv, ibw iw) where+          Tagged dv=dimension::Tagged v Int; Tagged ibv=indexBasis::Tagged v (Int->Basis v)+          Tagged ibw = indexBasis :: Tagged w (Int->Basis w)+  completeBasis = cb+   where cb :: ∀ s v w . (FiniteDimensional v, FiniteDimensional w)+               => Tagged (Linear s v w) [(Basis v, Basis w)]+         cb = Tagged $ liftA2 (,) cbv cbw where+          Tagged cbv = completeBasis :: Tagged v [Basis v]+          Tagged cbw = completeBasis :: Tagged w [Basis w]+  asPackedVector = getDenseMatrix >>> HMat.flatten+  fromPackedVector = fpv+   where fpv :: ∀ s v w . (FiniteDimensional v, Scalar v ~ s, FiniteDimensional w, Scalar w ~ s)+               => HMat.Vector s -> Linear s v w+         fpv = HMat.reshape dv >>> DenseLinear+          where Tagged dv = dimension :: Tagged v Int++instance (FiniteDimensional v, Scalar v ~ s, FiniteDimensional a, Scalar a ~ s)+    => AdditiveGroup (DenseLinearFuncValue s a v) where+  zeroV = GenericAgent zeroV+  GenericAgent f ^+^ GenericAgent g = GenericAgent $ f ^+^ g+  negateV (GenericAgent f) = GenericAgent $ negateV f   
Data/LinearMap/HerMetric.hs view
@@ -9,14 +9,16 @@ {-# LANGUAGE ConstraintKinds            #-} {-# LANGUAGE ScopedTypeVariables        #-} {-# LANGUAGE UnicodeSyntax              #-}+{-# LANGUAGE LambdaCase                 #-}     module Data.LinearMap.HerMetric (   -- * Metric operator types-    HerMetric, HerMetric'+    HerMetric(..), HerMetric'(..)   -- * Evaluating metrics+  , toDualWith, fromDualWith   , metricSq, metricSq', metric, metric', metrics, metrics'   -- * Defining metrics   , projector, projector'@@ -39,6 +41,8 @@   , metriScale', metriScale   , adjoint   , extendMetric+  , applyLinMapMetric, applyLinMapMetric'+  , imitateMetricSpanChange   -- * The dual-space class   , HasMetric   , HasMetric'(..)@@ -99,22 +103,22 @@ --   Yet other possible interpretations of this type include /density matrix/ (as in --   quantum mechanics), /standard range of statistical fluctuations/, and /volume element/. newtype HerMetric v = HerMetric {-   -- morally:  @getHerMetric :: v :-* DualSpace v@.-          metricMatrix :: Maybe (HMat.Matrix (Scalar v)) -- @Nothing@ for zero metric.+          metricMatrix :: Maybe (Linear (Scalar v) v (DualSpace v)) -- @Nothing@ for zero metric.                       }  matrixMetric :: HasMetric v => HMat.Matrix (Scalar v) -> HerMetric v-matrixMetric = HerMetric . Just+matrixMetric = HerMetric . Just . DenseLinear +-- | Deprecated (this doesn't preserve positive-definiteness) instance (HasMetric v) => AdditiveGroup (HerMetric v) where   zeroV = HerMetric Nothing-  negateV (HerMetric m) = HerMetric $ negate <$> m+  negateV (HerMetric m) = HerMetric $ negateV <$> m   HerMetric Nothing ^+^ HerMetric n = HerMetric n   HerMetric m ^+^ HerMetric Nothing = HerMetric m-  HerMetric (Just m) ^+^ HerMetric (Just n) = HerMetric . Just $ m + n+  HerMetric (Just m) ^+^ HerMetric (Just n) = HerMetric . Just $ m ^+^ n instance HasMetric v => VectorSpace (HerMetric v) where   type Scalar (HerMetric v) = Scalar v-  s *^ (HerMetric m) = HerMetric $ HMat.scale s <$> m +  s *^ (HerMetric m) = HerMetric $ (s*^) <$> m   -- | A metric on the dual space; equivalent to a linear mapping from the dual space --   to the original vector space.@@ -122,15 +126,15 @@ --   Prime-versions of the functions in this module target those dual-space metrics, so --   we can avoid some explicit handling of double-dual spaces. newtype HerMetric' v = HerMetric' {-          metricMatrix' :: Maybe (HMat.Matrix (Scalar v))+          metricMatrix' :: Maybe (Linear (Scalar v) (DualSpace v) v)                       }  extendMetric :: (HasMetric v, Scalar v~ℝ) => HerMetric v -> v -> HerMetric v extendMetric (HerMetric Nothing) _ = HerMetric Nothing-extendMetric (HerMetric (Just m)) v-      | isInfinite' detm  = HerMetric $ Just m+extendMetric (HerMetric (Just (DenseLinear m))) v+      | isInfinite' detm  = HerMetric . Just $ DenseLinear m       | isInfinite' detmninv  = singularMetric-      | otherwise         = HerMetric $ Just mn+      | otherwise         = HerMetric . Just $ DenseLinear mn  where -- this could probably be done much more efficiently, with only        -- multiplications, no inverses.        (minv, (detm, _)) = HMat.invlndet m@@ -139,17 +143,18 @@                                 matrixMetric' :: HasMetric v => HMat.Matrix (Scalar v) -> HerMetric' v-matrixMetric' = HerMetric' . Just+matrixMetric' = HerMetric' . Just . DenseLinear +-- | Deprecated instance (HasMetric v) => AdditiveGroup (HerMetric' v) where   zeroV = HerMetric' Nothing-  negateV (HerMetric' m) = HerMetric' $ negate <$> m+  negateV (HerMetric' m) = HerMetric' $ negateV <$> m   HerMetric' Nothing ^+^ HerMetric' n = HerMetric' n   HerMetric' m ^+^ HerMetric' Nothing = HerMetric' m-  HerMetric' (Just m) ^+^ HerMetric' (Just n) = matrixMetric' $ m + n+  HerMetric' (Just m) ^+^ HerMetric' (Just n) = HerMetric' . Just $ m ^+^ n instance HasMetric v => VectorSpace (HerMetric' v) where   type Scalar (HerMetric' v) = Scalar v-  s *^ (HerMetric' m) = HerMetric' $ HMat.scale s <$> m +  s *^ (HerMetric' m) = HerMetric' $ (s*^) <$> m        -- | A metric on @v@ that simply yields the squared overlap of a vector with the@@ -183,13 +188,13 @@ --   this will be simply 'magnitudeSq'. metricSq :: HasMetric v => HerMetric v -> v -> Scalar v metricSq (HerMetric Nothing) _ = 0-metricSq (HerMetric (Just m)) v = vDecomp `HMat.dot` HMat.app m vDecomp+metricSq (HerMetric (Just (DenseLinear m))) v = vDecomp `HMat.dot` HMat.app m vDecomp  where vDecomp = asPackedVector v   metricSq' :: HasMetric v => HerMetric' v -> DualSpace v -> Scalar v metricSq' (HerMetric' Nothing) _ = 0-metricSq' (HerMetric' (Just m)) u = uDecomp `HMat.dot` HMat.app m uDecomp+metricSq' (HerMetric' (Just (DenseLinear m))) u = uDecomp `HMat.dot` HMat.app m uDecomp  where uDecomp = asPackedVector u  -- | Evaluate a vector's &#x201c;magnitude&#x201d; through a metric. This assumes an actual@@ -205,8 +210,12 @@  toDualWith :: HasMetric v => HerMetric v -> v -> DualSpace v toDualWith (HerMetric Nothing) = const zeroV-toDualWith (HerMetric (Just m)) = fromPackedVector . HMat.app m . asPackedVector+toDualWith (HerMetric (Just m)) = (m$) +fromDualWith :: HasMetric v => HerMetric' v -> DualSpace v -> v+fromDualWith (HerMetric' Nothing) = const zeroV+fromDualWith (HerMetric' (Just m)) = (m$)+ -- | Divide a vector by its own norm, according to metric, i.e. normalise it --   or &#x201c;project to the metric's boundary&#x201d;. metriNormalise :: (HasMetric v, Floating (Scalar v)) => HerMetric v -> v -> v@@ -237,31 +246,27 @@ metrics' m vs = sqrt . sum $ metricSq' m <$> vs  -transformMetric :: (HasMetric v, HasMetric w, Scalar v ~ Scalar w)-           => (w :-* v) -> HerMetric v -> HerMetric w+transformMetric :: ∀ s v w . (HasMetric v, HasMetric w, Scalar v~s, Scalar w~s)+           => Linear s w v -> HerMetric v -> HerMetric w transformMetric _ (HerMetric Nothing) = HerMetric Nothing-transformMetric t (HerMetric (Just m)) = matrixMetric $ HMat.tr tmat HMat.<> m HMat.<> tmat- where tmat = asPackedMatrix t+transformMetric t (HerMetric (Just m)) = HerMetric . Just $ adjoint t . m . t -transformMetric' :: ( HasMetric v, HasMetric w, Scalar v ~ Scalar w )-           => (v :-* w) -> HerMetric' v -> HerMetric' w+transformMetric' :: ∀ s v w . (HasMetric v, HasMetric w, Scalar v~s, Scalar w~s)+           => Linear s v w -> HerMetric' v -> HerMetric' w transformMetric' _ (HerMetric' Nothing) = HerMetric' Nothing-transformMetric' t (HerMetric' (Just m))-                      = matrixMetric' $ tmat HMat.<> m HMat.<> HMat.tr tmat- where tmat = asPackedMatrix t+transformMetric' t (HerMetric' (Just m)) = HerMetric' . Just $ t . m . adjoint t  -- | This does something vaguely like  @\\s t -> (s⋅t)²@, --   but without actually requiring an inner product on the covectors. --   Used for calculating the superaffine term of multiplications in --   'Differentiable' categories.-dualCoCoProduct :: (HasMetric v, HasMetric w, Scalar v ~ Scalar w)-           => (w :-* v) -> (w :-* v) -> HerMetric w-dualCoCoProduct s t = ( (sArr `HMat.dot` (t²PLUSs² HMat.<\> sArr))+dualCoCoProduct :: (HasMetric v, HasMetric w, Scalar v ~ s, Scalar w ~ s)+           => Linear s w v -> Linear s w v -> HerMetric w+dualCoCoProduct (DenseLinear smat) (DenseLinear tmat)+                  = ( (sArr `HMat.dot` (t²PLUSs² HMat.<\> sArr))                        * (tArr `HMat.dot` (t²PLUSs² HMat.<\> tArr)) )                     *^ matrixMetric t²PLUSs²- where tmat = asPackedMatrix t-       tArr = HMat.flatten tmat-       smat = asPackedMatrix s+ where tArr = HMat.flatten tmat        sArr = HMat.flatten smat        t²PLUSs² = tmat HMat.<> HMat.tr tmat + smat HMat.<> HMat.tr smat @@ -278,16 +283,17 @@ -- | The inverse mapping of a metric tensor. Since a metric maps from --   a space to its dual, the inverse maps from the dual into the --   (double-dual) space &#x2013; i.e., it is a metric on the dual space.+--   Deprecated: the singular case isn't properly handled. recipMetric' :: HasMetric v => HerMetric v -> HerMetric' v recipMetric' (HerMetric Nothing) = singularMetric'-recipMetric' (HerMetric (Just m))+recipMetric' (HerMetric (Just (DenseLinear m)))           | isInfinite' detm  = singularMetric'           | otherwise         = matrixMetric' minv  where (minv, (detm, _)) = HMat.invlndet m  recipMetric :: HasMetric v => HerMetric' v -> HerMetric v recipMetric (HerMetric' Nothing) = singularMetric-recipMetric (HerMetric' (Just m))+recipMetric (HerMetric' (Just (DenseLinear m)))           | isInfinite' detm  = singularMetric           | otherwise         = matrixMetric minv  where (minv, (detm, _)) = HMat.invlndet m@@ -309,24 +315,24 @@ --   &#x201c;scaled length&#x201d; doesn't really makes sense then in the usual way!) eigenSpan :: (HasMetric v, Scalar v ~ ℝ) => HerMetric' v -> [v] eigenSpan (HerMetric' Nothing) = []-eigenSpan (HerMetric' (Just m)) = map fromPackedVector eigSpan+eigenSpan (HerMetric' (Just (DenseLinear m))) = map fromPackedVector eigSpan  where (μs,vsm) = HMat.eigSH' m        eigSpan = zipWith (HMat.scale . sqrt) (HMat.toList μs) (HMat.toColumns vsm)  eigenSpan' :: (HasMetric v, Scalar v ~ ℝ) => HerMetric v -> [DualSpace v] eigenSpan' (HerMetric Nothing) = []-eigenSpan' (HerMetric (Just m)) = map fromPackedVector eigSpan+eigenSpan' (HerMetric (Just (DenseLinear m))) = map fromPackedVector eigSpan  where (μs,vsm) = HMat.eigSH' m        eigSpan = zipWith (HMat.scale . sqrt) (HMat.toList μs) (HMat.toColumns vsm)  eigenCoSpan :: (HasMetric v, Scalar v ~ ℝ) => HerMetric' v -> [DualSpace v] eigenCoSpan (HerMetric' Nothing) = []-eigenCoSpan (HerMetric' (Just m)) = map fromPackedVector eigSpan+eigenCoSpan (HerMetric' (Just (DenseLinear m))) = map fromPackedVector eigSpan  where (μs,vsm) = HMat.eigSH' m        eigSpan = zipWith (HMat.scale . recip . sqrt) (HMat.toList μs) (HMat.toColumns vsm) eigenCoSpan' :: (HasMetric v, Scalar v ~ ℝ) => HerMetric v -> [v] eigenCoSpan' (HerMetric Nothing) = []-eigenCoSpan' (HerMetric (Just m)) = map fromPackedVector eigSpan+eigenCoSpan' (HerMetric (Just (DenseLinear m))) = map fromPackedVector eigSpan  where (μs,vsm) = HMat.eigSH' m        eigSpan = zipWith (HMat.scale . recip . sqrt) (HMat.toList μs) (HMat.toColumns vsm) @@ -344,8 +350,7 @@ --   all about dual spaces. class ( FiniteDimensional v, FiniteDimensional (DualSpace v)       , VectorSpace (DualSpace v), HasBasis (DualSpace v)-      , MetricScalar (Scalar v), Scalar v ~ Scalar (DualSpace v)-      , Basis v ~ Basis (DualSpace v) )+      , MetricScalar (Scalar v), Scalar v ~ Scalar (DualSpace v) )     => HasMetric' v where            -- | @'DualSpace' v@ is isomorphic to the space of linear functionals on @v@, i.e.@@ -374,7 +379,15 @@   doubleDual :: HasMetric' (DualSpace v) => v -> DualSpace (DualSpace v)   doubleDual' :: HasMetric' (DualSpace v) => DualSpace (DualSpace v) -> v   +  basisInDual :: Tagged v (Basis v -> Basis (DualSpace v))+  basisInDual = bid+   where bid :: ∀ v . HasMetric' v => Tagged v (Basis v -> Basis (DualSpace v))+         bid = Tagged $ bi >>> ib'+          where Tagged bi = basisIndex :: Tagged v (Basis v -> Int)+                Tagged ib' = indexBasis :: Tagged (DualSpace v) (Int -> Basis (DualSpace v))+   +    -- | Simple flipped version of '<.>^'. (^<.>) :: HasMetric v => v -> DualSpace v -> Scalar v@@ -382,7 +395,7 @@   euclideanMetric' :: forall v . (HasMetric v, InnerSpace v) => HerMetric v-euclideanMetric' = HerMetric . pure $ HMat.ident n+euclideanMetric' = HerMetric . pure . DenseLinear $ HMat.ident n  where (Tagged n) = dimension :: Tagged v Int  -- -- | Associate a Hilbert space vector canonically with its dual-space counterpart,@@ -401,17 +414,24 @@ instance (MetricScalar k) => HasMetric' (ZeroDim k) where   Origin<.>^Origin = zeroV   functional _ = Origin-  doubleDual = id; doubleDual'= id+  doubleDual = id; doubleDual'= id; basisInDual = pure id instance HasMetric' Double where   (<.>^) = (<.>)   functional f = f 1-  doubleDual = id; doubleDual'= id+  doubleDual = id; doubleDual'= id; basisInDual = pure id instance ( HasMetric v, HasMetric w, Scalar v ~ Scalar w          ) => HasMetric' (v,w) where   type DualSpace (v,w) = (DualSpace v, DualSpace w)   (v,w)<.>^(v',w') = v<.>^v' + w<.>^w'   functional f = (functional $ f . (,zeroV), functional $ f . (zeroV,))   doubleDual = id; doubleDual'= id+  basisInDual = bid+   where bid :: ∀ v w . (HasMetric v, HasMetric w) => Tagged (v,w)+                       (Basis v + Basis w -> Basis (DualSpace v) + Basis (DualSpace w))+         bid = Tagged $ \case Left q -> Left $ bidv q+                              Right q -> Right $ bidw q+          where Tagged bidv = basisInDual :: Tagged v (Basis v -> Basis (DualSpace v))+                Tagged bidw = basisInDual :: Tagged w (Basis w -> Basis (DualSpace w)) instance (SmoothScalar s, Ord s, KnownNat n) => HasMetric' (s^n) where   type DualSpace (s^n) = s^n   (<.>^) = (<.>)@@ -420,7 +440,7 @@          fnal f =     FreeVect . Arr.generate n $             \i -> f . FreeVect . Arr.generate n $ \j -> if i==j then 1 else 0           where Tagged n = theNatN :: Tagged n Int-  doubleDual = id; doubleDual'= id+  doubleDual = id; doubleDual'= id; basisInDual = pure id instance (HasMetric v, s~Scalar v) => HasMetric' (FinVecArrRep t v s) where   type DualSpace (FinVecArrRep t v s) = FinVecArrRep t (DualSpace v) s   FinVecArrRep v <.>^ FinVecArrRep w = HMat.dot v w@@ -432,17 +452,38 @@                      $ (f . FinVecArrRep) <$> HMat.toRows (HMat.ident n)          Tagged n = dimension :: Tagged v Int   doubleDual = id; doubleDual'= id+  basisInDual = bid+   where bid :: ∀ s v t . (HasMetric v, s~Scalar v)+                     => Tagged (FinVecArrRep t v s) (Basis v -> Basis (DualSpace v))+         bid = Tagged bid₀+          where Tagged bid₀ = basisInDual :: Tagged v (Basis v -> Basis (DualSpace v)) +instance (HasMetric v, HasMetric w, s ~ Scalar v, s ~ Scalar w)+               => HasMetric' (Linear s v w) where+  type DualSpace (Linear s v w) = Linear s w v+  DenseLinear bw <.>^ DenseLinear fw+                  = HMat.sumElements (HMat.tr bw * fw) -- trace of product+  functional = completeBasisFunctional+  doubleDual = id; doubleDual' = id +completeBasisFunctional :: ∀ v . HasMetric' v => (v -> Scalar v) -> DualSpace v+completeBasisFunctional f = recompose [ (bid b, f $ basisValue b) | b <- cb ]+          where Tagged cb = completeBasis :: Tagged v [Basis v]+                Tagged bid = basisInDual :: Tagged v (Basis v -> Basis (DualSpace v))   + -- | Transpose a linear operator. Contrary to popular belief, this does not --   just inverse the direction of mapping between the spaces, but also switch to --   their duals.-adjoint :: (HasMetric v, HasMetric w, Scalar w ~ Scalar v)+adjoint :: (HasMetric v, HasMetric w, s~Scalar v, s~Scalar w)+     => (Linear s v w) -> Linear s (DualSpace w) (DualSpace v)+adjoint (DenseLinear m) = DenseLinear $ HMat.tr m++adjoint_fln :: (HasMetric v, HasMetric w, Scalar w ~ Scalar v)      => (v :-* w) -> DualSpace w :-* DualSpace v-adjoint m = linear $ \w -> functional $ \v+adjoint_fln m = linear $ \w -> functional $ \v                      -> w <.>^lapply m v  @@ -458,7 +499,8 @@   negate = negateV               -- | This does /not/ work correctly if the metrics don't share an eigenbasis!-  HerMetric m * HerMetric n = HerMetric $ liftA2 (HMat.<>) m n+  HerMetric m * HerMetric n = HerMetric . fmap DenseLinear+                              $ liftA2 (HMat.<>) (getDenseMatrix<$>m) (getDenseMatrix<$>n)                                  -- | Undefined, though it could actually be done.   abs = error "abs undefined for HerMetric"@@ -468,7 +510,8 @@ metrNumFun :: (HasMetric v, v ~ Scalar v, v ~ DualSpace v, Num v)       => (v -> v) -> HerMetric v -> HerMetric v metrNumFun f (HerMetric Nothing) = matrixMetric . HMat.scalar $ f 0-metrNumFun f (HerMetric (Just m)) = matrixMetric . HMat.scalar . f $ m HMat.! 0 HMat.! 0+metrNumFun f (HerMetric (Just (DenseLinear m)))+              = matrixMetric . HMat.scalar . f $ m HMat.! 0 HMat.! 0  instance (HasMetric v, v ~ Scalar v, v ~ DualSpace v, Fractional v)              => Fractional (HerMetric v) where@@ -530,40 +573,46 @@ productMetric :: ∀ v w . (HasMetric v, HasMetric w, Scalar v ~ ℝ, Scalar w ~ ℝ)                => HerMetric v -> HerMetric w -> HerMetric (v,w) productMetric (HerMetric Nothing) (HerMetric Nothing) = HerMetric Nothing-productMetric (HerMetric (Just mv)) (HerMetric (Just mw))-        = HerMetric . Just $ HMat.diagBlock [mv, mw]-productMetric (HerMetric Nothing) (HerMetric (Just mw))-        = HerMetric . Just $ HMat.diagBlock [HMat.konst 0 (dv,dv), mw]- where (Tagged dv) = dimension :: Tagged v Int-productMetric (HerMetric (Just mv)) (HerMetric Nothing)-        = HerMetric . Just $ HMat.diagBlock [mv, HMat.konst 0 (dw,dw)]- where (Tagged dw) = dimension :: Tagged w Int+productMetric (HerMetric (Just mv)) (HerMetric (Just mw)) = HerMetric . Just $ mv *** mw+productMetric (HerMetric Nothing) (HerMetric (Just mw)) = HerMetric . Just $ zeroV *** mw+productMetric (HerMetric (Just mv)) (HerMetric Nothing) = HerMetric . Just $ mv *** zeroV  productMetric' :: ∀ v w . (HasMetric v, HasMetric w, Scalar v ~ ℝ, Scalar w ~ ℝ)                => HerMetric' v -> HerMetric' w -> HerMetric' (v,w) productMetric' (HerMetric' Nothing) (HerMetric' Nothing) = HerMetric' Nothing-productMetric' (HerMetric' (Just mv)) (HerMetric' (Just mw))-        = HerMetric' . Just $ HMat.diagBlock [mv, mw]-productMetric' (HerMetric' Nothing) (HerMetric' (Just mw))-        = HerMetric' . Just $ HMat.diagBlock [HMat.konst 0 (dv,dv), mw]- where (Tagged dv) = dimension :: Tagged v Int-productMetric' (HerMetric' (Just mv)) (HerMetric' Nothing)-        = HerMetric' . Just $ HMat.diagBlock [mv, HMat.konst 0 (dw,dw)]- where (Tagged dw) = dimension :: Tagged w Int+productMetric' (HerMetric' (Just mv)) (HerMetric' (Just mw)) = HerMetric' . Just $ mv***mw+productMetric' (HerMetric' Nothing) (HerMetric' (Just mw)) = HerMetric' . Just $ zeroV***mw+productMetric' (HerMetric' (Just mv)) (HerMetric' Nothing) = HerMetric' . Just $ mv***zeroV  +applyLinMapMetric :: ∀ v w . (HasMetric v, HasMetric w, Scalar v ~ ℝ, Scalar w ~ ℝ)+               => HerMetric (Linear ℝ v w) -> DualSpace v -> HerMetric w+applyLinMapMetric met v' = transformMetric ap2v met+ where ap2v :: Linear ℝ w (Linear ℝ v w)+       ap2v = denseLinear $ \w -> denseLinear $ \v -> w ^* (v'<.>^v) +applyLinMapMetric' :: ∀ v w . (HasMetric v, HasMetric w, Scalar v ~ ℝ, Scalar w ~ ℝ)+               => HerMetric' (Linear ℝ v w) -> v -> HerMetric' w+applyLinMapMetric' met v = transformMetric' ap2v met+ where ap2v :: Linear ℝ (Linear ℝ v w) w+       ap2v = denseLinear ($v) +++imitateMetricSpanChange :: ∀ v . (HasMetric v, Scalar v ~ ℝ)+                           => HerMetric v -> HerMetric' v -> Linear ℝ v v+imitateMetricSpanChange (HerMetric (Just m)) (HerMetric' (Just n)) = n . m+imitateMetricSpanChange _ _ = zeroV++ covariance :: ∀ v w . (HasMetric v, HasMetric w, Scalar v ~ ℝ, Scalar w ~ ℝ)-          => HerMetric' (v,w) -> Option (v:-*w)+          => HerMetric' (v,w) -> Option (Linear ℝ v w) covariance (HerMetric' Nothing) = pure zeroV covariance (HerMetric' (Just m))     | isInfinite' detvnm  = empty-    | otherwise           = pure . fromPackedMatrix $-                               wmat HMat.<> m HMat.<> vmat HMat.<> vnorml- where wmat = asPackedMatrix (linear snd :: (v,w):-*w)-       vmat = asPackedMatrix (linear (id&&&const zeroV) :: v:-*(v,w))-       (vnorml, (detvnm, _)) = HMat.invlndet (HMat.tr vmat HMat.<> m HMat.<> vmat)+    | otherwise           = return $ snd . m . (id&&&zeroV) . DenseLinear vnorml+ where (vnorml, (detvnm, _))+           = HMat.invlndet . getDenseMatrix $ fst . m . (id&&&zeroV)   metricAsLength :: HerMetric ℝ -> ℝ
Data/Manifold.hs view
@@ -15,661 +15,12 @@  {-# LANGUAGE FlexibleInstances        #-} {-# LANGUAGE UndecidableInstances     #-}--- {-# LANGUAGE OverlappingInstances     #-}-{-# LANGUAGE TypeFamilies             #-}-{-# LANGUAGE FunctionalDependencies   #-}-{-# LANGUAGE FlexibleContexts         #-}-{-# LANGUAGE GADTs                    #-}-{-# LANGUAGE RankNTypes               #-}-{-# LANGUAGE TupleSections            #-}-{-# LANGUAGE ConstraintKinds          #-}-{-# LANGUAGE PatternGuards            #-}-{-# LANGUAGE TypeOperators            #-}-{-# LANGUAGE ScopedTypeVariables      #-}-{-# LANGUAGE RecordWildCards          #-}  -module Data.Manifold (module Data.Manifold, module Data.Manifold.Types.Primitive) where--import Data.List-import Data.Maybe-import Data.Semigroup-import Data.Function (on)--import Data.VectorSpace-import Data.AffineSpace-import Data.Basis-import Data.Complex hiding (magnitude)-import Data.Void-import Data.Manifold.Types.Primitive--import qualified Prelude--import Control.Category.Constrained.Prelude hiding ((^), Foldable(..))-import Control.Arrow.Constrained-import Control.Monad.Constrained-import Data.Foldable.Constrained------ | Continuous mapping.-data domain :--> codomain where-  Continuous :: ( Manifold d, Manifold c-                , v ~ TangentSpace d, u ~ TangentSpace c-                , δ ~ Metric v, ε ~ Metric u   ) =>-        { runContinuous :: Chart d -> v -> (Chart c, u, ε->Option δ) }-           -> d :--> c-   -------continuous_id' ::  Manifold m => m :--> m-continuous_id' = Continuous id'- where id' chart v = (chart, v, return)---const__ :: (Manifold c, Manifold d)-    => c -> d:-->c-const__ x = Continuous f- where f _ _ = (tgtChart, w, const mzero)-       tgtChart = head $ localAtlas x-       w = case tgtChart of -            IdChart          -> x-            Chart _ tchOut _ -> fromJust (tchOut x) $ x---flatContinuous :: ( FlatManifold v, FlatManifold w, δ~Metric v, ε~Metric w )-    => (v -> (w, ε -> Option δ)) -> (v:-->w)-flatContinuous f = Continuous cnt- where cnt IdChart v = let (w, postEps) = f v -                       in (IdChart, w, postEps)-       cnt (Chart inMap _ _) v = let (v', preEps) = runFlatContinuous inMap v-                                     (w, postEps) = f v'-                                 in (IdChart, w, preEps>=>postEps)--runFlatContinuous :: ( FlatManifold v, FlatManifold w, δ~Metric v, ε~Metric w )-    => (v:-->w) -> v -> (w, ε -> Option δ)-runFlatContinuous (Continuous cnf) v = (w, preEps>=>postEps)- where (cc', v', preEps) = cnf IdChart v-       (w, postEps) = case cc' of -           IdChart         -> (v', return)-           Chart inMap _ _ -> runFlatContinuous inMap v'---instance Category (:-->) where-  type Object (:-->) t = Manifold t--  id = Continuous $ \c v -> (c, v, just)-  -  Continuous f . Continuous g = Continuous h-   where h srcChart u = (tgtChart, w, q>=>p)-          where (interChart, v, p) = g srcChart u-                (tgtChart, w, q) = f interChart v-             -instance EnhancedCat (->) (:-->) where-  Continuous f `arr` x = y-   where (tch, v, _) = f sch u-         y = case tch of Chart tchIn _ _ -> tchIn $ v-                         IdChart         -> v-         u = case sch of Chart _ schOut _ -> fromJust (schOut x) $ x-                         IdChart          -> x-         sch = head $ localAtlas x---instance Cartesian (:-->) where-  type PairObjects (:-->) a b = ( FlatManifold a, FlatManifold b, Manifold(a,b) )-  swap = Continuous $ \c t -> case c of-           IdChart         -> let (v,w) = t in (IdChart, (w,v), return)-           Chart inMap _ _ -> let ((v,w), epsP) = runFlatContinuous inMap t -                              in  (IdChart, (w,v), epsP)-  attachUnit = Continuous $ \c v -> case c of-           IdChart         -> (IdChart, (v,()), return)-           Chart inMap _ _ -> let (v', epsP) = runFlatContinuous inMap v-                              in  (IdChart, (v',()), epsP)-  detachUnit = Continuous $ \c t -> case c of-           IdChart         -> let (v,()) = t in (IdChart, v, return)-           Chart inMap _ _ -> let ((v,()), epsP) = runFlatContinuous inMap t-                              in  (IdChart, v, epsP)-  regroup = Continuous $ \c t -> case c of-           IdChart         -> let (u,(v,w)) = t in (IdChart, ((u,v),w), return)-           Chart inMap _ _ -> let ((u,(v,w)), epsP) = runFlatContinuous inMap t-                              in  (IdChart, ((u,v),w), epsP)-  regroup' = Continuous $ \c t -> case c of-           IdChart         -> let ((u,v),w) = t in (IdChart, (u,(v,w)), return)-           Chart inMap _ _ -> let (((u,v),w), epsP) = runFlatContinuous inMap t-                              in  (IdChart, (u,(v,w)), epsP)--instance Morphism (:-->) where-  first (Continuous f) = Continuous $ \c t -> case c of-           IdChart -> let (v,w) = t-                          (IdChart, v', epsP) = f IdChart v-                      in  (IdChart, (v',w), (/ sqrt 2) >>> -                                            \ε -> fmap getMin $ (fmap Min $ epsP ε)-                                                              <>(just $ Min ε)      )-  second (Continuous g) = Continuous $ \c t -> case c of-           IdChart -> let (v,w) = t-                          (IdChart, w', epsP) = g IdChart w-                      in  (IdChart, (v,w'), (/ sqrt 2) >>> -                                            \ε -> fmap getMin $ (just $ Min ε)-                                                              <>(fmap Min $ epsP ε) )-  Continuous f *** Continuous g = Continuous $ \c t -> case c of-           IdChart -> let (v,w) = t-                          (IdChart, v', epsPv) = f IdChart v-                          (IdChart, w', epsPw) = g IdChart w-                      in  (IdChart, (v',w'), (/ sqrt 2) >>> -                                            \ε -> fmap getMin $ (fmap Min $ epsPv ε)-                                                              <>(fmap Min $ epsPw ε) )--instance PreArrow (:-->) where-  terminal = const__ ()-  Continuous f &&& Continuous g = Continuous $ \c v -> case c of-           IdChart -> let (IdChart, v', epsPv) = f IdChart v-                          (IdChart, w', epsPw) = g IdChart v-                      in  (IdChart, (v',w'), (/ sqrt 2) >>> -                                            \ε -> fmap getMin $ (fmap Min $ epsPv ε)-                                                              <>(fmap Min $ epsPw ε) )-  fst = Continuous $ \c t -> case c of-           IdChart -> let (v,_) = t-                      in  (IdChart, v, return)-  snd = Continuous $ \c t -> case c of-           IdChart -> let (_,v) = t-                      in  (IdChart, v, return)-  -------- | A chart is a homeomorphism from a connected, open subset /Q/ ⊂ /M/ of--- an /n/-manifold /M/ to either the open unit disk /Dⁿ/ ⊂ /V/ ≃ ℝ/ⁿ/, or--- the half-disk /Hⁿ/ = {/x/ ∊ /Dⁿ/: x₀≥0}. In e.g. the former case, 'chartInMap'--- is thus defined ∀ /v/ ∊ /V/ : |/v/| < 1, while 'chartOutMap p' will yield @Just x@--- with /x/ ∊ /Dⁿ/ provided /p/ is in /Q/, and @Nothing@ otherwise.--- Obviously, @fromJust . 'chartOutMap' . 'chartInMap'@ should be equivalent to @id@--- on /Dⁿ/, and @'chartInMap' . fromJust . 'chartOutMap'@ to @id@ on /Q/.-data Chart :: * -> * where-  IdChart :: (FlatManifold v) => Chart v-  Chart :: (Manifold m, v ~ TangentSpace m, FlatManifold v) =>-        { chartInMap :: v :--> m-        , chartOutMap :: m -> Maybe (m:-->v)-        , chartKind :: ChartKind      } -> Chart m-data ChartKind = LandlockedChart  -- ^ A /M/ ⇆ /Dⁿ/ chart, for ordinary manifolds-               | RimChart         -- ^ A /M/ ⇆ /Hⁿ/ chart, for manifolds with a rim---type FlatManifold v = (MetricSpace v, Manifold v, v~TangentSpace v)----type EuclidSpace v = (HasBasis v, EqFloating(Scalar v), Eq v)--isInUpperHemi :: EuclidSpace v => v -> Bool-isInUpperHemi v = (snd . head) (decompose v) >= 0---- rimGuard :: EuclidSpace v => ChartKind -> v -> Maybe v--- rimGuard LandlockedChart v = Just v--- rimGuard RimChart v---  | isInUpperHemi v = Just v---  | otherwise       = Nothing--- --- chartEnv :: Manifold m => Chart m---                -> (TangentSpace m->TangentSpace m)---                -> m -> Maybe m--- chartEnv IdChart f x = Just $ f x--- chartEnv (Chart inMap outMap chKind) f x = do---     vGet <- outMap x---     let v = vGet $ x---     v' <- rimGuard chKind v---     Just $ inMap $ v'--- -  -- --type Atlas m = [Chart m]--class (MetricSpace(TangentSpace m), Metric(TangentSpace m) ~ ℝ) => Manifold m where-  type TangentSpace m :: *-  type TangentSpace m = m   -- For \"flat\", i.e. vector space manifolds.-  -  localAtlas :: m -> Atlas m---vectorSpaceAtlas :: FlatManifold v => v -> Atlas v-vectorSpaceAtlas _ = [IdChart]---  -instance Manifold () where-  type TangentSpace () = ()-  localAtlas = vectorSpaceAtlas--instance Manifold Double where-  localAtlas = vectorSpaceAtlas-  -instance ( FlatManifold v₁, FlatManifold v₂, Scalar v₁~Scalar v₂-         , MetricSpace (Scalar v₁), Metric (Scalar v₁)~ℝ-         , VectorSpace (v₁,v₂), Scalar (v₁,v₂) ~ Scalar v₁-         ) => Manifold (v₁,v₂) where-  localAtlas = vectorSpaceAtlas---------type Representsℝ r = (EqFloating r, FlatManifold r, r~Scalar r, r~Metric r)--continuousFlatFunction :: ( FlatManifold d, FlatManifold c,  ε~Metric c, δ~Metric d ) -                          => (d -> (c, ε->Option δ)) -> d:-->c-continuousFlatFunction f = Continuous f'- where f' IdChart x = (IdChart, y, eps2Delta)-        where (y, eps2Delta) = f x-       f' (Chart inMap _ _) v = (IdChart, y, postEps>=>preEps)-        where (v', preEps) = runFlatContinuous inMap v-              (y, postEps) = f v'--type CntnRealFunction = Representsℝ r => r :--> r--sin__, cos__, atan__ ,  exp__ , sinh__, cosh__, tanh__, asinh__ :: CntnRealFunction-sin__ = continuousFlatFunction sin'- where sin' x = (sinx, eps2Delta)-        where eps2Delta ε-               | ε > 1 + abs sinx  = nothing-               | otherwise         = just $ ε / (dsinx + sqrt ε)-              dsinx = abs $ cos x-              sinx = sin x-cos__ = continuousFlatFunction cos'- where cos' x = (cosx, eps2Delta)-        where eps2Delta ε-               | ε > 1 + abs cosx  = nothing-               | otherwise         = just $ ε / (dcosx + sqrt ε)-              dcosx = abs $ sin x-              cosx = cos x-atan__ = continuousFlatFunction atan'- where atan' x = (atanx, eps2Delta)-        where eps2Delta ε-               | ε >= pi/2 + abs atanx  = nothing-               | otherwise              = just $ abs x - tan (abs atanx - ε)-              atanx = atan x--exp__ = continuousFlatFunction exp'- where exp' x = (expx, eps2Delta)-        where expx = exp x-              eps2Delta ε -                | x>0, expx*2 == expx  = just 0   -- "Infinity" in floating-point-                | otherwise            = just $ log (expx + ε) - x--- exp x + ε = exp (x + δ) = exp x * exp δ--- δ = ln ( (exp x + ε)/exp x )--sinh__ = continuousFlatFunction sinh'- where sinh' x = (sinhx, eps2Delta)-        where eps2Delta ε = just $ asinh (abs sinhx + ε) - abs x-              sinhx = sinh x-cosh__ = continuousFlatFunction cosh'- where cosh' x = (coshx, eps2Delta)-        where eps2Delta ε = just $ acosh (coshx + ε) - abs x-              coshx = cosh x-tanh__ = continuousFlatFunction tanh'- where tanh' x = (tanhx, eps2Delta)-        where eps2Delta ε-               | ε >= 1 + abs tanhx  = nothing-               | otherwise           = just $ abs x - atanh (abs tanhx - ε)-              tanhx = tanh x-asinh__ = continuousFlatFunction asinh'- where asinh' x = (asinhx, eps2Delta)-        where eps2Delta ε = just $ abs x - sinh (abs asinhx - ε)-              asinhx = asinh x-       --cntnFuncsCombine :: forall d v c c' c'' ε ε' ε''. -         (       FlatManifold c, FlatManifold c', FlatManifold c''-                     , ε ~ Metric c  , ε' ~ Metric c' , ε'' ~ Metric c'', ε~ε', ε~ε''  )-       => (c'->c''->(c, ε->(ε',ε''))) -> (d:-->c') -> (d:-->c'') -> d:-->c-cntnFuncsCombine cmb (Continuous f) (Continuous g) = Continuous h- where h ζd u = case (ζc', ζc'') of -                 (IdChart, IdChart) -                   -> let (y, epsSplit) = cmb fu gu-                          fullEps ε = fmap getMin $ (fmap Min $ fEps ε') -                                                  <>(fmap Min $ gEps ε'')-                           where (ε', ε'') = epsSplit ε-                      in  (IdChart, y, fullEps)-                 (IdChart, Chart c''In _ _)-                   -> let (y'', c''Eps) = runFlatContinuous c''In gu-                          (y, epsSplit) = cmb fu y''-                          fullEps ε = fmap getMin $ (fmap Min $ fEps ε')-                                                  <>(fmap Min $ gEps =<< c''Eps ε'')-                           where (ε', ε'') = epsSplit ε-                      in  (IdChart, y, fullEps)-                 (Chart c'In _ _, IdChart)-                   -> let (y', c'Eps) = runFlatContinuous c'In fu -                          (y, epsSplit) = cmb y' gu-                          fullEps ε = fmap getMin $ (fmap Min $ fEps =<< c'Eps ε') -                                                  <>(fmap Min $ gEps ε'')-                            where (ε', ε'') = epsSplit ε-                      in  (IdChart, y, fullEps)-                 (Chart c'In _ _, Chart c''In _ _)-                   -> let (y', c'Eps) = runFlatContinuous c'In fu -                          (y'', c''Eps) = runFlatContinuous c''In gu -                          (y, epsSplit) = cmb y' y'' -                          fullEps ε = fmap getMin $ (fmap Min $ fEps =<< c'Eps ε') -                                                  <>(fmap Min $ gEps =<< c''Eps ε'')-                            where (ε', ε'') = epsSplit ε-                      in  (IdChart, y, fullEps)-        where (ζc', fu, fEps) = f ζd u-              (ζc'',gu, gEps) = g ζd u---data CntnFuncValue d c = CntnFuncValue { runCntnFuncValue :: d :--> c }-                       | CntnFuncConst c--instance HasAgent (:-->) where-  type AgentVal (:-->) d c = CntnFuncValue d c-  alg f = case f $ CntnFuncValue id of -                          CntnFuncValue q -> q-                          CntnFuncConst c -> const__ c-  f $~ CntnFuncValue g = CntnFuncValue $ f . g-  f $~ CntnFuncConst c = CntnFuncConst $ f $ c--instance PointAgent CntnFuncValue (:-->) d c where-  point = CntnFuncConst--instance CartesianAgent (:-->) where-  alg1to2 f = case f $ CntnFuncValue id of-       (CntnFuncConst c₁, CntnFuncConst c₂) -> const__ (c₁, c₂)-       (CntnFuncConst c₁, CntnFuncValue f₂)-            -> Continuous $ \IdChart x -> let (fx, epsP) = runFlatContinuous f₂ x-                                          in (IdChart, (c₁, fx), epsP) -       (CntnFuncValue f₁, CntnFuncConst c₂)-            -> Continuous $ \IdChart x -> let (fx, epsP) = runFlatContinuous f₁ x-                                          in (IdChart, (fx, c₂), epsP) -       (CntnFuncValue f₁, CntnFuncValue f₂) -> f₁ &&& f₂ -  alg2to1 f = case f (CntnFuncValue fst) (CntnFuncValue snd) of-               CntnFuncConst c -> const__ c-               CntnFuncValue f -> f-  alg2to2 f = case f (CntnFuncValue fst) (CntnFuncValue snd) of-       (CntnFuncConst c₁, CntnFuncConst c₂) -> const__ (c₁, c₂)-       (CntnFuncConst c₁, CntnFuncValue f₂)-            -> Continuous $ \IdChart x -> let (fx, epsP) = runFlatContinuous f₂ x-                                          in (IdChart, (c₁, fx), epsP) -       (CntnFuncValue f₁, CntnFuncConst c₂)-            -> Continuous $ \IdChart x -> let (fx, epsP) = runFlatContinuous f₁ x-                                          in (IdChart, (fx, c₂), epsP) -       (CntnFuncValue f₁, CntnFuncValue f₂) -> f₁ &&& f₂ ----cntnFnValsFunc :: ( FlatManifold c, FlatManifold c', Manifold d-                  , ε~Metric c, ε~Metric c'                     )-             => (c' -> (c, ε->Option ε)) -> CntnFuncValue d c' -> CntnFuncValue d c-cntnFnValsFunc = ($~) . continuousFlatFunction--cntnFnValsCombine :: forall d c c' c'' ε ε' ε''. -         (             FlatManifold c, FlatManifold c', FlatManifold c'', Manifold d-                     , ε ~ Metric c  , ε' ~ Metric c'  , ε'' ~ Metric c'', ε~ε', ε~ε''  )-       => (  c' -> c'' -> (c, ε -> (ε',(ε',ε''),ε''))  )-         -> CntnFuncValue d c' -> CntnFuncValue d c'' -> CntnFuncValue d c-cntnFnValsCombine cmb (CntnFuncValue f) (CntnFuncValue g) -    = CntnFuncValue $ cntnFuncsCombine (second (>>> \(_,splε,_)->splε) .: cmb) f g-cntnFnValsCombine cmb (CntnFuncConst p) (CntnFuncConst q) -    = CntnFuncConst . fst $ cmb p q-cntnFnValsCombine cmb f (CntnFuncConst q) -    = cntnFnValsFunc (\c' -> second (>>> \(ε',_,_)->return ε') $ cmb c' q) f-cntnFnValsCombine cmb (CntnFuncConst p) g-    = cntnFnValsFunc (second (>>> \(_,_,ε'')->return ε'') . cmb p) g--instance (Representsℝ r, Manifold d) => Num (CntnFuncValue d r) where-  fromInteger = point . fromInteger-  -  (+) = cntnFnValsCombine $ \a b -> (a+b, \ε -> (ε, (ε/2,ε/2), ε))-  (-) = cntnFnValsCombine $ \a b -> (a-b, \ε -> (ε, (ε/2,ε/2), ε))-  -  (*) = cntnFnValsCombine $ \a b -> (a*b, -                             \ε -> ( ε/b-                                   , (ε / (2 * sqrt(2*b^2+ε)), ε / (2 * sqrt(2*a^2+ε)))-                                   , ε/a ))-  --  |δa| < ε / 2·sqrt(2·b² + ε) ∧ |δb| < ε / 2·sqrt(2·a² + ε)-  --  ⇒  | (a+δa) · (b+δb) - a·b | = | a·δb + b·δa + δa·δb | -  --   ≤ | a·δb | + | b·δa | + | δa·δb |-  --   ≤ | a·ε/2·sqrt(2·a² + ε) | + | b·ε/2·sqrt(2·b² + ε) | + | ε² / 4·sqrt(2·b² + ε)·sqrt(2·a² + ε) |-  --   ≤ | a·ε/2·sqrt(2·a²) | + | b·ε/2·sqrt(2·b²) | + | ε² / 4·sqrt(ε)·sqrt(ε) |-  --   ≤ | ε/sqrt(8) | + | ε/sqrt(8) | + | ε / 4 |-  --   ≈ .96·ε < ε--  negate = cntnFnValsFunc $ \x -> (negate x, return)-  abs = cntnFnValsFunc $ \x -> (abs x, return)-  signum = cntnFnValsFunc $ \x -> (signum x, \ε -> if ε>2 then nothing else just $ abs x)--instance (Representsℝ r, Manifold d) => Fractional (CntnFuncValue d r) where-  fromRational = point . fromRational-  recip = cntnFnValsFunc $ \x -> let x¹ = recip x-                                 in (x¹, \ε -> just $ abs x - recip(ε + abs x¹))-  -- Readily derived from the worst-case of ε = 1 / (|x| – δ) – 1/|x|.--instance (Representsℝ r, Manifold d) => Floating (CntnFuncValue d r) where-  pi = point pi-  -  exp x = exp__$~ x-  sin x = sin__$~ x-  cos x = cos__$~ x-  atan x = atan__$~ x-  sinh x = sinh__$~ x-  cosh x = cosh__$~ x-  tanh x = tanh__$~ x-  asinh x = asinh__$~ x-  -  log x = continuousFlatFunction ln' $~ x-   where ln' x = (lnx, eps2Delta)-          where lnx = log x-                eps2Delta ε = just $ x - exp (lnx - ε)-  asin x = continuousFlatFunction asin' $~ x-   where asin' x = (asinx, eps2Delta)-          where asinx = asin x-                eps2Delta ε = just $ -                    if ε > pi/2 - abs asinx-                     then 1 - abs x-                     else sin (abs asinx + ε) - abs x-  acos x = continuousFlatFunction acos' $~ x-   where acos' x = (acosx, eps2Delta)-          where acosx = acos x-                eps2Delta ε = just $ -                    if ε > pi/2 - abs (acosx - pi/2)-                     then 1 - abs x-                     else cos (abs acosx + ε) - abs x-  acosh x = continuousFlatFunction acosh' $~ x-   where acosh' x = (acoshx, eps2Delta)-          where acoshx = acosh x-                eps2Delta ε = just $ -                    if ε > acoshx-                     then x - 1-                     else x - cosh (acoshx - ε)-  atanh x = continuousFlatFunction atanh' $~ x-   where atanh' x = (atanhx, eps2Delta)-          where atanhx = atanh x-                eps2Delta ε = just $ tanh (abs atanhx + ε) - abs x---instance (FlatManifold v, Manifold d) => AdditiveGroup (CntnFuncValue d v) where-  zeroV = point zeroV-  (^+^) = cntnFnValsCombine $ \a b -> (a^+^b, \ε -> (ε, (ε/2,ε/2), ε))-  negateV = cntnFnValsFunc $ \x -> (negateV x, return)--instance ( FlatManifold v, MetricSpace v, Metric v~ℝ, FlatManifold (Scalar v)-         , MetricSpace (Scalar v), Metric (Scalar v) ~ ℝ, Manifold d ) -               => VectorSpace (CntnFuncValue d v) where-  type Scalar (CntnFuncValue d v) = CntnFuncValue d (Scalar v)-  (*^) = cntnFnValsCombine -           $ \λ v -> ( λ*^v-                     , \ε -> let l = metric v-                                 λ' = metric λ-                             in ( ε/l-                                , ( ε / (2 * sqrt(2 * l^2 + ε))-                                  , ε / (2 * sqrt(2 * λ'^2 + ε)))-                                , ε / λ' ))-         -  ------------finiteGraphContinℝtoℝ :: GraphWindowSpec -> (Double:-->Double) -> [(Double, Double)]-finiteGraphContinℝtoℝ (GraphWindowSpec{..}) fc-       = connect [(x, f x, δyG) | x<-[lBound, rBound] ] [(rBound, fst (f rBound))]-   where connect [(x₁, (y₁, eps₁), ε₁),  (x₂, (y₂, eps₂), ε₂)]-                = case (getOption $ eps₁ ε₁, getOption $ eps₂ ε₂) of-                   (Nothing, Nothing)                  -> done-                   (Just δ₁, Nothing) | δ₁>δxS         -> done-                                      | otherwise      -> refine-                   (Nothing, Just δ₂) | δ₂>δxS         -> done-                                      | otherwise      -> refine-                   (Just δ₁, Just δ₂) | δ₁>δxS, δ₂>δxS -> done-                                      | otherwise      -> refine-             where δxS = x₂-x₁-                   m = x₁ + δxS/2-                   fm@(ym, _) = f m-                   done = ((x₁, y₁) :)-                   refine = connect [(x₁, (y₁, eps₁), ε₁), (m, fm, ε')]-                          . connect [(m, fm, ε'), (x₂, (y₂, eps₂), ε₂)]-                   ε' = (if δxS < δxG then max (min (abs $ ym - y₁) (abs $ ym - y₂)) else id)-                          $ max ε₁ ε₂-         f = runFlatContinuous fc-         δxG = (rBound - lBound) / fromIntegral xResolution-         δyG = (tBound - bBound) / fromIntegral yResolution---finiteGraphContinℝtoℝ² :: GraphWindowSpec -> (Double:-->(Double, Double)) -> [[(Double, Double)]]-finiteGraphContinℝtoℝ² (GraphWindowSpec{..}) fc-       = map (\(tl, tu) -> reCoarsen $ connect (tl, f tl) (tu, f tu) [fst (f tu)]) segments-  where connect n₁@(t₁, (p₁, eps₁)) n₂@(t₂, (p₂, eps₂)) -           | and . catMaybes $ map (getOption . fmap( > t₂ - t₁ ) . ($reso)) [eps₁, eps₂]  -                                                     = (p₁ : )-           | m <- (id &&& f) $ midBetween [t₁, t₂]   = connect n₁ m . connect m n₂--        segments = do-                 (start, dir) <- [ (Just 0                                 , -1)-                                 , (go (\_ -> not . inRange) reasonable 1 0, 1 ) ]-                 foldMap (`explore`dir) start-         where explore t₀ dir-                 | Just ti <- go (\_ -> inRange) reasonable dir t₀-                 , Just tb <- exitWindow (-dir) ti-                 , Just te <- exitWindow   dir  ti-                              = (if dir > 0 then (tb, te) else (te, tb)) : explore te dir-                 | otherwise  = []-                where exitWindow = go (\t p -> not $ reasonable t && inRange p) (const True)-               go isDone hasHope dir t-                 | not $ hasHope t  = Nothing-                 | isDone t p       = Just t-                 | Just s <- getOption(epsP $ mobility p)-                                    = go isDone hasHope dir $ t + dir * s-                 | otherwise        = Nothing-                where (p, epsP) = f t--        f = runFlatContinuous fc-        inRange (x, y) = x > lBound && x < rBound && y > bBound && y < tBound-        reasonable = (< 1e+250) . abs-        mobility = \p -> sqrt $ max (distanceSq p cp₁) (distanceSq p cp₂) -         where cp₁ = ( midBetween[lBound, rBound, rBound], midBetween[bBound, tBound, tBound] )-               cp₂ = ( midBetween[lBound, lBound, rBound], midBetween[bBound, bBound, tBound] )-        resoSq = reso ^ 2-        reso = min ( (rBound - lBound) / fromIntegral xResolution )-                   ( (tBound - bBound) / fromIntegral yResolution ) * 2-        firstJust = head . catMaybes--        reCoarsen (p₁ : p₂ : ps)-          | distanceSq p₁ p₂ > resoSq  = p₁ : reCoarsen (p₂ : ps)-          | otherwise                  = reCoarsen (p₁ : ps)-        reCoarsen ps = ps---               -                      -        -midBetween :: (VectorSpace v, Fractional(Scalar v)) => [v] -> v-midBetween vs = sumV vs ^/ (fromIntegral $ Prelude.length vs)-------- instance Manifold S2 where---   type TangentSpace S2 = (Double, Double)---   localAtlas (S2 ϑ φ)---    | ϑ<pi-2     = [ Chart (\(x,y)---                              -> S2(2 * sqrt(x^2+y^2)) (atan2 y x) )---                           (\(S2 ϑ' φ')---                              -> let r=ϑ'/2---                                 in guard (r<1) >> Just (r * cos φ', r * sin φ') )---                           LandlockedChart ]---    | ϑ>2        = [ Chart (\(x,y)---                              -> S2(pi - 2*sqrt(x^2+y^2)) (atan2 y x) )---                           (\(S2 ϑ' φ')---                              -> let r=(pi-ϑ')/2---                                 in guard (r<1) >> Just (r * cos φ', r * sin φ') )---                           LandlockedChart ]---    | otherwise  = localAtlas(S2 0 φ) ++ localAtlas(S2 (2*pi) φ)--- --------(.:) :: (c->d) -> (a->b->c) -> a->b->d -(.:) = (.) . (.)---just = Option . Just-nothing = Option Nothing------class (RealFloat (Metric v), InnerSpace v) => MetricSpace v where-  type Metric v :: *-  type Metric v = ℝ-  metric :: v -> Metric v-  metric = sqrt . metricSq-  metricSq :: v -> Metric v-  metricSq = (^2) . metric-  (|*^) :: Metric v -> v -> v-  μ |*^ v = metricToScalar v μ *^ v -  metricToScalar :: v -> Metric v -> Scalar v-  --instance MetricSpace () where-  metric = const 0-  metricToScalar = const id-instance MetricSpace ℝ where-  metric = id-  metricToScalar = const id-instance ( RealFloat r, MetricSpace r, Scalar (Complex r)~Metric r ) -             => MetricSpace (Complex r) where-  type Metric (Complex r) = Metric r-  metricSq (a :+ b) = metricSq a + metricSq b-  metricToScalar = const id-instance ( MetricSpace v, MetricSpace (Scalar v)-         , MetricSpace w, Scalar v~Scalar w-         , Metric v~Metric (Scalar v), Metric w~Metric v-         , Metric(Scalar w)~Metric v, RealFloat (Metric v)-         ) => MetricSpace (v,w) where-  type Metric (v,w) = Metric v-  metricSq (v,w) = metric (magnitudeSq v) + metric (magnitudeSq w)-  metricToScalar (v,_) = metricToScalar v+module Data.Manifold (module Data.Manifold.PseudoAffine, module Data.Manifold.Types) where +import Data.Manifold.PseudoAffine+import Data.Manifold.Types   
Data/Manifold/Griddable.hs view
@@ -139,12 +139,12 @@                fstGriddingParams :: GriddingParameters m a              , sndGriddingParams :: GriddingParameters n a }   mkGridding (PairGriddingParameters p₁ p₂) n (Shade (c₁,c₂) e₁e₂)-          = gshmap ( uncurry fullShade . (                  (,c₂).(^.shadeCtr)+          = ( gshmap ( uncurry fullShade . (                  (,c₂).(^.shadeCtr)                                          &&& (`productMetric'`e₂).(^.shadeExpanse)) )-              <$> g₁s-         ++ gshmap ( uncurry fullShade . (                  (c₁,).(^.shadeCtr)+              <$> g₁s )+         ++ ( gshmap ( uncurry fullShade . (                  (c₁,).(^.shadeCtr)                                          &&& ( productMetric' e₁).(^.shadeExpanse)) )-              <$> g₂s+              <$> g₂s )    where g₁s = mkGridding p₁ n $ fullShade c₁ e₁          g₂s = mkGridding p₂ n $ fullShade c₂ e₂          (e₁,e₂) = factoriseMetric' e₁e₂ 
Data/Manifold/PseudoAffine.hs view
@@ -61,6 +61,8 @@             , HilbertSpace             , EuclidSpace             , LocallyScalable+            -- ** Local functions+            , LocalLinear, LocalAffine             -- * Misc             , palerp             ) where@@ -78,6 +80,7 @@ import Data.VectorSpace import Data.LinearMap import Data.LinearMap.HerMetric+import Data.LinearMap.Category import Data.MemoTrie (HasTrie(..)) import Data.AffineSpace import Data.Basis@@ -220,6 +223,9 @@                            , HasMetric (Needle x)                            , s ~ Scalar (Needle x) ) +type LocalLinear x y = Linear (Scalar (Needle x)) (Needle x) (Needle y)+type LocalAffine x y = (Needle y, LocalLinear x y)+ -- | Basically just an &#x201c;updated&#x201d; version of the 'VectorSpace' class. --   Every vector space is a manifold, this constraint makes it explicit. --   @@ -400,6 +406,17 @@   p.+~^n = p ^+^ linMapFromTensProd n instance (HasMetric a, FiniteDimensional b, Scalar a~Scalar b) => PseudoAffine (a:-*b) where   a.-~.b = pure . linMapAsTensProd $ a^-^b++instance (HasMetric a, FiniteDimensional b, Scalar a~s, Scalar b~s)+                          => Semimanifold (Linear s a b) where+  type Needle (Linear s a b) = Linear s a b+  fromInterior = id+  toInterior = pure+  translateP = Tagged (.+^)+  (.+~^) = (^+^)+instance (HasMetric a, FiniteDimensional b, Scalar a~s, Scalar b~s)+                          => PseudoAffine (Linear s a b) where+  a.-~.b = pure (a^-^b)  instance Semimanifold S⁰ where   type Needle S⁰ = ℝ⁰
Data/Manifold/TreeCover.hs view
@@ -13,6 +13,7 @@ {-# LANGUAGE DeriveGeneric              #-} {-# LANGUAGE DeriveFunctor              #-} {-# LANGUAGE DeriveFoldable             #-}+{-# LANGUAGE DeriveTraversable          #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE TypeFamilies               #-} {-# LANGUAGE FunctionalDependencies     #-}@@ -34,9 +35,15 @@  module Data.Manifold.TreeCover (        -- * Shades -         Shade(..), Shade'(..)-       -- ** Lenses and constructors-       , shadeCtr, shadeExpanse, shadeNarrowness, fullShade, fullShade', pointsShades+         Shade(..), Shade'(..), IsShade+       -- ** Lenses+       , shadeCtr, shadeExpanse, shadeNarrowness+       -- ** Construction+       , fullShade, fullShade', pointsShades+       -- ** Evaluation+       , occlusion+       -- ** Misc+       , factoriseShade, intersectShade's        -- * Shade trees        , ShadeTree(..), fromLeafPoints        -- * Simple view helpers@@ -45,6 +52,9 @@        , SimpleTree, Trees, NonEmptyTree, GenericTree(..)        -- * Misc        , sShSaw, chainsaw, HasFlatView(..), shadesMerge, smoothInterpolate+       , twigsWithEnvirons, completeTopShading, flexTwigsShading+       , WithAny(..), Shaded, stiAsIntervalMapping, spanShading+       , DifferentialEqn, filterDEqnSolution_static        -- ** Triangulation-builders        , TriangBuild, doTriangBuild, singleFullSimplex, autoglueTriangulation        , AutoTriang, elementaryTriang, breakdownAutoTriang@@ -63,6 +73,7 @@ import Control.DeepSeq  import Data.VectorSpace+import Data.AffineSpace import Data.LinearMap import Data.LinearMap.HerMetric import Data.LinearMap.Category@@ -89,6 +100,7 @@ import Data.Functor.Identity import Control.Monad.Trans.State import Control.Monad.Trans.Writer+import Control.Monad.Trans.Maybe import Control.Monad.Trans.Class import qualified Data.Foldable       as Hask import Data.Foldable (all, elem, toList, sum, foldr1)@@ -98,10 +110,11 @@ import qualified Numeric.LinearAlgebra.HMatrix as HMat  import Control.Category.Constrained.Prelude hiding-     ((^), all, elem, sum, forM, Foldable(..), foldr1, Traversable)+     ((^), all, elem, sum, forM, Foldable(..), foldr1, Traversable, traverse) import Control.Arrow.Constrained import Control.Monad.Constrained hiding (forM) import Data.Foldable.Constrained+import Data.Traversable.Constrained (traverse)  import GHC.Generics (Generic) @@ -122,12 +135,15 @@ --   there is 'Region', whose implementation is vastly more complex. data Shade x = Shade { _shadeCtr :: !(Interior x)                      , _shadeExpanse :: !(Metric' x) }+deriving instance (Show x, Show (Needle x), WithField ℝ Manifold x) => Show (Shade x)  -- | A &#x201c;co-shade&#x201d; can describe ellipsoid regions as well, but unlike --   'Shade' it can be unlimited / infinitely wide in some directions. --   It does OTOH need to have nonzero thickness, which 'Shade' needs not. data Shade' x = Shade' { _shade'Ctr :: !(Interior x)                        , _shade'Narrowness :: !(Metric x) }+deriving instance (Show x, Show (DualSpace (Needle x)), WithField ℝ Manifold x)+             => Show (Shade' x)  class IsShade shade where --  type (*) shade :: *->*@@ -135,15 +151,39 @@   shadeCtr :: Functor f (->) (->) => (Interior x->f (Interior x)) -> shade x -> f (shade x) --  -- | Convert between 'Shade' and 'Shade' (which must be neither singular nor infinite). --  unsafeDualShade :: WithField ℝ Manifold x => shade x -> shade* x+  -- | Check the statistical likelihood-density of a point being within a shade.+  --   This is taken as a normal distribution.+  occlusion :: ( Manifold x, s ~ (Scalar (Needle x)), RealDimension s )+                => shade x -> x -> s+  factoriseShade :: ( Manifold x, RealDimension (Scalar (Needle x))+                    , Manifold y, RealDimension (Scalar (Needle y)) )+                => shade (x,y) -> (shade x, shade y)  instance IsShade Shade where   shadeCtr f (Shade c e) = fmap (`Shade`e) $ f c+  occlusion (Shade p₀ δ) = occ+   where occ p = case p .-~. p₀ of+           Option(Just vd) | mSq <- metricSq δinv vd+                           , mSq == mSq  -- avoid NaN+                           -> exp (negate mSq)+           _               -> zeroV+         δinv = recipMetric δ+  factoriseShade (Shade (x₀,y₀) δxy) = (Shade x₀ δx, Shade y₀ δy)+   where (δx,δy) = factoriseMetric' δxy  shadeExpanse :: Functor f (->) (->) => (Metric' x -> f (Metric' x)) -> Shade x -> f (Shade x) shadeExpanse f (Shade c e) = fmap (Shade c) $ f e  instance IsShade Shade' where   shadeCtr f (Shade' c e) = fmap (`Shade'`e) $ f c+  occlusion (Shade' p₀ δinv) = occ+   where occ p = case p .-~. p₀ of+           Option(Just vd) | mSq <- metricSq δinv vd+                           , mSq == mSq  -- avoid NaN+                           -> exp (negate mSq)+           _               -> zeroV+  factoriseShade (Shade' (x₀,y₀) δxy) = (Shade' x₀ δx, Shade' y₀ δy)+   where (δx,δy) = factoriseMetric δxy  shadeNarrowness :: Functor f (->) (->) => (Metric x -> f (Metric x)) -> Shade' x -> f (Shade' x) shadeNarrowness f (Shade' c e) = fmap (Shade' c) $ f e@@ -186,6 +226,8 @@ pointsShades :: WithField ℝ Manifold x => [x] -> [Shade x] pointsShades = map snd . pointsShades' zeroV +pointsShade's :: WithField ℝ Manifold x => [x] -> [Shade' x]+pointsShade's = map (\(Shade c e) -> Shade' c $ recipMetric e) . pointsShades  pseudoECM :: WithField ℝ Manifold x => NonEmpty x -> (x, ([x],[x])) pseudoECM (p₀ NE.:| psr) = foldl' ( \(acc, (rb,nr)) (i,p)@@ -231,30 +273,34 @@                   = Just $ let cc = c₂ .+~^ v ^/ 2                                Option (Just cv₁) = c₁.-~.cc                                Option (Just cv₂) = c₂.-~.cc-                           in Shade cc . sumV $ [e₁, e₂] ++ projector'<$>[cv₁, cv₂] +                           in Shade cc . sumV $ [e₁, e₂] ++ (projector'<$>[cv₁, cv₂])            | otherwise  = Nothing shadesMerge _ shs = shs -minusLogOcclusion :: ( Manifold x, s ~ (Scalar (Needle x)), RealDimension s )-                => Shade x -> x -> s-minusLogOcclusion (Shade p₀ δ) = occ+-- | Evaluate the shade as a quadratic form; essentially+-- @+-- minusLogOcclusion sh x = x <.>^ (sh^.shadeExpanse $ x - sh^.shadeCtr)+-- @+-- where 'shadeExpanse' gives a metric (matrix) that characterises the+-- width of the shade.+minusLogOcclusion' :: ( Manifold x, s ~ (Scalar (Needle x)), RealDimension s )+              => Shade' x -> x -> s+minusLogOcclusion' (Shade' p₀ δinv) = occ  where occ p = case p .-~. p₀ of          Option(Just vd) | mSq <- metricSq δinv vd                          , mSq == mSq  -- avoid NaN                          -> mSq          _               -> 1/0-       δinv = recipMetric δ-  --- | Check the statistical likelyhood of a point being within a shade.-occlusion :: ( Manifold x, s ~ (Scalar (Needle x)), RealDimension s )-                => Shade x -> x -> s-occlusion (Shade p₀ δ) = occ+minusLogOcclusion :: ( Manifold x, s ~ (Scalar (Needle x)), RealDimension s )+              => Shade x -> x -> s+minusLogOcclusion (Shade p₀ δ) = occ  where occ p = case p .-~. p₀ of          Option(Just vd) | mSq <- metricSq δinv vd                          , mSq == mSq  -- avoid NaN-                         -> exp (negate mSq)-         _               -> zeroV+                         -> mSq+         _               -> 1/0        δinv = recipMetric δ+     @@ -306,8 +352,36 @@   DBranches b1 <> DBranches b2 = DBranches $ NE.zipWith (\(DBranch d1 c1) (DBranch _ c2)                                                               -> DBranch d1 $ c1<>c2 ) b1 b2   +directionChoices :: WithField ℝ Manifold x+               => [DBranch x]+                 -> [ ( (Needle' x, ShadeTree x)+                      ,[(Needle' x, ShadeTree x)] ) ]+directionChoices [] = []+directionChoices (DBranch ѧ (Hourglass t b) : hs)+       =  ( (ѧ,t), (v,b) : map fst uds)+          : ((v,b), (ѧ,t) : map fst uds)+          : map (second $ ((ѧ,t):) . ((v,b):)) uds+ where v = negateV ѧ+       uds = directionChoices hs +traverseDirectionChoices :: (WithField ℝ Manifold x, Hask.Applicative f)+               => (     (Needle' x, ShadeTree x)+                    -> [(Needle' x, ShadeTree x)]+                    -> f (ShadeTree x) )+                 -> [DBranch x]+                 -> f [DBranch x]+traverseDirectionChoices f dbs = td [] (dbs >>=+                            \(DBranch ѧ (Hourglass τ β))+                              -> [(ѧ,τ), (negateV ѧ,β)])+ where td pds ((ѧ,t):(v,b):vds)+         = liftA3 (\t' b' -> (DBranch ѧ (Hourglass t' b') :))+             (f (ѧ,t) $ pds++(v,b):uds)+             (f (v,b) $ pds++(ѧ,t):uds)+             $ td ((ѧ,t):(v,b):pds) vds+        where uds = pds ++ vds+       td _ _ = pure [] + instance (NFData x, NFData (Needle' x)) => NFData (ShadeTree x) where   rnf (PlainLeaves xs) = rnf xs   rnf (DisjointBranches n bs) = n `seq` rnf (NE.toList bs)@@ -345,22 +419,7 @@  -- | Build a quite nicely balanced tree from a cloud of points, on any real manifold. -- ---   Example:--- --- @--- > :m +Graphics.Dynamic.Plot.R2 Data.Manifold.TreeCover Data.VectorSpace Data.AffineSpace --- > import Diagrams.Prelude ((^&), p2, r2, P2, circle, fc, (&), moveTo, opacity)--- --- >   -- Generate sort-of&#x2013;random cloud of lots of points--- > let testPts0 = p2 \<$\> [(0,0), (0,1), (1,1), (1,2), (2,2)] :: [P2 Double]--- > let testPts1 = [p .+^ v^/3 | p\<-testPts0, v \<- r2\<$\>[(0,0), (-1,1), (1,2)]]--- > let testPts2 = [p .+^ v^/4 | p\<-testPts1, v \<- r2\<$\>[(0,0), (-1,1), (1,2)]]--- > let testPts3 = [p .+^ v^/5 | p\<-testPts2, v \<- r2\<$\>[(0,0), (-2,1), (1,2)]]--- > let testPts4 = [p .+^ v^/7 | p\<-testPts3, v \<- r2\<$\>[(0,1), (-1,1), (1,2)]]--- --- > plotWindow [ plot [ shapePlot $ circle 0.06 & moveTo p & opacity 0.3 | p <- testPts4 ]--- >            , plot . onlyNodes $ 'fromLeafPoints' testPts4 ]--- @+--   Example: https://nbviewer.jupyter.org/github/leftaroundabout/manifolds/blob/master/test/generate-ShadeTrees.ipynb#pseudorandomCloudTree --  -- <<images/examples/simple-2d-ShadeTree.png>> fromLeafPoints :: ∀ x. WithField ℝ Manifold x => [x] -> ShadeTree x@@ -375,7 +434,7 @@        fg_sShIdPart (Shade c expa) xs         | b:bs <- [DBranch (v, zeroV) mempty                     | v <- eigenCoSpan-                           (transformMetric' (linear fst) expa :: Metric' x) ]+                           (transformMetric' fst expa :: Metric' x) ]                       = sShIdPartition' c xs $ b:|bs  fromLeafPoints' :: ∀ x. WithField ℝ Manifold x =>@@ -461,78 +520,282 @@ sortByKey = map snd . sortBy (comparing fst)  +trunks :: ∀ x. WithField ℝ Manifold x => ShadeTree x -> [Shade x]+trunks (PlainLeaves lvs) = pointsShades lvs+trunks (DisjointBranches _ brs) = Hask.foldMap trunks brs+trunks (OverlappingBranches _ sh _) = [sh]  +nLeaves :: ShadeTree x -> Int+nLeaves (PlainLeaves lvs) = length lvs+nLeaves (DisjointBranches n _) = n+nLeaves (OverlappingBranches n _ _) = n++overlappingBranches :: Shade x -> NonEmpty (DBranch x) -> ShadeTree x+overlappingBranches shx brs = OverlappingBranches n shx brs+ where n = sum $ fmap (sum . fmap nLeaves) brs++unsafeFmapLeaves :: (x -> x) -> ShadeTree x -> ShadeTree x+unsafeFmapLeaves f (PlainLeaves lvs) = PlainLeaves $ fmap f lvs+unsafeFmapLeaves f (DisjointBranches n brs)+                  = DisjointBranches n $ unsafeFmapLeaves f <$> brs+unsafeFmapLeaves f (OverlappingBranches n sh brs)+                  = OverlappingBranches n sh $ fmap (unsafeFmapLeaves f) <$> brs++unsafeFmapTree :: (NonEmpty x -> NonEmpty y)+               -> (Needle' x -> Needle' y)+               -> (Shade x -> Shade y)+               -> ShadeTree x -> ShadeTree y+unsafeFmapTree _ _ _ (PlainLeaves []) = PlainLeaves []+unsafeFmapTree f _ _ (PlainLeaves lvs) = PlainLeaves . toList . f $ NE.fromList lvs+unsafeFmapTree f fn fs (DisjointBranches n brs)+    = let brs' = unsafeFmapTree f fn fs <$> brs+      in DisjointBranches (sum $ nLeaves<$>brs') brs'+unsafeFmapTree f fn fs (OverlappingBranches n sh brs)+    = let brs' = fmap (\(DBranch dir br)+                        -> DBranch (fn dir) (unsafeFmapTree f fn fs<$>br)+                      ) brs+      in overlappingBranches (fs sh) brs'++ intersectShade's :: ∀ y . WithField ℝ Manifold y => [Shade' y] -> Option (Shade' y) intersectShade's [] = error "Global `Shade'` not implemented, so can't do intersection of zero co-shades." intersectShade's (sh:shs) = Hask.foldrM inter2 sh shs  where inter2 :: Shade' y -> Shade' y -> Option (Shade' y)        inter2 (Shade' c e) (Shade' ζ η)-           | μc > 1 && μζ > 1  = empty-           | otherwise         = return $ Shade' (c.+~^w) (e^+^η)-        where Option (Just c2ζ) = ζ.-~.c-              Option (Just ζ2c) = c.-~.ζ-              ζNearest, cNearest :: y-              ζNearest = c .+~^ metriNormalise e c2ζ-              cNearest = ζ .+~^ metriNormalise η ζ2c-              Option (Just rζ) = ζNearest.-~.ζ-              Option (Just rc) = cNearest.-~.c-              μc = metric e rc-              μζ = metric η rζ-              w = c2ζ ^* (μζ/(μc + μζ))-              -- = (c^*μc + ζ^*μζ)/(μc + μζ) − c-              -- = (c^*μc + ζ^*μζ − c^*(μc+μζ))^/(μc + μζ)-              -- = (ζ^*μζ − c^*μζ)^/(μc + μζ)-              -- = (ζ−c)^*μζ/(μc + μζ)+           | μe < 1 && μη < 1  = return $ Shade' iCtr iExpa+           | otherwise         = empty+        where [c', ζ'] = [ ctr.+~^linearCombo+                                     [ (v, 1 / (1 + metricSq oExpa w))+                                     | v <- (*^) <$> [-1,1] <*> span+                                     , let p = ctr .+~^ v  :: y+                                           Option (Just w) = p.-~.oCtr+                                     ]+                         | ctr                  <- [c,     ζ    ]+                         | span <- eigenCoSpan'<$> [e,     η    ]+                         | (oCtr,oExpa)         <- [(ζ,η), (c,e)]+                         ]+              Option (Just c'2ζ') = ζ'.-~.c'+              Option (Just c2ζ') = ζ'.-~.c+              Option (Just ζ2c') = c'.-~.ζ+              μc = metricSq e c2ζ'+              μζ = metricSq η ζ2c'+              iCtr = c' .+~^ c'2ζ' ^* (μζ/(μc + μζ)) -- weighted mean between c' and ζ'.+              Option (Just rc) = c.-~.iCtr+              Option (Just rζ) = ζ.-~.iCtr+              rcⰰ = toDualWith e rc+              rζⰰ = toDualWith η rζ+              μe = rcⰰ<.>^rc+              μη = rζⰰ<.>^rζ+              iExpa = (e^+^η)^/2 ^+^ projector rcⰰ^/(1-μe) ^+^ projector rζⰰ^/(1-μη)    -type DifferentialEqn x y = RWDiffable ℝ (x,y) (Needle x :-* Needle y)+type DifferentialEqn x y = Shade' (x,y) -> Shade' (LocalLinear x y)   filterDEqnSolution_loc :: ∀ x y . (WithField ℝ Manifold x, WithField ℝ Manifold y)-           => DifferentialEqn x y -> (Shade' (x,y), [Shade' (x,y)]) -> [Shade' (x,y)]-filterDEqnSolution_loc (RWDiffable f) (Shade' (x,y) expa, neighbours) = case f (x,y) of-          (_, Option Nothing) -> []-          (r, Option (Just (Differentiable fl)))-                | (fc, fc', δ) <- fl (x,y)-                   -> let flatMet :: HerMetric (Needle (x,y))-                          flatMet = recipMetric -- this won't work, metric is singular.-                               . transformMetric' (linear $ id &&& lapply fc) -                               $ recipMetric' expax-                          -- fcs = lapply fc' <$> xSpan-                          -- flinRange = δ $ projectors fcs-                          marginδs :: [(Needle x, (Needle y, Metric y))]-                          marginδs = [ (δxm, (δym, expany))-                                     | Shade' (xn, yn) expan <- neighbours-                                     , let (Option (Just δx)) = x.-~.xn-                                           (expanx, expany) = factoriseMetric expan-                                           (Option (Just yc'n))-                                                  = covariance $ recipMetric' expan-                                           xntoMarg = metriNormalise expanx δx-                                           (Option (Just δxm))-                                              = (xn .+~^ xntoMarg :: x) .-~. x-                                           (Option (Just δym))-                                              = (yn .+~^ lapply yc'n xntoMarg :: y-                                                  ) .-~. y-                                     ]-                          ycQuad :: y-                          (Option (Just (Shade' ycQuad _))) = intersectShade's-                                     [ Shade' ycn expany-                                     | (δxm,(δym,expany)) <- marginδs-                                     , let fca :: Needle x:-*Needle y-                                           fca = fc .+~^ lapply fc' ((δxm,δym)^/2)-                                           ycn = y .+~^ (δym ^-^ lapply fca δxm)-                                     ]-                                     :: Option (Shade' y)-                      in [Shade' (x,ycQuad) flatMet]- where (expax, expay) = factoriseMetric expa+           => DifferentialEqn x y -> (Shade' (x,y), [Shade' (x,y)])+                   -> Option (Shade' y, LocalLinear x y)+filterDEqnSolution_loc f (shxy@(Shade' (x,y) expa), neighbours) = (,j₀) <$> yc+ where jShade@(Shade' j₀ jExpa) = f shxy+       marginδs :: [(Needle x, (Needle y, Metric y))]+       marginδs = [ (δxm, (δym, expany))+                  | Shade' (xn, yn) expan <- neighbours+                  , let (Option (Just δx)) = x.-~.xn+                        (expanx, expany) = factoriseMetric expan+                        (Option (Just yc'n))+                               = covariance $ recipMetric' expan+                        xntoMarg = metriNormalise expanx δx+                        (Option (Just δxm))+                           = (xn .+~^ xntoMarg :: x) .-~. x+                        (Option (Just δym))+                           = (yn .+~^ (yc'n $ xntoMarg) :: y+                               ) .-~. y+                  ]+       back2Centre :: (Needle x, (Needle y, Metric y)) -> Shade' y+       back2Centre (δx, (δym, expany))+            = Shade' (y.+~^δyb) . recipMetric+                $ recipMetric' expany+                  ^+^ recipMetric' (applyLinMapMetric jExpa δx')+        where δyb = δym ^-^ (j₀ $ δx)+              δx' = toDualWith expax δx+       yc :: Option (Shade' y)+       yc = intersectShade's $ back2Centre <$> marginδs+       (expax, expay) = factoriseMetric expa        xSpan = eigenCoSpan' expax  +-- Formerly, this was the signature of what has now become 'traverseTwigsWithEnvirons'.+-- The simple list-yielding version (see rev. b4a427d59ec82889bab2fde39225b14a57b694df+-- may well be more efficient than this version via a traversal.+twigsWithEnvirons :: ∀ x. WithField ℝ Manifold x+    => ShadeTree x -> [(ShadeTree x, [ShadeTree x])]+twigsWithEnvirons = execWriter . traverseTwigsWithEnvirons (writer . (fst&&&pure))++data OuterMaybeT f a = OuterNothing | OuterJust (f a) deriving (Hask.Functor)+instance (Hask.Applicative f) => Hask.Applicative (OuterMaybeT f) where+  pure = OuterJust . pure+  OuterJust fs <*> OuterJust xs = OuterJust $ fs <*> xs+  _ <*> _ = OuterNothing++traverseTwigsWithEnvirons :: ∀ x f .+            (WithField ℝ Manifold x, Hask.Applicative f)+    => ((ShadeTree x, [ShadeTree x]) -> f (ShadeTree x))+         -> ShadeTree x -> f (ShadeTree x)+traverseTwigsWithEnvirons f = fst . go []+ where go :: [ShadeTree x] -> ShadeTree x -> (f (ShadeTree x), Bool)+       go _ (DisjointBranches nlvs djbs) = ( fmap (DisjointBranches nlvs)+                                               $ Hask.traverse (fst . go []) djbs+                                           , False )+       go envi ct@(OverlappingBranches nlvs rob@(Shade robc _) brs)+                = ( case descentResult of+                     OuterNothing -> f+                         $ purgeRemotes (ct, Hask.foldMap (twigProximæ robc) envi)+                     OuterJust dR -> fmap (OverlappingBranches nlvs rob . NE.fromList) dR+                  , False )+        where descentResult = traverseDirectionChoices tdc $ NE.toList brs+              tdc (vy, ty) alts = case go envi'' ty of+                                   (_, True) -> OuterNothing+                                   (down, _) -> OuterJust down+               where envi'' = filter (trunks >>> \(Shade ce _:_)+                                         -> let Option (Just δyenv) = ce.-~.robc+                                                qq = vy<.>^δyenv+                                            in qq > -1 && qq < 5+                                       ) envi'+                              ++ map snd alts+              envi' = approach =<< envi+              approach apt@(OverlappingBranches _ (Shade envc _) _)+                  = twigsaveTrim hither apt+               where Option (Just δxenv) = robc .-~. envc+                     hither (DBranch bdir (Hourglass bdc₁ bdc₂))+                       | bdir<.>^δxenv > 0  = [bdc₁]+                       | otherwise          = [bdc₂]+              approach q = [q]+       go envi plvs@(PlainLeaves _) = (f $ purgeRemotes (plvs, envi), True)+       +       twigProximæ :: x -> ShadeTree x -> [ShadeTree x]+       twigProximæ x₀ (DisjointBranches _ djbs) = Hask.foldMap (twigProximæ x₀) djbs+       twigProximæ x₀ ct@(OverlappingBranches _ (Shade xb qb) brs)+                   = twigsaveTrim hither ct+        where Option (Just δxb) = x₀ .-~. xb+              hither (DBranch bdir (Hourglass bdc₁ bdc₂))+                 | bdir<.>^δxb > 0  = twigProximæ x₀ bdc₁+                 | otherwise        = twigProximæ x₀ bdc₂+       twigProximæ _ plainLeaves = [plainLeaves]+       +       twigsaveTrim :: (DBranch x -> [ShadeTree x])+                       -> ShadeTree x -> [ShadeTree x]+       twigsaveTrim f ct@(OverlappingBranches _ _ dbs)+                 = case Hask.mapM (f >>> noLeaf) dbs of+                      Just pqe -> Hask.fold pqe+                      _        -> [ct]+        where noLeaf [PlainLeaves _] = empty+              noLeaf bqs = pure bqs+       +       purgeRemotes :: (ShadeTree x, [ShadeTree x]) -> (ShadeTree x, [ShadeTree x])+       purgeRemotes (ctm@(OverlappingBranches _ sm@(Shade xm _) _), candidates)+                                       = (ctm, filter unobscured closeby)+        where closeby = filter proximate candidates+              proximate (OverlappingBranches _ sh@(Shade xh _) _)+                    = minusLogOcclusion sh xm * minusLogOcclusion sm xh+                       < 1024  -- = (2⋅4²)².  The four-radius occlusion occurs+                               -- if two 𝑟-sized shades have just enough space+                               -- to fit another 𝑟-shade between them; then+                               -- we don't consider the shades neighbours+                               -- anymore. A factor √2 for the discrepancy+                               -- between standard deviation and max distance.+              proximate _ = True+              unobscured ht@(OverlappingBranches _ (Shade xh _) _)+                     = all (don'tObscure (xh, onlyLeaves ht)) closeby+              don'tObscure (xh,lvsh) (OverlappingBranches _ sb@(Shade xb eb) _)+                          = vmc⋅vhc >= 0 || vm⋅vh >= 0+               where Option (Just vm) = pbm .-~. xb+                     Option (Just vh) = pbh .-~. xb+                     Option (Just vmc) = xm .-~. xb+                     Option (Just vhc) = xh .-~. xb+                     [pbm, pbh] = [ maximumBy (comparing $ \l ->+                                               let Option (Just w) = l.-~.xb+                                               in v⋅w ) lvs+                                  | lvs <- [lvsm, lvsh]+                                  | v <- [vhc, vmc] ]+                     (⋅) :: Needle x -> Needle x -> ℝ+                     v⋅w = toDualWith mb v <.>^ w+                     mb = recipMetric eb+              don'tObscure _ _ = True+              lvsm = onlyLeaves ctm+       purgeRemotes xyz = xyz     +    +completeTopShading :: (WithField ℝ Manifold x, WithField ℝ Manifold y)+                   => x`Shaded`y -> [Shade' (x,y)]+completeTopShading (PlainLeaves plvs)+                     = pointsShade's $ (_topological &&& _untopological) <$> plvs+completeTopShading (DisjointBranches _ bqs)+                     = take 1 . completeTopShading =<< NE.toList bqs+completeTopShading t = pointsShade's . map (_topological &&& _untopological) $ onlyLeaves t +flexTopShading :: ∀ x y f . ( WithField ℝ Manifold x, WithField ℝ Manifold y+                            , Applicative f (->) (->) )+                  => (Shade' (x,y) -> f (x, (Shade' y, LocalLinear x y)))+                      -> x`Shaded`y -> f (x`Shaded`y)+flexTopShading f tr = seq (assert_onlyToplevDisjoint tr)+                    $ recst (completeTopShading tr) tr+ where recst qsh@(_:_) (DisjointBranches n bqs)+          = undefined -- DisjointBranches n $ NE.zipWith (recst . (:[])) (NE.fromList qsh) bqs+       recst [sha@(Shade' (_,yc₀) expa₀)] t = fmap fts $ f sha+        where expa'₀ = recipMetric' expa₀+              j₀ :: LocalLinear x y+              Option (Just j₀) = covariance expa'₀+              (_,expay₀) = factoriseMetric expa₀+              fts (xc, (Shade' yc expay, jtg)) = unsafeFmapLeaves applδj t+               where Option (Just δyc) = yc.-~.yc₀+                     tfm = imitateMetricSpanChange expay₀ (recipMetric' expay)+                     applδj (WithAny y x)+                           = WithAny (yc₀ .+~^ ((tfm$δy) ^+^ (jtg$δx) ^+^ δyc)) x+                      where Option (Just δx) = x.-~.xc+                            Option (Just δy) = y.-~.(yc₀.+~^(j₀$δx))+       +       assert_onlyToplevDisjoint, assert_connected :: x`Shaded`y -> ()+       assert_onlyToplevDisjoint (DisjointBranches _ dp) = rnf (assert_connected<$>dp)+       assert_onlyToplevDisjoint t = assert_connected t+       assert_connected (OverlappingBranches _ _ dp)+           = rnf (Hask.foldMap assert_connected<$>dp)+       assert_connected (PlainLeaves _) = ()++flexTwigsShading :: ∀ x y f . ( WithField ℝ Manifold x, WithField ℝ Manifold y+                              , Hask.Applicative f )+                  => (Shade' (x,y) -> f (x, (Shade' y, LocalLinear x y)))+                      -> x`Shaded`y -> f (x`Shaded`y)+flexTwigsShading f = traverseTwigsWithEnvirons locFlex+ where locFlex :: ∀ μ . (x`Shaded`y, μ) -> f (x`Shaded`y)+       locFlex (lsh, _) = flexTopShading f lsh++filterDEqnSolution_static :: ∀ x y . (WithField ℝ Manifold x, WithField ℝ Manifold y)+           => DifferentialEqn x y+               -> x`Shaded`y -> Option (x`Shaded`y)+filterDEqnSolution_static deq tr = traverseTwigsWithEnvirons locSoltn tr+ where locSoltn :: (x`Shaded`y, [x`Shaded`y]) -> Option (x`Shaded`y)+       locSoltn (local, environs) = do+            let enviShades = completeTopShading =<< environs+            flexed <- flexTopShading+                           (\oSh@(Shade' (ox,_) _) -> +                              (ox,) <$> filterDEqnSolution_loc deq (oSh, enviShades)+                           ) local+            top'@(Shade' (top'x,_) top'exp)+                     <- intersectShade's $ completeTopShading =<< [local, flexed]+            let (_, top'ySh) = factoriseShade top'+            j' <- covariance $ recipMetric' top'exp+            flexTopShading (const $ pure (top'x, (top'ySh, j'))) flexed+                +++++++ -- simplexFaces :: forall n x . Simplex (S n) x -> Triangulation n x -- simplexFaces (Simplex p (ZeroSimplex q))    = TriangVertices $ Arr.fromList [p, q] -- simplexFaces splx = carpent splx $ TriangVertices ps@@ -633,7 +896,7 @@ simplexPlane :: forall n x . (KnownNat n, WithField ℝ Manifold x)         => Metric x -> Simplex n x -> Embedding (Linear ℝ) (FreeVect n ℝ) (Needle x) simplexPlane m s = embedding- where bc = barycenter s+ where bc = simplexBarycenter s        spread = init . map ((.-~.bc) >>> \(Option (Just v)) -> v) $ splxVertices s        embedding = case spanHilbertSubspace m spread of                      (Option (Just e)) -> e@@ -641,10 +904,14 @@                                 \ simplex (which cannot span sufficient basis vectors)."  +leavesBarycenter :: WithField ℝ Manifold x => NonEmpty x -> x+leavesBarycenter (x :| xs) = x .+~^ sumV [x'–x | x'<-xs] ^/ (n+1)+ where n = fromIntegral $ length xs+       x' – x = case x'.-~.x of {Option(Just v)->v}  -- simplexShade :: forall x n . (KnownNat n, WithField ℝ Manifold x)-barycenter :: forall x n . (KnownNat n, WithField ℝ Manifold x) => Simplex n x -> x-barycenter = bc +simplexBarycenter :: forall x n . (KnownNat n, WithField ℝ Manifold x) => Simplex n x -> x+simplexBarycenter = bc   where bc (ZS x) = x        bc (x :<| xs') = x .+~^ sumV [x'–x | x'<-splxVertices xs'] ^/ (n+1)        @@ -654,7 +921,7 @@ toISimplex :: forall x n . (KnownNat n, WithField ℝ Manifold x)                  => Metric x -> Simplex n x -> ISimplex n x toISimplex m s = ISimplex $ fromEmbedProject fromBrc toBrc- where bc = barycenter s+ where bc = simplexBarycenter s        (Embedding emb (DenseLinear prj))                          = simplexPlane m s        (r₀:rs) = [ prj HMat.#> asPackedVector v@@ -850,8 +1117,8 @@ partitionsOfFstLength :: Int -> [a] -> [([a],[a])] partitionsOfFstLength 0 l = [([],l)] partitionsOfFstLength n [] = []-partitionsOfFstLength n (x:xs) = first (x:) <$> partitionsOfFstLength (n-1) xs-                              ++ second (x:) <$> partitionsOfFstLength n xs+partitionsOfFstLength n (x:xs) = ( first (x:) <$> partitionsOfFstLength (n-1) xs )+                              ++ ( second (x:) <$> partitionsOfFstLength n xs )  splxVertices :: Simplex n x -> [x] splxVertices (ZS x) = [x]@@ -898,7 +1165,9 @@ type NonEmptyTree = GenericTree NonEmpty []      newtype GenericTree c b x = GenericTree { treeBranches :: c (x,GenericTree b b x) }- deriving (Hask.Functor)+ deriving (Generic, Hask.Functor, Hask.Foldable, Hask.Traversable)+instance (NFData x, Hask.Foldable c, Hask.Foldable b) => NFData (GenericTree c b x) where+  rnf (GenericTree t) = rnf $ toList t instance (Hask.MonadPlus c) => Semigroup (GenericTree c b x) where   GenericTree b1 <> GenericTree b2 = GenericTree $ Hask.mplus b1 b2 instance (Hask.MonadPlus c) => Monoid (GenericTree c b x) where@@ -1028,8 +1297,10 @@ data x`WithAny`y       = WithAny { _untopological :: y                 , _topological :: !x  }- deriving (Hask.Functor)+ deriving (Hask.Functor, Show, Generic) +instance (NFData x, NFData y) => NFData (WithAny x y)+ instance (Semimanifold x) => Semimanifold (x`WithAny`y) where   type Needle (WithAny x y) = Needle x   type Interior (WithAny x y) = Interior x `WithAny` y@@ -1068,6 +1339,9 @@   WithAny y x >>= f = WithAny r $ x^+^q    where WithAny r q = f y +shadeWithAny :: y -> Shade x -> Shade (x`WithAny`y)+shadeWithAny y (Shade x xe) = Shade (WithAny y x) xe+ shadeWithoutAnything :: Shade (x`WithAny`y) -> Shade x shadeWithoutAnything (Shade (WithAny _ b) e) = Shade b e @@ -1104,6 +1378,13 @@                  $ linearCombo [(v, d/dens) | Cℝay d v <- NE.toList contribs]         where dens = sum (hParamCℝay <$> contribs) +stiAsIntervalMapping :: (x ~ ℝ, y ~ ℝ)+            => x`Shaded`y -> [(x, ((y, Diff y), Linear ℝ x y))]+stiAsIntervalMapping = twigsWithEnvirons >=> pure.fst >=> completeTopShading >=> pure.+             \(Shade' (xloc, yloc) shd)+                 -> ( xloc, ( (yloc, recip $ metric shd (0,1))+                            , case covariance (recipMetric' shd) of+                                {Option(Just j)->j} ) )  smoothInterpolate :: (WithField ℝ Manifold x, WithField ℝ LinearManifold y)              => NonEmpty (x,y) -> x -> y@@ -1117,6 +1398,21 @@        ltr = stiWithDensity $ fromLeafPoints l'  +spanShading :: ∀ x y . (WithField ℝ Manifold x, WithField ℝ Manifold y)+          => (Shade x -> Shade y) -> ShadeTree x -> x`Shaded`y+spanShading f = unsafeFmapTree addYs id addYSh+ where addYs :: NonEmpty x -> NonEmpty (x`WithAny`y)+       addYs l = foldr (NE.<|) (fmap ( WithAny ymid) l     )+                               (fmap (`WithAny`xmid) yexamp)+          where [xsh@(Shade xmid _)] = pointsShades $ toList l+                Shade ymid yexpa = f xsh+                yexamp = [ ymid .+~^ σ*^δy+                         | δy <- eigenSpan yexpa, σ <- [-1,1] ]+       addYSh :: Shade x -> Shade (x`WithAny`y)+       addYSh xsh = shadeWithAny (_shadeCtr $ f xsh) xsh+                      ++ coneTip :: (AdditiveGroup v) => Cℝay v coneTip = Cℝay 0 zeroV @@ -1128,6 +1424,9 @@ foci :: [a] -> [(a,[a])] foci [] = [] foci (x:xs) = (x,xs) : fmap (second (x:)) (foci xs)+       +fociNE :: NonEmpty a -> NonEmpty (a,[a])+fociNE (x:|xs) = (x,xs) :| fmap (second (x:)) (foci xs)          (.:) :: (c->d) -> (a->b->c) -> a->b->d 
Data/Manifold/Types.hs view
@@ -50,10 +50,11 @@         , D¹(..), D²(..)         , ℝay         , CD¹(..), Cℝay(..)-        -- * Misc         -- * Cut-planes         , Cutplane(..)         , fathomCutDistance, sideOfCut+        -- * Linear mappings+        , Linear, denseLinear    ) where  @@ -75,6 +76,7 @@ import Data.Manifold.Cone import Data.LinearMap.HerMetric import Data.VectorSpace.FiniteDimensional+import Data.LinearMap.Category (Linear, denseLinear)  import qualified Prelude 
+ images/examples/cartesiandisk-2d-ShadeTree.png view

binary file changed (absent → 150317 bytes)

manifolds.cabal view
@@ -1,5 +1,5 @@ Name:                manifolds-Version:             0.1.6.3+Version:             0.2.0.1 Category:            Math Synopsis:            Coordinate-free hypersurfaces Description:         Manifolds, a generalisation of the notion of &#x201c;smooth curves&#x201d; or surfaces,@@ -48,7 +48,8 @@                      , void                      , tagged                      , deepseq-                     , constrained-categories >= 0.2 && < 0.3+                     , trivial-constraint >= 0.4+                     , constrained-categories >= 0.2.3 && < 0.3   other-extensions:  FlexibleInstances                      , TypeFamilies                      , FlexibleContexts