Risch’s structure theorem’s

For the next couple of weeks we will be moving to understand and implement the Risch’s structure theorem and applications that we will make use of in gsoc project. One of the application is that of “Simplification of real elementary functions”, a paper by Manuel Bronstein (in 1989)[1]. This paper by Bronstein uses Risch’s real structure theorem, the paper determines explicitly all algebraic relations among a set of real elementary functions.

Simplification of Real Elementary Functions

Risch in 1979 gave a theorem and an algorithm that found explicitly all algebraic relations among a set of only ’s and ’s. And to apply this algorithm required to convert trigonometric functions to ’s and ’s.

Consider the integrand . For this first we make use of form of , i.e . Substituting it in the original expression we get . Now using the exponential form of we get . And substituting in place of we get the final expression. , which is a complex algebraic function.

All of this could be avoided since the original function is a real algebraic function. The part that could be a problem to see it is , which can be seen to satisfy the algebraic equation using the formula for . Bronstein discusses the algorithm that wouldn’t require the use of complex ’s and ’s.

A function is called real elementary over a differential field , if for a differential extension () of . If either is algebraic over or it is , , , of an element of (consider this recursively). For example: is real elementary over , so is and .

Point to mention here is, we have to explicitly include , , since we don’t want the function to be a complex function by re-writing as , form( and can be written in form of complex and respectively), and we can write other trigonometric functions have real elementary relations with and . Alone or alone can’t do the job.

This way we can form the definition of a real-elementary extension of a differential field .

Functions currently using approach of structure theorems in SymPy

Moving on, let us now look at the three functions in SymPy that use the structure theorem “approach”:

  1. is_log_deriv_k_t_radical(fa, fd, DE): Checks if is the logarithmic derivative of a k(t)-radical. Mathematically where , . In naive terms if . Here k(t)-radical means n-th roots of element of . Used in process of calculating DifferentialExtension of an object where ‘case’ is ‘exp’.

  2. is_log_deriv_k_t_radical_in_field(fa, fd, DE): Checks if is the logarithmic derivative of a k(t)-radical. Mathematically where , . It may seem like it is just the same as above with f given as input instead of having to calculate , but the “in_field” part in function name is important.

  3. is_deriv_k: Checks if is the derivative of a k(t), i.e. where .

What have I done this week?

Moving onto what I have been doing for the last few days (at a very slow pace) went through a debugger for understanding the working of DifferentialExtension(exp(x**2/2) + exp(x**2), x) in which integer_powers function is currently used to determine the relation and , instead of and , since we can’t handle algebraic extensions currently (that will hopefully come later in my gsoc project). Similar example for is there in the book , though the difference is it uses the is_deriv_k (for case == 'primitive', we have is_log_deriv_k_t_radical for case == ‘exp’) to reach the conclusion that , and .

I still have to understand the structure theorem, for what they are? and how exactly they are used. According to Aaron, Kalevi, I should start reading the source of is_deriv_k, is_log_deriv_k_t_radical and parametric_log_deriv functions in prde.py file.

We worked on #12743 Liouvillian case for Parametric Risch Diff Eq. this week, it handles liouvillian cancellation cases. It enables us to handle integrands like .

>>> risch_integrate(log(x/exp(x) + 1), x)
(x*log(x*exp(-x) + 1) + NonElementaryIntegral((x**2 - x)/(x + exp(x)), x))

earlier it used to raise error prde_cancel() not implemented. After testing it a bit I realised that part of returned answer could be further integrated instead of being returned as a NonElementaryIntegral. Consider this

In [4]: risch_integrate(x + exp(x**2), x)
Out[4]: Integral(x + exp(x**2), x)

as can be easily seen it can be further integrated. So Aaron opened the issue #12779 Risch algorithm could split out more nonelementary cases.

Though I am not sure why Kalevi has still not merged the liouvillian PR (only a comment needs to be fixed n=2 -> n=5 in a comment), though that PR is not blocking me from doing further work.

Starting tomorrow (26th) we have the first evaluation of GSoC. Anyways I don’t like the idea of having 3 evaluations.

TODO for the next week:

Figuring out and implementing the structure theorems.


  • {1}. Simplification of real elementary functions, http://dl.acm.org/citation.cfm?id=74566