CG Coefficients
Matchete includes a framework for dealing with contractions of Clebsch-Gordan coefficients (CGs) in a pseudo-symbolic manner. The workflow involves associating explicit tensor representations to each symbolic CG. This allows contractions to be evaluated numerically (exact) with tensor contractions before the result is projected onto a basis consisting of the already defined CGs.
Organizing the symbolic CGs
All CGs transform under the action of a particular (gauge) group. It would be absurd to start talking about contracting invariants of SU(2)L and SU(3)c. Even contractions between two distinct SU(2) groups would not be sensible. To allow for evaluations in scenarios with multiple group indices, as required in realistic QFTs such as the SM, we must first define the symmetry groups and the relevant representations.
| DefineCGGroup[groupName, alg] | initializaes a Lie group with a reference name and algebra. |
| DefineRepresentation[repName, groupName, rep] | initializes a representation under a group with a representation name and its Dynkin coefficients. |
A group is initialized by giving it a reference name and specifying its Lie algebra (Alg), which informs all the representation theory associated with said group. The group name is a label that the user should use to refer to that specific group. The use of group names ensures that multiple groups with identical algebra can be discriminated. The user may, thus, define multiple SU(2) groups in the same session. When a group has been defined, one can define representations of that group to be used in Lagrangians of group theory contractions.
We may define a group, by specifying an arbitrary group label (SU3c), and an algebra (SU[3] in this case). GetGroups can be used to get an association with all the groups that have been defined in the current session.
We can then add representations for our SU(3) group that we wish to use in calculations. DefineRepresentations takes an arbitrary label used to reference it, the name of the group it belongs to, and the Dynkin coefficients specifying the (highest weight of the) representation in the group algebra. Here we define a fundamental, a 2-index symmetric, and an adjoint representations of our SU(3) group, while GetRepresentations returns an association with details about all representations defined in the current session:
N.b. DefineCGGroup is too bare bones for QFT applications. The user is encouraged to use DefineGaugeGroup or DefineGlobalGroup instead according to circumstances. These functions specifies important additional information about the QFT to Matchete in addition to automatically setting up some common representations and and CGs.
Indices in Matchete — for fields, CGs, derivatives, etc. — all have an index type. They are represented internally with Index[label, type], and all the representations that have been defined are valid index types. Bar is used to denote conjugate indices for indices in pseudoreal or complex representations. Complex and pseudoreal representations are always supposed to contract between conjugate indices with the same label.
Indices with label 'a' of the SU(3) fundamental representation we defined here are (for the ordinary index and its conjugate)
Defining CGs
Having defined groups and representations it becomes possible to define new CGs for use in calculations. Matchete needs information about the representation of all indices on the CG symbol and should have an exact numerical tensor to substitute in for the symbol when performing contractions with other CGs. Currently, there are two ways for the user to specify a new CG symbol to the program.
| DefineCG[cgName, {rep1, rep2, …}, tensor] | defines a CG symbol with indices in the the representations from a numerical tensor. |
| DefineCompositeCG[cgName, {cg1, cg2,…}, {indices1, indices2,…}] |
defines a CG symbol as a contraction (Einstein summation) of known CGs.
|
The most direct way of defining a CG is to use DefineCG. It requires 3 arguments: a label, a list of the representations of the indices, and an explicit sparse array with the numerical values for the tensor. Typically, the functions made available for the group invariants are used to construct/find explicit invariant tensors as detailed in Group Magic.
Returning to the example of the adjoint representation adj for our SU(3) group SU3c, we may define various CG coefficient corresponding to different invariant contractions of those indices. Here we define a Kronecker delta, the structure constants and the three-index symmetric invariant:
Here we have used InvariantTensors and StructureConstants to obtain the appropriate numerical tensor for each CG. A Kronecker delta CG for the adjoint representation, named del[adj], was automatically initialized when we defined the representation. At any time we can check the numerical tensor associated with a CG with GetCGTensor:
For indices of non-real representations, we need to distinguish between the indices and the conjugates. For instance, the Kronecker delta δij associated with fund comes with a fundamental and an anti-fundamental index of SU(3). It contracts (is an invariant of) an anti-fundamental and a fundamental representations: the order is reversed. We may specify that an index of a CG belongs to the conjugate representation by applying a Bar to the representation name.
The Kronecker delta of the fund representation of SU3c is automatically defined with the representation and is named del[fund]. If the user wanted to define such a delta themself, it might look like
The first index is fundamental and the second anti-fundamental. Valid contractions should always contract fundamental and anti-fundamental indices to ensure proper covariance, since the representation is complex. Also the InvariantTensors call needs to discriminate between the two indices by invoking the conjugate representation with CRep. Similarly, the generators of the fundamental representation comes with a fundamental and an anti-fundamental index. It can be initializes as
N.b. The user has a lot of flexibility when defining new CGs, but it requires meticulous care to get it right. We encourage the user to perform crosschecks wherever possible, to ensure that their CGs behave as expected.
Clearly, many other invariants can be constructed, but DefineCG will already be sufficient for most purposes. Sometimes it can be useful to construct new CGs from contractions of previously defined CGs, rather than use the rather less transparent InvariantTensors function to obtain a suitable numeric tensor. In such cases we can use the DefineCompositeCG to initialize the CG. The first argument is the CG label; the second argument is a list of CGs to be included in this tensor; and the third and last argument is a list of list of index labels for each of the CGs, with repeated indices being contracted and the rest open.
For instance, there are 8 invariants of 4 adjoint SU(3) representations if there are no restrictions from tensor symmetries. A good basis CG could be taken as the trace of fundamental generators Ta b c d=Tr[ta tb tc td], which has 6 unique permutations of indices making up 6 linearly independent invariants. We define this CG with
The CG object
| CG[cgName, {index1, index2,…}] | represents a CG with two or more indices. |
The Matchete form of the CG object.
The basic object in computations involving CGs is the CG head. The first argument of CG specifies the specific tensor (its label); the second argument is a list of its indices. For convenience we can enter a CG by specifying only the labels of the indices rather than entering them as Index objects. The full indices are automatically constructed based on the CG object. One can only enter CG objects that have already been initialized in the current session. Thus, Matchete never encounters unknown CGs. The CG objects are conveniently formatted under NiceForm, so that the user doesn't have to see the internal representation.
A second even more ergonomic shorthand notation is created when the CG is defined. We may simply use the CG label as a function like
Other than constructing the indices, CG does not do any evaluation: there is nothing to evaluate. Rather it is just the internal representation of a CG tensor. Sometimes one might wish to use the complex conjugate CG. Bar can be applied to CGs to get the complex conjugate.
Since the the fundamental generators are Hermitian, we observe that Bar simplifies away:
N.b. When applying Bar to a CG it turns the indices of any non-real representation into indices of the conjugate representation and vice versa.
Cleanup
Several functions are available to remove already loaded definitions of groups, representations, and CGs. When removing any of these, the functions automatically removes all associated definitions that rely on the one removed. These functions can be convenient when making mistakes during the setup of a model or something similar. In most other cases, the user may simply rely on ResetAll, which also removes all group definitions.
| RemoveCG[cgName] | removes the definition of a CG symbol. |
| RemoveRepresentation[repName] | removes the definition of a representation and all associated CGs. |
| RemoveGroup[groupName] | removes the definition of a group and all associated representations. |
| ClearGroups[] |
Removes all defined groups, representations and CGs.
|
Evaluating CG contractions
To evaluate contractions between CGs, we use the function ContractCGs , which will evaluate CG contractions appearing in all terms of an expression. That is ContractCGs carries out all Einstein summation between CGs, producing a result with no dummy-index contractions between CGs . To see how this works in practice, consider the following examples:
ContractCGs is not restricted to simple products of CGs, but works on generic expressions, such as
We can quickly verify that the Tr4 tensor is implemented correctly implemented as a trace of four generators of the fund representation:
ContractCGs is a versatile implementation of all manner of CG contractions. This versatility is due to contractions being performed numerically, a technique that is generally applicable to all possible CG contractions. However, numerical contractions of tensors can be computationally expensive, especially if the representations are large.
Going outside the CG basis
Finally, we see what happens when the predefined CGs are insufficient to identify a CG showing up in a product. In that case a new CG will simply be added and a message is displayed to inform the user about it. Any new CG defined this way can be used in CG objects same as any user defined CGs.
An example of going outside the CG basis derived from the previously defined CGs is the generator product (TATB)ij of two generators of the fund representation of SU3c:
The new CG gets a generic name, cg1 in this case, the user might therefore wish to rename it for easier reference with RenameCG; however, this is purely optional and not required to use the CG.
Some detective work is typically required to figure out what a new CG is. Particularly if it got defined deep in some Matchete calculation outside the control of the user. It can also happen that a CG is defined during the course of an evaluation but never makes it to the output. The first clue is to look at the message informing about the creation of the new CG, which provides a list of the representation of all the indices of the new CG. In some simple cases the user might be able to identify the CG through the explicit tensor representation with GetCGTensor, although more often than not this is next to meaningless to humans (and basis dependent). More commonly, the new CG can be traced back by using ReplaceCGs[expr] to re-expand the new CG. By default ReplaceCGs replaces all composite CGs created both by the user an automatically. Using the option CGsToReplace (default All), only the specified CGs will be replaced in an expression.
The composite CGs Tr4 (defined by the user with DefineCompositeCG) and t3t3 (defined automatically during ContractCGs) can be replaced simultaneously or one at a time to reveal the underlying contraction of CGs:
The user might wonder what then is the reason for adding the new CG at all if we simply wish to deconstruct it again? The benefit is that it simplifies expressions, and removes all internal index contractions, which helps identify and collect terms in complicated expressions.
Having defined t3t3, it becomes active in the CG basis and it can be identified in other CG contractions, such as
When dealing with new composite CGs showing up in a calculation, it can at times be beneficial to go back to the beginning and add a specific suitable CG to the basis (with definite symmetries) rather than relying on those that are automatically defined. Matchete does not attempt to be clever when assigning new CGs but takes the first new contraction that goes outside its basis as a new basis element with no consideration for further practicalities.
In place of the contraction of two fund generators, which does not poses any definite symmetry between the two adjoint indices, we might instead contract the generator with the f3 or d3 tensors. So we remove the automatically defined tensor (removing it from the basis) and define the two new tensors