How to write any function in Solidity

Rational approximations

$$ \frac{P(x_i)}{Q(x_i)} = f(x_i) $$

$$ P(x) = p_0 + p_1 x + p_2 x^2 + \dots $$

$$ Q(x) = 1 + q_1 x + q_2 x^2 + \dots $$

$$ P(x_i) = Q(x_i) f(x_i) $$

$$ \begin{bmatrix} 1 & x_0 & x_0^2 & \cdots \\ 1 & x_1 & x_1^2 & \cdots \\ 1 & x_2 & x_2^2 & \cdots \\ \vdots & \vdots & \vdots & \ddots \end{bmatrix} \begin{bmatrix} p_0 \\ p_1 \\ p_2 \\ \vdots \end{bmatrix} = \begin{bmatrix} 1 & x_0 & x_0^2 & \cdots \\ 1 & x_1 & x_1^2 & \cdots \\ 1 & x_2 & x_2^2 & \cdots \\ \vdots & \vdots & \vdots & \ddots \end{bmatrix} \begin{bmatrix} 1 \\ q_1 \\ q_2 \\ \vdots \end{bmatrix} \odot \begin{bmatrix} f(x_0) \\ f(x_1) \\ f(x_2) \\ \vdots \end{bmatrix} $$

$$ \begin{bmatrix} 1 & x_0 & x_0^2 & \cdots \\ 1 & x_1 & x_1^2 & \cdots \\ 1 & x_2 & x_2^2 & \cdots \\ \vdots & \vdots & \vdots & \ddots \end{bmatrix} \begin{bmatrix} p_0 \\ p_1 \\ p_2 \\ \vdots \end{bmatrix} = \begin{bmatrix} f(x_0) & f(x_0) x_0 & f(x_0) x_0^2 & \cdots \\ f(x_1) & f(x_1)x_1 & f(x_1)x_1^2 & \cdots \\ f(x_2) & f(x_2)x_2 & f(x_2)x_2^2 & \cdots \\ \vdots & \vdots & \vdots & \ddots \end{bmatrix} \begin{bmatrix} 1 \\ q_1 \\ q_2 \\ \vdots \end{bmatrix} $$

$$ \begin{bmatrix} 1 & x_0 & x_0^2 & \cdots \\ 1 & x_1 & x_1^2 & \cdots \\ 1 & x_2 & x_2^2 & \cdots \\ \vdots & \vdots & \vdots & \ddots \end{bmatrix} \begin{bmatrix} p_0 \\ p_1 \\ p_2 \\ \vdots \end{bmatrix} = \begin{bmatrix} f(x_0) x_0 & f(x_0) x_0^2 & \cdots \\ f(x_1)x_1 & f(x_1)x_1^2 & \cdots \\ f(x_2)x_2 & f(x_2)x_2^2 & \cdots \\ \vdots & \vdots & \ddots \end{bmatrix} \begin{bmatrix} q_1 \\ q_2 \\ \vdots \end{bmatrix} + \begin{bmatrix} f(x_0) \\ f(x_1) \\ f(x_2) \\ \vdots \end{bmatrix} $$

$$ \begin{bmatrix} 1 & x_0 & x_0^2 & \cdots & -f(x_0)x_0 & -f(x_0)x_0^2 & \cdots \\ 1 & x_1 & x_1^2 & \cdots & -f(x_1)x_1 & -f(x_1)x_1^2 & \cdots \\ 1 & x_2 & x_2^2 & \cdots & -f(x_2)x_2 & -f(x_2)x_2^2 & \cdots \\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \ddots \end{bmatrix} \begin{bmatrix} p_0 \\ p_1 \\ p_2 \\ \vdots \\ q_1 \\ q_2 \\ \vdots \end{bmatrix} = \begin{bmatrix} f(x_0) \\ f(x_1) \\ f(x_2) \\ \vdots \end{bmatrix} $$

Remez algorithm

By the Equioscilation theorem we know that when $P$ and $Q$ are optimal, the errors is oscilating between $\pm E$. Given the points of extremal error, $x_i$, this means

$$ \frac{P(x_i)}{Q(x_i)} - f(x_i) = (-1)^i E $$

This formula is the basis of the Remez algorithm. We itteratively solve for this equation, and use the result to find better approximations of the extremal points $x_i$.

$$ \begin{bmatrix} 1 & x_0 & x_0^2 & \cdots & -f(x_0)x_0 & -f(x_0)x_0^2 & \cdots & -1 \\ 1 & x_1 & x_1^2 & \cdots & -f(x_1)x_1 & -f(x_1)x_1^2 & \cdots & +1 \\ 1 & x_2 & x_2^2 & \cdots & -f(x_2)x_2 & -f(x_2)x_2^2 & \cdots & -1 \\ \vdots & \vdots & \vdots & \vdots & \vdots & \vdots & \ddots & \vdots \end{bmatrix} \begin{bmatrix} p_0 \\ p_1 \\ p_2 \\ \vdots \\ q_1 \\ q_2 \\ \vdots \\ E \end{bmatrix} = \begin{bmatrix} f(x_0) \\ f(x_1) \\ f(x_2) \\ \vdots \end{bmatrix} $$

TODO. In the complex domain, the ideal errors seem to be $e^{\pi i \frac{i}{n}} E$, this suggests that in the real domain we can use $\cos \frac{i}{n} E$. In a way, this is a generalization of the 'Modified Remez Algorithm' that also adds zero-error points $\frac{P(x_i)}{Q(x_i)} - f(x_i) = 0$.

Clenshaw algorithm and generalization of basis

We started out with polynomials of the form

$$ P(x) = p_0 + p_1 x + p_2 x^2 + \dots $$

If $\vert x \vert > 1$, the $x^i$ terms will grow exponentially, which can lead to numericall instabilities. A simple trick to avoid this is to apply a linear function to the domain to map it into $[-1, 1]$.

A more sophisticated way of avoiding it is by changing our basis polynomials. Let's say that till now we have used the basis

$$ \phi_i(x) = x^i $$

such that

$$ P(x) = p_0 \phi_0(x) + p_1 \phi_1(x) + p_2 \phi_2(x) + \dots $$

If these basis functions satisfy a recurrence

$$ \phi_{i+1}(x) = \alpha_i(x) \phi_i(x) + \beta_i(x) \phi_{i-1}(x) $$

then a generalization of Horner's evaluation mechanism applies:

The regular basis $\phi_i(x) = x^i$ satisfies with $\alpha_i(x) = x$ and $\beta_i(x) = 0$.

The Chebyshev basis satisfies $\alpha_i(x) = 2x$ and $\beta_i(x) = -1$.

$$ r_k = p_k + \alpha_k(x) r_{k+1} + \beta_{k+1} r_{k+2} $$

Assuming $\alpha$ and $\beta$ do not depend on the index:

Horner case using one variable

a = p_k + x * a

Chebyshev case using two variables

a = p_4 + 2x * b - a
b = p_3 + 2x * a - b
a = p_2 + 2x * b - a
b = p_1 + 2x * a - b

Chebyshev uses one more variable and has an additional subtraction, but same number of multiplications.

TODO Barycentric basis

https://web.archive.org/web/20200211232711/https://www.mn.uio.no/math/english/people/aca/michaelf/papers/rational.pdf

Remco Bloemen
Math & Engineering
https://2π.com