\subsection{interpolate}
\label{labinterpolate}
\noindent Name: \textbf{interpolate}\\
\phantom{aaa}computes an interpolation polynomial.\\[0.2cm]
\noindent Library names:\\
\verb|   sollya_obj_t sollya_lib_interpolate(sollya_obj_t, sollya_obj_t, ...)|\\
\verb|   sollya_obj_t sollya_lib_v_interpolate(sollya_obj_t, sollya_obj_t, va_list)|\\[0.2cm]
\noindent Usage: 
\begin{center}
\textbf{interpolate}(\emph{X}, \emph{Y}) : (\textsf{list}, \textsf{list}) $\rightarrow$ \textsf{function}\\
\textbf{interpolate}(\emph{X}, \emph{Y}, \emph{D}) : (\textsf{list}, \textsf{list}, \textsf{constant}) $\rightarrow$ \textsf{function}\\
\textbf{interpolate}(\emph{X}, \emph{Y}, \emph{D}, \emph{I}) : (\textsf{list}, \textsf{list}, \textsf{constant}, \textsf{range}) $\rightarrow$ \textsf{function}\\
\textbf{interpolate}(\emph{X}, \emph{f}) : (\textsf{list}, \textsf{function}) $\rightarrow$ \textsf{function}\\
\textbf{interpolate}(\emph{X}, \emph{f}, \emph{D}) : (\textsf{list}, \textsf{function}, \textsf{constant}) $\rightarrow$ \textsf{function}\\
\textbf{interpolate}(\emph{X}, \emph{f}, \emph{D}, \emph{I}) : (\textsf{list}, \textsf{function}, \textsf{constant}, \textsf{range}) $\rightarrow$ \textsf{function}\\
\end{center}
Parameters: 
\begin{itemize}
\item \emph{X} is a list of constants for the interpolation abscissas
\item \emph{Y} is a list of constants for the interpolation ordinates
\item \emph{f} is a function to be interpolated
\item \emph{D} is a constant defining the maximum permissible error
\item \emph{I} is an interval defining the domain to be considered for the error
\end{itemize}
\noindent Description: \begin{itemize}

\item \textbf{interpolate} computes an interpolation polynomial $p$ of minimal degree such
   that for all given abscissa points $x_i$ in the list \emph{X} the interpolation
   condition is fullfilled with $p(x_i) = y_i$, where $y_i$ is the corresponding entry
   in the list of ordinates \emph{Y}. All entries of the lists \emph{X} and \emph{Y} need to be
   constant expressions; the entries in the list of abscissas \emph{X} need to be
   pairwise distinct. If no parameter \emph{D} is given, the interpolation is exact,
   \emph{i.e.}, an interpolation polynomial (expression) is formed such that the
   interpolation condition is satisfied without error.

\item \textbf{interpolate} accepts a function \emph{f} instead of a list of ordinates. When
   called in this manner, \textbf{interpolate} computes a polynomial $p$ such that for all
   given abscissa points $x_i$ in the list \emph{X} the interpolation condition is
   fullfilled with $p(x_i) = f(x_i)$. All entries in the list \emph{X} still need to be
   constant expressions and they must be pairwise distinct. If no parameter \emph{D}
   is given, the interpolation stays exact, even if this means forming constant
   expressions for the ordinates $f(x_i)$.

\item As exact interpolation is often not needed and in order to speed up
   computations, \textbf{interpolate} accepts an optional parameter \emph{D}, a positive
   constant, that defines the maximum permissible error. In this case, instead
   of computing the exact interpolation polynomial $p$ as it is defined above,
   \textbf{interpolate} computes and returns an approximate interpolation polynomial $\tilde{p}$
   that does not differ from $p$ more than the amount \emph{D} with supremum norm over
   the interval $I$ that is given by the interval of all abscissa points in \emph{X}.
   \\
   Formally, let $I$ be the convex hull of all abscissa points in \emph{X}; typically,
   the lower bound of $I$ is the minimum value amongst all \emph{X}, the upper bound is
   the maximum value amongst all \emph{X}. Let $p$ be the unique polynomial such that
   $p(x_i) = y_i$ for all $x_i$ in the list \emph{X} and $y_i$ either the corresponding entry
   in the list \emph{Y} or $y_i = f(x_i)$. Then \textbf{interpolate} returns $\tilde{p}$ such that
   $$\| \tilde{p} - p \|_{\infty,I} \leq D.$$
   The support for \emph{D} works for any list of distinct abscissa points \emph{X} and
   for any list of ordinate points \emph{Y} or function \emph{f}. The algorithm is however
   optimized for the case when \emph{X} is a list of floating-point (or rational)
   constants and a function \emph{f}. When \emph{f} is a polynomial of degree $n$ and \emph{X}
   contains at most $n+1$ abscissa points, \textbf{interpolate} may return \emph{f} as-is, even
   though \emph{D} has been provided; typically without performing any rounding on
   the coefficients of the polynomial \emph{f}.

