Documentation |
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^2-b), a simple not iszero(a^2-b) suffices.
The difference between not iszero(a^2-b) and a^2-b <> 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/(a-b) - b/(2*(a-b)*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/(a-b) - b/((a-b)*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^(1-a)), [a]):
int(f(0, x), x)
int(f(1, x), x)
int(f(a, x), x)
pat |
The pattern to match: an arithmetical expression in x. |
x |
The variable of integration: an identifier. |
u .. v |
The interval of integration for a definite integral: arithmetical expressions or identifiers. |
res |
The antiderivative pattern: an arithmetical expression |
[var, …] |
"pattern variables": placeholders in pat and ret, i.e., identifiers that do not represent themselves but almost arbitrary MuPAD expressions not containing x and restricted by the conditions in the fifth parameter. |
[cond, …] |
Conditions on the pattern variables |