Index: /trunk/doc/pslib/psLibSDRS.tex
===================================================================
--- /trunk/doc/pslib/psLibSDRS.tex	(revision 1436)
+++ /trunk/doc/pslib/psLibSDRS.tex	(revision 1437)
@@ -1,3 +1,3 @@
-%%% $Id: psLibSDRS.tex,v 1.63 2004-08-07 04:11:59 price Exp $
+%%% $Id: psLibSDRS.tex,v 1.64 2004-08-09 23:22:58 price Exp $
 \documentclass[panstarrs,spec]{panstarrs}
 
@@ -32,5 +32,5 @@
 01 & 2004 May 19 & Extensive modifications, see appendix \\ \hline
 02 & 2004 Jun 22 & Incorporation of Bugzilla PRs (up to 69) \\ \hline
-03 & 2004 Aug 06 & Adding convolution, splines, chebyshevs \\
+03 & 2004 Aug 09 & Adding convolution, splines, chebyshevs \\
    &             & (modified polynomials), ImageTrim for Phase 2 \\ \hline
 \RevisionsEnd
@@ -1895,10 +1895,17 @@
 and double-precision (for milli-arcsec precision) versions.  We must
 also be able to calculate the errors in the fit coefficients, as well
-as be able to turn on and off each coefficient.  This leads us to
-define the following polynomial types:
+as be able to turn on and off each coefficient.
+
+In addition to general polynomials ($\sum_{i=0}^n a_i x^i$), we also
+use Chebyshev polynomials ($\sum_{i=0}^n a_i T_i(x)$), which have
+properties which are useful in the modeling of data over a defined
+domain.
+
+This leads us to define the following polynomial types:
 
 \begin{verbatim}
 /** One-dimensional polynomial */
 typedef struct {
+    psPolynomialType type;		///< Polynomial type
     int n;                              ///< Number of terms
     float *restrict coeff;              ///< Coefficients
@@ -1911,4 +1918,5 @@
 /** Two-dimensional polynomial */
 typedef struct {
+    psPolynomialType type;		///< Polynomial type
     int nX, nY;                         ///< Number of terms in x and y
     float *restrict *restrict coeff;    ///< Coefficients
@@ -1918,9 +1926,22 @@
 \end{verbatim}
 
-etc., up to four dimensions.  We also define double-precision versions:
+etc., up to four dimensions.  \code{psPolynomialType} is an
+enumerated type specifying the type of the polynomial: ordinary
+or Chebyshev:
+
+\begin{verbatim}
+/** Type of polynomial */
+typedef enum {
+    PS_POLYNOMIAL_ORD,			///< Ordinary polynomial
+    PS_POLYNOMIAL_CHEB			///< Chebyshev polynomial
+} psPolynomialType;
+\end{verbatim}
+
+We also define double-precision versions of the polynomials:
 
 \begin{verbatim}
 /** Double-precision one-dimensional polynomial */
 typedef struct {
+    psPolynomialType type;		///< Polynomial type
     int n;                              ///< Number of terms
     double *restrict coeff;             ///< Coefficients
@@ -1933,4 +1954,5 @@
 /** Double-precision two-dimensional polynomial */
 typedef struct {
+    psPolynomialType type;		///< Polynomial type
     int nX, nY;                         ///< Number of terms in x and y
     double *restrict *restrict coeff;   ///< Coefficients
@@ -1946,5 +1968,5 @@
 The constructor and destructor are:
 \begin{verbatim}
-psDPolynomial2D *psDPolynomial2DAlloc(int nX, int nY);
+psDPolynomial2D *psDPolynomial2DAlloc(int nX, int nY, psPolynomialType type);
 void p_psDPolynomial2DFree(psDPolynomial2D *restrict myPoly);
 \end{verbatim}
@@ -1957,11 +1979,80 @@
 \end{verbatim}
 
+In the event that several evaluations are required, we also define:
+\begin{verbatim}
+psVector *psDPolynomial2DEvalVector(psVector *x, psVector *y, const psDPolynomial2D *restrict myPoly);
+\end{verbatim}
+If the \code{x} and \code{y} vectors do not match the precision of the
+polynomial, the function shall generate a warning, and convert the
+vectors to the appropriate precision.  In the event that the \code{x}
+and \code{y} vectors are of differing sizes, the function shall
+generate a warning, truncate the longer vector to the size of the
+shorter, and continue.  The precision of the output \code{psVector}
+shall match that of the polynomial.
+
+\subsubsection{Splines}
+
+A spline is a popular choice for fitting 1D data, such as overscans,
+but we neglected to define them for PSLib.  We now define
+one-dimensional cubic splines, \code{psSpline1D}, which shall be
+incorporated into PSLib:
+
+\begin{verbatim}
+/** A 1D cubic-spline */
+typedef struct {
+    int n;                              ///< Number of spline pieces
+    psPolynomial1D *spline;		///< Array of n splines
+    float *domains;                     ///< The boundaries between each spline piece.  Size is n+1.
+} psSpline1D;
+\end{verbatim}
+
+The \code{psSpline1D} structure consists of an array of \code{n}
+polynomials, which are the spline pieces.  Note that this means that
+the spline pieces may, in general, be of any order.  \textbf{For the
+present, we shall restrict the order of the polynomials to either 1
+(linear) or 3 (cubic).}  All the spline pieces shall have the same
+order polynomial (the type of polynomial is left to the
+implementation).  The \code{domains} member specifies the boundaries
+between each spline piece (including the two ends).
+
+Of course, we require the appropriate constructors and destructor:
+\begin{verbatim}
+psSpline1D *psSpline1DAlloc(int n, int order, float min, float max);
+psSpline1D *psSpline1DAllocGeneric(const psVector *bounds, int order);
+\end{verbatim}
+
+\code{psSpline1DAlloc} shall allocate and return a \code{psSpline1D},
+setting the \code{domains} on the basis of the input number of spline
+pieces, \code{n}, and the minimum (\code{min}) and maximum
+(\code{max}) data values.  The spline pieces shall be of the specified
+\code{order}.
+
+\code{psSpline1DAllocGeneric} shall allocate and return a
+\code{psSpline1D}, using the \code{bounds} to define the number of
+spline pieces and the \code{domains}.  The spline pieces shall be of
+the specified \code{order}.
+
+Also, as for the polynomials, we require evaluators.  Given a
+\code{spline} and ordinate at which to evaluate, \code{x},
+\code{psSpline1DEval} shall evaluate and return the value of the
+spline at the ordinate.  If the ordinate is outside the bounds, then
+the function shall generate a warning, and extrapolate the spline to
+the ordinate and return the value.  Similarly,
+\code{psSpline1DEvalVector} shall return a vector of evaluated values
+for an input vector of ordinates.
+
+\begin{verbatim}
+float psSpline1DEval(const psSpline1D *spline, float x);
+psVector *psSpline1DEvalVector(psVector *x, const psSpline1D *spline);
+\end{verbatim}
+
+
 \subsubsection{Gaussians}
 
 Gaussians are used extensively in any data-analysis system, in
-particular to represent a real population distribution.  We require
-a function to evaluate a Gaussian for a given coordinate and one which
+particular to represent a real population distribution.  We require a
+function to evaluate a Gaussian for a given coordinate and one which
 generates a Gaussian deviate; a collection of data points whose
-distribution obeys a specified Gaussian.  
+distribution obeys a specified Gaussian.
 
 The Gaussian evaluation is provide by:
@@ -2044,8 +2135,8 @@
 
 \begin{verbatim}
-psPolynomial1D *psVectorFitPolynomial1D(psPolynomial1D myPoly, 
-                                     const psVector *restrict x,
-                                     const psVector *restrict y,
-                                     const psVector *restrict yErr);
+psPolynomial1D *psVectorFitPolynomial1D(psPolynomial1D *myPoly, 
+                                        const psVector *restrict x,
+                                        const psVector *restrict y,
+                                        const psVector *restrict yErr);
 \end{verbatim}
 \code{psVectorFitPolynomial1d} returns the polynomial that best fits the
@@ -2058,4 +2149,18 @@
 determined in the assumption that all data errors are equal.  This
 function must be valid only for types \code{psF32}, \code{psF64}.
+
+\begin{verbatim}
+psSpline1D *psVectorFitSpline1D(psSpline1D *mySpline,
+                                const psVector *x,
+				const psVector *y,
+				const psVector *yErr);
+\end{verbatim}
+\code{psVectorFitSpline} shall return the spline that best fits the
+given combination of ordinates (\code{x}) and coordinates (\code{y}).
+As for \code{psVectorFitPolynomial1D}, if \code{x} is \code{NULL},
+then the vector index shall be used as the ordinate; and if
+\code{yErr} is \code{NULL}, then all the data errors shall be assumed
+to be equal.  This function must be valid only for types \code{psF32},
+\code{psF64}.
 
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -2096,4 +2201,14 @@
 \code{psS8}, \code{psS16}, \code{psF32}, \code{psF64}, \code{psC32},
 \code{psC64}.
+
+\begin{verbatim}
+psImage *psImageTrim(psImage *image, int x0, int x1, int y0, int y1);
+\end{verbatim}
+Trim the specified \code{image} in-place, which involves shuffling the
+pixels around in memory.  The pixels in the region
+\code{[x0:x1,y0:y1]} (inclusive) shall consist the output image.
+
+The function shall generate an error if the specified region is
+outside the bounds of the input image.
 
 \subsubsection{Image Pixel Extractions}
@@ -2663,5 +2778,5 @@
     int xMax, yMax;                     ///< Most positive indices
     float **kernelRows;                 ///< Pointer to the rows of the kernel data
-    float **kernel;                     ///< Pointer to  in the kernel data
+    float **kernel;                     ///< Pointer to the kernel data
 } psKernel;
 \end{verbatim}
