API Reference (Julia)
Modules
XAct.XCore — Module
XCoreJulia port of the xAct/xCore utility layer required by xTensor and xPerm.
Only Category-A symbols (used by xTensor/xPerm) are implemented here. Category-B symbols are aliased to Julia built-ins. Category-C symbols (display, FoldedRule, testing framework, namespace management) are intentionally omitted — see sxAct-8wd design notes for the full categorisation.
FoldedRule decision: SKIP. FoldedRule and its companions (CollapseFoldedRule, DependentRules, IndependentRules) are not referenced anywhere in xTensor or xPerm. They are a Wolfram-specific rule-sequencing idiom with no downstream consumers in the packages we are porting.
XAct.XTensor.XPerm — Module
XPermJulia implementation of Butler-Portugal tensor index canonicalization.
Permutations are 1-indexed image vectors (perm[i] = j means point i → j). Signed permutations extend to degree n+2 where positions n+1, n+2 encode sign.
References:
- xperm.c: C reference implementation (GPL, not used at runtime)
- SymPy tensor_can.py: Python reference for Schreier-Sims
- Butler (1991): "Fundamental Algorithms for Permutation Groups"
- Niehoff (2018): Direct sorting shortcut for Sym/Antisym groups
XAct.XTensor — Module
XTensorAbstract tensor algebra for the xAct/sxAct system. Implements DefManifold, DefMetric, DefTensor, ToCanonical, and Contract.
Curvature tensors are auto-created by def_metric!. Condition evaluation (Assert, Evaluate) is handled in the Python adapter layer.
Reference: specs/2026-03-06-xperm-xtensor-design.md
XAct.XInvar — Module
XInvarInvariant permutation representation system for the Invar pipeline. Implements InvariantCase, RPerm, RInv types, MaxIndex table, and case enumeration for Riemann tensor invariant classification.
Reference: Martín-García, Yllanes & Portugal (2008) arXiv:0802.1274 Wolfram source: resources/xAct/Invar/Invar.m
XAct.TExprLayer — Module
TExprLayerTyped expression layer for xAct. Provides Idx, DnIdx, TensorHead, CovDHead, TTensor, TProd, TSum, TScalar, TSymbol, TCovD, the @indices macro, tensor() / covd() lookups, tostring() serialisation, and TExpr overloads for all engine functions.
Functions and Types
XAct.reset_state! — Method
reset_state!()Perform a global reset of all xAct subcomponents (XCore, XPerm, XTensor).
XAct.validate_deriv_orders — Method
validate_deriv_orders(deriv_orders) → nothingValidate that derivative orders are non-negative and sorted non-decreasing.
XAct.validate_disjoint_cycles — Method
validate_disjoint_cycles(cycles) → nothingValidate that no element appears in more than one cycle.
XAct.validate_identifier — Method
validate_identifier(name; context="") → SymbolValidate that name is a safe ASCII identifier: [A-Za-z_][A-Za-z0-9_]*. Returns the name as a Symbol on success; throws ArgumentError otherwise.
XAct.validate_order — Method
validate_order(order; context="perturbation order") → nothingValidate that a perturbation order is >= 1.
XAct.validate_perm — Method
validate_perm(p; context="permutation") → nothingValidate that p is a well-formed permutation: elements in 1:n with no duplicates.
XAct.XCore.AtomQ — Method
AtomQ(x) -> BoolReturn true for any value (analogous to Mathematica AtomQ). In Julia, every Symbol, Number, and String is atomic.
XAct.XCore.CheckOptions — Method
CheckOptions(opts...)Validate that every element (after flattening one level) is a Pair. Returns a flat Vector{Pair} on success; throws on invalid structure.
Each argument must be either a Pair (kept as-is) or an iterable of Pairs (flattened one level). Iterating over a bare Pair would yield its key and value, not a single rule, so Pair arguments are treated as atomic here.
XAct.XCore.Disclaimer — Method
Disclaimer()Print the GPL warranty disclaimer, analogous to Mathematica Disclaimer[].
XAct.XCore.FindSymbols — Method
FindSymbols(expr) -> Vector{Symbol}Recursively collect all Symbols in expr (including inside Expr args and collections). Returns a deduplicated vector.
XAct.XCore.HasDaggerCharacterQ — Method
HasDaggerCharacterQ(s::Symbol) -> BoolReturn true if the symbol name contains DaggerCharacter[].
XAct.XCore.JustOne — Method
JustOne(list)Return the single element of a one-element collection; throw otherwise. Used inside xTensor for pattern-match assertions.
XAct.XCore.LinkSymbols — Method
LinkSymbols(symbols::Vector{Symbol}) -> SymbolCreate a single symbol by interleaving symbols with LinkCharacter.
Analogous to Mathematica LinkSymbols[{s1, s2, ...}].
XAct.XCore.MakeDaggerSymbol — Method
MakeDaggerSymbol(s::Symbol) -> SymbolToggle the dagger character:
- If present, remove it.
- If absent, insert it before the first
$in the name, or append it.
XAct.XCore.MakexTensions — Method
MakexTensions(defcommand, moment, args...)Fire all hooks registered for (defcommand, moment) with args....
XAct.XCore.MapIfPlus — Method
MapIfPlus(f, expr)Map f over a vector/tuple (multi-term, analogous to Plus-headed expr), or apply f once to expr if it is a scalar.
XAct.XCore.NoPattern — Method
NoPattern(expr)Identity function. Julia has no Pattern/Blank wrappers; this is a no-op shim preserving call-site compatibility with xTensor code that calls NoPattern.
XAct.XCore.ReportSet — Method
ReportSet(ref::Ref, value; verbose=true)Assign value to ref[], printing a report if the value changed.
Analogous to Mathematica ReportSet[var, value] which assigns and prints when the variable changes. Mathematica uses HoldFirst to capture the variable name; Julia cannot do that, so callers pass a Ref wrapper.
Not used by xTensor or xPerm downstream.
XAct.XCore.ReportSetOption — Method
ReportSetOption(symbol, option => value)No-op shim. Mathematica's ReportSetOption sets an option on a symbol and prints if the value changed, relying on Options/SetOptions. Julia has no built-in option-dictionary system; packages manage their own option storage.
Not used by xTensor or xPerm downstream.
XAct.XCore.SetNumberOfArguments — Method
SetNumberOfArguments(f, n)No-op compatibility shim. Julia enforces arity through method dispatch; wrong-arity calls produce MethodError automatically. This function is provided so that xTensor/xPerm code that calls SetNumberOfArguments at load time does not error.
XAct.XCore.SubHead — Method
SubHead(expr) -> SymbolReturn the innermost atomic head of a nested expression. For a bare Symbol, returns itself. For an Expr, recurses into expr.head.
XAct.XCore.SymbolJoin — Method
SymbolJoin(symbols...)Create a new Symbol by concatenating the string representations of all arguments. Analogous to Mathematica SymbolJoin, used 21× in xTensor for composite names.
XAct.XCore.SymbolName — Method
SymbolName(s::Symbol) -> StringReturn the string name of a symbol (analogous to Mathematica SymbolName).
XAct.XCore.ThreadArray — Method
ThreadArray(head, left::AbstractArray, right::AbstractArray)Map head over corresponding pairs from left and right, preserving array shape. Analogous to Mathematica ThreadArray[head[left, right]] which threads head over matching elements at full array depth via MapThread.
Julia's map on two arrays already threads element-wise; this is a thin wrapper for call-site compatibility. Not used by xTensor or xPerm downstream.
XAct.XCore.TrueOrFalse — Method
TrueOrFalse(x)Return true if x isa Bool; return false otherwise.
XAct.XCore.UnlinkSymbol — Method
UnlinkSymbol(s::Symbol) -> Vector{Symbol}Split a symbol at each occurrence of LinkCharacter, returning the parts as symbols.
Analogous to Mathematica UnlinkSymbol[symbol].
XAct.XCore.ValidateSymbol — Method
ValidateSymbol(name::Symbol)Throw if name collides with any symbol already registered in the xAct registry, or if it is exported by Julia's Base. Returns nothing on success.
Error conditions (mirrors Mathematica ValidateSymbol):
nameis in_symbol_registry→ already used by that packagenameis aBaseexport → reserved by Julia
XAct.XCore.push_unevaluated! — Function
push_unevaluated!(collection, value)Append value to collection. Julia evaluates eagerly so this is an alias for push!; the "unevaluated" qualifier is a Mathematica artefact.
XAct.XCore.register_symbol — Method
register_symbol(name, package)Register name (a Symbol or string) as owned by package.
- If the name is already registered by the same package, the call is a no-op (idempotent).
- If the name is already registered by a different package, throws an error.
- On success, also appends
nameto the per-package name list ifpackageis one of the known xAct package labels.
XAct.XCore.reset_core! — Method
reset_core!()Empty the symbol registry and all name lists.
XAct.XCore.strip_variance — Method
strip_variance(s) -> StringStrip the leading "-" (covariant marker) from an index string. Returns the bare index label. E.g. strip_variance("-a") → "a", strip_variance("a") → "a".
XAct.XCore.xEvaluateAt — Method
xEvaluateAt(expr, positions)No-op shim. In Mathematica, this forces evaluation at given subexpression positions. Julia evaluates eagerly; there is nothing to force. Provided for call-site compatibility.
XAct.XCore.xTagSet! — Method
xTagSet!(tag, key, value)Assign value to key in the tag-indexed store for tag. Analogous to Mathematica xTagSet[{tag, lhs}, rhs].
XAct.XCore.xTagSetDelayed! — Method
xTagSetDelayed!(tag, key, thunk)Delayed variant of xTagSet!.
XAct.XCore.xTension! — Method
xTension!(package, defcommand, moment, func)Register func to be called at moment ("Beginning" or "End") during execution of defcommand. package is a string label used for grouping (stored as metadata only; hooks fire in registration order).
XAct.XCore.xUpAppendTo! — Method
xUpAppendTo!(property, tag, element)Append element to the upvalue list property[tag], initialising to [] if absent.
XAct.XCore.xUpDeleteCasesTo! — Method
xUpDeleteCasesTo!(property, tag, pred)Remove all elements satisfying pred from the upvalue list property[tag].
XAct.XCore.xUpSet! — Method
xUpSet!(property, tag, value)Attach value as the property upvalue of tag. Equivalent to Mathematica xUpSet[property[tag], value].
Returns value.
XAct.XCore.xUpSetDelayed! — Method
xUpSetDelayed!(property, tag, thunk)Attach a zero-argument function thunk as a delayed upvalue. Callers retrieve the value by invoking the stored thunk.
XAct.XCore.XHold — Type
XHold{T}Wrapper analogous to Mathematica's xHold / HoldForm: prevents the contained value from being printed at high precedence. Julia evaluates eagerly, so this is purely a display/typing artefact.
XAct.XCore.DaggerCharacter — Constant
Global dagger character appended to daggered symbol names. Default is the Unicode dagger † (U+2020), matching xCore's \[Dagger].
XAct.XCore.LinkCharacter — Constant
Global link character used to join symbol parts in LinkSymbols. Default is ⁀ (U+2040, UnderBracket), matching xCore's \[UnderBracket].
XAct.XCore.WarningFrom — Constant
Current warning source label, analogous to Mathematica $WarningFrom.
XAct.XCore.xActDirectory — Constant
Path to the xAct installation directory.
XAct.XCore.xActDocDirectory — Constant
Path to the xAct documentation directory.
XAct.XTensor.XPerm.ColAntisymmetrySGS — Method
ColAntisymmetrySGS(tableau, n) → StrongGenSetWL-compatible alias for col_antisymmetry_sgs.
XAct.XTensor.XPerm.Cycles — Method
Cycles(cycle1, cycle2, ...) → Vector{Int}Create a permutation image-vector from cycle notation. Cycles([1,2,3,4]) produces the 4-cycle 1→2→3→4→1. Cycles() returns Int[] (identity of degree 0).
XAct.XTensor.XPerm.DeleteRedundantGenerators — Method
DeleteRedundantGenerators(sgs) → StrongGenSetRemove generators from sgs that are redundant (expressible as products of the remaining generators). Iterates through the flat generator list, removing each generator whose removal does not change the group order.
XAct.XTensor.XPerm.Dimino — Function
Dimino(GS, names) → GroupEnumerate all elements of the group generated by GS using the Dimino algorithm. Returns a Group with elements in coset-expansion order (identity first). names is an optional Vector{Pair{String,Vector{Int}}} mapping name → permutation vector. Named elements appear as their String name; others appear as their permutation vector.
The algorithm: for each new generator s not yet in G, iterate through all current elements and left-multiply by s, appending new elements. This produces xPerm-compatible coset ordering.
XAct.XTensor.XPerm.GenSet — Method
GenSet(p1, p2, ...) → Vector{Vector{Int}}Collect permutations into a generator list.
XAct.XTensor.XPerm.Orbit — Method
Orbit(pt, genset_or_sgs) → Vector{Int}Return the orbit of pt under the generators, in BFS discovery order (matching xPerm's Mathematica output).
XAct.XTensor.XPerm.Orbits — Method
Orbits(genset_or_sgs [, n]) → Vector{Vector{Int}}Return all orbits of the generators, each in BFS discovery order.
XAct.XTensor.XPerm.OrderOfGroup — Method
OrderOfGroup(sgs) → IntXAct.XTensor.XPerm.PermDeg — Method
PermDeg(sgs) → IntReturn the physical degree (number of non-sign points) of the group. For a GenSet (Vector{Vector{Int}}), returns the maximum permutation length.
XAct.XTensor.XPerm.PermMemberQ — Method
PermMemberQ(perm, sgs) → BoolTest whether perm is an element of the group described by sgs. ID is treated as the identity permutation of degree sgs.n. An empty permutation Int[] is also treated as identity.
XAct.XTensor.XPerm.PermWord — Method
PermWord(perm, sgs) → PermWordResultDecompose perm as a product of coset representatives from the stabilizer chain. Returns the word [residual, u_k, ..., u_1] (residual first, then coset reps in reverse sift order) such that:
perm = u_1 ∘ u_2 ∘ ... ∘ u_k ∘ residualNamed generators (variables in Julia's Main scope) are returned as strings.
XAct.XTensor.XPerm.Permute — Method
Permute(a, b, ...) → Vector{Int}Compose permutations left-to-right: Permute(a, b) means apply a first, then b, i.e. compose(b, a) in right-to-left convention.
XAct.XTensor.XPerm.RightCosetRepresentative — Method
RightCosetRepresentative(perm, n, sgs) → Vector{Int}WL-compatible wrapper: return the canonical (lex-minimum) representative of the right coset S·perm in the group defined by sgs.
XAct.XTensor.XPerm.RowSymmetrySGS — Method
RowSymmetrySGS(tableau, n) → StrongGenSetWL-compatible alias for row_symmetry_sgs.
XAct.XTensor.XPerm.Schreier — Method
Schreier(args...) → SchreierResult or MultiSchreierResultWL-style constructor for SchreierResult (used in assertion comparisons).
- 3-arg form: Schreier(orbit, labels, parents)
- 4+-arg form: Schreier(orbit1, orbit2, ..., labels, parents)
XAct.XTensor.XPerm.SchreierOrbit — Method
SchreierOrbit(root, GS, n, names) → SchreierResultBFS from root under generators GS (each named by names[i]) in [1..n]. Returns a SchreierResult with orbit, label vector, and parent vector.
XAct.XTensor.XPerm.SchreierOrbits — Method
SchreierOrbits(GS, n, names) → MultiSchreierResultCompute all orbits under generators GS (named by names) in [1..n]. Returns all orbits and combined label/parent vectors.
XAct.XTensor.XPerm.SchreierSims — Method
SchreierSims(base, genset, n) → StrongGenSet
SchreierSims(genset) → StrongGenSetWL-style Schreier-Sims wrapper.
XAct.XTensor.XPerm.Stabilizer — Method
Stabilizer(pts, GS) → GenSetReturn the subset of generators in GS that fix every point in pts.
XAct.XTensor.XPerm.StablePoints — Method
StablePoints(perm) → Vector{Int}
StablePoints(gs::Vector) → Vector{Int}
StablePoints(sgs::StrongGenSet) → Vector{Int}Return the sorted list of points fixed by all generators.
XAct.XTensor.XPerm.StandardTableau — Method
StandardTableau(partition, indices) → YoungTableauWL-compatible alias for standard_tableau.
XAct.XTensor.XPerm.TableauFilling — Method
TableauFilling(tableau) → Vector{Vector{Int}}Return the filling of a YoungTableau (for WL-compatible field access).
XAct.XTensor.XPerm.TableauPartition — Method
TableauPartition(tableau) → Vector{Int}Return the partition of a YoungTableau (for WL-compatible field access).
XAct.XTensor.XPerm.TranslatePerm — Method
TranslatePerm(perm, format) → Vector{Int}Identity conversion: the image vector is already in the right format.
XAct.XTensor.XPerm.YoungProjector — Method
YoungProjector(tableau, n) → Vector{Tuple{Vector{Int}, Int}}WL-compatible alias for young_projector.
XAct.XTensor.XPerm._bare_label — Method
_bare_label(s) → StringStrip leading '-' from an index label.
XAct.XTensor.XPerm._canonicalize_antisymmetric — Method
_canonicalize_antisymmetric(indices, slots) → (Vector{String}, Int)Niehoff shortcut for Antisymmetric groups: sort slot positions by bare label name. Returns (newindices, sign) where sign=parity(sortpermutation), or ([], 0) if repeated.
XAct.XTensor.XPerm._canonicalize_riemann — Method
_canonicalize_riemann(indices, slots) → (Vector{String}, Int)Butler-Portugal via enumeration for the Riemann symmetry group (order 8). Finds the lex-min (by bare label) arrangement among the 8 group elements.
XAct.XTensor.XPerm._canonicalize_symmetric — Method
_canonicalize_symmetric(indices, slots) → (Vector{String}, Int)Niehoff shortcut for Symmetric groups: sort slot positions by bare label name. Returns (new_indices, sign=+1).
XAct.XTensor.XPerm._canonicalize_young — Method
_canonicalize_young(indices, partition, slots) → (Vector{String}, Int)Canonicalize indices at slots under the Young symmetry group defined by partition.
The Young symmetry group is {c·r : c ∈ colgroup, r ∈ rowgroup} with sign = sgn(c). We enumerate all orbit elements and return the lexicographically minimal representative together with its sign s such that T[canonical] = s · T[original].
XAct.XTensor.XPerm._enumerate_group_elements — Method
_enumerate_group_elements(sgs) → Vector{Perm}Enumerate all elements of the group described by sgs via BFS on the Cayley graph. Returns unsigned permutations of degree sgs.n.
XAct.XTensor.XPerm._enumerate_signed_group_elements — Method
_enumerate_signed_group_elements(sgs) → Vector{Tuple{Perm, Int}}Enumerate all elements of a signed group described by sgs via BFS. Returns (unsignedperm, sign) pairs where unsignedperm has degree sgs.n.
XAct.XTensor.XPerm._riemann_8_elements — Method
_riemann_8_elements(i, j, k, l) → Vector{Tuple{NTuple{4,Int}, Int}}Return all 8 elements of the Riemann symmetry group as (slotimage, sign) pairs. slotimage[m] = which original slot position goes to position m.
XAct.XTensor.XPerm._sift — Method
_sift(p, sgs_levels, n) → (residual, depth)Sift permutation p through the partial BSGS represented by sgs_levels. Returns (residual, depth) where:
- If residual is identity at depth == length(sgs_levels)+1, p ∈ group.
- Otherwise, the residual is a new generator for level
depth.
XAct.XTensor.XPerm._sift_with_cache — Method
_sift_with_cache(p, base, level_GS, sv_cache, n) → (residual, depth)Like _sift but uses a shared sv_cache of SchreierVectors (entries are nothing when invalidated). Recomputes and stores missing entries. This avoids redundant BFS inside the tight Schreier-Sims loop.
XAct.XTensor.XPerm._young_columns — Method
_young_columns(tab) → Vector{Vector{Int}}Return the columns of a YoungTableau as lists of slot positions. Column j contains tab.filling[i][j] for each row i that has ≥ j elements.
XAct.XTensor.XPerm.antisymmetric_sgs — Method
antisymmetric_sgs(slots, n) → StrongGenSetAlternating-sign group A_k on slots. Adjacent transpositions each carry sign=-1 (transposed via n+1 ↔ n+2 in extended rep). Returns signed StrongGenSet (signed=true).
XAct.XTensor.XPerm.canonical_perm — Method
canonical_perm(perm, sgs, free_points, dummy_groups) → (Perm, Int)Returns (canonical_perm, sign) where sign ∈ {-1, 0, +1}. Returns (Int[], 0) if the expression is zero (repeated antisymmetric index).
XAct.XTensor.XPerm.canonicalize_slots — Function
canonicalize_slots(indices, sym_type, slots[, partition]) → (Vector{String}, Int)Apply symmetry canonicalization to indices at the given slots. symtype: one of :Symmetric, :Antisymmetric, :GradedSymmetric, :RiemannSymmetric, :YoungSymmetry, :NoSymmetry For :YoungSymmetry, partition must be provided (e.g. [2,1]). Returns (newindices, sign) where sign ∈ {-1, 0, +1}.
XAct.XTensor.XPerm.col_antisymmetry_sgs — Method
col_antisymmetry_sgs(tableau, n) → StrongGenSetReturn the signed StrongGenSet for the column antisymmetrization group of tableau. The column group permutes within each column, with sign = sign(permutation). Generators are adjacent transpositions within each column (degree n, signed = true).
For partition [λ₁, λ₂, ...], column j contains the j-th element of each row that is long enough.
XAct.XTensor.XPerm.compose — Method
compose(p, q) → PermReturn the composition p∘q: (p∘q)[i] = p[q[i]]. (Apply q first, then p.)
XAct.XTensor.XPerm.double_coset_rep — Method
double_coset_rep(perm, sgs, dummy_groups) → (Perm, Int)Find the canonical representative of S · perm · D where D is the dummy symmetry group.
dummy_groups is a Vector of Vector{Int}: each inner vector lists positions (1-indexed) that are freely exchangeable (dummy index relabeling symmetry). For each group, every transposition of two positions in the group is a generator of D.
Algorithm:
- Build generators of D from transpositions within each dummy group.
- Enumerate all elements of D by BFS over the Cayley graph (small groups in practice).
- For each d ∈ D, compute rightcosetrep(perm ∘ d, sgs).
- Return the lex-minimum result (by comparing the returned unsigned perm).
For Tier 1 tests (no dummy indices), dummygroups is empty → reduces to rightcoset_rep.
XAct.XTensor.XPerm.identity_perm — Method
identity_perm(n) → PermReturn the identity permutation of degree n: [1, 2, ..., n].
XAct.XTensor.XPerm.identity_signed_perm — Method
identity_signed_perm(n) → SignedPermReturn the identity signed permutation of degree n+2: [1, 2, ..., n, n+1, n+2].
XAct.XTensor.XPerm.inverse_perm — Method
inverse_perm(p) → PermReturn the inverse of p: inv_p[p[i]] = i.
XAct.XTensor.XPerm.is_identity — Method
is_identity(p) → BoolTrue iff p is the identity permutation.
XAct.XTensor.XPerm.on_list — Method
on_list(p, lst) → Vector{Int}Return the image of each point in lst under p: [p[i] for i in lst].
XAct.XTensor.XPerm.on_point — Method
on_point(p, i) → IntReturn the image of point i under permutation p: p[i].
XAct.XTensor.XPerm.orbit — Method
orbit(root, GS, n) → Vector{Int}Return sorted list of all points reachable from root under generators GS.
XAct.XTensor.XPerm.order_of_group — Method
order_of_group(sgs) → IntCompute |G| as product of orbit sizes at each base level.
XAct.XTensor.XPerm.perm_equal — Method
perm_equal(p, q) → BoolXAct.XTensor.XPerm.perm_member_q — Method
perm_member_q(p, sgs) → BoolTest whether p belongs to the group described by sgs.
XAct.XTensor.XPerm.perm_sign — Method
perm_sign(p) → IntReturn the sign (+1 or -1) of an unsigned permutation p using cycle decomposition.
XAct.XTensor.XPerm.riemann_sgs — Method
riemann_sgs(slots, n) → StrongGenSetRiemann symmetry group on exactly 4 slots (i,j,k,l) (1-indexed). Generators (signed): g1 = swap slots i,j with sign=-1 (antisym in first pair) g2 = swap slots k,l with sign=-1 (antisym in second pair) g3 = cycle (i↔k, j↔l) with sign=+1 (pair exchange) Group order = 8. Returns signed StrongGenSet.
XAct.XTensor.XPerm.right_coset_rep — Method
right_coset_rep(perm, sgs) → (Perm, Int)Find the lex-minimum (by base order) element of the right coset S · perm, where S is the group described by sgs. Returns (canonical_perm, sign).
- sign = +1 always for unsigned groups (sgs.signed == false)
- sign extracted from position n+1 for signed groups
XAct.XTensor.XPerm.row_symmetry_sgs — Method
row_symmetry_sgs(tableau, n) → StrongGenSetReturn the unsigned StrongGenSet for the row symmetrization group of tableau. The row group is the direct product S{λ₁} × S{λ₂} × ... where S_{λᵢ} permutes within row i. Generators are adjacent transpositions within each row.
The group acts on points 1..n (unsigned permutations, sign = +1 for all elements).
XAct.XTensor.XPerm.schreier_sims — Method
schreier_sims(initbase, generators, n) → StrongGenSetBuild a Strong Generating Set via the basic Schreier-Sims algorithm. initbase — initial base (vector of points; extended during computation) generators — initial generators (Perm or SignedPerm of degree n or n+2) n — number of physical points (1..n)
XAct.XTensor.XPerm.schreier_vector — Method
schreier_vector(root, GS, n) → SchreierVectorCompute the Schreier vector for the orbit of root under the generators GS, where each generator acts on points 1..n (or 1..n+2 for signed; only 1..n matter).
XAct.XTensor.XPerm.standard_tableau — Method
standard_tableau(partition, indices) → YoungTableauConstruct a Young tableau for partition using the given indices (slot positions). The filling is assigned left-to-right within each row, top-to-bottom across rows.
Arguments
partition::Vector{Int}: row lengths in descending order, must sum to length(indices).indices::Vector{Int}: 1-indexed slot positions to fill into the tableau.
Example
# Partition [3,2] on indices [1,2,3,4,5]
tab = standard_tableau([3, 2], [1, 2, 3, 4, 5])
# tab.filling == [[1, 2, 3], [4, 5]]XAct.XTensor.XPerm.symmetric_sgs — Method
symmetric_sgs(slots, n) → StrongGenSetSymmetric group S_k on slots (1-indexed positions in 1..n). Generators: adjacent transpositions of consecutive slot positions. Returns unsigned StrongGenSet (signed=false).
XAct.XTensor.XPerm.trace_schreier — Method
trace_schreier(sv, p, GS) → PermRecover the group element (product of generators) that maps sv.root to point p, by tracing the Schreier tree backwards from p to root. Returns the permutation u such that u(root) = p.
XAct.XTensor.XPerm.young_projector — Method
young_projector(tableau, n) → Vector{Tuple{Vector{Int}, Int}}Compute the Young projector (symmetrizer) Pλ = Qλ · R_λ for the given Young tableau.
The Young projector is: Pλ = Σ{q ∈ colgroup} Σ{r ∈ row_group} sign(q) · q · r
Returns a vector of (perm, sign) pairs representing the expansion of Pλ in Sn, where perm is a permutation of degree n and sign ∈ {-1, +1}.
Duplicate permutations are collected and their signs summed; entries with net sign zero are dropped. The result is the "support" of the projector.
Arguments
tableau::YoungTableau: the Young tableau.n::Int: degree of the symmetric group (total number of physical points).
Example
# Partition [2,1]: hook shape on n=3 indices [1,2,3]
# Row group: {e, (12)}; Column group: {e, -(13)}
# P = e·e + e·(12) - (13)·e - (13)·(12)
tab = standard_tableau([2, 1], [1, 2, 3])
terms = young_projector(tab, 3)
# 4 terms (before collecting): each with sign ±1XAct.XTensor.XPerm.Group — Type
Group(elem1, elem2, ...) → GroupOrdered list of group elements as returned by xPerm's Dimino. Each element is either a String (named generator or "ID") or a Vector{Int} (Cycles form). Equality treats "ID" and Int[] as equivalent identity representations.
XAct.XTensor.XPerm.PermWordResult — Type
PermWordResultResult of PermWord: a list of permutation-vector coset representatives. Stores actual Vector{Int} values (suitable for splatting into Permute). show() outputs WL-compatible {elem, ...} notation, substituting names from Julia's Main scope for any generator that matches a named variable.
XAct.XTensor.XPerm.SchreierResult — Type
SchreierResultResult of SchreierOrbit: orbit, label vector (generator name or 0), parent vector. Displays as WL-style Schreier[{orbit}, {labels}, {parents}].
XAct.XTensor.XPerm.SchreierVector — Type
Schreier vector for orbit(root, generators, n). orbit — sorted list of points reachable from root under the generators. nu — length-n vector; nu[i] = index (1-based) into GS of the generator that moved point i into the orbit tree, or 0 if i ∉ orbit. w — length-n vector; w[i] = the predecessor point from which i was reached in BFS, or 0 if i ∉ orbit. root — the starting point.
XAct.XTensor.XPerm.StrongGenSet — Type
Strong Generating Set for a permutation group G ≤ S_n. base[i] — a point moved by the i-th stabilizer but fixed by all later ones. GS — flat list of generators; each is a Perm (unsigned) or SignedPerm (signed). n — degree of the physical points (1..n). signed — true iff generators are signed (degree n+2); false iff unsigned (degree n).
XAct.XTensor.XPerm.StrongGenSet — Method
StrongGenSet(base, genset) → StrongGenSetWL-style constructor: build a strong generating set via Schreier-Sims from a base vector and a generator list.
XAct.XTensor.XPerm.YoungTableau — Type
YoungTableauRepresents a Young tableau for a partition λ = (λ₁ ≥ λ₂ ≥ ... ≥ λₖ) of n.
Fields: partition — row lengths in descending order, e.g. [3, 2, 1] for a 6-index tensor. filling — filling[row] = sorted list of index positions (1-indexed) in that row.
The standard filling places indices left-to-right in each row: row 1: positions 1..λ₁ row 2: positions λ₁+1..λ₁+λ₂ etc.
For a custom filling (e.g. to apply the symmetrizer to specific slot positions), use standard_tableau(partition, indices) which reindexes from an arbitrary list of n slot positions.
XAct.XTensor.XPerm.YoungTableau — Method
YoungTableau(partition, indices) → YoungTableauWL-compatible constructor alias for standard_tableau.
XAct.XTensor.XPerm._IDType — Type
Identity permutation sentinel. PermMemberQ(ID, sgs) expands to identity_perm(sgs.n).
XAct.XTensor.AllContractions — Method
AllContractions(expression, metric_name) → Vector{String}Find all independent scalar contractions of an expression with a metric. For a rank-2 tensor T{ab}, this contracts g^{ab} T{ab} → scalar. Returns a vector of simplified scalar expressions (one per contraction pattern).
XAct.XTensor.BasisChangeMatrix — Method
BasisChangeMatrix(from, to) → MatrixReturn the transformation matrix from from basis to to basis.
XAct.XTensor.BasisChangeQ — Method
BasisChangeQ(from, to) → BoolCheck if a basis change from from to to is registered.
XAct.XTensor.CTensorQ — Method
CTensorQ(tensor, bases...) → BoolReturn true if component values are stored for the given tensor and bases.
XAct.XTensor.CollectTensors — Method
CollectTensors(expression) → StringCollect like terms in a tensor expression by canonicalizing each term and combining terms with identical canonical monomials.
XAct.XTensor.CommuteCovDs — Method
CommuteCovDs(expr, covd_name, idx1, idx2) → StringApply the commutation identity for two covariant derivatives: ∇{idx1} ∇{idx2} T = ∇{idx2} ∇{idx1} T + curvature correction terms
where correction terms are given by the Riemann curvature:
- For each covariant slot -aᵢ: correction
- RiemannCD[-aᵢ, e, idx1, idx2] T[..., -e, ...] - For each contravariant slot aᵢ: correction
+ RiemannCD[aᵢ, -e, idx1, idx2] T[..., e, ...]
Here e is a fresh dummy index (contravariant/covariant in Riemann, covariant/contravariant in T).
Args: expr : String expression containing covd[idx1][covd[idx2][tensor[slots]]] covd_name : Symbol — e.g. :CVD idx1 : String — first derivative index, e.g. "-cva" idx2 : String — second derivative index, e.g. "-cvb"
Returns a String expression suitable for ToCanonical.
XAct.XTensor.ComponentArray — Method
ComponentArray(tensor, bases) → ArrayReturn just the array of component values for a tensor in the given bases.
XAct.XTensor.Contract — Method
Contract(expression::String) → StringPerform metric contraction (ContractMetric) on a tensor expression.
For each metric factor in the expression, contracts its indices with matching indices in other factors (raises/lowers indices, removes the metric).
Physics rules applied:
- Weyl-type tensors (traceless): any self-trace → term is 0
- Einstein tensor trace: tr(G_{ab}) → (1 - dim/2) * RicciScalar
XAct.XTensor.FromBasis — Method
FromBasis(tensor, bases) → StringReturn the abstract-index expression string for a tensor whose components are stored in the given bases. Verifies components exist, then reconstructs the symbolic form using the tensor's declared index slots.
XAct.XTensor.IBP — Method
IBP(expr, covd_name) → StringIntegrate expr by parts with respect to covd_name. For each term:
- Pure divergence
covd[-a][V[a]]: dropped (→ 0) - Product
A * covd[-a][B]: →-(covd[-a][A]) * B(mod total derivative) - Otherwise: unchanged Result is passed through Simplify.
XAct.XTensor.InverseBasisChangeMatrix — Method
InverseBasisChangeMatrix(from, to) → MatrixReturn the inverse transformation matrix (i.e. the matrix that goes from to back to from).
XAct.XTensor.Jacobian — Method
Jacobian(basis1, basis2) → AnyReturn the Jacobian determinant of the transformation from basis1 to basis2.
XAct.XTensor.MakeTraceFree — Method
MakeTraceFree(expression, metric_name) → StringCompute the trace-free part of a rank-2 tensor expression with respect to the given metric. For T_{ab}:
T{ab}^TF = T{ab} - (1/dim) g{ab} g^{cd} T{cd}
where dim is the manifold dimension.
XAct.XTensor.PerturbationAtOrder — Method
PerturbationAtOrder(background, order) → SymbolReturn the name of the perturbation tensor registered for background at perturbation order. Throws an error if no such perturbation is registered.
Examples
PerturbationAtOrder(:g, 1) # → :Pertg1
PerturbationAtOrder(:g, 2) # → :Pertg2XAct.XTensor.PerturbationOrder — Method
PerturbationOrder(tensor_name) → IntReturn the perturbation order of a registered perturbation tensor. Throws an error if tensor_name is not a registered perturbation.
Examples
PerturbationOrder(:Pertg1) # → 1
PerturbationOrder(:Pertg2) # → 2XAct.XTensor.RegisterIdentity! — Method
RegisterIdentity!(tensor_name, identity)Register a multi-term identity for a tensor. Identities are applied during canonicalization by _apply_identities!.
XAct.XTensor.SignDetOfMetric — Method
SignDetOfMetric(metric_name) → IntReturn the sign of the determinant (+1 Riemannian, -1 Lorentzian) for a registered metric.
XAct.XTensor.Simplify — Method
Simplify(expression::AbstractString) → StringAlgebraic simplification of a tensor expression.
Iterates Contract followed by ToCanonical until the expression stops changing (convergence), providing:
- Metric contraction (index raising/lowering, self-trace → dimension)
- Weyl-tracelessness and Einstein-trace physics rules
- Index canonicalization and sign normalization
- Like-term collection (sum simplification)
- Bianchi identity reduction
- Einstein tensor expansion
For example, g^{ab}g_{ab} is reduced to n (the manifold dimension) in a single pass without requiring a prior Contract call.
XAct.XTensor.SymmetryOf — Method
SymmetryOf(expression) → StringDetermine the symmetry type of an expression by examining its behavior under index permutations. Returns "Symmetric", "Antisymmetric", or "NoSymmetry". For expressions with 0 or 1 free indices, returns "Symmetric".
XAct.XTensor.ToBasis — Method
ToBasis(expr_str, basis) → CTensorObjConvert an abstract-index tensor expression to component form in the given basis.
Handles single tensors, products, sums, and automatically contracts dummy (repeated) indices via einsum.
Examples
ToBasis("g[-a,-b]", :Polar) # metric components
ToBasis("g[-a,-b] * v[a]", :Polar) # contraction g_{ab} v^a
ToBasis("T[-a,-b] + S[-a,-b]", :Polar) # sum of tensorsXAct.XTensor.ToCanonical — Method
ToCanonical(expression::String) → StringCanonicalize a tensor expression. Returns "0" if all terms cancel.
XAct.XTensor.TotalDerivativeQ — Method
TotalDerivativeQ(expr, covd_name) → BoolReturn true iff expr is a total divergence (IBP drops it entirely).
XAct.XTensor.TraceBasisDummy — Method
TraceBasisDummy(tensor, bases) → CTensorObjAutomatically find and contract all pairs of basis indices where one slot is covariant and the other is contravariant (with the same basis), mirroring Wolfram's TraceBasisDummy. Returns the contracted CTensorObj.
For a rank-2 mixed tensor like T^a_{b} with both slots in the same basis, this computes the trace.
XAct.XTensor.ValidateSymbolInSession — Method
ValidateSymbolInSession(name::Symbol)Check that name is not already used as a manifold, tensor, metric, vbundle, covariant derivative, or perturbation in the current session. Throws on collision. Analogous to Wolfram ValidateSymbolInSession.
XAct.XTensor.VarD — Method
VarD(expr, field_name, covd_name) → StringEuler-Lagrange derivative of Lagrangian expr w.r.t. field field_name. Uses IBP to move derivatives off the field variation. Result is simplified.
XAct.XTensor._apply_identities! — Method
_apply_identities!(coeff_map, key_order)Apply all registered multi-term identities to the canonical term map. Replaces the hardcoded _bianchi_reduce! with a general framework.
XAct.XTensor._apply_single_identity! — Method
_apply_single_identity!(coeff_map, key_order, id)Apply one multi-term identity to the canonical term map.
Groups single-factor terms by sector (values at fixedslots + sorted values at cycledslots), then for each complete sector eliminates the designated term.
XAct.XTensor._apply_trace_rules — Method
_apply_trace_rules(...) → (:zero, nothing) | (:replaced, TermAST) | (:none, nothing)Dispatch trace rules through registries. Returns:
(:zero, nothing)when the trace vanishes (traceless tensor)(:replaced, term)when a trace rule fired(:none, nothing)when no rule matched (caller should fall through)
XAct.XTensor._auto_create_curvature! — Method
Auto-create Riemann, Ricci, RicciScalar, Einstein tensors for a metric.
XAct.XTensor._bare — Method
Return the bare index label (strip leading '-').
XAct.XTensor._bianchi_reduce! — Method
_bianchi_reduce!(coeff_map, key_order)Legacy wrapper: delegates to _apply_identities!. Kept for backward compatibility; new code should call _apply_identities! directly.
XAct.XTensor._canonicalize_term — Method
Canonicalize a single term; returns nothing if the term is zero.
XAct.XTensor._collect_covd_terms — Method
_collect_covd_terms(terms::Vector{String}) -> Vector{String}Group CovD terms by body (ignoring coefficient), sum coefficients, and return only terms with non-zero coefficient. This ensures e.g. T - T = 0.
XAct.XTensor._commute_covd_pair — Method
_commute_covd_pair(covd_str, covd_indices, swap_pos, tensor_name, inner_slots, manifold_sym)Commute the adjacent CovD pair at positions swap_pos and swap_pos+1 in a CovD chain, producing the swapped chain plus Riemann correction terms.
The Riemann correction acts on ALL effective indices below the swap point: the CovD indices from swap_pos+2 to end, plus the innermost tensor's slots.
Returns a vector of string terms (the swapped main term + correction terms).
XAct.XTensor._compositions — Method
Generate all compositions of n into k non-negative integer parts.
Returns compositions in descending order of the first element, so that for order=1 the term with the first factor perturbed comes first (matching the natural Leibniz convention).
XAct.XTensor._contract_array_axes — Method
_contract_array_axes(arr, ax1, ax2) → ArrayContract (trace over) two axes of an N-dimensional array.
XAct.XTensor._contract_one_metric — Method
Find one metric factor and contract it with another factor (or apply a trace rule). Returns the updated TermAST, the same TermAST if no metric found, or nothing if zero.
XAct.XTensor._contract_slot — Method
Contract matrix M into array along the given slot dimension.
XAct.XTensor._contract_term — Method
Apply ContractMetric to a single term. Returns the contracted TermAST, or nothing if the term is zero.
XAct.XTensor._einsum_eval — Function
_einsum_eval(factor_arrays, factor_labels, dummy_labels, assignment, dim) → Float64Recursively sum over dummy indices, then evaluate the product of all factors. Uses a pre-allocated index buffer per factor and a flat assignment vector (keyed by label ordinal) to avoid Dict/Array allocation in the inner loop.
XAct.XTensor._expand_einstein_terms — Method
Expand any EinsteinXXX factors using G{ab} = R{ab} - (1/2) g_{ab} R.
XAct.XTensor._extract_covd_chain — Method
_extract_covd_chain(term::AbstractString, covd_str::AbstractString)Find a CovD chain in a single term string and return: (covdindices, innertensorname, innerslots, prefix, suffix)
where covd_indices is the list of CovD indices in outer-to-inner order, inner_tensor_name is the innermost tensor name (e.g. "T"), inner_slots is the list of slot strings (e.g. ["-a","-b"]), prefix is everything before the CovD chain (coefficient etc.), and suffix is everything after the CovD chain.
Returns nothing if no CovD chain with ≥ 2 derivatives is found.
XAct.XTensor._extract_leading_coeff — Method
Extract leading coefficient from term body string. Returns (coeff::Rational{Int}, remaining_str). Matches (N/D) rest or N rest (integer followed by whitespace). Otherwise coeff=1//1.
XAct.XTensor._factor_as_metric — Method
Find which registered metric a tensor factor corresponds to, and its variance. Returns (covdkey, MetricObj, :contravariant | :covariant) or nothing. :contravariant — g^{ab}: both indices up (no '-' prefix) → raises indices :covariant — g{ab}: both indices down ('-' prefix) → lowers indices
XAct.XTensor._find_manifold_for_indices — Method
Find which manifold has all of the given index labels (stripping '-').
XAct.XTensor._find_unsorted_pair — Method
_find_unsorted_pair(covd_indices::Vector{String}) -> Union{Int, Nothing}Find the first adjacent pair of CovD indices that is out of canonical (lexicographic) order. Returns the index i such that covd_indices[i] > covd_indices[i+1], or nothing if all are sorted.
Comparison is on the bare index name (stripping the leading '-').
XAct.XTensor._fmt_pos_coeff — Method
Format rational coefficient for positive printing.
XAct.XTensor._has_top_level_sum — Method
Check if a string contains a top-level + or - (not inside brackets).
XAct.XTensor._ibp_term_factors — Method
Apply one IBP step to factors of a single term. Returns (new_coeff, new_body) or nothing (no CovD found). Returns (0//1, "0") for a pure total divergence.
XAct.XTensor._index_appears_in — Method
Check if bare index idx (e.g. "a") appears as a contracted (dummy) index inside expr.
XAct.XTensor._index_label — Method
_index_label(idx_str) → SymbolExtract the bare label from an index string (strip leading '-').
XAct.XTensor._is_covariant — Method
True if index is covariant (has leading '-').
XAct.XTensor._join_term_strings — Method
Join a vector of signed term strings into a sum expression. Each element may start with "-" (negative) or not (positive). Adjacent terms are separated by " - " or " + " as appropriate.
XAct.XTensor._label_pattern — Method
Build a label-boundary regex for swapindices (cached per label string).
XAct.XTensor._leibniz_covd — Method
Expand covd[der_idx][f1 f2 ... fn] via Leibniz product rule. Returns a Vector of term strings, each with CovD applied to one factor.
XAct.XTensor._make_bianchi_identity — Method
_make_bianchi_identity(tensor_name)Construct the first Bianchi identity R_{a[bcd]} = 0 for a 4-slot tensor with RiemannSymmetric symmetry.
Canonical forms for indices p < q < r < s: X₁ = R[p,q,r,s] → cycled ranks [1,2,3] X₂ = R[p,r,q,s] → cycled ranks [2,1,3] X₃ = R[p,s,q,r] → cycled ranks [3,1,2] Identity: X₁ - X₂ + X₃ = 0; eliminate X₃.
XAct.XTensor._multinomial — Method
Multinomial coefficient: $n! / (k₁! k₂! ⋯ kₘ!)$.
XAct.XTensor._negate_term — Method
Flip the leading sign of a term string.
XAct.XTensor._parse_covd_application — Method
Parse covd_name[-der_idx][inner_expr] from a factor string. Returns a named tuple (der_idx, inner) or nothing.
XAct.XTensor._parse_expression — Method
_parse_expression(expr_str) → Vector{TermAST}Parse a tensor expression string into a list of terms.
XAct.XTensor._parse_symmetry — Method
_parse_symmetry(sym_str, slot_specs) → SymmetrySpecParse a Wolfram symmetry string like "Symmetric[{-bta,-btb}]" into a SymmetrySpec. slot_specs is the tensor's slot list for mapping labels → slot positions.
XAct.XTensor._perfect_matchings — Method
_perfect_matchings(items) → Vector{Vector{Tuple{String,String}}}Recursively compute all perfect pair matchings of a list of items.
XAct.XTensor._preprocess_covd_reductions — Method
Apply CovD reductions before canonical parsing.
XAct.XTensor._push_chunk! — Method
Push a parsed chunk into terms, handling parenthesized sub-expressions and scalar-times-subexpression patterns.
XAct.XTensor._rebuild_covd_expr — Method
_rebuild_covd_expr(covd_str, covd_indices, tensor_name, slots)Rebuild a CovD chain expression from parts: covd[i1][covd[i2][...covd[in][tensor[slots]]...]]
XAct.XTensor._reduce_metric_compatibility — Method
Apply metric compatibility: CovD[-x][g[-a,-b]] → 0 for any registered metric.
XAct.XTensor._reduce_second_bianchi — Method
Apply second Bianchi identity: detect cyclic sum ∇e R{abcd} + ∇c R{abde} + ∇d R{abec} = 0 and replace all three terms with 0.
XAct.XTensor._regex_escape — Method
Escape special regex characters in a string.
XAct.XTensor._replace_label — Method
Replace a whole index label inside a bracket string, bounded by delimiters.
XAct.XTensor._safe_simplify — Method
Simplify expr only if it contains no CovD-applied factors (patterns like CovD[-a][inner]). _parse_monomial truncates such factors at the first bracket group, so Simplify would corrupt them. A quick regex scan over registered CovD names is sufficient; full factor parsing is not needed.
XAct.XTensor._serialize — Method
Serialize the canonical map to a Wolfram-style string.
XAct.XTensor._serialize_terms — Method
Serialize a list of TermAST back to a string (without collecting like terms).
XAct.XTensor._split_covd_coeff — Method
_split_covd_coeff(term) -> (Rational{Int}, String)Split a CovD term string into (coefficient, body). Handles leading signs and integer/rational coefficients, e.g. "- 3 SCD[-a][T[-b]]" → (-3//1, "SCD[-a][T[-b]]").
XAct.XTensor._split_expression_terms — Method
_split_expression_terms(expr::AbstractString) -> Vector{String}Split a tensor expression string into additive terms, preserving signs. Each returned term includes its leading sign ('+' or '-') if not the first term. Returns individual term strings that can be recombined with ' '.
XAct.XTensor._split_factor_strings — Method
Split a multiplicative term body into individual factor strings. Each factor is Name[...] or CovD[-a][inner_expr] (CovD has two bracket groups).
XAct.XTensor._split_string_terms — Method
Split expression into signed string terms. Returns Vector{Tuple{Int, String}} = [(sign, body), ...]. Splits on top-level + and -, tracking bracket depth.
XAct.XTensor._swap_indices — Method
_swap_indices(expr, label_a, label_b) → StringSwap two index labels in an expression string, handling both covariant (-label) and contravariant (label) forms.
XAct.XTensor._term_key_str — Method
Serialize a structured key to a canonical string for O(1) Dict hashing.
XAct.XTensor._term_string — Method
Format (coeff, body) as a signed term string suitable for joining.
XAct.XTensor._to_numeric_array — Method
Convert an array to a concrete numeric array, promoting Any elements.
XAct.XTensor._tobasis_term — Method
_tobasis_term(term, basis, dim) → (Array, Vector{Symbol})Evaluate a single parsed term to component form. Returns (array, freeindexlabels). Uses einsum-style evaluation: for each assignment of free index values, sums over all dummy index values the product of factor components.
XAct.XTensor._vard_term_contributions — Method
Compute all EL contributions from a single term for variational derivative w.r.t. field. Returns Vector{Tuple{Rational{Int}, String}} of (coeff, body) contributions.
XAct.XTensor.change_basis — Method
change_basis(array, bases, slot, from_basis, to_basis) → ArrayApply a basis change to a specific slot of a component array.
array— the component array (Vector for rank-1, Matrix for rank-2, etc.)bases— vector of basis symbols for each slot (unused, reserved for future)slot— 1-indexed slot to transformfrom_basis— current basis of that slotto_basis— target basis
For rank-1 (vector): result = M * v For rank-2 (matrix): transforms the specified slot using the transformation matrix.
XAct.XTensor.check_metric_consistency — Method
check_metric_consistency(metric_name) → BoolVerify that a registered metric is internally consistent: its metric tensor is symmetric and its inverse (raised-index version) is registered as its own symmetric tensor. Currently validates:
- The metric tensor exists in the tensor registry.
- The metric is recorded in the metric registry (via
def_metric!). - The metric tensor is symmetric (rank-2 with Symmetric symmetry).
Returns true if all checks pass, false otherwise (never throws).
XAct.XTensor.check_perturbation_order — Method
check_perturbation_order(tensor_name, order) → BoolVerify that a perturbation tensor is registered with the given perturbation order. Returns true if tensor_name is a registered perturbation of exactly order, false otherwise.
XAct.XTensor.christoffel! — Method
christoffel!(metric, basis; metric_derivs=nothing) → CTensorObjCompute and store Christoffel symbols (second kind) from metric CTensor components.
The Christoffel symbol is:
Γ^a_{bc} = (1/2) g^{ad} (∂_b g_{dc} + ∂_c g_{bd} - ∂_d g_{bc})Arguments:
metric: the metric tensor symbol (must have stored components inbasis)basis: the coordinate basis (chart) in which to computemetric_derivs: optional rank-3 array wheredg[c,a,b] = ∂_c g_{ab}. If omitted, assumes constant metric (all derivatives zero → all Christoffels zero).
Returns the CTensorObj stored under the auto-created Christoffel tensor name.
XAct.XTensor.component_value — Method
component_value(tensor, indices, bases) → AnyReturn a single component value from a stored CTensor. indices are 1-based integer indices into the array.
XAct.XTensor.ctensor_contract — Method
ctensor_contract(tensor, bases, slot1, slot2) → CTensorObjContract (trace) two indices of a CTensor. Both slots must be in the same basis. The result has rank reduced by 2. For rank-2, this is the matrix trace.
XAct.XTensor.def_basis! — Method
def_basis!(name, vbundle, cnumbers) → BasisObjDefine a basis of vector fields on a vector bundle. cnumbers are integer labels for the basis elements (length must equal dim of vbundle). Auto-creates a parallel derivative symbol PD<name>.
XAct.XTensor.def_chart! — Method
def_chart!(name, manifold, cnumbers, scalars) → ChartObjDefine a coordinate chart on a manifold. Internally creates a BasisObj (coordinate basis) and registers the coordinate scalar fields as tensors. scalars are the coordinate field names, e.g. [:t, :r, :theta, :phi].
XAct.XTensor.def_manifold! — Method
def_manifold!(name, dim, index_labels) → ManifoldObjDefine a new abstract manifold.
XAct.XTensor.def_metric! — Method
def_metric!(signdet, metric_expr, covd_name) → MetricObjDefine a metric tensor and auto-create curvature tensors. metricexpr: e.g. "Cng[-cna,-cnb]" covdname: e.g. "Cnd" (used as suffix for auto-created curvature tensors)
XAct.XTensor.def_perturbation! — Method
def_perturbation!(tensor, background, order) → PerturbationObjRegister a perturbation tensor.
tensor— name of the perturbed tensor (e.g.:Pertg1)background— name of the background tensor it perturbs (e.g.:g)order— perturbation order (≥ 1)
The perturbed tensor must already be registered (via def_tensor!). The background tensor must already be registered (via def_tensor! or def_metric!). Raises an error if either tensor is unknown, order < 1, or the perturbation is already defined.
XAct.XTensor.def_tensor! — Method
def_tensor!(name, index_specs, manifold; symmetry_str=nothing) → TensorObjDefine a new abstract tensor. index_specs: vector of strings like ["-bta","-btb"] or ["bta"].
XAct.XTensor.def_tensor! — Method
def_tensor!(name, index_specs, manifolds::Vector{Symbol}; symmetry_str=nothing) → TensorObjMulti-index-set variant: each index label must belong to one of the given manifolds. The first manifold in the list is used as the primary manifold stored in TensorObj.manifold. This enables tensors that mix indices from e.g. spacetime and internal gauge manifolds.
XAct.XTensor.get_components — Method
get_components(tensor, bases) → CTensorObjRetrieve stored component values for a tensor in the given bases. If not directly stored, attempts to transform from a stored basis configuration using registered basis changes.
XAct.XTensor.perturb — Method
perturb(expr::AbstractString, order::Int) → StringApply the Leibniz rule to expand perturbations of a tensor expression at the given order.
Supported forms
- Single tensor name — looks up registered perturbation for that background. Index decorations (e.g.
Cng[-a,-b]) are stripped before lookup. - Sum
A + B—perturb(A,n) + perturb(B,n). - Difference
A - B—perturb(A,n) - perturb(B,n). - Product
A BorA * B— general Leibniz (multinomial) rule: $δⁿ(A₁⋯Aₖ) = Σ C(n;i₁,…,iₖ) δⁱ¹(A₁)⋯δⁱᵏ(Aₖ)$ where the sum runs over all non-negative integer compositions $i₁+⋯+iₖ = n$ and $C$ is the multinomial coefficient. - Numeric coefficient
c A— coefficient passes through unchanged. - Factor with no registered perturbation — treated as background (variation = 0).
XAct.XTensor.perturb — Method
perturb(tensor_name::Symbol, order::Int) → StringLook up the registered perturbation tensor for tensor_name at the given perturbation order. Returns the perturbation tensor name as a String, or throws an error if no such perturbation is registered.
XAct.XTensor.perturb_curvature — Method
perturb_curvature(covd_name, metric_pert_name; order=1) → Dict{String,String}Return the first-order perturbation formulas for the Riemann tensor, Ricci tensor, Ricci scalar, and Christoffel symbol perturbation for the metric associated with covd_name, using metric_pert_name as the first-order metric perturbation h_{ab}.
The formulas are returned in the system's CovD string notation using the manifold's first four abstract index labels. Index positions: a = idxs[1], b = idxs[2], c = idxs[3], d = idxs[4]
Standard GR perturbation theory (xPert conventions)
First-order Christoffel perturbation: δΓ^a{bc} = (1/2) g^{ad} (∇b h{cd} + ∇c h{bd} - ∇d h_{bc})
First-order Riemann perturbation (fully covariant): δR{abcd} = ∇c δΓ{abd} - ∇d δΓ_{abc} (with all indices lowered using the background metric)
First-order Ricci perturbation: δR{ab} = ∇c δΓ^c{ab} - ∇b δΓ^c{ac} = (1/2)(∇c ∇a h^cb + ∇c ∇b h^ca - □h{ab} - ∇a ∇b h)
First-order Ricci scalar perturbation: δR = g^{ab} δR{ab} - R{ab} h^{ab}
The returned dict has keys: "Christoffel1" — δΓ expressed in CovD notation (mixed index) "Riemann1" — δR{abcd} in CovD notation "Ricci1" — δR{ab} in CovD notation "RicciScalar1" — δR string formula (contracted Ricci)
All expressions use abstract index labels from the metric's manifold.
XAct.XTensor.reset_session! — Method
reset_session!(s::Session)Clear all state in session s and increment its generation counter.
XAct.XTensor.set_basis_change! — Method
set_basis_change!(from_basis, to_basis, matrix) → BasisChangeObjRegister a coordinate transformation between two bases. The matrix transforms components from from_basis to to_basis. Both the forward (from→to) and inverse (to→from) directions are stored.
Validates:
- Both bases exist (via BasisQ)
- Both bases belong to the same vector bundle
- Matrix is square with size matching the basis dimension
- Matrix is invertible (non-singular)
XAct.XTensor.set_components! — Method
set_components!(tensor, array, bases; weight=0) → CTensorObjStore component values for a tensor in the given bases.
Validates:
- Tensor exists (via TensorQ or MetricQ)
- Each basis exists (via BasisQ)
- Array rank matches number of bases
- Each array dimension matches the basis dimension (length of CNumbersOf)
XAct.XTensor.set_symbol_hooks! — Method
set_symbol_hooks!(validate, register)Install XCore symbol-validation and registration hooks.
Called by XAct.jl after loading both XCore and XTensor:
XTensor.set_symbol_hooks!(XCore.ValidateSymbol, XCore.register_symbol)XAct.XTensor.BasisChangeObj — Type
A coordinate transformation between two bases (stored as matrix + inverse + jacobian).
XAct.XTensor.BasisObj — Type
A basis of vector fields on a vector bundle (non-coordinate frame). Created by def_basis! or internally by def_chart!.
XAct.XTensor.CTensorObj — Type
A component tensor: stores explicit numerical values of a tensor in a given basis.
XAct.XTensor.ChartObj — Type
A coordinate chart on a manifold. Internally creates a BasisObj.
XAct.XTensor.IndexSpec — Type
An abstract index slot: the declared label and its variance.
XAct.XTensor.MultiTermIdentity — Type
MultiTermIdentityA multi-term identity relating N canonical tensor terms by a linear relation.
The identity asserts: Σᵢ coefficients[i] * T[slotperms[i](freeindices)] = 0
Fields:
name: identity label (e.g. :FirstBianchi)tensor: which tensor this applies to (e.g. :RiemannCD)n_slots: total tensor rank (4 for Riemann)fixed_slots: slot positions held constant across termscycled_slots: slot positions permuted across termsslot_perms: for each term, the rank-permutation of cycled_slot valuescoefficients: coefficient of each term in the identity (Σ coefficients[i] * X_i = 0)eliminate: which term index to eliminate (reduce away)
Example — First Bianchi identity R_{a[bcd]} = 0: Three canonical forms for 4 distinct indices p < q < r < s: X₁ = R[p,q,r,s] → cycled ranks [1,2,3] X₂ = R[p,r,q,s] → cycled ranks [2,1,3] X₃ = R[p,s,q,r] → cycled ranks [3,1,2] Identity: X₁ - X₂ + X₃ = 0; eliminate X₃.
XAct.XTensor.PerturbationObj — Type
A perturbation of a tensor: records the perturbed tensor name, its background tensor name, and the perturbation order (1 = first order, 2 = second order, ...).
XAct.XTensor.Session — Type
SessionHolds all mutable state for one xAct session. Replaces 22 global containers. Enables concurrent sessions, proper reset semantics, and structural thread safety.
The default session shares its dict objects with the module-level globals, so existing code that reads/writes globals implicitly uses the default session.
XAct.XTensor.Session — Method
Session()Create a new empty Session with generation 0 and no-op symbol hooks.
XAct.XTensor.SymmetrySpec — Type
Describes the permutation symmetry of a tensor's slot group. type — one of: :Symmetric, :Antisymmetric, :GradedSymmetric, :RiemannSymmetric, :YoungSymmetry, :NoSymmetry slots — 1-indexed positions (within this tensor's slot list) that the symmetry acts on. For :RiemannSymmetric, exactly 4 elements. For :NoSymmetry, empty.
XAct.XTensor.TensorObj — Type
A fully defined tensor object.
XAct.XTensor.FactorNode — Type
A factor is either a plain tensor or a CovD application.
XAct.XTensor.ZERO_TERM — Constant
Zero-coefficient sentinel: returned instead of nothing to keep TermAST endomorphism.
XAct.XInvar.InvSimplify — Function
InvSimplify(rinv::RInv, level::Int=6; db::InvarDB, dim=nothing) -> InvExprSimplify a single Riemann invariant using pre-computed database rules. Returns a linear combination of independent invariants.
Levels:
- 1: identity (no simplification)
- 2: cyclic identity rules
- 3: + Bianchi identity rules
- 4: + CovD commutation rules
- 5: + dimension-dependent rules (requires integer
dim) - 6: + dual reduction rules (requires
dim == 4)
Source: Invar.m:628-678
XAct.XInvar.InvSimplify — Function
InvSimplify(expr::InvExpr, level::Int=6; db::InvarDB, dim=nothing) -> InvExprSimplify a linear combination of Riemann invariants.
Dual invariants (n_epsilon == 1) require dim == 4. An ArgumentError is raised if any dual term is present and dim is not 4.
XAct.XInvar.InvToPerm — Method
InvToPerm(rinv::RInv; db::InvarDB) -> RPermReverse lookup: given an RInv, return the canonical RPerm from the database.
For dual invariants (rinv.case.n_epsilon == 1), looks up in the dual permutation tables.
Throws ArgumentError if the invariant index is not found.
XAct.XInvar.InvarCases — Method
InvarCases(order, degree) -> Vector{InvariantCase}Non-dual cases for a given order and degree (number of Riemann tensors).
XAct.XInvar.InvarCases — Method
InvarCases(order) -> Vector{InvariantCase}Non-dual cases for a given even derivative order (2 ≤ order ≤ 14). Degrees enumerate from highest to lowest.
XAct.XInvar.InvarCases — Method
InvarCases() -> Vector{InvariantCase}All non-dual invariant cases through order 14 (48 cases). Matches Wolfram InvarCases[].
XAct.XInvar.InvarDualCases — Method
InvarDualCases(order) -> Vector{InvariantCase}Dual cases for a given even derivative order (2 ≤ order ≤ 10).
XAct.XInvar.InvarDualCases — Method
InvarDualCases() -> Vector{InvariantCase}All dual invariant cases through order 10. Matches Wolfram InvarDualCases[].
XAct.XInvar.LoadInvarDB — Method
LoadInvarDB(dbdir::String; dim::Int=4) -> InvarDBLoad all Invar database files from dbdir.
The database directory should contain a Riemann/ subdirectory with the standard step structure. Missing files are skipped with a warning.
Arguments:
dbdir: Path to the directory containingRiemann/.dim: Spacetime dimension for dimension-dependent rules (steps 5, 6). Default: 4.
XAct.XInvar.MaxDualIndex — Method
MaxDualIndex(case) -> IntNumber of independent dual Riemann invariants for a given case.
Source: Invar.m:455-483
XAct.XInvar.MaxIndex — Method
MaxIndex(case) -> IntNumber of independent Riemann invariants for a given case. Accepts InvariantCase, Vector{Int} (deriv_orders), or Int (pure algebraic degree).
Source: Invar.m:389-451
XAct.XInvar.PermDegree — Method
PermDegree(case::InvariantCase) -> IntPermutation degree (number of index slots) for an invariant case.
Formula: 4 * n_riemanns + sum(deriv_orders) + 4 * n_epsilon
Source: Invar.m:696
XAct.XInvar.PermToInv — Method
PermToInv(rperm::RPerm; db::InvarDB) -> RInvLook up the invariant label for a canonical RPerm from the loaded database.
The RPerm's permutation must already be in canonical form (as produced by RiemannToPerm). Returns the corresponding RInv with the database index.
For dual invariants (rperm.case.n_epsilon == 1), looks up in the dual permutation tables.
Throws ArgumentError if the permutation is not found in the database.
XAct.XInvar.PermToRiemann — Method
PermToRiemann(rperm::RPerm; covd::Symbol=rperm.metric, curvature_relations::Bool=false) -> StringConvert an RPerm back to a tensor expression string.
The contraction permutation is an involution: perm[i]=j means slot i contracts with slot j. Each pair gets a unique index name. The lower-numbered slot gets the covariant (down) index, the higher slot gets the contravariant (up) index.
If curvature_relations=true, contracted Riemann tensors are replaced with Ricci or RicciScalar where applicable.
XAct.XInvar.RiemannSimplify — Method
RiemannSimplify(expr, metric; covd, level, curvature_relations, db, dim) -> StringSimplify a Riemann scalar expression using the Invar database.
Pipeline: parse → RiemannToPerm → PermToInv → InvSimplify → InvToPerm → PermToRiemann.
Arguments
expr::String: tensor expression (fully contracted scalar)metric::Symbol: the metric symbolcovd::Symbol=metric: covariant derivative name (determines tensor prefixes)level::Int=6: InvSimplify level (1-6)curvature_relations::Bool=false: replace contracted Riemanns with Ricci/RicciScalardb::InvarDB: loaded Invar databasedim::Union{Int,Nothing}=nothing: manifold dimension (needed for levels 5-6)
Returns
A simplified tensor expression string, or "0" if all terms cancel.
Source: Invar.m:834-839
XAct.XInvar.RiemannToPerm — Method
RiemannToPerm(expr::String, metric::Symbol; covd::Symbol=metric)Convert a Riemann scalar expression into canonical RPerm permutation form.
Returns Vector{Tuple{Rational{Int}, RPerm}} — one entry per term.
The expression should use pre-canonicalized index ordering. The covd keyword determines the tensor name prefix (default: same as metric).
Examples
RiemannToPerm("RiemannCD[-a,-b,-c,-d] RiemannCD[a,b,c,d]", :g; covd=:CD)
RiemannToPerm("RicciScalarCD[]", :g; covd=:CD)XAct.XInvar._all_block_permutations — Method
_all_block_permutations(groups, n, slot_ranges) -> Vector{Tuple{Vector{Int}, Int}}Generate all block permutations respecting same-derivative-order groups. Returns (blockperm, sign) pairs where blockperm[i] = position that factor i maps to.
XAct.XInvar._all_permutations_of — Method
_all_permutations_of(indices::Vector{Int}) -> Vector{Tuple{Vector{Int}, Int}}Generate all permutations of indices as (permutedlist, signrelativetosorted) pairs.
XAct.XInvar._apply_block_perm_to_contraction — Method
_apply_block_perm_to_contraction(perm, block_perm, slot_ranges, degree) -> Vector{Int}Apply a block (factor) permutation to a contraction permutation. block_perm[i] = j means factor i moves to position j.
XAct.XInvar._apply_step_rules — Method
_apply_step_rules(expr::InvExpr, step::Int, db::InvarDB; dim::Int=4) -> InvExprApply substitution rules from database step to each term in the expression. Dependent invariants are replaced with linear combinations of independent ones.
For dual invariants (n_epsilon == 1), uses db.dual_rules instead of db.rules.
XAct.XInvar._backtrack_riemann_syms! — Method
_backtrack_riemann_syms!(perm, sign, factor, ...)Recursively apply Riemann symmetries to factors factor..n_factors, pruning branches where frozen positions are already worse than best_perm.
Uses two pruning levels:
- Frozen: position j where
slot_to_factor[j] ≤ kandslot_to_factor[perm[j]] ≤ k— value is exact, compare directly. - Bounded: position j where
slot_to_factor[j] ≤ kbutslot_to_factor[perm[j]] > k— value will change but is bounded to[slot_lb[v], slot_ub[v]]. Prune if lb > best, keep if ub < best.
XAct.XInvar._bare_index — Method
_bare_index(idx::String) -> StringStrip the leading '-' from a covariant index.
XAct.XInvar._build_case_dispatch — Method
_build_case_dispatch(index_to_perm, case) -> Dict{Vector{Int}, Int}Build a reverse lookup for a single case: canonical involution → invariant index. DB permutations are converted from Invar labeling convention to contraction involutions and canonicalized to match the output of _canonicalize_contraction_perm.
XAct.XInvar._build_case_dispatch_raw — Method
_build_case_dispatch_raw(index_to_perm) -> Dict{Vector{Int}, Int}Build a reverse lookup for a single case using raw DB permutations (no conversion). Used for dual cases where the epsilon tensor slots complicate canonicalization.
XAct.XInvar._canonicalize_contraction_perm — Method
_canonicalize_contraction_perm(perm, case) -> (canonical_perm, sign)Canonicalize a contraction permutation under the symmetry group of a product of Riemann tensors. The symmetry group combines:
- Riemann pair symmetries (8 elements per factor): swap (a,b) sign=-1, swap (c,d) sign=-1, exchange pairs (a,b)↔(c,d) sign=+1.
- Block permutations of factors with the same derivative order (sign = parity).
Returns the lexicographically minimal permutation and its sign.
XAct.XInvar._case_to_filename — Method
_case_to_filename(deriv_orders::Vector{Int}) -> StringEncode a case vector as a filename component. [0,0] → "0_0", [0] → "0", [1,3] → "1_3".
Matches Wolfram intercase (Invar.m:252).
XAct.XInvar._classify_case — Method
_classify_case(expr::String, metric::Symbol) -> InvariantCaseClassify a single monomial (product of Riemann tensors, possibly with CovD derivatives) into an InvariantCase. Ricci/RicciScalar should already be replaced with Riemann.
XAct.XInvar._collect_inv_terms — Method
_collect_inv_terms(expr::InvExpr) -> InvExprCombine like terms (same RInv) and remove zeros. Returns sorted result.
XAct.XInvar._collect_used_indices — Method
_collect_used_indices(expr::String) -> Set{String}Collect all bare index names used in the expression.
XAct.XInvar._cycles_to_images — Method
_cycles_to_images(cycles::Vector{Vector{Int}}, degree::Int) -> Vector{Int}Convert a list of disjoint cycles to images (one-line) notation.
Each cycle [a, b, c, ...] means a→b, b→c, ..., last→a. Fixed points map to themselves.
Example: [[2,1],[4,3]] on degree 4 → [2,1,4,3] Example: [[1,3,2]] on degree 4 → [3,2,1,4] (1→3, 3→2, 2→1, 4→4)
XAct.XInvar._dinv_filename — Method
_dinv_filename(step::Int, case::Vector{Int}; dim::Int=0) -> StringBuild a DInv (dual) filename. Matches Wolfram dualfilename (Invar.m:259-260).
XAct.XInvar._ensure_case_dispatch — Method
_ensure_case_dispatch(db::InvarDB, case_key::Vector{Int}, is_dual::Bool) -> Dict{Vector{Int}, Int}Return the cached dispatch table for a specific case, building it lazily if needed. Non-dual cases convert from Invar labeling to canonical involutions. Dual cases use raw DB perms (looked up via _involution_to_invar_perm conversion).
XAct.XInvar._ensure_invar_db — Function
_ensure_invar_db(; dbdir::String="", dim::Int=4) -> InvarDBLoad the Invar database for the given dimension if not already cached. Returns the cached instance. If dbdir is empty, searches standard resource paths.
XAct.XInvar._extract_contraction_perm — Method
_extract_contraction_perm(expr::String, case::InvariantCase) -> Vector{Int}Extract the contraction permutation from a monomial string.
Slot assignment: for each Riemann factor (left to right), CovD indices come before the 4 Riemann indices. The result is an involution: perm[i] = j and perm[j] = i for each contracted pair (i, j).
XAct.XInvar._extract_inv_case — Method
_extract_inv_case(s::String) -> Union{Nothing, Vector{Int}}Extract the case vector from RInv[{0,0},3] → [0,0].
XAct.XInvar._extract_inv_index — Method
_extract_inv_index(s::String) -> Union{Nothing, Int}Extract the invariant index from RInv[{0,0},3] or DualRInv[{0,0},3] → 3.
XAct.XInvar._find_covd_split — Method
_find_covd_split(content::String) -> Union{Int, Nothing}Find the position of '][' in content that indicates a CovD split. Returns the position of the ']' or nothing.
XAct.XInvar._find_self_contractions — Method
Find pairs of indices within a single factor that contract with each other. Returns list of (slot1, slot2) tuples.
XAct.XInvar._format_rational — Method
Format a rational coefficient as a string. Integers omit the denominator.
XAct.XInvar._fresh_indices — Method
_fresh_indices(n::Int, used::Set{String}) -> Vector{String}Generate n fresh index names not in used. Mutates used by adding the new names.
XAct.XInvar._inv_expr_to_string — Method
_inv_expr_to_string(expr::InvExpr; covd, curvature_relations, db) -> StringConvert a simplified InvExpr back to a tensor expression string.
XAct.XInvar._invar_perm_to_involution — Method
_invar_perm_to_involution(σ::Vector{Int}) -> Vector{Int}Convert a Wolfram Invar "canonical labeling" permutation to a contraction involution. In the Invar convention, σ(i) gives the position of slot i in a canonical paired arrangement where pairs occupy consecutive positions (1,2), (3,4), etc. The returned involution maps each slot to the slot it contracts with: invol[i] = j means slot i and slot j share the same dummy index.
XAct.XInvar._involution_to_invar_perm — Method
_involution_to_invar_perm(invol::Vector{Int}) -> Vector{Int}Convert a contraction involution back to the Wolfram Invar "canonical labeling" convention. Contracted pairs are assigned consecutive positions (1,2), (3,4), etc. in the order they appear (scanning slots left to right).
XAct.XInvar._is_covariant_idx — Method
_is_covariant_idx(idx::String) -> BoolTrue if the index is covariant (starts with '-').
XAct.XInvar._monomial_to_rperm — Method
Process a single monomial into (coefficient, RPerm).
XAct.XInvar._parse_coefficient — Method
_parse_coefficient(s::String) -> Rational{Int}Parse a coefficient string that may include:
- Empty or "+" → 1//1
- "-" → -1//1
- "2*" → 2//1
- "-3/2*" → -3//2
- "sigma*" → 1//1 (sigma is the sign of the metric determinant, treated as symbolic)
- "- sigma*" → -1//1
Note: sigma appears in some step-6 (dual) rules. We store it as ±1 since the actual sign is resolved at application time.
XAct.XInvar._parse_idx_list — Method
_parse_idx_list(s::String) -> Vector{String}Parse a comma-separated index list like "-a,-b,c,d" into ["-a", "-b", "c", "d"].
XAct.XInvar._parse_int_csv — Method
_parse_int_csv(s::String) -> Vector{Int}Parse a comma-separated string of integers: "2,1" → [2, 1].
XAct.XInvar._parse_invar_monomial — Method
_parse_invar_monomial(mono::String) -> (Rational{Int}, Vector{_InvarFactor})Parse a monomial string into its numeric coefficient and tensor factors. Handles CovD notation: CD[-e][RiemannCD[-a,-b,-c,-d]] is parsed as a single factor with covd_indices=["-e"] and tensor RiemannCD with indices ["-a","-b","-c","-d"].
XAct.XInvar._parse_invar_sum — Method
_parse_invar_sum(expr::String) -> Vector{Tuple{Int, String}}Split an expression on top-level + and - (not inside brackets) into signed monomial strings. Returns (sign, monomial_string) pairs.
XAct.XInvar._parse_linear_combination — Method
_parse_linear_combination(s::String) -> Vector{Tuple{Int, Rational{Int}}}Parse a linear combination of RInv/DualRInv terms.
Examples:
RInv[{0,0},1] - RInv[{0,0},2]→ [(1, 1//1), (2, -1//1)]2*RInv[{0,0},1]→ [(1, 2//1)]-3/2*RInv[{0,0},1] + RInv[{0,0},2]→ [(1, -3//2), (2, 1//1)]RInv[{0,0},2]/2→ [(2, 1//2)] (trailing division)-RInv[{0,0,0},5]/4+RInv[{0,0,0},8]→ [(5, -1//4), (8, 1//1)]
XAct.XInvar._parse_maple_perm_line — Method
_parse_maple_perm_line(line::String) -> Union{Nothing, Vector{Int}}Parse a single line of step-1 (Maple format) perm file.
Handles two formats:
- Legacy:
RInv[{0,0},1] := [[2,1],[4,3],[6,5],[8,7]]; - Current (xact.es download):
[[2,3],[4,5],[6,7]]:(bare cycles + trailing colon)
The Wolfram parser (ReadInvarPerms, Invar.m:284) uses readline to strip the prefix before := and the trailing ; or :, then replacebrackets and ToExpression.
Returns nothing for blank or comment lines.
XAct.XInvar._parse_mma_rule — Method
_parse_mma_rule(line::String) -> Union{Nothing, Tuple{Int, Vector{Tuple{Int, Rational{Int}}}}}Parse a single line of steps 2-6 (Mathematica format) rule file.
Format: RInv[{0,0},3] -> RInv[{0,0},1] - RInv[{0,0},2]
Returns (dependent_index, [(independent_index, coefficient), ...]) or nothing.
The LHS is always a single RInv[{case},idx] or DualRInv[{case},idx]. The RHS is a linear combination of RInv/DualRInv terms with rational coefficients.
XAct.XInvar._parse_nested_intlist — Method
_parse_nested_intlist(s::String) -> Vector{Vector{Int}}Parse a string like [[2,1],[4,3],[6,5],[8,7]] into a vector of int vectors. Handles both [...] (Maple) and {...} (Mathematica) bracket styles.
XAct.XInvar._parse_one_factor — Method
_parse_one_factor(s, pos) -> (_InvarFactor or nothing, new_pos)Parse one tensor factor starting at position pos. Handles both plain TensorName[indices] and CovD-wrapped CovD[-i][...CovD[-j][Tensor[indices]]...].
XAct.XInvar._perm_sign_of — Method
_perm_sign_of(arr::Vector{Int}) -> IntCompute the sign (parity) of the permutation arr relative to its sorted order.
XAct.XInvar._reset_invar_db! — Method
_reset_invar_db!()Clear all cached InvarDB instances and dispatch tables. Called by reset_state! in XAct.jl.
XAct.XInvar._ricci_to_riemann — Method
_ricci_to_riemann(expr::String, covd::Symbol) -> StringReplace Ricci and RicciScalar tensors with their contracted Riemann equivalents.
RicciCD[-a,-b]→RiemannCD[xa,-a,-xa,-b](contracted Riemann)RicciScalarCD[]→RiemannCD[xa,xb,-xa,-xb](double-contracted Riemann)
The covd name determines the tensor prefix (e.g., covd=:CD → RiemannCD, RicciCD, etc.).
XAct.XInvar._riemann_to_ricci — Method
_riemann_to_ricci(expr::String, covd::Symbol) -> StringReplace contracted Riemann patterns with Ricci/RicciScalar where applicable. A Riemann factor with indices that self-contract can be simplified.
XAct.XInvar._rinv_filename — Method
_rinv_filename(step::Int, case::Vector{Int}; dim::Int=0) -> StringBuild an RInv filename. Matches Wolfram filename (Invar.m:255-256).
filename[step:(5|6), case, dim] = filename[step, case] * "_" * dim
filename[step, case] = "RInv-" * intercase(case) * "-" * stepXAct.XInvar._sorted_partitions — Method
All partitions of n into k non-negative parts in non-decreasing order.
XAct.XInvar._step_subdir — Method
_step_subdir(step::Int; dim::Int=4) -> StringReturn the subdirectory name for a given step.
Step 1: "1"
Step 2: "2"
Step 3: "3"
Step 4: "4"
Step 5: "5_$dim" (e.g. "5_4")
Step 6: "6_$dim" (e.g. "6_4")XAct.XInvar._swap_slots! — Method
_swap_slots!(perm::Vector{Int}, a::Int, b::Int)Conjugate the contraction permutation by the transposition (a b). This swaps slots a and b: perm → (a b) ∘ perm ∘ (a b).
XAct.XInvar.read_invar_perms — Method
read_invar_perms(filepath::String; degree::Int=0) -> Dict{Int, Vector{Int}}Read a step-1 (Maple format) permutation basis file. Returns Dict mapping invariant index (1-based, positional) to permutation in images notation.
Each line in the file defines one invariant's contraction permutation. Lines are indexed sequentially: line 1 = invariant 1, line 2 = invariant 2, etc.
The degree parameter specifies the permutation degree (number of index slots). If 0, the degree is inferred from the max element in the cycles (may be too small if the last positions are fixed points).
Reference: Wolfram ReadInvarPerms (Invar.m:284).
XAct.XInvar.read_invar_rules — Method
read_invar_rules(filepath::String) -> Dict{Int, Vector{Tuple{Int, Rational{Int}}}}Read a steps 2-6 (Mathematica format) rule file. Returns Dict mapping dependent invariant index to its linear combination of independent invariants: [(index, coefficient), ...].
Reference: Wolfram ReadInvarRules (Invar.m:293).
XAct.XInvar.InvExpr — Type
A linear combination of RInv terms: [(coefficient, RInv), ...].
XAct.XInvar.InvarDB — Type
InvarDBHolds all loaded database state: permutation bases (step 1) and substitution rules (steps 2-6).
Fields:
perms: case → (index → permutation in images notation)dual_perms: case → (index → permutation in images notation)rules: step → (case → (dependentindex → [(independentindex, coefficient)]))dual_rules: step → (case → (dependentindex → [(independentindex, coefficient)]))
XAct.XInvar.InvariantCase — Type
InvariantCase(deriv_orders, n_epsilon=0)Classifies a Riemann scalar monomial by the derivative orders on each Riemann factor and the number of epsilon (Levi-Civita) tensors.
deriv_orders: sorted non-decreasing list; length = degree (number of Riemanns)n_epsilon: 0 = non-dual, 1 = dual (4D only)
The derivative order of an invariant case is 2 * degree + sum(deriv_orders).
XAct.XInvar.RInv — Type
RInv(metric, case, index)A labeled Riemann invariant with a canonical index (1-based) from the Invar database.
XAct.XInvar.RPerm — Type
RPerm(metric, case, perm)A Riemann invariant in permutation representation. The permutation encodes the contraction pattern of indices across all tensor factors in images notation.
XAct.XInvar._InvarFactor — Type
A parsed tensor factor from a monomial string.
XAct.XInvar._invar_db_cache — Constant
Global cached InvarDB instances, keyed by dimension. Different dimensions load different step-5 rules.
XAct.XInvar._perm_dispatch — Constant
Global cached dispatch tables. Built lazily per case on first PermToInv call. Perm→index mapping is dimension-independent (structural, not rule-dependent).
XAct.TExprLayer._parse_to_texpr — Method
_parse_to_texpr(s::AbstractString) -> TExprParse an engine output string into a typed expression tree.
Supported formats (same as _to_string output):
"0"→TScalar(0//1)"Name[i1,i2]"→TTensor"Name[-i][operand]"→TCovD"2 * Name[...]","(1/2) * Name[...]","-Name[...]"→TProd"A + B","A - B"→TSum
XAct.TExprLayer._to_string_factor — Method
Serialise a factor inside a product, parenthesising sums.
XAct.TExprLayer.covd — Method
covd(name::Symbol) -> CovDHeadLook up a registered covariant derivative and return a CovDHead handle. Throws if name is not a defined CovD.
XAct.TExprLayer.tensor — Method
tensor(name::Symbol) -> TensorHeadLook up a registered tensor and return a TensorHead handle. Throws if the tensor is not defined (e.g. after reset_state!()).
XAct.TExprLayer.CovDHead — Type
Lightweight handle for a registered covariant derivative. Not a TExpr.
XAct.TExprLayer.DnIdx — Type
Covariant (down) index — wraps an Idx.
XAct.TExprLayer.Idx — Type
Abstract index label bound to a manifold (contravariant / up).
XAct.TExprLayer.TCovD — Type
Covariant derivative applied to an expression: CD[-a](T[-b,-c]).
XAct.TExprLayer.TProd — Type
Product of tensor expressions with a rational coefficient.
XAct.TExprLayer.TScalar — Type
Numeric scalar coefficient.
XAct.TExprLayer.TSum — Type
Sum of tensor expressions.
XAct.TExprLayer.TSymbol — Type
Bare symbol returned by the engine (e.g. a perturbation tensor name without indices). Serialises back to the bare name string.
XAct.TExprLayer.TTensor — Type
A tensor with indices applied, e.g. T[-a, -b].
XAct.TExprLayer.TensorHead — Type
Lightweight handle for a registered tensor. Not a TExpr itself; must apply indices via getindex to produce a TTensor.
XAct.TExprLayer._CovDApplicator — Type
Intermediate callable produced by CD[-a]; call it on a TExpr to produce a TCovD node.
XAct.TExprLayer.SlotIdx — Type
Union of Idx and DnIdx — anything that goes in a tensor slot.
XAct.TExprLayer.@indices — Macro
@indices M a b c d ...Declare index variables bound to manifold M. Generates runtime Idx constructor calls (with validation) that assign each name in the current scope.
Example:
def_manifold!(:M, 4, [:a, :b, :c, :d])
@indices M a b c d
# a = Idx(:a, :M), b = Idx(:b, :M), ...Typed Expression API (TExprLayer)
The TExprLayer module provides a typed, validated expression layer on top of the string-based engine API.
Current behavior: engine functions accept TExpr inputs, serialize them into the existing string-based engine, then reconstruct typed results on the way out where supported.
Index Types
# Declare index variables bound to manifold M
def_manifold!(:M, 4, [:a, :b, :c, :d])
@indices M a b c d
# a = Idx(:a, :M), b = Idx(:b, :M), ...
# Covariant (down) index via negation
-a # DnIdx wrapping a
--a # back to Idx (identity)| Type | Description |
|---|---|
Idx(label, manifold) | Contravariant (up) index bound to a manifold |
DnIdx(parent) | Covariant (down) index; produced by -idx |
SlotIdx | Union of Idx and DnIdx |
Expression Types
| Type | Description | Example |
|---|---|---|
TTensor | Tensor with indices applied | T[-a, -b] |
TProd | Product with rational coefficient | 2 * T[-a] * V[a] |
TSum | Sum of expressions | T[-a,-b] + S[-a,-b] |
TCovD | Covariant derivative applied to an expression, e.g. a scalar field | CD[-a] acting on a scalar tensor |
Handles (not TExpr)
| Type | Description |
|---|---|
TensorHead | Lightweight tensor name handle; apply indices via T[...] |
CovDHead | Covariant derivative handle; apply index via CD[-a] |
Factory Functions
# Declare typed index variables
@indices M a b c d # binds a, b, c, d as Idx(:a,:M), ...
# Look up registered tensor by name
Riem = tensor(:RiemannCD) # or tensor("RiemannCD")
g = tensor(:g)
# Look up registered covariant derivative
CD = covd(:CD)Operator Overloading
def_manifold!(:M, 4, [:a, :b, :c, :d])
def_metric!(-1, "g[-a,-b]", :CD)
@indices M a b c d
# Apply indices
Riem = tensor(:RiemannCD)
expr = Riem[-a, -b, -c, -d] # TTensor
# Arithmetic
T = tensor(:T)
prod = T[-a, -b] * T[a, c] # TProd
sum = T[-a, -b] + T[-b, -a] # TSum
neg = -T[-a, -b] # TProd(coeff=-1, ...)
scl = 2 * T[-a, -b] # TProd(coeff=2, ...)
# Covariant derivative
CD = covd(:CD)
phi = tensor(:phi)
deriv = CD[-a](scalar_field) # TCovD over a scalar expressionValidation at Construction Time
Errors are raised when the expression is built, not deep in the engine:
# Wrong slot count
T[-a] # ERROR: T has 2 slots, got 1
# Index from wrong manifold
@indices N p q
T[-p, -q] # ERROR: p is from manifold N, but T expects MEngine Integration
All engine functions accept TExpr in addition to String:
# These two are equivalent:
ToCanonical("RiemannCD[-a,-b,-c,-d] + RiemannCD[-a,-c,-d,-b]")
Riem = tensor(:RiemannCD)
@indices M a b c d
ToCanonical(Riem[-a,-b,-c,-d] + Riem[-a,-c,-d,-b])Supported: ToCanonical, Contract, Simplify, perturb, CommuteCovDs, SortCovDs, IBP, TotalDerivativeQ, VarD.