#Complex promotion rules between types with numeric parameters

1 messages · Page 1 of 1 (latest)

summer oak
#

I've asked about this in the past, but since the help channels were archived I thought it would be wise to start a thread.

Currently, I have some related types that work with multivectors from geometric algebra:

# Used to store information about the Clifford algebra an `AbstractMultivector` belongs to
struct CliffordAlgebra{P,N,Z} end
dimension(::Type{CliffordAlgebra{P,N,Z}}) where {P,N,Z} = P+N+Z

abstract type AbstractMultivector{Cl<:CliffordAlgebra,T<:Number} end

# Contains all grades; L is the total length of the data, 2^(P+N+Z)
struct Multivector{Cl,T,L}
    ...
end

# Contains only the even grades; L = 2^(P+N+Z-1)
struct EvenMultivector{Cl,T,L}
    ...
end

# Contains a single grade, K, L = binomial(dimension(Cl),K)
struct KVector{Cl,K,T,L}
    ...
end

Now, I want to define a promotion rule so that when you add two KVectors of different grades, it can convert to an EvenMultivector if both grades are even and a Multivector otherwise. Basically this:

function Base.promote_rule(::Type{<:KVector{Cl,K1,T1}}, ::Type{<:KVector{Cl,K2,T2}}) where {Cl,K1,K2,T1,T2}
    T = promote_type(T1,T2)
    return iseven(K1) && iseven(K2) ? EvenMultivector{Cl,T,2^(dimension(Cl) - 1)} : Multivector{Cl,T,2^dimension(Cl)}
end

Is there a way to accomplish something like this while achieving type stability? I know that the easy solution is just to promote pairs of KVectors with different grades to a Multivector every time (which is how I currently have it), but I'm more so just curious if an optimization like this could be made.

cyan cloud
#

I feel like I already answered that you can do this with macros, it generates the correct type on compile time that way

#

if you do it at runtime inside a function it cannot be type stable