My Journey with Integration in Finite Terms in Mathematica

Sam Blake

samuel.thomas.blake@gmail.com

My early years with Mathematica

— Around 1998 I found an old copy of DERIVE for DOS on a desktop computer at my high school.

Mathematica 3.0

— I wrote away to a reseller of Mathematica (from Woodend?) and was mailed a trial copy of Mathematica.

Monash University and Scientific Notebook

— In 2002 I started studying maths at Monash University.

— Monash relied heavily on Scientific Notebook. 
	- No programming. 
	- Clunky interface to Maple.
	- Awkward attempt to recreate LATEX-like equations inline.

2004 Mathematica 5

— In 2004 I started using Mathematica 5.2

WalkD

— I was inspired by George Beck’s WalkD program to write a step-by-step integrator.

StepByStepIntegrate

— StepByStepIntegrate started with a set of simple pattern matching transformation rules.

linearityRule = integral[e_Plus, x_]  :> (Print[Style["Integrate the sum term-by-term:", Darker @ Green]];Distribute[integral[e, x]]);

constantRule = integral[a_, x_] /; FreeQ[a, x] :>(Print[Style[Row @ {"The integral of ", a, " is ", a x,":"}, Darker @ Green]];a x);

monomialRule = integral[a_. ((x_)^(n_.)),x_] /; FreeQ[n, x] && n =!= -1 :>(Print[Style[Row @ {"The integral of ", a (x^n), " is ", a ((x^(n+1))/(n+1)),":"}, Darker @ Green]]; a ((x^(n+1))/(n+1)));

Format[integral[e_, x_], StandardForm] := Defer[Integrate[e, x]]

Example, compute ∫(x^2)-x-1dx:

integral[(x^2)-x-1,x] /. linearityRule

(integral[-1,x] /. constantRule) +integral[-x,x]+integral[(x^2),x]

-x+(integral[-x,x] /. monomialRule)+integral[(x^2),x]

-x-((x^2)/2)+(integral[(x^2),x] /. monomialRule)

StepByStepIntegrate

— The scope of the transformation rules in StepByStepIntegrate grew quickly.

— When StepByStepIntegrate could solve 99+% of integrals in common calculus books I sent it to WRI for suggested inclusion in Mathematica.

— To my surprise I was offered a job with WRI.

— My first project at WRI was stitching StepByStepIntegrate into Wolfram Alpha.

— StepByStepIntegrate contained around 350 pattern matching / transformation rules, and a (relatively clever) derivative-divides routine.

— [I also wrote the step-by-step programs for derivatives, limits, partial fractions, solving equations/inequalities, and algebraic simplification of expressions.]

StepByStepIntegrate

— StepByStepIntegrate now sits behind a paywall, however it can be accessed within a Mathematica notebook.

The transcendental Risch-Bronstein algorithm in Mathematica

— In 2005 I implemented Bronstein’s transcendental Risch algorithm.

— Bronstein’s transcendental Risch algorithm (circa 1997) is a significant advance over prior schemes and Mathematica’s transcendental Risch implementation from the early 1990s (Roach, 1992).

Risch[((((E^x)-(x^2)+2x)/((x^2)(((x+(E^x)))^2))))(E^((((x^2)-1)/x)+(1/(x+(E^x))))),x]

Integrate[((((E^x)-(x^2)+2x)/((x^2)(((x+(E^x)))^2))))(E^((((x^2)-1)/x)+(1/(x+(E^x))))),x]

The Risch-Norman algorithm

— Mathematica does not (as far as any exploratory testing can reveal) use the Risch-Norman (or Parallel Risch) algorithm.

— In 2006 I translated Bronstein's 'poor man's integrator' from Maple into Mathematica.

Pmint[Log[x] ExpIntegralE[1,b x],x]

Integrate[Log[x] ExpIntegralE[1,b x],x]

— I hope to submit this as a Wolfram Resource Function later in the year.

IntegrateAlgebraic

— I left WRI in 2011 and didn’t look at anything computer algebra related for almost a decade.

