From 0a5e007c82388bfe34cfcf275ebe0b609049480d Mon Sep 17 00:00:00 2001 From: Michael Reed <18372368+chakravala@users.noreply.github.com> Date: Sat, 6 Apr 2024 16:08:55 -0400 Subject: [PATCH] refined metric, antimetric, complements, etc --- Project.toml | 2 +- src/DirectSum.jl | 4 ++-- src/generic.jl | 4 ++-- src/operations.jl | 57 +++++++++++++++++++++++++++++++++++++---------- 4 files changed, 50 insertions(+), 17 deletions(-) diff --git a/Project.toml b/Project.toml index 4f342c4..cc0df10 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "DirectSum" uuid = "22fd7b30-a8c0-5bf2-aabe-97783860d07c" authors = ["Michael Reed"] -version = "0.8.8" +version = "0.8.9" [deps] ComputedFieldTypes = "459fdd68-db75-56b8-8c15-d717a790f88e" diff --git a/src/DirectSum.jl b/src/DirectSum.jl index 3660e5d..a03f4d8 100644 --- a/src/DirectSum.jl +++ b/src/DirectSum.jl @@ -454,7 +454,7 @@ end for M ∈ (:Signature,:DiagonalForm,:Submanifold) @eval begin - @inline (V::$M)(s::LinearAlgebra.UniformScaling{T}) where T = Single{V}(T<:Bool ? (s.λ ? 1 : -1) : s.λ,getbasis(V,(one(T)<<(mdims(V)-diffvars(V)))-1)) + @inline (V::$M)(s::LinearAlgebra.UniformScaling{T}) where T = Single{V}(T<:Bool ? (s.λ ? 1 : -1) : s.λ,getbasis(V,(one(UInt)<<(mdims(V)-diffvars(V)))-1)) (W::$M)(b::Single) = Single{W}(value(b),W(basis(b))) ==(::Type{<:$M}, ::Type{Union{}}) = false end @@ -544,7 +544,7 @@ end @inline Base.abs2(t::Zero) = t -const g_zero,g_one = Zero,One +const g_zero = Zero @pure One(::Type{T}) where T = one(T) @pure Zero(::Type{T}) where T = zero(T) diff --git a/src/generic.jl b/src/generic.jl index 395f0fa..1ff3f93 100644 --- a/src/generic.jl +++ b/src/generic.jl @@ -47,7 +47,7 @@ export antigrade, antireverse, antiinvolute, anticlifford n,C = mdims(M),diffmode(M) sum(in.(1+n-(C<0 ? 2 : 1)*diffvars(M):n,Ref(indices(S)))) end -for mode ∈ (:options,:metric,:polymode,:dyadmode,:diffmode) +for mode ∈ (:options,:polymode,:dyadmode,:diffmode) @eval @pure $mode(::Submanifold{M}) where M = $mode(M) end @@ -81,7 +81,7 @@ end @pure volume(t::Submanifold{V,G}) where {V,G} = G == mdims(V) ? t : Zero(V) @pure isvolume(t::Submanifold) = rank(t) == mdims(V) -for (part,G) ∈ ((:scalar,0),(:vector,1),(:bivector,2)) +for (part,G) ∈ ((:scalar,0),(:vector,1),(:bivector,2),(:trivector,3)) ispart = Symbol(:is,part) @eval begin @pure $part(t::Submanifold{V,$G} where V) = t diff --git a/src/operations.jl b/src/operations.jl index 4ccc146..a0621c5 100644 --- a/src/operations.jl +++ b/src/operations.jl @@ -194,11 +194,11 @@ end if Q == V if G == M == 1 y,v = evaluate1(W,b) - y ? g_zero(V) : v*Submanifold{V}() + y ? Zero(V) : v*Submanifold{V}() elseif G == 1 && M == 2 (!isdyadic(V)) && throw(error("wrong basis")) y,v,B = evaluate2(W,b) - y ? g_zero(V) : v*getbasis(V,B) + y ? Zero(V) : v*getbasis(V,B) else throw(error("unsupported transformation")) end @@ -209,7 +209,7 @@ end return Submanifold{Submanifold(W),G}(R) elseif W⊆V S = UInt(W) - count_ones(R&S)==G ? getbasis(W,lowerbits(mdims(V),S,R)) : g_zero(W) + count_ones(R&S)==G ? getbasis(W,lowerbits(mdims(V),S,R)) : Zero(W) elseif V⊆W WC,VC = isdyadic(W),isdyadic(V) #if ((C1≠C2)&&(C1≥0)&&(C2≥0)) @@ -238,34 +238,34 @@ end (a::Single)(b::T) where {T<:TensorAlgebra} = interform(a,b) function (a::Submanifold{V,1})(b::Single{V,1}) where V y,v = evaluate1(a,b) - y ? g_zero(V) : (v*b.v)*Submanifold{V}() + y ? Zero(V) : (v*b.v)*Submanifold{V}() end function (a::Single{V,1})(b::Submanifold{V,1}) where V y,v = evaluate1(a,b) - y ? g_zero(V) : (v*a.v)*Submanifold{V}() + y ? Zero(V) : (v*a.v)*Submanifold{V}() end @eval begin function (a::Single{V,1})(b::Single{V,1}) where V $(insert_expr((:t,))...) y,v = evaluate1(a,b) - y && (return g_zero(V)) - y ? g_zero(V) : Single{V}((v*a.v*b.v)::t,Submanifold{V}()) + y && (return Zero(V)) + y ? Zero(V) : Single{V}((v*a.v*b.v)::t,Submanifold{V}()) end end function (a::Single{V,2})(b::Submanifold{V,1}) where V (!isdyadic(V)) && throw(error("wrong basis")) y,v,B = evaluate2(a,b) - @inbounds y ? g_zero(V) : (v*a.v)*getbasis(V,B) + @inbounds y ? Zero(V) : (v*a.v)*getbasis(V,B) end function (a::Submanifold{V,2})(b::Single{V,1}) where V (!isdyadic(V)) && throw(error("wrong basis")) y,v,B = evaluate2(a,b) - @inbounds y ? g_zero(V) : (v*b.v)*getbasis(V,B) + @inbounds y ? Zero(V) : (v*b.v)*getbasis(V,B) end function (a::Single{V,2})(b::Single{V,1}) where V (!isdyadic(V)) && throw(error("wrong basis")) y,v,B = evaluate2(a,b) - @inbounds y ? g_zero(V) : (v*a.v*b.v)*getbasis(V,B) + @inbounds y ? Zero(V) : (v*a.v*b.v)*getbasis(V,B) end ## complement parity @@ -304,11 +304,28 @@ for side ∈ (:left,:right) end end +for Q ∈ (:DiagonalForm,:Submanifold) + @eval begin + @pure function paritymetric(V::$Q,B,G=count_ones(B)) + prod(V[indices(B&(UInt(1)<<(mdims(V)-diffvars(V))-1),mdims(V))]) + end + @pure function parityanti(V::$Q,B) + paritymetric(V,complement(mdims(V),B,diffvars(V),hasinf(V)+hasorigin(V))) + end + end +end +@pure paritymetric(::Submanifold{V,G,B}) where {V,G,B} = paritymetric(V,B,G) +@pure parityanti(::Submanifold{V,G,B}) where {V,G,B} = parityanti(V,B) + ## complement import Leibniz: complementright, complementrighthodge, ⋆, complement -import AbstractTensors: complementleft, complementlefthodge +import AbstractTensors: complementleft, complementlefthodge, complementleftanti, complementrightanti, antimetric export complementleft, complementright, ⋆, complementlefthodge, complementrighthodge +export complementleftanti, complementrightanti + +@inline complementrightanti(t) = complementright(antimetric(t)) +@inline complementleftanti(t) = complementleft(antimetric(t)) for side ∈ (:left,:right) s,p = Symbol(:complement,side),Symbol(:parity,side) @@ -321,11 +338,27 @@ for side ∈ (:left,:right) v = $(c≠h ? :($pn(V,B,value(d))) : :(value(d))) typeof(V)<:Signature ? ($p(b) ? Single{V}(-v,d) : isone(v) ? d : Single{V}(v,d)) : Single{V}($p(b)*v,d) end - $c(b::Single) = value(b)≠0 ? conj(value(b))*$c(basis(b)) : g_zero(Manifold(b)) + $c(b::Single) = conj(value(b))*$c(basis(b)) end end end +@eval begin + @pure function metric(b::Submanifold{V,G,B}) where {V,G,B} + !isbasis(b) && (return metric(V)) + isdyadic(V) && throw(error("Complement for mixed tensors is undefined")) + p = paritymetric(b) + typeof(V)<:Signature ? (p ? -b : b ) : Single{V}(p,b) + end + metric(b::Single) = conj(value(b))*metric(basis(b)) + @pure function antimetric(b::Submanifold{V,G,B}) where {V,G,B} + isdyadic(V) && throw(error("Complement for mixed tensors is undefined")) + p = parityanti(b) + typeof(V)<:Signature ? (p ? -b : b ) : Single{V}(p,b) + end + antimetric(b::Single) = conj(value(b))*antimetric(basis(b)) +end + # other import Leibniz: parityinvolute, parityreverse