Skip to content

Commit

Permalink
simplified generated algebra dispatch
Browse files Browse the repository at this point in the history
  • Loading branch information
chakravala committed Sep 13, 2020
1 parent d8a4012 commit 5228f28
Show file tree
Hide file tree
Showing 3 changed files with 323 additions and 359 deletions.
65 changes: 37 additions & 28 deletions src/algebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -410,33 +410,36 @@ for T ∈ (:Real,:Complex)
generate_inverses(Base,T)
end

### Sum Algebra Constructor
### Algebra Constructors

const NSE = Union{Symbol,Expr,<:Real,<:Complex}
insert_t(x) = Expr(:block,:(t=promote_type(valuetype(a),valuetype(b))),x)

Base.:-(t::SubManifold) = Simplex(-value(t),t)
addvec(a,b,s,o) = o :+ ? subvec(a,b,s) : addvec(a,b,s)
addvec(a,b,s) = isfixed(a,b) ? (:($Sym.:∑),:($Sym.:∑),:svec) : (:+,:+,:mvec)
subvec(a,b,s) = isfixed(a,b) ? (s ? (:($Sym.:-),:($Sym.:∑),:svec) : (:($Sym.:∑),:($Sym.:-),:svec)) : (s ? (:-,:+,:mvec) : (:+,:-,:mvec))

for (op,eop) ((:+,:(+=)),(:-,:(-=)))
for Term (:TensorGraded,:TensorMixed)
@eval begin
$op(a::T,b::NSE) where T<:$Term = iszero(b) ? a : $op(a,b*g_one(Manifold(a)))
$op(a::NSE,b::T) where T<:$Term = iszero(a) ? $op(b) : $op(a*g_one(Manifold(b)),b)
end
end
@eval begin
@generated function $op(a::SubManifold{V,L},b::SubManifold{V,G}) where {V,L,G}
adder(a,b,nothing,$(QuoteNode(op)),:mvec)
end
end
end
subvec(b) = isfixed(valuetype(b)) ? (:($Sym.:-),:svec,:($Sym.:∏)) : (:-,:mvec,:*)
conjvec(b) = isfixed(valuetype(b)) ? (:($Sym.conj),:svec) : (:conj,:mvec)

mulvec(a,b) = isfixed(a,b) ? (:($Sym.:∏),:svec) : (:*,:mvec)
isfixed(a,b) = isfixed(valuetype(a))&&isfixed(valuetype(b))
isfixed(::Type{Rational{BigInt}}) = true
isfixed(::Type{BigFloat}) = true
isfixed(::Type{BigInt}) = true
isfixed(::Type{Complex{BigFloat}}) = true
isfixed(::Type{Complex{BigInt}}) = true
isfixed(::Type{<:Number}) = false
isfixed(::Type{<:Any}) = true

const NSE = Union{Symbol,Expr,<:Real,<:Complex}

@inline swapper(a,b,swap) = swap ? (b,a) : (a,b)

adder(a,b,left=:+,right=:+) = adder(typeof(a),typeof(b),left,right)
adder(a::Type,b::Type,left=:+,right=:+) = adder(a,b,left,right,:mvec)
adder(a,b,op=:+) = adder(typeof(a),typeof(b),op)

