예제 #1
0
void theta::fill_mode_support(theta::ParValues & mode,
                std::map<theta::ParId, std::pair<double, double> > & support, const theta::Distribution & d){
    ParIds pids = d.get_parameters();
    d.mode(mode);
    theta_assert(mode.contains_all(pids));
    for(ParIds::const_iterator p_it=pids.begin(); p_it!=pids.end(); ++p_it){
        support[*p_it] = d.support(*p_it);
    }
}
예제 #2
0
파일: secant.hpp 프로젝트: blinkseb/theta
double brent(const FT & f, double a, double b, double xtol, double fa, double fb, double f_accuracy = 1e-7, unsigned int limit = 10000){
    if(fabs(fa) <= f_accuracy) return a;
    if(fabs(fb) <= f_accuracy) return b;
    theta_assert(fa * fb < 0.0);
    if(fabs(fa) < fabs(fb)){
        std::swap(fa, fb);
        std::swap(a, b);
    }
    double d = 0.0;
    double c = a;
    double fc = fa;
    bool mflag = true;
    for(unsigned int i=0; i < limit; ++i){
        if(fabs(a-b) <= xtol){
            return (a + b) / 2;
        }
        if(fabs(fa) <= f_accuracy) return a;
        if(fabs(fb) <= f_accuracy) return b;
        double s;
        if(fabs(fa - fc) < f_accuracy && fabs(fb - fc) < f_accuracy){
            s = a * fb * fc / (fa - fb) / (fa - fc) + b * fa * fc / (fb - fa) / (fb - fc) + c * fa * fb / (fc - fa) / (fc - fb);
        }
        else{
            s = b - fb * (b - a) / (fb - fa);
        }
        double tmp2 = (3 * a + b) / 4;
        if (!((s > tmp2 && s < b) || (s < tmp2 && s > b))
             || (mflag && fabs(s - b) >= fabs(b - c) / 2)
             || (!mflag && fabs(s - b) >= fabs(c - d) / 2)
             || (mflag && fabs(b - c) < xtol)
             || (!mflag && (fabs(c - d) < xtol))
           ){
            s = (a + b) / 2;
            mflag = true;
        }
        else{
            mflag = false;
        }
        double fs = f(s);
        d = c;
        c = b;
        fc = fb;
        if (fa * fs < 0) { b = s; fb = fs; }
        else { a = s; fa = fs; }
        if(fabs(fa) < fabs(fb)){
            std::swap(fa, fb);
            std::swap(a, b);
        }
    }
    throw theta::Exception("brent: Too many iterations");
}
예제 #3
0
파일: secant.hpp 프로젝트: blinkseb/theta
double secant(double x_low, double x_high, double x_accuracy, double f_x_low, double f_x_high, double f_accuracy, const T & function, int limit_depth = 500){
    theta_assert(std::isfinite(x_low) && std::isfinite(x_high));
    theta_assert(x_low <= x_high);
    theta_assert(std::isfinite(f_x_low) && std::isfinite(f_x_high));
    theta_assert(limit_depth > 0);
    if(f_x_low * f_x_high >= 0) throw std::invalid_argument("secant: function values have the same sign!");
    if(std::fabs(f_x_low) <= f_accuracy) return x_low;
    if(std::fabs(f_x_high) <= f_accuracy) return x_high;

    const double old_interval_length = x_high - x_low;    
    //calculate intersection point for secant method:
    double x_intersect = x_low - (x_high - x_low) / (f_x_high - f_x_low) * f_x_low;
    theta_assert(x_intersect >= x_low);
    theta_assert(x_intersect <= x_high);
    if(old_interval_length < x_accuracy){
        return x_intersect;
    }
    double f_x_intersect = function(x_intersect);
    double f_mult = f_x_low * f_x_intersect;
    //fall back to bisection if the new interval would not be much smaller:
    double new_interval_length = f_mult < 0 ? x_intersect - x_low : x_high - x_intersect;
    if(new_interval_length > 0.5 * old_interval_length){
        x_intersect = 0.5*(x_low + x_high);
        f_x_intersect = function(x_intersect);
        f_mult = f_x_low * f_x_intersect;
    }
    if(f_mult < 0){
        return secant(x_low, x_intersect, x_accuracy, f_x_low, f_x_intersect, f_accuracy, function, limit_depth - 1);
    }
    else if(f_mult > 0.0){
        return secant(x_intersect, x_high, x_accuracy, f_x_intersect, f_x_high, f_accuracy, function, limit_depth - 1);
    }
    //it can actually happen that we have 0.0. In this case, return the x value for
    // the smallest absolute function value:
    else{
        f_x_intersect = fabs(f_x_intersect);
        f_x_low = fabs(f_x_low);
        f_x_high = fabs(f_x_high);
        if(f_x_low < f_x_high && f_x_low < f_x_intersect) return x_low;
        if(f_x_high < f_x_intersect) return x_high;
        return x_intersect;
    }
}
예제 #4
0
 virtual void operator()(const T& t) const {
     theta_assert(h0.get_nbins() == t.get_nbins());
     h0.add_with_coeff(coeff, t);
 }