Commit 0092ae2c authored by Laurent Belcour's avatar Laurent Belcour

Updating the fitter interface

parent de1d814b
......@@ -20,12 +20,11 @@ class fitter
//! \brief static function to fit a data set d with the underling
//! function class. Return the best fit (along with fitting
//! information ?)
virtual bool fit_data(const ptr<data> d, function* f, const arguments& args) = 0 ;
virtual bool fit_data(const ptr<data>& d, ptr<function>& f, const arguments& args) = 0 ;
//! \brief parse the command line arguments to setup some general
//! options before any fit. Those options should be resilient to
//! \brief parse the command line arguments to setup some general
//! options before any fit. Those options should be resilient to
//! multiple call to the fit_data procedure
virtual void set_parameters(const arguments& args) = 0 ;
} ;
......@@ -38,7 +38,7 @@ template<typename T> T open_library(const std::string& filename, const char* fun
}
#else
void* handle = dlopen(filename.c_str(), RTLD_GLOBAL | RTLD_LAZY);
if(handle != NULL)
{
void (*res)();
......@@ -79,7 +79,7 @@ function* plugins_manager::get_function(const std::string& filename)
// Parameters of the function object
int nX, nY;
params::input param_in = params::UNKNOWN_INPUT;
params::input param_in = params::UNKNOWN_INPUT;
params::output param_out = params::UNKNOWN_OUTPUT;
arguments args;
......@@ -170,7 +170,7 @@ function* plugins_manager::get_function(const arguments& args)
//! create a <em>compound</em> class to store multiple
//! functions in it.
compound_function* compound = new compound_function();
//! For each args_vec element, create a function object and add
//! it to the compound one.
for(unsigned int i=0; i<args_vec.size(); ++i)
......@@ -268,14 +268,14 @@ function* plugins_manager::get_function(const arguments& args)
func = new product_function(cosine, dynamic_cast<nonlinear_function*>(func));
}
// End of correction
*/
*/
return func;
}
ptr<data> plugins_manager::get_data(const std::string& n)
{
if(n.empty())
{
#ifdef DEBUG
#ifndef DEBUG
std::cout << "<<DEBUG>> no data plugin specified, returning a vertial_segment loader" << std::endl;
#endif
return new vertical_segment();
......@@ -320,7 +320,7 @@ ptr<fitter> plugins_manager::get_fitter(const std::string& n)
}
}
void plugins_manager::check_compatibility(ptr<data>& d, function*& f,
void plugins_manager::check_compatibility(ptr<data>& d, const ptr<function>& f,
const arguments& args)
{
if(d->input_parametrization() == params::UNKNOWN_INPUT &&
......@@ -344,8 +344,8 @@ void plugins_manager::check_compatibility(ptr<data>& d, function*& f,
{
std::cout << "<<INFO>> has to change the parametrization of the input data " << params::get_name(d->input_parametrization()) << std::endl;
std::cout << "<<INFO>> to " << params::get_name(f->input_parametrization()) << std::endl;
data_params* dd = new data_params(d, f->input_parametrization());
d = dd ;
ptr<data_params> dd = new data_params(d, f->input_parametrization());
d = dynamic_pointer_cast<data>(dd) ;
}
else
{
......@@ -367,7 +367,7 @@ void plugins_manager::check_compatibility(ptr<data>& d, function*& f,
}
*/
}
// \todo implement the Darwin (MACOS) version.
#ifdef WIN32
#include <windows.h>
......
......@@ -26,11 +26,11 @@ class plugins_manager
//! \brief load a function from the ALTA input file.
static function* get_function(const std::string& filename);
//! \brief get an instance of the data that is defined in the plugin with
//! filename n. Return null if no one exist.
static ptr<data> get_data(const std::string& n) ;
//! \brief get an instance of the fitter that is defined in the plugin with
//! filename n. Return null if no one exist.
static ptr<fitter> get_fitter(const std::string& n) ;
......@@ -40,7 +40,7 @@ class plugins_manager
//! this has to be done before fitting to ensure that the
//! parametrizations spaces are the same.
//! \todo specify an output parametrization for the function ?
static void check_compatibility(ptr<data>& d, function*& f,
static void check_compatibility(ptr<data>& d, const ptr<function>& f,
const arguments& args) ;
......
......@@ -20,7 +20,7 @@ ALTA_DLL_EXPORT fitter* provide_fitter()
class CeresFunctor : public ceres::CostFunction
{
public:
CeresFunctor(nonlinear_function* f, const vec& xi, const arguments& args) : _f(f), _xi(xi)
CeresFunctor(const ptr<nonlinear_function>& f, const vec& xi, const arguments& args) : _f(f), _xi(xi)
{
set_num_residuals(f->dimY());
mutable_parameter_block_sizes()->push_back(f->nbParameters());
......@@ -28,7 +28,7 @@ class CeresFunctor : public ceres::CostFunction
_log_fit = args.is_defined("log-fit");
}
virtual bool Evaluate(double const* const* x, double* y, double** dy) const
virtual bool Evaluate(double const* const* x, double* y, double** dy) const
{
// Check that the parameters used are within the bounds defined
// by the function
......@@ -91,21 +91,21 @@ class CeresFunctor : public ceres::CostFunction
protected:
// Data point and function to optimize
nonlinear_function* _f;
const ptr<nonlinear_function>& _f;
const vec _xi;
// Arguments of the fitting procedure
bool _log_fit;
};
nonlinear_fitter_ceres::nonlinear_fitter_ceres()
nonlinear_fitter_ceres::nonlinear_fitter_ceres()
{
}
nonlinear_fitter_ceres::~nonlinear_fitter_ceres()
nonlinear_fitter_ceres::~nonlinear_fitter_ceres()
{
}
bool nonlinear_fitter_ceres::fit_data(const ptr<data> d, function* fit, const arguments &args)
bool nonlinear_fitter_ceres::fit_data(const ptr<data>& d, const ptr<function>& fit, const arguments &args)
{
// I need to set the dimension of the resulting function to be equal
// to the dimension of my fitting problem
......@@ -115,12 +115,13 @@ bool nonlinear_fitter_ceres::fit_data(const ptr<data> d, function* fit, const ar
fit->setMax(d->max()) ;
// Convert the function and bootstrap it with the data
if(dynamic_cast<nonlinear_function*>(fit) == NULL)
ptr<nonlinear_function> nf = dynamic_pointer_cast<nonlinear_function>(fit);
if(!nf)
{
std::cerr << "<<ERROR>> the function is not a non-linear function" << std::endl;
return false;
}
nonlinear_function* nf = dynamic_cast<nonlinear_function*>(fit);
#ifndef DEBUG
std::cout << "<<DEBUG>> number of parameters: " << nf->nbParameters() << std::endl;
......
......@@ -19,12 +19,12 @@
*
* \details
* <h3>Third party requirements</h3>
*
*
* You will need three external libraries to compile this plugin:
* <ul>
* <li><a href="https://ceres-solver.googlesource.com/ceres-solver">CERES</a>
* <li><a href="https://ceres-solver.googlesource.com/ceres-solver">CERES</a>
* library, version 1.5.0</li>
* <li><a href="http://code.google.com/p/google-glog">Google glog</a> library
* <li><a href="http://code.google.com/p/google-glog">Google glog</a> library
* version 0.3.1</li>
* <li><a href="http://eigen.tuxfamily.org/">Eigen library</a> version 3</li>
* </ul>
......@@ -61,7 +61,7 @@ class nonlinear_fitter_ceres: public fitter
// Fitting a data object
//
virtual bool fit_data(const ptr<data> d, function* fit, const arguments& args) ;
virtual bool fit_data(const ptr<data>& d, const ptr<function>& fit, const arguments& args) ;
// Provide user parameters to the fitter
//
......@@ -72,4 +72,3 @@ class nonlinear_fitter_ceres: public fitter
// Fitter options
ceres::Solver::Options options;
} ;
......@@ -20,7 +20,7 @@ ALTA_DLL_EXPORT fitter* provide_fitter()
struct EigenFunctor: Eigen::DenseFunctor<double>
{
EigenFunctor(nonlinear_function* f, const ptr<data> d, bool use_cosine) :
EigenFunctor(const ptr<nonlinear_function>& f, const ptr<data> d, bool use_cosine) :
Eigen::DenseFunctor<double>(f->nbParameters(), d->dimY()*d->size()), _f(f), _d(d), _cosine(use_cosine)
{
#ifndef DEBUG
......@@ -73,7 +73,7 @@ struct EigenFunctor: Eigen::DenseFunctor<double>
_di[i] = _x[_f->dimX() + i];
// Should add the resulting vector completely
vec _y = _di - cos*(*_f)(x);
vec _y = _di - cos*_f->value(x);
for(int i=0; i<_f->dimY(); ++i)
y(i*_d->size() + s) = _y[i];
......@@ -129,7 +129,7 @@ struct EigenFunctor: Eigen::DenseFunctor<double>
}
nonlinear_function* _f;
const ptr<nonlinear_function>& _f;
const ptr<data> _d;
// Flags
......@@ -139,7 +139,7 @@ struct EigenFunctor: Eigen::DenseFunctor<double>
struct CompoundFunctor: Eigen::DenseFunctor<double>
{
CompoundFunctor(compound_function* f, int index, const ptr<data> d, bool use_cosine) :
Eigen::DenseFunctor<double>((*f)[index]->nbParameters(), d->dimY()*d->size()), _f(f), _index(index), _d(d), _cosine(use_cosine)
Eigen::DenseFunctor<double>((*f)[index]->nbParameters(), d->dimY()*d->size()), _f(f), _d(d), _index(index), _cosine(use_cosine)
{
#ifndef DEBUG
std::cout << "<<DEBUG>> constructing an EigenFunctor for n=" << inputs() << " parameters and m=" << values() << " points" << std::endl ;
......@@ -275,7 +275,7 @@ nonlinear_fitter_eigen::~nonlinear_fitter_eigen()
{
}
bool nonlinear_fitter_eigen::fit_data(const ptr<data> d, function* fit, const arguments &args)
bool nonlinear_fitter_eigen::fit_data(const ptr<data>& d, const ptr<function>& fit, const arguments &args)
{
// I need to set the dimension of the resulting function to be equal
// to the dimension of my fitting problem
......@@ -285,12 +285,12 @@ bool nonlinear_fitter_eigen::fit_data(const ptr<data> d, function* fit, const ar
fit->setMax(d->max()) ;
// Convert the function and bootstrap it with the data
if(dynamic_cast<nonlinear_function*>(fit) == NULL)
if(!dynamic_pointer_cast<nonlinear_function>(fit))
{
std::cerr << "<<ERROR>> the function is not a non-linear function" << std::endl;
return false;
}
nonlinear_function* nf = dynamic_cast<nonlinear_function*>(fit);
ptr<nonlinear_function> nf = dynamic_pointer_cast<nonlinear_function>(fit);
nf->bootstrap(d, args);
#ifndef DEBUG
......@@ -305,17 +305,16 @@ bool nonlinear_fitter_eigen::fit_data(const ptr<data> d, function* fit, const ar
vec nf_x = nf->parameters();
int info;
#ifdef OLD
if(args.is_defined("fit-compound"))
{
if(dynamic_cast<compound_function*>(nf) == NULL)
ptr<compound_function> compound = dynamic_pointer_cast<compound_function>(nf);
if(!compound_function)
{
std::cerr << "<<ERROR>> you should use --fit-compound with a compound function" << std::endl;
return false;
}
compound_function* compound = dynamic_cast<compound_function*>(nf);
// Register how many parameter are already fitted
int already_fit = 0;
......@@ -363,6 +362,7 @@ bool nonlinear_fitter_eigen::fit_data(const ptr<data> d, function* fit, const ar
}
}
else
#endif
{
Eigen::VectorXd x(nf->nbParameters());
for(int i=0; i<nf->nbParameters(); ++i)
......
......@@ -45,7 +45,7 @@ class nonlinear_fitter_eigen: public fitter
// Fitting a data object
//
virtual bool fit_data(const ptr<data> d, function* fit, const arguments& args) ;
virtual bool fit_data(const ptr<data>& d, const ptr<function>& fit, const arguments& args) ;
// Provide user parameters to the fitter
//
......
......@@ -23,7 +23,7 @@ ALTA_DLL_EXPORT fitter* provide_fitter()
class altaNLP : public Ipopt::TNLP
{
public:
altaNLP(nonlinear_function* f, const ptr<data> d) : TNLP(), _f(f), _d(d)
altaNLP(const ptr<nonlinear_function>& f, const ptr<data>& d) : TNLP(), _f(f), _d(d)
{
}
......@@ -209,8 +209,8 @@ class altaNLP : public Ipopt::TNLP
protected:
const ptr<data> _d;
nonlinear_function* _f;
const ptr<data>& _d;
const ptr<nonlinear_function>& _f;
};
nonlinear_fitter_ipopt::nonlinear_fitter_ipopt()
......@@ -220,7 +220,7 @@ nonlinear_fitter_ipopt::~nonlinear_fitter_ipopt()
{
}
bool nonlinear_fitter_ipopt::fit_data(const ptr<data> d, function* fit, const arguments &args)
bool nonlinear_fitter_ipopt::fit_data(const ptr<data>& d, ptr<function>& fit, const arguments &args)
{
// I need to set the dimension of the resulting function to be equal
// to the dimension of my fitting problem
......@@ -230,12 +230,12 @@ bool nonlinear_fitter_ipopt::fit_data(const ptr<data> d, function* fit, const ar
fit->setMax(d->max()) ;
// Convert the function and bootstrap it with the data
if(dynamic_cast<nonlinear_function*>(fit) == NULL)
ptr<nonlinear_function> nf = dynamic_pointer_cast<nonlinear_function>(fit);
if(!nf)
{
std::cerr << "<<ERROR>> the function is not a non-linear function" << std::endl;
return false;
}
nonlinear_function* nf = dynamic_cast<nonlinear_function*>(fit);
nf->bootstrap(d, args);
#ifndef DEBUG
......
......@@ -54,7 +54,7 @@ class nonlinear_fitter_ipopt: public fitter
// Fitting a data object
//
virtual bool fit_data(const ptr<data> d, function* fit, const arguments& args) ;
virtual bool fit_data(const ptr<data>& d, ptr<function>& fit, const arguments& args) ;
// Provide user parameters to the fitter
//
......
......@@ -34,7 +34,7 @@ void print_nlopt_error(nlopt_result res, const std::string& string)
// The parameter of the function _f should be set prior to this function
// call. If not it will produce undesirable results.
void df(double* fjac, const nonlinear_function* f, const ptr<data> d)
void df(double* fjac, const nonlinear_function* f, const data* d)
{
// Clean memory
memset(fjac, 0.0, f->nbParameters()*sizeof(double));
......@@ -77,7 +77,7 @@ void df(double* fjac, const nonlinear_function* f, const ptr<data> d)
double f(unsigned n, const double* x, double* dy, void* dat)
{
nonlinear_function* _f = (nonlinear_function*)(((void**)dat)[0]);
const ptr<data> _d = *(const ptr<data>*)(((void**)dat)[1]);
const data* _d = (const data*)(((void**)dat)[1]);
// Update the parameters vector
vec _p(_f->nbParameters());
......@@ -125,7 +125,7 @@ nonlinear_fitter_nlopt::~nonlinear_fitter_nlopt()
{
}
bool nonlinear_fitter_nlopt::fit_data(const ptr<data> d, function* fit, const arguments &args)
bool nonlinear_fitter_nlopt::fit_data(const ptr<data>& d, ptr<function>& fit, const arguments &args)
{
// I need to set the dimension of the resulting function to be equal
// to the dimension of my fitting problem
......@@ -135,12 +135,12 @@ bool nonlinear_fitter_nlopt::fit_data(const ptr<data> d, function* fit, const ar
fit->setMax(d->max()) ;
// Convert the function and bootstrap it with the data
if(dynamic_cast<nonlinear_function*>(fit) == NULL)
ptr<nonlinear_function> nf = dynamic_pointer_cast<nonlinear_function>(fit);
if(!nf)
{
std::cerr << "<<ERROR>> the function is not a non-linear function" << std::endl;
return false;
}
nonlinear_function* nf = dynamic_cast<nonlinear_function*>(fit);
nf->bootstrap(d, args);
#ifndef DEBUG
......@@ -233,8 +233,8 @@ bool nonlinear_fitter_nlopt::fit_data(const ptr<data> d, function* fit, const ar
// Create the problem
void* dat[2];
dat[0] = (void*)nf;
dat[1] = (void*)&d;
dat[0] = (void*)nf.get();
dat[1] = (void*)d.get();
res = nlopt_set_min_objective(opt, f, dat);
if(res < 0)
{
......
......@@ -46,7 +46,7 @@ class nonlinear_fitter_nlopt: public fitter
// Fitting a data object
//
virtual bool fit_data(const ptr<data> d, function* fit, const arguments& args) ;
virtual bool fit_data(const ptr<data>& d, ptr<function>& fit, const arguments& args) ;
// Provide user parameters to the fitter
//
......
......@@ -30,11 +30,11 @@ rational_fitter_cgal::~rational_fitter_cgal()
{
}
bool rational_fitter_cgal::fit_data(const ptr<data> dat, function* fit, const arguments&)
bool rational_fitter_cgal::fit_data(const ptr<data>& dat, ptr<function>& fit, const arguments&)
{
rational_function* r = dynamic_cast<rational_function*>(fit) ;
ptr<rational_function> r = dynamic_pointer_cast<rational_function>(fit) ;
const ptr<vertical_segment> d = dynamic_pointer_cast<vertical_segment>(dat) ;
if(r == NULL || !d)
if(!r || !d)
{
std::cerr << "<<ERROR>> not passing the correct class to the fitter" << std::endl ;
return false ;
......@@ -90,7 +90,7 @@ void rational_fitter_cgal::set_parameters(const arguments& args)
_min_nq = args.get_float("min-nq", _max_nq) ;
}
bool rational_fitter_cgal::fit_data(const ptr<vertical_segment>& d, int np, int nq, rational_function* r)
bool rational_fitter_cgal::fit_data(const ptr<vertical_segment>& d, int np, int nq, const ptr<rational_function>& r)
{
// For each output dimension (color channel for BRDFs) perform
// a separate fit on the y-1D rational function.
......
......@@ -25,7 +25,7 @@ class rational_fitter_cgal : public fitter
// Fitting a data object
//
virtual bool fit_data(const ptr<data> d, function* fit, const arguments& args) ;
virtual bool fit_data(const ptr<data>& d, ptr<function>& fit, const arguments& args) ;
// Provide user parameters to the fitter
//
......@@ -35,7 +35,7 @@ class rational_fitter_cgal : public fitter
// Fitting a data object using np elements in the numerator and nq
// elements in the denominator
virtual bool fit_data(const ptr<vertical_segment>& d, int np, int nq, rational_function* fit) ;
virtual bool fit_data(const ptr<vertical_segment>& d, int np, int nq, const ptr<rational_function>& fit) ;
virtual bool fit_data(const ptr<vertical_segment>& dat, int np, int nq, int ny, rational_function_1d* fit) ;
// min and Max usable np and nq values for the fitting
......
......@@ -19,28 +19,18 @@ ALTA_DLL_EXPORT fitter* provide_fitter()
return new rational_fitter_dca();
}
ptr<data> rational_fitter_dca::provide_data() const
{
return new vertical_segment() ;
}
function* rational_fitter_dca::provide_function() const
{
return new rational_function() ;
}
rational_fitter_dca::rational_fitter_dca() : QObject()
rational_fitter_dca::rational_fitter_dca()
{
}
rational_fitter_dca::~rational_fitter_dca()
{
}
bool rational_fitter_dca::fit_data(const ptr<data> dat, function* fit, const arguments &args)
bool rational_fitter_dca::fit_data(const ptr<data>& dat, ptr<function>& fit, const arguments &args)
{
rational_function* r = dynamic_cast<rational_function*>(fit) ;
const vertical_segment* d = dynamic_cast<const vertical_segment*>(dat) ;
if(r == NULL || d == NULL)
ptr<rational_function> r = dynamic_pointer_cast<rational_function>(fit) ;
const ptr<vertical_segment> d = dynamic_pointer_cast<vertical_segment>(dat) ;
if(!r || !d)
{
std::cerr << "<<ERROR>> not passing the correct class to the fitter" << std::endl ;
return false ;
......@@ -85,7 +75,7 @@ void rational_fitter_dca::set_parameters(const arguments& args)
{
}
double distance(const rational_function* f, const ptr<data> d)
double distance(const ptr<rational_function>& f, const ptr<data>& d)
{
double distance = 0.0;
for(int i=0; i<d->size(); ++i)
......@@ -107,7 +97,7 @@ double distance(const rational_function* f, const ptr<data> d)
}
// Bootstrap the DCA algorithm with an already done fit
void rational_fitter_dca::bootstrap(const ptr<data> d, int& np, int& nq, rational_function* fit, double& delta, const arguments& args)
void rational_fitter_dca::bootstrap(const ptr<data>& d, int& np, int& nq, const ptr<rational_function>& fit, double& delta, const arguments& args)
{
if(args.is_defined("bootstrap"))
......@@ -146,7 +136,7 @@ void rational_fitter_dca::bootstrap(const ptr<data> d, int& np, int& nq, rationa
// np and nq are the degree of the RP to fit to the data
// y is the dimension to fit on the y-data (e.g. R, G or B for RGB signals)
// the function return a ration BRDF function and a boolean
bool rational_fitter_dca::fit_data(const ptr<data> d, rational_function* r, const arguments& args)
bool rational_fitter_dca::fit_data(const ptr<data>& d, const ptr<rational_function>& r, const arguments& args)
{
int np, nq;
......@@ -348,7 +338,7 @@ bool rational_fitter_dca::fit_data(const ptr<data> d, rational_function* r, cons
r->update(a, b) ;
#ifdef DEBUG
std::cout << "<<DEBUG>> current rational function: " << *r << std::endl ;
std::cout << "<<DEBUG>> current rational function: " << *(r.get()) << std::endl ;
#endif
// Compute the new delta_k, the distance to the data points
......@@ -386,5 +376,3 @@ bool rational_fitter_dca::fit_data(const ptr<data> d, rational_function* r, cons
return true;
}
}
Q_EXPORT_PLUGIN2(rational_fitter_dca, rational_fitter_dca)
......@@ -6,7 +6,6 @@
#include <engine.h>
// Interface
#include <QObject>
#include <core/function.h>
#include <core/data.h>
#include <core/fitter.h>
......@@ -20,10 +19,8 @@
* \todo I should be able to test when load a BRDF text file to ensure the
* loaded object is correct.
*/
class rational_fitter_dca : public QObject, public fitter
class rational_fitter_dca : public fitter
{
Q_OBJECT
Q_INTERFACES(fitter)
public: // methods
......@@ -32,28 +29,24 @@ class rational_fitter_dca : public QObject, public fitter
// Fitting a data object
//
virtual bool fit_data(const ptr<data> d, function* fit, const arguments& args) ;
virtual bool fit_data(const ptr<data>& d, ptr<function>& fit, const arguments& args) ;
// Provide user parameters to the fitter
//
virtual void set_parameters(const arguments& args) ;
// Obtain associated data and functions
//
virtual ptr<data> provide_data() const ;
virtual function* provide_function() const ;
protected: // function
// Fitting a data object using np elements in the numerator and nq
// elements in the denominator
virtual bool fit_data(const ptr<data> d, rational_function* fit, const arguments& args) ;
virtual bool fit_data(const ptr<data>& d, ptr<rational_function>& fit, const arguments& args) ;
//! \brief Bootstrap the DCA algorithm with an already fitted function. It will
//! load the the rational function object from a text file defined in the argument
//! --bootstrap %filename%.
void bootstrap(const ptr<data> d, int& np, int& nq, rational_function* fit, double& delta,
const arguments& args) ;
void bootstrap(const ptr<data> d, int& np, int& nq,
const ptr<rational_function>& fit, double& delta,
const arguments& args) ;
protected: // data
......
......@@ -24,15 +24,16 @@ rational_fitter_eigen::~rational_fitter_eigen()
{
}
bool rational_fitter_eigen::fit_data(const ptr<data> dat, function* fit, const arguments &args)
bool rational_fitter_eigen::fit_data(const ptr<data>& dat, ptr<function>& fit, const arguments&)
{
rational_function* r = dynamic_cast<rational_function*>(fit) ;
ptr<vertical_segment> d = dynamic_pointer_cast<vertical_segment>(dat) ;
if(r == NULL)
ptr<rational_function> r = dynamic_pointer_cast<rational_function>(fit) ;
if(!r)
{
std::cerr << "<<ERROR>> not passing the correct function object to the fitter" << std::endl ;
return false ;
}
ptr<vertical_segment> d = dynamic_pointer_cast<vertical_segment>(dat) ;
if(!d)
{
std::cerr << "<<ERROR>> not passing the correct data object to the fitter" << std::endl ;
......@@ -74,7 +75,7 @@ void rational_fitter_eigen::set_parameters(const arguments& args)
_nq = args.get_float("nq", 10) ;
}
bool rational_fitter_eigen::fit_data(const ptr<vertical_segment> d, int np, int nq, rational_function* r)