]> www.ginac.de Git - ginac.git/blobdiff - doc/tutorial/ginac.texi
- list delimiters are now { }, matrix delimiters are now [ ]
[ginac.git] / doc / tutorial / ginac.texi
index 04c5024adf7edaf585c933afe397acf09730aa6e..e81e5b95f177191ac6dcf3db368ddcd1b7f81f1e 100644 (file)
@@ -350,14 +350,20 @@ a matrix class for this purpose but we can see what it can do using
 @example
 > lsolve(a+x*y==z,x);
 y^(-1)*(z-a);
-> lsolve([3*x+5*y == 7, -2*x+10*y == -5], [x, y]);
-[x==19/8,y==-1/40]
-> M = [[ [[1, 3]], [[-3, 2]] ]];
-[[ [[1,3]], [[-3,2]] ]]
+> lsolve(@{3*x+5*y == 7, -2*x+10*y == -5@}, @{x, y@});
+@{x==19/8,y==-1/40@}
+> M = [ [1, 3], [-3, 2] ];
+[[1,3],[-3,2]]
 > determinant(M);
 11
 > charpoly(M,lambda);
 lambda^2-3*lambda+11
+> A = [ [1, 1], [2, -1] ];
+[[1,1],[2,-1]]
+> A+2*M;
+[[1,1],[2,-1]]+2*[[1,3],[-3,2]]
+> evalm(");
+[[3,7],[-4,3]]
 @end example
 
 Multivariate polynomials and rational functions may be expanded,
@@ -758,7 +764,7 @@ $\sqrt{2}$
 @dots{}
 @item @code{pseries} @tab Power Series, e.g. @math{x-1/6*x^3+1/120*x^5+O(x^7)}
 @item @code{function} @tab A symbolic function like @math{sin(2*x)}
-@item @code{lst} @tab Lists of expressions [@math{x}, @math{2*y}, @math{3+z}]
+@item @code{lst} @tab Lists of expressions @{@math{x}, @math{2*y}, @math{3+z}@}
 @item @code{matrix} @tab @math{n}x@math{m} matrices of expressions
 @item @code{relational} @tab A relation like the identity @math{x}@code{==}@math{y}
 @item @code{indexed} @tab Indexed object like @math{A_ij}
@@ -1161,8 +1167,8 @@ Finally you can append or prepend an expression to a list with the
 
 @example
     // ...
-    l.append(4*x);   // l is now [x, 2, y, x+y, 4*x]
-    l.prepend(0);    // l is now [0, x, 2, y, x+y, 4*x]
+    l.append(4*x);   // l is now @{x, 2, y, x+y, 4*x@}
+    l.prepend(0);    // l is now @{0, x, 2, y, x+y, 4*x@}
 @}
 @end example
 
@@ -1786,7 +1792,7 @@ It is output as @samp{eps}:
 @}
 @end example
 
-The matrix representation of the spinor metric is @code{[[ [[ 0, 1 ]], [[ -1, 0 ]] ]]}.
+The matrix representation of the spinor metric is @code{[[0, 1], [-1, 0]]}.
 
 @cindex @code{epsilon_tensor()}
 @cindex @code{lorentz_eps()}
@@ -1832,11 +1838,11 @@ and scalar products):
 
     ex e = indexed(A, i, j) * indexed(X, j);
     cout << e.simplify_indexed() << endl;
-     // -> [[ [[2*y+x]], [[4*y+3*x]] ]].i
+     // -> [[2*y+x],[4*y+3*x]].i
 
     e = indexed(A, i, j) * indexed(X, i) + indexed(X, j) * 2;
     cout << e.simplify_indexed() << endl;
-     // -> [[ [[3*y+3*x,6*y+2*x]] ]].j
+     // -> [[3*y+3*x,6*y+2*x]].j
 @}
 @end example
 
@@ -1970,6 +1976,10 @@ Other representation labels yield a different @code{return_type_tinfo()},
 but it's the same for any two objects with the same label. This is also true
 for color objects.
 
