 evalindets - Maple Help

evalindets

transform all subexpressions of a given type Calling Sequence evalindets( expr, atype, transformer, rest ) evalindets[flat]( expr, atype, transformer, rest ) evalindets[nocache]( expr, atype, transformer, rest ) evalindets[N]( expr, atype, preargs, transformer, rest ) Parameters

 expr - anything; any Maple expression atype - type; any Maple type expression transformer - anything; an expression (typically, a procedure) to be called on each subexpression processed rest - anything; (optional) expression sequence of extra arguments to be passed to transformer N - integer; the number of arguments passed to the transformer before the subexpression preargs - anything; expression sequence of N-1 arguments to be passed to the transformer before the subexpression Description

 • The command evalindets is a particular combination of calls to eval and indets that allows you to efficiently transform all subexpressions of a given type by some algorithm. It encapsulates a common "pattern" used in expression manipulation and transformation.
 • Each subexpression of type atype is transformed by the supplied transformer procedure. Then, each subexpression is replaced in the original expression, using eval, with the corresponding transformed expression.
 • If the flat option is supplied as an index to the evalindets command, then Maple will not recursively look inside any subexpressions of the given atype for further (nested) subexpressions of that type. This provides a hint to Maple that it can use a somewhat faster algorithm in this special case.
 • If the flat option is not supplied, then subexpressions of type atype at deeper levels of nesting are processed and replaced before subexpressions at shallower levels of nesting. This is illustrated in an example below.
 • By default, evalindets uses a cache to avoid repetitive type checking and repeated calls to transformer for multiple instances of the same subexpression (this cache is limited in size, so repeated calls may occur, but there is no guarantee that they will). The nocache option, specified as an index to the evalindets command, prevents the use of this cache, and guarantees that transformer will be called once for each instance of any common subexpression matching atype. Note that using the nocache option can dramatically lower the performance of evalindets on expressions containing many common subexpressions.
 • If evalindets is called with an integer index, N, then each subexpression to be processed by transformer will be passed as the N-th argument to transformer. The sequence of N-1 arguments of evalindets between atype and transformer will be passed as the first N-1 arguments to transformer.
 • A numeric index may be combined with the flat option, and they can be specified in either order. Examples

This example changes every call to $F$ to a call to $H$.

 > $\mathrm{evalindets}\left(F\left(G\left(x\right),F\left(x,y\right)\right),'\mathrm{specfunc}\left(\mathrm{anything},F\right)',f↦\mathrm{subsop}\left(0=H,f\right)\right)$
 ${H}{}\left({G}{}\left({x}\right){,}{H}{}\left({x}{,}{y}\right)\right)$ (1)
 > $\mathrm{evalindets}\left[\mathrm{flat}\right]\left(F\left(2.3\right)+G\left(4,1.1\right),'\mathrm{float}',\mathrm{trunc}\right)$
 ${F}{}\left({2}\right){+}{G}{}\left({4}{,}{1}\right)$ (2)
 > $\mathrm{evalindets}\left[\mathrm{flat}\right]\left(F\left(G\left(x\right),F\left(x,y\right)\right),'\mathrm{specfunc}\left(\mathrm{anything},F\right)',f↦\mathrm{subsop}\left(0=H,f\right)\right)$
 ${H}{}\left({G}{}\left({x}\right){,}{F}{}\left({x}{,}{y}\right)\right)$ (3)
 > $\mathrm{evalindets}\left(F\left(G\left(x\right),F\left(x,y\right)\right),'\mathrm{specfunc}\left(\mathrm{symbol},F\right)',f↦\mathrm{subsop}\left(0=H,f\right)\right)$
 ${F}{}\left({G}{}\left({x}\right){,}{H}{}\left({x}{,}{y}\right)\right)$ (4)

Shift all symbols by a constant of $\mathrm{\pi }$.

 > $\mathrm{evalindets}\left(\left[\mathrm{sin}\left(x\right),\mathrm{cos}\left(y\right),\mathrm{tan}\left(z\right)\right],'\mathrm{symbol}',y↦y+\mathrm{\pi }\right)$
 $\left[{-}{\mathrm{sin}}{}\left({x}\right){,}{-}{\mathrm{cos}}{}\left({y}\right){,}{\mathrm{tan}}{}\left({z}\right)\right]$ (5)

 > $\mathrm{expr}≔\mathrm{sin}\left(x+y\right)+x\left(x+1\right)+\left(x+1\right)\left(x+2\right)$
 ${\mathrm{expr}}{≔}{\mathrm{sin}}{}\left({x}{+}{y}\right){+}{x}{}\left({x}{+}{1}\right){+}\left({x}{+}{1}\right){}\left({x}{+}{2}\right)$ (6)
 > $\mathrm{evalindets}\left(\mathrm{expr},'\mathrm{*}',\mathrm{expand}\right)$
 ${\mathrm{sin}}{}\left({x}{+}{y}\right){+}{2}{}{{x}}^{{2}}{+}{4}{}{x}{+}{2}$ (7)
 > $\mathrm{expand}\left(\mathrm{expr}\right)$
 ${\mathrm{sin}}{}\left({x}\right){}{\mathrm{cos}}{}\left({y}\right){+}{\mathrm{cos}}{}\left({x}\right){}{\mathrm{sin}}{}\left({y}\right){+}{2}{}{{x}}^{{2}}{+}{4}{}{x}{+}{2}$ (8)

