Why is Vector3D unrelated to RealVector?

Hello,

I’ve been trying to do a matrix-vector product using a 3x3 RealMatrix instance and a Vector3D instance. The method of the RealMatrix interface for matrix-vector product is the .operate method, which takes a RealVector as input (or a double[] but it is not my point here).

However, the Vector3D class is not a subclass of RealVector, nor does it have any link with it. This seems counterintuitive to me. The .operate(RealVector) is thus unusuable here.

To do this matrix-vector product, it seems that one need to convert the Vector3D to a double[], use the .operate(double[]) method, and then convert the output double array back to Vector3D, which I find to be a clunky way of doing things.

Am I missing something here? Are the objects I use not the good ones to do what I am trying to do? Or should Vector3D be a subclass of RealVector ?

Cheers,
Guillaume

Hi Guillaume,

I believe this behavior and architecture are inherited from Apache’s Common Math, of which Hipparchus was originally a fork. From what I can see in the documentation and the code itself, RealVector is intended for Linear Algebra while Vector3D is an object for geometrical problems. They might even have been implemented completely independently.
I’ll let other developers comment on a potential workaround or judge if modifications are necessary at this stage.

Romain.

1 Like

Hi!

I agree with Romain’s remark. The two objects have two different purposes. Vector3D is design for geometrical operations while RealVector is a more a N-dimension container for algebra operations. Therefore, RealVector can be used to store and do operations on data like a state vector or a measurement residuals vector. I think the difference between the two objects is very important.

Because there is a method toArray() in Vector3D class, maybe we could also have a method toRealVector(). (We should also add it in Vector2D)

Something like:

public RealVector toRealVector() {
   return MatrixUtils.createRealVector(toArray());
}

Do you think this method could be useful for you?

Best regards,
Bryan

Yes, Vector3D' belongs to the geometry module, which depends on the core module that contains the linear algebra stuff. There are some geometry specific operations that could be considered as linear transforms, but they are semantically at a higher level. As an example, you can apply a Rotationto aVector3D`, but it is not necessarily the same as multiplying a 3x3 matrix and a 3x1 vector. In fact, it is not done this way as we use quaternions to implement rotations, not matrices.

So blurring the distinction between high level geometry and low level linear algebra is against the current design choices. What could however be changed in would fit nicely in the architecture is to provide more geometrical operators like translation, translation-rotation combinations and similar things. This is what the `Transform’ in Orekit do.

Thanks for all your answers !

I think I understand better why Vector3D does not extend RealVector as of the development history hindsight you gave me. My point was not to change what RealVector is used for, but rather to let Vector3D be seen as this kind of N-dimension container (with N = 3). However I understand that this could be against the current design choice of separating geometry and linear algebra.

Do you think this method could be useful for you?

I don’t think adding this method will really change anything in my case, because it is a matter of code clunkyness and not of actually performing the computation. My issue here is that because the .operate method does not handle Vector3D, the following:

RealMatrix matrix = someRealMatrix();
Vector3D vector = someVector3D();
Vector3D output = matrix.operate(vector);

does not work, and we have to use a workaround like :

RealMatrix matrix = someRealMatrix();
Vector3D vector = someVector3D();
Vector3D output = new Vector3D(matrix.operate(vector.toArray()));

which I think is more tedious than needed. Adding the .toRealVector() in the Vector3D class would lead to similar cumbersome :

RealMatrix matrix = someRealMatrix();
Vector3D vector = someVector3D();
Vector3D output = new Vector3D(matrix.operate(vector.toRealVector()));

As an example, you can apply a Rotation to a Vector3D, but it is not necessarily the same as multiplying a 3x3 matrix and a 3x1 vector. In fact, it is not done this way as we use quaternions to implement rotations, not matrices.

I agree that rotation should indeed be represented with Rotation instances and not by RealMatrix ones, however in my case the matrix I need to use is not a rotation matrix (it is an inertia matrix), so the Rotation class is not the appropriate way to represent it. But maybe once again I am not using the proper tools to solve my problem?

Anyway, thank you again for all your answers and sorry if I am too verbose to express my issue.

Cheers,
Guillaume