\item When a permissible-error argument \emph{D} is given to \textbf{interpolate}, the command
   additionnally supports an optional interval parameter \emph{I}. If this parameter
   is specified, the interval $I$ to consider the error between $\tilde{p}$ and $p$ on is not
   taken as the convex hull of the abscissa points \emph{X} but assumed to be the
   interval $I$. This parameter is supported to both allow for interpolation over
   intervals where the first (or last) interpolation point does not lie on the
   lower (resp. upper) bound of the interval and to speed up computation:
   determining the minimum and maximum values in \emph{X} may be expensive.

\item \textbf{interpolate} is completely insensible to the tool's working precision \textbf{prec}.
   It adapts its own working precision entirely automatically. However the user
   should be aware that precision adaption comes at a price: if the
   interpolation problem requires high precision to be solved, the execution
   time of \textbf{interpolate} will be high. This can typically be observed when the
   list of abscissas \emph{X} contains two values that are mathematically different
   but for which high precision is needed to distinguish them.

\item In case of error, \emph{e.g.}, when the abscissa points in \emph{X} are not all
   distinct, when the function does not evaluate at one of the abscissa points
   or when the permissible error \emph{D} or domain interval \emph{I} are not acceptable,
   \textbf{interpolate} evaluates to \textbf{error}.
