Copyright | (c) Justus Sagemüller 2016 |
---|---|
License | GPL v3 |
Maintainer | (@) sagemueller $ geo.uni-koeln.de |
Stability | experimental |
Portability | portable |
Safe Haskell | Safe |
Language | Haskell2010 |
- data BoundarylessWitness m where
- BoundarylessWitness :: (Semimanifold m, Interior m ~ m) => BoundarylessWitness m
- data SemimanifoldWitness x where
- SemimanifoldWitness :: (Semimanifold (Needle x), Needle (Interior x) ~ Needle x, Needle (Needle x) ~ Needle x, Interior (Needle x) ~ Needle x) => BoundarylessWitness (Interior x) -> SemimanifoldWitness x
- data PseudoAffineWitness x where
- PseudoAffineWitness :: (PseudoAffine (Interior x), PseudoAffine (Needle x)) => SemimanifoldWitness x -> PseudoAffineWitness x
- class AdditiveGroup (Needle x) => Semimanifold x where
- class Semimanifold x => PseudoAffine x where
- data FibreBundle b f = FibreBundle {
- baseSpace :: !(Interior b)
- fibreSpace :: !f
- type TangentBundle m = FibreBundle m (Needle m)
- palerp :: forall x. (PseudoAffine x, VectorSpace (Needle x)) => x -> x -> Maybe (Scalar (Needle x) -> x)
- palerpB :: forall x. (PseudoAffine x, VectorSpace (Needle x), Scalar (Needle x) ~ ℝ) => x -> x -> Maybe (D¹ -> x)
- alerpB :: forall x. (AffineSpace x, VectorSpace (Diff x), Scalar (Diff x) ~ ℝ) => x -> x -> D¹ -> x
- hugeℝVal :: ℝ
- tau :: ℝ
- toS¹range :: ℝ -> ℝ
- toℝP¹range :: ℝ -> ℝ
- toUnitrange :: ℝ -> ℝ
- data NeedleProductSpace f g p = NeedleProductSpace !(Needle (f p)) !(Needle (g p))
- data InteriorProductSpace f g p = InteriorProductSpace !(Interior (f p)) !(Interior (g p))
- newtype GenericNeedle x = GenericNeedle {
- getGenericNeedle :: Needle (VRep x)
- newtype GenericInterior x = GenericInterior {
- getGenericInterior :: Interior (VRep x)
- type VRep x = Rep x Void
Documentation
data BoundarylessWitness m where Source #
BoundarylessWitness :: (Semimanifold m, Interior m ~ m) => BoundarylessWitness m |
data SemimanifoldWitness x where Source #
This is the reified form of the property that the interior of a semimanifold
is a manifold. These constraints would ideally be expressed directly as
superclass constraints, but that would require the UndecidableSuperclasses
extension, which is not reliable yet.
Also, if all those equality constraints are in scope, GHC tends to infer needlessly
complicated types like
, which is
the same as just Interior
(Interior
(Needle
(Interior
x)))
.Needle
x
SemimanifoldWitness :: (Semimanifold (Needle x), Needle (Interior x) ~ Needle x, Needle (Needle x) ~ Needle x, Interior (Needle x) ~ Needle x) => BoundarylessWitness (Interior x) -> SemimanifoldWitness x |
data PseudoAffineWitness x where Source #
PseudoAffineWitness :: (PseudoAffine (Interior x), PseudoAffine (Needle x)) => SemimanifoldWitness x -> PseudoAffineWitness x |
class AdditiveGroup (Needle x) => Semimanifold x where Source #
The space of “natural” ways starting from some reference point
and going to some particular target point. Hence,
the name: like a compass needle, but also with an actual length.
For affine spaces, Needle
is simply the space of
line segments (aka vectors) between two points, i.e. the same as Diff
.
The AffineManifold
constraint makes that requirement explicit.
This space should be isomorphic to the tangent space (and is in fact used somewhat synonymously).
Manifolds with boundary are a bit tricky. We support such manifolds, but carry out most calculations only in “the fleshy part” – the interior, which is an “infinite space”, so you can arbitrarily scale paths.
The default implementation is
, which corresponds
to a manifold that has no boundary to begin with.Interior
x = x
(.+~^) :: Interior x -> Needle x -> x infixl 6 Source #
Generalised translation operation. Note that the result will always also be in the interior; scaling up the needle can only get you ever closer to a boundary.
fromInterior :: Interior x -> x Source #
id
sans boundary.
toInterior :: x -> Maybe (Interior x) Source #
toInterior :: (Generic x, Semimanifold (VRep x), Interior x ~ GenericInterior x) => x -> Maybe (Interior x) Source #
translateP :: Tagged x (Interior x -> Needle x -> Interior x) Source #
The signature of .+~^
should really be
,
only, this is not possible because it only consists of non-injective type families.
The solution is this tagged signature, which is of course rather unwieldy. That's
why Interior
x -> Needle
x -> Interior
x.+~^
has the stronger, but easier usable signature. Without boundary, these
functions should be equivalent, i.e. translateP = Tagged (.+~^)
.
translateP :: (Generic x, Semimanifold (VRep x), Interior x ~ GenericInterior x, Needle x ~ GenericNeedle x) => Tagged x (Interior x -> Needle x -> Interior x) Source #
The signature of .+~^
should really be
,
only, this is not possible because it only consists of non-injective type families.
The solution is this tagged signature, which is of course rather unwieldy. That's
why Interior
x -> Needle
x -> Interior
x.+~^
has the stronger, but easier usable signature. Without boundary, these
functions should be equivalent, i.e. translateP = Tagged (.+~^)
.
(.-~^) :: Interior x -> Needle x -> x infixl 6 Source #
Shorthand for \p v -> p .+~^
, which should obey the asymptotic lawnegateV
v
p .-~^ v .+~^ v ≅ p
Meaning: if v
is scaled down with sufficiently small factors η, then
the difference (p.-~^v.+~^v) .-~. p
should scale down even faster:
as O (η²). For large vectors, it will however behave differently,
except in flat spaces (where all this should be equivalent to the AffineSpace
instance).
semimanifoldWitness :: SemimanifoldWitness x Source #
semimanifoldWitness :: (Semimanifold (Interior x), Semimanifold (Needle x), Interior (Interior x) ~ Interior x, Needle (Interior x) ~ Needle x, Needle (Needle x) ~ Needle x, Interior (Needle x) ~ Needle x) => SemimanifoldWitness x Source #
Semimanifold Double Source # | |
Semimanifold Rational Source # | |
Semimanifold D¹ Source # | |
Semimanifold ℝP¹ Source # | |
Semimanifold S¹ Source # | |
Semimanifold ℝP⁰ Source # | |
Semimanifold S⁰ Source # | |
Semimanifold (ZeroDim k) Source # | |
Semimanifold (VRep x) => Semimanifold (GenericInterior x) Source # | |
AdditiveGroup (Needle (VRep x)) => Semimanifold (GenericNeedle x) Source # | |
(Semimanifold a, Semimanifold b) => Semimanifold (a, b) Source # | |
Semimanifold a => Semimanifold (Rec0 * a s) Source # | |
(Semimanifold a, Semimanifold b, Semimanifold c) => Semimanifold (a, b, c) Source # | |
(Semimanifold (f p), Semimanifold (g p)) => Semimanifold (InteriorProductSpace f g p) Source # | |
(Semimanifold (f p), Semimanifold (g p)) => Semimanifold (NeedleProductSpace f g p) Source # | |
(Semimanifold (f p), Semimanifold (g p)) => Semimanifold ((:*:) * f g p) Source # | |
Semimanifold (f p) => Semimanifold (M1 * i c f p) Source # | |
class Semimanifold x => PseudoAffine x where Source #
This is the class underlying manifolds. (Manifold
only precludes boundaries
and adds an extra constraint that would be circular if it was in a single
class. You can always just use Manifold
as a constraint in your signatures,
but you must define only PseudoAffine
for manifold types –
the Manifold
instance follows universally from this, if 'Interior x ~ x
.)
The interface is (boundaries aside) almost identical to the better-known
AffineSpace
class, but we don't require associativity of .+~^
with ^+^
– except in an asymptotic sense for small vectors.
That innocent-looking change makes the class applicable to vastly more general types:
while an affine space is basically nothing but a vector space without particularly
designated origin, a pseudo-affine space can have nontrivial topology on the global
scale, and yet be used in practically the same way as an affine space. At least the
usual spheres and tori make good instances, perhaps the class is in fact equivalent to
manifolds in their usual maths definition (with an atlas of charts: a family of
overlapping regions of the topological space, each homeomorphic to the Needle
vector space or some simply-connected subset thereof).
(.-~.) :: x -> x -> Maybe (Needle x) infix 6 Source #
The path reaching from one point to another.
Should only yield Nothing
if
- The points are on disjoint segments of a non–path-connected space.
- Either of the points is on the boundary. Use
|-~.
to deal with this.
On manifolds, the identity
p .+~^ (q.-~.p) ≡ q
should hold, at least save for floating-point precision limits etc..
.-~.
and .+~^
only really work in manifolds without boundary. If you consider
the path between two points, one of which lies on the boundary, it can't really
be possible to scale this path any longer – it would have to reach “out of the
manifold”. To adress this problem, these functions basically consider only the
interior of the space.
(.-~!) :: HasCallStack => x -> x -> Needle x infix 6 Source #
Unsafe version of .-~.
. If the two points lie in disjoint regions,
the behaviour is undefined.
pseudoAffineWitness :: PseudoAffineWitness x Source #
pseudoAffineWitness :: (PseudoAffine (Interior x), PseudoAffine (Needle x)) => PseudoAffineWitness x Source #
PseudoAffine Double Source # | |
PseudoAffine Rational Source # | |
PseudoAffine D¹ Source # | |
PseudoAffine ℝP¹ Source # | |
PseudoAffine S¹ Source # | |
PseudoAffine ℝP⁰ Source # | |
PseudoAffine S⁰ Source # | |
PseudoAffine (ZeroDim k) Source # | |
PseudoAffine (VRep x) => PseudoAffine (GenericInterior x) Source # | |
AdditiveGroup (Needle (VRep x)) => PseudoAffine (GenericNeedle x) Source # | |
(PseudoAffine a, PseudoAffine b) => PseudoAffine (a, b) Source # | |
PseudoAffine a => PseudoAffine (Rec0 * a s) Source # | |
(PseudoAffine a, PseudoAffine b, PseudoAffine c) => PseudoAffine (a, b, c) Source # | |
(PseudoAffine (f p), PseudoAffine (g p)) => PseudoAffine (InteriorProductSpace f g p) Source # | |
(PseudoAffine (f p), PseudoAffine (g p)) => PseudoAffine (NeedleProductSpace f g p) Source # | |
(PseudoAffine (f p), PseudoAffine (g p)) => PseudoAffine ((:*:) * f g p) Source # | |
PseudoAffine (f p) => PseudoAffine (M1 * i c f p) Source # | |
data FibreBundle b f Source #
A fibre bundle combines points in the base space b
with points in the fibre
f
. The type FibreBundle b f
is thus isomorphic to the tuple space (b,f)
, but
it can have a different topology, the prime example being TangentBundle
, where
nearby points may have differently-oriented tangent spaces.
FibreBundle | |
|
(Show (Interior b), Show f) => Show (FibreBundle b f) Source # | |
Generic (FibreBundle b f) Source # | |
type Rep (FibreBundle b f) Source # | |
type TangentBundle m = FibreBundle m (Needle m) Source #
Points on a manifold, combined with vectors in the respective tangent space.
palerp :: forall x. (PseudoAffine x, VectorSpace (Needle x)) => x -> x -> Maybe (Scalar (Needle x) -> x) Source #
Interpolate between points, approximately linearly. For points that aren't close neighbours (i.e. lie in an almost flat region), the pathway is basically undefined – save for its end points.
A proper, really well-defined (on global scales) interpolation
only makes sense on a Riemannian manifold, as Geodesic
.
palerpB :: forall x. (PseudoAffine x, VectorSpace (Needle x), Scalar (Needle x) ~ ℝ) => x -> x -> Maybe (D¹ -> x) Source #
Like palerp
, but actually restricted to the interval between the points,
with a signature like geodesicBetween
rather than alerp
.
alerpB :: forall x. (AffineSpace x, VectorSpace (Diff x), Scalar (Diff x) ~ ℝ) => x -> x -> D¹ -> x Source #
Like alerp
, but actually restricted to the interval between the points.
toℝP¹range :: ℝ -> ℝ Source #
toUnitrange :: ℝ -> ℝ Source #
data NeedleProductSpace f g p Source #
NeedleProductSpace !(Needle (f p)) !(Needle (g p)) |
data InteriorProductSpace f g p Source #
InteriorProductSpace !(Interior (f p)) !(Interior (g p)) |
Generic (InteriorProductSpace f g p) Source # | |
(PseudoAffine (f p), PseudoAffine (g p)) => PseudoAffine (InteriorProductSpace f g p) Source # | |
(Semimanifold (f p), Semimanifold (g p)) => Semimanifold (InteriorProductSpace f g p) Source # | |
type Rep (InteriorProductSpace f g p) Source # | |
type Needle (InteriorProductSpace f g p) Source # | |
type Interior (InteriorProductSpace f g p) Source # | |
newtype GenericNeedle x Source #
GenericNeedle | |
|
Generic (GenericNeedle x) Source # | |
AdditiveGroup (Needle (VRep x)) => AffineSpace (GenericNeedle x) Source # | |
VectorSpace (Needle (VRep x)) => VectorSpace (GenericNeedle x) Source # | |
InnerSpace (Needle (VRep x)) => InnerSpace (GenericNeedle x) Source # | |
AdditiveGroup (Needle (VRep x)) => AdditiveGroup (GenericNeedle x) Source # | |
AdditiveGroup (Needle (VRep x)) => PseudoAffine (GenericNeedle x) Source # | |
AdditiveGroup (Needle (VRep x)) => Semimanifold (GenericNeedle x) Source # | |
type Rep (GenericNeedle x) Source # | |
type Diff (GenericNeedle x) Source # | |
type Scalar (GenericNeedle x) Source # | |
type Needle (GenericNeedle x) Source # | |
type Interior (GenericNeedle x) Source # | |
newtype GenericInterior x Source #
Generic (GenericInterior x) Source # | |
PseudoAffine (VRep x) => PseudoAffine (GenericInterior x) Source # | |
Semimanifold (VRep x) => Semimanifold (GenericInterior x) Source # | |
type Rep (GenericInterior x) Source # | |
type Needle (GenericInterior x) Source # | |
type Interior (GenericInterior x) Source # | |