+As a last note, positive integer powers of non-commutative objects are
+automatically expanded in GiNaC. For example, @code{pow(a*b, 2)} becomes
+@samp{a*b*a*b} if @samp{a} and @samp{b} are non-commutative expressions).
+
 
 @cindex @code{clifford} (class)
 @subsection Clifford algebra
@@ -2292,6 +2302,7 @@ avoided.
 * Rational Expressions::            Working with rational functions.
 * Symbolic Differentiation::
 * Series Expansion::                Taylor and Laurent expansion.
+* Symmetrization::
 * Built-in Functions::              List of predefined mathematical functions.
 * Input/Output::                    Input and output of expressions.
 @end menu
@@ -2640,7 +2651,7 @@ The matching algorithm works as follows:
   fails (i.e. a sum only matches a sum, a function only matches a function,
   etc.).
 @item If the pattern is a function, it only matches the same function
-  (i.e. @samp{sin($0)} matches @samp{sin(x)} but doesn't match @samp{exp(x)}.
+  (i.e. @samp{sin($0)} matches @samp{sin(x)} but doesn't match @samp{exp(x)}).
 @item Except for sums and products, the match fails if the number of
   subexpressions (@code{nops()}) is not equal to the number of subexpressions
   of the pattern.
@@ -2677,47 +2688,47 @@ match fails, and the list of wildcard replacements otherwise):
 
 @example
 > match((x+y)^a,(x+y)^a);
-[]
+@{@}
 > match((x+y)^a,(x+y)^b);
 FAIL
 > match((x+y)^a,$1^$2);
-[$1==x+y,$2==a]
+@{$1==x+y,$2==a@}
 > match((x+y)^a,$1^$1);
 FAIL
 > match((x+y)^(x+y),$1^$1);
-[$1==x+y]
+@{$1==x+y@}
 > match((x+y)^(x+y),$1^$2);
-[$1==x+y,$2==x+y]
+@{$1==x+y,$2==x+y@}
 > match((a+b)*(a+c),($1+b)*($1+c));
-[$1==a]
+@{$1==a@}
 > match((a+b)*(a+c),(a+$1)*(a+$2));
-[$1==c,$2==b]
+@{$1==c,$2==b@}
   (Unpredictable. The result might also be [$1==c,$2==b].)
 > match((a+b)*(a+c),($1+$2)*($1+$3));
   (The result is undefined. Due to the sequential nature of the algorithm
    and the re-ordering of terms in GiNaC, the match for the first factor
-   may be [$1==a,$2==b] in which case the match for the second factor
-   succeeds, or it may be [$1==b,$2==a] which causes the second match to
+   may be @{$1==a,$2==b@} in which case the match for the second factor
+   succeeds, or it may be @{$1==b,$2==a@} which causes the second match to
    fail.)
-> match(2*(x+y)+2*z-2,2*$1+$2);
-  (This is also ambiguous and may return either [$1==z,$2==-2+2*x+2*y] or
-   [$1=x+y,$2=2*z-2].)
+> match(a*(x+y)+a*z+b,a*$1+$2);
+  (This is also ambiguous and may return either @{$1==z,$2==a*(x+y)+b@} or
+   @{$1=x+y,$2=a*z+b@}.)
 > match(a+b+c+d+e+f,c);
 FAIL
 > match(a+b+c+d+e+f,c+$0);
-[$0==a+e+b+f+d]
+@{$0==a+e+b+f+d@}
 > match(a+b+c+d+e+f,c+e+$0);
-[$0==a+b+f+d]
+@{$0==a+b+f+d@}
 > match(a+b,a+b+$0);
-[$0==0]
+@{$0==0@}
 > match(a*b^2,a^$1*b^$2);
 FAIL
-  (The matching is syntactic, not algebraic, and "a" doesn't match "a^$0"
-   even if a==a^x for x==0.)
+  (The matching is syntactic, not algebraic, and "a" doesn't match "a^$1"
+   even if a==a^1.)
 > match(x*atan2(x,x^2),$0*atan2($0,$0^2));
-[$0==x]
+@{$0==x@}
 > match(atan2(y,x^2),atan2(y,$0));
-[$0==x^2]
+@{$0==x^2@}
 @end example
 
 @cindex @code{has()}
@@ -2779,6 +2790,8 @@ b^4+a^4+(x+y)^4
 (a+b+c)^2
 > subs((a+b+c)^2,a+b+$1==x+$1);
 (x+c)^2
+> subs(a+2*b,a+b=x);
+a+2*b
 > subs(4*x^3-2*x^2+5*x-1,x==a);
 -1+5*a-2*a^2+4*a^3
 > subs(4*x^3-2*x^2+5*x-1,x^$0==a^$0);
@@ -2797,7 +2810,7 @@ The last example would be written in C++ in this way:
     e = a*pow(sin(x+y), 2) + a*pow(cos(x+y), 2) + b;
     e = e.subs(pow(cos(wild()), 2) == 1-pow(sin(wild()), 2));
     cout << e.expand() << endl;
-     // -> "b+a"
+     // -> a+b
 @}
 @end example
 
