Class Transformed<V extends RealVector>

java.lang.Object
com.apple.foundationdb.linear.Transformed<V>
Type Parameters:
V - the wrapped kind of RealVector

public final class Transformed<V extends RealVector> extends Object
This class aims to reduce potential logic problems with respect to coordinate transformations by soliciting help from Java's type system.

While implementing complex algorithms that required coordinate transformations, some problems seemed to occur repeatedly and the following observations were made:

  • A few algorithms use an API that passes vectors back and forth in a coordinate system given by the user. Internally, however, the same algorithms transform these vectors into some other coordinate system that is more advantageous to the algorithm in some way. Therefore, vectors are constantly transformed back and forth between the respective coordinate systems.
  • We observed cases where there are mixtures of vectors handled withing the same methods, i.e. some vectors were expressed using the internal and some vectors were expressed using the external coordinate system. Problems occur when these vectors are intermingled and the coordinate system mappings of the individual vectors are lost.
  • We observed cases where a vector is transformed from one coordinate system to another one and then erroneously transformed a second time.

The following approach only makes sense for scenarios that deal with exactly two coordinate systems.

We would like to express vectors in one system by RealVector whereas the vectors in the secondary system are expressed using Transformed of RealVector. The hope is that Java's compiler can assist in avoiding using the wrong sort of vector in the wrong situation. While it is possible to circumvent these best-effort type system-imposed restrictions, this class is meant to be utilized in a more pragmatic way.

Objects of this class wrap some vector of type V creating a transformed vector. The visibility of this class' constructor is package-private by design. Only operators implementing VectorOperator can transform an instance of type V extends RealVector into a Transformed object. The same is true for inverse transformations: only operators can transform a Transformed vector back to the original vector.

In other places where Transformeds are created (and destructed) users should be aware of exactly what happens and why. We tried to restrict visibilities of constructors and accessors, but due to Java's lack in expressiveness when it comes to type system finesse, this is a best-effort approach. If a Transformed is deconstructed using getUnderlyingVector(), the user should ensure that the resulting vector is not further transformed by e.g. another affine operator. In short, we want to avoid users to write code similar to someNewOperator.transform(oldTransformed.getUnderlyingVector() as the result would be a transformed vector that is in fact transformed a second time. Note that this can make sense in some cases, however, in the described use case it mostly does not.