// 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 <cassert>
#include <cctype>
#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<DataWithSum*> get_datasets_(Ftk* ftk, int dataset)
{
vector<DataWithSum*> 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<double> Fityk::get_sum_vector(vector<double> const& x, int dataset)
throw(ExecuteError)
{
check_valid_dataset(dataset);
vector<double> xx(x);
vector<double> 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<double> const& x,
std::vector<double> const& y,
std::vector<double> 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<Point> 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<vector<double> > Fityk::get_covariance_matrix(int dataset)
throw(ExecuteError)
{
vector<double> 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<vector<double> > r(na);
for (size_t i = 0; i != na; ++i)
r[i] = vector<double>(c.begin() + i*na, c.begin() + i*(na+1));
return r;
}
} //namespace fityk
syntax highlighted by Code2HTML, v. 0.9.1