// This file is part of fityk program. Copyright (C) Marcin Wojdyr // Licence: GNU General Public License version 2 // $Id: fityk.cpp 322 2007-07-24 00:17:11Z wojdyr $ /// implementation of public API of libfityk, declared in fityk.h #include #include #include "fityk.h" #include "common.h" #include "ui.h" #include "logic.h" #include "data.h" #include "sum.h" #include "fit.h" #include "cmd.h" #include "func.h" using namespace std; namespace { fityk::t_show_message *simple_message_handler = 0; FILE* message_sink = 0; void message_handler(OutputStyle style, std::string const& s) { if (simple_message_handler && style != os_input) (*simple_message_handler)(s); } void message_redir(OutputStyle style, std::string const& s) { if (message_sink && style != os_input) fprintf(message_sink, "%s\n", s.c_str()); } void check_valid_dataset(int /*dataset*/) { // do nothing, let throwing exception //assert(dataset >= 0); //assert(dataset < ftk->get_ds_count()); } double get_wssr_or_ssr(Ftk const* ftk, int dataset, bool weigthed) { if (dataset == fityk::all_ds) { double result = 0; for (int i = 0; i < ftk->get_ds_count(); ++i) result += Fit::compute_wssr_for_data(ftk->get_ds(i), weigthed); return result; } else { check_valid_dataset(dataset); return Fit::compute_wssr_for_data(ftk->get_ds(dataset), weigthed); } } vector get_datasets_(Ftk* ftk, int dataset) { vector dd; if (dataset == fityk::all_ds) { for (int i = 0; i < ftk->get_ds_count(); ++i) dd.push_back(ftk->get_ds(i)); } else { check_valid_dataset(dataset); dd.push_back(ftk->get_ds(dataset)); } return dd; } } //anonymous namespace namespace fityk { Point::Point() : x(0), y(0), sigma(1), is_active(true) {} Point::Point(double x_, double y_) : x(x_), y(y_), sigma(1), is_active(true) {} Point::Point(double x_, double y_, fp sigma_) : x(x_), y(y_), sigma(sigma_), is_active(true) {} std::string Point::str() { return "(" + S(x) + "; " + S(y) + "; " + S(sigma) + (is_active ? ")*" : ") "); } Fityk::Fityk() { if (AL != 0) throw ExecuteError("Program is not thread-safe yet, " "so you can only have one Fityk instance."); ftk = new Ftk; AL = ftk; } Fityk::~Fityk() { delete ftk; AL = 0; } void Fityk::execute(string const& s) throw(SyntaxError, ExecuteError, ExitRequestedException) { bool r = parse_and_execute_e(s); if (!r) throw SyntaxError(); } bool Fityk::safe_execute(string const& s) throw(ExitRequestedException) { return ftk->exec(s) == Commands::status_ok; } string Fityk::get_info(string const& s, bool full) throw(SyntaxError, ExecuteError) { try { return get_info_string(s, full); } catch (ExecuteError& e) { if (startswith(e.what(), "Syntax error")) throw SyntaxError(); else throw; } } int Fityk::get_dataset_count() { return ftk->get_ds_count(); } double Fityk::get_sum_value(double x, int dataset) throw(ExecuteError) { check_valid_dataset(dataset); return ftk->get_sum(dataset)->value(x); } vector Fityk::get_sum_vector(vector const& x, int dataset) throw(ExecuteError) { check_valid_dataset(dataset); vector xx(x); vector yy(x.size(), 0.); ftk->get_sum(dataset)->calculate_sum_value(xx, yy); return yy; } int Fityk::get_variable_nr(string const& name) throw(ExecuteError) { if (name.empty()) throw ExecuteError("get_variable_nr() called with empty name"); string vname; if (name[0] == '$') vname = string(name, 1); else if (name[0] == '%' && name.find('.') < name.size() - 1) { string::size_type pos = name.find('.'); Function const* f = ftk->find_function(string(1, pos-1)); vname = f->get_param_varname(string(name, pos+1)); } else vname = name; return ftk->find_variable(vname)->get_nr(); } double Fityk::get_variable_value(string const& name) throw(ExecuteError) { if (name.empty()) throw ExecuteError("get_variable_value() called with empty name"); if (name[0] == '$') return ftk->find_variable(string(name, 1))->get_value(); else if (name[0] == '%' && name.find('.') < name.size() - 1) { string::size_type pos = name.find('.'); Function const* f = ftk->find_function(string(name, 1, pos-1)); return f->get_param_value(string(name, pos+1)); } else return ftk->find_variable(name)->get_value(); } void Fityk::load_data(int dataset, std::vector const& x, std::vector const& y, std::vector const& sigma, std::string const& title) throw(ExecuteError) { check_valid_dataset(dataset); ftk->get_data(dataset)->load_arrays(x, y, sigma, title); } void Fityk::add_point(double x, double y, double sigma, int dataset) throw(ExecuteError) { check_valid_dataset(dataset); ftk->get_data(dataset)->add_one_point(x, y, sigma); } vector const& Fityk::get_data(int dataset) throw(ExecuteError) { check_valid_dataset(dataset); return ftk->get_data(dataset)->points(); } void Fityk::set_show_message(t_show_message *func) { simple_message_handler = func; ftk->get_ui()->set_show_message(message_handler); } void Fityk::redir_messages(std::FILE *stream) { message_sink = stream; ftk->get_ui()->set_show_message(message_redir); } double Fityk::get_wssr(int dataset) throw(ExecuteError) { return get_wssr_or_ssr(ftk, dataset, true); } double Fityk::get_ssr(int dataset) throw(ExecuteError) { return get_wssr_or_ssr(ftk, dataset, false); } double Fityk::get_rsquared(int dataset) throw(ExecuteError) { if (dataset == fityk::all_ds) { double result = 0; for (int i = 0; i < ftk->get_ds_count(); ++i) result += Fit::compute_r_squared_for_data(ftk->get_ds(i)); return result; } else { check_valid_dataset(dataset); return Fit::compute_r_squared_for_data(ftk->get_ds(dataset)); } } int Fityk::get_dof(int dataset) throw(ExecuteError) { return ftk->get_fit()->get_dof(get_datasets_(ftk, dataset)); } vector > Fityk::get_covariance_matrix(int dataset) throw(ExecuteError) { vector c = ftk->get_fit()->get_covariance_matrix(get_datasets_(ftk, dataset)); //reshape size_t na = ftk->get_parameters().size(); assert(c.size() == na * na); vector > r(na); for (size_t i = 0; i != na; ++i) r[i] = vector(c.begin() + i*na, c.begin() + i*(na+1)); return r; } } //namespace fityk