casa
$Rev:20696$
|
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