There are a couple of ways to construct matrices, with or without preset
elements:
+@cindex @code{lst_to_matrix()}
+@cindex @code{diag_matrix()}
+@cindex @code{unit_matrix()}
+@cindex @code{symbolic_matrix()}
@example
matrix::matrix(unsigned r, unsigned c);
matrix::matrix(unsigned r, unsigned c, const lst & l);
ex lst_to_matrix(const lst & l);
ex diag_matrix(const lst & l);
+ex unit_matrix(unsigned x);
+ex unit_matrix(unsigned r, unsigned c);
+ex symbolic_matrix(unsigned r, unsigned c, const string & base_name);
+ex symbolic_matrix(unsigned r, unsigned c, const string & base_name, const string & tex_base_name);
@end example
The first two functions are @code{matrix} constructors which create a matrix
with @samp{r} rows and @samp{c} columns. The matrix elements can be
initialized from a (flat) list of expressions @samp{l}. Otherwise they are
all set to zero. The @code{lst_to_matrix()} function constructs a matrix
-from a list of lists, each list representing a matrix row. Finally,
-@code{diag_matrix()} constructs a diagonal matrix given the list of diagonal
-elements. Note that the last two functions return expressions, not matrix
-objects.
+from a list of lists, each list representing a matrix row. @code{diag_matrix()}
+constructs a diagonal matrix given the list of diagonal elements.
+@code{unit_matrix()} creates an @samp{x} by @samp{x} (or @samp{r} by @samp{c})
+unit matrix. And finally, @code{symbolic_matrix} constructs a matrix filled
+with newly generated symbols made of the specified base name and the
+position of each element in the matrix.
Matrix elements can be accessed and set using the parenthesis (function call)
operator:
the @code{op()} method. But C++-style subscripting with square brackets
@samp{[]} is not available.
-Here are a couple of examples that all construct the same 2x2 diagonal
-matrix:
+Here are a couple of examples of constructing matrices:
@example
@{
symbol a("a"), b("b");
- ex e;
matrix M(2, 2);
M(0, 0) = a;
M(1, 1) = b;
- e = M;
-
- e = matrix(2, 2, lst(a, 0, 0, b));
+ cout << M << endl;
+ // -> [[a,0],[0,b]]
- e = lst_to_matrix(lst(lst(a, 0), lst(0, b)));
+ cout << matrix(2, 2, lst(a, 0, 0, b)) << endl;
+ // -> [[a,0],[0,b]]
- e = diag_matrix(lst(a, b));
+ cout << lst_to_matrix(lst(lst(a, 0), lst(0, b))) << endl;
+ // -> [[a,0],[0,b]]
- cout << e << endl;
+ cout << diag_matrix(lst(a, b)) << endl;
// -> [[a,0],[0,b]]
+
+ cout << unit_matrix(3) << endl;
+ // -> [[1,0,0],[0,1,0],[0,0,1]]
+
+ cout << symbolic_matrix(2, 3, "x") << endl;
+ // -> [[x00,x01,x02],[x10,x11,x12]]
@}
@end example
The @code{matrix} class provides a couple of additional methods for
computing determinants, traces, and characteristic polynomials:
+@cindex @code{determinant()}
+@cindex @code{trace()}
+@cindex @code{charpoly()}
@example
ex matrix::determinant(unsigned algo = determinant_algo::automatic) const;
ex matrix::trace(void) const;
// -> 2*A.j.i
cout << indexed(B, sy_anti(), i, j)
+ indexed(B, sy_anti(), j, i) << endl;
- // -> -B.j.i
+ // -> 0
cout << indexed(B, sy_anti(), i, j, k)
- + indexed(B, sy_anti(), j, i, k) << endl;
+ - indexed(B, sy_anti(), j, k, i) << endl;
// -> 0
...
@end example
dummy nor free indices.
To be recognized as a dummy index pair, the two indices must be of the same
-class and dimension and their value must be the same single symbol (an index
-like @samp{2*n+1} is never a dummy index). If the indices are of class
+class and their value must be the same single symbol (an index like
+@samp{2*n+1} is never a dummy index). If the indices are of class
@code{varidx} they must also be of opposite variance; if they are of class
@code{spinidx} they must be both dotted or both undotted.
multiples of the unity element, even though it's customary to omit it.
E.g. instead of @code{dirac_gamma(mu)*(dirac_slash(q,4)+m)} you have to
write @code{dirac_gamma(mu)*(dirac_slash(q,4)+m*dirac_ONE())}. Otherwise,
-GiNaC may produce incorrect results.
+GiNaC will complain and/or produce incorrect results.
@cindex @code{dirac_gamma5()}
-There's a special element @samp{gamma5} that commutes with all other
-gammas and in 4 dimensions equals @samp{gamma~0 gamma~1 gamma~2 gamma~3},
-provided by
+There is a special element @samp{gamma5} that commutes with all other
+gammas, has a unit square, and in 4 dimensions equals
+@samp{gamma~0 gamma~1 gamma~2 gamma~3}, provided by
@example
ex dirac_gamma5(unsigned char rl = 0);
@end example
-@cindex @code{dirac_gamma6()}
-@cindex @code{dirac_gamma7()}
-The two additional functions
+@cindex @code{dirac_gammaL()}
+@cindex @code{dirac_gammaR()}
+The chiral projectors @samp{(1+/-gamma5)/2} are also available as proper
+objects, constructed by
@example
-ex dirac_gamma6(unsigned char rl = 0);
-ex dirac_gamma7(unsigned char rl = 0);
+ex dirac_gammaL(unsigned char rl = 0);
+ex dirac_gammaR(unsigned char rl = 0);
@end example
-return @code{dirac_ONE(rl) + dirac_gamma5(rl)} and @code{dirac_ONE(rl) - dirac_gamma5(rl)},
-respectively.
+They observe the relations @samp{gammaL^2 = gammaL}, @samp{gammaR^2 = gammaR},
+and @samp{gammaL gammaR = gammaR gammaL = 0}.
@cindex @code{dirac_slash()}
Finally, the function
Such slashed expressions are printed with a trailing backslash, e.g. @samp{e\}.
In products of dirac gammas, superfluous unity elements are automatically
-removed, squares are replaced by their values and @samp{gamma5} is
-anticommuted to the front. The @code{simplify_indexed()} function performs
-contractions in gamma strings, for example
+removed, squares are replaced by their values, and @samp{gamma5}, @samp{gammaL}
+and @samp{gammaR} are moved to the front.
+
+The @code{simplify_indexed()} function performs contractions in gamma strings,
+for example
@example
@{
@math{1-v^2/c^2+O(v^10)}, without that call we would just have a long
series raised to the power @math{-2}.
-@cindex M@'echain's formula
+@cindex Machin's formula
As another instructive application, let us calculate the numerical
value of Archimedes' constant
@tex
$\pi$
@end tex
(for which there already exists the built-in constant @code{Pi})
-using M@'echain's amazing formula
+using Machin's amazing formula
@tex
$\pi=16$~atan~$\!\left(1 \over 5 \right)-4$~atan~$\!\left(1 \over 239 \right)$.
@end tex
#include <ginac/ginac.h>
using namespace GiNaC;
-ex mechain_pi(int degr)
+ex machin_pi(int degr)
@{
symbol x;
ex pi_expansion = series_to_poly(atan(x).series(x,degr));
using std::endl; // ...dealing with this namespace std.
ex pi_frac;
for (int i=2; i<12; i+=2) @{
- pi_frac = mechain_pi(i);
+ pi_frac = machin_pi(i);
cout << i << ":\t" << pi_frac << endl
<< "\t" << pi_frac.evalf() << endl;
@}