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 *