@eval begin
@noinline function adder(a::Type{<:TensorTerm{V,L}},b::Type{<:TensorTerm{V,G}},left,bop,VEC) where {V,L,G}
@noinline function adder(a::Type{<:TensorTerm{V,L}},b::Type{<:TensorTerm{V,G}},op) where {V,L,G}
left,bop,VEC = addvec(a,b,false,op)
if basis(a) == basis(b)
:(Simplex{V,L}($bop(value(a),value(b)),basis(a)))
elseif L == G
Expand Down Expand Up @@ -469,7 +472,8 @@ adder(a::Type,b::Type,left=:+,right=:+) = adder(a,b,left,right,:mvec)
return MultiVector{V}(out)
end end
end
@noinline function adder(a::Type{<:TensorTerm{V,G}},b::Type{<:Chain{V,G,T}},left,right,VEC,swap=false) where {V,G,T}
@noinline function adder(a::Type{<:TensorTerm{V,G}},b::Type{<:Chain{V,G,T}},op,swap=false) where {V,G,T}
left,right,VEC = addvec(a,b,swap,op)
if binomial(mdims(V),G)<(1<<cache_limit)
$(insert_expr((:N,:ib,:t),:svec)...)
out = zeros(svec(N,G,Any))
Expand All @@ -493,7 +497,8 @@ adder(a::Type,b::Type,left=:+,right=:+) = adder(a,b,left,right,:mvec)
return Chain{V,G}(out)
end end end
end
@noinline function adder(a::Type{<:TensorTerm{V,L}},b::Type{<:Chain{V,G,T}},left,right,VEC,swap=false) where {V,G,T,L}
@noinline function adder(a::Type{<:TensorTerm{V,L}},b::Type{<:Chain{V,G,T}},op,swap=false) where {V,G,T,L}
left,right,VEC = addvec(a,b,swap,op)
if mdims(V)<cache_limit
$(insert_expr((:N,:ib,:bn,:t),:svec)...)
out = zeros(svec(N,Any))
Expand Down Expand Up @@ -528,7 +533,8 @@ adder(a::Type,b::Type,left=:+,right=:+) = adder(a,b,left,right,:mvec)
return MultiVector{V}(out)
end end end
end
@noinline function adder(a::Type{<:TensorTerm{V,G}},b::Type{<:MultiVector{V,T}},left,right,VEC,swap=false) where {V,G,T}
@noinline function adder(a::Type{<:TensorTerm{V,G}},b::Type{<:MultiVector{V,T}},op,swap=false) where {V,G,T}
left,right,VEC = addvec(a,b,swap,op)
if mdims(V)<cache_limit
$(insert_expr((:N,:bs,:bn,:t),:svec)...)
out = zeros(svec(N,Any))
Expand All @@ -555,7 +561,8 @@ adder(a::Type,b::Type,left=:+,right=:+) = adder(a,b,left,right,:mvec)
return MultiVector{V}(out)
end end end
end
@noinline function product(a::Type{S},b::Type{<:Chain{V,G,T}},MUL,VEC,swap=false) where S<:TensorGraded{V,L} where {V,G,L,T}
@noinline function product(a::Type{S},b::Type{<:Chain{V,G,T}},swap=false) where S<:TensorGraded{V,L} where {V,G,L,T}
MUL,VEC = mulvec(a,b)
if G == 0
return S<:Chain ? :(Chain{V,L}(broadcast($MUL,a.v,Ref(b[1])))) : swap ? :(b[1]*a) : :(a*b[1])
elseif S<:Chain && L == 0
Expand Down Expand Up @@ -622,7 +629,8 @@ adder(a::Type,b::Type,left=:+,right=:+) = adder(a,b,left,right,:mvec)
return MultiVector{V}(out)
end end
end
@noinline function product_contraction(a::Type{S},b::Type{<:Chain{V,G,T}},MUL,VEC,swap=false) where S<:TensorGraded{V,L} where {V,G,T,L}
@noinline function product_contraction(a::Type{S},b::Type{<:Chain{V,G,T}},swap=false) where S<:TensorGraded{V,L} where {V,G,T,L}
MUL,VEC = mulvec(a,b)
(swap ? G<L : L<G) && (!istangent(V)) && (return g_zero(V))
GL = swap ? G-L : L-G
if binomial(mdims(V),G)*(S<:Chain ? binomial(mdims(V),L) : 1)<(1<<cache_limit)
Expand Down Expand Up @@ -723,7 +731,8 @@ for (op,po,GL,grass) ∈ ((:∧,:>,:(G+L),:exter),(:∨,:<,:(G+L-mdims(V)),:meet
grassaddmulti!_pre = Symbol(grassaddmulti!,:_pre)
grassaddblade!_pre = Symbol(grassaddblade!,:_pre)
prop = Symbol(:product_,op)
@eval @noinline function $prop(a::Type{S},b::Type{<:Chain{R,L,T}},MUL,VEC,swap=false) where S<:TensorGraded{Q,G} where {Q,R,T,G,L}
@eval @noinline function $prop(a::Type{S},b::Type{<:Chain{R,L,T}},swap=false) where S<:TensorGraded{Q,G} where {Q,R,T,G,L}
MUL,VEC = mulvec(a,b)
w,W = swap ? (R,Q) : (Q,R)
V = w==W ? w : ((w==dual(W)) ? (dyadmode(w)0 ? Ww : wW) : (return :(interop($$op,a,b))))
$po(G+L,mdims(V)) && (!istangent(V)) && (return g_zero(V))
Expand Down Expand Up @@ -835,9 +844,9 @@ for (op,product!) ∈ ((:∧,:exteraddmulti!),(:*,:geomaddmulti!),
(:,:meetaddmulti!),(:contraction,:skewaddmulti!))
preproduct! = Symbol(product!,:_pre)
prop = op:* ? Symbol(:product_,op) : :product
@eval $prop(a,b,MUL=:+) = $prop(typeof(a),typeof(b),MUL)
@eval $prop(a::Type,b::Type,MUL=:+) = $prop(a,b,MUL,:mvec)
@eval @noinline function $prop(a::Type{S},b::Type{<:MultiVector{V,T}},MUL,VEC,swap=false) where S<:TensorGraded{V,G} where {V,G,T}
@eval $prop(a,b,swap=false) = $prop(typeof(a),typeof(b),swap)
@eval @noinline function $prop(a::Type{S},b::Type{<:MultiVector{V,T}},swap=false) where S<:TensorGraded{V,G} where {V,G,T}
MUL,VEC = mulvec(a,b)
if mdims(V)<cache_limit
$(insert_expr((:N,:t,:out,:ib,:bs,:bn,),:svec)...)
for g 1:N+1
Expand Down
3 changes: 3 additions & 0 deletions src/multivectors.jl
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,9 @@ export valuetype, scalar, isscalar, vector, isvector, indices

@pure valuetype(::Chain{V,G,T} where {V,G}) where T = T
@pure valuetype(::MultiVector{V,T} where V) where T = T
@pure valuetype(::Type{<:Chain{V,G,T} where {V,G}}) where T = T
@pure valuetype(::Type{<:MultiVector{V,T} where V}) where T = T

@inline value(m::Chain,T=valuetype(m)) = T(valuetype(m),Any) ? convert(T,m.v) : m.v
@inline value(m::MultiVector,T=valuetype(m)) = T(valuetype(m),Any) ? convert(T,m.v) : m.v
@inline value_diff(m::Chain{V,0} where V) = (v=value(m)[1];istensor(v) ? v : m)
Expand Down
Loading

2 comments on commit 5228f28

@chakravala
Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@JuliaRegistrator register()

@JuliaRegistrator
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Registration pull request created: JuliaRegistries/General/21306

After the above pull request is merged, it is recommended that a tag is created on this repository for the registered package version.

This will be done automatically if the Julia TagBot GitHub Action is installed, or can be done manually through the github interface, or via:

git tag -a v0.7.1 -m "<description of version>" 5228f2868de087e1f155842f132769cea7ea8d9c
git push origin v0.7.1

Please sign in to comment.