Skip to content

The output type of some operations should be mainly QuatRotation #253

Description

@hyrodium

With the current implementation, the output types of some operations such as * are inconsistent.

julia> RotX(1) * RotYZX(1,2,3)
3×3 RotMatrix3{Float64} with indices SOneTo(3)×SOneTo(3):
 -0.224845   0.605127   -0.763718
  0.196633   0.795841    0.572689
  0.954348  -0.0214059  -0.297929

julia> MRP(1,2,3) * QuatRotation(1,2,3,4)
3×3 RotMatrix3{Float64} with indices SOneTo(3)×SOneTo(3):
  0.0325926  -0.514963  0.856593
  0.992593    0.117037  0.0325926
 -0.117037    0.849185  0.514963

julia> MRP(1,2,3) * MRP(2,3,4)
3×3 MRP{Float64} with indices SOneTo(3)×SOneTo(3)(-0.152589, -0.247956, -0.376022):
 -0.0795062  0.975486  -0.205195
 -0.57284    0.123753   0.810272
  0.815802   0.181965   0.548958

julia> RotX(1) * AngleAxis(1,2,3,4.0)
3×3 RotMatrix3{Float64} with indices SOneTo(3)×SOneTo(3):
 0.603709  -0.529919    0.595585
 0.676841  -0.0540276  -0.734144
 0.421215   0.846325    0.326054

julia> AngleAxis(1,2,3,4.0) * AngleAxis(1,2,3,4.0)
3×3 QuatRotation{Float64} with indices SOneTo(3)×SOneTo(3)(QuaternionF64(0.540302, 0.312514, 0.468772, 0.625029)):
 -0.220816  -0.382413  0.897218
  0.968405   0.023347  0.248287
 -0.115896   0.923696  0.365176

The following is a full list of return types of *.

julia> RotTypes = subtypes(Rotation{3})
27-element Vector{Any}:
 AngleAxis
 MRP
 QuatRotation
 RodriguesParam
 RotMatrix{3}
 RotX
 RotXY
 RotXYX
 RotXYZ
 RotXZ
 RotXZX
 RotXZY
 RotY
 RotYX
 RotYXY
 RotYXZ
 RotYZ
 RotYZX
 RotYZY
 RotZ
 RotZX
 RotZXY
 RotZXZ
 RotZY
 RotZYX
 RotZYZ
 RotationVec

julia> [typeof(one(R1)*one(R2)) for R1 in RotTypes, R2 in RotTypes]
27×27 Matrix{DataType}:
 QuatRotation{Float64}  RotMatrix3{Float64}  QuatRotation{Float64}  RotMatrix3{Float64}      RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  QuatRotation{Float64}
 RotMatrix3{Float64}    MRP{Float64}         RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotMatrix3{Float64}     RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 QuatRotation{Float64}  RotMatrix3{Float64}  QuatRotation{Float64}  RotMatrix3{Float64}      RotMatrix3{Float64}  RotMatrix3{Float64}     RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  QuatRotation{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RodriguesParam{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}     RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Int64}    RotMatrix3{Float64}     RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotX{Float64}          RotXZX{Float64}      RotMatrix3{Float64}  RotMatrix3{Float64}  RotXZY{Float64}      RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotXYX{Float64}         RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotXYX{Float64}         RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotMatrix3{Float64}     RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotXZX{Float64}         RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotXZX{Float64}        RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotMatrix3{Float64}     RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotYX{Float64}          RotYZX{Float64}      RotMatrix3{Float64}  RotMatrix3{Float64}  RotYZY{Float64}      RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotYX{Float64}          RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotMatrix3{Float64}     RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotYZX{Float64}         RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotYZX{Float64}         RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotMatrix3{Float64}     RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotZX{Float64}          RotZX{Float64}       RotZXY{Float64}      RotZXZ{Float64}      RotZY{Float64}       RotZYX{Float64}      RotZYZ{Float64}      RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotZX{Float64}         RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotMatrix3{Float64}     RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotMatrix3{Float64}     RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotZYX{Float64}         RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotZYX{Float64}         RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}      RotMatrix3{Float64}  RotMatrix3{Float64}    RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}
 QuatRotation{Float64}  RotMatrix3{Float64}  QuatRotation{Float64}  RotMatrix3{Float64}      RotMatrix3{Float64}  RotMatrix3{Float64}     RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  RotMatrix3{Float64}  QuatRotation{Float64}

RotMatrix3 is the most used return type, but I think this should be QuatRotation because it is more efficient.
However, I am not sure we would like to have *(::RotMatrix, ::RodriguesVec) is RotMatrix or QuatRotation. (x-ref: #190)

This issue is not just about the multiplication *, but also includes other operations such as /, ^, sqrt(#234) etc.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions