Skip to content

Commit 8c60c81

Browse files
committed
add embed()
1 parent 58b8946 commit 8c60c81

File tree

5 files changed

+57
-8
lines changed

5 files changed

+57
-8
lines changed

src/GeometricAlgebra.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export geometric_prod,
2424
sandwich_prod
2525
export reversion, involution
2626
export flipdual, hodgedual, invhodgedual, ldual, rdual
27-
export matrix_repr, outermorphism
27+
export matrix_repr, outermorphism, embed
2828
export @symbolicga
2929
export MiniCAS
3030

src/MiniCAS/algebra.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ const Π = ProductNode
1010
const Σ = SumNode
1111

1212
Base.copy(a::Union{Π,Σ}) = typeof(a)(copy(a.x))
13+
Base.broadcastable(a::Union{Π,Σ}) = Ref(a)
1314

1415
(a: == b:) = a.x == b.x
1516
(a: == b:) = a.x == b.x

src/algebra.jl

Lines changed: 41 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,8 +44,8 @@ Base.:isapprox(a::Scalar, b::AbstractMultivector; kwargs...) = isapprox(zero(b)
4444
scalar_multiply(a::BasisBlade{Sig,K}, b) where {Sig,K} = BasisBlade{Sig,K}(a.coeff*b, a.bits)
4545
scalar_multiply(a, b::BasisBlade{Sig,K}) where {Sig,K} = BasisBlade{Sig,K}(a*b.coeff, b.bits)
4646

47-
scalar_multiply(a::Multivector, b) = constructor(a)(a.comps*b)
48-
scalar_multiply(a, b::Multivector) = constructor(b)(a*b.comps)
47+
scalar_multiply(a::Multivector, b) = constructor(a)(a.comps.*b)
48+
scalar_multiply(a, b::Multivector) = constructor(b)(a.*b.comps)
4949

5050
Base.:*(a::AbstractMultivector, b::Scalar) = scalar_multiply(a, b)
5151
Base.:*(a::Scalar, b::AbstractMultivector) = scalar_multiply(a, b)
@@ -633,7 +633,46 @@ function outermorphism(mat::AbstractMatrix, a::AbstractMultivector{Sig}; sig=Sig
633633
end
634634
outermorphism(mat, a::Scalar) = a
635635

636+
"""
637+
embed(sig, a::Multivector)
638+
639+
Embed a multivector into the algebra of metric signature `sig`, adding or discarding dimensions as necessary.
640+
641+
Basis vectors in the original and new spaces are associated by the order in which they appear.
642+
Components are dropped if `dimension(sig) < dimension(a)`, and extra zero components are added
643+
if `dimension(sig) > dimension(a)`.
636644
645+
# Examples
646+
```jldoctest
647+
julia> embed(Cl(2,2), Multivector{3,2}([1, 2, 3]))
648+
6-component Multivector{Cl(2,2), 2, SVector{6, Float64}}:
649+
1.0 v12
650+
2.0 v13
651+
3.0 v23
652+
0.0 v14
653+
0.0 v24
654+
0.0 v34
655+
656+
julia> embed(2, Multivector{3,1}([1,2,3]))
657+
2-component Multivector{2, 1, SVector{2, Int64}}:
658+
1 v1
659+
2 v2
660+
```
661+
"""
662+
function embed(sig, a::Multivector)
663+
T = Multivector{sig,grade(a)}
664+
b = zero(T)
665+
for k in grade(a)
666+
n_orig = ncomponents(signature(a), k)
667+
n_new = ncomponents(sig, k)
668+
if n_new > n_orig
669+
b += Multivector{sig,k}([a[k].comps; zeros(n_new - n_orig)])
670+
else
671+
b += Multivector{sig,k}(a[k].comps[1:n_new])
672+
end
673+
end
674+
b
675+
end
637676

638677
unit_pseudoscalar(::Val{Sig}) where {Sig} = let dim = dimension(Sig)
639678
BasisBlade{Sig,dim}(1, bits_dual(dim, UInt(0)))

src/generated.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@ end
142142

143143
@generated function symbolic_multivector_eval(::Val{Sig}, f::Function, args...) where Sig
144144
@assert isdefined(f, :instance)
145-
1
145+
2
146146
symbolic_multivector_eval(Expr, Val(Sig), f.instance, args...)
147147
end
148148

@@ -180,11 +180,11 @@ To do this, the metric signatures in `args` are replaced with the equivalent can
180180
of the first `AbstractMultivector` argument in `args`.
181181
(The actual signature is lost because signatures are converted to canonical tuples.)
182182
"""
183-
function symbolic_optim(f::Function, args...)
183+
function symbolic_optim(f::Function, args...; sig::Val=first_signature(args...))
184184
# we’re replacing objects’ type parameters, so type stability is a little delicate
185185
args′ = map(canonicalize, args)
186-
Sig::Val = first_signature(args...) # guess the original (non-canonical) signature of f(args...)
187-
result = symbolic_multivector_eval(Sig, f, args′...)
186+
# Sig::Val = first_signature(args...) # guess the original (non-canonical) signature of f(args...)
187+
result = symbolic_multivector_eval(sig, f, args′...)
188188
end
189189

190190
"""

test/algebra.jl

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -274,4 +274,13 @@ end
274274
@inferred ab
275275
@inferred (ab)(v12b)*I
276276
end
277-
end
277+
end
278+
279+
@testset "embed" begin
280+
a = Multivector{3,1}(1, 2, 3)
281+
@test embed(4, a) == Multivector{4,1}(1, 2, 3, 0)
282+
@test embed(2, a) == Multivector{2,1}(1, 2)
283+
284+
a = randn(Multivector{3,0:3})
285+
@test embed(3, embed(Cl(4,1), a)) == a
286+
end

0 commit comments

Comments
 (0)