New Features in Maple 2018 - Physics - Maplesoft

What's New in Maple 2018

Physics




Maple provides a state-of-the-art environment for algebraic computations in Physics, with emphasis on ensuring that the computational experience is as natural as possible. The theme of the Physics project for Maple 2018 has been the consolidation of the functionality introduced in previous releases, together with significant enhancements, mainly in the handling of differential (quantum or not) tensorial operators, new ways to minimize the number of tensor components taking its symmetries into account, automatic handling of collision of indices in tensorial expressions, automatic setting of the EnergyMomentum tensor when loading solutions to Einstein's equations from the database of solutions, automatic setting of the algebras for the Dirac, Pauli and Gell-Mann matrices when Physics is loaded, simplification of Dirac matrices, a new package Physics:-Cactus related to Numerical Relativity and several other improvements.

Taking all together, there are more than 300 enhancements throughout the entire package, increasing robustness, versatility and functionality, extending once more the range of Physics-related algebraic computations that can be done using computer algebra software, and in a natural way.

As part of its commitment to providing the best possible environment for algebraic computations in Physics, Maplesoft launched a Maple Physics: Research and Development web site with Maple 18, which enabled users to download research versions, ask questions, and provide feedback. The results from this accelerated exchange with people around the world have been incorporated into the Physics package in Maple 2018.



Automatic handling of collision of tensor indices in products

User defined algebraic differential operators

Automatic setting of the EnergyMomentumTensor for metrics of the database of solutions to Einstein's equations

Minimize the number of tensor components according to its symmetries, relabel, redefine or count the number of independent tensor components 

New functionality and display for inert names and inert tensors

Automatic setting of Dirac, Paul and Gell-Mann algebras

Simplification of products of Dirac matrices

New Library routines to perform matrix operations in expressions involving spinors with omitted indices 

Miscellaneous improvements




Automatic handling of collision of tensor indices in products 

The design of products of tensorial expressions that have contracted indices got enhanced. The idea: repeated indices in certain subexpressions are actually dummies. So suppose T[a, b] and B[b] are tensors, then in T[trace] = T[a, `~a`], a is just dummy, therefore `*`(T[a, `~a`], `*`(B[a])) = `*`(T[b, `~b`], `*`(B[a])) is a well defined object. The new design automatically maps input like `*`(T[a, `~a`], `*`(B[a])) into `*`(T[b, `~b`], `*`(B[a])).

> restart; 1
> with(Physics); -1; Setup(spacetimeindices = lowercaselatin, quiet)
[spacetimeindices = lowercaselatin] (1)
> Define(T[a, b], B[b])
`Defined objects with tensor properties`
{B[b], Physics:-Dgamma[a], Physics:-Psigma[a], T[a, b], Physics:-d_[a], Physics:-g_[a, b], Physics:-KroneckerDelta[a, b], Physics:-LeviCivita[a, b, c, d]} (2)

This shows the automatic handling of collision of indices

> `*`(T[a, a], `*`(B[a]))
`*`(T[b, `~b`], `*`(B[a])) (3)
> `*`(`^`(T[a, a], 2))
`*`(T[a, `~a`], `*`(T[b, `~b`])) (4)

Consider now the case of three tensors

> Define(A[a], C[a])
`Defined objects with tensor properties`
{A[a], B[b], C[a], Physics:-Dgamma[a], Physics:-Psigma[a], T[a, b], Physics:-d_[a], Physics:-g_[a, b], Physics:-KroneckerDelta[a, b], Physics:-LeviCivita[a, b, c, d]} (5)
> `*`(A[a], `*`(B[a], `*`(C[a])))
`*`(A[a], `*`(B[a], `*`(C[a]))) (6)

The product above has indeed the index a repeated more than once, therefore none of its occurrences got automatically transformed into contravariant in the output, and Check detects the problem interrupting with an error message

> Check(`*`(A[a], `*`(B[a], `*`(C[a]))))
Error, (in Physics:-Check) wrong use of the summation rule for repeated indices: `a repeated 3 times`, in A[a]*B[a]*C[a]

However, it is now also possible to indicate, using parenthesis, that the product of two of these tensors actually form a subexpression, so that the following two tensorial expressions are well defined, where the dummy is automatically replaced making that explicit


> `*`(A[a], `*`(B[a], `*`(C[a])))
`*`(A[b], `*`(B[`~b`], `*`(C[a]))) (7)
> `*`(A[a], `*`(B[a], `*`(C[a])))
`*`(A[a], `*`(B[b], `*`(C[`~b`]))) (8)

This change in design makes concretely simpler the use of indices in that it eliminates the need for manually replacing dummies. For example, consider the tensorial expression for the angular momentum in terms of the coordinates and momentum vectors, in 3 dimensions

> Setup(coordinates = cartesian, dimension = 3, metric = euclidean, quiet)
[coordinatesystems = {X}, dimension = 3, metric = {(1, 1) = 1, (2, 2) = 1, (3, 3) = 1}] (9)

Define L[j], p[k] respectively representing angular and linear momentum