\end{itemize}
\noindent Example 1: 
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> p = interpolate([| 1, 2, 3 |], [| 3, 5, 9 |]);
> write("p = ", p, "\n");
p = 3 + _x_ * (-1 + _x_)
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 2: 
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> p = interpolate([| 1, 2, 3, 4 |], [| 1, -1, 2, -3 |]);
> write("p = ", p, "\n");
p = 21 + _x_ * (-100 / 3 + _x_ * (15.5 + _x_ * -13 / 6))
> p = interpolate([| 1, 2, 3, 4 |], [| 1, -1, 2, -3 |], 2^-17);
> write("p = ", p, "\n");
p = 21 + _x_ * (-33.333333492279052734375 + _x_ * (15.5 + _x_ * (-2.166666656732
5592041015625)))
> p = interpolate([| 1, 2, 3, 4 |], [| 1, -1, 2, -3 |], 2^-17, [0; 2^42]);
> write("p = ", p, "\n");
p = 21 + _x_ * (-33.333333333333333333333333333333333333333333363228 + _x_ * (15
.5 + _x_ * (-2.1666666666666666666666666666666666666666666647983)))
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 3: 
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> p = interpolate([| 1, 2, 3, 4 |], [| 1, -1, 2, -3 |]);
> q = interpolate([| 1, 2, 3, 4 |], [| 1, -1, 2, -3 |], 2^-17);
> delta = horner(p - q);
> write("delta = ", delta, "\n");
delta = _x_ * (1 / 6291456 + _x_^2 * -1 / 100663296)
> Delta = dirtyinfnorm(delta,[1;4]);
> "Delta = ", Delta, " = 2^(", log2(Delta), ")";
Delta = 2.4471294368728034316556666925301338011322095712879e-7 = 2^(-21.96240625
1802890453634347359869541271899536019231)
> p = interpolate([| 1, 2, 3, 4 |], [| 1, -1, 2, -3 |]);
> q = interpolate([| 1, 2, 3, 4 |], [| 1, -1, 2, -3 |], 2^-2000);
> delta = horner(p - q);
> write("delta = ", delta, "\n");
delta = _x_ * (1 / 4.4088218698531373730540794925222988186456999760206e604 + _x_
^2 * -1 / 7.054114991765019796886527188035678109833119961633e605)
> Delta = dirtyinfnorm(delta,[1;4]);
> "Delta = ", Delta, " = 2^(", log2(Delta), ")";
Delta = 3.4920910013773992744476948245123751988401933577684e-605 = 2^(-2007.9624
062518028904536343473598695412718995360192)
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 4: 
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> p = interpolate([| 1, 2, 3, 4 |], [| 1, -1, 2, -3 |]);
> q = interpolate([| 1, 2, 3, 4 |], [| 1, -1, 2, -3 |], 2^-17, [0;2^10]);
> delta = horner(p - q);
> write("delta = ", delta, "\n");
delta = _x_ * (1 / 422212465065984 + _x_^2 * -1 / 6755399441055744)
> Delta = dirtyinfnorm(delta,[0;2^10]);
> "Delta = ", Delta, " = 2^(", log2(Delta), ")";
Delta = 1.589432940818369388580322265625e-7 = 2^(-22.584984514668420136955755457
026138868402791643092)
> p = interpolate([| 1, 2, 3, 4 |], [| 1, -1, 2, -3 |]);
> q = interpolate([| 1, 2, 3, 4 |], [| 1, -1, 2, -3 |], 2^-2000, [0;2^10]);
> delta = horner(p - q);
> write("delta = ", delta, "\n");
delta = _x_ * (-1 / 3.6983878408024986992700435663608496048481867984446e611 + _x
_^2 * 1 / 5.9174205452839979188320697061773593677570988775114e612)
> Delta = dirtyinfnorm(delta,[0;2^10]);
> "Delta = ", Delta, " = 2^(", log2(Delta), ")";
Delta = 1.8145160239721784427448462541908690004638874174061e-604 = 2^(-2005.5849
8451466842013695575545702613886840279164307)
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 5: 
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> p = interpolate([| 1, 2, 3, 4 |], 17 + _x_ * (42 + _x_ * (23 + _x_ * 1664)));
> write("p = ", p, "\n");
p = 17 + _x_ * (42 + _x_ * (23 + _x_ * 1664))
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 6: 
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> p = interpolate([| 1, 2, 3, 4 |], exp(_x_));
> write("p = ", p, "\n");
p = -1 * (-2 * (-3 * ((exp(4) - exp(3) - (exp(3) - exp(2))) / 2 - (exp(3) - exp(
2) - (exp(2) - exp(1))) / 2) / 3 + (exp(3) - exp(2) - (exp(2) - exp(1))) / 2) + 
exp(2) - exp(1)) + exp(1) + _x_ * (-1 * (-2 * ((exp(4) - exp(3) - (exp(3) - exp(
2))) / 2 - (exp(3) - exp(2) - (exp(2) - exp(1))) / 2) / 3 + -3 * ((exp(4) - exp(
3) - (exp(3) - exp(2))) / 2 - (exp(3) - exp(2) - (exp(2) - exp(1))) / 2) / 3 + (
exp(3) - exp(2) - (exp(2) - exp(1))) / 2) + -2 * (-3 * ((exp(4) - exp(3) - (exp(
3) - exp(2))) / 2 - (exp(3) - exp(2) - (exp(2) - exp(1))) / 2) / 3 + (exp(3) - e
xp(2) - (exp(2) - exp(1))) / 2) + exp(2) - exp(1) + _x_ * (-1 * ((exp(4) - exp(3
) - (exp(3) - exp(2))) / 2 - (exp(3) - exp(2) - (exp(2) - exp(1))) / 2) / 3 + -2
 * ((exp(4) - exp(3) - (exp(3) - exp(2))) / 2 - (exp(3) - exp(2) - (exp(2) - exp
(1))) / 2) / 3 + -3 * ((exp(4) - exp(3) - (exp(3) - exp(2))) / 2 - (exp(3) - exp
(2) - (exp(2) - exp(1))) / 2) / 3 + (exp(3) - exp(2) - (exp(2) - exp(1))) / 2 + 
_x_ * ((exp(4) - exp(3) - (exp(3) - exp(2))) / 2 - (exp(3) - exp(2) - (exp(2) - 
exp(1))) / 2) / 3))
> p = interpolate([| 1, 2, 3, 4 |], exp(_x_), 2^-17);
> write("p = ", p, "\n");
p = -7.7172116227447986602783203125 + _x_ * (17.9146616198122501373291015625 + _
x_ * (-9.7775724567472934722900390625 + _x_ * 2.2984042889438569545745849609375)
)
> p = interpolate([| 1, 2, 3, 4 |], exp(_x_), 2^-17, [0; 2^42]);
> write("p = ", p, "\n");
p = -7.717211620141288536337557462573403702892010733189 + _x_ * (17.914661614969
411928830253122773955194465923548481 + _x_ * (-9.7775724550214350407416860470959
032694184512464826 + _x_ * 2.2984042886523568836092778582480142756017855238293))

