Add patterns for integration
This functionality does not run in MATLAB.
int::addpattern(pat
,x
,res
, <[var, …], <[cond, …]>
>) int::addpattern(pat
,x = u .. v
,res
, <[var, …], <[cond, …]>
>)
int::addpattern(pat, x, res)
teaches int
to make use of
.
int::addpattern(pat, x=u..v, res)
teaches int
that
.
A large part of a computer algebra system's integration abilities
stems from mathematical pattern matching. The MuPAD^{®} pattern matcher
can be extended at runtime with int::addpattern
.
Unless further limited by conditions in the fifth argument,
pattern variables listed in the fourth argument represent arbitrary MuPAD expressions
not containing the variable of integration, x
.
Any identifier can be used as the variable of integration in
a call to int::addpattern
, and any identifier can
be used in calls to int
.
They need not be identical.
For definite integration, each integration bound is either an arithmetical expression which may contain pattern variables, or an identifier which can be used as a variable in the result and condition terms.
Users can include additional conditions by giving additional
arguments. These conditions, as well as the result, are protected
from premature evaluation, i.e., it is not necessary to write hold(
_not @ iszero )(a^2b)
, a simple not iszero(a^2b)
suffices.
The difference between not iszero(a^2b)
and a^2b
<> 0
when given as a condition is that the latter
takes into account asuumptions on the identifiers encountered, while
the first does not. Cf. Example 4.
Patterns introduced by int::addpattern
are
also used in recursive calls of the integrator and are automatically
extended to include simple applications of integration by change of
variables. Cf. Example 1.
Patterns added by int::addpattern
are not replaced
by later calls, they remain active. int
selects the most simple result found.
There is no way to remove patterns once added. Cf. Example 5.
Calling int::addpattern
changes the expressions
returned by future calls to int
.
Additionally, the remembered values of previous calls to int
are forgotten.
Not surprisingly, MuPAD does not know how to integrate the function foo:
int(foo(x), x)
We add a pattern for this function:
int::addpattern(foo(x), x, foo(x)^x)
int(foo(x), x)
Note that this pattern is also used indirectly:
int(x*foo(x^2), x)
intlib::byparts(int(foo(x)*sin(x), x), foo(x))
Definite integrals can be added similarly. Note that the result does not depend on the integration variable:
int::addpattern(wilma(x), x=0..1, fred)
int(wilma(x), x=0..1)
The above pattern will not match integrals with different integration bounds:
int(wilma(x), x=0..2)
Integration bounds may also contain variables occurring in the pattern or result:
int::addpattern(wilma(x, a), x=0..a, fred(a), [a])
int(wilma(x,2), x=0..2)
The integration variable in the call to int::addpattern
need
not be the same as used in the integration call:
int::addpattern(1/(t^2*(ln(t)+1)), t, E*Ei(ln(t)+1))
int(cos(y)/sin(y)^2/(ln(sin(y)) + 1), y)
Conditions are checked using is
and therefore react to assumptions:
int::addpattern(1/(a+b*tan(x)^2), x, x/(ab)  b/(2*(ab)*sqrt(a*b)) * ln((b*tan(x)sqrt(a*b)) /(b*tan(x)+sqrt(a*b))), [a, b], [a*b < 0])
int::addpattern(1/(a+b*tan(x)^2), x, x/(ab)  b/((ab)*sqrt(a*b)) * arctan(b*tan(x)/ sqrt(a*b)), [a, b], [a*b > 0])
int(1/(3+a*tan(x)^2), x) assuming a > 0
int(1/(3+a*tan(x)^2), x) assuming a < 0
If either the conditions are not satisfied or substituting the values into the result yields an error, the pattern is ignored. In the patterns above, the case a = b causes a division by zero. There is no need to include a condition to guard against this case, though, MuPAD simply computes the integral as usual:
int(1/(3+3*tan(x)^2), x)
Assume we have added the following pattern:
int::addpattern(f(x), x, f(x)^x):
Now, f is a pretty generic name, so we could later regard it as a different function and attempt to redefine its antiderivative:
int::addpattern(f(x), x, 1/sin(f(x))):
int(f(x), x)
What happened?
As it turns out, int::addpattern
has simply added the
new pattern, and since f(x)^{x} is
considered "simpler" than
,
the result of the first pattern added is still returned.
This behavior is reasonable, since there may be multiple ways of representing an antiderivative and depending on parameter values, one or the other may be preferable:
int::addpattern(f(a, x), x, x*f1(a, x^a), [a]): int::addpattern(f(a, x), x, x*f2(a, x^(1a)), [a]):
int(f(0, x), x)
int(f(1, x), x)
int(f(a, x), x)

The pattern to match: an arithmetical expression in 

The variable of integration: an 

The interval of integration for a definite integral: arithmetical expressions or identifiers. 

The antiderivative pattern: an arithmetical expression 

"pattern variables": placeholders in 

Conditions on the pattern variables 
Object of type DOM_NULL