[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |
5.3 Substituting expressions
Algebraic objects inside expressions can be replaced with arbitrary
expressions via the .subs()
method:
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); |
In the first form, subs()
accepts a relational of the form
‘object == expression’ or a lst
of such relationals:
{ symbol x("x"), y("y"); ex e1 = 2*x^2-4*x+3; cout << "e1(7) = " << e1.subs(x == 7) << endl; // -> 73 ex e2 = x*y + x; cout << "e2(-2, 4) = " << e2.subs(lst(x == -2, y == 4)) << endl; // -> -10 } |
If you specify multiple substitutions, they are performed in parallel, so e.g.
subs(lst(x == y, y == x))
exchanges ‘x’ and ‘y’.
The second form of subs()
takes an exmap
object which is a
pair associative container that maps expressions to expressions (currently
implemented as a std::map
). This is the most efficient one of the
three 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:
{ 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; } |
The third form of 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
{ symbol x("x"), y("y"); ex e2 = x*y + x; cout << "e2(-2, 4) = " << e2.subs(lst(x, y), lst(-2, 4)) << endl; } |
The optional last argument to subs()
is a combination of
subs_options
flags. There are three options available:
subs_options::no_pattern
disables pattern matching, which makes
large subs()
operations significantly faster if you are not using
patterns. The second option, subs_options::algebraic
enables
algebraic substitutions in products and powers.
See section Pattern matching and advanced substitutions, for more information
about patterns and algebraic substitutions. The third option,
subs_options::no_index_renaming
disables the feature that dummy
indices are renamed if the substitution could give a result in which a
dummy index occurs more than two times. This is sometimes necessary if
you want to use subs()
to rename your dummy indices.
subs()
performs syntactic substitution of any complete algebraic
object; it does not try to match sub-expressions as is demonstrated by the
following example:
{ symbol x("x"), y("y"), z("z"); ex e1 = pow(x+y, 2); cout << e1.subs(x+y == 4) << endl; // -> 16 ex e2 = sin(x)*sin(y)*cos(x); cout << e2.subs(sin(x) == cos(x)) << endl; // -> cos(x)^2*sin(y) ex e3 = x+y+z; cout << e3.subs(x+y == 4) << endl; // -> x+y+z // (and not 4+z as one might expect) } |
A more powerful form of substitution using wildcards is described in the next section.
[ < ] | [ > ] | [ << ] | [ Up ] | [ >> ] | [Top] | [Contents] | [Index] | [ ? ] |