Using evalindets, you can avoid expanding things you might not want expanded.

 > $\mathrm{evalindets}\left(\mathrm{sin}\left(\left(3+I\right)\mathrm{\pi }\right)+{\left(x+y\right)}^{100},'\mathrm{sin}\left(\mathrm{anything}\right)',\mathrm{expand}\right)$
 ${-}{I}{}{\mathrm{sinh}}{}\left({\mathrm{\pi }}\right){+}{\left({x}{+}{y}\right)}^{{100}}$ (9)

Optional arguments may be passed to the transformer.

 > $\mathrm{expr}≔\mathrm{sin}\left(x+y\right)+x\left(x+3\right)+\mathrm{exp}\left(x+1\right)\left(y+2\right)$
 ${\mathrm{expr}}{≔}{\mathrm{sin}}{}\left({x}{+}{y}\right){+}{x}{}\left({x}{+}{3}\right){+}{{ⅇ}}^{{x}{+}{1}}{}\left({y}{+}{2}\right)$ (10)
 > $\mathrm{evalindets}\left(\mathrm{expr},'\mathrm{*}',\mathrm{expand}\right)$
 ${\mathrm{sin}}{}\left({x}{+}{y}\right){+}{{x}}^{{2}}{+}{3}{}{x}{+}{{ⅇ}}^{{x}}{}{ⅇ}{}{y}{+}{2}{}{{ⅇ}}^{{x}}{}{ⅇ}$ (11)
 > $\mathrm{evalindets}\left(\mathrm{expr},'\mathrm{*}',\mathrm{expand},\mathrm{exp}\right)$
 ${\mathrm{sin}}{}\left({x}{+}{y}\right){+}{{x}}^{{2}}{+}{3}{}{x}{+}{{ⅇ}}^{{x}{+}{1}}{}{y}{+}{2}{}{{ⅇ}}^{{x}{+}{1}}$ (12)

The following example demonstrates the use of evalindets[nocache]

In this first case, without nocache, the transformer function will be called at least once, and most likely only once, though this is not guaranteed, for each matching subexpression:

 > $\mathrm{expr}≔{x}^{2}+3x+f\left(x\right):$
 > $\mathrm{count}≔0:$
 > evalindets(expr,symbol,proc(s) global count; count:=count+1; cat(s,count) end);
 ${{\mathrm{x1}}}^{{2}}{+}{3}{}{\mathrm{x1}}{+}{f}{}\left({\mathrm{x1}}\right)$ (13)

In this next case, with the nocache option, the transformer function is guaranteed to be called once for every instance of each matching subexpression:

 > $\mathrm{count}≔0:$
 > evalindets['nocache'](expr,symbol,proc(s) global count; count:=count+1; cat(s,count) end);
 ${{\mathrm{x1}}}^{{2}}{+}{3}{}{\mathrm{x2}}{+}{f}{}\left({\mathrm{x3}}\right)$ (14)

The following example demonstrates the use of evalindets[N]

The evalindets[N] calling sequence is used when you want to pass additional arguments to the transformer function before the subexpression to be transformed:

 > $\mathrm{expr}≔{f\left(x,y\right)}^{2}+3f\left(x,y\right)+3;$$\mathrm{evalindets}\left[2\right]\left(\mathrm{expr},\mathrm{specfunc}\left(f\right),1,\mathrm{op}\right)$
 ${\mathrm{expr}}{≔}{{f}{}\left({x}{,}{y}\right)}^{{2}}{+}{3}{}{f}{}\left({x}{,}{y}\right){+}{3}$
 ${{x}}^{{2}}{+}{3}{}{x}{+}{3}$ (15)

This calls op(1,x) for each subexpression, _x_ of type specfunc(f).

Without the [N] option, the alternative would be to introduce a procedure that takes a single argument $x$, and returns op(1,x):

 > $\mathrm{evalindets}\left(\mathrm{expr},\mathrm{specfunc}\left(f\right),x↦\mathrm{op}\left(1,\mathrm{ex}\right)\right)$
 ${{\mathrm{ex}}}^{{2}}{+}{3}{}{\mathrm{ex}}{+}{3}$ (16)

This is less efficient because of the extra level of procedure calling. The subsindets command calls your procedure which calls op, instead of just calling op directly.

This example illustrates the remark above about the order in which subexpressions at various levels of nesting depth are processed. In it, we replace each integer in the expression that occurs inside a function call with a name that indicates the name of the closest enclosing function. This is done by using a second call to evalindets as the transformer.

 > $\mathrm{expr}≔2+f\left(4,g\left(h\left(6\right)\right)\right)$
 ${\mathrm{expr}}{≔}{2}{+}{f}{}\left({4}{,}{g}{}\left({h}{}\left({6}\right)\right)\right)$ (17)
 > $\mathrm{evalindets}\left(\mathrm{expr},\mathrm{function},\mathrm{fn}↦\mathrm{evalindets}\left(\mathrm{fn},\mathrm{integer},i↦\mathrm{cat}\left(i,"in",\mathrm{op}\left(0,\mathrm{fn}\right)\right)\right)\right)$
 ${2}{+}{f}{}\left({\mathrm{4 in f}}{,}{g}{}\left({h}{}\left({\mathrm{6 in h}}\right)\right)\right)$ (18)

This works because the outer call to evalindets processes h(6) (turning it into h(6 in f)) before it processes the calls to g or f; so when the transformer processes those calls, the integer 6 doesn't occur anymore. Compatibility

 • The evalindets command was updated in Maple 2015.
 • The N parameter was introduced in Maple 2015.
 • The preargs parameter was updated in Maple 2015.
 • The nocache option was introduced in Maple 2015.