// 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); }
/// 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."); }
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); }
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); }
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."); }
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 + "'"); } }
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; } }
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]; }