Indirect recursion using mXparser

Hello,

Today I will present how flexible mXparser really is. As an example we will approximate \sin(x) and \cos(x) using indirect recursion steps, which means two functions depending on each other. Let us start with a bit of theory starting with basic trigonometric identities:

\sin(2x)=2\sin(x)\cos(x)
\cos(2x)=\cos^2(x)-\sin^2(x)

Above formals can be equivalently written as

\sin(x)=2\sin\big(\frac{x}{2}\big)\cos\big(\frac{x}{2}\big)
\cos(x)=\cos^2\big(\frac{x}{2}\big)-\sin^2\big(\frac{x}{2}\big)

Please notice that knowing the solution for smaller value \frac{x}{2} it is possible to get solution for the original one x.  This simply means that mentioned trigonometric identities are in fact example of recursion - here indirect recursion as \sin(x) function is using \cos(x), and \cos(x) is using \sin(x). The complete recursion definition requires base case definition (stop condition).

For x near to 0 function \sin(x) can be well approximated exactly by x, while in case of \cos(x) constant 1 is pretty good approximation. This gives good stop condition.

For small a>0 let us define two recursive functions:

\text{s}(x)=\begin{cases}x&\text{dla}\quad |x|<a\\2\text{s}\big(\frac{x}{2}\big)\text{c}\big(\frac{x}{2}\big)&\text{dla}\quad |x|\geq a\end{cases}
\text{c}(x)=\begin{cases}1&\text{dla}\quad |x|<a\\\text{c}^2\big(\frac{x}{2}\big)-\text{s}^2\big(\frac{x}{2}\big)&\text{dla}\quad |x|\geq a\end{cases}

Once again please notice that \text{s} (and \text{c} separately) is using both \text{s}\big(\frac{x}{2}\big) and \text{c}\big(\frac{x}{2}\big).

We expect that smaller parameter a is giving better approximations - below you will find functions graphs separately for a = 0.5 and a=0.01.

import org.mariuszgromada.math.mxparser.*;
...
/* Recursive functions definition */
Constant a = new Constant("a", 0.1);
Function s = new Function("s(x) =  if( abs(x) < a, x, 2*s(x/2)*c(x/2) )", a);
Function c = new Function("c(x) =  if( abs(x) < a, 1, c(x/2)^2-s(x/2)^2 )", a);

/* Pointing that 's' is using 'c', and 'c' is using 's' */
s.addDefinitions(c);
c.addDefinitions(s);

 

Best regards,

Mariusz Gromada

 

Leave a Reply

Your email address will not be published. Required fields are marked *