— After a long hiatus from playing with integrals, I started writing a package, IntegrateAlgebraic, for computing difficult algebraic integrals in finite terms.

— IntegrateAlgebraic contains around 20 methods (heuristics) for computing algebraic integrals.

— The most effective methods compute integrals of the form:

∫R(u, (Sqrt[a (u^2)+b u+c]))du, where u=(Subscript[c, -n])(x^(-n))+(Subscript[c, -n+1])(x^(-n+1))+(Subscript[…c, -1])(x^(-1))+(Subscript[c, 0])+(Subscript[c, 1])x+…+(Subscript[c, m])(x^m)

and

∫R(u)du, where u=((p(x))/(q(x)((r(x))^(1/n)))).

IntegrateAlgebraic

— Examples of IntegrateAlgebraic (mostly pulled from my 2021 Wolfram Blog post):

IntegrateAlgebraic[(((x^12)+1)/(((x^12)-1) ((((x^8)+1))^(1/4)))),x]

IntegrateAlgebraic[((2 (x^6)-1)/(((x^6)+1) (Sqrt[(x^6)+(x^2)+1]))),x]

IntegrateAlgebraic[(((x-1) ((((x^6)-(x^5)))^(1/3)))/(x+1)),x]

IntegrateAlgebraic

— IntegrateAlgebraic also contains (primarily Groebner basis-based) methods for computing integrals of nested radicals:

IntegrateAlgebraic[((Sqrt[(x^2)+(Sqrt[(x^4)+1])])/((((x+1))^3) (Sqrt[(x^4)+1]))),x]

IntegrateAlgebraic

— IntegrateAlgebraic was integrated into Mathematica’s default integrator, Integrate, in 2022.

SystemOptions["IntegrateOptions"]

— One of the 20 methods (the Laurent polynomial reduction method) in IntegrateAlgebraic was translated into Maple’s int() command by John May in 2022.

IntegrateRational

— IntegrateAlgebraic almost always requires a recursive call to a rational function integrator. I was consistently disappointed with the answers coming from Integrate.

— IntegrateRational is a rational function integrator.

— IntegrateRational contains numerous improvements over Integrate.

ResourceFunction["IntegrateRational"][((4-2 x-2 (x^2)+6 (x^3)+2 (x^4)-3 (x^5))/(-1-2 (x^2)+3 (x^4)-(x^6))),x]

Integrate[((4-2 x-2 (x^2)+6 (x^3)+2 (x^4)-3 (x^5))/(-1-2 (x^2)+3 (x^4)-(x^6))),x]

ResourceFunction["IntegrateRational"][(((x^3) (2+(x^2)))/(((-2+(Sqrt[3])+(-2+(Sqrt[3])) (x^2)-(x^4)))^2)),x]

Integrate[(((x^3) (2+(x^2)))/(((-2+(Sqrt[3])+(-2+(Sqrt[3])) (x^2)-(x^4)))^2)),x]

Rubi

— The open source Rule-Based Integrator (Rubi) was developed by Albert Rich (the co-author of the DERIVE computer algebra system) from around 2010 onwards.

— Rubi contains almost 7000 Mathematica pattern matching/transformation rules.

— Rubi is good at computing integrals it has seen before.

— Rubi has extensive testing, however these tests are highly Rubi-biased.

— With the sad passing of Albert last year I have become the defacto maintainer of Rubi.

— Porting Rubi to other computer algebra systems has proved to be a difficult task, as it relies on many subtle features of the Mathematica pattern matcher (backtracking, use of Condition, matching Orderless, Flat, OneIdentity exprs etc) and supporting algebraic manipulation routines (Apart, Together, Cancel, Simplify etc.)

— I have been experimenting with running the Rubi rules in LISP.

Future directions

— Computing integrals is just for fun.

— Unfortunately, nobody pays me to work on this area and its far removed from what I do professionally, so it must sit close to the bottom of my many to do lists.

— I am currently writing a book which focuses on integrals with at least math olympiad-level difficulty.