Commit c67999f3 authored by Laurent Belcour's avatar Laurent Belcour
Browse files

Updating the plugins to be multidimensionals

parent d028fa16
......@@ -5,17 +5,18 @@
#include <string>
// Interface
#include <QObject>
//#include <QObject>
#include <core/function.h>
#include <core/data.h>
#include <core/fitter.h>
#include <core/args.h>
class rational_data : public QObject, public data
class rational_data : /*public QObject,*/ public data
{
/*
Q_OBJECT
Q_INTERFACES(data)
*/
public: // methods
// Load data from a file
......
......@@ -20,6 +20,17 @@ typedef CGAL::Quadratic_program<ET> Program ;
typedef CGAL::Quadratic_program_solution<ET> Solution ;
typedef CGAL::Quadratic_program_options Options ;
data* rational_fitter_cgal::provide_data() const
{
return new rational_data() ;
}
function* rational_fitter_cgal::provide_function() const
{
return new rational_function() ;
}
rational_fitter_cgal::rational_fitter_cgal() : QObject()
{
}
......@@ -42,18 +53,6 @@ bool rational_fitter_cgal::fit_data(const data* dat, function* fit)
r->setDimX(d->dimX()) ;
r->setDimY(d->dimY()) ;
#ifdef DEBUG_DEGREES
for(int i=0; i<100; ++i)
{
std::vector<int> v = r->index2degree(i) ;
std::cout << i << " = " ;
for(int j=0; j<v.size(); ++j)
std::cout << v[j] << "\t" ;
std::cout << std::endl ;
}
throw ;
#endif
std::cout << "<<INFO>> np in [" << _min_np << ", " << _max_np
<< "] & nq in [" << _min_nq << ", " << _max_nq << "]" << std::endl ;
......@@ -100,7 +99,6 @@ void rational_fitter_cgal::set_parameters(const arguments& args)
_min_nq = args.get_float("min-nq", _max_nq) ;
}
// TODO Finish
bool rational_fitter_cgal::fit_data(const rational_data* d, int np, int nq, rational_function* r)
{
......@@ -317,12 +315,9 @@ bool rational_fitter_cgal::fit_data(const rational_data* d, int np, int nq, int
q[i-np] = v ;
}
}
/*
r = new rational_function(p, q);
/*/
r->update(p, q) ;
//*/
std::cout << "<<INFO>> got solution " << *r << std::endl ;
return true;
}
else
......
......@@ -25,28 +25,26 @@ class rational_fitter_cgal : public QObject, public fitter
virtual ~rational_fitter_cgal() ;
// Fitting a data object
//
virtual bool fit_data(const data* d, function* fit) ;
// Fitting a data object using np elements in the numerator and nq
// elements in the denominator
virtual bool fit_data(const rational_data* d, int np, int nq, rational_function* fit) ;
virtual bool fit_data(const rational_data* dat, int np, int nq, int ny, rational_function* fit) ;
// Provide user parameters to the fitter
//
virtual void set_parameters(const arguments& args) ;
virtual data* provide_data() const
{
return new rational_data() ;
} ;
virtual function* provide_function() const
{
return new rational_function() ;
} ;
// Obtain associated data and functions
//
virtual data* provide_data() const ;
virtual function* provide_function() const ;
protected: // data
// Fitting a data object using np elements in the numerator and nq
// elements in the denominator
virtual bool fit_data(const rational_data* d, int np, int nq, rational_function* fit) ;
virtual bool fit_data(const rational_data* dat, int np, int nq, int ny, rational_function* fit) ;
// min and Max usable np and nq values for the fitting
int _max_np, _max_nq ;
int _min_np, _min_nq ;
} ;
......@@ -12,6 +12,16 @@
#include <QTime>
data* rational_fitter_eigen::provide_data() const
{
return new rational_data() ;
}
function* rational_fitter_eigen::provide_function() const
{
return new rational_function() ;
}
rational_fitter_eigen::rational_fitter_eigen() : QObject()
{
}
......@@ -40,6 +50,7 @@ bool rational_fitter_eigen::fit_data(const data* dat, function* fit)
QTime time ;
time.start() ;
if(fit_data(d, _np, _nq, r))
{
int msec = time.elapsed() ;
......@@ -64,7 +75,6 @@ void rational_fitter_eigen::set_parameters(const arguments& args)
_nq = args.get_float("nq", 10) ;
}
// TODO Finish
bool rational_fitter_eigen::fit_data(const rational_data* d, int np, int nq, rational_function* r)
{
......@@ -129,16 +139,33 @@ bool rational_fitter_eigen::fit_data(const rational_data* d, int np, int nq, int
// M.setZero();
// M.selfadjointView<Lower>().rankUpdate(CI.transpose());
Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> solver(M) ;
// std::cout << M << std::endl << std::endl ;
/*
std::cout << M.size() << std::endl << std::endl ;
std::cout << M << std::endl << std::endl ;
*/
if(solver.info() == Eigen::Success)
{
/*
std::cout << solver.eigenvalues() << std::endl ;
*/
// Calculate the minimum eigen value and
// its position
#ifdef NOT_WORKING
int min_id = 0;
double min_val = solver.eigenvalues().minCoeff(&min_id);
#else
int min_id = 0 ;
double min_val = std::numeric_limits<double>::max() ;
for(int i=0; i<solver.eigenvalues().size(); ++i)
{
double value = solver.eigenvalues()[i] ;
if(value >= 0 && value < min_val)
{
min_id = i ;
min_val = value ;
}
}
#endif
// Recopy the vector d
std::vector<double> p, q;
p.assign(np, 0.0) ; q.assign(nq, 0.0) ;
......
......@@ -23,25 +23,27 @@ class rational_fitter_eigen : public QObject, public fitter
rational_fitter_eigen() ;
virtual ~rational_fitter_eigen() ;
// Fitting a data object
//
virtual bool fit_data(const data* d, function* fit) ;
// Provide user parameters to the fitter
//
virtual void set_parameters(const arguments& args) ;
// Obtain associated data and functions
//
virtual 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 rational_data* d, int np, int nq, rational_function* fit) ;
virtual bool fit_data(const rational_data* dat, int np, int nq, int ny, rational_function* fit) ;
virtual void set_parameters(const arguments& args) ;
virtual data* provide_data() const
{
return new rational_data() ;
} ;
virtual function* provide_function() const
{
return new rational_function() ;
} ;
protected: // data
// min and Max usable np and nq values for the fitting
......
......@@ -16,6 +16,16 @@
#include <rational_function.h>
#include <rational_data.h>
data* rational_fitter_quadprog::provide_data() const
{
return new rational_data() ;
}
function* rational_fitter_quadprog::provide_function() const
{
return new rational_function() ;
}
rational_fitter_quadprog::rational_fitter_quadprog() : QObject()
{
}
......@@ -43,11 +53,11 @@ bool rational_fitter_quadprog::fit_data(const data* dat, function* fit)
int temp_np = _min_np, temp_nq = _min_nq ;
while(temp_np <= _max_np || temp_nq <= _max_nq)
while(temp_np < _max_np || temp_nq < _max_nq)
{
QTime time ;
time.start() ;
if(fit_data(d, temp_np, temp_nq, r))
{
int msec = time.elapsed() ;
......@@ -85,7 +95,31 @@ void rational_fitter_quadprog::set_parameters(const arguments& args)
}
bool rational_fitter_quadprog::fit_data(const data* dat, int np, int nq, function* rf)
bool rational_fitter_quadprog::fit_data(const rational_data* 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 ;
}
// 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_quadprog::fit_data(const rational_data* dat, int np, int nq, int ny, rational_function* rf)
{
// by default, we have a nonnegative QP with Ax - b >= 0
// Program qp (CGAL::LARGER, false, 0, false, 0) ;
......@@ -155,15 +189,15 @@ bool rational_fitter_quadprog::fit_data(const data* dat, int np, int nq, functio
d->get(i, yl, yu) ;
const double qi = r->q(d->get(i), j-np) ;
a0_norm += qi*qi * (yl[0]*yl[0]) ;
CI[j][i] = -yl[0] * qi ;
a0_norm += qi*qi * (yl[ny]*yl[ny]) ;
CI[j][i] = -yl[ny] * qi ;
a1_norm += qi*qi * (yu[0]*yu[0]) ;
CI[j][i+d->size()] = yu[0] * qi ;
a1_norm += qi*qi * (yu[ny]*yu[ny]) ;
CI[j][i+d->size()] = yu[ny] * qi ;
// Updating Eigen matrix
eCI(j,i) = -yl[0] * qi ;
eCI(j,i+d->size()) = yu[0] * qi ;
eCI(j,i) = -yl[ny] * qi ;
eCI(j,i+d->size()) = yu[ny] * qi ;
}
}
......@@ -189,7 +223,6 @@ bool rational_fitter_quadprog::fit_data(const data* dat, int np, int nq, functio
#endif
// Update the ci column with the delta parameter
// (See Celis et al. 2007 p.12)
Eigen::JacobiSVD<Eigen::MatrixXd> svd(eCI);
const double sigma_m = svd.singularValues()(std::min(2*d->size(), np+nq)-1) ;
const double sigma_M = svd.singularValues()(0) ;
......@@ -225,57 +258,6 @@ bool rational_fitter_quadprog::fit_data(const data* dat, int np, int nq, functio
ci[i] = ci[i] * delta ;
}
#ifdef DEBUG
// Export some informations on the problem to solve
// std::cout << "<<DEBUG>> " << qp.get_n() << " variables" << std::endl ;
// std::cout << "<<DEBUG>> " << qp.get_m() << " constraints" << std::endl ;
#endif
/*
if(qp.is_linear() && !qp.is_nonnegative())
{
std::cerr << "<<ERROR>> the problem should not be linear or negative!" << std::endl ;
return false ;
}
*/
#ifdef EXTREM_DEBUG
/*
// Iterate over the rows
std::cout << std::endl ;
std::cout << "A = [" ;
for(int j=0; j<qp.get_m(); ++j)
{
if(j == 0) std::cout << " " ;
// Iterate over the columns
for(int i=0; i<qp.get_n(); ++i)
{
if(i > 0) std::cout << ",\t" ;
std::cout << *(*(qp.get_a()+i) +j) ;
}
std::cout << ";" ;
if(j < qp.get_n()-1) std::cout << std::endl ;
}
std::cout << "]" << std::endl << std::endl ;
std::cout << std::endl ;
std::cout << "D = [" ;
for(int j=0; j<np+nq; ++j)
{
if(j == 0) std::cout << " " ;
// Iterate over the columns
for(int i=0; i<np+nq; ++i)
{
if(i > 0) std::cout << ",\t" ;
std::cout << *(*(qp.get_d()+i) +j) ;
}
std::cout << ";" ;
}
std::cout << "]" << std::endl << std::endl ;
*/
#endif
// Compute the solution
QuadProgPP::Vector<double> x;
double cost = QuadProgPP::solve_quadprog(G, g, CE, ce, CI, ci, x);
......@@ -306,13 +288,9 @@ bool rational_fitter_quadprog::fit_data(const data* dat, int np, int nq, functio
}
}
if(r != NULL)
{
delete r ;
}
r = new rational_function(p, q);
r->update(p, q);
std::cout << "<<INFO>> got solution " << *r << std::endl ;
return true;
}
else
......
......@@ -26,24 +26,25 @@ class rational_fitter_quadprog : public QObject, public fitter
virtual ~rational_fitter_quadprog() ;
// Fitting a data object
//
virtual bool fit_data(const data* d, function* fit) ;
// Fitting a data object using np elements in the numerator and nq
// elements in the denominator
virtual bool fit_data(const data* d, int np, int nq, function* fit) ;
// Provide user parameters to the fitter
//
virtual void set_parameters(const arguments& args) ;
virtual data* provide_data() const
{
return new rational_data() ;
} ;
virtual function* provide_function() const
{
return new rational_function() ;
} ;
// Obtain associated data and functions
//
virtual data* provide_data() const ;
virtual function* provide_function() const ;
protected: // data
// Fitting a data object using np elements in the numerator and nq
// elements in the denominator
virtual bool fit_data(const rational_data* d, int np, int nq, rational_function* fit) ;
virtual bool fit_data(const rational_data* dat, int np, int nq, int ny, rational_function* fit) ;
// min and Max usable np and nq values for the fitting
int _max_np, _max_nq ;
int _min_np, _min_nq ;
......
......@@ -5,18 +5,19 @@
#include <string>
// Interface
#include <QObject>
//#include <QObject>
#include <core/function.h>
#include <core/data.h>
#include <core/fitter.h>
#include <core/args.h>
#include <core/common.h>
class rational_function : public QObject, public function
class rational_function : /*public QObject,*/ public function
{
/*
Q_OBJECT
Q_INTERFACES(function)
*/
public: // methods
rational_function() ;
......
......@@ -106,9 +106,12 @@ int main(int argc, char** argv)
if(fitters.size() > 0 && datas.size() > 0 && functions.size() > 0)
{
fitters[0]->set_parameters(args) ;
/*
function* f = functions[0] ;
data* d = datas[0] ;
*/
function* f = fitters[0]->provide_function() ;
data* d = fitters[0]->provide_data() ;
d->load(args["input"], args);
bool is_fitted = fitters[0]->fit_data(d, f) ;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment