RATINT: Integrate Rational Functions using the Minimal Algebraic Extension to the Constant Field
Date: 2020-10-07 18:10:00

Up | Next | Prev | PrevTail | Tail

### 16.54 RATINT: Integrate Rational Functions using the Minimal Algebraic Extension to the Constant Field

Author: Neil Langmead

This package was written when the author was a placement student at ZIB Berlin.

#### 16.54.1 Rational Integration

This package implements the Horowitz/ Rothstein/ Trager algorithms [GCL92] for the integration of rational functions in REDUCE. We work within a ﬁeld K of characteristic 0 and functions p,q ∈ K[x]. K is normally the ﬁeld Q of rational numbers, but not always. These procedures return ∫ dx. The aim is to be able to integrate any function of the form p∕q in x, where p and q are polynomials in the ﬁeld Q. The algorithms used avoid algebraic number extensions wherever possible, and in general, express the integral using the minimal algebraic extension ﬁeld.

##### 16.54.1.1 Syntax of ratint

This function has the following syntax:

ratint(p,q,var)

where p∕q is a rational function in var. The output of ratint is a list of two elements: the ﬁrst is the polynomial part of the integral, the second is the logarithmic part. The integral is the sum of these parts.

##### 16.54.1.2 Examples

consider the following examples in REDUCE:

ratint(1,x^2-2,x);
sqrt(2)*x-2 sqrt(2)*x+2
log(-------------) - log(-------------)
sqrt(2) sqrt(2)
{ 0, --------------------------------------- }
2*sqrt(2)
p:=441*x^7+780*x^6-2861*x^5+4085*x^4+7695*x^3+3713*x^2-43253*x
+24500;
q:=9*x^6+6*x^5-65*x^4+20*x^3+135*x^2-154*x+49;
ratint(p,q,x);
49 6 226 5 268 4 1332 3 2809 2 752 256
---*(x + ---*x - ---*x + ----*x - ----*x - ---*x + ---)
2 147 49 49 147 21 9
{----------------------------------------------------------- , 0 }
4 2 3 2 7
x - ---*x - 4*x + 6*x - ---
3 3
k:=36*x^6+126*x^5+183*x^4+(13807/6)*x^3-407*x^2-(3242/5)*x+(3044/15);
l:=(x^2+(7/6)*x+(1/3))^2*(x-(2/5))^3;
ratint(k,l,x);
5271 3 39547 2 31018 7142
------*(x + -------*x - -------*x + -------)
5 52710 26355 26355
{------------------------------------------------,
4 11 3 11 2 2 4
x + ----*x - ----*x - ----*x + ----
30 25 25 75
37451 2 91125 2 128000 1
-------*(log(x - ---) + -------*log(x + ---) - --------*log(x + ---))}
16 5 37451 3 37451 2
ratint(1,x^2+1,x);
2 1
{0,log_sum(beta,beta + ---,0,log(2*beta*x - 1)*beta)}
4

The meaning of the log_sum function will be explained later.

#### 16.54.2 The Algorithm

The following main algorithm is used:

procedure ratint(p,q,x);

solution_list ← HorowitzReduction(p,q,x)
c∕d ← part(solution_list,1)
poly_part ← part(solution_list,2)
rat_part ← part(solution_list,3)
rat_part ← LogarithmicPartIntegral(rat_part,x)
return(rat_part + c∕d + poly_part)
end

The algorithm contains two subroutines, HorowitzReduction and rt. HorowitzReduction is an implementation of Horowitz’ method to reduce a given rational function into a polynomial part and a logarithmic part. The integration of the polynomial part is a trivial task, and is done by the int operator in REDUCE. The integration of the logarithmic part is done by the routine rt, which is an impementation of the Rothstein and Trager method. These two answers are outputed in a list, the complete answer being the sum of these two parts.
These two algorithms are as follows:

procedure how(p,q,x)

for a given rational function p∕q in x, this algorithm calculates the reduction of ∫ (p∕q) into a polynomial part and logarithmic part.
poly_part ← quo(p,q); p ← rem(p,q);

d ← GCD(q,q′); b ← quo(q,d); m ← deg(b);
n ← deg(d);

a ←∑ i=1m−1a ixi; c ←∑ i=1n−1c ixi;
r ← b ∗ c′− quo(b ∗ d′,d) + d ∗ a;

solve(eqns,{a(0),....,a(m − 1),c(0),....,c(n − 1)});

return(c∕d + ∫ poly_part + ∫ a∕b);
end;

procedure RothsteinTrager(a,b,x)

% Given a rational function a∕b in x with deg(a) < deg(b), with b monic and square free, we calculate ∫ (a∕b)
R(z) ← residue(a − zb′,b)
(r1(z)...rk(z)) ← factors(R(z))
integral ← 0

#### 16.54.3 The log_sum operator

The algorithms above returns a sum of terms of the form

where R ∈ K[z] is square free, and S ∈ K[z,x]. In the cases where the degree of R(α) is less than two, this is merely a sum of logarithms. For cases where the degree is two or more, I have chosen to adopt this notation as the answer to the original problem of integrating the rational function. For example, consider the integral

