Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Problems with using subtypes of StaticArrays.FieldVector in perpendicular_vector() #265

Closed
tamasgal opened this issue Sep 20, 2023 · 2 comments · Fixed by #268
Closed

Problems with using subtypes of StaticArrays.FieldVector in perpendicular_vector() #265

tamasgal opened this issue Sep 20, 2023 · 2 comments · Fixed by #268

Comments

@tamasgal
Copy link

tamasgal commented Sep 20, 2023

Sometimes my code crashes because of a missing method of Rotations. perpendicular_vector while every other method in in Rotations.jl happily takes my custom StaticArrays.FieldVectors.

Here is what I mean, given some simple subtyping as recommended in the StaticArray.jl docs, we define Dir which works fine and is taken as FieldVector{3, Float64} and indices of SOneTo(3), so all fine:

julia> struct Dir <: FieldVector{3, Float64}
           x::Float64
           y::Float64
           z::Float64
       end

julia> d = Dir(1, 0, 0)
3-element Dir with indices SOneTo(3):
 1.0
 0.0
 0.0

julia> R = rand(RotMatrix{3})
3×3 RotMatrix3{Float64} with indices SOneTo(3)×SOneTo(3):
 -0.9449     0.324235  -0.0451206
 -0.254104  -0.639555   0.725535
  0.206387   0.697023   0.686705

julia> R * d
3-element Dir with indices SOneTo(3):
 -0.9448998601049303
 -0.2541038561489163
  0.2063867356782747

Now the problem: in some rotations, the perpendicular_vector is called (I have not traced down when this happens but it does not happen that much in my code, so it's something which is triggered by specific constellations of the vectors) and that method only accepts subtypes of SVector{3}:

julia> Rotations.perpendicular_vector(d)
ERROR: MethodError: no method matching perpendicular_vector(::Dir)

Closest candidates are:
  perpendicular_vector(::SVector{3})
   @ Rotations ~/.julia/packages/Rotations/vUzHx/src/util.jl:8

Stacktrace:
 [1] top-level scope
   @ REPL[17]:1

Can we widen the input type domain or is there a specific reason why SVector{3} has been chosen?

Btw. I aways assumed that FieldVector{3, Float64} is a subtype of SVector{3} but apparently it's not:

julia> FieldVector{3, Float64} <: SVector{3}
false

Edit: btw. the current workaround is wrapping the custom struct into SVector{3}. The problem is that I need to do this at the beginning of the chain (when calling the rotation functions) and then I also get SVector{3} back, which introduces type instabilities since there are other methods in my code which expect Dir.

Calling the "private" method at least works:

julia> Rotations.perpendicular_vector(SVector{3}(d))
3-element SVector{3, Float64} with indices SOneTo(3):
 -0.0
  1.0
  0.0
@hyrodium
Copy link
Collaborator

Thank you for creating the issue! Here's a MWE:

julia> using Rotations, StaticArrays

julia> u = MVector(1,0,0)
3-element MVector{3, Int64} with indices SOneTo(3):
 1
 0
 0

julia> v = MVector(-1,0,0)
3-element MVector{3, Int64} with indices SOneTo(3):
 -1
  0
  0

julia> rotation_between(u,v)
ERROR: MethodError: no method matching perpendicular_vector(::MVector{3, Int64})

Closest candidates are:
  perpendicular_vector(::SVector{3})
   @ Rotations ~/.julia/dev/Rotations/src/util.jl:8

Stacktrace:
 [1] rotation_between(u::MVector{3, Int64}, v::MVector{3, Int64})
   @ Rotations ~/.julia/dev/Rotations/src/rotation_between.jl:23
 [2] top-level scope
   @ REPL[4]:1

@tamasgal
Copy link
Author

Awesome, many thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants