26 #ifndef SHORE_MISC_MATHOPS_HPP__
27 #define SHORE_MISC_MATHOPS_HPP__
34 #include <boost/random.hpp>
40 template<
class U,
class T>
43 return static_cast<U
>(floatval+T(0.5));
47 double log2(
const double val);
51 double mean(
const Iter begin,
const Iter
end)
53 if(begin==end)
return 0.0;
54 const double sum=std::accumulate(begin,end,0.0);
55 const double size=end-begin;
73 void append(
const double d);
90 if(begin==end)
return 0.0;
96 sum+=(
static_cast<double>(begin->first)*static_cast<double>(begin->second));
97 nelem+=
static_cast<size_t>(begin->second);
101 return sum/
static_cast<double>(nelem);
114 const size_t size=end-begin;
116 const Iter median_i=begin+(size>>1);
118 std::nth_element(begin,median_i,end);
126 const Iter median_i_lower=median_i-1;
128 std::iter_swap(median_i_lower,std::max_element(begin,median_i));
130 const double med_low= *median_i_lower;
131 const double med_high= *median_i;
132 ret=0.5*(med_low+med_high);
145 for(Iter i=begin;i!=
end;++i)
161 return std::pow(2.0,logsmean);
168 const double amean1=
mean(begin,end);
170 const double gmean2=gmean1*gmean1;
172 return gmean2/amean1;
180 template<
class Iter,
class Oter>
184 const double m=
mean(begin,end);
190 const size_t size=end-begin;
194 const double diff=(*begin)-m;
195 const double diff2=diff*diff;
202 var/=
static_cast<double>(var_n?(
size):(size-1));
204 (*dest++)=var3/(var*sqrt(var)*
static_cast<double>(
size));
205 (*dest)=var4/(var*var*
static_cast<double>(
size))-3.0;
211 double var(
const Iter begin,
const Iter
end,
212 const double mu,
const bool var_n=
false)
220 const double diff=(*s)-mu;
221 const double diff2=diff*diff;
226 const size_t size=end-begin;
230 var/=
static_cast<double>(
size);
234 var=(size>1)?(var/static_cast<double>(size-1)):0.0;
244 const double mu,
const bool var_n=
false)
253 const double diff=s->first-mu;
254 const double diff2=diff*diff;
255 var+=(diff2*
static_cast<double>(s->second));
256 size+=
static_cast<size_t>(s->second);
262 var/=
static_cast<double>(
size);
266 var=(size>1)?(var/(static_cast<double>(size-1))):0.0;
274 double var(
const Iter begin,
const Iter
end,
const bool var_n=
false)
276 const double mu=
mean(begin,end);
277 return var(begin,end,mu,var_n);
282 double stddev(
const Iter begin,
const Iter
end,
const bool var_n=
false)
284 return std::sqrt(
var(begin,end,var_n));
291 const double mu,
const bool var_n=
false)
293 return std::sqrt(
var(begin,end,mu,var_n));
300 const double mu,
const bool var_n=
false)
302 return std::sqrt(
pairs_var(begin,end,mu,var_n));
306 template<
class Xter,
class Yter>
308 Xter x_beg,Xter x_end,
309 Yter y_beg,
double*
const ret_area2)
311 std::pair<double,double> ret(0.0,0.0);
318 const double x=double(*xi);
319 const double y=double(*yi);
328 xnext=double(*x_beg);
329 ynext=double(*y_beg);
336 const double xynext=x*ynext;
337 const double xnexty=xnext*y;
339 area2+=(xynext-xnexty);
340 ret.first+=((x+xnext)*(xynext-xnexty));
341 ret.second+=((y+ynext)*(xynext-xnexty));
346 const double sc=(1.0/(area2+area2+area2));
353 ret.first=0.5*((*(--xi))+(*x_beg));
354 ret.second=0.5*((*(--yi))+(*y_beg));
357 if(ret_area2!=0) (*ret_area2)=area2;
363 template<
class Xter,
class Yter>
365 Xter x_beg,Xter x_end,Yter y_beg)
367 return polycog(x_beg,x_end,y_beg,0);
380 throw std::runtime_error(
"mean filter width must be odd");
386 std::deque<double> w_mod;
391 for(
size_t i=0;i<width;++i)
403 double w_mean=w_total/w_div;
404 for(
size_t i=0;i<=(width>>1);++i)
410 w_mod.push_back(*w_cen);
417 w_total+=(double(*w_end)-w_mod.front());
420 w_mod.push_back(*w_cen);
422 w_mean=w_total/w_div;
438 template<
class T,
class Iter>
439 void seq(T lb,
const T ub,
const size_t len,Iter dest)
443 if(len==1) (*dest)=lb;
447 const T step=(ub-lb)/(len-1);
449 for(
size_t i=0;i<len;++i)
457 template<
class IIter,
class OIter,
class Rng>
462 const size_t size=e-b;
464 std::vector<size_t> vi(size);
465 seq(
size_t(0),size-1,size,vi.begin());
469 boost::uniform_int<size_t> range(0,vi.size()-1);
471 boost::variate_generator<Rng&,boost::uniform_int<size_t> >
474 const size_t id=die();
500 template<
typename IndexIter>
503 typedef typename std::iterator_traits<IndexIter>::value_type value_type;
507 std::generate(ib,ie,gen);
511 template<
typename DataIter,
typename Comparator=
void>
514 const DataIter m_data;
518 :m_data(data),m_cmp(cmp)
521 bool operator()(
const size_t i,
const size_t j)
523 return m_cmp(m_data[i],m_data[j]);
528 template<
typename DataIter>
531 const DataIter m_data;
537 bool operator()(
const size_t i,
const size_t j)
const
539 return m_data[i]<m_data[j];
544 template<
typename DataIter,
typename IndexIter>
549 std::sort(ib,ie,cmp);
553 template<
typename DataIter,
typename IndexIter,
typename Comparator>
554 void index_sort(IndexIter ib,IndexIter ie,DataIter db,Comparator data_cmp)
558 std::sort(ib,ie,cmp);
563 template<
typename DataIter,
typename OrderingIter,
typename RankIter>
564 void ranks(RankIter first,RankIter last,OrderingIter ob,DataIter db)
566 const size_t size=last-first;
569 first[ob[size-1]]=size-1;
570 for(
size_t i=size-2;i>0;--i)
572 if(db[ob[i]]<db[ob[i+1]]) first[ob[i]]=i;
573 else first[ob[i]]=first[ob[i+1]];
575 if(db[ob[0]]<db[ob[1]]) first[ob[0]]=0;
576 else first[ob[0]]=first[ob[1]];
582 template<
class Abs_t>
588 relabs():abs(0),rel(0.0) {}
590 double calc(
const Abs_t& refval)
const
592 if(rel!=0.0)
return rel*double(refval);
596 Abs_t round(
const Abs_t& refval)
const
598 return long(calc(refval)+0.5);
601 Abs_t floor(
const Abs_t& refval)
const
603 return std::floor(calc(refval));
606 Abs_t ceil(
const Abs_t& refval)
const
608 return std::ceil(calc(refval));
611 bool is_absolute()
const
633 template<
class Abs_t>
641 if((!is.eof())&&(is.peek()==
'%'))
653 template<
class Abs_t>
654 std::ostream& operator<<(std::ostream& os,const relabs<Abs_t>& val)
656 if(val.rel!=0.0) os<<(100.0*val.rel)<<
'%';
663 #endif // SHORE_MISC_MATHOPS_HPP__