00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
00100 int v1_up_bound_idx=-1,v1_low_bound_idx=-1;
00101
00102 Iter_T1 up_bound=(Iter_T1)(0);
00103 if (*(v1_start)<*(v1_start+1))
00104
00105 up_bound=upper_bound(v1_start,v1_end,val1,less<T1>());
00106 else
00107
00108 up_bound=upper_bound(v1_start,v1_end,val1,greater<T1>());
00109
00110 if (up_bound==v1_start) {
00111 v1_up_bound_idx=1;
00112 v1_low_bound_idx=0;
00113 } else if (up_bound==v1_end) {
00114 v1_up_bound_idx=size_v1-1;
00115 v1_low_bound_idx=size_v1-2;
00116 } else {
00117 v1_up_bound_idx=distance(v1_start,up_bound);
00118 v1_low_bound_idx=v1_up_bound_idx-1;
00119 }
00120
00121
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
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
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;
00165
00166 if (nb_val==0) return 0;
00167 assert(nb_val>1);
00168
00169
00170 NumType* low=NULL;
00171 if (*(v_start+1)>*(v_start))
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
00176 int low_idx=low-v_start;
00177 if (low_idx==0) return 0;
00178 else if (low_idx==(nb_val)) return nb_val-1;
00179 else {
00180
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