\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 7: 
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> p = interpolate([| 1, 2, 3, 4 |], exp(_x_));
> q = interpolate([| 1, 2, 3, 4 |], exp(_x_), 2^-17);
> delta = horner(p - q);
> Delta = dirtyinfnorm(delta,[1;4]);
> "Delta = ", Delta, " = 2^(", log2(Delta), ")";
Delta = 7.8101123470606372346391215972092629613859312741733e-9 = 2^(-26.93200955
2561199842757802778211432954321538161928)
> p = interpolate([| 1, 2, 3, 4 |], exp(_x_));
> q = interpolate([| 1, 2, 3, 4 |], exp(_x_), 2^-2000);
> delta = horner(p - q);
> Delta = dirtyinfnorm(delta,[1;4]);
> "Delta = ", Delta, " = 2^(", log2(Delta), ")";
Delta = 3.574737886097255322676984068596786349480238060537e-606 = 2^(-2011.25058
80400718258175558034736121948862189809702)
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 8: 
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> p = interpolate([| 1, 2, 3, 4 |], exp(_x_));
> q = interpolate([| 1, 2, 3, 4 |], exp(_x_), 2^-17, [0;2^10]);
> delta = horner(p - q);
> Delta = dirtyinfnorm(delta,[0;2^10]);
> "Delta = ", Delta, " = 2^(", log2(Delta), ")";
Delta = 3.3174992022654716926120201737930257514243356389991e-9 = 2^(-28.16725673
5304970710773265696018465191273351786528)
> p = interpolate([| 1, 2, 3, 4 |], exp(_x_));
> q = interpolate([| 1, 2, 3, 4 |], exp(_x_), 2^-2000, [0;2^10]);
> delta = horner(p - q);
> Delta = dirtyinfnorm(delta,[0;2^10]);
> "Delta = ", Delta, " = 2^(", log2(Delta), ")";
Delta = 1.67480290063655159679957323422134460429582811153817e-605 = 2^(-2009.022
5060850185477225876655278327362519640642038)
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 9: 
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> f = exp(_x_);
> I = [-1/2;1/2];
> n = 17;
> X = [||]; for i from 0 to n do X = (~(1/2 * (inf(I) + sup(I)) + 1/2 * (sup(I) 
- inf(I)) * cos(pi * ((2 * i + 1)/(2 * (n + 1)))))) .: X; X = revert(X);
> p = interpolate(X, f, 2^-110);
> q = remez(f, n, I);
> Delta = dirtyinfnorm(p-f,I);
> "||p-f|| = ", Delta, " = 2^(", log2(Delta), ")";
||p-f|| = 4.6822823648740795415790209572324990540532715520787e-27 = 2^(-87.46484
6623211506004130540250100341126958424233896)
> Delta = dirtyinfnorm(q-f,I);
> "||q-f|| = ", Delta, " = 2^(", log2(Delta), ")";
||q-f|| = 4.5615560104462964431174181483603567519672456911095e-27 = 2^(-87.50253
2530192383004694428978646385337892102159012)
> Delta = dirtyinfnorm(horner(p-q),I);
> "||p-q|| = ", Delta, " = 2^(", log2(Delta), ")";
||p-q|| = 1.20729201910945452306513389470528343007256343110758e-28 = 2^(-92.7422
11980284523389260465711218526032152621095553)
\end{Verbatim}
\end{minipage}\end{center}
\noindent Example 10: 
\begin{center}\begin{minipage}{15cm}\begin{Verbatim}[frame=single]
> interpolate([| 1, 1 + 2^-1000 |], 17 + 42 * x);
17 + x * 42
> interpolate([| 1, 1 + 2^-10000 |], 17 + 42 * x);
17 + x * 42
> interpolate([| 1, 1 |], 17 + 42 * x);
error
\end{Verbatim}
\end{minipage}\end{center}
See also: \textbf{remez} (\ref{labremez}), \textbf{dirtyinfnorm} (\ref{labdirtyinfnorm}), \textbf{supnorm} (\ref{labsupnorm}), \textbf{prec} (\ref{labprec}), \textbf{error} (\ref{laberror})
