Tensoren (Maxima Manual)

## 20 Tensoren

### 20.1 Tensorpakete in Maxima

Maxima hat drei verschiedene Pakete, um mit Tensoren zu rechnen. Das Paket `ctensor` implementiert das Rechnen mit Tensoren in der Koordinatendarstellung und das Paket `itensor` das Rechnen in einer Indexnotation. Das Paket `atensor` erlaubt die algebraische Manipulation von Tensoren in verschiedenen Algebren.

Beim Rechnen in einer Koordinatendarstellung mit dem Paket `ctensor` werden Tensoren als Arrays oder Matrizen dargestellt. Operationen mit Tensoren wie die Tensorverjüngung oder die kovariante Ableitung werden ausgeführt als Operationen mit den Komponenten des Tensors, die in einem Array oder einer Matrix gespeichert sind.

Beim Rechnen in der Indexnotation mit dem Paket `itensor` werden Tensoren als Funktionen ihrer kovarianten und kontravarianten Indizes sowie den Ableitungen nach den Komponenten dargestellt. Operationen wie die Tensorverjüngung oder die kovariante Ableitung werden ausgeführt, in dem die Indizes manipuliert werden.

Die beiden genannten Pakete `itensor` und `ctensor` für die Behandlung von mathematischen Problemen im Zusammenhang mit der Riemannschen Geometrie haben verschiedene Vor- und Nachteile, die sich erst anhand des zu behandelnden Problems und dessen Schwierigkeitsgrad zeigen. Folgenden Eigenschaften der beiden Implementierungen sollten beachtet werden:

Die Darstellung von Tensoren und Tensoroperationen in einer expliziten Koordinatendarstellung vereinfacht die Nutzung des Paketes `ctensor`. Die Spezifikation der Metrik und die Ableitung von Tensoren sowie von Invarianten ist unkompliziert. Trotz Maximas Methoden für die Vereinfachung von Ausdrücken kann jedoch eine komplexe Metrik mit komplizierten funktionalen Abhängigkeiten der Koordinaten leicht zu sehr großen Ausdrücken führen, die die Struktur eines Ergebnisses verbergen. Weiterhin können Rechnungen zu sehr großen Zwischenergebnisse führen, die zu einem Programmabbruch führen, bevor die Rechnung beendet werden kann. Jedoch kann der Nutzer mit einiger Erfahrung viele dieser Probleme vermeiden.

Aufgrund der besonderen Weise, wie Tensoren und Tensoroperationen als symbolische Operationen ihrer Indizes dargestellt werden, können Ausdrücke, die in einer Koordinatendarstellung sehr unhandlich sind, mit Hilfe spezieller Routinen für symmetrische Objekte in `itensor` manchmal erheblich vereinfacht werden. Auf diese Weise kann die Struktur großer Ausdrücke transparenter sein. Auf der anderen Seite kann die Spezifikation einer Metrik, die Definition von Funktionen und die Auswertung von abgeleiteten indizierten Objekten für den Nutzer schwierig sein.

Mit dem Paket `itensor` können Ableitungen nach einer indizierten Variablen ausgeführt werden, wodurch es möglich ist, `itensor` auch für Probleme im Zusammenhang mit dem Lagrange- oder Hamiltonian-Formalismus einzusetzen. Da es möglich ist, die Lagrangeschen Feldgleichungen nach einer indizierten Variablen abzuleiten, können zum Beispiel die Euler-Lagrange-Gleichungen in einer Indexnotation aufgestellt werden. Werden die Gleichungen mit der Funktion `ic_convert` in eine Komponentendarstellung für das Paket `ctensor` transformiert, können die Feldgleichungen in einer bestimmten Koordinatendarstellung gelöst werden. Siehe dazu die ausführlichen Beispiele in `einhil.dem` und `bradic.dem`.

### 20.2 Paket ITENSOR

#### 20.2.1 Einführung in ITENSOR

Das Paket `itensor` für das Rechnen mit Tensoren in der Indexnotation wird mit dem Kommando `load("itensor")` geladen. Mit dem Kommando `demo(tensor)` wird eine Liste mit verschiedenen Beispielen angezeigt.

Im Paket `itensor` werden Tensoren als indiziertes Objekte dargestellt. Ein indiziertes Objekt ist eine Funktion mit drei Gruppen an Indizes, die die kovarianten, kontravarianten und Ableitungsindizes eines Tensors darstellen. Das erste Argument der Funktion ist eine Liste der kovarianten Indizes und das zweite Argument die Liste der kontravarianten Indizes. Hat der Tensor keine entsprechenden Komponenten, dann wird eine leere Liste als Argument angegeben. Zum Beispiel repräsentiert `g([a,b], [c]` einen Tensor `g`, der zwei kovariante Indizes `[a,b]`, einen kontravarianten Index `[c]` und keinen Ableitungsindex hat. Mit der Funktion `ishow` werden Tensoren in einer besonderen Schreibweise ausgegeben.

Beispiele:

    (%i1) load("itensor")$

    (%i2) g([a,b], [c]);
    (%o2)                    g([a, b], [c])

    (%i3) ishow(g([a,b], [c]))$
                                   c
    (%t3)                         g
                                   a b

Ableitungsindizes werden als weitere Argumente der Funktion hinzugefügt, die den Tensor repräsentiert. Ableitungsindizes können vom Nutzer angegeben oder bei der Ableitung von Tensoren von Maxima hinzugefügt werden. Im Allgemeinen ist die Differentiation kommutativ, so dass die Reihenfolge der Ableitungsindizes keine Rolle spielt. Daher werden die Indizes von Maxima bei der Vereinfachung mit Funktionen wie `rename` alphabetisch sortiert. Dies ist jedoch nicht der Fall, wenn bewegte Bezugssysteme genutzt werden, was mit der Optionsvariablen `iframe_flag` angezeigt wird, die in diesem Fall den Wert `true` erhält. Es ist zu beachten, dass mit dem Paket `itensor` Ableitungsindizes nicht angehoben werden können und nur als kovariante Indizes auftreten.

Beispiele:

    (%i1) load("itensor")$

    (%i2) ishow(t([a,b],[c],j,i))$
                                 c
    (%t2)                       t
                                 a b,j i
    (%i3) ishow(rename(%))$
                                 c
    (%t3)                       t
                                 a b,i j
    (%i4) ishow(t([a,b],[c],j,i) - t([a,b],[c],i,j))$
                            c          c
    (%t4)                  t        - t
                            a b,j i    a b,i j
    (%i5) ishow(rename(%))$
    (%t5)                           0
    (%i6) iframe_flag:true;
    (%o6)                         true
    (%i7) ishow(t([a,b],[c],j,i) - t([a,b],[c],i,j))$
                            c          c
    (%t7)                  t        - t
                            a b,j i    a b,i j
    (%i8) ishow(rename(%))$
                            c          c
    (%t8)                  t        - t
                            a b,j i    a b,i j

Das folgende Beispiel zeigt einen Ausdruck mit verschiedenen Ableitungen eines Tensors `g`. Ist `g` der metrische Tensor, dann entspricht das Ergebnis der Definition des Christoffel-Symbols der ersten Art.

    (%i1) load("itensor")$

    (%i2) ishow(1/2*(idiff(g([i,k],[]),j) + idiff(g([j,k],[]),i)
                                          - idiff(g([i,j],[]),k)))$
                        g      + g      - g
                         j k,i    i k,j    i j,k
    (%t2)               ------------------------
                                   2

Tensoren werden standardmäßig nicht als symmetrisch angenommen. Erhält die Optionsvariable `allsym` den Wert `true`, dann werden alle Tensoren als symmetrisch in den kovarianten und kontravarianten Indizes angenommen.

Das Paket `itensor` behandelt Tensoren im Allgemeinen als opake Objekte. Auf Tensorgleichungen werden algebraischen Regeln insbesondere Symmetrieregeln und Regeln für die Tensorverjüngung angewendet. Weiterhin kennt `itensor` die kovariante Ableitung, Krümmung und die Torsion. Rechnungen können in bewegten Bezugssystemen ausgeführt werden.

Beispiele:

Die folgenden Beispiele zeigen einige Anwendungen des Paketes `itensor`.

    (%i1) load("itensor");
    (%o1)      /share/tensor/itensor.lisp
    (%i2) imetric(g);
    (%o2)                                done
    (%i3) components(g([i,j],[]),p([i,j],[])*e([],[]))$
    (%i4) ishow(g([k,l],[]))$
    (%t4)                               e p
                                           k l
    (%i5) ishow(diff(v([i],[]),t))$
    (%t5)                                  0
    (%i6) depends(v,t);
    (%o6)                               [v(t)]
    (%i7) ishow(diff(v([i],[]),t))$
                                        d
    (%t7)                               -- (v )
                                        dt   i
    (%i8) ishow(idiff(v([i],[]),j))$
    (%t8)                                v
                                          i,j
    (%i9) ishow(extdiff(v([i],[]),j))$
    (%t9)                             v    - v
                                       j,i    i,j
                                      -----------
                                           2
    (%i10) ishow(liediff(v,w([i],[])))$
                                   %3          %3
    (%t10)                        v   w     + v   w
                                       i,%3    ,i  %3
    (%i11) ishow(covdiff(v([i],[]),j))$
                                                  %4
    (%t11)                        v    - v   ichr2
                                   i,j    %4      i j
    (%i12) ishow(ev(%,ichr2))$
                    %4 %5
    (%t12) v    - (g      v   (e p       + e   p     - e p       - e    p
            i,j            %4     j %5,i    ,i  j %5      i j,%5    ,%5  i j

                                             + e p       + e   p    ))/2
                                                  i %5,j    ,j  i %5
    (%i13) iframe_flag:true;
    (%o13)                               true
    (%i14) ishow(covdiff(v([i],[]),j))$
                                                 %6
    (%t14)                        v    - v   icc2
                                   i,j    %6     i j
    (%i15) ishow(ev(%,icc2))$
                                                 %6
    (%t15)                        v    - v   ifc2
                                   i,j    %6     i j
    (%i16) ishow(radcan(ev(%,ifc2,ifc1)))$

                 %6 %7                    %6 %7
    (%t16) - (ifg      v   ifb       + ifg      v   ifb       - 2 v
                        %6    j %7 i             %6    i j %7      i,j

                                                 %6 %7
                                            - ifg      v   ifb      )/2
                                                        %6    %7 i j

    (%i17) ishow(canform(s([i,j],[])-s([j,i])))$
    (%t17)                            s    - s
                                       i j    j i
    (%i18) decsym(s,2,0,[sym(all)],[]);
    (%o18)                               done
    (%i19) ishow(canform(s([i,j],[])-s([j,i])))$
    (%t19)                                 0
    (%i20) ishow(canform(a([i,j],[])+a([j,i])))$
    (%t20)                            a    + a
                                       j i    i j
    (%i21) decsym(a,2,0,[anti(all)],[]);
    (%o21)                               done
    (%i22) ishow(canform(a([i,j],[])+a([j,i])))$
    (%t22)                                 0

#### 20.2.2 Funktionen und Variablen für ITENSOR

#### 20.2.2.1 Behandlung indizierter Größen

Funktion: canten (expr) ¶

  Ist vergleichbar mit der Funktion `rename` und vereinfacht den Ausdruck expr indem gebundene Indizes umbenannt und permutiert werden. Wie die Funktion `rename` kann `canten` nur Ausdrücke mit Summen von Tensorprodukten vereinfachen, in denen keine Ableitungen nach Tensorkomponenten auftreten. Daher sollte `canten` nur verwendet werden, wenn sich mit der Funktion `canform` nicht die gewünschte Vereinfachung eines Ausdrucks erzielen lässt.

  Das Ergebnis der Funktion `canten` ist mathematisch nur korrekt, wenn die Tensoren symmetrisch in ihren Indizes sind. Hat die Optionsvariable `allsym` nicht den Wert `true`, bricht `canten` mit einer Fehlermeldung ab.

  Siehe auch die Funktion `concan`, mit der Ausdrücke mit Tensoren ebenfalls vereinfacht werden können, wobei `concan` zusätzlich Tensorverjüngungen ausführt.

Funktion: changename (old, new, expr) ¶

  Ändert den Namen aller Tensoren im Ausdruck expr von old nach new. Das Argument old kann ein Symbol oder eine Liste der Form `[name, m, n]` sein. Im letzteren Fall werden nur die Tensoren zu new umbenannt, die den Namen name sowie m kovariante und n kontravariante Indizes haben.

  Beispiel:

  In diesem Beispiel wird der Name c zu w geändert.

      (%i1) load("itensor")$

      (%i2) expr:a([i,j],[k])*b([u],[],v)+c([x,y],[])*d([],[])*e$

      (%i3) ishow(changename(c, w, expr))$
                                        k
      (%t3)                 d e w    + a    b
                                 x y    i j  u,v

Funktion: components (tensor, expr) ¶

  Erlaubt die Zuweisung von Werten an die Komponenten eines Tensors tensor, die mit dem Argument expr angegeben werden. Immer wenn der Tensor tensor mit all seinen Indizes in einem Ausdruck auftritt, werden die Komponenten mit den angegebenen Werten substituiert. Der Tensor muss die Form `t([...],[...])` haben, wobei die Listen auch leer sein können. Das Argument expr ist irgendein Ausdruck, der dieselben freien Indizes wie der Tensor tensor hat. Sollen Werte an einen Metriktensor zugewiesen werden, der Dummy-Indizes hat, so muss auf die Benennung der Indizes sorgfältig geachtet werden, um das Auftreten von Mehrfachen Dummy-Indizes zu vermeiden. Mit der Funktion `remcomps` werden Zuweisungen der Funktion `components` an die Komponenten eines Tensors entfernt.

  Es muss beachtet werden, dass die Funktion `components` nur den Typ eines Tensors, aber nicht die Ordnung der Indizes beachtet. Werden daher Werte an die Komponenten der Tensoren `x([i,-j],[])`, `x([-j,i],[])` oder `x([i],[j])` zugewiesen, ergibt sich jeweils dasselbe Ergebnis.

  Komponenten können einem indizierten Ausdruck auf vier verschiedene Methoden zugeordnet werden. Zwei Methoden nutzen die Funktion `components`.

  1) Als ein indizierte Ausdruck:

      (%i2) components(g([],[i,j]), e([],[i])*p([],[j]))$
      (%i3) ishow(g([],[i,j]))$
                                            i  j
      (%t3)                                e  p

  2) Als eine Matrix:

      (%i5) lg:-ident(4)$ lg[1,1]:1$ lg;
                                  [ 1   0    0    0  ]
                                  [                  ]
                                  [ 0  - 1   0    0  ]
      (%o5)                       [                  ]
                                  [ 0   0   - 1   0  ]
                                  [                  ]
                                  [ 0   0    0   - 1 ]

      (%i6) components(g([i,j],[]), lg);
      (%o6)                                done
      (%i7) ishow(g([i,j],[]))$
      (%t7)                                g
                                            i j
      (%i8) g([1,1],[]);
      (%o8)                                  1
      (%i9) g([4,4],[]);
      (%o9)                                 - 1

  3) Als eine Funktion: Die Werte der Komponenten eines Tensors werden durch eine Funktion gegeben.

      (%i4) h(l1,l2,[l3]):=if length(l1)=length(l2) and length(l3)=0
        then kdelta(l1,l2) else apply(g,append([l1,l2], l3))$
      (%i5) ishow(h([i],[j]))$
                                                j
      (%t5)                               kdelta
                                                i
      (%i6) ishow(h([i,j],[k],l))$
                                           k
      (%t6)                               g
                                           i j,l

  4) Mit Mustern und Regeln: Im Folgenden wird ein Beispiel mit den Funktionen `defrule` und `applyb1` gezeigt.

      (%i1) load("itensor");
      (%o1)      /share/tensor/itensor.lisp
      (%i2) matchdeclare(l1,listp);
      (%o2)                                done
      (%i3) defrule(r1,m(l1,[]),(i1:idummy(),
            g([l1[1],l1[2]],[])*q([i1],[])*e([],[i1])))$

      (%i4) defrule(r2,m([],l1),(i1:idummy(),
            w([],[l1[1],l1[2]])*e([i1],[])*q([],[i1])))$

      (%i5) ishow(m([i,n],[])*m([],[i,m]))$
                                          i m
      (%t5)                              m    m
                                               i n
      (%i6) ishow(rename(applyb1(%,r1,r2)))$
                                 %1  %2  %3 m
      (%t6)                     e   q   w     q   e   g
                                               %1  %2  %3 n

Funktion: concan (expr) ¶

  Ist vergleichbar mit der Funktion `canten`. Im Unterschied zu `canten` werden zusätzlich Tensorverjüngungen ausgeführt.

Funktion: contract (expr) ¶

  Führt die Tensorverjüngungen im Ausdruck expr aus, die beliebige Summen und Produkte sein können. `contract` nutzt die Informationen, die für die Tensoren mit der Funktion `defcon` definiert sind. Die besten Ergebnisse werden erzielt, wenn der Ausdruck expr vollständig expandiert wird. Die Funktion `radexpand` expandiert Produkte und Potenzen von Summen am schnellsten, sofern keine Variablen im Nenner der Terme auftreten. Die Optionsvariable `gcd` sollte den Wert `false` haben, wenn das Kürzen durch einen größten gemeinsamen Teiler nicht notwendig ist.

Systemvariable: contractions ¶

  Die Liste `contractions` enthält die Tensoren, die mit der Funktion `defcon` die Eigenschaft einer Tensorverjüngung erhalten haben.

