but it's the same for any two objects with the same label. This is also true
for color objects.
+As a last note, powers of non-commutative objects are not allowed in GiNaC.
+You can use the function
+
+@example
+ex ncpow(const ex & basis, unsigned exponent)
+@end example
+
+instead which returns an expanded product (e.g. @code{ncpow(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
* 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
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
@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
@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()}
@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