> Define(L[j], p[k])
`Defined objects with tensor properties`
Typesetting:-mprintslash([{Physics:-Dgamma[a], L[j], Physics:-Psigma[a], X[a], Physics:-d_[a], Physics:-g_[a, b], p[k], Physics:-KroneckerDelta[a, b], Physics:-LeviCivita[a, b, c]}], [{Physics:-Dgamma... (10)

Introduce the tensorial expression for L[a]

> L[a] = `*`(LeviCivita[a, b, c], `*`(X[b], `*`(p[c])))
Typesetting:-mprintslash([L[a] = `*`(Physics:-LeviCivita[a, b, c], `*`(X[b], `*`(p[c])))], [L[a] = `*`(Physics:-LeviCivita[a, b, c], `*`(Physics:-SpaceTimeVector[b](X), `*`(p[c])))]) (11)

The left-hand side has one free index, a, while the right-hand side has two dummy indices b and c  

> Check(L[a] = `*`(Physics:-LeviCivita[a, b, c], `*`(Physics:-SpaceTimeVector[b](X), `*`(p[c]))), all)
`*`(`The repeated indices per term are: `[{`...`}, {`...`}, `...`], `*`(`; the free indices are: `, `*`({`...`})))
([{}], {a}) = ([{b, c}], {a}) (12)

If we want to compute`#mrow(msup(mfenced(mover(mi(we can now take the square of L[a] = `*`(LeviCivita[a, b, c], `*`(X[b], `*`(p[c]))) directly, and the dummy indices on the right-hand side are automatically handled, there is now no need to manually substitute the repeated indices to avoid their collision

> `^`(L[a] = `*`(Physics:-LeviCivita[a, b, c], `*`(Physics:-SpaceTimeVector[b](X), `*`(p[c]))), 2)
Typesetting:-mprintslash([`*`(`^`(L[a], 2)) = `*`(Physics:-LeviCivita[a, b, c], `*`(X[b], `*`(p[c], `*`(Physics:-LeviCivita[a, d, e], `*`(X[d], `*`(p[e]))))))], [`*`(`^`(L[a], 2)) = `*`(Physics:-LeviC... (13)

The repeated indices on the right-hand side are now a, b, c, d, e

> Check(`*`(`^`(L[a], 2)) = `*`(Physics:-LeviCivita[a, b, c], `*`(Physics:-SpaceTimeVector[b](X), `*`(p[c], `*`(Physics:-LeviCivita[a, d, e], `*`(Physics:-SpaceTimeVector[d](X), `*`(p[e])))))), all)
`*`(`The repeated indices per term are: `[{`...`}, {`...`}, `...`], `*`(`; the free indices are: `, `*`({`...`})))
([{a}], {}) = ([{a, b, c, d, e}], {}) (14)

User defined algebraicdifferential operators

A new keyword in Setup: differentialoperators, allows for defining differential operators (not necessarily linear) with respect to indicated differentiation variables, so that they are treated as noncommutative operands in products, as we do with paper and pencil. These user-defined differential operators can also be vectorial and/or tensorial or inert. When desired, one can use Library:-ApplyProductOfDifferentialOperators to transform the products in the function application of these operators. This new functionality is a generalization of the differential operators `∂`[mu] and `▿`[mu], and can used beyond Physics.

A new routine Library:-GetDifferentiationVariables also acts on a differential operator and tells who are the corresponding differentiation variables


Example:

In Quantum Mechanics, in the coordinates representation, the component of the momentum operator along the x axis is given by the differential operator


The purpose of the exercises below is thus to derive the commutation rules, in the coordinates representation, between an arbitrary function of the coordinates and the related momentum, departing from the differential representation

p[n] = `+`(`-`(`*`(i, `*`(`ℏ`, `*`(`∂`[n])))));


%Commutator(g(x, y, z), p_) = `*`(I, `*`(`ℏ`, `*`(Typesetting:-delayGradient(F(X)))))

> restart; -1; with(Physics); -1; with(Physics[Vectors]); -1; interface(imaginaryunit = i); -1

Start setting the problem:

  • all ofx, y, z, p__x, p__y, p__z are Hermitian operators
  • all of x, y, z commute between each other
  • tell the system only that the operators x, y, z are the differentiation variables of the corresponding (differential) operators p__x, p__y, p__z but do not tell what is the form of the operators

> Setup(mathematicalnotation = true, differentialoperators = {[p_, [x, y, z]]}, hermitianoperators = {p, x, y, z}, algebrarules = {%Commutator(x, y) = 0, %Commutator(x, z) = 0, %Commutator(y, z) = 0}, q...
Setup(mathematicalnotation = true, differentialoperators = {[p_, [x, y, z]]}, hermitianoperators = {p, x, y, z}, algebrarules = {%Commutator(x, y) = 0, %Commutator(x, z) = 0, %Commutator(y, z) = 0}, q...
Setup(mathematicalnotation = true, differentialoperators = {[p_, [x, y, z]]}, hermitianoperators = {p, x, y, z}, algebrarules = {%Commutator(x, y) = 0, %Commutator(x, z) = 0, %Commutator(y, z) = 0}, q...
Setup(mathematicalnotation = true, differentialoperators = {[p_, [x, y, z]]}, hermitianoperators = {p, x, y, z}, algebrarules = {%Commutator(x, y) = 0, %Commutator(x, z) = 0, %Commutator(y, z) = 0}, q...
Setup(mathematicalnotation = true, differentialoperators = {[p_, [x, y, z]]}, hermitianoperators = {p, x, y, z}, algebrarules = {%Commutator(x, y) = 0, %Commutator(x, z) = 0, %Commutator(y, z) = 0}, q...
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (15)

Assuming F(X) is a smooth function, the idea is to apply the commutator %Commutator(F(X), p_) to an arbitrary ket of the Hilbert space Ket(psi, x, y, z), perform the operation explicitly after setting a differential operator representation for `#mover(mi(, and from there get the commutation rule between F(X) and `#mover(mi(.


Start introducing the commutator, to proceed with full control of the operations we use the inert form %Commutator

> alias(X = (x, y, z)); -1
> CompactDisplay(F(X))
`*`(` F`(X), `*`(`will now be displayed as`, `*`(F))) (16)
> `*`(%Commutator(F(X), p_), `*`(Ket(psi, X)))
Typesetting:-mrow(Typesetting:-mi( (17)

For illustration purposes only (not necessary), expand this commutator

> Physics:-`*`(%Commutator(F(X), p_), Physics:-Ket(psi, x, y, z)) = expand(Physics:-`*`(%Commutator(F(X), p_), Physics:-Ket(psi, x, y, z)))

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (18)

Note that  `#mover(mi(, F(X) and the ket Ket(psi, x, y, z) are operands in the products above and that they do not commute: we indicated that the coordinates x, y, z are the differentiation variables of `#mover(mi(. This emulates what we do when computing with these operators with paper and pencil, where we represent the application of a differential operator as a product operation.

This representation can be transformed into the (traditional in computer algebra) application of the differential operator when desired, as follows:

> Physics:-`*`(%Commutator(F(X), p_), Physics:-Ket(psi, x, y, z)) = Library:-ApplyProductsOfDifferentialOperators(Physics:-`*`(%Commutator(F(X), p_), Physics:-Ket(psi, x, y, z)))
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (19)

Note that, in `#mover(mi(, the application of `#mover(mi( is not expanded: at this point nothing is known about  `#mover(mi( , it is not necessarily a linear operator. In the Quantum Mechanics problem at hands, however, it is. So give now the operator  `#mover(mi( an explicit representation as a linear vectorial differential operator (we use the inert form %Nabla, %Nabla, to be able to proceed with full control one step at a time)

> p_ := proc (f) options operator, arrow; `+`(`-`(`*`(`+`(I), `*`(`ℏ`, `*`(%Nabla(f)))))) end proc
Typesetting:-mprintslash([p_ := proc (f) options operator, arrow; `+`(`-`(Physics:-`*`(I, `ℏ`, %Nabla(f)))) end proc], [proc (f) options operator, arrow; `+`(`-`(Physics:-`*`(I, `ℏ`, %Nabla(... (20)

The expression (19) becomes

> Physics:-`*`(%Commutator(F(X), p_), Physics:-Ket(psi, x, y, z)) = `+`(Physics:-`*`(F(X), p_(Physics:-Ket(psi, x, y, z))), `-`(p_(Physics:-`*`(F(X), Physics:-Ket(psi, x, y, z)))))
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (21)

Activate now the inert operator VectorCalculus:-Nabla and simplify taking into account the algebra rules for the coordinate operators {%Commutator(x, y) = 0, %Commutator(x, z) = 0, %Commutator(y, z) = 0}

> Simplify(value(Physics:-`*`(%Commutator(F(X), p_), Physics:-Ket(psi, x, y, z)) = `+`(`-`(`*`(`+`(I), `*`(`ℏ`, `*`(Physics:-`*`(F(X), %Nabla(Physics:-Ket(psi, x, y, z))))))), `*`(I, `*`(`ℏ`, ...
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (22)

To make explicit the gradient in disguise on the right-hand side, factor out the arbitrary ket Ket(psi, x, y, z)

> Factor(Physics:-`*`(Physics:-Commutator(F(X), p_), Physics:-Ket(psi, x, y, z)) = `+`(`*`(I, `*`(`ℏ`, `*`(_i, `*`(Physics:-`*`(diff(F(X), x), Physics:-Ket(psi, x, y, z)))))), `*`(I, `*`(`ℏ`, ...
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (23)

Combine now the expanded gradient into its inert (not-expanded) form

> subs((Gradient = %Gradient)(F(X)), Physics:-`*`(Physics:-Commutator(F(X), p_), Physics:-Ket(psi, x, y, z)) = `*`(I, `*`(`ℏ`, `*`(Physics:-`*`(`+`(`*`(diff(F(X), x), `*`(_i)), `*`(diff(F(X), y), `...
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (24)

Since subs((Gradient = %Gradient)(F(X)), Physics:-`*`(Physics:-Commutator(F(X), p_), Physics:-Ket(psi, x, y, z)) = `*`(I, `*`(`ℏ`, `*`(Physics:-`*`(`+`(`*`(diff(F(X), x), `*`(_i)), `*`(diff(F(X), y), `... is true for allKet(psi, x, y, z), this ket can be removed from both sides of the equation. One can do that either taking coefficients or multiplying by the "formal inverse" of this ket, arriving at the (expected) form of the commutation rule between F(X) and `#mover(mi(

> 0 = `*`(I, `*`(Inverse(Ket(psi, x, y, z)), `*`(`ℏ`, `*`(%Gradient(F(X)), `*`(Physics:-Ket(psi, x, y, z))))))
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (25)

Tensor notation,

The computation rule for position and momentum, this time in tensor notation, is performed in the same way, just that, additionally, specify that the space indices to be used are lowercase Latin letters, and set the relationship between the differential operators and the coordinates directly using tensor notation.

You can also specify that the metric is Euclidean, but that is not necessary: the default metric of the Physics package, a Minkowski spacetime, includes a 3D subspace that is Euclidean, and the default signature, (- - - +), is not a problem regarding this computation.


> restart; 1; with(Physics); -1; interface(imaginaryunit = i); -1
> Setup(mathematicalnotation = true, coordinates = cartesian, spaceindices = lowercaselatin, algebrarules = {%Commutator(x, y) = 0, %Commutator(x, z) = 0, %Commutator(y, z) = 0}, hermitianoperators = {P...
Setup(mathematicalnotation = true, coordinates = cartesian, spaceindices = lowercaselatin, algebrarules = {%Commutator(x, y) = 0, %Commutator(x, z) = 0, %Commutator(y, z) = 0}, hermitianoperators = {P...
Setup(mathematicalnotation = true, coordinates = cartesian, spaceindices = lowercaselatin, algebrarules = {%Commutator(x, y) = 0, %Commutator(x, z) = 0, %Commutator(y, z) = 0}, hermitianoperators = {P...
Setup(mathematicalnotation = true, coordinates = cartesian, spaceindices = lowercaselatin, algebrarules = {%Commutator(x, y) = 0, %Commutator(x, z) = 0, %Commutator(y, z) = 0}, hermitianoperators = {P...
Setup(mathematicalnotation = true, coordinates = cartesian, spaceindices = lowercaselatin, algebrarules = {%Commutator(x, y) = 0, %Commutator(x, z) = 0, %Commutator(y, z) = 0}, hermitianoperators = {P...
Setup(mathematicalnotation = true, coordinates = cartesian, spaceindices = lowercaselatin, algebrarules = {%Commutator(x, y) = 0, %Commutator(x, z) = 0, %Commutator(y, z) = 0}, hermitianoperators = {P...
Setup(mathematicalnotation = true, coordinates = cartesian, spaceindices = lowercaselatin, algebrarules = {%Commutator(x, y) = 0, %Commutator(x, z) = 0, %Commutator(y, z) = 0}, hermitianoperators = {P...
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (26)

Define now the tensor P[m]

> Define(P[m], quiet)
Typesetting:-mprintslash([{Physics:-Dgamma[mu], P[m], Physics:-Psigma[mu], X[mu], Physics:-d_[mu], Physics:-g_[mu, nu], Physics:-gamma_[a, b], Physics:-KroneckerDelta[mu, nu], Physics:-LeviCivita[alph... (27)

Introduce now the Commutator, this time in active form, to show how to reobtain the non-expanded form at the end by resorting the operands in products

> `*`(Commutator(X[m], P[n]), `*`(Ket(psi, x, y, z)))
Typesetting:-mrow(Typesetting:-mi( (28)

Expand first (not necessary) to see how the operator P[n] is going to be applied

> Physics:-`*`(Physics:-Commutator(Physics:-SpaceTimeVector[m](X), P[n]), Physics:-Ket(psi, x, y, z)) = expand(Physics:-`*`(Physics:-Commutator(Physics:-SpaceTimeVector[m](X), P[n]), Physics:-Ket(psi, x...
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (29)

Now expand and directly apply in one ago the differential operator P[n];

> Physics:-`*`(Physics:-Commutator(Physics:-SpaceTimeVector[m](X), P[n]), Physics:-Ket(psi, x, y, z)) = Library:-ApplyProductsOfDifferentialOperators(Physics:-`*`(Physics:-Commutator(Physics:-SpaceTimeV...

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (30)

Introducing the explicit differential operator representation for P[n], here again using the inert %d_[n] to keep control of the computations step by step

> P[n] := proc (f) options operator, arrow; `+`(`-`(`*`(`+`(I), `*`(`ℏ`, `*`(%d_[n](f)))))) end proc
Typesetting:-mprintslash([P[n] := proc (f) options operator, arrow; `+`(`-`(Physics:-`*`(I, `ℏ`, %d_[n](f)))) end proc], [proc (f) options operator, arrow; `+`(`-`(Physics:-`*`(I, `ℏ`, %d_[n... (31)

The expanded and applied commutator (30) becomes

> Physics:-`*`(Physics:-Commutator(Physics:-SpaceTimeVector[m](X), P[n]), Physics:-Ket(psi, x, y, z)) = `+`(Physics:-`*`(Physics:-SpaceTimeVector[m](X), P[n](Physics:-Ket(psi, x, y, z))), `-`(P[n](Physi...
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (32)

Activate now the inert operators %d_[n] and simplify taking into account Einstein's rule for repeated indices

> Simplify(value(Physics:-`*`(Physics:-Commutator(Physics:-SpaceTimeVector[m](X), P[n]), Physics:-Ket(psi, x, y, z)) = `+`(`-`(`*`(`+`(I), `*`(`ℏ`, `*`(Physics:-`*`(Physics:-SpaceTimeVector[m](X), ...
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (33)

Since the ket Ket(psi, x, y, z) is arbitrary, we can take coefficients (or multiply by the formal Inverse of this ket as done in the previous section). For illustration purposes, we use  Coefficients and note how it automatically expands the commutator

> Coefficients(Physics:-`*`(Physics:-Commutator(Physics:-SpaceTimeVector[m](X), P[n]), Physics:-Ket(psi, x, y, z)) = `*`(I, `*`(`ℏ`, `*`(Physics:-g_[m, n], `*`(Physics:-Ket(psi, x, y, z))))), Ket(p...
Typesetting:-mprintslash([`+`(Physics:-`*`(X[m], P[n]), `-`(Physics:-`*`(P[n], X[m]))) = `*`(I, `*`(`ℏ`, `*`(Physics:-g_[m, n])))], [`+`(Physics:-`*`(Physics:-SpaceTimeVector[m](X), P[n]), `-`(Ph... (34)

One can undo this (frequently undesired) expansion of the commutator by sorting the products on the left-hand side using the commutator between X[m] and P[n]

> Library:-SortProducts(`+`(Physics:-`*`(Physics:-SpaceTimeVector[m](X), P[n]), `-`(Physics:-`*`(P[n], Physics:-SpaceTimeVector[m](X)))) = `*`(I, `*`(`ℏ`, `*`(Physics:-g_[m, n]))), [P[n], X[m]], us...
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (35)

And that is the result we wanted to compute.


Additionally, to see this rule in matrix form,

> TensorArray(`+`(`-`(Physics:-Commutator(Physics:-SpaceTimeVector[m](X), P[n]) = `*`(I, `*`(`ℏ`, `*`(Physics:-g_[m, n]))))))
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (36)

In the above, we use equation (30) multiplied by -1 to avoid a minus sign in all the elements of (36), due to having worked with the default signature (- - - +); this minus sign is not necessary if in the Setup at the beginning one also sets  signature = `+ + + -` 


For display purposes, to see this matrix expressed in terms of the geometrical components of the momentum `#mover(mi( , redefine the tensor P[n] explicitly indicating its Cartesian component

> Define(P[m] = [p__x, p__y, p__z], quiet)
Typesetting:-mprintslash([{Physics:-Dgamma[mu], P[m], Physics:-Psigma[mu], X[mu], Physics:-d_[mu], Physics:-g_[mu, nu], Physics:-gamma_[a, b], Physics:-KroneckerDelta[mu, nu], Physics:-LeviCivita[alph... (37)
> TensorArray(`+`(`-`(Physics:-Commutator(Physics:-SpaceTimeVector[m](X), P[n]) = `*`(I, `*`(`ℏ`, `*`(Physics:-g_[m, n]))))))
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (38)

Finally, in a typical situation, these commutation rules are to be taken into account in further computations, and for that purpose they can be added to the setup via

>
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi(
(39)

For example, from herein computations are performed taking into account that

> (%Commutator = Commutator)(x, p__x)
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (40)

Automatic setting of the EnergyMomentumTensor for metrics of the database of solutions to Einstein's equations

There are 991 metrics in the database of solutions to Einstein's equations, based on the book "Exact solutions to Einstein's equations". One can check this number via

> nops(DifferentialGeometry:-Library:-Retrieve(
991 (41)

For the majority of these solutions, the book also presents, explicit or implicitly, the form of the Energy-Momentum tensor. New in Maple 2018, we added to the database one more entry indicating the components of the corresponding EnergyMomentum tensor, covering, in Maple 2018.0, 686 out of these 991 solutions.

The design of the EnergyMomentum tensor got slightly adjusted to take these new database entries into account, so that when you load one of these solutions, if the corresponding entry for the EnergyMomentumTensor is already in the database, it is automatically loaded together with the solution.

In addition, it is now possible to define the tensor components using the Define command, or redefine any of its components using the new Library:-RedefineTensorComponent routine.


Examples

> restart; 1; with(Physics); -1

Consider the metric of Chapter 12, equation number 16.1

> g_[[12, 18, 1]]



`*`(`Systems of spacetime Coordinates are: `, `*`({X = (tau, r, theta, phi)}))
`*`(`Default differentiation variables for d_, D_ and dAlembertian are: `, `*`({X = (tau, r, theta, phi)}))
`The Bertotti (1959), Kramer (1978), Levi-Civita (1917), Robinson (1959) metric in coordinates `[tau, r, theta, phi]
`Parameters: `[k, kappa0, beta]
`Resetting the signature of spacetime from
Typesetting:-mrow(Typesetting:-msub(Typesetting:-mrow(Typesetting:-mi( (42)

New, the covariant components of the EnergyMomentum tensor got automatically loaded, given by

> EnergyMomentum[]
Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi( (43)

One can verify this checking for the tensor's definition

> EnergyMomentum[definition]

Typesetting:-mprintslash([Physics:-EnergyMomentum[mu, nu] = `+`(`/`(`*`(`/`(1, 8), `*`(Physics:-Einstein[mu, nu])), `*`(Pi))), Physics:-EnergyMomentum[`~mu`, `~nu`] = (Matrix(4, 4, {(1, 1) = Typesetti... (44)

Take now the tensor components of the first defining equation of (44)

>
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mfrac(Typesetting:-mn( (45)

where kappa0 = `+`(`*`(8, `*`(Pi))) is related to Newton’s constant.


To see the continuity equations for the components of Tau[mu, nu], use for instance the inert version of the covariant derivative operator D_ and the TensorArray command

> (%D_[mu] = D_[mu])(EnergyMomentum[mu, nu])
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi( (46)
> TensorArray(%D_[mu](Physics:-EnergyMomentum[`~mu`, nu]) = 0)

Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi( (47)

>

Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mn( (48)

The EnergyMomentum tensor can also be (re)defined in any particular way (a correct definition must satisfy `▿`[mu](Tau[`~mu`, nu]) = 0).

Example:

Define the EnergyMomentum tensor indicating the functionality in the definition in terms of W to be constant energy (i.e. no functionality) and the flux density S[mu] and stress sigma[mu, nu] tensors depending on For this purpose, use the new option minimizetensorcomponents to make explicit the symmetry of the stress tensor sigma[mu, nu] 

> Define(S[mu], sigma[mu, nu], symmetric, minimizetensorcomponents)
`Defined objects with tensor properties`
Typesetting:-mprintslash([{Physics:-D_[mu], Physics:-Dgamma[mu], Physics:-Psigma[mu], Physics:-Ricci[mu, nu], Physics:-Riemann[mu, nu, alpha, beta], S[mu], Physics:-Weyl[mu, nu, alpha, beta], X[mu], P... (49)

The symmetry of sigma[mu, nu] is now explicit in that its matrix form is symmetric

> sigma[]
Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(, italic = (50)

The new routines for testing tensor symmetries

> Library:-IsTensorialSymmetric(sigma[mu, nu])
true (51)

The symmetry is regarding interchanging positions of the 1st and 2nd indices

> Library:-GetTensorSymmetryProperties(sigma)
{[1, 2]}, {} (52)

So this is the form of the EnergyMomentum with all its components - but for the total energy - depending on the coordinates

> EnergyMomentum[mu, nu] = Matrix(4, proc (mu, nu) options operator, arrow; if mu = 4 then if nu = 4 then W else S[nu](X) end if elif nu = 4 then S[mu](X) else sigma[mu, nu](X) end if end proc)

Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi( (53)

>

`*`(` S`(X), `*`(`will now be displayed as`, `*`(S)))
`*`(` sigma`(X), `*`(`will now be displayed as`, `*`(sigma))) (54)

Define now Tau[mu, nu] with these components

>
`Defined objects with tensor properties`
Typesetting:-mprintslash([{Physics:-D_[mu], Physics:-Dgamma[mu], Physics:-Psigma[mu], Physics:-Ricci[mu, nu], Physics:-Riemann[mu, nu, alpha, beta], S[mu], Physics:-Weyl[mu, nu, alpha, beta], X[mu], P... (55)
> EnergyMomentum[]
Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi( (56)

To see the continuity equations for the components of Tau[mu, nu], use again the inert version of the covariant derivative operator D_ and the TensorArray command

> (%D_[mu] = D_[mu])(EnergyMomentum[mu, nu])
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi( (57)

For a more convenient reading, present the result as a vector column

> Vector[column](TensorArray(%D_[mu](Physics:-EnergyMomentum[`~mu`, nu]) = 0))

Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi( (58)

Comparing the specific form (43) for the EnergyMomentum loaded from the database of solutions to Einstein's equations with the general form (56), one can ask the formal question of whether there are other forms for the EnergyMomentum satisfying  the continuity equations (58).

To answer that question, rewrite this system of equations for the flux density S[mu] and stress sigma[mu, nu] tensors as a set, and solve it for them

>

Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mo(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mo(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mo(
(59)

This system in fact admits much more general solutions than (43):

> pdsolve({`+`(`-`(`/`(`*`(`^`(r, 2), `*`(diff(S[1](X), tau))), `*`(`^`(k, 2)))), `/`(`*`(`+`(`*`(2, `*`(r, `*`(S[2](X)))), `*`(`^`(r, 2), `*`(diff(S[2](X), r))))), `*`(`^`(k, 2))), `/`(`*`(diff(S[3](X)...

Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi(
(60)

This solution can be verified in different ways, for instance using pdetest showing it cancels the PDE system (59) for S[mu] and stress sigma[mu, nu]

> pdetest({S[1](X) = S[1](X), S[2](X) = S[2](X), S[3](X) = `/`(`*`(`+`(Int(`+`(`*`(`^`(r, 2), `*`(diff(S[1](X), tau), `*`(sin(theta)))), `-`(`*`(sin(theta), `*`(diff(S[2](X), r), `*`(`^`(r, 2)))))), the...
{0} (61)

Minimize the number of tensor components according to its symmetries, and relabel, redefine or count the number of independent tensor components

A new keyword in Define and Setup: minimizetensorcomponents, allows for automatically minimizing the number of tensor components taking into account the tensor symmetries. For example, if a 2-tensor in a 4D spacetime is defined a antisymmetric, the number of different tensor components is 6, and the elements of the diagonal are automatically set equal to 0. After setting this keyword to true with Setup, all subsequent definitions of tensors automatically minimize the number of components while using this keyword with Define makes this minimization only happen with the tensors being defined in the call to Define.

Related to this new functionality, 4 new Library routines were added: MinimizeTensorComponents, NumberOfIndependentTensorComponents, RelabelTensorComponents and RedefineTensorComponents


Example:

> restart; 1; with(Physics); -1

Define an antisymmetric tensor with two indices


> Define(F[mu, nu], antisymmetric)
`Defined objects with tensor properties`
{Physics:-Dgamma[mu], F[mu, nu], Physics:-Psigma[mu], Physics:-d_[mu], Physics:-g_[mu, nu], Physics:-KroneckerDelta[mu, nu], Physics:-LeviCivita[alpha, beta, mu, nu]} (62)

Although the system knows that F[mu, nu] is antisymmetric,

> `+`(F[mu, nu], F[nu, mu])
`+`(F[mu, nu], F[nu, mu]) (63)
> Simplify(`+`(F[mu, nu], F[nu, mu]))
0 (64)

by default the compotes of F[mu, nu] do not automatically reflect that, it is necessary to use the simplifier of the Physics package, Simplify.

> `+`(F[1, 2], F[2, 1])
`+`(F[1, 2], F[2, 1]) (65)
> Simplify(`+`(F[1, 2], F[2, 1]))
0 (66)

Likewise, computing the array form of F[mu, nu] we do not see the elements of the diagonal equal to nor the lower-left triangle equal to the upper-right triangle but with a different sign:

> TensorArray(F[mu, nu])
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-msub(Typesetting:-mi( (67)

This new functionality, here called minimizetensorcomponents, makes the symmetries of the tensor explicitly reflected in its components. There are three ways to use it. First, one can minimize the number of tensor components of a tensor previously defined. For example

> Library:-MinimizeTensorComponents(F)
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mn( (68)

After this, both `+`(F[mu, nu], F[nu, mu]) and Simplify(`+`(F[mu, nu], F[nu, mu])) are automatically equal to 0 without having to use Simplify

> `+`(F[mu, nu], F[nu, mu])
0 (69)
> 0
0 (70)

And the output of TensorArray in TensorArray(F[mu, nu]) becomes equal to Library:-MinimizeTensorComponents(F).

NOTE: after using minimizetensorcomponents in the definition of a tensor, say F, all the keywords implemented for Physics tensors are available for the F:

> F[]
Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi( (71)
> F[trace]
0 (72)
> F[nonzero]
F[mu, nu] = {(1, 2) = F[1, 2], (1, 3) = F[1, 3], (1, 4) = F[1, 4], (2, 1) = `+`(`-`(F[1, 2])), (2, 3) = F[2, 3], (2, 4) = F[2, 4], (3, 1) = `+`(`-`(F[1, 3])), (3, 2) = `+`(`-`(F[2, 3])), (3, 4) = F[3,...
F[mu, nu] = {(1, 2) = F[1, 2], (1, 3) = F[1, 3], (1, 4) = F[1, 4], (2, 1) = `+`(`-`(F[1, 2])), (2, 3) = F[2, 3], (2, 4) = F[2, 4], (3, 1) = `+`(`-`(F[1, 3])), (3, 2) = `+`(`-`(F[2, 3])), (3, 4) = F[3,...
(73)
> F[`~1`, mu, matrix]
Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi( (74)

Alternatively, one can define a tensor, specifying that the symmetries should be taken into account to minimize the number of its components passing the keyword minimizetensorcomponents to Define.


Example:

Define a tensor with the symmetries of the Riemann tensor, that is, a tensor of 4 indices that is symmetric with respect to interchanging the positions of the 1st and 2nd pair of indices and antisymmetric with respect to interchanging the position of its 1st and 2nd indices, or 3rd and 4th indices, and minimizing the number of tensor components

> Define(R[alpha, beta, mu, nu], symmetric = {[[1, 2], [3, 4]]}, antisymmetric = {[1, 2], [3, 4]}, minimizetensorcomponents)
`Defined objects with tensor properties`
{Physics:-Dgamma[mu], F[mu, nu], Physics:-Psigma[mu], R[mu, nu, alpha, beta], Physics:-d_[mu], Physics:-g_[mu, nu], Physics:-KroneckerDelta[mu, nu], Physics:-LeviCivita[alpha, beta, mu, nu]} (75)
> `+`(R[1, 2, 3, 4], R[2, 1, 3, 4])
0 (76)
> `+`(R[alpha, beta, mu, nu], `-`(R[mu, nu, alpha, beta]))
0 (77)

One can always retrieve the symmetry properties in the abstract notation used by the Define command using the new Library:-GetTensorSymmetryProperties, its output is ordered, first the symmetric then the antisymmetric properties

> Library:-GetTensorSymmetryProperties(R)
{[[1, 2], [3, 4]]}, {[1, 2], [3, 4]} (78)

After making the symmetries explicit (and also before that), it frequently s useful to know the number of independent components of a given tensor. For this purpose use the new Library:-NumberOfIndependentTensorComponents

> Library:-NumberOfIndependentTensorComponents(R)
21 (79)

and besides the symmetries, in the case of the Riemann tensor after taking into account the first Bianchi identity, this number of components is further reduced to 20.


A third way of using the new minimizetensorcomponents functionality is using Setup, so that every subsequent definition of tensors with symmetries is automatically performed minimizing the number of components.


Example:

> Setup(minimizetensorcomponents = true)
[minimizetensorcomponents = true] (80)

You can now define without having to include the keyword minimizetensorcomponents in the definition of tensors with symmetries

> Define(C[alpha, beta], antisymmetric)
`Defined objects with tensor properties`
{C[mu, nu], Physics:-Dgamma[mu], F[mu, nu], Physics:-Psigma[mu], R[mu, nu, alpha, beta], Physics:-d_[mu], Physics:-g_[mu, nu], Physics:-KroneckerDelta[mu, nu], Physics:-LeviCivita[alpha, beta, mu, nu]... (81)

> C[]
Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi( (82)

  • Two new related functionalities are provided via Library:-RelabelTensorComponents and Library:-RedefineTensorComponent, the first one to have the number of tensor components directly reflected in the names of the components, the second one to redefine only one of these components
> Library:-RelabelTensorComponents(C)
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mn( (83)

Suppose now we want to make one of these components equal to 1, say C__2

> Library:-RedefineTensorComponent(C[1, 2] = 1)
Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi( (84)

New functionality and display for inert names and inert tensors


New: as part of the developments of Physics bug regardless of loading the Physics package, inert names are now typeset in gray, the standard for inert functions, with copy & paste working

> restart; 1
> %x
Typesetting:-mi( (85)
> `+`(`*`(2, `*`(%x)))
`+`(`*`(2, `*`(%x))) (86)

Note that this was already in place in previous releases regarding inert functions but not regarding inert names. Regarding inert functions, since Maple 2016 their typesetting is also in grey with copy & paste working

> %f(x)
Typesetting:-mrow(Typesetting:-mi( (87)

Regarding Physics, having the right typeset also for symbols and tensor names is particularly relevant now that one can compute  with differential operators as operands of a product


Example:

> with(Physics); -1; with(Vectors); -1
> Setup(op = {p_, x, y, z}, differentialoperators = [[p_, [x, y, z]]])
`* Partial match of  'op' against keyword 'quantumoperators'`
[differentialoperators = {[p_, [x, y, z]]}, quantumoperators = {p_, x, y, z}] (88)

The active and inert representations of the same differential-vectorial operator are

> p_ = %p_
p_ = %p_ (89)

Hence, you can:

a) assign a mapping to p_ while represent it using %p_ when you do not want the mapping to be applied.

b) using %p_ has mathematical and clear typesetting (in gray always means inert) making its use more pleasant / easy to read.


Example:

> interface(imaginaryunit = i); -1

Assign a procedure to the differential-vectorial operator `#mover(mi(

> p_ := proc (f) options operator, arrow; `+`(`-`(`*`(`+`(I), `*`(`ℏ`, `*`(%Nabla(f)))))) end proc
Typesetting:-mprintslash([p_ := proc (f) options operator, arrow; `+`(`-`(Physics:-`*`(Physics:-`*`(I, `ℏ`), %Nabla(f)))) end proc], [proc (f) options operator, arrow; `+`(`-`(Physics:-`*`(Physic... (90)

Apply both the active and the inert operators to some function of the coordinates

> `*`(f(x, y, z), `*`(%p_)) = `*`(f(x, y, z), `*`(p_))
Typesetting:-mprintslash([Physics:-`*`(%p_, f(x, y, z)) = Physics:-`*`(p_, f(x, y, z))], [Physics:-`*`(%p_, f(x, y, z)) = Physics:-`*`(p_, f(x, y, z))]) (91)

Apply now the differential operators in products: the left-hand side, inert, remains a product, while the right-hand side, becomes a function application, and so p_ := proc (f) options operator, arrow; `+`(`-`(`*`(`+`(I), `*`(`ℏ`, `*`(%Nabla(f)))))) end proc gets applied

> Library:-ApplyProductsOfDifferentialOperators(Physics:-`*`(%p_, f(x, y, z)) = Physics:-`*`(p_, f(x, y, z)))
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (92)

NOTE: the implementation is such that if p is noncommutative, then so is %p and the same holds regarding their possibly differential operator and tensorial character: the inert versions inherit the properties of their active counterparts, and the same regarding their tensorial character: if p is a tensor, so is %p. In addition, inert tensors are also now displayed the same way as their active versions but in gray, improving the readability of tensorial expressions


Example:

Load a curved spacetime, for instance Schwarzschild's metric

> g_[sc]
`*`(`Systems of spacetime Coordinates are: `, `*`({X = (r, theta, phi, t)}))
`*`(`Default differentiation variables for d_, D_ and dAlembertian are: `, `*`({X = (r, theta, phi, t)}))
`The Schwarzschild metric in coordinates `[r, theta, phi, t]
`Parameters: `[m]
Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi( (93)

Define a tensor and compute its covariant derivative equating the inert with the active form of it

> Define(A[mu])
`Defined objects with tensor properties`
Typesetting:-mprintslash([{A[mu], Physics:-D_[mu], Physics:-Dgamma[mu], Physics:-Psigma[mu], Physics:-Ricci[mu, nu], Physics:-Riemann[mu, nu, alpha, beta], Physics:-Weyl[mu, nu, alpha, beta], X[mu], P... (94)
> CompactDisplay(A(X))
`*`(` A`(X), `*`(`will now be displayed as`, `*`(A))) (95)

Since A[mu] is a tensor, so is `*`(%, `*`(A[mu])), and the latter is typeset as the former, only in gray, with copy & paste working, reproducing `*`(%, `*`(A[mu]))

> A[`~mu`] = %A[`~mu`]
A[`~mu`] = %A[`~mu`] (96)
> map(type, A[`~mu`] = %A[`~mu`], Library:-PhysicsType:-Tensor)
true = true (97)

Also new, the same holds for the typesetting of inert differential operators, the inert display of the covariant derivative symbol is now the same as the active one only in gray.

> (%D_[mu] = D_[mu])(A[nu](X))
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi( (98)

Expand the right-hand side and replace the active Christoffel by its inert counterpart %Christoffel

> (lhs = `@`(expand, rhs))(%D_[mu](A[nu](X)) = Physics:-D_[mu](A[nu](X), [X]))
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi( (99)
> subs(Christoffel = %Christoffel, %D_[mu](A[nu](X)) = `+`(Physics:-d_[mu](A[nu](X), [X]), `-`(`*`(Physics:-Christoffel[`~alpha`, mu, nu], `*`(A[alpha](X))))))
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi( (100)

Compute the components of the left and right hand sides of this tensorial equation, it is a 2x2 matrix of equations; check one of these components: the readability of the inert symbols entering the equation is now straightforward due to the typesetting of inert tensors

> T := TensorArray(%D_[mu](A[nu](X)) = `+`(Physics:-d_[mu](A[nu](X), [X]), `-`(`*`(%Christoffel[`~alpha`, mu, nu], `*`(A[alpha](X))))), simplifier = simplify); -1
> T[4, 4]
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-msub(Typesetting:-mi( (101)

These expression are not just typeset but true inert representations of the underlying computations. To transform them into active, use value

> value(`+`(%d_[4](A[4](X), [X]), `/`(`*`(`+`(`-`(r), `*`(2, `*`(m))), `*`(m, `*`(A[1](X)))), `*`(`^`(r, 3)))) = `+`(diff(A[4](X), t), `-`(`*`(%Christoffel[`~1`, 4, 4], `*`(A[1](X)))), `-`(`*`(%Christof...
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (102)

Automatic setting of Pauli, Dirac and Gell-Mann algebras

New in Maple 2018, the algebra rules for the Dirac, Pauli and Gell-Mann matrices are automatically set when Physics is loaded. This means expressions can be simplified taking into account these algebra rules, which can also be queried using a new Library:-DefaultAlgebraRules routine that returns the algebras in terms of generic lowercase Latin indices

> restart; -1; with(Physics); -1

The algebra rules for all of the Pauli, Dirac and Gell-Mann matrices, in a 4D spacetime, are given according to the value of the signature by

> for algebra in Library:-DefaultAlgebraRules() do algebra end do; 1
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi(
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi(
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi(
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (103)

Simplification of products of Dirac matrices work automatically taking the corresponding (3rd) algebra rule into account; for example (see also next section)

> `*`(`^`(Dgamma[mu], 2), `*`(Dgamma[`~lambda`], `*`(Dgamma[`~nu`], `*`(Dgamma[`~rho`]))))

Typesetting:-mprintslash([Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~rho`], Physics:-Dgamma[`~mu`])], [Physics:-`*`(Physics:-Dgamma[mu], Ph... (104)

> Simplify(Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~rho`], Physics:-Dgamma[`~mu`]))

Typesetting:-mprintslash([`+`(`-`(`*`(2, `*`(Physics:-`*`(Physics:-Dgamma[`~rho`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~lambda`])))))], [`+`(`-`(`*`(2, `*`(Physics:-`*`(Physics:-Dgamma[`~rho`], P... (105)

> `*`(`^`(Dgamma[mu], 2), `*`(Dgamma[`~lambda`], `*`(Dgamma[`~nu`], `*`(Dgamma[`~rho`], `*`(Dgamma[`~sigma`])))))

Typesetting:-mprintslash([Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~rho`], Physics:-Dgamma[`~sigma`], Physics:-Dgamma[`~mu`])], [Physics:-... (106)

> Simplify(Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~rho`], Physics:-Dgamma[`~sigma`], Physics:-Dgamma[`~mu`]))

Typesetting:-mprintslash([`+`(`*`(2, `*`(Physics:-`*`(Physics:-Dgamma[`~sigma`], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~rho`]))), `*`(2, `*`(Physics:-`*`(Physics:-Dgamma... (107)

The convention for gamma[5] follows the  Landau, Bogoliubov and Tong books on quantum fields, so for the default signature

> Setup(signature)

[signature = `- - - +`] (108)

using the new Library:-Dgamma5ToOtherDgamma routine, we have

> Dgamma[`~5`] = Library:-Dgamma5ToOtherDgamma()

Typesetting:-mprintslash([Physics:-Dgamma[`~5`] = `+`(`-`(`*`(`+`(I), `*`(Physics:-`*`(Physics:-Dgamma[`~4`], Physics:-Dgamma[`~1`], Physics:-Dgamma[`~2`], Physics:-Dgamma[`~3`])))))], [Physics:-Dgamm... (109)

This new Library:-Dgamma5ToOtherDgamma routine takes into account  the possibly Euclidean character of spacetime, also the possible values of the signature: (- - - +), (+ - - -), (+ + + -) and (- + + +), and uses formulas valid for the three representations: standard, chiral and majorana.


The algebra rules now automatically loaded when Physics is loaded can always overwritten. For instance, to represent the algebra of Dirac matrices with an identity matrix on the right-hand side, one can proceed as follows.


First create the identity matrix. To emulate what we do with paper and pencil, where we write to represent an identity matrix without having to see the actual table 2x2 with the number 1 in the diagonal and a bunch of 0, I will use the matrix command, not the Matrix one. One way of entering this identity matrix is

> `𝕀` := matrix(4, 4, proc (i, j) options operator, arrow; KroneckerDelta[i, j] end proc)

Typesetting:-mprintslash([`𝕀` := matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])], [array( 1 .. 4, 1 .. 4, [( 1, 4 ) = (0), ( 2, 3 ) = (0), ( 4, 1 ) = (0), ( 2, 4 ) = (0), ( 3, 3... (110)

Depending on the context, the advantage of matrix versus Matrix is that is also of type algebraic

> type(`𝕀`, algebraic)

true (111)

Consequently, one can operate with it algebraically without displaying its contents (not possible with Matrix) 

> `𝕀`

`𝕀` (112)

Most commands of the library only work with objects of type algebraic, all these will be able to handle this matrix, and the contents is displayed only on demand, for instance using eval

> eval(`𝕀`)

Typesetting:-mprintslash([matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]])], [array( 1 .. 4, 1 .. 4, [( 1, 4 ) = (0), ( 2, 3 ) = (0), ( 4, 1 ) = (0), ( 2, 4 ) = (0), ( 3, 3 ) = (1), ( ... (113)

Set now the algebra for Dirac matrices with an matrix on the right-hand side

> %AntiCommutator(Dgamma[mu], Dgamma[nu]) = `+`(`*`(2, `*`(g_[mu, nu], `*`(`𝕀`))))

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (114)

> Setup(algebrarules = (%AntiCommutator(Physics:-Dgamma[mu], Physics:-Dgamma[nu]) = `+`(`*`(2, `*`(Physics:-g_[mu, nu], `*`(`𝕀`))))))

Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (115)

Verifying

> (%AntiCommutator = AntiCommutator)(Dgamma[mu], Dgamma[nu])

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (116)

Set now a Dirac spinor (in a week from today, this will be possible directly using Physics:-Setup, but today, here, I do it step-by-step)


For that you can also use {vector, matrix, array} or {Vector, Matrix, Array}, and again, if you use the Upper case commands, you always have the components visible, and cannot compute with these object using commands that require the input to be of type algebraic. So I use matrix, not Matrix, and matrix instead of vector so that the Dirac spinor that is both algebraic and matrix, is also displayed in the usual display as a "column vector"

To reuse the letter Psi which in Maple represents the Psi function, use a local version of it

> _local(Psi)

> Setup(anticommutativeprefix = {Psi, psi})

[anticommutativeprefix = {_lambda, psi, :-Psi}] (117)

Specify the components of the spinor, in any preferred way, for example using psi[j]

> Psi := matrix(4, 1, [psi[1], psi[2], psi[3], psi[4]])

Typesetting:-mprintslash([Psi := matrix([[psi[1]], [psi[2]], [psi[3]], [psi[4]]])], [array( 1 .. 4, 1 .. 1, [( 4, 1 ) = (psi[4]), ( 2, 1 ) = (psi[2]), ( 1, 1 ) = (psi[1]), ( 3, 1 ) = (psi[3])  ] )]) (118)

Check it out:

> Psi

Psi (119)

> type(Psi, algebraic); 1

true (120)

Let’s see all this working together by multiplying the anticommutator equation by Psi

> `*`(Psi, `*`(%AntiCommutator(Physics:-Dgamma[mu], Physics:-Dgamma[nu]))) = `+`(`*`(2, `*`(Psi, `*`(Physics:-g_[mu, nu], `*`(`𝕀`)))))

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (121)

To see the matrix form of this equation use the new Library:-RewriteInMatrixForm routine

> Library:-RewriteInMatrixForm(Physics:-`*`(%AntiCommutator(Physics:-Dgamma[mu], Physics:-Dgamma[nu]), Psi) = `+`(`*`(2, `*`(Physics:-g_[mu, nu], `*`(Physics:-`*`(`𝕀`, Psi))))))

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (122)

Or directly rewrite, then perform, in one go, the matrix operations behind (121)

> Library:-PerformMatrixOperations(Physics:-`*`(%AntiCommutator(Physics:-Dgamma[mu], Physics:-Dgamma[nu]), Psi) = `+`(`*`(2, `*`(Physics:-g_[mu, nu], `*`(Physics:-`*`(`𝕀`, Psi))))))

Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (123)

REMARK: As shown above, in general, the representation using lowercase commands allows you to use `*` or `.` depending on whether you want to represent the operation or perform the operation. For example this represents the operation, as an exact mimicry of what we do with paper and pencil, both regarding input and output

> `*`(`𝕀`, `*`(Psi))

Typesetting:-mprintslash([Physics:-`*`(`𝕀`, Psi)], [Physics:-`*`(`𝕀`, Psi)]) (124)

And this performs the operation

> Typesetting:-delayDotProduct(`𝕀`, Psi)

Typesetting:-mprintslash([matrix([[psi[1]], [psi[2]], [psi[3]], [psi[4]]])], [array( 1 .. 4, 1 .. 1, [( 4, 1 ) = (psi[4]), ( 2, 1 ) = (psi[2]), ( 1, 1 ) = (psi[1]), ( 3, 1 ) = (psi[3])  ] )]) (125)

Or to only displaying the operation

> Library:-RewriteInMatrixForm(Physics:-`*`(`𝕀`, Psi))

Typesetting:-mprintslash([Physics:-`.`(matrix([[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]), matrix([[psi[1]], [psi[2]], [psi[3]], [psi[4]]]))], [Physics:-`.`(array( 1 .. 4, 1 .. 4, [( 1, ... (126)

Finally, another way to visualize the equations behind (121) is

> TensorArray(Physics:-`*`(%AntiCommutator(Physics:-Dgamma[mu], Physics:-Dgamma[nu]), Psi) = `+`(`*`(2, `*`(Physics:-g_[mu, nu], `*`(Physics:-`*`(`𝕀`, Psi))))))

Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (127)

Or additionally performing the matrix operations of each of the equations in (127) using the new option performmatrixoperations of TensorArray

> TensorArray(Physics:-`*`(%AntiCommutator(Physics:-Dgamma[mu], Physics:-Dgamma[nu]), Psi) = `+`(`*`(2, `*`(Physics:-g_[mu, nu], `*`(Physics:-`*`(`𝕀`, Psi))))), performmatrixoperations, simplifier ...

Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mfenced(Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetti... (128)

Simplification of products of Dirac matrices

The computation of traces of products of Dirac matrices was implemented years ago - see Physics,Trace.

The simplification of products of Dirac matrices, however, was not. Now in Maple 2018 it is.

> restart; 1

> with(Physics); -1

First of all, when loading Physics, a frequent question is about the signature, the default is (- - - +) 

> Setup(signature)

[signature = `- - - +`] (129)

This is important because the convention for the Algebra of Dirac Matrices depends on the signature. With the signatures (- - - +) as well as (+ - - -), the sign of the timelike component is 1

> Library:-SignOfTimelikeComponent()

1 (130)

With the signatures (+ + + -) as well as (- + + +), the sign of the timelike component is -1

> Library:-SignOfTimelikeComponent(`+ + + -`)

-1 (131)

The simplification of products of Dirac Matrices, illustrated below with the default signature, works fine with any of these signatures, and works without having to set a representation for the Dirac matrices -- all the results are representation-independent.

Consider now the following five products of Dirac matrices

> e0 := `*`(`^`(Dgamma[mu], 2))

Typesetting:-mprintslash([e0 := Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~mu`])], [Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~mu`])]) (132)

> e1 := `*`(`^`(Dgamma[mu], 2), `*`(Dgamma[`~nu`]))

Typesetting:-mprintslash([e1 := Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~mu`])], [Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~mu`])]) (133)

> e2 := `*`(`^`(Dgamma[mu], 2), `*`(Dgamma[`~lambda`], `*`(Dgamma[`~nu`])))

Typesetting:-mprintslash([e2 := Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~mu`])], [Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lam... (134)

> e3 := `*`(`^`(Dgamma[mu], 2), `*`(Dgamma[`~lambda`], `*`(Dgamma[`~nu`], `*`(Dgamma[`~rho`]))))

Typesetting:-mprintslash([e3 := Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~rho`], Physics:-Dgamma[`~mu`])], [Physics:-`*`(Physics:-Dgamma[m... (135)

> e4 := `*`(`^`(Dgamma[mu], 2), `*`(Dgamma[`~lambda`], `*`(Dgamma[`~nu`], `*`(Dgamma[`~rho`], `*`(Dgamma[`~sigma`])))))

Typesetting:-mprintslash([e4 := Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~rho`], Physics:-Dgamma[`~sigma`], Physics:-Dgamma[`~mu`])], [Phy... (136)

New: the simplification of these products is now implemented

> e0 = Simplify(e0)
Typesetting:-mprintslash([Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~mu`]) = 4], [Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~mu`]) = 4]) (137)

Verify this result performing the underlying matrix operations

> T := SumOverRepeatedIndices(Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~mu`]) = 4)
Typesetting:-mprintslash([T := `+`(Physics:-`*`(Physics:-Dgamma[1], Physics:-Dgamma[`~1`]), Physics:-`*`(Physics:-Dgamma[2], Physics:-Dgamma[`~2`]), Physics:-`*`(Physics:-Dgamma[3], Physics:-Dgamma[`~... (138)

Note that in (138) the right-hand side has no matrix elements. This is standard in particle physics where the computations with Dirac matrices are performed algebraically. For the purpose of actually performing the underlying matrix operations, however, one may want to rewrite the algebra of Dirac matrices including a 4x4 identity matrix. For that purpose, see Algebra of Dirac Matrices with an identity matrix on the right-hand side. For the purpose of this illustration, below we proceed with as shown in (138), interpreting right-hand sides as if they involve an identity matrix.

To verify these results checking the components of the matrices involved we set a representation for the Dirac matrices, for example the standard one

> Setup(Dgamma = standard)
`* Partial match of  'Physics:-Dgamma' against keyword 'Dgammarepresentation'`
`Setting lowercaselatin letters to represent spinor indices `
`Defined Dirac gamma matrices (Dgamma) in standard representation`, gamma[1], gamma[2], gamma[3], gamma[4]
__________________________________________________
[Dgammarepresentation = standard] (139)

Verify T := SumOverRepeatedIndices(Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~mu`]) = 4) using the new Library:-PerformMatrixOperations routine

> Library:-PerformMatrixOperations(T)
Typesetting:-mrow(Typesetting:-mfenced(Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mn( (140)

The same with the other expressions

> e1 = Simplify(e1)

Typesetting:-mprintslash([Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~mu`]) = `+`(`-`(`*`(2, `*`(Physics:-Dgamma[`~nu`]))))], [Physics:-`*`(Physics:-Dgamma[mu], Physics... (141)

> SumOverRepeatedIndices(Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~mu`]) = `+`(`-`(`*`(2, `*`(Physics:-Dgamma[`~nu`])))))

Typesetting:-mprintslash([`+`(Physics:-`*`(Physics:-Dgamma[1], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~1`]), Physics:-`*`(Physics:-Dgamma[2], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~2`]), Physics:... (142)

> T := TensorArray(`+`(Physics:-`*`(Physics:-Dgamma[1], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~1`]), Physics:-`*`(Physics:-Dgamma[2], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~2`]), Physics:-`*`(Phys...

Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi(
(143)

> Library:-PerformMatrixOperations(T)

Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mfenced(Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetti... (144)

For e2

> e2 = Simplify(e2)

Typesetting:-mprintslash([Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~mu`]) = `+`(`*`(4, `*`(Physics:-g_[`~lambda`, `~nu`])))], [Physics:-`*... (145)

> SumOverRepeatedIndices(Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~mu`]) = `+`(`*`(4, `*`(Physics:-g_[`~lambda`, `~nu`]))))
Typesetting:-mprintslash([`+`(Physics:-`*`(Physics:-Dgamma[1], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~1`]), Physics:-`*`(Physics:-Dgamma[2], Physics:-Dgamma[`~lambda`], ... (146)

To make the output simpler, use the new option performmatrixoperations of TensorArray, accomplishing two steps in one go

> T := TensorArray(`+`(Physics:-`*`(Physics:-Dgamma[1], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~1`]), Physics:-`*`(Physics:-Dgamma[2], Physics:-Dgamma[`~lambda`], Physics:-...

Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mfenced(Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetti... (147)

For the other two products of Dirac matrices we have

> e3 = Simplify(e3)
Typesetting:-mprintslash([Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~rho`], Physics:-Dgamma[`~mu`]) = `+`(`-`(`*`(2, `*`(Physics:-`*`(Physi... (148)
> e4 = Simplify(e4)
Typesetting:-mprintslash([Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~rho`], Physics:-Dgamma[`~sigma`], Physics:-Dgamma[`~mu`]) = `+`(`*`(2,... (149)

These results can be verified in the same way done for the simplification of e2 and e1, as shown in this page, under Library routines to perform matrix operations in expressions involving spinors with omitted indices 

Finally, let's define some tensors and contract their product with these expressions involving products of Dirac matrices.


Example

> Define(A, B)
`Defined objects with tensor properties`
{A, B, Physics:-Dgamma[mu], Physics:-Psigma[mu], Physics:-d_[mu], Physics:-g_[mu, nu], Physics:-KroneckerDelta[mu, nu], Physics:-LeviCivita[alpha, beta, mu, nu]} (150)

Contract with e1 and e2 and simplify

> `*`(A[nu], `*`(e1)); -1; % = Simplify(%)
Typesetting:-mprintslash([`*`(A[nu], `*`(Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~mu`]))) = `+`(`-`(`*`(2, `*`(A[`~nu`], `*`(Physics:-Dgamma[nu])))))], [`*`(A[nu], `... (151)
> `*`(A[nu], `*`(B[lambda], `*`(e2))); -1; % = Simplify(%)
Typesetting:-mprintslash([`*`(A[nu], `*`(B[lambda], `*`(Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~mu`])))) = `+`(`*`(4, `*`(B[`~nu`], `*`(... (152)

New Library routines to perform matrix operations in expressions involving spinors with omitted indices


New Physics:-Library routines, RewriteInMatrixForm, and PerformMatrixOperations where added, to rewrite or perform the matrix operations implicit in expressions where the spinor indices are omitted. In some sense, the new Library:-PerformMatrixOperations is a Matrix version (or spinor version) of the TensorArray command, which now also has a new option, performmatrixoperations to additionally perform the matrix or spinor operations in expressions

Example:

The computation of traces of products of Dirac matrices was implemented years ago.


The simplification of products of Dirac matrices, however, was not. Now it is.

> with(Physics); -1

Set a representation for the Dirac matrices, say the standard one

> Setup(Dgamma = standard, math = true, quiet)
[Dgammarepresentation = standard, mathematicalnotation = true] (153)

An Array with the four Dirac matrices are

> TensorArray(Dgamma[`~mu`])
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-msub(Typesetting:-mi( (154)

The definition of the Dirac matrices is implemented in Maple following the conventions of Landau books ([1] Quantum Electrodynamics, V4), and does not depend on the signature, i.e. the form of these matrices is, using the new Library:-RewriteInMatrixForm 

>
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-m... (155)

With the default signature (- - - +), the space part components of  gamma[mu] change sign when compared with corresponding ones from gamma[`~mu`] while the timelike component remains unchanged

> TensorArray(Dgamma[mu])
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-msub(Typesetting:-mi( (156)
>
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-m... (157)

With this default signature (- - - +), the algebra of the Dirac Matrices, now loaded by default when Physics is loaded, is (see page 80 of [1])

> (%AntiCommutator = AntiCommutator)(Dgamma[`~mu`], Dgamma[`~nu`])
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (158)

You can also display this algebra, with generic indices j, k,  using the new Library routine for this purpose

> Library:-DefaultAlgebraRules()[3]
Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi( (159)

Verify the algebra rule by performing all the involved matrix operations

> expand(%AntiCommutator(Physics:-Dgamma[`~mu`], Physics:-Dgamma[`~nu`]) = `+`(`*`(2, `*`(Physics:-g_[`~mu`, `~nu`]))))
Typesetting:-mprintslash([`+`(Physics:-`*`(Physics:-Dgamma[`~mu`], Physics:-Dgamma[`~nu`]), Physics:-`*`(Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~mu`])) = `+`(`*`(2, `*`(Physics:-g_[`~mu`, `~nu`])))]... (160)

Note that, regarding the spacetime indices, this is a 4x4 matrix, whose elements are in turn 4x4 matrices. Compute first the external 4x4 matrix related to mu and nu

> TensorArray(`+`(Physics:-`*`(Physics:-Dgamma[`~mu`], Physics:-Dgamma[`~nu`]), Physics:-`*`(Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~mu`])) = `+`(`*`(2, `*`(Physics:-g_[`~mu`, `~nu`]))))
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mn( (161)

Perform now all the matrix operations involved in each of the elements of this 4x4 matrix: you can do this by using the new option performmatrixoperations of TensorArray or using the new Library routine for this purpose

>

Typesetting:-msub(Typesetting:-mi( (162)

By eye everything checks OK. Note as well that in (162) the right-hand sides have no matrix elements. This is standard in particle physics where the computations with Dirac matrices are performed algebraically. For the purpose of actually performing the underlying matrix operations, however, one may want to rewrite this algebra including a 4x4 identity matrix on the right-hand sides. For that purpose, see the MaplePrimes post Algebra of Dirac Matrices with an identity matrix on the right-hand side. For the purpose of this illustration, below we proceed with the algebra as shown in (162), interpreting right-hand sides as if they involve an identity matrix.


Consider now the following five products of Dirac matrices

> e0 := `*`(`^`(Dgamma[mu], 2))
Typesetting:-mprintslash([e0 := Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~mu`])], [Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~mu`])]) (163)

> e1 := `*`(`^`(Dgamma[mu], 2), `*`(Dgamma[`~nu`]))

Typesetting:-mprintslash([e1 := Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~mu`])], [Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~mu`])]) (164)

> e2 := `*`(`^`(Dgamma[mu], 2), `*`(Dgamma[`~lambda`], `*`(Dgamma[`~nu`])))

Typesetting:-mprintslash([e2 := Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~mu`])], [Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lam... (165)

> e3 := `*`(`^`(Dgamma[mu], 2), `*`(Dgamma[`~lambda`], `*`(Dgamma[`~nu`], `*`(Dgamma[`~rho`]))))

Typesetting:-mprintslash([e3 := Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~rho`], Physics:-Dgamma[`~mu`])], [Physics:-`*`(Physics:-Dgamma[m... (166)

> e4 := `*`(`^`(Dgamma[mu], 2), `*`(Dgamma[`~lambda`], `*`(Dgamma[`~nu`], `*`(Dgamma[`~rho`], `*`(Dgamma[`~sigma`])))))

Typesetting:-mprintslash([e4 := Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~rho`], Physics:-Dgamma[`~sigma`], Physics:-Dgamma[`~mu`])], [Phy... (167)

New: the simplification of these products is now implemented

> e0 = Simplify(e0)

Typesetting:-mprintslash([Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~mu`]) = 4], [Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~mu`]) = 4]) (168)

Verify this result performing the underlying matrix operations

> T := SumOverRepeatedIndices(Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~mu`]) = 4)

Typesetting:-mprintslash([T := `+`(Physics:-`*`(Physics:-Dgamma[1], Physics:-Dgamma[`~1`]), Physics:-`*`(Physics:-Dgamma[2], Physics:-Dgamma[`~2`]), Physics:-`*`(Physics:-Dgamma[3], Physics:-Dgamma[`~... (169)

> Library:-PerformMatrixOperations(T)

Typesetting:-mrow(Typesetting:-mfenced(Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mn( (170)

The same with the other expressions

> e1 = Simplify(e1)

Typesetting:-mprintslash([Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~mu`]) = `+`(`-`(`*`(2, `*`(Physics:-Dgamma[`~nu`]))))], [Physics:-`*`(Physics:-Dgamma[mu], Physics... (171)

> SumOverRepeatedIndices(Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~mu`]) = `+`(`-`(`*`(2, `*`(Physics:-Dgamma[`~nu`])))))

Typesetting:-mprintslash([`+`(Physics:-`*`(Physics:-Dgamma[1], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~1`]), Physics:-`*`(Physics:-Dgamma[2], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~2`]), Physics:... (172)

> T := TensorArray(`+`(Physics:-`*`(Physics:-Dgamma[1], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~1`]), Physics:-`*`(Physics:-Dgamma[2], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~2`]), Physics:-`*`(Phys...

Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi(
(173)

> Library:-PerformMatrixOperations(T)

Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mfenced(Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetti... (174)

For e2

> e2 = Simplify(e2)

Typesetting:-mprintslash([Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~mu`]) = `+`(`*`(4, `*`(Physics:-g_[`~lambda`, `~nu`])))], [Physics:-`*... (175)

> SumOverRepeatedIndices(Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~mu`]) = `+`(`*`(4, `*`(Physics:-g_[`~lambda`, `~nu`]))))

Typesetting:-mprintslash([`+`(Physics:-`*`(Physics:-Dgamma[1], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~1`]), Physics:-`*`(Physics:-Dgamma[2], Physics:-Dgamma[`~lambda`], ... (176)

> T := TensorArray(`+`(Physics:-`*`(Physics:-Dgamma[1], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~1`]), Physics:-`*`(Physics:-Dgamma[2], Physics:-Dgamma[`~lambda`], Physics:-...

Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi(
Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mrow(Typesetting:-mi(
(177)

> Library:-PerformMatrixOperations(T)

Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mrow(Typesetting:-mfenced(Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetti... (178)

For e3 we have 

> e3 = Simplify(e3)

Typesetting:-mprintslash([Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~rho`], Physics:-Dgamma[`~mu`]) = `+`(`-`(`*`(2, `*`(Physics:-`*`(Physi... (179)

Verify this result,

> SumOverRepeatedIndices(Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~rho`], Physics:-Dgamma[`~mu`]) = `+`(`-`(`*`(2, `*`(Physics:-`*`(Physics:...

Typesetting:-mprintslash([`+`(Physics:-`*`(Physics:-Dgamma[1], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~rho`], Physics:-Dgamma[`~1`]), Physics:-`*`(Physics:-Dgamma[2], Phy... (180)

In this case, with three free spacetime indices lambda, nu, rho, the spacetime components form an array 4x4x4 of 64 components, each of which is a matrix equation

> T := TensorArray(`+`(Physics:-`*`(Physics:-Dgamma[1], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~rho`], Physics:-Dgamma[`~1`]), Physics:-`*`(Physics:-Dgamma[2], Physics:-Dga...

Typesetting:-mprintslash([T := RTABLE(18446744078163780782, anything, Array, rectangular, Fortran_order, [], 3, 1 .. 4, 1 .. 4, 1 .. 4)], [Array(%id = 18446744078163780782)]) (181)

For instance, the first element is

> T[1, 1, 1]

Typesetting:-mprintslash([`+`(Physics:-`*`(Physics:-Dgamma[1], Physics:-`^`(Physics:-Dgamma[`~1`], 4)), Physics:-`*`(Physics:-Dgamma[2], Physics:-`^`(Physics:-Dgamma[`~1`], 3), Physics:-Dgamma[`~2`]),... (182)

and it checks OK:

> Library:-PerformMatrixOperations(T[1, 1, 1])

Typesetting:-mrow(Typesetting:-mfenced(Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mn( (183)

How can you test the 64 components of T all at once?

1. Compute the matrices, without displaying the whole thing, take the elements of the array and remove the indices (i.e. take the right-hand side); call it M


> M := map(rhs, ArrayElems(Library:-PerformMatrixOperations(T))); -1

For instance,

> M[1]

Typesetting:-mrow(Typesetting:-mfenced(Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mn( (184)

Now verify all these matrix equations at once: take the elements of the arrays on each side of the equations and verify that the are the same: we expect for output just {true}


> map(proc (u) options operator, arrow; evalb(map(ArrayElems, u)) end proc, M)

{true} (185)

The same for e4

> e4 = Simplify(e4)

Typesetting:-mprintslash([Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~rho`], Physics:-Dgamma[`~sigma`], Physics:-Dgamma[`~mu`]) = `+`(`*`(2,... (186)

> SumOverRepeatedIndices(Physics:-`*`(Physics:-Dgamma[mu], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~rho`], Physics:-Dgamma[`~sigma`], Physics:-Dgamma[`~mu`]) = `+`(`*`(2, `*...

Typesetting:-mprintslash([`+`(Physics:-`*`(Physics:-Dgamma[1], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~rho`], Physics:-Dgamma[`~sigma`], Physics:-Dgamma[`~1`]), Physics:-... (187)

Regarding the spacetime indices this is now an array 4x4x4x4

> T := TensorArray(`+`(Physics:-`*`(Physics:-Dgamma[1], Physics:-Dgamma[`~lambda`], Physics:-Dgamma[`~nu`], Physics:-Dgamma[`~rho`], Physics:-Dgamma[`~sigma`], Physics:-Dgamma[`~1`]), Physics:-`*`(Physi...

Typesetting:-mprintslash([T := RTABLE(18446744078201340382, anything, Array, rectangular, Fortran_order, [], 4, 1 .. 4, 1 .. 4, 1 .. 4, 1 .. 4)], [Array(%id = 18446744078201340382)]) (188)

For instance the first of these 256 matrix equations

> T[1, 1, 1, 1]

Typesetting:-mprintslash([`+`(Physics:-`*`(Physics:-Dgamma[1], Physics:-`^`(Physics:-Dgamma[`~1`], 5)), Physics:-`*`(Physics:-Dgamma[2], Physics:-`^`(Physics:-Dgamma[`~1`], 4), Physics:-Dgamma[`~2`]),... (189)

verifies OK:

> Library:-PerformMatrixOperations(`+`(Physics:-`*`(Physics:-Dgamma[1], Physics:-`^`(Physics:-Dgamma[`~1`], 5)), Physics:-`*`(Physics:-Dgamma[2], Physics:-`^`(Physics:-Dgamma[`~1`], 4), Physics:-Dgamma[...

Typesetting:-mrow(Typesetting:-mfenced(Typesetting:-mfenced(Typesetting:-mrow(Typesetting:-mtable(Typesetting:-mtr(Typesetting:-mtd(Typesetting:-mn( (190)

Now all the 256 matrix equations verified at once as done for e3


> M := map(rhs, ArrayElems(Library:-PerformMatrixOperations(T))); -1

> map(proc (u) options operator, arrow; evalb(map(ArrayElems, u)) end proc, M)

{true} (191)

Miscellaneous improvements


A large number of miscellaneous improvements happened for Physics in Maple 2018. For brevity, these improvements are only listed; among the most relevant ones:

  • There are six new Library routines, DefaultAlgebraRules, Dgamma5ToOtherDgamma, GetDifferentiationVariables, GetRepeatedIndices, IsSymmetricMatrix, RewriteInMatrixForm, all of which are illustrated in the previous sections.
  • All the tensors of 2 indices automatically defined in the Physics package, as well as those you can define using Define with a defining equation, or indicating its symmetries and using the new option minimizetensorcomponents of the Define command, accept a new keyword, trace to represent their trace.
  • The rewriting in terms of `^`(X, mu)  of `∂`[mu](() .. ()) constructions in a Minkowski spacetime can now be computed using convert(`∂`[mu](() .. ()), diff)
  • Change in the design: allow the derivative diff(H(x), x) to proceed also when x is noncommutative by returning unevaluated. In this way one can afterwards define commutation rules such that derivative can be computed.
  • Make diff(H(x, y), x, y) = diff(H(x, y), y, x) when x and y are noncommutative but commute between themselves.
  • Make x and y that belong to one and the same coordinate system always commute, even if x and y are quantum operators.
  • Make all the coordinates of system X[j] set as a quantum operator that commutes with another quantum operator V, also commute with V.
  • Add a differentiation rule for Bracket
  • Physics:-TensorArray: add a new keyword performmatrixoperations (illustrated in the previous sections) and, although unusual, if the input is an Array or Matrix of tensorial equations, map over their elements.
  • Allow to set X[mu], a coordinate system vector, as a quantum operator. With that, automatically, X[mu], is of type noncommutative.
  • When defining a Commutator algebra between indexed objects, that are afterwards defined as tensors, now results in the same behavior as when first defining the tensors then the algebra rules.
  • Tensor input like GAMMA[1, j, k, matrix] now return a 3x3 matrix when j, k are space indices.
  • The Coefficients now automatically maps over equations
  • The Library:-GetTensorSymmetryProperties got entirely rewritten significantly enhanced, and now it always returns sets of sets (automatically normalized), not anymore sets of lists (that do not normalize automatically). This helps, for example, in perceiving by eye that the symmetries of two tensors are actually the same.
  • Reorder the flow within Setup so that first the notation is set, then coordinates followed by the TensorSimplifier and the realojects, and only then the metric is set, that gets simplified taking all of the previous ones into account. This permits to update coordinates dimension, signature, metric and other things all in one go, a single call to Setup.
  • There are some new Setup options, including differentialoperators (illustrated in the previous sections) and usecoordinatesastensorindices that permits indexing tensors directly with the coordinates (easier to remember) instead of with the coordinate's positions. Note: when using usecoordinatesastensorindices the tensors can still also be indexed with the coordinate's positions.
  • Reorder the flow within Define so that first the tensors whose definition is not an equation definition are define, then those that are defined with defining equations. The former definitions can be performed right away and these tensors can now appear on the right-hand sides of other tensor definitions being defined simultaneously with defining equations.
  • Change in the display of covariant derivatives represented using the D_ command: instead of we now use , an upside down triangle that is slightly different from Nabla, used in Physics:-Vectors.
  • Add more types to the Physics:-Library:-PhysicsType package of Physics types, that in Maple 2018 comes with 92 specialized types
  • Allow geometrical coordinates to be defined as tensors (so they become of type Physics:-Tensor) instead of interrupting with an error due to the coordinates being assigned as it was the case of previous releases.
  • MakeDagger(X[mu]) = X[mu] for the Dagger of the SpaceTimeVector (any coordinate system defined through Setup or Coordinates).
  • Make Dagger and d/dx commute also when x is Hermitian (of Library:-PhysicsType:-Hermitian).
  • Implement Dgamma[definition] as the algebra rules satisfied by the Dirac gamma matrices.
  • Make the error message by Check, for instance when indices appear repeated more than once, to also indicate the actual expression where free and/or repeated indices are found to be incorrect.
  • The typesetdot and typesetprime Typesetting rules are now automatically enabled when Physics is loaded.
  • Full revision of the conventions for the Dirac matrices in the different representations and Euclidean space, with Dgamma[5] now following the convention used in the Landau, Bogoliubov and Tong books on Quantum Fields.
  • Add a new option settetrad to TransformTetrad, analogous to the option setmetric of TranformCoordinates.
  • TransformTetrads: when computing a canonicalform for a tetrad the starting tetrad is expected to be in null form, or if it is orthonormal it is automatically converted to null for before proceeding with rotations to achieve a canonical form.
  • Add a new keyword output = listlist to Physics:-Library:-TensorComponent.
  • More documentation: new help pages showing how to perform with the Physics packages the computations one could perform in the past with the (now deprecated) tensor Maple package and the (non-Maplesoft) GRTensor package.