Funktion: defcon (tensor_1) ¶
Funktion: defcon (tensor_1, tensor_2, tensor_3) ¶

  Gibt einem Tensor tensor_1 die Eigenschaft, dass die Tensorverjüngung des Produktes tensor_1 mit tensor_2 das Ergebnis tensor_3 hat. Wird nur ein Argument tensor_1 angegeben, dann hat die Tensorverjüngung für jeden Tensor `tensor`, der die korrekten Indizes hat, das Ergebnis `tensor` mit neuen Indizes, die die Tensorverjüngung widerspiegeln.

  Wird zum Beispiel die Metrik als `imetric: g` gesetzt, dann wird mit `defcon(g)` das Hochstellen und Herunterstellen der Indizes mit dem Metriktensor definiert.

  Wird `defcon` wiederholt für einen Tensor aufgerufen, ist jeweils die letzte Definition wirksam.

  Die Liste `contractions` enthält die Tensoren, die mit der Funktion `defcon` die Eigenschaft einer Tensorverjüngung erhalten haben.

Funktion: dispcon (tensor_1, tensor_2, …) ¶
Funktion: dispcon (all) ¶

  Zeigt die Kontraktionseigenschaften der Tensoren tensor_1, tensor_2, … wie sie mit der Funktion `defcon` definiert wurden. Das Kommando `dispcon(all)` zeigt alle vom Nutzer definierten Kontraktionseigenschaften.

  Beispiel:

  Wird das Paket `itensor` geladen, gibt `dispcon` das folgende Ergebnis.

      (%i1) load("itensor")$

      (%i2) dispcon(all);
      (%o2)      [[[ifr, ifri, ifg]], [[ifg, ifg, kdelta]]]

Funktion: entertensor (name) ¶

  Die Funktion `entertensor` ermöglicht die Eingabe eines indizierten Tensors mit einer beliebigen Anzahl an Tensorindizes und Ableitungen. Es kann ein einzelner Index oder eine Liste mit Indizes angegeben werden. Die Liste kann eine leere Liste sein.

  Beispiel:

      (%i1) load("itensor")$

      (%i2) entertensor()$
      Enter tensor name: a;
      Enter a list of the covariant indices: [i,j];
      Enter a list of the contravariant indices: [k];
      Enter a list of the derivative indices: [];
                                     k
      (%t2)                         a
                                     i j

Optionsvariable: flipflag ¶

  Standardwert: `false`

  Hat die Optionsvariable `flipflag` den Wert `false`, werden die Indizes von der Funktion `rename` bei der Umbenennung in der Reihenfolge der kontravarianten Indizes sortiert, ansonsten in der Reihenfolge der kovarianten Indizes.

  Siehe auch das Beispiel für die Funktion `rename`.

Optionsvariable: icounter ¶

  Standardwert: `0`

  Enthält die laufende Nummer, um den nächsten Dummy-Index zu bilden. `icounter` wird automatisch erhöht, bevor der neue Index gebildet wird. Dem Wert `icounter` wird er Präfix `idummyx` vorangestellt. Der Standardwert von `idummyx` ist `%`.

Funktion: idummy () ¶

  Erhöht den Wert der laufenden Nummer `icounter` und gibt einen neuen Index zurück, indem der Präfix `idummyx` der Nummer `icounter` vorangestellt wird. Siehe auch die Funktion `indices`.

Optionsvariable: idummyx ¶

  Standardwert: `%`

  Enthält den Präfix, der einem neuen Index vorangestellt wird, der mit der Funktion `idummy` gebildet wird.

Funktion: indexed_tensor (tensor) ¶

  Muss ausgeführt werden, bevor einem Tensors tensor Komponenten zugewiesen werden, für die bereits interne Werte vorliegen wie für `ichr1`, `ichr2` oder `icurvature`. Siehe das Beispiel zur Funktion `icurvature`.

Funktion: indices (expr) ¶

  Gibt eine Liste mit zwei Elementen zurück. Das erste Element ist eine Liste mit den Indizes im Ausdruck expr die frei sind, also nur einmal auftreten. Das zweite Elemente ist eine Liste mit den Indizes, über die summiert wird, die also im Ausdruck genau zweimal auftreten.

  Ein Tensorprodukt mit einem Index der mehr als zweimal auftritt, ist nicht korrekt formuliert. Die Funktion `indices` gibt in einem solchen Fall jedoch keinen Fehler aus.

  Beispiel:

      (%i1) load("itensor")$

      (%i2) ishow(a([i,j],[k,l],m,n)*b([k,o],[j,m,p],q,r))$
                               k l      j m p
      (%t2)                   a        b
                               i j,m n  k o,q r
      (%i3) indices(%);
      (%o3)          [[l, p, i, n, o, q, r], [k, j, m]]

Funktion: ishow (expr) ¶

  Zeigt den Ausdruck expr an, wobei Tensoren im Ausdruck mit tiefgestellten kovarianten Indizes und hochgestellten kontravarianten Indizes sowie die Ableitungen mit durch ein Komma getrennten tiefgestellte Indizes angezeigt werden.

  Beispiel:

      (%i1) load("itensor")$

      (%i2) ishow(a([i,j], [k], v,w))$
                                   k
      (%t2)                       a
                                   i j,v w

Funktion: kdels (L1, L2) ¶

  `kdels` gibt wie die Funktion `kdelta` ein Kronecker-Delta zurück. Im Unterschied zu `kdelta` ist das Kronecker-Delta der Funktion `kdels` symmetrisch.

  Beispiele:

      (%i1) load("itensor");
      (%o1)      /share/tensor/itensor.lisp
      (%i2) kdelta([1,2],[2,1]);
      (%o2)                                 - 1
      (%i3) kdels([1,2],[2,1]);
      (%o3)                                  1
      (%i4) ishow(kdelta([a,b],[c,d]))$
                                   c       d         d       c
      (%t4)                  kdelta  kdelta  - kdelta  kdelta
                                   a       b         a       b
      (%i4) ishow(kdels([a,b],[c,d]))$
                                   c       d         d       c
      (%t4)                  kdelta  kdelta  + kdelta  kdelta
                                   a       b         a       b

Funktion: kdelta (L1, L2) ¶

  Ist das verallgemeinerte Kronecker-Delta im `itensor`-Paket. Das Argument L1 ist die Liste der kovarianten und L2 der kontravarianten Indizes. `kdelta([i],[j])` gibt das einfache Kronecker-Delta zurück.

  Das `itensor`-Paket erlaubt die Definition des Kronecker-Delta nur mit kovarianten oder kontravarianten Indizes, wie zum Beispiel `kdelta([i,j],[])`. Mit diesen Größen kann gerechnet werden, sie sind jedoch keine Tensoren.

