Quaternionic.jl
Quaternionic.jl copied to clipboard
Broadcast algebra
We should be able to broadcast-multiply floats with quaternions, but this errors out:
julia> t = collect(LinRange(-10, 10, 201));
julia> t .* imz
MethodError: no method matching Float64(::QuaternionF64)
Closest candidates are:
(::Type{T})(::T) where T<:Number at boot.jl:760
(::Type{T})(::AbstractChar) where T<:Union{AbstractChar, Number} at char.jl:50
(::Type{T})(::Base.TwicePrecision) where T<:Number at twiceprecision.jl:243
...
Stacktrace:
[1] convert(#unused#::Type{Float64}, x::QuaternionF64)
@ Base ./number.jl:7
[2] setindex!(A::Vector{Float64}, x::QuaternionF64, i1::Int64)
@ Base ./array.jl:839
[3] macro expansion
@ ./broadcast.jl:984 [inlined]
[4] macro expansion
@ ./simdloop.jl:77 [inlined]
[5] copyto!
@ ./broadcast.jl:983 [inlined]
[6] copyto!
@ ./broadcast.jl:936 [inlined]
[7] copy
@ ./broadcast.jl:908 [inlined]
[8] materialize(bc::Base.Broadcast.Broadcasted{Base.Broadcast.DefaultArrayStyle{1}, Nothing, typeof(*), Tuple{Vector{Float64}, Quaternion{Bool}}})
@ Base.Broadcast ./broadcast.jl:883
[9] top-level scope
@ In[80]:1
[10] eval
@ ./boot.jl:360 [inlined]
[11] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
@ Base ./loading.jl:1094
imz .* t too
On the other hand, [imz] .* t and t .* [imz] work correctly...
I think something like this might do what I need:
struct QuaternionStyle{T} <: Broadcast.BroadcastStyle where {T} end
function Base.BroadcastStyle(::Type{AT}) where {T, AT<:Quaternion{T}}
QuaternionStyle{T}()
end
function Base.BroadcastStyle(::QuaternionStyle{T}, ::Base.Broadcast.DefaultArrayStyle{N}) where {T, N}
return QuaternionStyle{T}()
end
function Base.similar(bc::Broadcast.Broadcasted{QuaternionStyle{T}}, ::Type{ElType}) where {T, ElType}
similar(Array{Quaternion{promote_type(T, ElType)}}, axes(bc))
end
The main problem is what to do about the other subtypes with their special operations. Should I have those types broadcast to Quaternion by default, but then specialize broadcast for certain functions (*, /, +, -, exp, log, sqrt...) and combinations of subtypes?