• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

/home/pascal/depot/filedata/src/statistic.h

Go to the documentation of this file.
00001 /***************************************************************************
00002  *   Copyright (C) 2006 by Nicolas PASCAL   *
00003  *   pascal@icare-pc12   *
00004  *                                                                         *
00005  *   This program is free software; you can redistribute it and/or modify  *
00006  *   it under the terms of the GNU General Public License as published by  *
00007  *   the Free Software Foundation; either version 2 of the License, or     *
00008  *   (at your option) any later version.                                   *
00009  *                                                                         *
00010  *   This program is distributed in the hope that it will be useful,       *
00011  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00012  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00013  *   GNU General Public License for more details.                          *
00014  *                                                                         *
00015  *   You should have received a copy of the GNU General Public License     *
00016  *   along with this program; if not, write to the                         *
00017  *   Free Software Foundation, Inc.,                                       *
00018  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
00019  ***************************************************************************/
00020 
00021 #ifndef STATISTIC_H
00022 #define STATISTIC_H
00023 
00024 #include <numeric>
00025 #include <algorithm>
00026 
00037 template<class T, class Iter_T>
00038 inline T mean(Iter_T first, Iter_T last) {
00039   T sum=accumulate(first,last,T());
00040   size_t nb_val=distance(first,last);
00041   return sum/nb_val;
00042 }
00043 
00058 inline double bilinear_interpolation( const double &x, const double &y,
00059                                 const double &x1, const double &y1,
00060                                 const double &x2, const double &y2,
00061                                 const double &f11, const double &f12, const double &f21, const double &f22) {
00062 double u = (x-x1)/(x2-x1);
00063 double v = (y-y1)/(y2-y1);
00064 return (1.-u)*(1.-v)*f11 + (1.-u)*(v)*f12 + (u)*(1.-v)*f21 + (u)*(v)*f22;
00065 
00066 };
00076 inline double linear_interpolation( const double x, const double x1, const double x2, const double f1, const double f2 ) {
00077   return f1+(x-x1)*(f2-f1)/(x2-x1);
00078 };
00079 
00088 template<class T1, class Iter_T1,class T2, class Iter_T2>
00089 inline void interpolate( Iter_T1 v1_start,  Iter_T1 v1_end,  Iter_T2 v2_start,  Iter_T2 v2_end, T1 &val1, T2 &val2) {
00090   int size_v1=distance(v1_start, v1_end);
00091   int size_v2=distance(v2_start, v2_end);
00092   //--- Check the input parameters validity
00093   if (size_v1<2 || size_v2<2 || size_v1!=size_v2) {
00094     string msg="the abscissa vectors do not have a valid size : size(v1)="+MyTools::to_string(size_v1)+" size(v2)="+MyTools::to_string(size_v2);
00095     InterpolationError e(__FILE__,__LINE__,msg);
00096     throw e;
00097   }
00098 
00099   //--- find the 2 values in v1 that "bounds" val1. If val1 is less that the min value of v1 or gretaer than the max value of v1, an extrapolatino either of an interpolation
00100   int v1_up_bound_idx=-1,v1_low_bound_idx=-1; // indexes of the values that bound val1 in v1
00101 
00102   Iter_T1 up_bound=(Iter_T1)(0);
00103   if (*(v1_start)<*(v1_start+1))
00104     // v1 sorted in increasing order
00105     up_bound=upper_bound(v1_start,v1_end,val1,less<T1>());
00106   else
00107     // v1 sorted in decreasing order
00108     up_bound=upper_bound(v1_start,v1_end,val1,greater<T1>());
00109 
00110   if (up_bound==v1_start) { // val1 is lower than the min value of v1 -> extrapolate
00111     v1_up_bound_idx=1;
00112     v1_low_bound_idx=0;
00113   } else if (up_bound==v1_end) { // val1 is upper than the max value of v1 -> extrapolate
00114     v1_up_bound_idx=size_v1-1;
00115     v1_low_bound_idx=size_v1-2;
00116   } else { // general case
00117     v1_up_bound_idx=distance(v1_start,up_bound);
00118     v1_low_bound_idx=v1_up_bound_idx-1;
00119   }
00120 
00121   //--- find the 2 values that correspond to v1_upper_val and v1_lower_val in v2
00122   T1 v1_upper_val=*(v1_start+v1_up_bound_idx);
00123   T1 v1_lower_val=*(v1_start+v1_low_bound_idx);
00124   T2 v2_upper_val=*(v2_start+v1_up_bound_idx);
00125   T2 v2_lower_val=*(v2_start+v1_low_bound_idx);
00126 
00127   //--- do the interpolation
00128   val2=(T2)(linear_interpolation((double)(val1),(double)(v1_lower_val),(double)(v1_upper_val),(double)(v2_lower_val),(double)(v2_upper_val)));
00129 }
00130 
00142 template<class Iter_T1,class Iter_T2>
00143 inline void interpolate( Iter_T1 v1_start, Iter_T1 v1_end, Iter_T2 v2_start, Iter_T2 v2_end, Iter_T1 vin_start, Iter_T1 vin_end, Iter_T2 vout_start) {
00144   for (Iter_T1 p_inval=vin_start;p_inval!=vin_end;++p_inval )
00145     // interpolate all values of vin and store them in vout
00146     interpolate(v1_start, v1_end, v2_start, v2_end,*p_inval,*(vout_start+distance(vin_start,p_inval)));
00147 }
00148 
00149 template<typename NumType>
00160 long get_nearest_val_idx( const NumType* v_start, const NumType* v_end, const NumType &val) {
00161   if (v_start==NULL || v_end==NULL ||  v_end-v_start<=1)
00162     return -1;
00163 
00164   int nb_val=v_end-v_start; // number of values of the vector
00165   /* if the vector has only one value, the nearest one is at index 0 */
00166   if (nb_val==0) return 0;
00167   assert(nb_val>1);
00168 
00169   /* search for the insertion position of val */
00170   NumType* low=NULL;
00171   if (*(v_start+1)>*(v_start)) // vector is sorted in ascending order
00172     low=lower_bound(const_cast<NumType*>(v_start),const_cast<NumType*>(v_end),val,less<NumType>());
00173   else
00174     low=lower_bound(const_cast<NumType*>(v_start),const_cast<NumType*>(v_end),val,greater<NumType>());
00175   /* search for the nearest value */
00176   int low_idx=low-v_start; // index of the lower bound
00177   if (low_idx==0) return 0;
00178   else if (low_idx==(nb_val)) return nb_val-1;
00179   else {
00180     // compute distance to the bounding values
00181     NumType lower_val=*(v_start+low_idx-1);
00182     NumType lower_val_dist=fabs(val-lower_val);
00183     NumType upper_val=*(v_start+low_idx);
00184     NumType upper_val_dist=fabs(val-upper_val);
00185     if (lower_val_dist<upper_val_dist) return low_idx-1;
00186     else return low_idx;
00187   }
00188 }
00189 
00190 #endif

Generated on Thu Feb 14 2013 17:59:03 for filedata.kdevelop by  doxygen 1.7.1