@@ -39,11 +39,11 @@ import Leibniz: parityrightnull, parityleftnull, parityrightnullpre, parityleftn
3939import Leibniz: hasconformal, parval, TensorTerm, mixed, subs, sups, vio, gdims
4040
4141import Leibniz: grade, order, options, metric, polymode, dyadmode, diffmode, diffvars
42- import Leibniz: pseudograde, hasinf, hasorigin, norm, indices, isbasis, Bits, bits, ≅
42+ import Leibniz: pseudograde, hasinf, hasorigin, norm, indices, isbasis, ≅
4343import Leibniz: isdyadic, isdual, istangent, involute, basis, alphanumv, alphanumw
4444
4545import Leibniz: algebra_limit, sparse_limit, cache_limit, fill_limit
46- import Leibniz: binomial, binomial_set , binomsum, binomsum_set , lowerbits, expandbits
46+ import Leibniz: binomial, gdimsall , binomsum, binomcumsum , lowerbits, expandbits
4747import Leibniz: bladeindex, basisindex, indexbasis, indexbasis_set, loworder, intlog
4848import Leibniz: promote_type, mvec, svec, intlog, insert_expr, indexparity!
4949
@@ -52,6 +52,8 @@ import Leibniz: promote_type, mvec, svec, intlog, insert_expr, indexparity!
5252"""
5353 TensorBundle{n,ℙ,g,ν,μ} <: Manifold{n}
5454
55+ A manifold representing the space of tensors with a given metric and basis for projection.
56+
5557Let `n` be the rank of a `Manifold{n}`.
5658The type `TensorBundle{n,ℙ,g,ν,μ}` uses *byte-encoded* data available at pre-compilation, where
5759`ℙ` specifies the basis for up and down projection,
@@ -62,26 +64,67 @@ Lastly, `ν` is the number of tangent variables.
6264abstract type TensorBundle{n,Options,Metrics,Vars,Diff,Name} <: Manifold{n,Int} end
6365rank (:: TensorBundle{n} ) where n = n
6466mdims (M:: TensorBundle ) = rank (M)
67+ # Return the manifold dimension (i.e., rank) of a tensor bundle.
68+
69+ """
70+ tensorhash(d, o; c=0, C=0) -> Int
6571
66- @pure doc2m (d,o,c = 0 ,C = 0 ) = ( 1 << (d - 1 )) | ( 1 << ( 2 * o - 1 )) | (c < 0 ? 8 : ( 1 << ( 3 * c - 1 ))) | ( 1 << ( 5 * C - 1 ))
72+ Compute a unique integer representation for a set of options.
6773
68- const names_cache = NTuple{4 ,String}[]
69- function names_index (a:: NTuple{4,String} )
70- if a ∈ names_cache
71- findfirst (x-> x== a,names_cache)
72- else
73- push! (names_cache,a)
74- length (names_cache)
74+ # Arguments:
75+ - `d`: Number of tangent variables (corresponds to `ν`).
76+ - `o`: Order of Leibniz-Taylor monomials multiplicity limit (corresponds to `μ`).
77+ - `c`: Coefficient used to specify the metric (corresponds to `g`). Defaults to 0.
78+ - `C`: Additional coefficient. Defaults to 0.
79+
80+ # Returns
81+ A unique integer representation that can be used as a cache key.
82+ """
83+ @pure function tensorhash (d,o,c= 0 ,C= 0 )
84+ (1 << (d- 1 ))| (1 << (2 * o- 1 ))| (c< 0 ? 8 : (1 << (3 * c- 1 )))| (1 << (5 * C- 1 ))
85+ end
86+
87+ const namecache = NTuple{4 ,String}[]
88+
89+ """
90+ nameindex(a::NTuple{4, String}) -> Int
91+
92+ Get a unique index for a set of name options, based on a cached result.
93+ """
94+ function nameindex (a:: NTuple{4,String} )
95+ if a ∈ namecache # check if options are in cache
96+ findfirst (x-> x== a,namecache)
97+ else # cache the options and add them to the list
98+ push! (namecache,a)
99+ length (namecache)
75100 end
76101end
77- @pure names_index (V:: T ) where T<: TensorBundle{N,M,S,F,D,Q} where {N,M,S,F,D} where Q = Q
78- @pure names_index (V:: T ) where T<: Manifold = names_index (supermanifold (V))
79- @pure names_index (V:: Int ) = 1
80- @pure namelist (V) = names_cache[names_index (V)]
81102
82- # vector and co-vector prefix
83- names_index (pre)
84- names_index (PRE)
103+ # initialize vector and co-vector prefix
104+ nameindex (pre)
105+ nameindex (PRE)
106+
107+ """
108+ nameindex(V::T) -> Int
109+
110+ Returns the name index for `V` when `V` is a `TensorBundle` or `Manifold`.
111+ """
112+ @pure nameindex (V:: T ) where T<: TensorBundle{N,M,S,F,D,Q} where {N,M,S,F,D} where Q = Q
113+ @pure nameindex (V:: T ) where T<: Manifold = nameindex (supermanifold (V))
114+
115+ """
116+ nameindex(V::Int) -> Int
117+
118+ Returns a default name index for an integer input.
119+ """
120+ @pure nameindex (V:: Int ) = 1
121+
122+ """
123+ namelist(V) -> String
124+
125+ Get the cached name list for the options specified in `V`.
126+ """
127+ @pure namelist (V) = namecache[nameindex (V)]
85128
86129# # Signature{N}
87130
92135@pure Signature {N,M,S,F,D} () where {N,M,S,F,D} = Signature {N,M,S,F,D,1} ()
93136@pure Signature {N,M,S} () where {N,M,S} = Signature {N,M,S,0,0} ()
94137@pure Signature {N,M} (b:: BitArray{1} ,f= 0 ,d= 0 ) where {N,M} = Signature {N,M,bit2int(b[1:N]),f,d} ()
95- @pure Signature {N,M} (b:: Array {Bool,1 } ,f= 0 ,d= 0 ) where {N,M} = Signature {N,M} (convert (BitArray{1 },b),f,d)
138+ @pure Signature {N,M} (b:: Vector {Bool} ,f= 0 ,d= 0 ) where {N,M} = Signature {N,M} (convert (BitArray{1 },b),f,d)
96139@pure Signature {N,M} (s:: String ) where {N,M} = Signature {N,M} ([k== ' -' for k∈ s])
97140@pure Signature (str:: String ) = Signature {length(str)} (str)
98- @pure Signature (n:: Int ,d:: Int = 0 ,o:: Int = 0 ,s:: UInt = zero (UInt)) = Signature {n,doc2m(d,o),s} ()
99-
141+ @pure Signature (n:: Int ,d:: Int = 0 ,o:: Int = 0 ,s:: UInt = zero (UInt)) = Signature {n,tensorhash(d,o),s} ()
100142@pure function Signature {N} (s:: String ) where N
101143 ms = match (r" [0-9]+" ,s)
102144 if ms ≠ nothing && String (ms. match) == s
103145 length (s) < 4 && (s *= join (zeros (Int,5 - length (s))))
104146 Signature (parse (Int,s[1 ]),parse (Int,s[2 ]),parse (Int,s[3 ]),UInt (parse (Int,s[4 : end ])))
105147 else
106- Signature {N,doc2m (Int(vio[1]∈s),Int(vio[2]∈s))} (replace (replace (s,vio[1 ]=> ' +' ),vio[2 ]=> ' -' ))
148+ Signature {N,tensorhash (Int(vio[1]∈s),Int(vio[2]∈s))} (replace (replace (s,vio[1 ]=> ' +' ),vio[2 ]=> ' -' ))
107149 end
108150end
109151
@@ -118,7 +160,9 @@ Base.firstindex(m::TensorBundle) = 1
118160Base. lastindex (m:: TensorBundle{N} ) where N = N
119161Base. length (s:: TensorBundle{N} ) where N = N
120162
163+ # Type promotion to allow using `Int` with `Signature`
121164Base. promote_rule (:: Type{Int} , :: Type{<:Signature} ) = Signature
165+ # Base.promote_rule(::Type{Int}, ::Type{<:TensorBundle}) = Signature
122166
123167@inline sig (s:: Bool ) = s ? ' -' : ' +'
124168@inline sig (s:: Int ,k) = ' 1'
@@ -129,7 +173,7 @@ Base.promote_rule(::Type{Int}, ::Type{<:Signature}) = Signature
129173@inline printsep (io,s,k,n) = k≠ n && print (io,' ,' )
130174
131175function Base. show (io:: IO ,s:: Signature )
132- dm = diffmode (s)
176+ dm = diffmode (s) # print lead symbols
133177 print (io,dm> 0 ? " T$(sups[dm]) ⟨" : ' ⟨' )
134178 C,d = dyadmode (s),diffvars (s)
135179 N = mdims (s)- (d> 0 ? (C< 0 ? 2 d : d) : 0 )
@@ -139,9 +183,9 @@ function Base.show(io::IO,s::Signature)
139183 print (io,sig .(s[hasinf (s)+ hasorigin (s)+ 1 + (d< 0 ? abs (d) : 0 ): N])... )
140184 d> 0 && print (io,[((C> 0 )⊻ ! polymode (s) ? sups : subs)[x] for x ∈ 1 : abs (d)]. .. )
141185 d> 0 && C< 0 && print (io,[sups[x] for x ∈ 1 : abs (d)]. .. )
142- print (io,' ⟩' )
186+ print (io,' ⟩' ) # print end symbols
143187 C ≠ 0 ? print (io, C < 0 ? ' *' : ' '' ) : nothing
144- names_index (s)> 1 && print (io,subs[names_index (s)])
188+ nameindex (s)> 1 && print (io,subs[nameindex (s)])
145189end
146190
147191# # DiagonalForm{N}
@@ -195,7 +239,7 @@ function Base.show(io::IO,s::DiagonalForm)
195239 d> 0 && C< 0 && print (io,[sups[x] for x ∈ 1 : abs (d)]. .. )
196240 print (io,' ⟩' )
197241 C ≠ 0 ? print (io, C < 0 ? ' *' : ' '' ) : nothing
198- names_index (s)> 1 && print (io,subs[names_index (s)])
242+ nameindex (s)> 1 && print (io,subs[nameindex (s)])
199243end
200244
201245# # Submanifold{N}
@@ -307,7 +351,7 @@ function Base.show(io::IO,s::Submanifold{V,NN,S}) where {V,NN,S}
307351 d> 0 && C< 0 && print (io,[sups[x- NM] for x ∈ ind[N+ abs (d)+ 1 : end ]]. .. )
308352 print (io,' ⟩' )
309353 C ≠ 0 ? print (io, C < 0 ? ' *' : ' '' ) : nothing
310- names_index (s)> 1 && print (io,subs[names_index (s)])
354+ nameindex (s)> 1 && print (io,subs[nameindex (s)])
311355 PnV && print (io,' ×' ,length (V))
312356end
313357
0 commit comments