er wrote:
I'm now trying to generalize this i.e. find c such that w1/c+...+wn/c
<= C:
Finally, my solution below. Perhaps some room for improvement still?
template<typename InIt>
typename iterator_value<InIt>::type
find_scale_finite_sum(
InIt b,InIt e,
typename iterator_value<InIt>::type low_init,
typename iterator_value<InIt>::type high_init
){
typedef typename iterator_value<InIt>::type val_;
static val_ zero = static_cast(0);
static val_ two = static_cast(2);
static val_ eps = math::tools::epsilon();
val_ low = low_init;
val_ high = high_init;
val_ mid = (low + high)/two;
val_ delta, acc;
do{
delta = high - low;
acc =
std::accumulate(b,e,zero, lambda::_1 + ( lambda::_2
/mid) );
if(boost::math::isinf(acc)){
low = mid;
}else{
high = mid;
}
mid = (low+high)/two;
}while(
delta - (high - low)>eps
);
return high;
}
// Overload finds initial low, high
typename iterator_value<InIt>::type
find_scale_finite_sum(
InIt b,InIt e
){
// Pseudo code:
// i) Splits [b,e) into maximal size groups with
// finite sums, [b1,e1)
// ii) low = high = find_scale_finite_sum(b1,e1,1,highest)
// iii) low/=2 and high*=2 until
// isinf(sum), !isinf(sum), respectively
// iv) return find_scale_finite_sum(b,e,1ow,high)
}