casa  $Rev:20696$
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines
InterpolateArray1D.h
Go to the documentation of this file.
00001 //# Interpolate1DArray.h: Interpolation in last dimension of an Array
00002 //# Copyright (C) 1997,1999,2000,2001
00003 //# Associated Universities, Inc. Washington DC, USA.
00004 //#
00005 //# This library is free software; you can redistribute it and/or modify it
00006 //# under the terms of the GNU Library General Public License as published by
00007 //# the Free Software Foundation; either version 2 of the License, or (at your
00008 //# option) any later version.
00009 //#
00010 //# This library is distributed in the hope that it will be useful, but WITHOUT
00011 //# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00012 //# FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Library General Public
00013 //# License for more details.
00014 //#
00015 //# You should have received a copy of the GNU Library General Public License
00016 //# along with this library; if not, write to the Free Software Foundation,
00017 //# Inc., 675 Massachusetts Ave, Cambridge, MA 02139, USA.
00018 //#
00019 //# Correspondence concerning AIPS++ should be addressed as follows:
00020 //#        Internet email: aips2-request@nrao.edu.
00021 //#        Postal address: AIPS++ Project Office
00022 //#                        National Radio Astronomy Observatory
00023 //#                        520 Edgemont Road
00024 //#                        Charlottesville, VA 22903-2475 USA
00025 //#
00026 //# $Id: Interpolate1DArray.h,v 8.1 1997/05/21 22:59:29 rm
00027 
00028 #ifndef SCIMATH_INTERPOLATEARRAY1D_H
00029 #define SCIMATH_INTERPOLATEARRAY1D_H
00030 
00031 
00032 #include <casa/aips.h>
00033 
00034 namespace casa { //# NAMESPACE CASA - BEGIN
00035 
00036 template <class T> class PtrBlock;
00037 template <class T> class Block;
00038 template <class T> class Array;
00039 template <class T> class Vector;
00040 template <class T> class Cube;
00041 
00042 // <summary> Interpolate in one dimension </summary>
00043  
00044 // <use visibility=export>
00045  
00046 // <reviewed reviewer="" date="" tests="" demos="">
00047 // </reviewed>
00048  
00049 // <prerequisite>
00050 //   <li> <linkto class=Array>Array</linkto> 
00051 //   <li> <linkto class=Vector>Vector</linkto> 
00052 // </prerequisite>
00053  
00054 // <etymology>
00055 // The InterpolateArray1D class does interpolation in one dimension of
00056 // an Array only.
00057 // </etymology>
00058  
00059 // <synopsis>
00060 // This class will, given the abscissa and ordinates of a set of one
00061 // dimensional data, interpolate on this data set giving the value at any
00062 // specified ordinate. It will extrapolate if necessary, but this is will
00063 // usually give a poor result. There is no requirement for the ordinates to
00064 // be regularly spaced, however they do need to be sorted and each
00065 // abscissa should have a unique value. 
00066 //
00067 // Interpolation can be done using the following methods:
00068 // <ul>
00069 //   <li> Nearest Neighbour 
00070 //   <li> Linear (default unless there is only one data point)
00071 //   <li> Cubic Polynomial
00072 //   <li> Natural Cubic Spline
00073 // </ul>
00074 //
00075 // The abscissa must be a simple type (scalar value) that
00076 // can be ordered. ie. an uInt, Int, Float or Double (not Complex). The
00077 // ordinate can be an Array of any data type that has addition, and 
00078 // subtraction defined as well as multiplication by a scalar of the abcissa 
00079 // type. 
00080 // So the ordinate can be complex numbers, where the interpolation is done 
00081 // separately on the real and imaginary components.
00082 // Use of Arrays as the the Range type is discouraged, operations will 
00083 // be very slow, it would be better to construct a single higher dimensional 
00084 // array that contains all the data.
00085 //
00086 // Note: this class (and these docs) are heavily based on the
00087 // <linkto class=Interpolate1D>Interpolate1D</linkto>
00088 // class in aips/Functionals. That class proved to be
00089 // too slow for interpolation of large data volumes (i.e. spectral line
00090 // visibility datasets) mainly due to the interface which forced the 
00091 // creation of large numbers of temporary Vectors and Arrays.
00092 // This class is 5-10 times faster than Interpolate1D in cases where
00093 // large amounts of data are to be interpolated.
00094 // </synopsis>
00095  
00096 // <example>
00097 // This code fragment does cubic interpolation on (xin,yin) pairs to
00098 // produce (xout,yout) pairs.
00099 // <srcblock>
00100 //  Vector<Float> xin(4); indgen(xin); 
00101 //  Vector<Double> yin(4); indgen(yin); yin = yin*yin*yin;
00102 //  Vector<Float> xout(20); 
00103 //  for (Int i=0; i<20; i++) xout(i) = 1 + i*0.1;
00104 //  Vector<Double> yout;
00105 //  InterpolateArray1D<Float, Double>::interpolate(yout, xout, xin, yin, 
00106 //                         InterpolateArray1D<Float,Double>::cubic);
00107 // </srcblock>
00108 // </example>
00109  
00110 // <motivation>
00111 // This class was motivated by the need to interpolate visibilities
00112 // in frequency to allow selection and gridding in velocity space
00113 // with on-the-fly doppler correction.
00114 // </motivation>
00115  
00116 // <templating arg=Domain>
00117 // <li> The Domain class must be a type that can be ordered in a mathematical
00118 // sense. This includes uInt, Int, Float, Double, but not Complex. 
00119 // </templating>
00120  
00121 // <templating arg=Range>
00122 // <li> The Range class must have addition and subtraction of Range objects with
00123 // each other as well as multiplication by a scalar defined. Besides the
00124 // scalar types listed above this includes Complex, DComplex, and Arrays of
00125 // any of these types. Use of Arrays is discouraged however.
00126 // </templating>
00127  
00128 // <thrown>
00129 //    <li> AipsError
00130 // </thrown> 
00131 // <todo asof="1997/06/17">
00132 //   <li> Implement flagging in cubic and spline interpolation
00133 // </todo>
00134  
00135 
00136 template <class Domain, class Range>
00137 class InterpolateArray1D
00138 {
00139 public:
00140   // Interpolation methods
00141   enum InterpolationMethod {
00142     // nearest neighbour
00143     nearestNeighbour,
00144     // linear
00145     linear,
00146     // cubic
00147     cubic,
00148     // cubic spline
00149     spline
00150   };
00151 
00152   // Interpolate in the last dimension of array yin whose x coordinates 
00153   // along this dimension are given by xin. 
00154   // Output array yout has interpolated values for x coordinates xout.
00155   // E.g., interpolate a Cube(pol,chan,time) in the time direction, all
00156   // values in the pol-chan plane are interpolated to produce the output
00157   // pol-chan plane.
00158   static void interpolate(Array<Range>& yout, 
00159                           const Vector<Domain>& xout,
00160                           const Vector<Domain>& xin, 
00161                           const Array<Range>& yin,
00162                           Int method);
00163 
00164   // deprecated version of previous function using Blocks - no longer needed
00165   // now that Vector has a fast index operator [].
00166   static void interpolate(Array<Range>& yout, 
00167                           const Block<Domain>& xout,
00168                           const Block<Domain>& xin, 
00169                           const Array<Range>& yin,
00170                           Int method);
00171 
00172   // Interpolate in the last dimension of array yin whose x coordinates 
00173   // along this dimension are given by xin. 
00174   // Output array yout has interpolated values for x coordinates xout.
00175   // This version handles flagged data in a simple way: all outputs
00176   // depending on a flagged input are flagged.
00177   // If goodIsTrue==True, then that means
00178   // a good data point has a flag value of True (usually for 
00179   // visibilities, good is False and for images good is True)
00180   // If extrapolate==False, then xout points outside the range of xin
00181   // will always be marked as flagged.
00182   // TODO: implement flags for cubic and spline (presently input flags
00183   // are copied to output).  
00184   static void interpolate(Array<Range>& yout, 
00185                           Array<Bool>& youtFlags,
00186                           const Vector<Domain>& xout,
00187                           const Vector<Domain>& xin, 
00188                           const Array<Range>& yin,
00189                           const Array<Bool>& yinFlags,
00190                           Int method,
00191                           Bool goodIsTrue=False,
00192                           Bool extrapolate=False);
00193 
00194   // deprecated version of previous function using Blocks - no longer needed
00195   // now that Vector has a fast index operator [].
00196   static void interpolate(Array<Range>& yout, 
00197                           Array<Bool>& youtFlags,
00198                           const Block<Domain>& xout,
00199                           const Block<Domain>& xin, 
00200                           const Array<Range>& yin,
00201                           const Array<Bool>& yinFlags,
00202                           Int method,
00203                           Bool goodIsTrue=False,
00204                           Bool extrapolate=False);
00205 
00206   // Interpolate in the middle axis in 3D array (yin) whose x coordinates along the
00207   // this dimension are given by xin.
00208   // Interpolate a Cube(pol,chan,time) in the chan direction.
00209   // Currently only linear interpolation method is implemented.
00210   // TODO: add support for nearest neiborhood, cubic, and cubic spline. 
00211   static void interpolatey(Cube<Range>& yout,
00212                           const Vector<Domain>& xout,
00213                           const Vector<Domain>& xin,
00214                           const Cube<Range>& yin,
00215                           Int method);
00216 
00217   // Interpolate in the middle dimension of 3D array yin whose x coordinates 
00218   // along this dimension are given by xin. 
00219   // Output array yout has interpolated values for x coordinates xout.
00220   // This version handles flagged data in a simple way: all outputs
00221   // depending on a flagged input are flagged.
00222   // If goodIsTrue==True, then that means
00223   // a good data point has a flag value of True (usually for 
00224   // visibilities, good is False and for images good is True)
00225   // If extrapolate==False, then xout points outside the range of xin
00226   // will always be marked as flagged.
00227   // Currently only linear interpolation method is implemented.
00228   // TODO: add support for nearest neiborhood, cubic, and cubic spline. 
00229   static void interpolatey(Cube<Range>& yout,
00230                           Cube<Bool>& youtFlags,
00231                           const Vector<Domain>& xout,
00232                           const Vector<Domain>& xin,
00233                           const Cube<Range>& yin,
00234                           const Cube<Bool>& yinFlags,
00235                           Int method,
00236                           Bool goodIsTrue=False,
00237                           Bool extrapolate=False);
00238 
00239 private:
00240   // Interpolate the y-vectors of length ny from x values xin to xout.
00241   static void interpolatePtr(PtrBlock<Range*>& yout, 
00242                              Int ny, 
00243                              const Vector<Domain>& xout, 
00244                              const Vector<Domain>& xin,
00245                              const PtrBlock<const Range*>& yin, 
00246                              Int method);
00247 
00248   // Interpolate the y-vectors of length ny from x values xin to xout.
00249   // Take flagging into account
00250   static void interpolatePtr(PtrBlock<Range*>& yout, 
00251                              PtrBlock<Bool*>& youtFlags,
00252                              Int ny, 
00253                              const Vector<Domain>& xout, 
00254                              const Vector<Domain>& xin,
00255                              const PtrBlock<const Range*>& yin, 
00256                              const PtrBlock<const Bool*>& yinFlags, 
00257                              Int method, Bool goodIsTrue,
00258                              Bool extrapolate);
00259 
00260   // Interpolate along yaxis 
00261   static void interpolateyPtr(PtrBlock<Range*>& yout,
00262                              Int na,
00263                              Int nb,
00264                              Int nc,
00265                              const Vector<Domain>& xout,
00266                              const Vector<Domain>& xin,
00267                              const PtrBlock<const Range*>& yin,
00268                              Int method);
00269 
00270   // Take flagging into account
00271   static void interpolateyPtr(PtrBlock<Range*>& yout, 
00272                              PtrBlock<Bool*>& youtFlags,
00273                              Int na,
00274                              Int nb, 
00275                              Int nc, 
00276                              const Vector<Domain>& xout, 
00277                              const Vector<Domain>& xin,
00278                              const PtrBlock<const Range*>& yin, 
00279                              const PtrBlock<const Bool*>& yinFlags, 
00280                              Int method, Bool goodIsTrue,
00281                              Bool extrapolate);
00282 
00283   // Interpolate the y-vectors of length ny from x values xin to xout
00284   // using polynomial interpolation with specified order.
00285   static void polynomialInterpolation(PtrBlock<Range*>& yout, 
00286                                       Int ny, 
00287                                       const Vector<Domain>& xout, 
00288                                       const Vector<Domain>& xin,
00289                                       const PtrBlock<const Range*>& yin, 
00290                                       Int order);
00291 
00292 };
00293 
00294 
00295 
00296 } //# NAMESPACE CASA - END
00297 
00298 #ifndef CASACORE_NO_AUTO_TEMPLATES
00299 #include <scimath/Mathematics/InterpolateArray1D.tcc>
00300 #endif //# CASACORE_NO_AUTO_TEMPLATES
00301 #endif