Commit fd0f7c9e authored by Laurent Belcour's avatar Laurent Belcour

Reformating of rational function done, now I need to update all

the plugin to the according format.
parent be73d84a
......@@ -288,7 +288,7 @@ class parametrized
{
return;
}
else if(_out_param == params::UNKNOWN_INPUT)
else if(_out_param == params::UNKNOWN_OUTPUT)
{
_out_param = new_param;
}
......
This diff is collapsed.
......@@ -15,7 +15,7 @@
//! \todo template this
#ifdef NEW
#ifndef NEW
class rational_function_1d : public function
{
public: // methods
......@@ -57,15 +57,16 @@ class rational_function_1d : public function
// STL stream ouput
friend std::ostream& operator<< (std::ostream& out, const rational_function_1d& r) ;
//! Convert a 1D index into a vector of degree for a
//! multinomial coeffcient. The resulting vector v should
//! be used as prod_k x[k]^v[k] for the monomial basis
std::vector<int> index2degree(int i) const ;
protected: // functions
//! Convert a 1D index into a vector of degree for a
//! multinomial coeffcient. The resulting vector v should
//! be used as prod_k x[k]^v[k] for the monomial basis
std::vector<int> index2degree(int i) const ;
static int estimate_dk(int k, int d);
static void populate(std::vector<int>& vec, int N, int M, int j);
static void populate(std::vector<int>& vec, int N, int M, int j);
protected: // data
......@@ -75,22 +76,20 @@ class rational_function_1d : public function
std::vector<double> a ;
std::vector<double> b ;
} ;
/*
// Prior definition for the standard output declaration
template<class RF1D> class rational_function_t ;
template<class RF1D> std::ostream& operator<< (std::ostream& out, rational_function_t<RF1D>& r) ;
*/
template<class RF1D> class rational_function_t : public QObject, public function
/*template<class RF1D>*/ class rational_function : public function
{
Q_OBJECT
Q_INTERFACES(function)
public: // methods
rational_function_t() ;
rational_function_t(int np, int nq) ;
rational_function_t(const std::vector<double>& a, const std::vector<double>& b) ;
virtual ~rational_function_t() ;
rational_function() ;
rational_function(int np, int nq) ;
rational_function(const std::vector<double>& a, const std::vector<double>& b) ;
virtual ~rational_function() ;
// Overload the function operator
virtual vec value(const vec& x) const ;
......@@ -100,14 +99,15 @@ template<class RF1D> class rational_function_t : public QObject, public function
virtual void load(const std::string& filename) ;
// Update the function
virtual void update(int i, RF1D* r) ;
virtual void update(int i, rational_function_1d* r) ;
//! Get the 1D function associated with color channel i. If no one exist, this
//! function allocates a new element. If i > nY, it returns NULL.
virtual RF1D* get(int i) ;
virtual rational_function_1d* get(int i) ;
virtual rational_function_1d* get(int i) const ;
// STL stream ouput
friend std::ostream& operator<< <> (std::ostream& out, rational_function_t<RF1D>& r) ;
friend std::ostream& operator<<(std::ostream& out, rational_function& r) ;
//! \brief Output the rational function as a gnuplot file. It requires
//! the data object to output the function at the input location only.
......@@ -136,7 +136,7 @@ template<class RF1D> class rational_function_t : public QObject, public function
// Store the y \in R rational functions. Each channel is a distinct polynomial
// and should be fitted separately.
std::vector<RF1D*> rs ;
std::vector<rational_function_1d*> rs ;
// Size of the polynomials
//! \todo Change it by a more adaptive scheme, with different np, nq per color
......@@ -145,15 +145,15 @@ template<class RF1D> class rational_function_t : public QObject, public function
} ;
#include "rational_function.inl"
/*
typedef rational_function_t<rational_function_1d> rational_function;
*/
#else
class rational_function : public QObject, public function
{
class rational_function : /*public QObject,*/ public function
{/*
Q_OBJECT
Q_INTERFACES(function)
*/
public: // methods
rational_function() ;
......
This diff is collapsed.
......@@ -2,16 +2,16 @@ TEMPLATE = subdirs
SUBDIRS = \
rational_fitter_cgal \
rational_fitter_quadprog \
rational_fitter_parallel \
rational_fitter_quadprog \
# rational_fitter_parallel \
rational_fitter_eigen \
rational_fitter_leastsquare \
rational_function_chebychev \
rational_fitter_matlab \
rational_fitter_dca \
# rational_fitter_dca \
nonlinear_levenberg_eigen \
nonlinear_function_phong \
nonlinear_function_lafortune \
data_merl \
# data_astm
data_astm
......@@ -107,37 +107,31 @@ void rational_fitter_cgal::set_parameters(const arguments& args)
bool rational_fitter_cgal::fit_data(const vertical_segment* d, int np, int nq, rational_function* r)
{
// Multidimensional coefficients
std::vector<double> Pn ; Pn.reserve(d->dimY()*np) ;
std::vector<double> Qn ; Qn.reserve(d->dimY()*nq) ;
for(int j=0; j<d->dimY(); ++j)
{
if(!fit_data(d, np, nq, j, r))
return false ;
for(int i=0; i<np; ++i) { Pn.push_back(r->getP(i)) ; }
for(int i=0; i<nq; ++i) { Qn.push_back(r->getQ(i)) ; }
}
r->update(Pn, Qn) ;
return true ;
// For each output dimension (color channel for BRDFs) perform
// a separate fit on the y-1D rational function.
for(int j=0; j<d->dimY(); ++j)
{
rational_function_1d* rs = r->get(j);
rs->resize(np, nq);
if(!fit_data(d, np, nq, j, rs))
{
return false ;
}
}
return true ;
}
// dat is the data object, it contains all the points to fit
// 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_cgal::fit_data(const vertical_segment* d, int np, int nq, int ny, rational_function* r)
bool rational_fitter_cgal::fit_data(const vertical_segment* d, int np, int nq, int ny, rational_function_1d* r)
{
// by default, we have a nonnegative QP with Ax - b >= 0
Program qp (CGAL::LARGER, false, 0, false, 0) ;
// Get the maximum value in data to scale the input parameter space
// so that it reduces the values of the polynomial
vec dmax = d->max() ;
// Select the size of the result vector to
// be equal to the dimension of p + q
for(int i=0; i<np+nq; ++i)
......
......@@ -42,7 +42,7 @@ class rational_fitter_cgal : public QObject, public fitter
// Fitting a data object using np elements in the numerator and nq
// elements in the denominator
virtual bool fit_data(const vertical_segment* d, int np, int nq, rational_function* fit) ;
virtual bool fit_data(const vertical_segment* dat, int np, int nq, int ny, rational_function* fit) ;
virtual bool fit_data(const vertical_segment* dat, int np, int nq, int ny, rational_function_1d* fit) ;
// min and Max usable np and nq values for the fitting
int _max_np, _max_nq ;
......
......@@ -71,7 +71,7 @@ bool rational_fitter_dca::fit_data(const data* dat, function* fit, const argumen
int sec = (msec / 1000) % 60 ;
int min = (msec / 60000) % 60 ;
int hour = (msec / 3600000) ;
std::cout << "<<INFO>> got a fit using np = " << r->getP().size() << " & nq = " << r->getQ().size() << " " << std::endl ;
std::cout << "<<INFO>> got a fit" << std::endl;
std::cout << "<<INFO>> it took " << hour << "h " << min << "m " << sec << "s" << std::endl ;
return true ;
......@@ -113,8 +113,9 @@ void rational_fitter_dca::bootstrap(const data* d, int& np, int& nq, rational_fu
if(args.is_defined("bootstrap"))
{
fit->load(args["bootstrap"]);
np = fit->getP().size();
nq = fit->getQ().size();
rational_function_1d* rf = fit->get(0);
np = rf->getP().size();
nq = rf->getQ().size();
}
else
{
......@@ -130,7 +131,12 @@ void rational_fitter_dca::bootstrap(const data* d, int& np, int& nq, rational_fu
q[0] = 1.0;
p[1] = 0.0;
fit->update(p, q);
for(int y=0; y<d->dimY(); ++y)
{
rational_function_1d* rf = fit->get(y);
rf->update(p, q);
}
}
delta = distance(fit, d);
......@@ -246,11 +252,12 @@ bool rational_fitter_dca::fit_data(const data* d, rational_function* r, const ar
// Filling the p part
if(j<np)
{
const double pi = r->p(xi, j) ;
// Updating Eigen matrix
// Updating Eigen matrix
for(int y=0; y<nY; ++y)
{
rational_function_1d* rf = r->get(y);
const double pi = rf->p(xi, j) ;
CI(2*(nY*i + y)+0, nY*j + y) = pi ;
CI(2*(nY*i + y)+1, nY*j + y) = -pi ;
CI(2*M*nY + 2*(nY*i+y) + 0, nY*j+y) = -pi ;
......@@ -259,12 +266,13 @@ bool rational_fitter_dca::fit_data(const data* d, rational_function* r, const ar
}
// Filling the q part
else if(j<np+nq)
{
const double qi = r->q(xi, j-np) ;
{
// Updating Eigen matrix
for(int y=0; y<nY; ++y)
{
rational_function_1d* rf = r->get(y);
const double qi = rf->q(xi, j-np) ;
CI(2*(nY*i + y)+0, nY*j + y) = -(delta_k+xi[d->dimX()+y]) * qi ;
CI(2*(nY*i + y)+1, nY*j + y) = -(delta_k-xi[d->dimX()+y]) * qi ;
CI(2*M*nY + 2*(nY*i+y) + 0, nY*j + y) = 0.0 ;
......@@ -274,9 +282,11 @@ bool rational_fitter_dca::fit_data(const data* d, rational_function* r, const ar
else
{
// Last column of the constraint matrix
vec qk = r->q(xi) ;
for(int y=0; y<nY; ++y)
{
rational_function_1d* rf = r->get(y);
vec qk = rf->q(xi) ;
CI(2*(nY*i + y)+0, nY*j + y) = -qk[y] ;
CI(2*(nY*i + y)+1, nY*j + y) = -qk[y] ;
CI(2*M*nY + 2*(nY*i+y) + 0, nY*j + y) = 0.0 ;
......@@ -333,8 +343,8 @@ bool rational_fitter_dca::fit_data(const data* d, rational_function* r, const ar
}
}
std::vector<double> tempP = r->getP();
std::vector<double> tempQ = r->getQ();
std::vector<double> tempP = rf->getP();
std::vector<double> tempQ = rf->getQ();
r->update(a, b) ;
#ifdef DEBUG
......
......@@ -86,29 +86,27 @@ void rational_fitter_eigen::set_parameters(const arguments& args)
bool rational_fitter_eigen::fit_data(const vertical_segment* d, int np, int nq, rational_function* r)
{
// Multidimensional coefficients
std::vector<double> Pn ; Pn.reserve(d->dimY()*np) ;
std::vector<double> Qn ; Qn.reserve(d->dimY()*nq) ;
for(int j=0; j<d->dimY(); ++j)
{
if(!fit_data(d, np, nq, j, r))
return false ;
for(int i=0; i<np; ++i) { Pn.push_back(r->getP(i)) ; }
for(int i=0; i<nq; ++i) { Qn.push_back(r->getQ(i)) ; }
}
r->update(Pn, Qn) ;
return true ;
// For each output dimension (color channel for BRDFs) perform
// a separate fit on the y-1D rational function.
for(int j=0; j<d->dimY(); ++j)
{
rational_function_1d* rs = r->get(j);
rs->resize(np, nq);
if(!fit_data(d, np, nq, j, rs))
{
return false ;
}
}
return true ;
}
// dat is the data object, it contains all the points to fit
// 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_eigen::fit_data(const vertical_segment* d, int np, int nq, int ny, rational_function* r)
bool rational_fitter_eigen::fit_data(const vertical_segment* d, int np, int nq, int ny, rational_function_1d* r)
{
// Each constraint (fitting interval or point
// add another dimension to the constraint
......
......@@ -41,7 +41,7 @@ class rational_fitter_eigen : public QObject, public fitter
// Fitting a data object using np elements in the numerator and nq
// elements in the denominator
virtual bool fit_data(const vertical_segment* d, int np, int nq, rational_function* fit) ;
virtual bool fit_data(const vertical_segment* dat, int np, int nq, int ny, rational_function* fit) ;
virtual bool fit_data(const vertical_segment* dat, int np, int nq, int ny, rational_function_1d* fit) ;
protected: // data
......
......@@ -87,29 +87,27 @@ void rational_fitter_leastsquare::set_parameters(const arguments& args)
bool rational_fitter_leastsquare::fit_data(const vertical_segment* d, int np, int nq, rational_function* r)
{
// For each output dimension (color channel for BRDFs) perform
// a separate fit on the y-1D rational function.
for(int j=0; j<d->dimY(); ++j)
{
rational_function_1d* rs = r->get(j);
rs->resize(np, nq);
// Multidimensional coefficients
std::vector<double> Pn ; Pn.reserve(d->dimY()*np) ;
std::vector<double> Qn ; Qn.reserve(d->dimY()*nq) ;
for(int j=0; j<d->dimY(); ++j)
{
if(!fit_data(d, np, nq, j, r))
return false ;
for(int i=0; i<np; ++i) { Pn.push_back(r->getP(i)) ; }
for(int i=0; i<nq; ++i) { Qn.push_back(r->getQ(i)) ; }
}
if(!fit_data(d, np, nq, j, rs))
{
return false ;
}
}
r->update(Pn, Qn) ;
return true ;
return true ;
}
// dat is the data object, it contains all the points to fit
// 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_leastsquare::fit_data(const vertical_segment* d, int np, int nq, int ny, rational_function* r)
bool rational_fitter_leastsquare::fit_data(const vertical_segment* d, int np, int nq, int ny, rational_function_1d* r)
{
using namespace Eigen;
......
......@@ -41,7 +41,7 @@ class rational_fitter_leastsquare : public QObject, public fitter
// Fitting a data object using np elements in the numerator and nq
// elements in the denominator
virtual bool fit_data(const vertical_segment* d, int np, int nq, rational_function* fit) ;
virtual bool fit_data(const vertical_segment* dat, int np, int nq, int ny, rational_function* fit) ;
virtual bool fit_data(const vertical_segment* dat, int np, int nq, int ny, rational_function_1d* fit) ;
protected: // data
......
......@@ -109,29 +109,27 @@ void rational_fitter_matlab::set_parameters(const arguments& args)
bool rational_fitter_matlab::fit_data(const vertical_segment* d, int np, int nq, rational_function* r)
{
// Multidimensional coefficients
std::vector<double> Pn ; Pn.reserve(d->dimY()*np) ;
std::vector<double> Qn ; Qn.reserve(d->dimY()*nq) ;
for(int j=0; j<d->dimY(); ++j)
{
if(!fit_data(d, np, nq, j, r))
return false ;
for(int i=0; i<np; ++i) { Pn.push_back(r->getP(i)) ; }
for(int i=0; i<nq; ++i) { Qn.push_back(r->getQ(i)) ; }
}
r->update(Pn, Qn) ;
return true ;
// For each output dimension (color channel for BRDFs) perform
// a separate fit on the y-1D rational function.
for(int j=0; j<d->dimY(); ++j)
{
rational_function_1d* rs = r->get(j);
rs->resize(np, nq);
if(!fit_data(d, np, nq, j, rs))
{
return false ;
}
}
return true ;
}
// dat is the data object, it contains all the points to fit
// 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_matlab::fit_data(const vertical_segment* d, int np, int nq, int ny, rational_function* r)
bool rational_fitter_matlab::fit_data(const vertical_segment* d, int np, int nq, int ny, rational_function_1d* r)
{
// Size of the problem
int N = np+nq ;
......
......@@ -42,7 +42,7 @@ class rational_fitter_matlab : public QObject, public fitter
// Fitting a data object using np elements in the numerator and nq
// elements in the denominator
virtual bool fit_data(const vertical_segment* d, int np, int nq, rational_function* fit) ;
virtual bool fit_data(const vertical_segment* dat, int np, int nq, int ny, rational_function* fit) ;
virtual bool fit_data(const vertical_segment* dat, int np, int nq, int ny, rational_function_1d* fit) ;
protected: // data
......
......@@ -156,7 +156,7 @@ class quadratic_program
}
//! \brief Test all the constraints of the data
bool test_constraints(int ny, const rational_function* r, const vertical_segment* data)
bool test_constraints(int ny, const rational_function_1d* r, const vertical_segment* data)
{
int nb_failed = 0;
for(int n=0; n<data->size(); ++n)
......@@ -207,7 +207,7 @@ class quadratic_program
//! \brief Generate two constraint vectors from a vertical segment and a
//! ration function type.
inline void get_constraint(const vec& xi, const vec& yl, const vec& yu, int ny,
const rational_function* func,
const rational_function_1d* func,
vec& cu, vec& cl)
{
cu.resize(_np+_nq);
......@@ -237,7 +237,7 @@ class quadratic_program
//! \brief Give the next position in the data that is not satisfied.
//! This method works only for a single color channel ny !
static int next_unmatching_constraint(int i, int ny, const rational_function* r,
static int next_unmatching_constraint(int i, int ny, const rational_function_1d* r,
const vertical_segment* data)
{
for(int n=i; n<data->size(); ++n)
......
......@@ -62,7 +62,7 @@ bool rational_fitter_parallel::fit_data(const data* dat, function* fit, const ar
std::cout << "<<INFO>> N in [" << _min_np << ", " << _max_np << "]" << std::endl ;
int k = 1;
for(int i=_min_np; i<=_max_np; i+=rational_function::estimate_dk(k++, d->dimX()))
for(int i=_min_np; i<=_max_np; ++i)
{
std::cout << "<<INFO>> fit using np+nq = " << i << std::endl ;
std::cout.flush() ;
......@@ -251,39 +251,23 @@ bool rational_fitter_parallel::fit_data(const vertical_segment* d, int np, int n
rational_function* r, const arguments &args,
vec& P, vec& Q, double& delta, double& linf_dist, double& l2_dist)
{
rj->setDimX(d->dimX()) ;
rj->setDimY(d->dimY()) ;
rj->setMin(d->min()) ;
rj->setMax(d->max()) ;
for(int j=0; j<d->dimY(); ++j)
{
vec p(np), q(nq);
if(!fit_data(d, np, nq, j, r, p, q, delta))
rational_function_1d* rf = r->get(j);
if(!fit_data(d, np, nq, j, rf, p, q, delta))
return false ;
for(int i=0; i<np; ++i) { P[j*np + i] = p[i] ; }
for(int i=0; i<nq; ++i) { Q[j*nq + i] = q[i] ; }
}
rational_function* rj = dynamic_cast<rational_function*>(plugins_manager::get_function(args["func"]));
rj->setDimX(d->dimX()) ;
rj->setDimY(d->dimY()) ;
rj->setMin(d->min()) ;
rj->setMax(d->max()) ;
rj->update(P, Q);
linf_dist = 0.0;
l2_dist = 0.0;
for(int i=0; i<d->size(); ++i)
{
vec dat = d->get(i);
vec y(d->dimY());
for(int j=0; j<d->dimY(); ++j)
y[j] = dat[d->dimX()+j];
linf_dist = std::max<double>(linf_dist, std::abs<double>(norm(y-rj->value(dat))));
l2_dist += std::pow(norm(y-rj->value(dat)), 2);
rf->update(p, q);
}
l2_dist = std::sqrt(l2_dist / d->size());
delete rj;
linf_dist = r->Linf_distance(d);
l2_dist = r->L2_distance(d);
return true ;
}
......@@ -293,7 +277,7 @@ bool rational_fitter_parallel::fit_data(const vertical_segment* d, int np, int n
// 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_parallel::fit_data(const vertical_segment* d, int np, int nq, int ny,
rational_function* r,
rational_function_1d* r,
vec& p, vec& q, double& delta)
{
const int m = d->size(); // 2*m = number of constraints
......
......@@ -114,52 +114,21 @@ void rational_fitter_quadprog::set_parameters(const arguments& args)
}
bool rational_fitter_quadprog::fit_data(const vertical_segment* d, int np, int nq, rational_function* r)
bool rational_fitter_quadprog::fit_data(const vertical_segment* d, int np, int nq, rational_function* r)
{
// Multidimensional coefficients
/*
std::vector<double> Pn ; Pn.reserve(d->dimY()*np) ;
std::vector<double> Qn ; Qn.reserve(d->dimY()*nq) ;
*/
// For each output dimension (color channel for BRDFs) perform
// a separate fit on the y-1D rational function.
for(int j=0; j<d->dimY(); ++j)
{
#ifdef NEW
rational_function_1d* rs = r->get(j);
rs->resize(np, nq);
if(!fit_data(d, np, nq, j, rs))
{
return false ;
#ifndef DEBUG_MULTIDIMENSIONAL
std::stringstream filename;
filename << "/tmp/fit_channel" << j << ".gnuplot" ;
std::ofstream file(filename.str().c_str(), std::ios_base::trunc);
for(int i=0; i<d->size(); ++i)
{
vec v = d->get(i) ;
// vec y1(d->dimY()) ;
// for(int k=0; k<d->dimY(); ++k) { y1[k] = v[d->dimX() + k] ; }
vec y2 = rs->value(v) ;
for(int u=0; u<d