casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
GenericL2Fit.h
Go to the documentation of this file.
00001 //# GenericL2Fit.h: Generic base class for least-squares fit.
00002 //#
00003 //# Copyright (C) 2001,2002,2004,2005
00004 //# Associated Universities, Inc. Washington DC, USA.
00005 //#
00006 //# This library is free software; you can redistribute it and/or modify it
00007 //# under the terms of the GNU Library General Public License as published by
00008 //# the Free Software Foundation; either version 2 of the License, or (at your
00009 //# option) any later version.
00010 //#
00011 //# This library is distributed in the hope that it will be useful, but WITHOUT
00012 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00013 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00014 //# License for more details.
00015 //#
00016 //# You should have received a copy of the GNU Library General Public License
00017 //# along with this library; if not, write to the Free Software Foundation,
00018 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00019 //#
00020 //# Correspondence concerning AIPS++ should be addressed as follows:
00021 //#        Internet email: aips2-request@nrao.edu.
00022 //#        Postal address: AIPS++ Project Office
00023 //#                        National Radio Astronomy Observatory
00024 //#                        520 Edgemont Road
00025 //#                        Charlottesville, VA 22903-2475 USA
00026 //#
00027 //# $Id: GenericL2Fit.h 21024 2011-03-01 11:46:18Z gervandiepen $
00028 
00029 #ifndef SCIMATH_GENERICL2FIT_H
00030 #define SCIMATH_GENERICL2FIT_H
00031 
00032 //# Includes
00033 #include <casa/aips.h>
00034 #include <casa/Arrays/Matrix.h>
00035 #include <casa/Arrays/Vector.h>
00036 #include <casa/Containers/Block.h>
00037 #include <scimath/Fitting/LSQaips.h>
00038 #include <scimath/Fitting/LSQTraits.h>
00039 #include <scimath/Functionals/Function.h>
00040 #include <scimath/Functionals/FunctionTraits.h>
00041 #include <scimath/Mathematics/AutoDiff.h>
00042 
00043 namespace casa { // begin namespace casa
00044 
00045 //# Forward declarations
00046 template <class T> class Array;
00047 template <class T, class U> class Function;
00048 
00049 // <summary> Generic base class for least-squares fit.
00050 // </summary>
00051 //
00052 // <reviewed reviewer="wbrouw" date="2004/06/14" tests="tLinearFitSVD.cc"
00053 //       demos="">
00054 // </reviewed>
00055 //
00056 // <prerequisite>
00057 //   <li> <linkto class="Function">Function</linkto> 
00058 //   <li> <linkto module="Fitting">Fitting</linkto>
00059 // </prerequisite>
00060 //
00061 // <etymology>
00062 // A set of data point is fit with some functional equation.
00063 // The class acts as a generic base class for <src>L2</src> type
00064 // fits.
00065 // </etymology>
00066 //
00067 // <synopsis>
00068 // NOTE: Constraints added. Documentation out of date at moment, check
00069 // the tLinearFitSVD and tNonLinearFitLM programs for examples.
00070 //
00071 // The class acts as a base class for L2-type (least-squares) fitting. 
00072 // Actual classes (se e.g. <linkto class=LinearFit>LinearFit</linkto> and
00073 // <linkto class=NonLinearFit>NonLinearFit</linkto>.
00074 //
00075 // The following is a brief summary of the linear least-squares fit problem.
00076 // See module header, <linkto module="Fitting">Fitting</linkto>,
00077 // for a more complete description.  
00078 //
00079 // Given a set of N data points (measurements), (x(i), y(i)) i = 0,...,N-1, 
00080 // along with a set of standard deviations, sigma(i), for the data points, 
00081 // and M specified functions, f(j)(x) j = 0,...,M-1, we form a linear 
00082 // combination of the functions: 
00083 // <srcblock>
00084 // z(i) = a(0)f(0)(x(i)) + a(1)f(1)(x(i)) + ... + a(M-1)f(M-1)(x(i)),
00085 // </srcblock>
00086 // where a(j) j = 0,...,M-1 are a set of parameters to be determined.
00087 // The linear least-squares fit tries to minimize
00088 // <srcblock>
00089 // chi-square = [(y(0)-z(0))/sigma(0)]^2 + [(y(1)-z(1))/sigma(1)]^2 + ... 
00090 //              + [(y(N-1)-z(N-1))/sigma(N-1)]^2.
00091 // </srcblock>
00092 // by adjusting {a(j)} in the equation. 
00093 //
00094 // For complex numbers, <code>[(y(i)-z(i))/sigma(i)]^2</code> in chi-square 
00095 // is replaced by
00096 // <code>[(y(i)-z(i))/sigma(i)]*conjugate([(y(i)-z(i))/sigma(i)])</code>
00097 //
00098 // For multidimensional functions, x(i) is a vector, and
00099 // <srcblock> 
00100 // f(j)(x(i)) = f(j)(x(i,0), x(i,1), x(i,2), ...)
00101 // </srcblock>
00102 //
00103 // Normally, it is necessary that N > M for the solutions to be valid, since 
00104 // there must be more data points than model parameters to be solved.
00105 //
00106 // If the measurement errors (standard deviation sigma) are not known 
00107 // at all, they can all be set to one initially.  In this case, we assume all 
00108 // measurements have the same standard deviation, after minimizing
00109 // chi-square, we recompute
00110 // <srcblock>  
00111 // sigma^2 = {(y(0)-z(0))^2 + (y(1)-z(1))^2 + ... 
00112 //           + (y(N-1)-z(N-1))^2}/(N-M) = chi-square/(N-M).
00113 // </srcblock> 
00114 //
00115 // A statistic weight can also be assigned to each measurement if the 
00116 // standard deviation is not available.  sigma can be calculated from
00117 // <srcblock>
00118 // sigma = 1/ sqrt(weight)
00119 // </srcblock>
00120 // Alternatively a 'weight' switch can be set with <src>asWeight()</src>.
00121 // For best arithmetic performance, weight should be normalized to a maximum
00122 // value of one. Having a large weight value can sometimes lead to overflow
00123 // problems.
00124 //
00125 // The function to be fitted to the data can be given as an instance of the
00126 // <linkto class="Function">Function</linkto> class.
00127 // One can also form a sum of functions using the
00128 // <linkto class="CompoundFunction">CompoundFunction</linkto>.  
00129 //
00130 // For small datasets the usage of the calls is:
00131 // <ul>
00132 //  <li> Create a functional description of the parameters
00133 //  <li> Create a fitter: GenericL2Fit<T> fitter();
00134 //  <li> Set the functional representation: fitter.setFunction()
00135 //  <li> Do the fit to the data: fitter.fit(x, data, sigma)
00136 //      (or do a number of calls to buildNormalMatrix(x, data, sigma)
00137 //      and finish of with fitter.fit() or fitter.sol())
00138 //  <li> if needed the covariance; residuals; chiSquared, parameter errors
00139 //       can all be obtained
00140 // </ul>
00141 // Note that the fitter is reusable. An example is given in the following.
00142 //
00143 // The solution of a fit always produces the total number of parameters given 
00144 // to the fitter. I.e. including any parameters that were fixed. In the
00145 // latter case the solution returned will be the fixed value.
00146 // 
00147 // <templating arg=T>
00148 // <li> The following data types can be used to instantiate the GenericL2Fit 
00149 //      templated class:
00150 //      Known classes for FunctionTraits. I.e simple numerical like
00151 //      <src>Float</src>, <src>Double</src>, <src>Complex</src>,
00152 //       <src>DComplex</src>; and the <src>AutoDiff<></src> versions.
00153 // </templating>
00154 //
00155 // If there are a large number of unknowns or a large number of data points
00156 // machine memory limits (or timing reasons) may not allow a complete
00157 // in-core fitting to be performed.  In this case one can incrementally
00158 // build the normal equation (see buildNormalMatrix()).
00159 //
00160 // The normal operation of the class tests for real inversion problems
00161 // only. If tests are needed for almost collinear columns in the
00162 // solution matrix, the collinearity can be set as the square of the sine of
00163 // the minimum angle allowed.
00164 //
00165 // Singular Value Decomposition is supported by the
00166 // <em> asSVD()</em> (which will also set the
00167 // default collinearity to 1e-8).
00168 //
00169 // Other information (see a.o. <linkto class=LSQFit>LSQFit</linkto>) can
00170 // be set and obtained as well.
00171 // </synopsis>
00172 //
00173 // <motivation>
00174 // The creation of this class was driven by the need to write code
00175 // to perform baseline fitting or continuum subtraction.
00176 // </motivation>
00177 
00178 // <example>
00179 // In the following a polynomial is fitted through the first 20 prime numbers.
00180 // The data is given in the x vector (1 to 20) and in the primesTable
00181 // (2, 3, ..., 71) (see tLinearFitSVD test program). In the following
00182 // all four methods to calculate a polynomial through the data is used
00183 // <srcblock>
00184 //      // The list of coordinate x-values
00185 //      Vector<Double> x(nPrimes);
00186 //      indgen(x, 1.0);  // 1, 2, ...
00187 //      Vector<Double> primesTable(nPrimes);
00188 //      for (uInt i=1; i < nPrimes; i++) {
00189 //        primesTable(i) =
00190 //         Primes::nextLargerPrimeThan(Int(primesTable(i-1)+0.01));
00191 //      }   
00192 //      Vector<Double> sigma(nPrimes);
00193 //      sigma = 1.0;
00194 //      // The fitter
00195 //      LinearFit<Double> fitter;
00196 //      // Linear combination of functions describing 1 + x + x*x
00197 //      combination.setCoefficient(0, 1.0);   // 1
00198 //      combination.setCoefficient(1, 1.0);     // x
00199 //      combination.setCoefficient(2, 1.0);     // x^2
00200 //      // Get the solution
00201 //      fitter.setFunction(combination);
00202 //      Vector<Double> solution = fitter.fit(x, primesTable, sigma);
00203 //      // Try with a function with automatic derivatives (note that default 
00204 //      // polynomial has zero first guess)
00205 //      LinearFit<AutoDiffA<Double> > fitad;
00206 //      Polynomial<AutoDiffA<Double> > sqre(2);
00207 //      fitad.setFunction(sqre);
00208 //      solution = fitad.fit(x, primesTable, sigma);
00209 // </srcblock>
00210 // In the test program examples are given on how to get the other
00211 // information, and other examples.
00212 // </example>
00213 
00214 template<class T> class GenericL2Fit : public LSQaips {
00215  public: 
00216   //# Constants
00217   // Default collinearity test for SVD
00218   const Double COLLINEARITY;
00219 
00220   //# Constructors
00221   // Create a fitter: the normal way to generate a fitter object. Necessary
00222   // data will be deduced from the Functional provided with
00223   // <src>setFunction()</src>
00224   GenericL2Fit();
00225   // Copy constructor (deep copy)
00226   GenericL2Fit(const GenericL2Fit &other);
00227   // Assignment (deep copy)
00228   GenericL2Fit &operator=(const GenericL2Fit &other);
00229 
00230   // Destructor
00231   virtual ~GenericL2Fit();
00232 
00233   // Sets the function to be fitted.  Upon entry, the argument function object 
00234   // is cloned.  The cloned copy is used in the later fitting process.
00235   // A valid function should be an instance of the
00236   // <linkto class="Function">Function</linkto> class,
00237   // so that derivatives with respect to the adjustable parameters
00238   // can be calculated.  The current values of the "available" parameters
00239   // of the function are taken as the initial guess for the non-linear fitting.
00240   template <class U>  
00241     void setFunction(const Function<U,U> &function) { resetFunction();
00242     ptr_derive_p = function.cloneAD(); setFunctionEx(); }
00243 
00244   // Set the possible constraint functions. The <src>addConstraint</src>
00245   // will add one; the <src>setConstraint</src> will [re-]set the
00246   // <src>n</src>th constraint. If unsucessful, False returned.<br>
00247   // Constraint functional can only be set when the function to be fitted
00248   // has been set. It should have the same number of parameters as the function
00249   // to be fitted. The <src>x</src> should have the correct dimension.
00250   // <group>
00251   template <class U>
00252     Bool setConstraint(const uInt n,
00253                        const Function<U,U> &function,
00254                        const Vector<typename FunctionTraits<T>::BaseType> &x,
00255                        const typename FunctionTraits<T>::BaseType y=
00256                        typename FunctionTraits<T>::BaseType(0)) {
00257     if (n >= constrFun_p.nelements() ||
00258         !ptr_derive_p ||
00259         ptr_derive_p->nparameters() != function.nparameters() ||
00260         function.ndim() != x.nelements()) return False;
00261     delete constrFun_p[n]; constrFun_p[n] = 0;
00262     constrFun_p[n] = function.cloneAD(); return setConstraintEx(n, x, y); }
00263   Bool setConstraint(const uInt n,
00264                      const Vector<typename FunctionTraits<T>::BaseType> &x,
00265                      const typename FunctionTraits<T>::BaseType y=
00266                      typename FunctionTraits<T>::BaseType(0));
00267   Bool setConstraint(const uInt n,
00268                      const typename FunctionTraits<T>::BaseType y=
00269                      typename FunctionTraits<T>::BaseType(0));
00270   Bool addConstraint(const Function<typename FunctionTraits<T>::DiffType,
00271                      typename FunctionTraits<T>::DiffType> &function,
00272                      const Vector<typename FunctionTraits<T>::BaseType> &x,
00273                      const typename FunctionTraits<T>::BaseType y=
00274                      typename FunctionTraits<T>::BaseType(0));
00275   Bool addConstraint(const Vector<typename FunctionTraits<T>::BaseType> &x,
00276                      const typename FunctionTraits<T>::BaseType y=
00277                      typename FunctionTraits<T>::BaseType(0));
00278   Bool addConstraint(const typename FunctionTraits<T>::BaseType y=
00279                      typename FunctionTraits<T>::BaseType(0));
00280   // </group>
00281   // Set the collinearity factor as the square of the sine of the
00282   // minimum angle allowed between input vectors (default zero for non-SVD,
00283   // 1e-8 for SVD)
00284   void setCollinearity(const Double cln);
00285 
00286   // Set sigma values to be interpreted as weight (i.e. 1/sigma/sigma).
00287   // A value of zero or -1 will be skipped. The switch will stay in effect
00288   // until set False again explicitly. Default is False.
00289   void asWeight(const Bool aswgt) { asweight_p = aswgt; }
00290 
00291   // Set the use of SVD or not (default). When set the default collinearity
00292   // is set as well.
00293   void asSVD(const Bool svd);
00294 
00295   // Return a pointer to the function being fitted.  Should
00296   // never delete this pointer.
00297   // <group>
00298   Function<typename FunctionTraits<T>::DiffType,
00299     typename FunctionTraits<T>::DiffType> *fittedFunction() {
00300     return ptr_derive_p; }
00301   const Function<typename FunctionTraits<T>::DiffType,
00302                  typename FunctionTraits<T>::DiffType>*
00303     fittedFunction() const { return ptr_derive_p; }
00304   // </group>
00305   // Return the number of fitted parameters
00306   uInt fittedNumber() const { return aCount_ai; }
00307 
00308   // Return the number of constraints, and pointers to constraint functions.
00309   // A <src>0-pointer</src> will be returned if no such constraint present.
00310   // This pointer should never be destroyed.
00311   // <group>
00312   uInt NConstraints() { return constrFun_p.nelements(); }
00313   Function<typename FunctionTraits<T>::DiffType,
00314     typename FunctionTraits<T>::DiffType> *getConstraint(const uInt n) {
00315     return (n >= constrFun_p.nelements() ? 0 : constrFun_p[n]); }
00316   // </group>
00317 
00318   // Return the nth constraint equation derived from SVD
00319   // Note that the number present will be given by <src>getDeficiency()</src>
00320   Vector<typename LSQTraits<typename FunctionTraits<T>::
00321     BaseType>::base> getSVDConstraint(uInt n);
00322   // Set the parameter values. The input is a vector of parameters; all
00323   // or only the masked ones' values will be set, using the input values
00324   // <group>
00325   void setParameterValues
00326     (const Vector<typename FunctionTraits<T>::BaseType> &parms);
00327   void setMaskedParameterValues
00328     (const Vector<typename FunctionTraits<T>::BaseType> &parms);
00329   // </group>
00330   
00331   // Fit the function to the data. If no sigma provided, all ones assumed.
00332   // In the case of no x,y,sigma the fitting equations are supposed to be
00333   // generated by previous calls to buildNormalMatrix. Note that the ones
00334   // with a scalar sigma will assume sigma=1 (overloading problem). The mask
00335   // assumes that if present, points with False will be skipped.
00336   // <thrown>
00337   //  <li> AipsError if unmatched array sizes given
00338   //  <li> AipsError if equations cannot be inverted (not in SVD case and in
00339   //            the case of the Bool versions.)
00340   // </thrown>
00341   // <group>
00342   Vector<typename FunctionTraits<T>::BaseType>
00343     fit(const Vector<typename FunctionTraits<T>::BaseType> &x, 
00344         const Vector<typename FunctionTraits<T>::BaseType> &y,
00345         const Vector<typename FunctionTraits<T>::BaseType> &sigma,
00346         const Vector<Bool> *const mask=0);
00347   Vector<typename FunctionTraits<T>::BaseType>
00348     fit(const Matrix<typename FunctionTraits<T>::BaseType> &x, 
00349         const Vector<typename FunctionTraits<T>::BaseType> &y,
00350         const Vector<typename FunctionTraits<T>::BaseType> &sigma,
00351         const Vector<Bool> *const mask=0);
00352   Vector<typename FunctionTraits<T>::BaseType>
00353     fit(const Vector<typename FunctionTraits<T>::BaseType> &x, 
00354         const Vector<typename FunctionTraits<T>::BaseType> &y,
00355         const Vector<Bool> *const mask=0);
00356   Vector<typename FunctionTraits<T>::BaseType>
00357     fit(const Matrix<typename FunctionTraits<T>::BaseType> &x, 
00358         const Vector<typename FunctionTraits<T>::BaseType> &y,
00359         const Vector<Bool> *const mask=0);
00360   Vector<typename FunctionTraits<T>::BaseType>
00361     fit(const Vector<Bool> *const mask=0); 
00362   Bool fit(Vector<typename FunctionTraits<T>::BaseType> &sol,
00363            const Vector<typename FunctionTraits<T>::BaseType> &x, 
00364            const Vector<typename FunctionTraits<T>::BaseType> &y,
00365            const Vector<typename FunctionTraits<T>::BaseType> &sigma,   
00366            const Vector<Bool> *const mask=0);
00367   Bool fit(Vector<typename FunctionTraits<T>::BaseType> &sol,
00368            const Matrix<typename FunctionTraits<T>::BaseType> &x, 
00369            const Vector<typename FunctionTraits<T>::BaseType> &y,
00370            const Vector<typename FunctionTraits<T>::BaseType> &sigma,
00371            const Vector<Bool> *const mask=0);
00372   Bool fit(Vector<typename FunctionTraits<T>::BaseType> &sol,
00373            const Vector<typename FunctionTraits<T>::BaseType> &x, 
00374            const Vector<typename FunctionTraits<T>::BaseType> &y,
00375            const typename FunctionTraits<T>::BaseType &sigma,
00376            const Vector<Bool> *const mask=0);
00377   Bool fit(Vector<typename FunctionTraits<T>::BaseType> &sol,
00378            const Matrix<typename FunctionTraits<T>::BaseType> &x, 
00379            const Vector<typename FunctionTraits<T>::BaseType> &y,
00380            const typename FunctionTraits<T>::BaseType &sigma,
00381            const Vector<Bool> *const mask=0);
00382   Bool fit(Vector<typename FunctionTraits<T>::BaseType> &sol,
00383            const Vector<Bool> *const mask=0);
00384   // </group>
00385 
00386   // Obtain the chi squared. It has already been calculated during the
00387   // fitting process.
00388   // <group>
00389   Double chiSquare() const { return getChi(); }
00390   // </group>
00391 
00392   // Get the errors on the solved values
00393   // <thrown>
00394   //  <li> AipsError if none present (or Bool returned)
00395   // </thrown>
00396   // <group>
00397   const Vector<typename FunctionTraits<T>::BaseType> &errors() const;
00398   Bool errors(Vector<typename FunctionTraits<T>::BaseType> &err) const;
00399   // </group>
00400 
00401   // Get covariance matrix
00402   // <group>
00403   Matrix<Double> compuCovariance();
00404   void compuCovariance(Matrix<Double> &cov);
00405   // </group>
00406 
00407   // Generate the normal equations by one or more calls to the
00408   // buildNormalMatrix(), before calling a fit() without arguments.
00409   // The arguments are the same as for the fit(arguments) function.
00410   // A False is returned if the Array sizes are unmatched.
00411   // <group>
00412   void buildNormalMatrix
00413     (const Vector<typename FunctionTraits<T>::BaseType> &x, 
00414      const Vector<typename FunctionTraits<T>::BaseType> &y,
00415      const Vector<typename FunctionTraits<T>::BaseType> &sigma,
00416      const Vector<Bool> *const mask=0);
00417   void buildNormalMatrix
00418     (const Matrix<typename FunctionTraits<T>::BaseType> &x, 
00419      const Vector<typename FunctionTraits<T>::BaseType> &y,
00420      const Vector<typename FunctionTraits<T>::BaseType> &sigma,
00421      const Vector<Bool> *const mask=0);
00422   void buildNormalMatrix
00423     (const Vector<typename FunctionTraits<T>::BaseType> &x, 
00424      const Vector<typename FunctionTraits<T>::BaseType> &y,
00425      const Vector<Bool> *const mask=0);
00426   void buildNormalMatrix
00427     (const Matrix<typename FunctionTraits<T>::BaseType> &x, 
00428      const Vector<typename FunctionTraits<T>::BaseType> &y,
00429      const Vector<Bool> *const mask=0);
00430   // </group>
00431   // Return the residual after a fit in y. x can 
00432   // be a vector (if 1D function) or a matrix (ND functional), as in the 
00433   // fit() methods. If sol is given, it is the solution derived from
00434   // a fit and its value will be used; otherwise  only the parameters
00435   // in the fitted functional will be used.
00436   // If <src>model</src> is given as <src>True</src>, the model, rather
00437   // the residual <src><data>-<model></src> will be returned in <src>y</src>.
00438   // False is returned if residuals cannot be calculated.
00439   // <thrown>
00440   // <li> Aipserror if illegal array sizes
00441   // </thrown>
00442   // <group>
00443   Bool residual(Vector<typename FunctionTraits<T>::BaseType> &y,
00444                 const Array<typename FunctionTraits<T>::BaseType> &x,
00445                 const Vector<typename FunctionTraits<T>::BaseType> &sol,
00446                 const Bool model=False);
00447   Bool residual(Vector<typename FunctionTraits<T>::BaseType> &y,
00448                 const Array<typename FunctionTraits<T>::BaseType> &x,
00449                 const Bool model=False);
00450   // </group>
00451   // Get the rank of the solution (or zero of no fit() done yet). A 
00452   // valid solution will have the same rank as the number of unknowns (or
00453   // double that number in the complex case). For SVD solutions the
00454   // rank could be less.
00455   uInt getRank() const {
00456     return (solved_p ? nUnknowns()-getDeficiency() : 0); }
00457 
00458  protected:
00459   //#Data
00460   // Adjustable
00461   uInt aCount_ai;
00462   // SVD indicator
00463   Bool svd_p;
00464   // Function to use in evaluating condition equation
00465   Function<typename FunctionTraits<T>::DiffType,
00466     typename FunctionTraits<T>::DiffType> *ptr_derive_p;
00467   // List of functions describing the possible constraint equations
00468   // e.g. The sum of 3 angles w`could be described by a
00469   // <src>HyperPlane(3)</src> function with <src>[1,1,1]</src>
00470   // as parameters; giving <src>[1,1,1]</src> as argument vector and
00471   // <src>3.1415</src> as value.
00472   // <group>
00473   PtrBlock<Function<typename FunctionTraits<T>::DiffType,
00474     typename FunctionTraits<T>::DiffType>*> constrFun_p;
00475   // List of vectors describing the constraint equations' arguments
00476   PtrBlock<Vector<typename FunctionTraits<T>::BaseType>*> constrArg_p;
00477   // List of values describing the constraint equations' value
00478   PtrBlock<typename FunctionTraits<T>::BaseType *> constrVal_p;
00479   // </group>
00480   // Number of available parameters
00481   uInt pCount_p;
00482   // Number of dimensions of input data
00483   uInt ndim_p;
00484   // No normal equations yet.
00485   Bool needInit_p;
00486   // Have solution
00487   Bool solved_p;
00488   // Have errors
00489   Bool errors_p;
00490   mutable Bool ferrors_p;
00491   // Interpret as weights rather than as sigma the given values.
00492   Bool asweight_p;
00493   // The rank of the solution
00494   uInt nr_p;
00495   // Condition equation parameters (for number of adjustable parameters)
00496   mutable Vector<typename FunctionTraits<T>::BaseType> condEq_p;
00497   // Equation for all available parameters
00498   mutable Vector<typename FunctionTraits<T>::BaseType> fullEq_p;
00499   // Contiguous argument areas
00500   // <group>
00501   mutable Vector<typename FunctionTraits<T>::ArgType> arg_p;
00502   mutable Vector<typename FunctionTraits<T>::ArgType> carg_p;
00503   // </group>
00504   // Local solution area
00505   // <group>
00506   mutable Vector<typename FunctionTraits<T>::BaseType> sol_p;
00507   mutable Vector<typename FunctionTraits<T>::BaseType> fsol_p;
00508   // </group>
00509   // Local error area
00510   // <group>
00511   mutable Vector<typename FunctionTraits<T>::BaseType> err_p;
00512   mutable Vector<typename FunctionTraits<T>::BaseType> ferr_p;
00513   // </group>
00514   // Local value and derivatives
00515   mutable typename FunctionTraits<T>::DiffType valder_p;
00516   // Local SVD constraints
00517   mutable Vector<Vector<typename LSQTraits<typename FunctionTraits<T>::
00518     BaseType>::base> > consvd_p;
00519   //# Member functions
00520   // Generalised fitter
00521   virtual Bool fitIt
00522     (Vector<typename FunctionTraits<T>::BaseType> &sol,
00523      const Array<typename FunctionTraits<T>::BaseType> &x, 
00524      const Vector<typename FunctionTraits<T>::BaseType> &y,
00525      const Vector<typename FunctionTraits<T>::BaseType> *const sigma,
00526      const Vector<Bool> *const mask=0) = 0;
00527   // Build the normal matrix
00528   void buildMatrix(const Array<typename FunctionTraits<T>::BaseType> &x, 
00529                    const Vector<typename FunctionTraits<T>::BaseType> &y,
00530                    const Vector<typename FunctionTraits<T>::BaseType>
00531                    *const sigma,
00532                    const Vector<Bool> *const mask=0);
00533   // Build the constraint equations
00534   void buildConstraint();
00535   // Get the SVD constraints
00536   void fillSVDConstraints();
00537   // Calculate residuals
00538   Bool buildResidual(Vector<typename FunctionTraits<T>::BaseType> &y,
00539                      const Array<typename FunctionTraits<T>::BaseType> &x,
00540                      const Vector<typename FunctionTraits<T>::BaseType>
00541                      *const sol, const Bool model=False);
00542   // Function to get evaluated functional value
00543   typename FunctionTraits<T>::BaseType
00544     getVal_p(const Array<typename FunctionTraits<T>::BaseType> &x,
00545              uInt j, uInt i) const;
00546   // Initialise the fitter with number of solvable parameters
00547   void initfit_p(uInt parcnt);
00548   // Return number of condition equations and check sizes x, y, sigma
00549   // <thrown>
00550   //  <li> Aipserror if size inconsistencies 
00551   // </thrown>
00552   uInt testInput_p
00553     (const Array<typename FunctionTraits<T>::BaseType> &x,
00554      const Vector<typename FunctionTraits<T>::BaseType> &y,
00555      const Vector<typename FunctionTraits<T>::BaseType> *const sigma);
00556   // Reset all the input
00557   void resetFunction();
00558 
00559  private:
00560   //# Data
00561 
00562   //# Member functions
00563   // Set function properties
00564   void setFunctionEx();
00565   // Set Constraint properties
00566   Bool setConstraintEx(const uInt n,
00567                        const Vector<typename FunctionTraits<T>::BaseType> &x,
00568                        const typename FunctionTraits<T>::BaseType y);
00569 };
00570 
00571 } //# End namespace casa
00572 #ifndef CASACORE_NO_AUTO_TEMPLATES
00573 #include <scimath/Fitting/GenericL2Fit.tcc>
00574 #endif //# CASACORE_NO_AUTO_TEMPLATES
00575 #endif