Regel: lc_l ¶

  `lc_l` ist eine Regel, um Ausdrücke zu vereinfachen, die Levi-Civita-Symbole enthalten. Zusammen mit der Regel `lc_u` kann die Regel zum Beispiel mit der Funktion `applyb1` angewendet werden, um Ausdrücke effizienter zu vereinfachen, als durch eine Auswertung des Symbols `levi_civita`.

  Beispiele:

      (%i1) load("itensor");
      (%o1)      /share/tensor/itensor.lisp
      (%i2) el1:ishow('levi_civita([i,j,k],[])*a([],[i])*a([],[j]))$
                                   i  j
      (%t2)                       a  a  levi_civita
                                                   i j k
      (%i3) el2:ishow('levi_civita([],[i,j,k])*a([i])*a([j]))$
                                             i j k
      (%t3)                       levi_civita      a  a
                                                    i  j
      (%i4) canform(contract(expand(applyb1(el1,lc_l,lc_u))));
      (%t4)                                  0
      (%i5) canform(contract(expand(applyb1(el2,lc_l,lc_u))));
      (%t5)                                  0

Regel: lc_u ¶

  `lc_u` ist eine Regel, um Ausdrücke zu vereinfachen, die Levi-Civita-Symbole enthalten. Zusammen mit der Regel `lc_c` kann die Regel zum Beispiel mit der Funktion `applyb1` angewendet werden, um Ausdrücke effizienter zu vereinfachen, als durch eine Auswertung des Symbols `levi_civita`. Siehe `lc_l` für Beispiele.

Funktion: lc2kdt (expr) ¶

  Vereinfacht den Ausdruck expr mit Levi-Civita-Symbolen. Wenn möglich werden diese zu Kronecker-Delta-Symbolen vereinfacht. Im Unterschied zu der Auswertung eines Ausdrucks mit Levi-Civita-Symbolen, vermeidet die Funktion `lc2kdt` das Einführen von numerischen Indizes, die für eine weitere symbolische Vereinfachung zum Beispiel mit den Funktionen `rename` oder `contract` nicht geeignet sind.

  Beispiel:

      (%i1) load("itensor");
      (%o1)      /share/tensor/itensor.lisp
      (%i2) expr:ishow('levi_civita([],[i,j])
                       *'levi_civita([k,l],[])*a([j],[k]))$
                                        i j  k
      (%t2)                  levi_civita    a  levi_civita
                                             j            k l
      (%i3) ishow(ev(expr,levi_civita))$
                                        i j  k       1 2
      (%t3)                       kdelta    a  kdelta
                                        1 2  j       k l
      (%i4) ishow(ev(%,kdelta))$
                   i       j         j       i   k
      (%t4) (kdelta  kdelta  - kdelta  kdelta ) a
                   1       2         1       2   j

                                     1       2         2       1
                              (kdelta  kdelta  - kdelta  kdelta )
                                     k       l         k       l
      (%i5) ishow(lc2kdt(expr))$
                           k       i       j    k       j       i
      (%t5)               a  kdelta  kdelta  - a  kdelta  kdelta
                           j       k       l    j       k       l
      (%i6) ishow(contract(expand(%)))$
                                       i           i
      (%t6)                           a  - a kdelta
                                       l           l

  Die Funktion `lc2kdt` benötigt in einigen Fällen den Metriktensor. Ist der Metriktensor zuvor nicht mit der Funktion `imetric` definiert, dann meldet Maxima einen Fehler.

      (%i7) expr:ishow('levi_civita([],[i,j])
                       *'levi_civita([],[k,l])*a([j,k],[]))$
                                       i j            k l
      (%t7)                 levi_civita    levi_civita    a
                                                           j k
      (%i8) ishow(lc2kdt(expr))$
      Maxima encountered a Lisp error:

       Error in $IMETRIC [or a callee]:
       $IMETRIC [or a callee] requires less than two arguments.

      Automatically continuing.
      To reenable the Lisp debugger set *debugger-hook* to nil.
      (%i9) imetric(g);
      (%o9)                                done
      (%i10) ishow(lc2kdt(expr))$

               %3 i       k   %4 j       l     %3 i       l   %4 j
      (%t10) (g     kdelta   g     kdelta   - g     kdelta   g
                          %3             %4               %3
                    k
              kdelta  ) a
                    %4   j k

      (%i11) ishow(contract(expand(%)))$
                                        l i    l i  j
      (%t11)                           a    - g    a
                                                    j

Funktion: levi_civita (L) ¶

  Ist der Levi-Civita-Tensor, der auch Permutationstensor genannt wird. Der Tensor hat den Wert `1`, wenn die Liste L eine gerade Permutation ganzer Zahlen ist, den Wert `-1` für eine ungerade Permutation und ansonsten den Wert `0`.

  Beispiel:

  Für eine Kreisbewegung ist die Bahngeschwindigkeit `v` das Kreuzprodukt aus Winkelgeschwindigkeit `w` und Ortsvektor `r`. Wir haben also `v = w x r`. Hier wird eine tensorielle Schreibweise des Kreuzproduktes mit dem Levi-Civita-Tensor eingeführt. Der Ausdruck wird sodann für die erste Komponente zu der bekannten Definition des Kreuzproduktes vereinfacht.

      (%i1) load("itensor")$

      (%i2) ishow(v([],[a])=
                 'levi_civita([],[a,b,c])*w([b],[])*r([c],[]))$

                          a              a b c
      (%t2)              v  = levi_civita      w  r
                                                b  c

      (%i3) ishow(subst([a=1],%))$
                          1              1 b c
      (%t3)              v  = levi_civita      w  r
                                                b  c
      (%i4) ishow(ev(%, levi_civita))$
                            1         1 b c
      (%t4)                v  = kdelta      w  r
                                      1 2 3  b  c
      (%i5) ishow(expand(ev(%, kdelta)))$
              1         b       c               c       b
      (%t5)  v  = kdelta  kdelta  w  r  - kdelta  kdelta  w  r
                        2       3  b  c         2       3  b  c
      (%i6) ishow(contract(%))$
                              1
      (%t6)                  v  = w  r  - r  w
                                   2  3    2  3

  In diesem Beispiel wird das Spatprodukt von drei Vektoren `a`, `b` und `b` mit dem Levi-Civita-Tensor definiert und dann vereinfacht.

      (%i1) load("itensor")$

      (%i2) ishow(levi_civita([],[i,j,k])*a([i],[])*b([j],[])*c([k],[]))$
                                  i j k
      (%t2)                 kdelta      a  b  c
                                  1 2 3  i  j  k
      (%i3) ishow(contract(expand(ev(%,kdelta))))$
      (%t3) a  b  c  - b  a  c  - a  c  b  + c  a  b  + b  c  a
             1  2  3    1  2  3    1  2  3    1  2  3    1  2  3
                                                             - c  b  a
                                                                1  2  3

Funktion: listoftens (expr) ¶

  Gibt eine Liste mit allen Tensoren zurück, die im Argument expr enthalten sind.

  Beispiel:

      (%i1) load("itensor")$

      (%i2) ishow(a([i,j],[k])*b([u],[],v)+c([x,y],[])*d([],[])*e)$
                                        k
      (%t2)                 d e c    + a    b
                                 x y    i j  u,v
      (%i3) ishow(listoftens(%))$
                              k
      (%t3)                 [a   , b   , c   , d]
                              i j   u,v   x y

Funktion: remcomps (tensor) ¶

  Entfernt alle Werte von den Komponenten des Tensors tensor, die einen Wert mit der Funktion `components` erhalten haben.

Funktion: remcon (tensor_1, …, tensor_n) ¶
Funktion: remcon (all) ¶

  Entfernt die Eigenschaften der Tensorverjüngung von den Tensoren tensor_1, …, tensor_n. `remcon(all)` entfernt die Eigenschaften von der Tensorverjüngung für alle Tensoren. Das sind die Tensoren, die in der Liste `contractions` enthalten sind.

Funktion: rename (expr) ¶
Funktion: rename (expr, count) ¶

  Gibt einen zum Argument expr äquivalenten Ausdruck zurück, wobei die Summationsindizes mit den Werten aus der liste `[%1, %2, ...]` umbenannt sind. Wird das zusätzlich das Argument count angegeben, wird die Nummerierung mit dem Wert count begonnen. Jeder Summationsindex in einem Produkt erhält einen verschiedenen Namen. Für eine Summe wird der Zähler für jeden Term zurückgesetzt. Auf diese Weise wirkt die Funktion `rename` wie eine Vereinfachung eines tensoriellen Ausdrucks. Hat die Optionsvariable `allsym` den Wert `true`, werden die Indizes alphabetisch nach den kovarianten oder kontravarianten Indizes geordnet, entsprechend dem Wert der Optionsvariablen `flipflag`. Hat die Optionsvariable `flipflag` den Wert `true`, werden die Indizes entsprechend der Ordnung der kovarianten Indizes geordnet. Es ist häufig der Fall, dass das Ordnen sowohl nach den kovarianten als auch den kontravarianten Indizes einen Ausdruck besser vereinfacht, als allein die Ordnung nach einer der Indizes.

  Beispiele:

      (%i1) load("itensor")$

      (%i2) allsym: true;
      (%o2)                         true
      (%i3) g([],[%4,%5])*g([],[%6,%7])*ichr2([%1,%4],[%3])
                   *ichr2([%2,%3],[u])*ichr2([%5,%6],[%1])
                   *ichr2([%7,r],[%2])
       -g([],[%4,%5])*g([],[%6,%7])*ichr2([%1,%2],[u])
                     *ichr2([%3,%5],[%1])*ichr2([%4,%6],[%3])
                     *ichr2([%7,r],[%2])$

      (%i4) expr: ishow(%)$

             %4 %5  %6 %7      %3         u          %1         %2
      (%t4) g      g      ichr2      ichr2      ichr2      ichr2
                               %1 %4      %2 %3      %5 %6      %7 r
                %4 %5  %6 %7      u          %1         %3         %2
             - g      g      ichr2      ichr2      ichr2      ichr2
                                  %1 %2      %3 %5      %4 %6      %7 r

      (%i5) flipflag: true;
      (%o5)                         true
      (%i6) ishow(rename(expr))$
             %2 %5  %6 %7      %4         u          %1         %3
      (%t6) g      g      ichr2      ichr2      ichr2      ichr2
                               %1 %2      %3 %4      %5 %6      %7 r
                %4 %5  %6 %7      u          %1         %3         %2
             - g      g      ichr2      ichr2      ichr2      ichr2
                                  %1 %2      %3 %4      %5 %6      %7 r
      (%i7) flipflag: false;
      (%o7)                         false
      (%i8) rename(%th(2));
      (%o8)                           0
      (%i9) ishow(rename(expr))$
             %1 %2  %3 %4      %5         %6         %7        u
      (%t9) g      g      ichr2      ichr2      ichr2     ichr2
                               %1 %6      %2 %3      %4 r      %5 %7
                %1 %2  %3 %4      %6         %5         %7        u
             - g      g      ichr2      ichr2      ichr2     ichr2
                                  %1 %3      %2 %6      %4 r      %5 %7

Funktion: showcomps (tensor) ¶

  Zeigt die Zuweisungen mit der Funktion `components` an die Komponenten des Tensors tensor. Die Funktion `showcomps` kann auch die Komponenten eines Tensors mit einer höheren Stufe als 2 zeigen.

  Beispiel:

      (%i1) load("ctensor")$
      (%i2) load("itensor")$
      (%i3) lg:matrix([sqrt(r/(r-2*m)),0,0,0],[0,r,0,0],
                      [0,0,sin(theta)*r,0],[0,0,0,sqrt((r-2*m)/r)]);

                     [         r                                     ]
                     [ sqrt(-------)  0       0              0       ]
                     [      r - 2 m                                  ]
                     [                                               ]
                     [       0        r       0              0       ]
      (%o3)          [                                               ]
                     [       0        0  r sin(theta)        0       ]
                     [                                               ]
                     [                                      r - 2 m  ]
                     [       0        0       0        sqrt(-------) ]
                     [                                         r     ]

      (%i4) components(g([i,j],[]),lg);
      (%o4)                                done
      (%i5) showcomps(g([i,j],[]));

                        [         r                                     ]
                        [ sqrt(-------)  0       0              0       ]
                        [      r - 2 m                                  ]
                        [                                               ]
                        [       0        r       0              0       ]
      (%t5)      g    = [                                               ]
                  i j   [       0        0  r sin(theta)        0       ]
                        [                                               ]
                        [                                      r - 2 m  ]
                        [       0        0       0        sqrt(-------) ]
                        [                                         r     ]

      (%o5)                                false

#### 20.2.2.2 Tensorsymmetrien

Optionsvariable: allsym ¶

  Standardwert: `false`

  Hat die Optionsvariable `allsym` den Wert `true`, werden alle indizierten Größen als symmetrisch in ihren kovarianten und kontravarianten Indizes angenommen. Ist der Wert `false`, werden keine Symmetrien für die Indizes angenommen. Die Indizes von Ableitungen werden immer als symmetrisch angenommen, außer wenn die Optionsvariable `iframe_flag` den Wert `true` hat.

Funktion: decsym (tensor, m, n, [cov_1, cov_2, …], [contr_1, contr_2, …]) ¶

  Definiert Symmetrieeigenschaften für den Tensor tensor mit m kovarianten und n kontravarianten Indizes. Die Argumente cov_i und contr_i geben Symmetrieeigenschaften zwischen den kontravarianten und kontravarianten Indizes an. Die Argumente haben die Form `symoper(index_1, index_2, ...`. `symoper` ist einer der Symmetrieeigenschaften `sym` für symmetrisch, `anti` für antisymmetrisch oder `cyc` für zyklisch und die Argumente index_i sind ganze Zahlen, die die Position des Index im Tensor tensor angegeben. Weiterhin ist die Form `symoper(all)` möglich. In diesem Fall wird die entsprechende Symmetrieeigenschaft für alle Indizes angenommen.

  Ist zum Beispiel `b` ein Tensor mit 5 kovarianten Indizes, dann wird mit `decsym(b, 5, 3, [sym(1,2), anti(3,4)], [cyc(all)])` definiert, dass `b` symmetrisch in den Indizes `1` und `2`, antisymmetrisch in den Indizes `3` und `4` sowie zyklisch in allen kontravarianten Indizes ist.

  Symmetrieeigenschaften, die mit der Funktion `decsym` definiert werden, werden von der Funktion `canform` angewendet.

  Beispiele:

      (%i1) load("itensor");
      (%o1)      /share/tensor/itensor.lisp
      (%i2) expr:contract( expand( a([i1, j1, k1], [])
                 *kdels([i, j, k], [i1, j1, k1])))$
      (%i3) ishow(expr)$
      (%t3)         a      + a      + a      + a      + a      + a
                     k j i    k i j    j k i    j i k    i k j    i j k
      (%i4) decsym(a,3,0,[sym(all)],[]);
      (%o4)                                done
      (%i5) ishow(canform(expr))$
      (%t5)                              6 a
                                            i j k
      (%i6) remsym(a,3,0);
      (%o6)                                done
      (%i7) decsym(a,3,0,[anti(all)],[]);
      (%o7)                                done
      (%i8) ishow(canform(expr))$
      (%t8)                                  0
      (%i9) remsym(a,3,0);
      (%o9)                                done
      (%i10) decsym(a,3,0,[cyc(all)],[]);
      (%o10)                               done
      (%i11) ishow(canform(expr))$

      (%t11)                        3 a      + 3 a
                                       i k j      i j k

      (%i12) dispsym(a,3,0);
      (%o12)                     [[cyc, [[1, 2, 3]], []]]

Funktion: remsym (tensor, m, n) ¶

  Entfernt die Symmetrieeigenschaften des Tensors tensor, der m kovariante und n kontravariante Indizes hat.

Funktion: canform (expr) ¶
Funktion: canform (expr, rename) ¶

  Vereinfacht den Ausdruck expr indem alle Dummy-Indizes umbenannt und umgeordnet werden, wobei vorhandene Symmetrieeigenschaften angewendet werden. Hat die Optionsvariable `allsym` den Wert `true`, werden alle Indizes als symmetrisch angenommen. Ansonsten werden Symmetrieeigenschaften angewendet, die mit der Funktion `decsym` definiert sind. Die Dummy-Indizes werden auf gleiche Weise umbenannt wie von der Funktion `rename`. Wird `canform` auf einen großen Ausdruck angewendet, kann die Ausführung eine lange Zeit beanspruchen. Die Rechenzeit kann verkürzt werden, indem zuerst die Funktion `rename` auf den Ausdruck angewendet wird.

  `canform` kann einen Ausdruck nicht immer in die einfachste Form bringen, jedoch ist das Ergebnis immer mathematisch korrekt.

  Erhält das optionale zweite Argument rename den Wert `false`, wird die Umbenennung mit der Funktion `rename` nicht ausgeführt.

  Für ein Beispiel siehe die Funktion `decsym`.

#### 20.2.2.3 Tensoranalysis

Funktion: diff (expr, v_1, n_1, v_2, n_2, …) ¶

  Ist die gleichnamige Funktion `diff` für die Differentiation einer tensoriellen Größe. `diff` ist für das Paket `itensor` erweitert. Die tensorielle Größe expr wird n_1-mal nach der Variablen v_1, n_2 nach der Variablen v_2, … abgeleitet. Die Argumente `v_1` können ganze Zahlen von `1`, …, `dim` sein. In diesem Fall bezeichnen die ganzen Zahlen der Reihe nach die Indizes, die in der Optionsvariablen `vect_coords` abgelegt sind. `dim` ist die Dimension der tensoriellen Größen.

  Weiterhin erlaubt die erweiterte Funktion `diff` die Berechnung von Ableitungen nach indizierten Variablen. So können Ausdrücke, die den Metriktensor und seine Ableitungen enthalten, nach dem Metriktensor und seinen Ableitungen abgeleitet werden.

  Beispiele:

      (%i1) load("itensor")$

      (%i2) depends(v,t);
      (%o2)                        [v(t)]
      (%i3) ishow(diff(v([i,j],[k])^2, t,1))$
                                k    d    k
      (%t3)                  2 v    (-- (v   ))
                                i j  dt   i j
      (%i4) ishow(diff(v([i,j],[k])^2, t,2))$
                             2
                       k    d     k          d    k    2
      (%t4)         2 v    (--- (v   )) + 2 (-- (v   ))
                       i j    2   i j        dt   i j
                            dt

Funktion: idiff (expr, v_1, [n_1, [v_2, n_2] …]) ¶

  `idiff` führt Ableitungen nach den Koordinaten einer tensoriellen Größe aus. Im Unterschied dazu führt die Funktion `diff` Ableitungen nach den unabhängigen Variablen aus. Eine tensorielle Größe erhält zusätzlich den Index v_1, der die Ableitung bezeichnet. Mehrfache Indizes für Ableitungen werden sortiert, außer wenn die Optionsvariable `iframe_flag` den Wert `true` hat.

  `idiff` kann auch die Determinante des Metriktensors ableiten. Wird zum Beispiel der Optionsvariablen `imetric` der Wert `g` zugewiesen, dann hat das Kommando `idiff(determinant(g), k)` das Ergebnis `2 * determinant(g) * ichr2([%i,k], [%i])`, wobei die Dummy-Variable passend gewählt wird.

Funktion: liediff (v, ten) ¶

  Berechnet die Lie-Ableitung eines tensoriellen Ausdrucks ten für das Vektorfeld v. Das Argument ten kann irgendeine tensorielle Größe sein. Das Argument v ist der Name eines Vektorfeldes und wird ohne Indizes angegeben.

  Beispiel:

      (%i1) load("itensor");
      (%o1)      /share/tensor/itensor.lisp
      (%i2) ishow(liediff(v,a([i,j],[])*b([],[k],l)))$
             k    %2            %2          %2
      (%t2) b   (v   a       + v   a     + v   a    )
             ,l       i j,%2    ,j  i %2    ,i  %2 j

                                %1  k        %1  k      %1  k
                            + (v   b      - b   v    + v   b   ) a
                                    ,%1 l    ,l  ,%1    ,l  ,%1   i j

Funktion: rediff (ten) ¶

  Wertet jedes Auftreten von Substantivformen der Funktion `idiff` in dem tensoriellem Ausdruck ten aus.

Funktion: undiff (expr) ¶

  Gibt einen zum Argument expr äquivalenten Ausdruck zurück, in dem alle Ableitungen von indizierten Größen durch Substantivformen der Funktion `idiff` ersetzt sind.

Funktion: evundiff (expr) ¶

  Ist äquivalent zur Ausführung der Funktion `undiff`, der die Funktionen `ev` und `rediff` nachfolgen.

  `evundiff` erlaubt die Auswertung von Ausdrücken, die nicht direkt in ihrer abgeleiteten Form ausgewertet werden können. So führt das folgende Beispiel zu einer Fehlermeldung:

      (%i1) load("itensor");
      (%o1)      /share/tensor/itensor.lisp
      (%i2) icurvature([i,j,k],[l],m);
      Maxima encountered a Lisp error:

       Error in $ICURVATURE [or a callee]:
       $ICURVATURE [or a callee] requires less than three arguments.

      Automatically continuing.
      To reenable the Lisp debugger set *debugger-hook* to nil.

  Wird jedoch `icurvature` in der Substantivform verwendet, kann der Ausdruck mit `evundiff` ausgewertet werden:

      (%i3) ishow('icurvature([i,j,k],[l],m))$

                                               l
      (%t3)                          icurvature
                                               i j k,m

      (%i4) ishow(evundiff(%))$
                   l              l         %1           l           %1
      (%t4) - ichr2        - ichr2     ichr2      - ichr2       ichr2
                   i k,j m        %1 j      i k,m        %1 j,m      i k

                   l              l         %1           l           %1
            + ichr2        + ichr2     ichr2      + ichr2       ichr2
                   i j,k m        %1 k      i j,m        %1 k,m      i j

  Um Christoffel-Symbole abzuleiten, wird die Funktion `evundiff` nicht benötigt:

      (%i5) imetric(g);
      (%o5)                                done
      (%i6) ishow(ichr2([i,j],[k],l))$

             k %3
            g     (g         - g         + g        )
                    j %3,i l    i j,%3 l    i %3,j l
      (%t6) -----------------------------------------
                                2

                               k %3
                              g     (g       - g       + g      )
                               ,l     j %3,i    i j,%3    i %3,j
                            + -----------------------------------
                                               2

Funktion: flush (expr, tensor_1, tensor_2, …) ¶

  Alle tensoriellen Größen tensor_i die im Ausdruck expr auftreten und keine Ableitungen haben, werden zu Null gesetzt.

Funktion: flushd (expr, tensor_1, tensor_2, …) ¶

  Alle tensoriellen Größen tensor_i die im Ausdruck expr auftreten und Ableitungen haben, werden zu Null gesetzt.

Funktion: flushnd (expr, tensor, n) ¶

  Setzt alle Ableitungen der tensoriellen Größe tensor die im Ausdruck expr auftritt und n oder mehr Ableitungen hat, auf den Wert Null.

  Beispiele:

      (%i1) load("itensor");
      (%o1)      /share/tensor/itensor.lisp
      (%i2) ishow(a([i],[J,r],k,r)+a([i],[j,r,s],k,r,s))$
                                      J r      j r s
      (%t2)                          a      + a
                                      i,k r    i,k r s
      (%i3) ishow(flushnd(%,a,3))$
                                           J r
      (%t3)                               a
                                           i,k r

Funktion: coord (tensor_1, tensor_2, …) ¶
Systemvariable: coord ¶

  Gibt der tensoriellen Größe tensor_i die Eigenschaft, dass die kovariante Ableitung eines Vektors mit dem Namen tensor_i das Ergebnis Kronecker-Delta hat.

  `coord` ist auch eine Systemvariable, die alle tensoriellen Größen enthält, die mit der Funktion `coord` die Eigenschaft der kovarianten Ableitung erhalten haben.

  Beispiel:

      (%i1) coord(x);
      (%o1)                         done
      (%i2) idiff(x([],[i]),j);
      (%o2)                   kdelta([j], [i])
      (%i3) coord;
      (%o3)                          [x]

Funktion: remcoord (tensor_1, tensor_2, …) ¶
Funktion: remcoord (all) ¶

  Entfernt die mit der Funktion `coord` definierte Eigenschaft für die tensoriellen Größen tensor_i. Das Kommando `remcoord(all)` entfernt diese Eigenschaft für alle tensoriellen Größen.

Funktion: makebox (expr, name) ¶

  Zeigt das Argument expr auf die gleiche Weise an wie die Funktion `ishow` mit dem Unterschied, dass der d’Alembert-Operator name im Ausdruck durch `[]` ersetzt wird.

  Beispiel:

      (%i1) makebox(g([],[i,j])*p([m],[n],i,j),g);
      (%o1)                     []p([m], [n])

Funktion: conmetderiv (expr, tensor) ¶

  Vereinfacht Ausdrücke, die kovariante und kontravariante Ableitungen des Metriktensors enthalten. `conmetderiv` kann zum Beispiel die Ableitungen des kontravarianten Metriktensors in Beziehung zu den Christoffel-Symbolen setzen:

      (%i1) load("itensor");
      (%o1)      /share/tensor/itensor.lisp
      (%i2) ishow(g([],[a,b],c))$
                                            a b
      (%t2)                                g
                                            ,c
      (%i3) ishow(conmetderiv(%,g))$
                               %1 b      a       %1 a      b
      (%t3)                 - g     ichr2     - g     ichr2
                                         %1 c              %1 c

Funktion: simpmetderiv (expr) ¶
Funktion: simpmetderiv (expr[, stop]) ¶

  Vereinfacht Ausdrücke die Produkte von Ableitungen des Metriktensors enthalten. Im besonderen erkennt `simpmetderiv` die folgenden Identitäten:

         ab        ab           ab                 a
        g   g   + g   g     = (g   g  )   = (kdelta )   = 0
         ,d  bc        bc,d         bc ,d          c ,d

  daher ist

         ab          ab
        g   g   = - g   g
         ,d  bc          bc,d

  und

        ab          ab
       g   g     = g   g
        ,j  ab,i    ,i  ab,j

  was aus den Symmetrien der Christoffel-Symbole folgt.

  Die Funktion `simpmetderiv` akzeptiert einen optionalen Parameter stop. Ist dieser vorhanden, stoppt die Funktion nach der ersten erfolgreichen Substitution in einem Produkt. `simpmetderiv` beachtet ferner die Optionsvariable `flipflag`, welche die Ordnung der Indizes kontrolliert.

  Siehe auch `weyl.dem` für Beispiele der Funktionen `simpmetderiv` und `conmetderiv`, die die Vereinfachung des Weyl-Tensors zeigen.

  Beispiel:

      (%i1) load("itensor");
      (%o1)      /share/tensor/itensor.lisp
      (%i2) imetric(g);
      (%o2)                                done
      (%i3) ishow(g([],[a,b])*g([],[b,c])*g([a,b],[],d)*g([b,c],[],e))$
                                   a b  b c
      (%t3)                       g    g    g      g
                                             a b,d  b c,e
      (%i4) ishow(canform(%))$

      errexp1 has improper indices
       -- an error.  Quitting.  To debug this try debugmode(true);
      (%i5) ishow(simpmetderiv(%))$
                                   a b  b c
      (%t5)                       g    g    g      g
                                             a b,d  b c,e
      (%i6) flipflag:not flipflag;
      (%o6)                                true
      (%i7) ishow(simpmetderiv(%th(2)))$
                                     a b  b c
      (%t7)                         g    g    g    g
                                     ,d   ,e   a b  b c
      (%i8) flipflag:not flipflag;
      (%o8)                                false
      (%i9) ishow(simpmetderiv(%th(2),stop))$
                                     a b  b c
      (%t9)                       - g    g    g      g
                                          ,e   a b,d  b c
      (%i10) ishow(contract(%))$
                                          b c
      (%t10)                           - g    g
                                          ,e   c b,d

Funktion: flush1deriv (expr, tensor) ¶

  Setzt alle tensoriellen Größen, die genau einen Ableitungsindex haben, auf den Wert Null.

Optionsvariable: vect_coords ¶

  Standardwert: `false`

  Tensoren können durch Angabe von ganzen Zahlen nach den einzelnen Komponenten abgeleitet werden. In diesem Fall bezeichnen die ganzen Zahlen der Reihe nach die Indizes, die in der Optionsvariablen `vect_coords` abgelegt sind.

#### 20.2.2.4 Tensoren in gekrümmten Räumen

Funktion: imetric (g) ¶
Systemvariable: imetric ¶

  Spezifiziert die Metrik, indem der Variablen `imetric` der Wert `g` zugewiesen wird. Die Eigenschaften für die Verjüngung von Tensoren werden mit den Kommandos `defcon(g)` und `defcon(g, g, kdelta)` initialisiert.

Funktion: idim (n) ¶

  Die Funktion `idim` setzt die Dimension der Metrik zu n. Die Variable `dim` auf den Wert n gesetzt und die antisymmetrischen Eigenschaften des Levi-Civita-Symbols für die Dimension n werden initialisiert.

Funktion: ichr1 ([i, j, k]) ¶

  Gibt das Christoffel-Symbol der ersten Art zurück, das definiert ist als

             (g      + g      - g     )/2 .
               ik,j     jk,i     ij,k

  Um das Christoffel-Symbol für eine spezielle Metrik auszuwerten, muss der Optionsvariablen `imetric` ein Wert zugewiesen werden. Siehe dazu das Beispiel zu `ichr2`.

Funktion: ichr2 ([i, j], [k]) ¶

  Gibt das Christoffel-Symbol der zweiten Art zurück, das definiert ist als

                             ks
         ichr2([i,j],[k]) = g    (g      + g      - g     )/2
                                   is,j     js,i     ij,s

Funktion: icurvature ([i, j, k], [h]) ¶

  Gibt den Riemannschen Krümmungstensor in einer Darstellung mit Christoffel-Symbolen zurück:

                  h             h            h         %1         h
        icurvature     = - ichr2      - ichr2     ichr2    + ichr2
                  i j k         i k,j        %1 j      i k        i j,k
                                  h          %1
                           + ichr2      ichr2
                                  %1 k       i j

Funktion: covdiff (expr, v_1, v_2, …) ¶

  Gibt die kovariante Ableitung des Ausdruck expr nach den Variablen v_i in einer Darstellung mit Christoffel-Symbolen der zweiten Art `ichr2` zurück. Um den erhaltenen Ausdruck auszuwerten, kann das Kommando `ev(expr, ichr2)`.

      (%i1) load("itensor");
      (%o1)      /share/tensor/itensor.lisp
      (%i2) entertensor()$
      Enter tensor name: a;
      Enter a list of the covariant indices: [i,j];
      Enter a list of the contravariant indices: [k];
      Enter a list of the derivative indices: [];

                                            k
      (%t2)                                a
                                            i j

      (%i3) ishow(covdiff(%,s))$
                   k         %1     k         %1     k
      (%t3)     - a     ichr2    - a     ichr2    + a
                   i %1      j s    %1 j      i s    i j,s

                   k     %1
            + ichr2     a
                   %1 s  i j
      (%i4) imetric:g;
      (%o4)                                  g
      (%i5) ishow(ev(%th(2),ichr2))$
               %1 %4  k
              g      a     (g       - g       + g      )
                      i %1   s %4,j    j s,%4    j %4,s
      (%t5) - ------------------------------------------
                                  2
          %1 %3  k
         g      a     (g       - g       + g      )
                 %1 j   s %3,i    i s,%3    i %3,s
       - ------------------------------------------
                             2
          k %2  %1
         g     a    (g        - g        + g       )
                i j   s %2,%1    %1 s,%2    %1 %2,s     k
       + ------------------------------------------- + a
                              2                         i j,s
      (%i6)

Funktion: lorentz_gauge (expr) ¶

  Wendet die Lorenz-Eichung an, indem alle indizierten Größen in expr zu Null gesetzt werden, die einen zu einem kontravarianten Index identischen Ableitungsindex haben.

Funktion: igeodesic_coords (expr, name) ¶

  Bewirkt, dass nicht abgeleitete Christoffel-Symbole und erste Ableitungen des Metriktensors im Ausdruck expr verschwinden. Das Argument name bezeichnet die Metrik name, wenn im Ausdruck expr vorhanden und die Christoffel-Symbole werden mit ichr1 und ichr2 bezeichnet.

  Beispiele:

      (%i1) load("itensor");
      (%o1)      /share/tensor/itensor.lisp
      (%i2) ishow(icurvature([r,s,t],[u]))$

                   u            u         %1         u
      (%t2) - ichr2      - ichr2     ichr2    + ichr2
                   r t,s        %1 s      r t        r s,t

                                                    u         %1
                                             + ichr2     ichr2
                                                    %1 t      r s

      (%i3) ishow(igeodesic_coords(%,ichr2))$
                                       u            u
      (%t3)                       ichr2      - ichr2
                                       r s,t        r t,s
      (%i4) ishow(igeodesic_coords(icurvature([r,s,t],[u]),ichr2)+
                  igeodesic_coords(icurvature([s,t,r],[u]),ichr2)+
                  igeodesic_coords(icurvature([t,r,s],[u]),ichr2))$
                   u            u            u            u
      (%t4) - ichr2      + ichr2      + ichr2      - ichr2
                   t s,r        t r,s        s t,r        s r,t

                                                   u            u
                                            - ichr2      + ichr2
                                                   r t,s        r s,t
      (%i5) canform(%);
      (%o5)                                  0

#### 20.2.2.5 Begleitende Vielbeine

Maxima now has the ability to perform calculations using moving frames. These can be orthonormal frames (tetrads, vielbeins) or an arbitrary frame.

To use frames, you must first set `iframe_flag` to `true`. This causes the Christoffel-symbols, `ichr1` and `ichr2`, to be replaced by the more general frame connection coefficients `icc1` and `icc2` in calculations. Speficially, the behavior of `covdiff` and `icurvature` is changed.

The frame is defined by two tensors: the inverse frame field (`ifri`, the dual basis tetrad), and the frame metric `ifg`. The frame metric is the identity matrix for orthonormal frames, or the Lorentz metric for orthonormal frames in Minkowski spacetime. The inverse frame field defines the frame base (unit vectors). Contraction properties are defined for the frame field and the frame metric.

When `iframe_flag` is true, many `itensor` expressions use the frame metric `ifg` instead of the metric defined by `imetric` for raising and lowerind indices.

IMPORTANT: Setting the variable `iframe_flag` to `true` does NOT undefine the contraction properties of a metric defined by a call to `defcon` or `imetric`. If a frame field is used, it is best to define the metric by assigning its name to the variable `imetric` and NOT invoke the `imetric` function.

Maxima uses these two tensors to define the frame coefficients (`ifc1` and `ifc2`) which form part of the connection coefficients (`icc1` and `icc2`), as the following example demonstrates:

    (%i1) load("itensor");
    (%o1)      /share/tensor/itensor.lisp
    (%i2) iframe_flag:true;
    (%o2)                                true
    (%i3) ishow(covdiff(v([],[i]),j))$
                                   i        i     %1
    (%t3)                         v   + icc2     v
                                   ,j       %1 j
    (%i4) ishow(ev(%,icc2))$
                                   %1     i       i
    (%t4)                         v   ifc2     + v
                                          %1 j    ,j
    (%i5) ishow(ev(%,ifc2))$
                              %1    i %2                i
    (%t5)                    v   ifg     ifc1        + v
                                             %1 j %2    ,j
    (%i6) ishow(ev(%,ifc1))$
                %1    i %2
               v   ifg     (ifb        - ifb        + ifb       )
                               j %2 %1      %2 %1 j      %1 j %2     i
    (%t6)      -------------------------------------------------- + v
                                       2                             ,j
    (%i7) ishow(ifb([a,b,c]))$
                                                       %3    %4
    (%t7)               (ifri        - ifri       ) ifr   ifr
                             a %3,%4       a %4,%3     b     c

An alternate method is used to compute the frame bracket (`ifb`) if the `iframe_bracket_form` flag is set to `false`:

    (%i8) block([iframe_bracket_form:false],ishow(ifb([a,b,c])))$
                                    %6    %5        %5      %6
    (%t8)              ifri     (ifr   ifr     - ifr     ifr  )
                           a %5     b     c,%6      b,%6    c

Optionsvariable: iframe_flag ¶

  Standardwert: `false`

  To use frames, you must first set `iframe_flag` to `true`. This causes the Christoffel-symbols, `ichr1` and `ichr2`, to be replaced by the more general frame connection coefficients `icc1` and `icc2` in calculations. Speficially, the behavior of `covdiff` and `icurvature` is changed.

  The frame is defined by two tensors: the inverse frame field (`ifri`, the dual basis tetrad), and the frame metric `ifg`. The frame metric is the identity matrix for orthonormal frames, or the Lorentz metric for orthonormal frames in Minkowski spacetime. The inverse frame field defines the frame base (unit vectors). Contraction properties are defined for the frame field and the frame metric.

  When `iframe_flag` is true, many `itensor` expressions use the frame metric `ifg` instead of the metric defined by `imetric` for raising and lowerind indices.

  IMPORTANT: Setting the variable `iframe_flag` to `true` does NOT undefine the contraction properties of a metric defined by a call to `defcon` or `imetric`. If a frame field is used, it is best to define the metric by assigning its name to the variable `imetric` and NOT invoke the `imetric` function.

Function: iframes () ¶

  Since in this version of Maxima, contraction identities for `ifr` and `ifri` are always defined, as is the frame bracket (`ifb`), this function does nothing.

Variable: ifb ¶

  The frame bracket. The contribution of the frame metric to the connection coefficients is expressed using the frame bracket:

                - ifb      + ifb      + ifb
                     c a b      b c a      a b c
      ifc1    = --------------------------------
          abc                  2

  The frame bracket itself is defined in terms of the frame field and frame metric. Two alternate methods of computation are used depending on the value of `frame_bracket_form`. If true (the default) or if the `itorsion_flag` is `true`:

                d      e                                      f
      ifb =  ifr    ifr   (ifri      - ifri      - ifri    itr   )
         abc    b      c       a d,e       a e,d       a f    d e

  Otherwise:

                   e      d        d      e
      ifb    = (ifr    ifr    - ifr    ifr   ) ifri
         abc       b      c,e      b,e    c        a d

Variable: icc1 ¶

  Connection coefficients of the first kind. In `itensor`, defined as

      icc1    = ichr1    - ikt1    - inmc1
          abc        abc       abc        abc

  In this expression, if `iframe_flag` is true, the Christoffel-symbol `ichr1` is replaced with the frame connection coefficient `ifc1`. If `itorsion_flag` is `false`, `ikt1` will be omitted. It is also omitted if a frame base is used, as the torsion is already calculated as part of the frame bracket. Lastly, of `inonmet_flag` is `false`, `inmc1` will not be present.

Variable: icc2 ¶

  Connection coefficients of the second kind. In `itensor`, defined as

          c         c        c         c
      icc2   = ichr2   - ikt2   - inmc2
          ab        ab       ab        ab

  In this expression, if `iframe_flag` is true, the Christoffel-symbol `ichr2` is replaced with the frame connection coefficient `ifc2`. If `itorsion_flag` is `false`, `ikt2` will be omitted. It is also omitted if a frame base is used, as the torsion is already calculated as part of the frame bracket. Lastly, of `inonmet_flag` is `false`, `inmc2` will not be present.

Variable: ifc1 ¶

  Frame coefficient of the first kind (also known as Ricci-rotation coefficients.) This tensor represents the contribution of the frame metric to the connection coefficient of the first kind. Defined as:

                - ifb      + ifb      + ifb
                     c a b      b c a      a b c
      ifc1    = --------------------------------
          abc                   2

Variable: ifc2 ¶

  Frame coefficient of the first kind. This tensor represents the contribution of the frame metric to the connection coefficient of the first kind. Defined as a permutation of the frame bracket (`ifb`) with the appropriate indices raised and lowered as necessary:

          c       cd
      ifc2   = ifg   ifc1
          ab             abd

Variable: ifr ¶

  The frame field. Contracts with the inverse frame field (`ifri`) to form the frame metric (`ifg`).

Variable: ifri ¶

  The inverse frame field. Specifies the frame base (dual basis vectors). Along with the frame metric, it forms the basis of all calculations based on frames.

Variable: ifg ¶

  The frame metric. Defaults to `kdelta`, but can be changed using `components`.

Variable: ifgi ¶

  The inverse frame metric. Contracts with the frame metric (`ifg`) to `kdelta`.

Option variable: iframe_bracket_form ¶

  Default value: `true`

  Specifies how the frame bracket (`ifb`) is computed.

#### 20.2.2.6 Torsion und Nichtmetrizität

Maxima can now take into account torsion and nonmetricity. When the flag `itorsion_flag` is set to `true`, the contribution of torsion is added to the connection coefficients. Similarly, when the flag `inonmet_flag` is true, nonmetricity components are included.

Variable: inm ¶

  The nonmetricity vector. Conformal nonmetricity is defined through the covariant derivative of the metric tensor. Normally zero, the metric tensor’s covariant derivative will evaluate to the following when `inonmet_flag` is set to `true`:

      g     =- g  inm
       ij;k     ij   k

Variable: inmc1 ¶

  Covariant permutation of the nonmetricity vector components. Defined as

                 g   inm  - inm  g   - g   inm
                  ab    c      a  bc    ac    b
      inmc1    = ------------------------------
           abc                 2

  (Substitute `ifg` in place of `g` if a frame metric is used.)

Variable: inmc2 ¶

  Contravariant permutation of the nonmetricity vector components. Used in the connection coefficients if `inonmet_flag` is `true`. Defined as:

                            c         c         cd
                -inm  kdelta  - kdelta  inm  + g   inm  g
           c        a       b         a    b          d  ab
      inmc2   = -------------------------------------------
           ab                        2

  (Substitute `ifg` in place of `g` if a frame metric is used.)

Variable: ikt1 ¶

  Covariant permutation of the torsion tensor (also known as contorsion). Defined as:

                        d           d       d
                -g   itr  - g    itr   - itr   g
                  ad    cb    bd    ca      ab  cd
      ikt1    = ----------------------------------
          abc                   2

  (Substitute `ifg` in place of `g` if a frame metric is used.)

Variable: ikt2 ¶

  Contravariant permutation of the torsion tensor (also known as contorsion). Defined as:

          c     cd
      ikt2   = g   ikt1
          ab           abd

  (Substitute `ifg` in place of `g` if a frame metric is used.)

Variable: itr ¶

  The torsion tensor. For a metric with torsion, repeated covariant differentiation on a scalar function will not commute, as demonstrated by the following example:

      (%i1) load("itensor");
      (%o1)      /share/tensor/itensor.lisp
      (%i2) imetric:g;
      (%o2)                                  g
      (%i3) covdiff( covdiff( f( [], []), i), j)
                            - covdiff( covdiff( f( [], []), j), i)$
      (%i4) ishow(%)$
                                         %4              %2
      (%t4)                    f    ichr2    - f    ichr2
                                ,%4      j i    ,%2      i j
      (%i5) canform(%);
      (%o5)                                  0
      (%i6) itorsion_flag:true;
      (%o6)                                true
      (%i7) covdiff( covdiff( f( [], []), i), j)
                            - covdiff( covdiff( f( [], []), j), i)$
      (%i8) ishow(%)$
                                 %8             %6
      (%t8)             f    icc2    - f    icc2    - f     + f
                         ,%8     j i    ,%6     i j    ,j i    ,i j
      (%i9) ishow(canform(%))$
                                         %1             %1
      (%t9)                     f    icc2    - f    icc2
                                 ,%1     j i    ,%1     i j
      (%i10) ishow(canform(ev(%,icc2)))$

                                         %1             %1
      (%t10)                    f    ikt2    - f    ikt2
                                 ,%1     i j    ,%1     j i

      (%i11) ishow(canform(ev(%,ikt2)))$
                            %2 %1                    %2 %1
      (%t11)          f    g      ikt1       - f    g      ikt1
                       ,%2            i j %1    ,%2            j i %1
      (%i12) ishow(factor(canform(rename(expand(ev(%,ikt1))))))$
                                 %3 %2            %1       %1
                           f    g      g      (itr    - itr   )
                            ,%3         %2 %1     j i      i j
      (%t12)               ------------------------------------
                                            2
      (%i13) decsym(itr,2,1,[anti(all)],[]);
      (%o13)                               done
      (%i14) defcon(g,g,kdelta);
      (%o14)                               done
      (%i15) subst(g,nounify(g),%th(3))$
      (%i16) ishow(canform(contract(%)))$
                                                 %1
      (%t16)                           - f    itr
                                          ,%1    i j

#### 20.2.2.7 Graßmann-Algebra

The `itensor` package can perform operations on totally antisymmetric covariant tensor fields. A totally antisymmetric tensor field of rank (0,L) corresponds with a differential L-form. On these objects, a multiplication operation known as the exterior product, or wedge product, is defined.

Unfortunately, not all authors agree on the definition of the wedge product. Some authors prefer a definition that corresponds with the notion of antisymmetrization: in these works, the wedge product of two vector fields, for instance, would be defined as

                a a  - a a
                 i j    j i
     a  /\ a  = -----------
      i     j        2

More generally, the product of a p-form and a q-form would be defined as

                           1     k1..kp l1..lq
    A       /\ B       = ------ D              A       B
     i1..ip     j1..jq   (p+q)!  i1..ip j1..jq  k1..kp  l1..lq

where `D` stands for the Kronecker-delta.

Other authors, however, prefer a “geometric” definition that corresponds with the notion of the volume element:

    a  /\ a  = a a  - a a
     i     j    i j    j i

and, in the general case

                           1    k1..kp l1..lq
    A       /\ B       = ----- D              A       B
     i1..ip     j1..jq   p! q!  i1..ip j1..jq  k1..kp  l1..lq

Since `itensor` is a tensor algebra package, the first of these two definitions appears to be the more natural one. Many applications, however, utilize the second definition. To resolve this dilemma, a flag has been implemented that controls the behavior of the wedge product: if `igeowedge_flag` is `false` (the default), the first, "tensorial" definition is used, otherwise the second, "geometric" definition will be applied.

Operator: ~ ¶

  The wedge product operator is denoted by the tilde `~`. This is a binary operator. Its arguments should be expressions involving scalars, covariant tensors of rank one, or covariant tensors of rank `l` that have been declared antisymmetric in all covariant indices.

  The behavior of the wedge product operator is controlled by the `igeowedge_flag` flag, as in the following example:

      (%i1) load("itensor");
      (%o1)      /share/tensor/itensor.lisp
      (%i2) ishow(a([i])~b([j]))$
                                       a  b  - b  a
                                        i  j    i  j
      (%t2)                            -------------
                                             2
      (%i3) decsym(a,2,0,[anti(all)],[]);
      (%o3)                                done
      (%i4) ishow(a([i,j])~b([k]))$
                                a    b  + b  a    - a    b
                                 i j  k    i  j k    i k  j
      (%t4)                     ---------------------------
                                             3
      (%i5) igeowedge_flag:true;
      (%o5)                                true
      (%i6) ishow(a([i])~b([j]))$
      (%t6)                            a  b  - b  a
                                        i  j    i  j
      (%i7) ishow(a([i,j])~b([k]))$
      (%t7)                     a    b  + b  a    - a    b
                                 i j  k    i  j k    i k  j

Operator: | ¶

  The vertical bar `|` denotes the "contraction with a vector" binary operation. When a totally antisymmetric covariant tensor is contracted with a contravariant vector, the result is the same regardless which index was used for the contraction. Thus, it is possible to define the contraction operation in an index-free manner.

  In the `itensor` package, contraction with a vector is always carried out with respect to the first index in the literal sorting order. This ensures better simplification of expressions involving the `|` operator. For instance:

      (%i1) load("itensor");
      (%o1)      /share/tensor/itensor.lisp
      (%i2) decsym(a,2,0,[anti(all)],[]);
      (%o2)                                done
      (%i3) ishow(a([i,j],[])|v)$
                                          %1
      (%t3)                              v   a
                                              %1 j
      (%i4) ishow(a([j,i],[])|v)$
                                           %1
      (%t4)                             - v   a
                                               %1 j

  Note that it is essential that the tensors used with the `|` operator be declared totally antisymmetric in their covariant indices. Otherwise, the results will be incorrect.

Function: extdiff (expr, i) ¶

  Computes the exterior derivative of expr with respect to the index i. The exterior derivative is formally defined as the wedge product of the partial derivative operator and a differential form. As such, this operation is also controlled by the setting of `igeowedge_flag`. For instance:

      (%i1) load("itensor");
      (%o1)      /share/tensor/itensor.lisp
      (%i2) ishow(extdiff(v([i]),j))$
                                        v    - v
                                         j,i    i,j
      (%t2)                             -----------
                                             2
      (%i3) decsym(a,2,0,[anti(all)],[]);
      (%o3)                                done
      (%i4) ishow(extdiff(a([i,j]),k))$
                                 a      - a      + a
                                  j k,i    i k,j    i j,k
      (%t4)                      ------------------------
                                            3
      (%i5) igeowedge_flag:true;
      (%o5)                                true
      (%i6) ishow(extdiff(v([i]),j))$
      (%t6)                             v    - v
                                         j,i    i,j
      (%i7) ishow(extdiff(a([i,j]),k))$
      (%t7)                    - (a      - a      + a     )
                                   k j,i    k i,j    j i,k

Function: hodge (expr) ¶

  Compute the Hodge-dual of expr. For instance:

      (%i1) load("itensor");
      (%o1)      /share/tensor/itensor.lisp
      (%i2) imetric(g);
      (%o2)                            done
      (%i3) idim(4);
      (%o3)                            done
      (%i4) icounter:100;
      (%o4)                             100
      (%i5) decsym(A,3,0,[anti(all)],[])$

      (%i6) ishow(A([i,j,k],[]))$
      (%t6)                           A
                                       i j k
      (%i7) ishow(canform(hodge(%)))$

                                %1 %2 %3 %4
                     levi_civita            g        A
                                             %1 %102  %2 %3 %4
      (%t7)          -----------------------------------------
                                         6

      (%i8) ishow(canform(hodge(%)))$
                       %1 %2 %3 %8            %4 %5 %6 %7
      (%t8) levi_civita            levi_civita            g
                                                           %1 %106
                                   g        g        g      A         /6
                                    %2 %107  %3 %108  %4 %8  %5 %6 %7
      (%i9) lc2kdt(%)$

      (%i10) %,kdelta$

      (%i11) ishow(canform(contract(expand(%))))$
      (%t11)                     - A
                                    %106 %107 %108

Option variable: igeowedge_flag ¶

  Default value: `false`

  Controls the behavior of the wedge product and exterior derivative. When set to `false` (the default), the notion of differential forms will correspond with that of a totally antisymmetric covariant tensor field. When set to `true`, differential forms will agree with the notion of the volume element.

#### 20.2.2.8 Exportiere als TeX

The `itensor` package provides limited support for exporting tensor expressions to TeX. Since `itensor` expressions appear as function calls, the regular Maxima `tex` command will not produce the expected output. You can try instead the `tentex` command, which attempts to translate tensor expressions into appropriately indexed TeX objects.

Function: tentex (expr) ¶

  To use the `tentex` function, you must first load `tentex`, as in the following example:

      (%i1) load("itensor")$
      (%i2) load("tentex")$
      (%i3) idummyx:m;
      (%o3)                                  m
      (%i4) ishow(icurvature([j,k,l],[i]))$

                  m1       i           m1       i           i
      (%t4)  ichr2    ichr2     - ichr2    ichr2     - ichr2
                  j k      m1 l        j l      m1 k        j l,k

                                                            i
                                                     + ichr2
                                                            j k,l

      (%i5) tentex(%)$
      $$\Gamma_{j\,k}^{m_1}\,\Gamma_{l\,m_1}^{i}-\Gamma_{j\,l}^{m_1}\,
       \Gamma_{k\,m_1}^{i}-\Gamma_{j\,l,k}^{i}+\Gamma_{j\,k,l}^{i}$$

  Note the use of the `idummyx` assignment, to avoid the appearance of the percent sign in the TeX expression, which may lead to compile errors.

  NB: This version of the `tentex` function is somewhat experimental.

#### 20.2.2.9 Schnittstelle zum Paket CTENSOR

Das Paket `itensor` ermöglicht die Generierung von Maxima-Code, der im Kontext des Paketes `ctensor` ausgeführt werden kann. Die Funktion `ic_convert` erzeugt den Maxima-Code.

Funktion: ic_convert (eqn) ¶

  Konvertiert eine `itensor`-Gleichung eqn in einen `ctensor`-Ausdruck. Implizite Summen über Dummy-Indizes werden explizit ausgeführt und indizierte Größen werden in Arrays umgewandelt. Die Indizes der Arrays sind in der Reihenfolge der kovarianten und dann der kontravarianten Indizes der indizierte Größe. Die Ableitung einer indizierten Größe wird durch die Substantivform der Ableitung `diff` nach der Variablen `ct_coords` ersetzt, die den Index der Ableitung erhält. Die Christoffel-Symbole `ichr1` und `ichr2` werden zu den Funktionen `lcs` und `mcs` transformiert. Hat `metricconvert` den Wert `true`, dann wird der Metriktensor mit zwei kovarianten Indizes durch `lg` und mit zwei kontravarianten Indizes durch `ug` ersetzt. Weiterhin werden `do`-Schleifen für die Summation über die freien Indizes eingeführt.

  Beispiele:

      (%i1) load("itensor");
      (%o1)      /share/tensor/itensor.lisp
      (%i2) eqn:ishow(t([i,j],[k])=f([],[])*g([l,m],[])*a([],[m],j)
            *b([i],[l,k]))$
                                   k        m   l k
      (%t2)                       t    = f a   b    g
                                   i j      ,j  i    l m
      (%i3) ic_convert(eqn);

      (%o3) for i thru dim do (for j thru dim do (
             for k thru dim do
              t        : f sum(sum(diff(a , ct_coords ) b
               i, j, k                   m           j   i, l, k

       g    , l, 1, dim), m, 1, dim)))
        l, m

      (%i4) imetric(g);
      (%o4)                                done
      (%i5) metricconvert:true;
      (%o5)                                true
      (%i6) ic_convert(eqn);

      (%o6) for i thru dim do (for j thru dim do (
             for k thru dim do
              t        : f sum(sum(diff(a , ct_coords ) b
               i, j, k                   m           j   i, l, k

       lg    , l, 1, dim), m, 1, dim)))
         l, m

#### 20.2.2.10 Reservierte Bezeichner

Die folgenden Maxima Bezeichner werden im Paket `itensor` intern genutzt und sollten vom Nutzer nicht umdefiniert werden.

      Keyword    Comments
      ------------------------------------------
      indices2() Internal version of indices()
      conti      Lists contravariant indices
      covi       Lists covariant indices of an indexed object
      deri       Lists derivative indices of an indexed object
      name       Returns the name of an indexed object
      concan
      irpmon
      lc0
      _lc2kdt0
      _lcprod
      _extlc

### 20.3 Paket CTENSOR

#### 20.3.1 Einführung in CTENSOR

`ctensor` ist ein Paket, um mit den Komponenten eines Tensors zu rechnen. Das Paket wird mit dem Kommando `load("ctensor")` geladen. Zu Beginn muss das Paket mit dem Kommando `csetup` initialisiert werden. Als erstes wird die Anzahl der Dimensionen angegeben. Werden `2`, `3` oder `4` Dimensionen angegeben, dann erhalten die Koordinaten standardmäßig die Bezeichnungen `[x,y]`, `[x,y,z]` oder `[x,y,z,t]`. Diese Bezeichnungen können geändert werden, indem der Optionsvariablen `ct_coords` eine neue Liste mit den gewünschten Bezeichnungen zugewiesen wird.

Danach wird eine Metrik eingegeben oder aus einer Datei geladen. Die Metrik wird in der Matrix `lg` gespeichert. Maxima berechnet die inverse der Metrik und speichert diese in der Matrix `ug` ab. Maxima bietet die Option an, alle Rechnungen in einer Reihenentwicklung auszuführen.

Die folgende Sitzung zeigt ein Beispiel für die Initialisierung einer sphärischen, symmetrischen Metrik, wie sie zum Beispiel im Falle der Einsteinschen Vakuumgleichen verwendet wird.

Beispiel:

    (%i1) load("ctensor");
    (%o1)      /share/tensor/ctensor.mac
    (%i2) csetup();
    Enter the dimension of the coordinate system:
    4;
    Do you wish to change the coordinate names?
    n;
    Do you want to
    1. Enter a new metric?

    2. Enter a metric from a file?

    3. Approximate a metric with a Taylor series?
    1;

    Is the matrix  1. Diagonal  2. Symmetric  3. Antisymmetric  4. General
    Answer 1, 2, 3 or 4
    1;
    Row 1 Column 1:
    a;
    Row 2 Column 2:
    x^2;
    Row 3 Column 3:
    x^2*sin(y)^2;
    Row 4 Column 4:
    -d;

    Matrix entered.
    Enter functional dependencies with the DEPENDS function or 'N' if none
    depends([a,d],x);
    Do you wish to see the metric?
    y;
                              [ a  0       0        0  ]
                              [                        ]
                              [     2                  ]
                              [ 0  x       0        0  ]
                              [                        ]
                              [         2    2         ]
                              [ 0  0   x  sin (y)   0  ]
                              [                        ]
                              [ 0  0       0       - d ]
    (%o2)                                done
    (%i3) christof(mcs);
                                                a
                                                 x
    (%t3)                          mcs        = ---
                                      1, 1, 1   2 a

                                                 1
    (%t4)                           mcs        = -
                                       1, 2, 2   x

                                                 1
    (%t5)                           mcs        = -
                                       1, 3, 3   x

                                                d
                                                 x
    (%t6)                          mcs        = ---
                                      1, 4, 4   2 d

                                                  x
    (%t7)                          mcs        = - -
                                      2, 2, 1     a

                                               cos(y)
    (%t8)                         mcs        = ------
                                     2, 3, 3   sin(y)

                                                   2
                                              x sin (y)
    (%t9)                      mcs        = - ---------
                                  3, 3, 1         a

    (%t10)                   mcs        = - cos(y) sin(y)
                                3, 3, 2

                                                d
                                                 x
    (%t11)                         mcs        = ---
                                      4, 4, 1   2 a
    (%o11)                               done

#### 20.3.2 Funktionen und Variablen für CTENSOR

#### 20.3.2.1 Initialisierung

Funktion: csetup () ¶

  Mit der Funktion `csetup` wird das Paket `ctensor` initialisiert. Vom Nutzer werden die Angaben zu einer Metrik abgefragt. Für ein Beispiel siehe Einführung in CTENSOR.

Funktion: cmetric (dis) ¶
Funktion: cmetric () ¶

  Die Funktion `cmetric` berechnet die inverse der Metrik und führt weitere Initialisierungen für die Rechnung mit Tensoren aus.

  Hat die Optionsvariable `cframe_flag` den Wert `false`, wird die inverse Metrik mit der vom Nutzer angegebenen Metrik berechnet, die in der Matrix `lg` enthalten ist, und in der Matrix `ug` abgespeichert. Die Determinante der Metrik wird in der Variablen `gdet` abgelegt. Ist die Metrik diagonal wird die Variable `diagmetric` entsprechend gesetzt. Hat das optionale Argument dis einen von `false` verschiedenen Wert wird die inverse Metrik ausgegeben.

  Hat die Optionsvariable `cframe_flag` den Wert `true`, erwartet `cmetric`, dass die Matrizen `lfg` für die Metrik des bewegten Bezugssystems und `fri` für die inverse dieser Metrik definiert sind. Mit diesen Matrizen berechnet `cmetric` dann die Werte der Matrizen `fr` und die inverse `ufg`.

Function: ct_coordsys (coordinate_system, extra_arg) ¶
Function: ct_coordsys (coordinate_system) ¶

  Sets up a predefined coordinate system and metric. The argument coordinate_system can be one of the following symbols:

       SYMBOL             Dim Coordinates     Description/comments
       ------------------------------------------------------------------
       cartesian2d           2  [x,y]             Cartesian 2D coordinate
                                                  system
       polar                 2  [r,phi]           Polar coordinate system
       elliptic              2  [u,v]             Elliptic coord. system
       confocalelliptic      2  [u,v]             Confocal elliptic
                                                  coordinates
       bipolar               2  [u,v]             Bipolar coord. system
       parabolic             2  [u,v]             Parabolic coord. system
       cartesian3d           3  [x,y,z]           Cartesian 3D coordinate
                                                  system
       polarcylindrical      3  [r,theta,z]       Polar 2D with
                                                  cylindrical z
       ellipticcylindrical   3  [u,v,z]           Elliptic 2D with
                                                  cylindrical z
       confocalellipsoidal   3  [u,v,w]           Confocal ellipsoidal
       bipolarcylindrical    3  [u,v,z]           Bipolar 2D with
                                                  cylindrical z
       paraboliccylindrical  3  [u,v,z]           Parabolic 2D with
                                                  cylindrical z
       paraboloidal          3  [u,v,phi]         Paraboloidal coords.
       conical               3  [u,v,w]           Conical coordinates
       toroidal              3  [u,v,phi]         Toroidal coordinates
       spherical             3  [r,theta,phi]     Spherical coord. system
       oblatespheroidal      3  [u,v,phi]         Oblate spheroidal
                                                  coordinates
       oblatespheroidalsqrt  3  [u,v,phi]
       prolatespheroidal     3  [u,v,phi]         Prolate spheroidal
                                                  coordinates
       prolatespheroidalsqrt 3  [u,v,phi]
       ellipsoidal           3  [r,theta,phi]     Ellipsoidal coordinates
       cartesian4d           4  [x,y,z,t]         Cartesian 4D coordinate
                                                  system
       spherical4d           4  [r,theta,eta,phi] Spherical 4D coordinate
                                                  system
       exteriorschwarzschild 4  [t,r,theta,phi]   Schwarzschild metric
       interiorschwarzschild 4  [t,z,u,v]         Interior Schwarzschild
                                                  metric
       kerr_newman           4  [t,r,theta,phi]   Charged axially
                                                  symmetric metric

  `coordinate_system` can also be a list of transformation functions, followed by a list containing the coordinate variables. For instance, you can specify a spherical metric as follows:

      (%i1) load("ctensor");
      (%o1)       /share/tensor/ctensor.mac
      (%i2) ct_coordsys([r*cos(theta)*cos(phi),r*cos(theta)*sin(phi),
                         r*sin(theta),[r,theta,phi]]);
      (%o2)                                done
      (%i3) lg:trigsimp(lg);
                                 [ 1  0         0        ]
                                 [                       ]
                                 [     2                 ]
      (%o3)                      [ 0  r         0        ]
                                 [                       ]
                                 [         2    2        ]
                                 [ 0  0   r  cos (theta) ]
      (%i4) ct_coords;
      (%o4)                           [r, theta, phi]
      (%i5) dim;
      (%o5)                                  3

  Transformation functions can also be used when `cframe_flag` is `true`:

      (%i1) load("ctensor");
      (%o1)       /share/tensor/ctensor.mac
      (%i2) cframe_flag:true;
      (%o2)                                true
      (%i3) ct_coordsys([r*cos(theta)*cos(phi),r*cos(theta)*sin(phi),
            r*sin(theta),[r,theta,phi]]);
      (%o3)                                done
      (%i4) fri;
      (%o4)
       [cos(phi)cos(theta) -cos(phi) r sin(theta) -sin(phi) r cos(theta)]
       [                                                                ]
       [sin(phi)cos(theta) -sin(phi) r sin(theta)  cos(phi) r cos(theta)]
       [                                                                ]
       [    sin(theta)           r cos(theta)                0          ]

      (%i5) cmetric();
      (%o5)                                false
      (%i6) lg:trigsimp(lg);
                                 [ 1  0         0        ]
                                 [                       ]
                                 [     2                 ]
      (%o6)                      [ 0  r         0        ]
                                 [                       ]
                                 [         2    2        ]
                                 [ 0  0   r  cos (theta) ]

  The optional argument extra_arg can be any one of the following:

  `cylindrical` tells `ct_coordsys` to attach an additional cylindrical coordinate.

  `minkowski` tells `ct_coordsys` to attach an additional coordinate with negative metric signature.

  `all` tells `ct_coordsys` to call `cmetric` and `christof(false)` after setting up the metric.

  If the global variable `verbose` is set to `true`, `ct_coordsys` displays the values of `dim`, `ct_coords`, and either `lg` or `lfg` and `fri`, depending on the value of `cframe_flag`.

Function: init_ctensor () ¶

  Initializes the `ctensor` package.

  The `init_ctensor` function reinitializes the `ctensor` package. It removes all arrays and matrices used by `ctensor`, resets all flags, resets `dim` to 4, and resets the frame metric to the Lorentz-frame.

#### 20.3.2.2 The tensors of curved space

The main purpose of the `ctensor` package is to compute the tensors of curved space(time), most notably the tensors used in general relativity.

When a metric base is used, `ctensor` can compute the following tensors:

     lg  -- ug
       \      \
        lcs -- mcs -- ric -- uric
                  \      \       \
                   \      tracer - ein -- lein
                    \
                     riem -- lriem -- weyl
                         \
                          uriem

`ctensor` can also work using moving frames. When `cframe_flag` is set to `true`, the following tensors can be calculated:

     lfg -- ufg
         \
     fri -- fr -- lcs -- mcs -- lriem -- ric -- uric
          \                       |  \      \       \
           lg -- ug               |   weyl   tracer - ein -- lein
                                  |\
                                  | riem
                                  |
                                  \uriem

Function: christof (dis) ¶

  A function in the `ctensor` (component tensor) package. It computes the Christoffel symbols of both kinds. The argument dis determines which results are to be immediately displayed. The Christoffel symbols of the first and second kinds are stored in the arrays `lcs[i,j,k]` and `mcs[i,j,k]` respectively and defined to be symmetric in the first two indices. If the argument to `christof` is `lcs` or `mcs` then the unique non-zero values of `lcs[i,j,k]` or `mcs[i,j,k]`, respectively, will be displayed. If the argument is `all` then the unique non-zero values of `lcs[i,j,k]` and `mcs[i,j,k]` will be displayed. If the argument is `false` then the display of the elements will not occur. The array elements `mcs[i,j,k]` are defined in such a manner that the final index is contravariant.

Function: ricci (dis) ¶

  A function in the `ctensor` (component tensor) package. `ricci` computes the covariant (symmetric) components `ric[i,j]` of the Ricci tensor. If the argument dis is `true`, then the non-zero components are displayed.

Function: uricci (dis) ¶

  This function first computes the covariant components `ric[i,j]` of the Ricci tensor. Then the mixed Ricci tensor is computed using the contravariant metric tensor. If the value of the argument dis is `true`, then these mixed components, `uric[i,j]` (the index `i` is covariant and the index `j` is contravariant), will be displayed directly. Otherwise, `ricci(false)` will simply compute the entries of the array `uric[i,j]` without displaying the results.

Function: scurvature () ¶

  Returns the scalar curvature (obtained by contracting the Ricci tensor) of the Riemannian manifold with the given metric.

Function: einstein (dis) ¶

  A function in the `ctensor` (component tensor) package. `einstein` computes the mixed Einstein tensor after the Christoffel symbols and Ricci tensor have been obtained (with the functions `christof` and `ricci`). If the argument dis is `true`, then the non-zero values of the mixed Einstein tensor `ein[i,j]` will be displayed where `j` is the contravariant index. The variable `rateinstein` will cause the rational simplification on these components. If `ratfac` is `true` then the components will also be factored.

Function: leinstein (dis) ¶

  Covariant Einstein-tensor. `leinstein` stores the values of the covariant Einstein tensor in the array `lein`. The covariant Einstein-tensor is computed from the mixed Einstein tensor `ein` by multiplying it with the metric tensor. If the argument dis is `true`, then the non-zero values of the covariant Einstein tensor are displayed.

Function: riemann (dis) ¶

  A function in the `ctensor` (component tensor) package. `riemann` computes the Riemann curvature tensor from the given metric and the corresponding Christoffel symbols. The following index conventions are used:

                      l      _l       _l       _l   _m    _l   _m
       R[i,j,k,l] =  R    = |      - |      + |    |   - |    |
                      ijk     ij,k     ik,j     mk   ij    mj   ik

  This notation is consistent with the notation used by the `itensor` package and its `icurvature` function. If the optional argument dis is `true`, the non-zero components `riem[i,j,k,l]` will be displayed. As with the Einstein tensor, various switches set by the user control the simplification of the components of the Riemann tensor. If `ratriemann` is `true`, then rational simplification will be done. If `ratfac` is `true` then each of the components will also be factored.

  If the variable `cframe_flag` is `false`, the Riemann tensor is computed directly from the Christoffel-symbols. If `cframe_flag` is `true`, the covariant Riemann-tensor is computed first from the frame field coefficients.

Function: lriemann (dis) ¶

  Covariant Riemann-tensor (`lriem[]`).

  Computes the covariant Riemann-tensor as the array `lriem`. If the argument dis is `true`, unique nonzero values are displayed.

  If the variable `cframe_flag` is `true`, the covariant Riemann tensor is computed directly from the frame field coefficients. Otherwise, the (3,1) Riemann tensor is computed first.

  For information on index ordering, see `riemann`.

Function: uriemann (dis) ¶

  Computes the contravariant components of the Riemann curvature tensor as array elements `uriem[i,j,k,l]`. These are displayed if dis is `true`.

Function: rinvariant () ¶

  Forms the Kretchmann-invariant (`kinvariant`) obtained by contracting the tensors

      lriem[i,j,k,l]*uriem[i,j,k,l].

  This object is not automatically simplified since it can be very large.

Function: weyl (dis) ¶

  Computes the Weyl conformal tensor. If the argument dis is `true`, the non-zero components `weyl[i,j,k,l]` will be displayed to the user. Otherwise, these components will simply be computed and stored. If the switch `ratweyl` is set to `true`, then the components will be rationally simplified; if `ratfac` is `true` then the results will be factored as well.

#### 20.3.2.3 Taylor series expansion

The `ctensor` package has the ability to truncate results by assuming that they are Taylor-series approximations. This behavior is controlled by the `ctayswitch` variable; when set to true, `ctensor` makes use internally of the function `ctaylor` when simplifying results.

The `ctaylor` function is invoked by the following `ctensor` functions:

        Function     Comments
        ---------------------------------
        christof()   For mcs only
        ricci()
        uricci()
        einstein()
        riemann()
        weyl()
        checkdiv()

Function: ctaylor () ¶

  The `ctaylor` function truncates its argument by converting it to a Taylor-series using `taylor`, and then calling `ratdisrep`. This has the combined effect of dropping terms higher order in the expansion variable `ctayvar`. The order of terms that should be dropped is defined by `ctaypov`; the point around which the series expansion is carried out is specified in `ctaypt`.

  As an example, consider a simple metric that is a perturbation of the Minkowski metric. Without further restrictions, even a diagonal metric produces expressions for the Einstein tensor that are far too complex:

      (%i1) load("ctensor");
      (%o1)       /share/tensor/ctensor.mac
      (%i2) ratfac:true;
      (%o2)                                true
      (%i3) derivabbrev:true;
      (%o3)                                true
      (%i4) ct_coords:[t,r,theta,phi];
      (%o4)                         [t, r, theta, phi]
      (%i5) lg:matrix([-1,0,0,0],[0,1,0,0],[0,0,r^2,0],
                      [0,0,0,r^2*sin(theta)^2]);
                              [ - 1  0  0         0        ]
                              [                            ]
                              [  0   1  0         0        ]
                              [                            ]
      (%o5)                   [          2                 ]
                              [  0   0  r         0        ]
                              [                            ]
                              [              2    2        ]
                              [  0   0  0   r  sin (theta) ]
      (%i6) h:matrix([h11,0,0,0],[0,h22,0,0],[0,0,h33,0],[0,0,0,h44]);
                                  [ h11   0    0    0  ]
                                  [                    ]
                                  [  0   h22   0    0  ]
      (%o6)                       [                    ]
                                  [  0    0   h33   0  ]
                                  [                    ]
                                  [  0    0    0   h44 ]
      (%i7) depends(l,r);
      (%o7)                               [l(r)]
      (%i8) lg:lg+l*h;
            [ h11 l - 1      0          0                 0            ]
            [                                                          ]
            [     0      h22 l + 1      0                 0            ]
            [                                                          ]
      (%o8) [                        2                                 ]
            [     0          0      r  + h33 l            0            ]
            [                                                          ]
            [                                    2    2                ]
            [     0          0          0       r  sin (theta) + h44 l ]
      (%i9) cmetric(false);
      (%o9)                                done
      (%i10) einstein(false);
      (%o10)                               done
      (%i11) ntermst(ein);
      [[1, 1], 62]
      [[1, 2], 0]
      [[1, 3], 0]
      [[1, 4], 0]
      [[2, 1], 0]
      [[2, 2], 24]
      [[2, 3], 0]
      [[2, 4], 0]
      [[3, 1], 0]
      [[3, 2], 0]
      [[3, 3], 46]
      [[3, 4], 0]
      [[4, 1], 0]
      [[4, 2], 0]
      [[4, 3], 0]
      [[4, 4], 46]
      (%o12)                               done

  However, if we recompute this example as an approximation that is linear in the variable `l`, we get much simpler expressions:

      (%i14) ctayswitch:true;
      (%o14)                               true
      (%i15) ctayvar:l;
      (%o15)                                 l
      (%i16) ctaypov:1;
      (%o16)                                 1
      (%i17) ctaypt:0;
      (%o17)                                 0
      (%i18) christof(false);
      (%o18)                               done
      (%i19) ricci(false);
      (%o19)                               done
      (%i20) einstein(false);
      (%o20)                               done
      (%i21) ntermst(ein);
      [[1, 1], 6]
      [[1, 2], 0]
      [[1, 3], 0]
      [[1, 4], 0]
      [[2, 1], 0]
      [[2, 2], 13]
      [[2, 3], 2]
      [[2, 4], 0]
      [[3, 1], 0]
      [[3, 2], 2]
      [[3, 3], 9]
      [[3, 4], 0]
      [[4, 1], 0]
      [[4, 2], 0]
      [[4, 3], 0]
      [[4, 4], 9]
      (%o21)                               done
      (%i22) ratsimp(ein[1,1]);
                               2      2  4               2     2
      (%o22) - (((h11 h22 - h11 ) (l )  r  - 2 h33 l    r ) sin (theta)
                                    r               r r

                                  2               2      4    2
                    - 2 h44 l    r  - h33 h44 (l ) )/(4 r  sin (theta))
                             r r                r

  This capability can be useful, for instance, when working in the weak field limit far from a gravitational source.

#### 20.3.2.4 Frame fields

Optionsvariable: cframe_flag ¶

  Standardwert: `false`

  When the variable `cframe_flag` is set to true, the `ctensor` package performs its calculations using a moving frame.

Function: frame_bracket (fr, fri, diagframe) ¶

  The frame bracket (`fb[]`).

  Computes the frame bracket according to the following definition:

         c          c         c        d     e
      ifb   = ( ifri    - ifri    ) ifr   ifr
         ab         d,e       e,d      a     b

#### 20.3.2.5 Algebraic classification

A new feature (as of November, 2004) of `ctensor` is its ability to compute the Petrov classification of a 4-dimensional spacetime metric. For a demonstration of this capability, see the file `share/tensor/petrov.dem`.

Function: nptetrad () ¶

  Computes a Newman-Penrose null tetrad (`np`) and its raised-index counterpart (`npi`). See `petrov` for an example.

  The null tetrad is constructed on the assumption that a four-diemensional orthonormal frame metric with metric signature (-,+,+,+) is being used. The components of the null tetrad are related to the inverse frame matrix as follows:

      np  = (fri  + fri ) / sqrt(2)
        1       1      2

      np  = (fri  - fri ) / sqrt(2)
        2       1      2

      np  = (fri  + %i fri ) / sqrt(2)
        3       3         4

      np  = (fri  - %i fri ) / sqrt(2)
        4       3         4

Function: psi (dis) ¶

  Computes the five Newman-Penrose coefficients `psi[0]`...`psi[4]`. If `psi` is set to `true`, the coefficients are displayed. See `petrov` for an example.

  These coefficients are computed from the Weyl-tensor in a coordinate base. If a frame base is used, the Weyl-tensor is first converted to a coordinate base, which can be a computationally expensive procedure. For this reason, in some cases it may be more advantageous to use a coordinate base in the first place before the Weyl tensor is computed. Note however, that constructing a Newman-Penrose null tetrad requires a frame base. Therefore, a meaningful computation sequence may begin with a frame base, which is then used to compute `lg` (computed automatically by `cmetric` and then `ug`. At this point, you can switch back to a coordinate base by setting `cframe_flag` to false before beginning to compute the Christoffel symbols. Changing to a frame base at a later stage could yield inconsistent results, as you may end up with a mixed bag of tensors, some computed in a frame base, some in a coordinate base, with no means to distinguish between the two.

Function: petrov () ¶

  Computes the Petrov classification of the metric characterized by `psi[0]` … `psi[4]`.

  For example, the following demonstrates how to obtain the Petrov-classification of the Kerr metric:

      (%i1) load("ctensor");
      (%o1)       /share/tensor/ctensor.mac
      (%i2) (cframe_flag:true,gcd:spmod,ctrgsimp:true,ratfac:true);
      (%o2)                                true
      (%i3) ct_coordsys(exteriorschwarzschild,all);
      (%o3)                                done
      (%i4) ug:invert(lg)$
      (%i5) weyl(false);
      (%o5)                                done
      (%i6) nptetrad(true);
      (%t6) np =

      [ sqrt(r - 2 m)           sqrt(r)                                 ]
      [---------------   ---------------------    0            0        ]
      [sqrt(2) sqrt(r)   sqrt(2) sqrt(r - 2 m)                          ]
      [                                                                 ]
      [ sqrt(r - 2 m)            sqrt(r)                                ]
      [---------------  - ---------------------   0            0        ]
      [sqrt(2) sqrt(r)    sqrt(2) sqrt(r - 2 m)                         ]
      [                                                                 ]
      [                                          r      %i r sin(theta) ]
      [       0                    0          -------   --------------- ]
      [                                       sqrt(2)       sqrt(2)     ]
      [                                                                 ]
      [                                          r       %i r sin(theta)]
      [       0                    0          -------  - ---------------]
      [                                       sqrt(2)        sqrt(2)    ]

                                   sqrt(r)         sqrt(r - 2 m)
      (%t7) npi = matrix([- ---------------------,---------------, 0, 0],
                            sqrt(2) sqrt(r - 2 m) sqrt(2) sqrt(r)

                sqrt(r)            sqrt(r - 2 m)
      [- ---------------------, - ---------------, 0, 0],
         sqrt(2) sqrt(r - 2 m)    sqrt(2) sqrt(r)

                 1               %i
      [0, 0, ---------, --------------------],
             sqrt(2) r  sqrt(2) r sin(theta)

                 1                 %i
      [0, 0, ---------, - --------------------])
             sqrt(2) r    sqrt(2) r sin(theta)

      (%o7)                                done
      (%i7) psi(true);
      (%t8)                              psi  = 0
                                            0

      (%t9)                              psi  = 0
                                            1

                                                m
      (%t10)                             psi  = --
                                            2    3
                                                r

      (%t11)                             psi  = 0
                                            3

      (%t12)                             psi  = 0
                                            4
      (%o12)                               done
      (%i12) petrov();
      (%o12)                                 D

  The Petrov classification function is based on the algorithm published in "Classifying geometries in general relativity: III Classification in practice" by Pollney, Skea, and d’Inverno, Class. Quant. Grav. 17 2885-2902 (2000). Except for some simple test cases, the implementation is untested as of December 19, 2004, and is likely to contain errors.

#### 20.3.2.6 Torsion and nonmetricity

`ctensor` has the ability to compute and include torsion and nonmetricity coefficients in the connection coefficients.

The torsion coefficients are calculated from a user-supplied tensor `tr`, which should be a rank (2,1) tensor. From this, the torsion coefficients `kt` are computed according to the following formulae:

                  m          m      m
           - g  tr   - g   tr   - tr   g
              im  kj    jm   ki     ij  km
    kt   = -------------------------------
      ijk                 2

      k     km
    kt   = g   kt
      ij         ijm

Note that only the mixed-index tensor is calculated and stored in the array `kt`.

The nonmetricity coefficients are calculated from the user-supplied nonmetricity vector `nm`. From this, the nonmetricity coefficients `nmc` are computed as follows:

                 k    k        km
           -nm  D  - D  nm  + g   nm  g
       k      i  j    i   j         m  ij
    nmc  = ------------------------------
       ij                2

where D stands for the Kronecker-delta.

When `ctorsion_flag` is set to `true`, the values of `kt` are substracted from the mixed-indexed connection coefficients computed by `christof` and stored in `mcs`. Similarly, if `cnonmet_flag` is set to `true`, the values of `nmc` are substracted from the mixed-indexed connection coefficients.

If necessary, `christof` calls the functions `contortion` and `nonmetricity` in order to compute `kt` and `nm`.

Function: contortion (tr) ¶

  Computes the (2,1) contortion coefficients from the torsion tensor tr.

Function: nonmetricity (nm) ¶

  Computes the (2,1) nonmetricity coefficients from the nonmetricity vector nm.

#### 20.3.2.7 Miscellaneous features

Function: ctransform (M) ¶

  A function in the `ctensor` (component tensor) package which will perform a coordinate transformation upon an arbitrary square symmetric matrix M. The user must input the functions which define the transformation. (Formerly called `transform`.)

Function: findde (A, n) ¶

  returns a list of the unique differential equations (expressions) corresponding to the elements of the n dimensional square array A. Presently, n may be 2 or 3. `deindex` is a global list containing the indices of A corresponding to these unique differential equations. For the Einstein tensor (`ein`), which is a two dimensional array, if computed for the metric in the example below, `findde` gives the following independent differential equations:

      (%i1) load("ctensor");
      (%o1)       /share/tensor/ctensor.mac
      (%i2) derivabbrev:true;
      (%o2)                                true
      (%i3) dim:4;
      (%o3)                                  4
      (%i4) lg:matrix([a, 0, 0, 0], [ 0, x^2, 0, 0],
                                    [0, 0, x^2*sin(y)^2, 0], [0,0,0,-d]);
                                [ a  0       0        0  ]
                                [                        ]
                                [     2                  ]
                                [ 0  x       0        0  ]
      (%o4)                     [                        ]
                                [         2    2         ]
                                [ 0  0   x  sin (y)   0  ]
                                [                        ]
                                [ 0  0       0       - d ]
      (%i5) depends([a,d],x);
      (%o5)                            [a(x), d(x)]
      (%i6) ct_coords:[x,y,z,t];
      (%o6)                            [x, y, z, t]
      (%i7) cmetric();
      (%o7)                                done
      (%i8) einstein(false);
      (%o8)                                done
      (%i9) findde(ein,2);
                                                  2
      (%o9) [d  x - a d + d, 2 a d d    x - a (d )  x - a  d d  x
              x                     x x         x        x    x

                                                    2          2
                                + 2 a d d   - 2 a  d , a  x + a  - a]
                                         x       x      x
      (%i10) deindex;
      (%o10)                     [[1, 1], [2, 2], [4, 4]]

Function: cograd () ¶

  Computes the covariant gradient of a scalar function allowing the user to choose the corresponding vector name as the example under `contragrad` illustrates.

Function: contragrad () ¶

  Computes the contravariant gradient of a scalar function allowing the user to choose the corresponding vector name as the example below for the Schwarzschild metric illustrates:

      (%i1) load("ctensor");
      (%o1)       /share/tensor/ctensor.mac
      (%i2) derivabbrev:true;
      (%o2)                                true
      (%i3) ct_coordsys(exteriorschwarzschild,all);
      (%o3)                                done
      (%i4) depends(f,r);
      (%o4)                               [f(r)]
      (%i5) cograd(f,g1);
      (%o5)                                done
      (%i6) listarray(g1);
      (%o6)                            [0, f , 0, 0]
                                            r
      (%i7) contragrad(f,g2);
      (%o7)                                done
      (%i8) listarray(g2);
                                     f  r - 2 f  m
                                      r        r
      (%o8)                      [0, -------------, 0, 0]
                                           r

Function: dscalar () ¶

  computes the tensor d’Alembertian of the scalar function once dependencies have been declared upon the function. For example:

      (%i1) load("ctensor");
      (%o1)       /share/tensor/ctensor.mac
      (%i2) derivabbrev:true;
      (%o2)                                true
      (%i3) ct_coordsys(exteriorschwarzschild,all);
      (%o3)                                done
      (%i4) depends(p,r);
      (%o4)                               [p(r)]
      (%i5) factor(dscalar(p));
                                2
                          p    r  - 2 m p    r + 2 p  r - 2 m p
                           r r           r r        r          r
      (%o5)               --------------------------------------
                                             2
                                            r

Function: checkdiv () ¶

  computes the covariant divergence of the mixed second rank tensor (whose first index must be covariant) by printing the corresponding n components of the vector field (the divergence) where n = `dim`. If the argument to the function is `g` then the divergence of the Einstein tensor will be formed and must be zero. In addition, the divergence (vector) is given the array name `div`.

Function: cgeodesic (dis) ¶

  A function in the `ctensor` (component tensor) package. `cgeodesic` computes the geodesic equations of motion for a given metric. They are stored in the array `geod[i]`. If the argument dis is `true` then these equations are displayed.

Function: bdvac (f) ¶

  generates the covariant components of the vacuum field equations of the Brans- Dicke gravitational theory. The scalar field is specified by the argument f, which should be a (quoted) function name with functional dependencies, e.g., `'p(x)`.

  The components of the second rank covariant field tensor are represented by the array `bd`.

Function: invariant1 () ¶

  generates the mixed Euler- Lagrange tensor (field equations) for the invariant density of R^2. The field equations are the components of an array named `inv1`.

Function: invariant2 () ¶

  *** NOT YET IMPLEMENTED ***

  generates the mixed Euler- Lagrange tensor (field equations) for the invariant density of `ric[i,j]*uriem[i,j]`. The field equations are the components of an array named `inv2`.

Function: bimetric () ¶

  *** NOT YET IMPLEMENTED ***

  generates the field equations of Rosen’s bimetric theory. The field equations are the components of an array named `rosen`.

#### 20.3.2.8 Utility functions

Function: diagmatrixp (M) ¶

  Returns `true` if M is a diagonal matrix or (2D) array.

Function: symmetricp (M) ¶

  Returns `true` if M is a symmetric matrix or (2D) array.

Function: ntermst (f) ¶

  gives the user a quick picture of the "size" of the doubly subscripted tensor (array) f. It prints two element lists where the second element corresponds to NTERMS of the components specified by the first elements. In this way, it is possible to quickly find the non-zero expressions and attempt simplification.

Function: cdisplay (ten) ¶

  displays all the elements of the tensor ten, as represented by a multidimensional array. Tensors of rank 0 and 1, as well as other types of variables, are displayed as with `ldisplay`. Tensors of rank 2 are displayed as 2-dimensional matrices, while tensors of higher rank are displayed as a list of 2-dimensional matrices. For instance, the Riemann-tensor of the Schwarzschild metric can be viewed as:

      (%i1) load("ctensor");
      (%o1)       /share/tensor/ctensor.mac
      (%i2) ratfac:true;
      (%o2)                                true
      (%i3) ct_coordsys(exteriorschwarzschild,all);
      (%o3)                                done
      (%i4) riemann(false);
      (%o4)                                done
      (%i5) cdisplay(riem);
                [ 0               0                   0           0     ]
                [                                                       ]
                [                              2                        ]
                [      3 m (r - 2 m)   m    2 m                         ]
                [ 0  - ------------- + -- - ----      0           0     ]
                [            4          3     4                         ]
                [           r          r     r                          ]
                [                                                       ]
      riem    = [                                m (r - 2 m)            ]
          1, 1  [ 0               0              -----------      0     ]
                [                                     4                 ]
                [                                    r                  ]
                [                                                       ]
                [                                           m (r - 2 m) ]
                [ 0               0                   0     ----------- ]
                [                                                4      ]
                [                                               r       ]

                                      [    2 m (r - 2 m)       ]
                                      [ 0  -------------  0  0 ]
                                      [          4             ]
                                      [         r              ]
                           riem     = [                        ]
                               1, 2   [ 0        0        0  0 ]
                                      [                        ]
                                      [ 0        0        0  0 ]
                                      [                        ]
                                      [ 0        0        0  0 ]

                                      [         m (r - 2 m)    ]
                                      [ 0  0  - -----------  0 ]
                                      [              4         ]
                                      [             r          ]
                           riem     = [                        ]
                               1, 3   [ 0  0        0        0 ]
                                      [                        ]
                                      [ 0  0        0        0 ]
                                      [                        ]
                                      [ 0  0        0        0 ]

                                      [            m (r - 2 m) ]
                                      [ 0  0  0  - ----------- ]
                                      [                 4      ]
                                      [                r       ]
                           riem     = [                        ]
                               1, 4   [ 0  0  0        0       ]
                                      [                        ]
                                      [ 0  0  0        0       ]
                                      [                        ]
                                      [ 0  0  0        0       ]

                                     [       0         0  0  0 ]
                                     [                         ]
                                     [       2 m               ]
                                     [ - ------------  0  0  0 ]
                          riem     = [    2                    ]
                              2, 1   [   r  (r - 2 m)          ]
                                     [                         ]
                                     [       0         0  0  0 ]
                                     [                         ]
                                     [       0         0  0  0 ]

                   [     2 m                                         ]
                   [ ------------  0        0               0        ]
                   [  2                                              ]
                   [ r  (r - 2 m)                                    ]
                   [                                                 ]
                   [      0        0        0               0        ]
                   [                                                 ]
        riem     = [                         m                       ]
            2, 2   [      0        0  - ------------        0        ]
                   [                     2                           ]
                   [                    r  (r - 2 m)                 ]
                   [                                                 ]
                   [                                         m       ]
                   [      0        0        0         - ------------ ]
                   [                                     2           ]
                   [                                    r  (r - 2 m) ]

                                      [ 0  0       0        0 ]
                                      [                       ]
                                      [            m          ]
                                      [ 0  0  ------------  0 ]
                           riem     = [        2              ]
                               2, 3   [       r  (r - 2 m)    ]
                                      [                       ]
                                      [ 0  0       0        0 ]
                                      [                       ]
                                      [ 0  0       0        0 ]

                                      [ 0  0  0       0       ]
                                      [                       ]
                                      [               m       ]
                                      [ 0  0  0  ------------ ]
                           riem     = [           2           ]
                               2, 4   [          r  (r - 2 m) ]
                                      [                       ]
                                      [ 0  0  0       0       ]
                                      [                       ]
                                      [ 0  0  0       0       ]

                                            [ 0  0  0  0 ]
                                            [            ]
                                            [ 0  0  0  0 ]
                                            [            ]
                                 riem     = [ m          ]
                                     3, 1   [ -  0  0  0 ]
                                            [ r          ]
                                            [            ]
                                            [ 0  0  0  0 ]

                                            [ 0  0  0  0 ]
                                            [            ]
                                            [ 0  0  0  0 ]
                                            [            ]
                                 riem     = [    m       ]
                                     3, 2   [ 0  -  0  0 ]
                                            [    r       ]
                                            [            ]
                                            [ 0  0  0  0 ]

                                     [   m                      ]
                                     [ - -   0   0       0      ]
                                     [   r                      ]
                                     [                          ]
                                     [        m                 ]
                                     [  0   - -  0       0      ]
                          riem     = [        r                 ]
                              3, 3   [                          ]
                                     [  0    0   0       0      ]
                                     [                          ]
                                     [              2 m - r     ]
                                     [  0    0   0  ------- + 1 ]
                                     [                 r        ]

                                          [ 0  0  0    0   ]
                                          [                ]
                                          [ 0  0  0    0   ]
                                          [                ]
                               riem     = [            2 m ]
                                   3, 4   [ 0  0  0  - --- ]
                                          [             r  ]
                                          [                ]
                                          [ 0  0  0    0   ]

                                      [       0        0  0  0 ]
                                      [                        ]
                                      [       0        0  0  0 ]
                                      [                        ]
                           riem     = [       0        0  0  0 ]
                               4, 1   [                        ]
                                      [      2                 ]
                                      [ m sin (theta)          ]
                                      [ -------------  0  0  0 ]
                                      [       r                ]

                                      [ 0        0        0  0 ]
                                      [                        ]
                                      [ 0        0        0  0 ]
                                      [                        ]
                           riem     = [ 0        0        0  0 ]
                               4, 2   [                        ]
                                      [         2              ]
                                      [    m sin (theta)       ]
                                      [ 0  -------------  0  0 ]
                                      [          r             ]

                                    [ 0  0          0          0 ]
                                    [                            ]
                                    [ 0  0          0          0 ]
                                    [                            ]
                         riem     = [ 0  0          0          0 ]
                             4, 3   [                            ]
                                    [                2           ]
                                    [         2 m sin (theta)    ]
                                    [ 0  0  - ---------------  0 ]
                                    [                r           ]

                 [        2                                             ]
                 [   m sin (theta)                                      ]
                 [ - -------------         0                0         0 ]
                 [         r                                            ]
                 [                                                      ]
                 [                         2                            ]
                 [                    m sin (theta)                     ]
      riem     = [        0         - -------------         0         0 ]
          4, 4   [                          r                           ]
                 [                                                      ]
                 [                                          2           ]
                 [                                   2 m sin (theta)    ]
                 [        0                0         ---------------  0 ]
                 [                                          r           ]
                 [                                                      ]
                 [        0                0                0         0 ]

      (%o5)                                done

Function: deleten (L, n) ¶

  Returns a new list consisting of L with the n’th element deleted.

#### 20.3.2.9 Variables used by `ctensor`

Option variable: dim ¶

  Default value: 4

  An option in the `ctensor` (component tensor) package. `dim` is the dimension of the manifold with the default 4. The command `dim: n` will reset the dimension to any other value `n`.

Option variable: diagmetric ¶

  Default value: `false`

  An option in the `ctensor` (component tensor) package. If `diagmetric` is `true` special routines compute all geometrical objects (which contain the metric tensor explicitly) by taking into consideration the diagonality of the metric. Reduced run times will, of course, result. Note: this option is set automatically by `csetup` if a diagonal metric is specified.

Option variable: ctrgsimp ¶

  Causes trigonometric simplifications to be used when tensors are computed. Presently, `ctrgsimp` affects only computations involving a moving frame.

Option variable: cframe_flag ¶

  Causes computations to be performed relative to a moving frame as opposed to a holonomic metric. The frame is defined by the inverse frame array `fri` and the frame metric `lfg`. For computations using a Cartesian frame, `lfg` should be the unit matrix of the appropriate dimension; for computations in a Lorentz frame, `lfg` should have the appropriate signature.

Option variable: ctorsion_flag ¶

  Causes the contortion tensor to be included in the computation of the connection coefficients. The contortion tensor itself is computed by `contortion` from the user-supplied tensor `tr`.

Option variable: cnonmet_flag ¶

  Causes the nonmetricity coefficients to be included in the computation of the connection coefficients. The nonmetricity coefficients are computed from the user-supplied nonmetricity vector `nm` by the function `nonmetricity`.

Option variable: ctayswitch ¶

  If set to `true`, causes some `ctensor` computations to be carried out using Taylor-series expansions. Presently, `christof`, `ricci`, `uricci`, `einstein`, and `weyl` take into account this setting.

Option variable: ctayvar ¶

  Variable used for Taylor-series expansion if `ctayswitch` is set to `true`.

Option variable: ctaypov ¶

  Maximum power used in Taylor-series expansion when `ctayswitch` is set to `true`.

Option variable: ctaypt ¶

  Point around which Taylor-series expansion is carried out when `ctayswitch` is set to `true`.

System variable: gdet ¶

  The determinant of the metric tensor `lg`. Computed by `cmetric` when `cframe_flag` is set to `false`.

Option variable: ratchristof ¶

  Causes rational simplification to be applied by `christof`.

Option variable: rateinstein ¶

  Default value: `true`

  If `true` rational simplification will be performed on the non-zero components of Einstein tensors; if `ratfac` is `true` then the components will also be factored.

Option variable: ratriemann ¶

  Default value: `true`

  One of the switches which controls simplification of Riemann tensors; if `true`, then rational simplification will be done; if `ratfac` is `true` then each of the components will also be factored.

Option variable: ratweyl ¶

  Default value: `true`

  If `true`, this switch causes the `weyl` function to apply rational simplification to the values of the Weyl tensor. If `ratfac` is `true`, then the components will also be factored.

Variable: lfg ¶

  The covariant frame metric. By default, it is initialized to the 4-dimensional Lorentz frame with signature (+,+,+,-). Used when `cframe_flag` is `true`.

Variable: ufg ¶

  The inverse frame metric. Computed from `lfg` when `cmetric` is called while `cframe_flag` is set to `true`.

Variable: riem ¶

  The (3,1) Riemann tensor. Computed when the function `riemann` is invoked. For information about index ordering, see the description of `riemann`.

  If `cframe_flag` is `true`, `riem` is computed from the covariant Riemann-tensor `lriem`.

Variable: lriem ¶

  The covariant Riemann tensor. Computed by `lriemann`.

Variable: uriem ¶

  The contravariant Riemann tensor. Computed by `uriemann`.

Variable: ric ¶

  The mixed Ricci-tensor. Computed by `ricci`.

Variable: uric ¶

  The contravariant Ricci-tensor. Computed by `uricci`.

Variable: lg ¶

  The metric tensor. This tensor must be specified (as a `dim` by `dim` matrix) before other computations can be performed.

Variable: ug ¶

  The inverse of the metric tensor. Computed by `cmetric`.

Variable: weyl ¶

  The Weyl tensor. Computed by `weyl`.

Variable: fb ¶

  Frame bracket coefficients, as computed by `frame_bracket`.

Variable: kinvariant ¶

  The Kretchmann invariant. Computed by `rinvariant`.

Variable: np ¶

  A Newman-Penrose null tetrad. Computed by `nptetrad`.

Variable: npi ¶

  The raised-index Newman-Penrose null tetrad. Computed by `nptetrad`. Defined as `ug.np`. The product `np.transpose(npi)` is constant:

      (%i39) trigsimp(np.transpose(npi));
                                    [  0   - 1  0  0 ]
                                    [                ]
                                    [ - 1   0   0  0 ]
      (%o39)                        [                ]
                                    [  0    0   0  1 ]
                                    [                ]
                                    [  0    0   1  0 ]

Variable: tr ¶

  User-supplied rank-3 tensor representing torsion. Used by `contortion`.

Variable: kt ¶

  The contortion tensor, computed from `tr` by `contortion`.

Variable: nm ¶

  User-supplied nonmetricity vector. Used by `nonmetricity`.

Variable: nmc ¶

  The nonmetricity coefficients, computed from `nm` by `nonmetricity`.

System variable: tensorkill ¶

  Variable indicating if the tensor package has been initialized. Set and used by `csetup`, reset by `init_ctensor`.

Option variable: ct_coords ¶

  Default value: `[]`

  An option in the `ctensor` (component tensor) package. `ct_coords` contains a list of coordinates. While normally defined when the function `csetup` is called, one may redefine the coordinates with the assignment `ct_coords: [j1, j2, ..., jn]` where the j’s are the new coordinate names. See also `csetup`.

#### 20.3.2.10 Reserved names

The following names are used internally by the `ctensor` package and should not be redefined:

      Name         Description
      ---------------------------------------------------------------------
      _lg()        Evaluates to lfg if frame metric used, lg otherwise
      _ug()        Evaluates to ufg if frame metric used, ug otherwise
      cleanup()    Removes items drom the deindex list
      contract4()  Used by psi()
      filemet()    Used by csetup() when reading the metric from a file
      findde1()    Used by findde()
      findde2()    Used by findde()
      findde3()    Used by findde()
      kdelt()      Kronecker-delta (not generalized)
      newmet()     Used by csetup() for setting up a metric interactively
      setflags()   Used by init_ctensor()
      readvalue()
      resimp()
      sermet()     Used by csetup() for entering a metric as Taylor-series
      txyzsum()
      tmetric()    Frame metric, used by cmetric() when cframe_flag:true
      triemann()   Riemann-tensor in frame base, used when cframe_flag:true
      tricci()     Ricci-tensor in frame base, used when cframe_flag:true
      trrc()       Ricci rotation coefficients, used by christof()
      yesp()

#### 20.3.2.11 Changes

In November, 2004, the `ctensor` package was extensively rewritten. Many functions and variables have been renamed in order to make the package compatible with the commercial version of Macsyma.

      New Name     Old Name        Description
      ---------------------------------------------------------------------
      ctaylor()    DLGTAYLOR()     Taylor-series expansion of an expression
      lgeod[]      EM              Geodesic equations
      ein[]        G[]             Mixed Einstein-tensor
      ric[]        LR[]            Mixed Ricci-tensor
      ricci()      LRICCICOM()     Compute the mixed Ricci-tensor
      ctaypov      MINP            Maximum power in Taylor-series expansion
      cgeodesic()  MOTION          Compute geodesic equations
      ct_coords    OMEGA           Metric coordinates
      ctayvar      PARAM           Taylor-series expansion variable
      lriem[]      R[]             Covariant Riemann-tensor
      uriemann()   RAISERIEMANN()  Compute the contravariant Riemann-tensor
      ratriemann   RATRIEMAN       Rational simplif. of the Riemann-tensor
      uric[]       RICCI[]         Contravariant Ricci-tensor
      uricci()     RICCICOM()      Compute the contravariant Ricci-tensor
      cmetric()    SETMETRIC()     Set up the metric
      ctaypt       TAYPT           Point for Taylor-series expansion
      ctayswitch   TAYSWITCH       Taylor-series setting switch
      csetup()     TSETUP()        Start interactive setup session
      ctransform() TTRANSFORM()    Interactive coordinate transformation
      uriem[]      UR[]            Contravariant Riemann-tensor
      weyl[]       W[]             (3,1) Weyl-tensor

### 20.4 Paket ATENSOR

#### 20.4.1 Einführung in ATENSOR

Das Paket `atensor` erlaubt das algebraische Rechnen mit Tensoren. Mit dem Kommando `load("atensor")` wird das Paket geladen. Um das Paket zu initialisieren, wird die Funktion `init_atensor` ausgeführt.

Im wesentlichen enthält das Paket `atensor` Regeln für die Vereinfachung von Ausdrücken mit dem `dot-Operator` Operator `"."`. `atensor` kennt verschiedene Algebren. Mit der Funktion `init_atensor` werden die Regeln einer Algebra initialisiert.

Um die Möglichkeiten des Paketes `atensor` zu zeigen, wird im Folgenden die Algebra der Quaternionen als eine Clifford-Algebra Cl(0,2) mit zwei Basisvektoren definiert. Die drei imaginären Einheiten `i`, `j` und `k` werden durch die zwei Vektoren `v[1]` und `v[2]` sowie das Produkt `v[1] . v[2]` dargestellt:

        i = v     j = v     k = v  . v
             1         2         1    2

Das Paket `atensor` hat eine vordefinierte Algebra der Quaternionen. Hier wird die Algebra der Quaterinonen als Clifford-Algebra Cl(0,2) definiert und die Multiplikationstabelle der Basisvektoren konstruiert.

    (%i1) load("atensor")$

    (%i2) init_atensor(clifford,0,0,2);
    (%o2)                         done
    (%i3) atensimp(v[1].v[1]);
    (%o3)                          - 1
    (%i4) atensimp((v[1].v[2]).(v[1].v[2]));
    (%o4)                          - 1
    (%i5) q:zeromatrix(4,4);
                             [ 0  0  0  0 ]
                             [            ]
                             [ 0  0  0  0 ]
    (%o5)                    [            ]
                             [ 0  0  0  0 ]
                             [            ]
                             [ 0  0  0  0 ]
    (%i6) q[1,1]:1;
    (%o6)                           1
    (%i7) for i thru adim do q[1,i+1]:q[i+1,1]:v[i];
    (%o7)                         done
    (%i8) q[1,4]:q[4,1]:v[1].v[2];
    (%o8)                        v  . v
                                  1    2
    (%i9) for i from 2 thru 4 do
              for j from 2 thru 4 do
                  q[i,j]:atensimp(q[i,1].q[1,j]);
    (%o9)                         done
    (%i10) q;
                [    1        v         v      v  . v  ]
                [              1         2      1    2 ]
                [                                      ]
                [   v         - 1     v  . v    - v    ]
                [    1                 1    2      2   ]
    (%o10)      [                                      ]
                [   v      - v  . v     - 1      v     ]
                [    2        1    2              1    ]
                [                                      ]
                [ v  . v      v        - v       - 1   ]
                [  1    2      2          1            ]

Indizierte Symbole mit dem Namen, der in der Optionsvariablen `asymbol` abgelegt ist, werden von `atensor` als Basisvektoren erkannt. Dabei läuft der Index von `1` bis `adim`. Für indizierte Symbole werden die Bilinearformen `sf`, `af` und `av` ausgewertet. Die Auswertung ersetzt die Bilinearform `fun(v[i].v[j])`, durch das Matrixelement `aform[i,j]`, wobei `v` einen Basisvektor bezeichnet und `fun` einer der Bilinearformen `sf` oder `af` ist. Ist `fun` die Bilinearform `av`, dann wird `v[aform[i,j]]` für `av(v[i],v[j])` substituiert. Siehe auch die Optionsvariable `aform`.

Die Bilinearformen `sf`, `af` und `av` können vom Nutzer neu definiert werden, um eine gewünschte Algebra zu definieren.

Wird das Paket `atensor` geladen, werden die folgenden Schalter auf die angegebenen Werte gesetzt:

    dotscrules  : true
    dotdistrib  : true
    dotexptsimp : false

Wird das symbolische Rechnen in einer nicht-assoziativen Algebra gewünscht, kann auch noch der Schalter `dotassoc` auf den Wert `false` gesetzt werden. In diesem Fall kann jedoch die Funktion `atensimp` nicht immer eine gewünschte Vereinfachung erzielen.

#### 20.4.2 Funktionen und Variablen für ATENSOR

Funktion: init_atensor (alg_type, opt_dims) ¶
Funktion: init_atensor (alg_type) ¶

  Initialisiert das Paket `atensor` mit der angegebenen Algebra alg_type. Das Argument alg_type kann einen der folgenden Werte haben:

  `universal`

    Eine allgemeine Algebra, für die keine Vertauschungsregeln definiert sind.

  `grassmann`

    Eine Graßmann-Algebra, für die die Vertauschungsregel `u.v + v.u = 0` definiert ist.

  `clifford`

    Eine Clifford-Algebra, die durch die Vertauschungsregel `u.v + v.u = -2*sf(u,v)` definiert ist. Die Bilinearform `sf` ist eine symmetrische Funktion, die einen skalaren Wert als Ergebnis hat. Das Argument opt_dims kann bis zu drei positive ganze Zahlen sein, die die positiven, entarteten und negativen Dimensionen der Algebra bezeichnen. Die Dimension `adim` und die Matrix `aform` werden entsprechend der angegebenen Argumente opt_dims initialisiert. Sind keine Argumente opt_dims vorhanden, wird die Dimension `adim` zu Null initialisiert und keine Matrix `aform` definiert.

  `symmetric`

    Eine symmetrische Algebra, die durch die Vertauschungsregel `u.v - v.u = 0` definiert ist.

  `symplectic`

    Eine symplektische Algebra, die durch die Vertauschungsregel `u.v - v.u = 2*af(u,v)` definiert ist. Die Bilinearform `af` ist eine antisymmetrische Funktion, die einen skalaren Wert als Ergebnis hat. Das Argument opt_dims kann bis zu zwei positive ganze Zahlen enthalten, die die nicht-degenerierten und degenerierten Dimensionen der Algebra bezeichnen. Die Dimension `adim` und die Matrix `aform` werden entsprechend der angegebenen Argumente opt_dims initialisiert. Sind keine Argumente opt_dims vorhanden, wird die Dimension `adim` zu Null initialisiert und keine Matrix `aform` definiert.

  `lie_envelop`

    Eine einhüllende Lie-Algebra, die durch die Vertauschungsregel `u.v - v.u = 2*av(u,v)` definiert ist, wobei die Bilinearform `av` eine antisymmetrische Funktion ist. Das Argument opt_dims kann eine positive ganze Zahl sein, welche die Dimension der Lie-Algebra angibt. Die Dimension `adim` und die Matrix `aform` werden entsprechend des Argumentes opt_dims initialisiert. Ist kein Argument opt_dims vorhanden, wird die Dimension `adim` zu Null initialisiert und keine Matrix `aform` definiert.

  Die Funktion `init_atensor` kennt weiterhin einige vordefinierte Algebren:

  `complex`

    Die Algebra der komplexen Zahlen, die als eine Clifford-Algebra Cl(0,1) definiert wird. Das Kommando `init_atensor(complex)` ist äquivalent zum Kommando `init_atensor(clifford, 0, 0, 1)`.

  `quaternion`

    Die Algebra der Quaternionen, die als eine Clifford-Algebra vom Typ Cl(0,2) definiert wird. Das Kommando `init_atensor(quaternion)` ist äquivalent zum Kommando `init_atensor(clifford, 0, 0, 2)`.

  `pauli`

    Die Algebra der Pauli-Matrizen, die als eine Clifford-Algebra Cl(3,0) definiert wird. Das Kommando `init_atensor(pauli)` ist äquivalent zum Kommando `init_atensor(clifford, 3)`.

  `dirac`

    Die Algebra der Dirac-Matrizen, die als eine Clifford-Algebra Cl(3,0,1) definiert wird. Das Kommando `init_atensor(dirac)` ist äquivalent zum Kommando `init_atensor(clifford, 3, 0, 1)`.

Funktion: atensimp (expr) ¶

  Vereinfacht einen Ausdruck expr entsprechend der Regeln für die Algebra, die mit der Funktion `init_atensor` festgelegt ist. Die Regeln werden rekursiv auf den Ausdruck angewendet. Dabei werden auch Bilinearformen `sf`, `af` und `av` ausgewertet.

  Beispiele:

  Die folgenden Beispiele zeigen das Rechnen mit der Algebra der Quaternionen.

      (%i1) load("atensor")$

      (%i2) init_atensor(quaternion);
      (%o2)                         done
      (%i3) atensimp(v[1].v[1]);
      (%o3)                          - 1
      (%i4) atensimp(v[2].v[2]);
      (%o4)                          - 1
      (%i5) atensimp((v[1].v[2]) . (v[1].v[2]));
      (%o5)                          - 1
      (%i6) expand((2*v[1]+3*v[2])^^2);
      (%o6) 9 (v  . v ) + 6 (v  . v ) + 6 (v  . v ) + 4 (v  . v )
                2    2        2    1        1    2        1    1
      (%i7) atensimp(%);
      (%o7)                         - 13

Optionsvariable: alg_type ¶

  Standardwert: `universal`

  Der Typ der Algebra, die bei der Vereinfachung von Ausdrücken mit der Funktion `atensimp` angewendet wird. Die Algebra wird von der Funktion `init_atensor` initialisiert. Mögliche Algebren sind `universal`, `grassmann`, `clifford`, `symmetric`, `symplectic` und `lie_envelop`. Siehe für eine ausführliche Erläuterung der Algebren die Funktion `init_atensor`.

Optionsvariable: adim ¶

  Standardwert: `0`

  Die Dimension der Algebra, die bei der Vereinfachung von Ausdrücken mit der Funktion `atensimp` angewendet wird. Die Dimension wird von der Funktion `init_atensor` initialisiert. Ein indiziertes Symbol mit dem Bezeichner `asymbol` ist dann ein Basisvektor, wenn der Index kleiner oder gleich der Dimension `adim` ist.

  Beispiel:

  Die Dirac-Algebra hat die Dimension `4` und `v[4]` ist ein Basisvektor.

      (%i1) load("atensor")$

      (%i2) init_atensor(dirac);
      (%o2)                         done
      (%i3) adim;
      (%o3)                           4
      (%i4) abasep(v[4]);
      (%o4)                         true

Optionsvariable: aform ¶

  Standardwert: `ident(3)`

  Matrix mit den Werten der Bilinearformen `sf`, `af` und `av`. Der Standardwert ist die dreidimensionale Einheitsmatrix.

  Beispiel:

  Das Beispiel zeigt die Matrix `aform` für eine Lie-Algebra mit drei Dimensionen und die Ergebnisse der Bilinearform `av` für diese Algebra.

      (%i1) load("atensor")$

      (%i2) init_atensor(lie_envelop, 3);
      (%o2)                         done
      (%i3) aform;
                              [  0    3   - 2 ]
                              [               ]
      (%o3)                   [ - 3   0    1  ]
                              [               ]
                              [  2   - 1   0  ]
      (%i4) av(v[1], v[2]);
      (%o4)                          v
                                      3
      (%i5) av(v[1], v[3]);
      (%o5)                         - v
                                       2

Optionsvariable: asymbol ¶

  Standardwert: `v`

  Enthält das Symbol, das einen Basisvektor des Paketes `atensor` bezeichnet. Mit der Funktion `abasep` kann getestet werde, ob ein indiziertes Symbol einen Basisvektor der Algebra bezeichnet.

  Beispiel:

  In diesem Beispiel wird `asymbol` auf den Wert `x` gesetzt.

      (%i1) load("atensor")$

      (%i2) init_atensor(symmetric, 2);
      (%o2)                         done
      (%i3) asymbol;
      (%o3)                           v
      (%i4) abasep(v[2]);
      (%o4)                         true
      (%i5) asymbol: x;
      (%o5)                           x
      (%i6) abasep(x[2]);
      (%o6)                         true

Funktion: sf (u, v) ¶

  Eine symmetrische Bilinearform, die bei der Vereinfachung von Ausdrücken mit der Funktion `atensimp` angewendet wird. Die Funktion kann vom Nutzer durch eine neue Funktion ersetzt werden. Die Standardimplementation prüft mit der Funktion `abasep`, ob die Argumente u und v Basisvektoren sind und setzt für diesen Fall den entsprechen Wert der Matrix `aform` ein.

Funktion: af (u, v) ¶

  Eine antisymmetrische Bilinearform, die bei der Vereinfachung von Ausdrücken mit der Funktion `atensimp` angewendet wird. Die Funktion kann vom Nutzer durch eine neue Funktion ersetzt werden. Die Standardimplementation prüft mit der Funktion `abasep`, ob die Argumente u und v Basisvektoren sind und setzt für diesen Fall den entsprechenden Wert der Matrix `aform` ein.

Funktion: av (u, v) ¶

  Eine antisymmetrische Bilinearform, die bei der Vereinfachung von Ausdrücken mit der Funktion `atensimp` angewendet wird. Die Funktion kann vom Nutzer durch eine neue Funktion ersetzt werden. Die Standardimplementation prüft mit der Funktion `abasep`, ob die Argumente u und v Basisvektoren sind und setzt für diesen Fall den entsprechenden Wert `v[aform[i,j]]` der Matrix `aform` ein.

  Beispiel:

      (%i1) load("atensor")$
      (%i2) adim: 3;
      (%o2)                           3
      (%i3) aform:matrix([0,3,-2],[-3,0,1],[2,-1,0]);
                              [  0    3   - 2 ]
                              [               ]
      (%o3)                   [ - 3   0    1  ]
                              [               ]
                              [  2   - 1   0  ]
      (%i4) asymbol: x;
      (%o4)                           x
      (%i5) av(x[1], x[2]);
      (%o5)                          x
                                      3
      (%i6) av(x[1], x[3]);
      (%o6)                         - x
                                       2

Funktion: abasep (v) ¶

  Prüft, ob das Argument v ein Basisvektor ist. Ein Basisvektor ist ein indiziertes Symbol mit dem Symbol `asymbol` als Bezeichner und einem Index im Bereich von `1` bis `adim`.

  Beispiel:

      (%i1) load("atensor")$
      (%i2) asymbol: x$
      (%i3) adim:3$
      (%i4) abasep(x[1]);
      (%o4)                         true
      (%i5) abasep(x[3]);
      (%o5)                         true
      (%i6) abasep(x[4]);
      (%o6)                         false