Calculating the resultant R(z) = resx(a − zb′,b) and factorising gives

Making the result monic, we have

which does not split over the constant ﬁeld Q. Continuting with the Rothstein Trager algorithm, we now calculate

where α is a root of R2(z).
Thus we can write

and this is the answer now returned by REDUCE, via a function called log_sum. This has the following syntax:

log_sum(α,eqn(α), 0,sum_term,var)

where α satisﬁes eqn = 0, and sum_term is the term of the summation in the variable var. Thus in the above example, we have

Many rational functions that could not be integrated by REDUCE previously can now be integrated with this package. The above is one example; some more are given on the next page.

##### 16.54.3.1 More examples

which should be read as

#### 16.54.4 Options

There are several alternative forms that the answer to the integration problem can take. One output is the log_sum form shown in the examples above. There is an option with this package to convert this to a "normal" sum of logarithms in the case when the degree of eqn in α is two, and α can be expressed in surds. To do this, use the function convert, which has the following syntax:

convert(exp)

If exp is free of log_sum terms, then exp itself is returned. If exp contains log_sum terms, then α is represented as surds, and substituted into the log_sum expression. For example, using the last example, we have in REDUCE:

2: ratint(a,b,x);
{0,
2 1
log_sum(alpha,alpha - alpha - ---,0,
4
2 7 2
log( - 2*alpha*x - 2*alpha*x + x + x - 1)*alpha,x)}
3: convert(ws);
1 2 7
---*(sqrt(2)*log( - sqrt(2)*x - sqrt(2)*x + x - x - 1)
2
2 7
- sqrt(2)*log(sqrt(2)*x + sqrt(2)*x + x - x - 1)
2 7
+ log( - sqrt(2)*x - sqrt(2)*x + x - x - 1)
2 7
+ log(sqrt(2)*x + sqrt(2)*x + x - x - 1))

##### 16.54.4.1 LogtoAtan function

The user could then combine these to form a more elegant answer, using the switch combinelogs if one so wished. Another option is to convert complex logarithms to real arctangents [Bro97], which is recommended if deﬁnite integration is the goal. This is implemented in REDUCE via a function convert_log, which has the following syntax:

convert_log(exp),

where exp is any log_sum expression.
The procedure to convert complex logarithms to real arctangents is based on an algorithm by Rioboo. Here is what it does:
Given a ﬁeld K of characteristic 0 such that − 1)∉K and A,B ∈ K[x] with B≠0, return a sum f of arctangents of polynomials in K[x] such that

Example:

Substituting α = i∕2 and α = −i∕2 gives the result

Applying logtoAtan now with A = x3 − 3x, and B = x2 − 2 we obtain

and this is the formula which should be used for deﬁnite integration.
Another example in REDUCE is given below:

1: ratint(1,x^2+1,x);
*** Domain mode rational changed to arnum
2 1
{0,log_sum(beta,beta + ---,0,log(2*beta*x - 1)*beta)}
4
13: part(ws,2);
2 1
log_sum(beta,beta + ---,0,log(2*beta*x - 1)*beta)
4
14: on combinelogs;
15: convertlog(ws);
1 - i*x + 1
---*log(------------)*i
2 i*x + 1
logtoAtan(-x,1,x);
2*atan(x)

#### 16.54.5 Hermite’s method

The package also implements Hermite’s method to reduce the integral into its polynomial and logarithmic parts, but occasionally, REDUCE returns the incorrect answer when this algorithm is used. This is due to the REDUCE operator pf, which performs a complete partial fraction expansion when given a rational function as input. Work is presently being done to give the pf operator a facility which tells it that the input is already factored. This would then enable REDUCE to perform a partial fraction decomposition with respect to a square free denominator, which may not necessarily be fully factored over Q.
For a complete explanation of this and the other algorithms used in this package, including the theoretical justiﬁcation and proofs, please consult [GCL92].

#### 16.54.6 Tracing the ratint program

The package includes a facility to trace in some detail the inner workings of the ratint program. Messages are given at the key stages of the algorithm, together with the results obtained. These messages are displayed when the switch traceratint is on, which is done in REDUCE with the command

on traceratint;

This switch is oﬀ by default. Here is an example of the output obtained with this switch on:

Loading image file: /silo/tony/red/lisp/psl/solaris/red/reduce.img
REDUCE Development Version, 21-May-97 ...
1: load_package ratint;
2: on traceratint;
3: ratint(1+x,x^2-2*x+1,x);
x + 1
performing Howoritz reduction on --------------
2
x - 2*x + 1
- 2 1
Howoritz gives: {-------,0,-------}
x - 1 x - 1
1
computing Rothstein Trager on -------
x - 1
integral in Rothstein T is log(x - 1)
- 2
{-------,log(x - 1)}
x - 1

#### 16.54.7 Bugs, suggestions and comments

This package was written when the author was working as a placement student at ZIB Berlin.

Up | Next | Prev | PrevTail | Front