Open c42f opened 7 years ago
I'm wondering if our earlier attempt at having AbstactAffineTransformation
as an interface and a set of abstract types (or perhaps traits?) would let us resolve this.
Perhaps something like this would work...
type TypedTransformation{OutType,IntermediateType,InType,WrappedTrans}
wrapped::WrappedTrans
end
function (trans::TypedTransformation{OutType,IntermediateType,InType}){OutType,IntermediateType,InType}(x::InType)
OutType(trans.wrapped(IntermediateType(x)))
end
function compose{Out,Intermed,InOut,In}(t1::TypedTransformation{Out,Intermed,InOut}, t2::TypedTransformation{InOut,Intermed,In})
TypedTransformation{Out,Intermed,In}(ComposedTransformation(t1, t2))
end
Hmmm... interesting. The call
function can be achieved as a ComposedTransformation
already - the trick here is the compose
implementation.
IntermediateType
is rather interesting... it doesn't necessarily have to be a type for all this to work, e.g. if InType
and OutType
are AbstractVector
and WrappedTrans
is AffineTransformation
then we are OK if IntermediateType = identity
. Possibly suggests a reordering of the type-params with a default IntermediateType
.
All very interesting! Can you see this working for nonlinear transformations? (I.e. things which aren't wrapped AffineMap
s?) If not, maybe we just want to implement TypedAffineMap
, TypedLinearMap
and TypedTranslation
.
Can you see this working for nonlinear transformations
For generic differential geometry you're probably transforming between different coordinate systems (for a shared patch of a manifold), and probably want a single coordinate type say PointCoord
for concrete (but coordinate system independent) representation of points.
If we then chose to specially name a particular subset of coordinate systems for convenience or type safety, we lift some information into the type domain. To me this is quite generic and shouldn't be restricted to affine transformations.
To be more concrete, I'd say this is exactly what we're doing with the motivation behind this (ie, defining NED, ENU frames etc): we've chosen to bless certain of the coordinate system information available to us by putting it in the type system.
Sorry... how does PointCoord
work? Is this like PointCoord{UTM}
or something? Or
immutable PointCoord{T <: Tuple}
data::T
end
where T
just mimics the fields of some actual type and PointCoord
is internal?
All I'm getting at is something like FixedSizeArrays.Point
: a type for representing the generic position of a point on some manifold, in some coordinate system. Not that I really know what Point
is I guess - I'm not sure we decide whether there was something implicitly affine there, or that it was a general coordinate type.
I chose the naming PointCoord
rather than Point
to emphasize that this is just the coordinates of a point in a coordinate system, not the abstract point on the manifold itself. (I know, I know, choosing a coordinate system is probably the only practical way to represent a point on a computer. The confusion is that the same mathematical point on the manifold has multiple representations, one from each coordinate system... not sure how to model this nicely.)
Back in #1 we decided that
Transformation
was agnostic about input and output coordinate types. I still think this was the right thing, but sometimes you may want a bit more checking of the input and output types. This is perfectly possible when creating a customTransformation
functor, but it would be nice to be able to reuse the composition and inverse rules of existing types likeAffineMap
andLinearMap
.