diff --git a/Project.toml b/Project.toml index e070d5a..a47120d 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" +version = "0.8.1" [deps] ComputedFieldTypes = "459fdd68-db75-56b8-8c15-d717a790f88e" diff --git a/README.md b/README.md index e0e4530..3809e8c 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,7 @@ The symmetrical algebra does not need to track this parity, but has higher multi Symmetric differential function algebra of Leibniz trivializes the orientation into a single class of index multi-sets, while Grassmann's exterior algebra is partitioned into two oriented equivalence classes by anti-symmetry. Full tensor algebra can be sub-partitioned into equivalence classes in multiple ways based on the element symmetry, grade, and metric signature composite properties. -By virtue of Julia's multiple dispatch on the field type `๐•‚`, methods can specialize on the dimension `n` and grade `G` with a `TensorBundle{n}` via the `TensorAlgebra{V}` subtypes, such as `Submanifold{V,G}`, `Simplex{V,G,B,๐•‚}`. +By virtue of Julia's multiple dispatch on the field type `๐•‚`, methods can specialize on the dimension `n` and grade `G` with a `TensorBundle{n}` via the `TensorAlgebra{V}` subtypes, such as `Submanifold{V,G}`, `Single{V,G,B,๐•‚}`. The elements of the `Basis` can be generated in many ways using the `Submanifold` elements created by the `@basis` macro, ```julia @@ -189,7 +189,7 @@ In order to work with a `TensorAlgebra{V}`, it is necessary for some computation Staging of precompilation and caching is designed so that a user can smoothly transition between very high dimensional and low dimensional algebras in a single session, with varying levels of extra caching and optimizations. The parametric type formalism in `DirectSum` is highly expressive and enables pre-allocation of geometric algebra computations involving specific sparse subalgebras, including the representation of rotational groups. -It is possible to reach `Simplex` elements with up to `N=62` vertices from a `TensorAlgebra` having higher maximum dimensions than supported by Julia natively. +It is possible to reach `Single` elements with up to `N=62` vertices from a `TensorAlgebra` having higher maximum dimensions than supported by Julia natively. The 62 indices require full alpha-numeric labeling with lower-case and capital letters. This now allows you to reach up to `4,611,686,018,427,387,904` dimensions with Julia `using DirectSum`. Then the volume element is ```julia vโ‚โ‚‚โ‚ƒโ‚„โ‚…โ‚†โ‚‡โ‚ˆโ‚‰โ‚€abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ diff --git a/src/DirectSum.jl b/src/DirectSum.jl index cbc368d..ddcac5e 100644 --- a/src/DirectSum.jl +++ b/src/DirectSum.jl @@ -360,42 +360,42 @@ for n โˆˆ 0:9 end """ - Simplex{V,G,B,๐•‚} <: TensorTerm{V,G} <: TensorGraded{V,G} + Single{V,G,B,๐•‚} <: TensorTerm{V,G} <: TensorGraded{V,G} -Simplex type with pseudoscalar `V::Manifold`, grade/rank `G::Int`, `B::Submanifold{V,G}`, field `๐•‚::Type`. +Single type with pseudoscalar `V::Manifold`, grade/rank `G::Int`, `B::Submanifold{V,G}`, field `๐•‚::Type`. """ -struct Simplex{V,G,B,T} <: TensorTerm{V,G} +struct Single{V,G,B,T} <: TensorTerm{V,G} v::T - Simplex{A,B,C,D}(t::E) where E<:D where {A,B,C,D} = new{submanifold(A),B,basis(C),D}(t) - Simplex{A,B,C,D}(t::E) where E<:TensorAlgebra{A} where {A,B,C,D} = new{submanifold(A),B,basis(C),D}(t) + Single{A,B,C,D}(t) where {A,B,C,D} = new{submanifold(A),B,basis(C),D}(t) + Single{A,B,C,D}(t::E) where E<:TensorAlgebra{A} where {A,B,C,D} = new{submanifold(A),B,basis(C),D}(t) end -export Simplex -@pure Simplex(b::Submanifold{V,G}) where {V,G} = Simplex{V}(b) -@pure Simplex{V}(b::Submanifold{V,G}) where {V,G} = Simplex{V,G,b,Int}(1) -Simplex{V}(v::T) where {V,T} = Simplex{V,0,Submanifold{V}(),T}(v) -Simplex{V}(v::S) where S<:TensorTerm where V = v -Simplex{V,G,B}(v::T) where {V,G,B,T} = Simplex{V,G,B,T}(v) -Simplex(v,b::S) where S<:TensorTerm{V} where V = Simplex{V}(v,b) -Simplex{V}(v,b::S) where S<:TensorAlgebra where V = v*b -Simplex{V}(v,b::Submanifold{V,G}) where {V,G} = Simplex{V,G}(v,b) -Simplex{V}(v,b::Submanifold{W,G}) where {V,W,G} = Simplex{V,G}(v,b) -function Simplex{V,G}(v::T,b::Submanifold{V,G}) where {V,G,T} - order(v)+order(b)>diffmode(V) ? Zero(V) : Simplex{V,G,b,T}(v) +export Single +@pure Single(b::Submanifold{V,G}) where {V,G} = Single{V}(b) +@pure Single{V}(b::Submanifold{V,G}) where {V,G} = Single{V,G,b,Int}(1) +Single{V}(v::T) where {V,T} = Single{V,0,Submanifold{V}(),T}(v) +Single{V}(v::S) where S<:TensorTerm where V = v +Single{V,G,B}(v::T) where {V,G,B,T} = Single{V,G,B,T}(v) +Single(v,b::S) where S<:TensorTerm{V} where V = Single{V}(v,b) +Single{V}(v,b::S) where S<:TensorAlgebra where V = v*b +Single{V}(v,b::Submanifold{V,G}) where {V,G} = Single{V,G}(v,b) +Single{V}(v,b::Submanifold{W,G}) where {V,W,G} = Single{V,G}(v,b) +function Single{V,G}(v::T,b::Submanifold{V,G}) where {V,G,T} + order(v)+order(b)>diffmode(V) ? Zero(V) : Single{V,G,b,T}(v) end -function Simplex{V,G}(v::T,b::Submanifold{W,G}) where {V,W,G,T} - order(v)+order(b)>diffmode(V) ? Zero(V) : Simplex{V,G,V(b),T}(v) +function Single{V,G}(v::T,b::Submanifold{W,G}) where {V,W,G,T} + order(v)+order(b)>diffmode(V) ? Zero(V) : Single{V,G,V(b),T}(v) end -function Simplex{V,G}(v::T,b::Submanifold{V,G}) where T<:TensorTerm where {G,V} - order(v)+order(b)>diffmode(V) ? Zero(V) : Simplex{V,G,b,Any}(v) +function Single{V,G}(v::T,b::Submanifold{V,G}) where T<:TensorTerm where {G,V} + order(v)+order(b)>diffmode(V) ? Zero(V) : Single{V,G,b,Any}(v) end -function Simplex{V,G,B}(b::T) where T<:TensorTerm{V} where {V,G,B} - order(B)+order(b)>diffmode(V) ? Zero(V) : Simplex{V,G,B,Any}(b) +function Single{V,G,B}(b::T) where T<:TensorTerm{V} where {V,G,B} + order(B)+order(b)>diffmode(V) ? Zero(V) : Single{V,G,B,Any}(b) end -Base.show(io::IO,m::Simplex) = Leibniz.showvalue(io,Manifold(m),UInt(basis(m)),value(m)) +Base.show(io::IO,m::Single) = Leibniz.showvalue(io,Manifold(m),UInt(basis(m)),value(m)) for VG โˆˆ ((:V,),(:V,:G)) - @eval function Simplex{$(VG...)}(v,b::Simplex{V,G}) where {V,G} - order(v)+order(b)>diffmode(V) ? Zero(V) : Simplex{V,G,basis(b)}(AbstractTensors.โˆ(v,b.v)) + @eval function Single{$(VG...)}(v,b::Single{V,G}) where {V,G} + order(v)+order(b)>diffmode(V) ? Zero(V) : Single{V,G,basis(b)}(AbstractTensors.โˆ(v,b.v)) end end @@ -403,7 +403,7 @@ equal(a::TensorTerm{V,G},b::TensorTerm{V,G}) where {V,G} = basis(a) == basis(b) for T โˆˆ (Fields...,Symbol,Expr) @eval begin - Base.isapprox(a::S,b::T;atol::Real=0,rtol::Real=Base.rtoldefault(a,b,atol),nans::Bool=false,norm::Function=LinearAlgebra.norm) where {S<:TensorAlgebra,T<:$T} = Base.isapprox(a,Simplex{Manifold(a)}(b);atol=atol,rtol=rtol,nans=nans,norm=norm) + Base.isapprox(a::S,b::T;atol::Real=0,rtol::Real=Base.rtoldefault(a,b,atol),nans::Bool=false,norm::Function=LinearAlgebra.norm) where {S<:TensorAlgebra,T<:$T} = Base.isapprox(a,Single{Manifold(a)}(b);atol=atol,rtol=rtol,nans=nans,norm=norm) Base.isapprox(a::S,b::T;atol::Real=0,rtol::Real=Base.rtoldefault(a,b,atol),nans::Bool=false,norm::Function=LinearAlgebra.norm) where {S<:$T,T<:TensorAlgebra} = Base.isapprox(b,a;atol=atol,rtol=rtol,nans=nans,norm=norm) end end @@ -412,18 +412,19 @@ for Field โˆˆ Fields TF = Field โˆ‰ Fields ? :Any : :T EF = Field โ‰  Any ? Field : ExprField @eval begin - Base.:*(a::F,b::Submanifold{V}) where {F<:$EF,V} = Simplex{V}(a,b) - Base.:*(a::Submanifold{V},b::F) where {F<:$EF,V} = Simplex{V}(b,a) - Base.:*(a::F,b::Simplex{V,G,B,T} where B) where {F<:$Field,V,G,T<:$Field} = Simplex{V,G}(Base.:*(a,b.v),basis(b)) - Base.:*(a::Simplex{V,G,B,T} where B,b::F) where {F<:$Field,V,G,T<:$Field} = Simplex{V,G}(Base.:*(a.v,b),basis(a)) - Base.adjoint(b::Simplex{V,G,B,T}) where {V,G,B,T<:$Field} = Simplex{dual(V),G,B',$TF}(Base.conj(value(b))) + Base.:*(a::F,b::Submanifold{V}) where {F<:$EF,V} = Single{V}(a,b) + Base.:*(a::Submanifold{V},b::F) where {F<:$EF,V} = Single{V}(b,a) + Base.:*(a::F,b::Single{V,G,B,T} where B) where {F<:$Field,V,G,T<:$Field} = Single{V,G}(Base.:*(a,b.v),basis(b)) + Base.:*(a::Single{V,G,B,T} where B,b::F) where {F<:$Field,V,G,T<:$Field} = Single{V,G}(Base.:*(a.v,b),basis(a)) + Base.adjoint(b::Single{V,G,B,T}) where {V,G,B,T<:$Field} = Single{dual(V),G,B',$TF}(Base.conj(value(b))) end end for M โˆˆ (:Signature,:DiagonalForm,:Submanifold) @eval begin - @inline (V::$M)(s::LinearAlgebra.UniformScaling{T}) where T = Simplex{V}(T<:Bool ? (s.ฮป ? 1 : -1) : s.ฮป,getbasis(V,(one(T)<<(mdims(V)-diffvars(V)))-1)) - (W::$M)(b::Simplex) = Simplex{W}(value(b),W(basis(b))) + @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)) + (W::$M)(b::Single) = Single{W}(value(b),W(basis(b))) + ==(::Type{<:$M}, ::Type{Union{}}) = false end end @@ -485,13 +486,12 @@ for T โˆˆ Fields end end -import AbstractTensors: clifford, complementleft, complementlefthodge -for op โˆˆ (:hodge,:clifford,:complementleft,:complementlefthodge,:involute) +import Base: reverse, conj +import AbstractTensors: hodge, clifford, complementleft, complementlefthodge +for op โˆˆ (:hodge,:clifford,:complementleft,:complementlefthodge,:involute,:conj,:reverse) @eval $op(t::Zero) = t end -@inline Base.exp(::Zero{V}) where V = One(V) - @inline Base.abs2(t::Zero) = t const g_zero,g_one = Zero,One diff --git a/src/basis.jl b/src/basis.jl index 7cc3771..1d7a74c 100644 --- a/src/basis.jl +++ b/src/basis.jl @@ -120,11 +120,11 @@ macro mixedbasis_str(str) Expr(:block,bases,alloc(V',vsn[2]),alloc(V),bases.args[end]) end -@inline function lookup_basis(V,v::Symbol)::Union{Simplex,Submanifold} +@inline function lookup_basis(V,v::Symbol)::Union{Single,Submanifold} p,b,w,z = indexparity(V,v) z && return g_zero(V) d = Submanifold{w}(indexbits(mdims(w),b)) - return p ? Simplex(-1,d) : d + return p ? Single(-1,d) : d end ## fundamentals @@ -281,10 +281,10 @@ Base.one(V::T) where T<:TensorBundle = One(V) Base.zero(V::T) where T<:TensorBundle = Zero(V) Base.zero(V::Submanifold) = Zero(V) Base.one(V::Submanifold{M}) where M = Submanifold{isbasis(V) ? M : V}() -Base.zero(::Simplex{V}) where V = Simplex{V}(0) -Base.one(::Simplex{V}) where V = Simplex{V}(1) -Base.zero(::Type{Simplex{V}}) where V = Simplex{V}(0) -Base.one(::Type{Simplex{V}}) where V = Simplex{V}(1) +Base.zero(::Single{V}) where V = Single{V}(0) +Base.one(::Single{V}) where V = Single{V}(1) +Base.zero(::Type{Single{V}}) where V = Single{V}(0) +Base.one(::Type{Single{V}}) where V = Single{V}(1) ## SparseAlgebra{V} diff --git a/src/generic.jl b/src/generic.jl index f4ff889..f666e0b 100644 --- a/src/generic.jl +++ b/src/generic.jl @@ -23,7 +23,7 @@ export valuetype, value, hasinf, hasorigin, isorigin, norm, indices, tangent, is #@pure Base.ndims(S::Submanifold{M,G}) where {G,M} = isbasis(S) ? mdims(M) : G @pure AbstractTensors.mdims(S::Submanifold{M,G}) where {G,M} = isbasis(S) ? mdims(M) : G @pure order(m::Submanifold{V,G,B} where G) where {V,B} = order(V)>0 ? count_ones(symmetricmask(V,B,B)[4]) : 0 -@pure order(m::Simplex) = order(basis(m))+order(value(m)) +@pure order(m::Single) = order(basis(m))+order(value(m)) @pure options(::T) where T<:TensorBundle{N,M} where N where M = M @pure options_list(V::M) where M<:Manifold = hasinf(V),hasorigin(V),dyadmode(V),polymode(V) @pure metric(::T) where T<:TensorBundle{N,M,S} where {N,M} where S = S @@ -44,7 +44,7 @@ export isdyadic, isdual, istangent @inline value(x::M,T=Int) where M<:TensorBundle = T==Any ? 1 : one(T) @inline value(::Submanifold,T=Int) = T==Any ? 1 : one(T) -@inline value(m::Simplex,T::DataType=valuetype(m)) = Tโˆ‰(valuetype(m),Any) ? convert(T,m.v) : m.v +@inline value(m::Single,T::DataType=valuetype(m)) = Tโˆ‰(valuetype(m),Any) ? convert(T,m.v) : m.v @pure basis(m::Zero{V}) where V = getbasis(V,UInt(0)) @pure basis(m::T) where T<:Submanifold = isbasis(m) ? m : Submanifold(m) @@ -52,13 +52,13 @@ export isdyadic, isdual, istangent for T โˆˆ (:T,:(Type{T})) @eval begin @pure valuetype(::$T) where T<:Submanifold = Int - @pure valuetype(::$T) where T<:Simplex{V,G,B,๐•‚} where {V,G,B} where ๐•‚ = ๐•‚ + @pure valuetype(::$T) where T<:Single{V,G,B,๐•‚} where {V,G,B} where ๐•‚ = ๐•‚ @pure isbasis(::$T) where T<:Submanifold{V} where V = issubmanifold(V) @pure isbasis(::$T) where T<:TensorBundle = false - @pure isbasis(::$T) where T<:Simplex = false - @pure basis(m::$T) where T<:Simplex{V,G,B} where {V,G} where B = B + @pure isbasis(::$T) where T<:Single = false + @pure basis(m::$T) where T<:Single{V,G,B} where {V,G} where B = B @pure UInt(b::$T) where T<:Submanifold{V,G,B} where {V,G} where B = B::UInt - @pure UInt(b::$T) where T<:Simplex = UInt(basis(b)) + @pure UInt(b::$T) where T<:Single = UInt(basis(b)) end end @pure det(s::Signature) = isodd(count_ones(metric(s))) ? -1 : 1 @@ -79,7 +79,7 @@ for (part,G) โˆˆ ((:scalar,0),(:vector,1),(:bivector,2)) end end for T โˆˆ (Expr,Symbol) - @eval @inline Base.iszero(t::Simplex{V,G,B,$T} where {V,G,B}) = false + @eval @inline Base.iszero(t::Single{V,G,B,$T} where {V,G,B}) = false end @pure val(G::Int) = Val{G}() @@ -89,10 +89,10 @@ grade(t::TensorGraded{V,L},g::Val{G}) where {V,G,L} = Zero(V) @pure hasinf(::T) where T<:TensorBundle{N,M} where N where M = _hasinf(M) @pure hasinf(::Submanifold{M,N,S} where N) where {M,S} = hasinf(M) && isodd(S) -@pure hasinf(t::Simplex) = hasinf(basis(t)) +@pure hasinf(t::Single) = hasinf(basis(t)) @pure hasorigin(::T) where T<:TensorBundle{N,M} where N where M = _hasorigin(M) @pure hasorigin(V::Submanifold{M,N,S} where N) where {M,S} = hasorigin(M) && (hasinf(M) ? (d=UInt(2);(d&S)==d) : isodd(S)) -@pure hasorigin(t::Simplex) = hasorigin(basis(t)) +@pure hasorigin(t::Single) = hasorigin(basis(t)) @pure Base.isinf(e::Submanifold{V}) where V = hasinf(e) && count_ones(UInt(e)) == 1 @pure isorigin(e::Submanifold{V}) where V = hasorigin(V) && count_ones(UInt(e))==1 && e[hasinf(V)+1] @@ -177,26 +177,26 @@ for r โˆˆ (:reverse,:involute,:(Base.conj),:clifford) p = Symbol(:parity,r==:(Base.conj) ? :conj : r) @eval begin @pure function $r(b::Submanifold{V,G,B}) where {V,G,B} - $p(grade(V,B)) ? Simplex{V}(-value(b),b) : b + $p(grade(V,B)) ? Single{V}(-value(b),b) : b end - $r(b::Simplex) = value(b) โ‰  0 ? Simplex(value(b),$r(basis(b))) : Zero(Manifold(b)) + $r(b::Single) = value(b) โ‰  0 ? Single(value(b),$r(basis(b))) : Zero(Manifold(b)) end end for op โˆˆ (:div,:rem,:mod,:mod1,:fld,:fld1,:cld,:ldexp) @eval begin Base.$op(a::Submanifold{V,G},m) where {V,G} = Submanifold{V,G}($op(value(a),m)) - Base.$op(b::Simplex{V,G,B,T},m) where {V,G,B,T} = Simplex{V,G,B}($op(value(b),m)) + Base.$op(b::Single{V,G,B,T},m) where {V,G,B,T} = Single{V,G,B}($op(value(b),m)) end end for op โˆˆ (:mod2pi,:rem2pi,:rad2deg,:deg2rad,:round) @eval begin Base.$op(a::Submanifold{V,G}) where {V,G} = Submanifold{V,G}($op(value(a))) - Base.$op(b::Simplex{V,G,B,T}) where {V,G,B,T} = Simplex{V,G,B}($op(value(b))) + Base.$op(b::Single{V,G,B,T}) where {V,G,B,T} = Single{V,G,B}($op(value(b))) end end Base.rationalize(t::Type,a::Submanifold{V,G},tol::Real=eps(T)) where {V,G} = Submanifold{V,G}(rationalize(t,value(a),tol)) -Base.rationalize(t::Type,b::Simplex{V,G,B,T};tol::Real=eps(T)) where {V,G,B,T} = Simplex{V,G,B}(rationalize(t,value(b),tol)) +Base.rationalize(t::Type,b::Single{V,G,B,T};tol::Real=eps(T)) where {V,G,B,T} = Single{V,G,B}(rationalize(t,value(b),tol)) # random samplers @@ -206,10 +206,10 @@ Base.rand(::AbstractRNG,::SamplerType{Manifold}) where V = Submanifold(Manifold( Base.rand(::AbstractRNG,::SamplerType{Submanifold}) = rand(Submanifold{rand(Manifold)}) Base.rand(::AbstractRNG,::SamplerType{Submanifold{V}}) where V = Submanifold{V}(UInt(rand(0:1<