00001
00002
00003
00004
00005
00006 #include <cassert>
00007 #include <cctype>
00008 #include "fityk.h"
00009 #include "common.h"
00010 #include "ui.h"
00011 #include "logic.h"
00012 #include "data.h"
00013 #include "model.h"
00014 #include "fit.h"
00015 #include "func.h"
00016 #include "info.h"
00017
00018 using namespace std;
00019
00020 #define CATCH_EXECUTE_ERROR \
00021 catch (ExecuteError& e) { \
00022 last_error_ = string("ExecuteError: ") + e.what(); \
00023 if (throws_) \
00024 throw; \
00025 }
00026
00027 #define CATCH_SYNTAX_ERROR \
00028 catch (SyntaxError& e) { \
00029 last_error_ = string("SyntaxError: ") + e.what(); \
00030 if (throws_) \
00031 throw; \
00032 }
00033
00034 namespace {
00035
00036 fityk::t_show_message *simple_message_handler = 0;
00037
00038 FILE* message_sink = 0;
00039
00040
00041
00042 void message_handler(UserInterface::Style style, string const& s)
00043 {
00044 if (simple_message_handler && style != UserInterface::kInput)
00045 (*simple_message_handler)(s);
00046 }
00047
00048 void message_redir(UserInterface::Style style, string const& s)
00049 {
00050 if (message_sink && style != UserInterface::kInput)
00051 fprintf(message_sink, "%s\n", s.c_str());
00052 }
00053
00054
00055 realt get_wssr_or_ssr(Ftk const* ftk, int dataset, bool weigthed)
00056 {
00057 if (dataset == fityk::all_datasets) {
00058 realt result = 0;
00059 for (int i = 0; i < ftk->get_dm_count(); ++i)
00060 result += Fit::compute_wssr_for_data(ftk->get_dm(i), weigthed);
00061 return result;
00062 }
00063 else {
00064 return Fit::compute_wssr_for_data(ftk->get_dm(dataset), weigthed);
00065 }
00066 }
00067
00068
00069 vector<DataAndModel*> get_datasets_(Ftk* ftk, int dataset)
00070 {
00071 vector<DataAndModel*> dd;
00072 if (dataset == fityk::all_datasets) {
00073 for (int i = 0; i < ftk->get_dm_count(); ++i)
00074 dd.push_back(ftk->get_dm(i));
00075 }
00076 else {
00077 dd.push_back(ftk->get_dm(dataset));
00078 }
00079 return dd;
00080 }
00081
00082 }
00083
00084 namespace fityk
00085 {
00086
00087 Point::Point() : x(0), y(0), sigma(1), is_active(true) {}
00088 Point::Point(realt x_, realt y_) : x(x_), y(y_), sigma(1), is_active(true) {}
00089 Point::Point(realt x_, realt y_, realt sigma_) : x(x_), y(y_), sigma(sigma_),
00090 is_active(true) {}
00091 string Point::str() const { return "(" + S(x) + "; " + S(y) + "; " +
00092 S(sigma) + (is_active ? ")*" : ") "); }
00093
00094
00095 Fityk::Fityk()
00096 : throws_(true), owns_(true)
00097 {
00098 ftk_ = new Ftk;
00099 }
00100
00101 Fityk::Fityk(Ftk* F)
00102 : throws_(true), owns_(false)
00103 {
00104 ftk_ = F;
00105 }
00106
00107 Fityk::~Fityk()
00108 {
00109 if (owns_)
00110 delete ftk_;
00111 }
00112
00113 void Fityk::execute(string const& s) throw(SyntaxError, ExecuteError,
00114 ExitRequestedException)
00115 {
00116 try {
00117 ftk_->get_ui()->raw_execute_line(s);
00118 }
00119 CATCH_SYNTAX_ERROR
00120 CATCH_EXECUTE_ERROR
00121 }
00122
00123 string Fityk::get_info(string const& s, int dataset) throw(SyntaxError,
00124 ExecuteError)
00125 {
00126 try {
00127 string result;
00128 parse_and_eval_info(ftk_, s, dataset, result);
00129 return result;
00130 }
00131 CATCH_SYNTAX_ERROR
00132 CATCH_EXECUTE_ERROR
00133 return "";
00134 }
00135
00136 realt Fityk::calculate_expr(string const& s, int dataset) throw(SyntaxError,
00137 ExecuteError)
00138 {
00139 try {
00140 Lexer lex(s.c_str());
00141 ExpressionParser ep(ftk_);
00142 ep.parse_expr(lex, dataset);
00143 return ep.calculate(0, ftk_->get_data(dataset)->points());
00144 }
00145 CATCH_SYNTAX_ERROR
00146 CATCH_EXECUTE_ERROR
00147 return 0.;
00148 }
00149
00150 int Fityk::get_dataset_count()
00151 {
00152 return ftk_->get_dm_count();
00153 }
00154
00155 realt Fityk::get_model_value(realt x, int dataset) throw(ExecuteError)
00156 {
00157 try {
00158 return ftk_->get_model(dataset)->value(x);
00159 }
00160 CATCH_EXECUTE_ERROR
00161 return 0.;
00162 }
00163
00164 vector<realt> Fityk::get_model_vector(vector<realt> const& x, int dataset)
00165 throw(ExecuteError)
00166 {
00167 vector<realt> xx(x);
00168 vector<realt> yy(x.size(), 0.);
00169 try {
00170 ftk_->get_model(dataset)->compute_model(xx, yy);
00171 }
00172 CATCH_EXECUTE_ERROR
00173 return yy;
00174 }
00175
00176 int Fityk::get_variable_nr(string const& name) throw(ExecuteError)
00177 {
00178 try {
00179 if (name.empty())
00180 throw ExecuteError("get_variable_nr() called with empty name");
00181 string vname;
00182 if (name[0] == '$')
00183 vname = string(name, 1);
00184 else if (name[0] == '%' && name.find('.') < name.size() - 1) {
00185 string::size_type pos = name.find('.');
00186 Function const* f = ftk_->find_function(string(1, pos-1));
00187 string pname = name.substr(pos+1);
00188 vname = f->get_var_name(f->get_param_nr(pname));
00189 }
00190 else
00191 vname = name;
00192 return ftk_->find_variable(vname)->get_nr();
00193 }
00194 CATCH_EXECUTE_ERROR
00195 return 0;
00196 }
00197
00198 void Fityk::load_data(int dataset,
00199 vector<realt> const& x,
00200 vector<realt> const& y,
00201 vector<realt> const& sigma,
00202 string const& title) throw(ExecuteError)
00203 {
00204 try {
00205 ftk_->get_data(dataset)->load_arrays(x, y, sigma, title);
00206 }
00207 CATCH_EXECUTE_ERROR
00208 }
00209
00210 void Fityk::add_point(realt x, realt y, realt sigma, int dataset)
00211 throw(ExecuteError)
00212 {
00213 try {
00214 ftk_->get_data(dataset)->add_one_point(x, y, sigma);
00215 }
00216 CATCH_EXECUTE_ERROR
00217 }
00218
00219 vector<Point> const& Fityk::get_data(int dataset) throw(ExecuteError)
00220 {
00221 static const vector<Point> empty;
00222 try {
00223 return ftk_->get_data(dataset)->points();
00224 }
00225 CATCH_EXECUTE_ERROR
00226 return empty;
00227 }
00228
00229
00230 void Fityk::set_show_message(t_show_message *func)
00231 {
00232 simple_message_handler = func;
00233 ftk_->get_ui()->set_show_message(message_handler);
00234 }
00235
00236 void Fityk::redir_messages(FILE *stream)
00237 {
00238 message_sink = stream;
00239 ftk_->get_ui()->set_show_message(message_redir);
00240 }
00241
00242 void Fityk::out(string const& s) const
00243 {
00244 ftk_->get_ui()->output_message(UserInterface::kNormal, s);
00245 }
00246
00247 realt Fityk::get_wssr(int dataset) throw(ExecuteError)
00248 {
00249 try {
00250 return get_wssr_or_ssr(ftk_, dataset, true);
00251 }
00252 CATCH_EXECUTE_ERROR
00253 return 0.;
00254 }
00255
00256 realt Fityk::get_ssr(int dataset) throw(ExecuteError)
00257 {
00258 try {
00259 return get_wssr_or_ssr(ftk_, dataset, false);
00260 }
00261 CATCH_EXECUTE_ERROR
00262 return 0.;
00263 }
00264
00265 realt Fityk::get_rsquared(int dataset) throw(ExecuteError)
00266 {
00267 try {
00268 if (dataset == fityk::all_datasets) {
00269 realt result = 0;
00270 for (int i = 0; i < ftk_->get_dm_count(); ++i)
00271 result += Fit::compute_r_squared_for_data(ftk_->get_dm(i),
00272 NULL, NULL);
00273 return result;
00274 }
00275 else {
00276 return Fit::compute_r_squared_for_data(ftk_->get_dm(dataset),
00277 NULL, NULL);
00278 }
00279 }
00280 CATCH_EXECUTE_ERROR
00281 return 0.;
00282 }
00283
00284 int Fityk::get_dof(int dataset) throw(ExecuteError)
00285 {
00286 try {
00287 return ftk_->get_fit()->get_dof(get_datasets_(ftk_, dataset));
00288 }
00289 CATCH_EXECUTE_ERROR
00290 return 0;
00291 }
00292
00293 vector<vector<realt> > Fityk::get_covariance_matrix(int dataset)
00294 throw(ExecuteError)
00295 {
00296 try {
00297 vector<DataAndModel*> dss = get_datasets_(ftk_, dataset);
00298 vector<realt> c = ftk_->get_fit()->get_covariance_matrix(dss);
00299
00300 size_t na = ftk_->parameters().size();
00301 assert(c.size() == na * na);
00302 vector<vector<realt> > r(na);
00303 for (size_t i = 0; i != na; ++i)
00304 r[i] = vector<realt>(c.begin() + i*na, c.begin() + i*(na+1));
00305 return r;
00306 }
00307 CATCH_EXECUTE_ERROR
00308 return vector<vector<realt> >();
00309 }
00310
00311 }
00312