\documentclass{article}		% -*- Mode: LaTeX -*-

\usepackage{amsmath,verbatim,latexsym}

\setlength\parindent{0pt}
\setlength\parskip\medskipamount

\title{Polynomial Interpolation in Perl}
\author{Mats Kindahl\thanks{IAR Systems, Uppsala}}

\begin{document}

\maketitle

The {\bf Lagrange's formula} for $n$-point interpolation of a polynom
is
\begin{displaymath}
    A(x) = \sum_{k=0}^{n-1} y_k
        \frac{\prod_{j \neq k} (x - x_j)}
         {\prod_{j \neq k} (x_k - x_j)}
\end{displaymath}

This formula is taken from the excellent book \emph{Introduction to
Algorithms} by Thomas H.~Cormen, Charles E.~Leiserson, Ronald
L.~Rivest.

To create an algorithm that performs polynom interpolation in
$\Theta(n^2)$-time the trick is to compute the polynomial $B(x) =
\prod_{j=0}^{n-1} (x - x_j)$ in advance (which can be done in
$\Theta(n^2)$ time), and then for each $k$ compute $T(x) = B(x) / (x -
x_k)$ ($\Theta(n)$ time), divide the result by $\prod_{j \neq k} (x_k
- x_j)$ ($\Theta(n)$ time to compute the value, which can be done by
computing $T(x_k)$) and then accumulate the result into the final
polynomia $A(x)$ ($\Theta(n)$ time).
%
A more formal description of the algorithm is:

\bigskip
\hspace{2em}\begin{minipage}{0.7\hsize}
\begin{tabbing}
8. \=\kill
\textbf{Input:} 
A list of pairs $\left<(x_0,y_0),\ldots,(x_n,y_n)\right>$. 
\\*
%
\textbf{Output:} 
A polynomial $A(x)$ such that $A(x_i) = y_i$ for $0 \leq i \leq n$.
\\*[\medskipamount]
%
1.      \>Let $A(x) = 0$ (a zero degree polynomial) \\*
2.      \>Compute $B(x) = \prod_{j=0}^{n-1} (x - x_j)$ \\*
3.      \>For each $k = 0,\ldots,n-1$, repeat steps 3--5 \\*
4.      \>\kern2em Let $T(x) = B(x) / (x - x_k)$ \\*
5.      \>\kern2em Let $A(x) := A(x) + T(x) / T(x_k)$
\end{tabbing}
\end{minipage}
\bigskip

The time complexity of the algorithm above is: 
\begin{displaymath}
\begin{split}
   \Theta(n^2) + n \cdot \left[\Theta(n) + \Theta(n) + \Theta(n)\right] 
	&=\; \Theta(n^2) + 3n \Theta(n) \\
	&=\; \Theta(n^2) + \Theta(n^2) \\
	&=\; \mathbf{\Theta(n^2)}.
\end{split}
\end{displaymath}

\section*{Problems}

In this section we will consider some problem with polynomial
interpolation in general. (Maybe I'll add something about errors in
computations later.)

\subsection*{The polynomial gives bad values}

When doing polynomial interpolation on a set of points, the resulting
polynomial will swing widely if the real function is not a
polynomial. This is most prominent when trying to extrapolate a
non-polynomial with a polynomial, but it can happen even when trying
to evaluate the polynomial in the interpolated range.

For example, consider the function $f(x) = 1/(3x - 2x^2)$. By evaluating
it at some points, we get the following sequence of samples.

\begin{displaymath}
\begin{array}{r|r|r|r|r|r}
\strut x_i	&0.050	&0.100	&0.750	&1.400	&1.450 \\
\hline
\strut y_i	&6.897 	&3.571 	&0.889	&3.571	&6.897 \\
\end{array}
\end{displaymath}

\begin{figure}[t]
\begin{center}
\input{exp.tex}
\end{center}
\caption{Plot of $f(x)$, samples, and $F(x)$}\label{fig:exp.ps}
\end{figure}

We use \texttt{interpolate} to compute a polynomial $F(x)$ for the
samples by calling Perl. In Figure~\ref{fig:exp.pl} you see the
contents of \texttt{exp.pl}.
% in Figure~\ref{fig:sample.dat} you see the contents of \texttt{sample.dat}.
%
As can be seen in Figure~\ref{fig:exp.ps}, the derived polynomial
$F(x)$ swings widely when compared with $f(x)$. 
%
This means that you can not expect any set of sample to give good
values between the samples.

\begin{figure}[tb]
\begin{center}
\begin{minipage}{0.8\hsize}
\verbatiminput{exp.pl}
\end{minipage}
\end{center}
\caption{The file \texttt{exp.pl}}\label{fig:exp.pl}
\end{figure}

% \begin{figure}[t]
% \begin{center}
% \begin{minipage}{0.3\hsize}
% \verbatiminput{sample.dat}
% \end{minipage}
% \end{center}
% \caption{The file \texttt{sample.dat}}\label{fig:sample.dat}
% \end{figure}

\end{document}
