I have a custom struct Body
(shown below). For another struct, I’d like to be able to keep vectors of Body
variables, and I’d like to be able to promote Body{Float32}
to Body{Float64}
, Body{Float64}
to Body{BigFloat}
, etc.
The following definition does run, but it still doesn’t allow for Body
promotion.
julia> promote_rule(::Type{Body{A}}, ::Type{Body{B}}) where {A<:AbstractFloat, B<:AbstractFloat} = Body{promote_type(A, B)}
julia> b1 = Body(Float32.([1, 2, 3]u"m"), Float32.([1,2,3]u"m/s"), Float32(1u"kg"))
julia> b2 = Body(Float64.([1, 2, 3]u"m"), Float64.([1,2,3]u"m/s"), Float64(1u"kg"))
julia> promote(b1, b2)
ERROR: promotion of types Body{Float32} and Body{Float64} failed to change any arguments
Is what I’m trying to do possible?
Body
Definition:
using Unitful
using StaticArrays
struct Body{F<:AbstractFloat}
r̅::SVector{3, Unitful.Length{F}}
v̅::SVector{3, Unitful.Velocity{F}}
m::Unitful.Mass{F}
function Body(r::R, v::V, m::M) where {
T <: AbstractFloat,
R <: AbstractVector{Unitful.Length{T}},
V <: AbstractVector{Unitful.Velocity{T}},
M <: Unitful.Mass{T}
}
if length(r) ≢ length(v) ≢ 3
error("The `Body` constructor requires 3 element vectors for position `r` and velocity `v`")
else
return new{T}(SVector{3}(T.(r)), SVector{3}(T.(v)), M(T(m)))
end
end
end