Beispiel #1
0
// outputs vector with: center, height, hwhm, area
// returns values corresponding to peak_traits
vector<double> Guess::estimate_peak_parameters() const
{
    // find the highest point, which must be higher than the previous point
    // and not lower than the next one (-> it cannot be the first/last point)
    int pos = -1;
    if (!sigma_.empty()) {
        for (int i = 1; i < (int) yy_.size() - 1; ++i) {
            int t = (pos == -1 ? i-1 : pos);
            if (sigma_[t] * yy_[i] > sigma_[i] * yy_[t] &&
                    sigma_[i+1] * yy_[i] >= sigma_[i] * yy_[i+1])
                pos = i;
        }
    } else {
        for (int i = 1; i < (int) yy_.size() - 1; ++i) {
            int t = (pos == -1 ? i-1 : pos);
            if (yy_[i] > yy_[t] && yy_[i] >= yy_[i+1])
                pos = i;
        }
    }
    if (pos == -1)
        throw ExecuteError("Peak outside of the range.");

    double height = yy_[pos] * settings_->height_correction;
    double center = xx_[pos];
    double area;
    double hwhm = find_hwhm(pos, &area) * settings_->width_correction;
    return vector4(center, height, hwhm, area);
}
Beispiel #2
0
/// find matching bracket for (, [ or {, return position in string
string::size_type
find_matching_bracket(const string& formula, string::size_type left_pos)
{
    if (left_pos == string::npos)
        return string::npos;
    assert(left_pos < formula.size());
    char opening = formula[left_pos],
         closing = 0;
    if (opening == '(')
        closing = ')';
    else if (opening == '[')
        closing = ']';
    else if (opening == '{')
        closing = '}';
    else
        assert(0);
    int level = 1;
    for (size_t p = left_pos+1; p < formula.size() && level > 0; ++p) {
        if (formula[p] == closing) {
            if (level == 1)
                return p;
            --level;
        } else if (formula[p] == opening)
            ++level;
    }
    throw ExecuteError("Matching bracket `" + S(closing) + "' not found.");
}
Beispiel #3
0
void SettingsMgr::set_as_number(string const& k, double d)
{
    string sp = get_as_string(k);
    if (sp == S(d)) {
        F_->msg("Option '" + k + "' already has value: " + sp);
        return;
    }
    const Option& opt = find_option(k);
    assert(opt.vtype == kInt || opt.vtype == kDouble || opt.vtype == kBool);
    if (opt.vtype == kInt) {
        m_.*opt.val.i.ptr = iround(d);
        if (k == "pseudo_random_seed")
            do_srand();
    }
    else if (opt.vtype == kDouble) {
        if (k == "epsilon") {
            if (d <= 0.)
                throw ExecuteError("Value of epsilon must be positive.");
            epsilon = d;
        }
        m_.*opt.val.d.ptr = d;
    }
    else // if (opt.vtype == kBool)
        m_.*opt.val.b.ptr = (fabs(d) >= 0.5);
}
Beispiel #4
0
const Option& find_option(const string& name)
{
    size_t len = sizeof(options) / sizeof(options[0]);
    for (size_t i = 0; i != len; ++i)
        if (options[i].name == name)
            return options[i];
    throw ExecuteError("Unknown option: " +  name);
}
Beispiel #5
0
static
void change_current_working_dir(const char* path)
{
#ifdef _WIN32
    bool ok = SetCurrentDirectoryA(path);
#else
    bool ok = (chdir(path) == 0);
#endif
    if (!ok)
        throw ExecuteError("Changing current working directory failed.");
}
Beispiel #6
0
void SettingsMgr::set_as_string(string const& k, string const& v)
{
    string sp = get_as_string(k);
    if (sp == v) {
        F_->msg("Option '" + k + "' already has value: " + v);
        return;
    }
    const Option& opt = find_option(k);
    assert(opt.vtype == kString || opt.vtype == kEnum);
    if (opt.vtype == kString) {
        if (k == "logfile" && !v.empty()) {
            FILE* f = fopen(v.c_str(), "a");
            if (!f)
                throw ExecuteError("Cannot open file for writing: " + v);
            // time_now() ends with "\n"
            fprintf(f, "%s. LOG START: %s", fityk_version_line,
                                              time_now().c_str());
            fclose(f);
        }
        else if (k == "numeric_format") {
            if (count(v.begin(), v.end(), '%') != 1)
                throw ExecuteError("Exactly one `%' expected, e.g. '%.9g'");
            set_long_double_format(v);
        }
        else if (k == "cwd") {
            change_current_working_dir(v.c_str());
        }
        m_.*opt.val.s.ptr = v;
    }
    else { // if (opt.vtype == kEnum)
        const char **ptr = opt.allowed_values;
        while (*ptr) {
            if (*ptr == v) {
                m_.*opt.val.e.ptr = *ptr;
                return;
            }
            ++ptr;
        }
        throw ExecuteError("`" + v + "' is not a valid value for `" + k + "'");
    }
}
Beispiel #7
0
bool LMfit::do_iteration()
//pre: init() callled
{
    if (na_ < 1)
        throw ExecuteError("No parameters to fit.");
    iter_nr_++;
    alpha_ = alpha;
    for (int j = 0; j < na_; j++)
        alpha_[na_ * j + j] *= (1.0 + lambda);
    beta_ = beta;
    if (F_->get_verbosity() > 1) { // level: debug
        F_->ui()->mesg(print_matrix (beta_, 1, na_, "beta"));
        F_->ui()->mesg(print_matrix (alpha_, na_, na_, "alpha'"));
    }

    // Matrix solution (Ax=b)  alpha_ * da == beta_
    Jordan (alpha_, beta_, na_);

    // da is in beta_
    if (F_->get_verbosity() >= 1) { // level: verbose
        vector<realt> rel(na_);
        for (int q = 0; q < na_; q++)
            rel[q] = beta_[q] / a[q] * 100;
        if (F_->get_verbosity() >= 1)
            F_->ui()->mesg(print_matrix (rel, 1, na_, "delta(A)/A[%]"));
    }

    for (int i = 0; i < na_; i++)
        beta_[i] = a[i] + beta_[i];   // and now there is new a[] in beta_[]

    if (F_->get_verbosity() >= 1)
        output_tried_parameters(beta_);

    // compute chi2_
    chi2_ = compute_wssr(beta_, dmdm_);
    if (chi2_ < chi2) { // better fitting
        chi2 = chi2_;
        a = beta_;
        compute_derivatives(a, dmdm_, alpha, beta);
        lambda /= F_->get_settings()->lm_lambda_down_factor;
        return true;
    }
    else { // worse fitting
        lambda *= F_->get_settings()->lm_lambda_up_factor;
        return false;
    }
}
Beispiel #8
0
void Guess::set_data(const Data* data, const RealRange& range, int ignore_idx)
{
    pair<int,int> point_indexes = data->get_index_range(range);
    int len = point_indexes.second - point_indexes.first;
    assert(len >= 0);
    if (len == 0)
        throw ExecuteError("guess: empty range");
    xx_.resize(len);
    for (int j = 0; j != len; ++j)
        xx_[j] = data->get_x(point_indexes.first + j);
    if (settings_->guess_uses_weights) {
        sigma_.resize(len);
        for (int j = 0; j != len; ++j)
            sigma_[j] = data->get_sigma(point_indexes.first + j);
    }
    yy_.clear(); // just in case
    yy_.resize(len, 0.);
    data->model()->compute_model(xx_, yy_, ignore_idx);
    for (int j = 0; j != len; ++j)
        yy_[j] = data->get_y(point_indexes.first + j) - yy_[j];
}