@@ -3125,16 +3138,20 @@ normalized to @code{P_a/P_b} = @code{(4*y+z)/(y+3*z)}.
 @cindex denominator
 @cindex @code{numer()}
 @cindex @code{denom()}
+@cindex @code{numer_denom()}
 
 The numerator and denominator of an expression can be obtained with
 
 @example
 ex ex::numer();
 ex ex::denom();
+ex ex::numer_denom();
 @end example
 
 These functions will first normalize the expression as described above and
-then return the numerator or denominator, respectively.
+then return the numerator, denominator, or both as a list, respectively.
+If you need both numerator and denominator, calling @code{numer_denom()} is
+faster than using @code{numer()} and @code{denom()} separately.
 
 
 @subsection Converting to a rational expression
@@ -3240,7 +3257,7 @@ When you run it, it produces the sequence @code{1}, @code{-1}, @code{5},
 @code{i} by two since all odd Euler numbers vanish anyways.
 
 
-@node Series Expansion, Built-in Functions, Symbolic Differentiation, Methods and Functions
+@node Series Expansion, Symmetrization, Symbolic Differentiation, Methods and Functions
 @c    node-name, next, previous, up
 @section Series expansion
 @cindex @code{series()}
@@ -3350,7 +3367,51 @@ program, it will type out:
 @end example
 
 
-@node Built-in Functions, Input/Output, Series Expansion, Methods and Functions
+@node Symmetrization, Built-in Functions, Series Expansion, Methods and Functions
+@c    node-name, next, previous, up
+@section Symmetrization
+@cindex @code{symmetrize()}
+@cindex @code{antisymmetrize()}
+
+The two methods
+
+@example
+ex ex::symmetrize(const lst & l);
+ex ex::antisymmetrize(const lst & l);
+@end example
+
+symmetrize an expression by returning the symmetric or antisymmetric sum
+over all permutations of the specified list of objects, weighted by the
+number of permutations.
+
+The two additional methods
+
+@example
+ex ex::symmetrize();
+ex ex::antisymmetrize();
+@end example
+
+symmetrize or antisymmetrize an expression over its free indices.
+
+Symmetrization is most useful with indexed expressions but can be used with
+almost any kind of object (anything that is @code{subs()}able):
+
+@example
+@{
+    idx i(symbol("i"), 3), j(symbol("j"), 3), k(symbol("k"), 3);
+    symbol A("A"), B("B"), a("a"), b("b"), c("c");
+                                           
+    cout << indexed(A, i, j).symmetrize() << endl;
+     // -> 1/2*A.j.i+1/2*A.i.j
+    cout << indexed(A, i, j, k).antisymmetrize(lst(i, j)) << endl;
+     // -> -1/2*A.j.i.k+1/2*A.i.j.k
+    cout << lst(a, b, c).symmetrize(lst(a, b, c)) << endl;
+     // -> 1/6*@{a,b,c@}+1/6*@{c,a,b@}+1/6*@{b,a,c@}+1/6*@{c,b,a@}+1/6*@{b,c,a@}+1/6*@{a,c,b@}
+@}
+@end example
+
+
+@node Built-in Functions, Input/Output, Symmetrization, Methods and Functions
 @c    node-name, next, previous, up
 @section Predefined mathematical functions