hierarchy and describe the classes of objects that are handled by
@code{ex}.
+@subsection Note: Expressions and STL containers
+
+GiNaC expressions (@code{ex} objects) have value semantics (they can be
+assigned, reassigned and copied like integral types) but the operator
+@code{<} doesn't provide a well-defined ordering on them. In STL-speak,
+expressions are @samp{Assignable} but not @samp{LessThanComparable}.
+
+This implies that in order to use expressions in sorted containers such as
+@code{std::map<>} and @code{std::set<>} you have to supply a suitable
+comparison predicate. GiNaC provides such a predicate, called
+@code{ex_is_less}. For example, a set of expressions should be defined
+as @code{std::set<ex, ex_is_less>}.
+
+Unsorted containers such as @code{std::vector<>} and @code{std::list<>}
+don't pose a problem. A @code{std::vector<ex>} works as expected.
+
+@xref{Information About Expressions}, for more about comparing and ordering
+expressions.
+
@node Automatic evaluation, Error handling, Expressions, Basic Concepts
@c node-name, next, previous, up
The GiNaC class @code{lst} serves for holding a @dfn{list} of arbitrary
expressions. They are not as ubiquitous as in many other computer algebra
packages, but are sometimes used to supply a variable number of arguments of
-the same type to GiNaC methods such as @code{subs()} and @code{to_rational()},
-so you should have a basic understanding of them.
+the same type to GiNaC methods such as @code{subs()} and some @code{matrix}
+constructors, so you should have a basic understanding of them.
Lists of up to 16 expressions can be directly constructed from single
expressions:
@example
ex ex::subs(const ex & e, unsigned options = 0);
+ex ex::subs(const exmap & m, unsigned options = 0);
ex ex::subs(const lst & syms, const lst & repls, unsigned options = 0);
@end example
If you specify multiple substitutions, they are performed in parallel, so e.g.
@code{subs(lst(x == y, y == x))} exchanges @samp{x} and @samp{y}.
-The second form of @code{subs()} takes two lists, one for the objects to be
+The second form of @code{subs()} takes an @code{exmap} object which is a
+pair associative container that maps expressions to expressions (currently
+implemented as a @code{std::map}). This is the most efficient one of the
+three @code{subs()} forms and should be used when the number of objects to
+be substituted is large or unknown.
+
+Using this form, the second example from above would look like this:
+
+@example
+@{
+ symbol x("x"), y("y");
+ ex e2 = x*y + x;
+
+ exmap m;
+ m[x] = -2;
+ m[y] = 4;
+ cout << "e2(-2, 4) = " << e2.subs(m) << endl;
+@}
+@end example
+
+The third form of @code{subs()} takes two lists, one for the objects to be
replaced and one for the expressions to be substituted (both lists must
contain the same number of elements). Using this form, you would write
-@code{subs(lst(x, y), lst(y, x))} to exchange @samp{x} and @samp{y}.
+
+@example
+@{
+ symbol x("x"), y("y");
+ ex e2 = x*y + x;
+
+ cout << "e2(-2, 4) = " << e2.subs(lst(x, y), lst(-2, 4)) << endl;
+@}
+@end example
The optional last argument to @code{subs()} is a combination of
@code{subs_options} flags. There are two options available:
above. You do this by calling
@example
-ex ex::to_polynomial(lst &l);
+ex ex::to_polynomial(exmap & m);
+ex ex::to_polynomial(lst & l);
@end example
or
@example
-ex ex::to_rational(lst &l);
+ex ex::to_rational(exmap & m);
+ex ex::to_rational(lst & l);
@end example
-on the expression to be converted. The supplied @code{lst} will be filled
-with the generated temporary symbols and their replacement expressions in
-a format that can be used directly for the @code{subs()} method. It can also
-already contain a list of replacements from an earlier application of
-@code{.to_polynomial()} or @code{.to_rational()}, so it's possible to use
-it on multiple expressions and get consistent results.
+on the expression to be converted. The supplied @code{exmap} or @code{lst}
+will be filled with the generated temporary symbols and their replacement
+expressions in a format that can be used directly for the @code{subs()}
+method. It can also already contain a list of replacements from an earlier
+application of @code{.to_polynomial()} or @code{.to_rational()}, so it's
+possible to use it on multiple expressions and get consistent results.
The difference betwerrn @code{.to_polynomial()} and @code{.to_rational()}
is probably best illustrated with an example:
ex a = pow(sin(x), 2) - pow(cos(x), 2);
ex b = sin(x) + cos(x);
ex q;
- lst l;
- divide(a.to_polynomial(l), b.to_polynomial(l), q);
- cout << q.subs(l) << endl;
+ exmap m;
+ divide(a.to_polynomial(m), b.to_polynomial(m), q);
+ cout << q.subs(m) << endl;
@}
@end example