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

Fixing the quadratic program to support streaming of constraints. It works now

but the streaming algorithm is dumb.
parent bdf57e7e
...@@ -9,7 +9,7 @@ ...@@ -9,7 +9,7 @@
class quadratic_program class quadratic_program
{ {
public: public:
//! \brief Constructor need to specify the number of coefficients //! \brief Constructor need to specify the number of coefficients
quadratic_program(int np, int nq) : _np(np), _nq(nq), CI(0.0, _np+_nq, 0) { } quadratic_program(int np, int nq) : _np(np), _nq(nq), CI(0.0, _np+_nq, 0) { }
...@@ -155,7 +155,7 @@ public: ...@@ -155,7 +155,7 @@ public:
} }
//! \brief Test all the constraints of the data //! \brief Test all the constraints of the data
bool test_constraints(const rational_function* r, const vertical_segment* data) bool test_constraints(int ny, const rational_function* r, const vertical_segment* data)
{ {
int nb_failed = 0; int nb_failed = 0;
for(int n=0; n<data->size(); ++n) for(int n=0; n<data->size(); ++n)
...@@ -164,19 +164,57 @@ public: ...@@ -164,19 +164,57 @@ public:
data->get(n, x, yl, yu); data->get(n, x, yl, yu);
vec y = r->value(x); vec y = r->value(x);
if(y < yl || y > yu) bool fail_upper = y > yu;
bool fail_lower = y < yl;
if(fail_lower || fail_upper)
{ {
nb_failed++; nb_failed++;
vec cu, cl;
get_constraint(x, yl, yu, ny, r, cu, cl);
add_constraints(cu);
add_constraints(cl);
} }
} }
#ifdef DEBUG #ifdef DEBUG
std::cout << "<<TRACE>> " << nb_failed << " constraints where not satified." << std::endl; std::cout << "<<TRACE>> " << nb_failed << " constraints where not satified." << std::endl;
#endif #endif
return nb_failed == 0; return nb_failed == 0;
} }
//! \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,
vec& cu, vec& cl)
{
cu.resize(_np+_nq);
cl.resize(_np+_nq);
// Create two vector of constraints
for(int j=0; j<_np+_nq; ++j)
{
// Filling the p part
if(j<_np)
{
const double pi = func->p(xi, j) ;
cu[j] = pi ;
cl[j] = -pi ;
}
// Filling the q part
else
{
const double qi = func->q(xi, j-_np) ;
cu[j] = -yu[ny] * qi ;
cl[j] = yl[ny] * qi ;
}
}
}
//! \brief Give the next position in the data that is not satisfied. //! \brief Give the next position in the data that is not satisfied.
//! This method works only for a single color channel ny ! //! 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* r,
...@@ -196,7 +234,7 @@ public: ...@@ -196,7 +234,7 @@ public:
return data->size(); return data->size();
} }
protected: protected:
int _np, _nq ; int _np, _nq ;
QuadProgPP::Matrix<double> CI; QuadProgPP::Matrix<double> CI;
......
...@@ -56,9 +56,10 @@ bool rational_fitter_parallel::fit_data(const data* dat, function* fit, const ar ...@@ -56,9 +56,10 @@ bool rational_fitter_parallel::fit_data(const data* dat, function* fit, const ar
const int _max_np = args.get_int("np", _min_np); const int _max_np = args.get_int("np", _min_np);
std::cout << "<<INFO>> N in [" << _min_np << ", " << _max_np << "]" << std::endl ; std::cout << "<<INFO>> N in [" << _min_np << ", " << _max_np << "]" << std::endl ;
for(int i=_min_np; i<=_max_np; ++i) for(int i=_min_np; i<=_max_np; ++i)
{ {
std::cout << "<<INFO>> fit using np+nq = " << i << "\r" ; std::cout << "<<INFO>> fit using np+nq = " << i << std::endl ;
std::cout.flush() ; std::cout.flush() ;
QTime time ; QTime time ;
time.start() ; time.start() ;
...@@ -82,6 +83,7 @@ bool rational_fitter_parallel::fit_data(const data* dat, function* fit, const ar ...@@ -82,6 +83,7 @@ bool rational_fitter_parallel::fit_data(const data* dat, function* fit, const ar
#ifdef DEBUG #ifdef DEBUG
std::cout << "<<DEBUG>> will use " << nb_cores << " threads to compute the quadratic programs" << std::endl ; std::cout << "<<DEBUG>> will use " << nb_cores << " threads to compute the quadratic programs" << std::endl ;
#endif #endif
omp_set_num_threads(nb_cores) ; omp_set_num_threads(nb_cores) ;
std::vector<rational_function*> rs; std::vector<rational_function*> rs;
for(int j=0; j<nb_cores; ++j) for(int j=0; j<nb_cores; ++j)
...@@ -89,7 +91,7 @@ bool rational_fitter_parallel::fit_data(const data* dat, function* fit, const ar ...@@ -89,7 +91,7 @@ bool rational_fitter_parallel::fit_data(const data* dat, function* fit, const ar
rational_function* rj = dynamic_cast<rational_function*>(plugins_manager::get_function(args["func"])); rational_function* rj = dynamic_cast<rational_function*>(plugins_manager::get_function(args["func"]));
rj->setDimX(d->dimX()) ; rj->setDimX(d->dimX()) ;
rj->setDimY(d->dimY()) ; rj->setDimY(1) ;
rj->setMin(d->min()) ; rj->setMin(d->min()) ;
rj->setMax(d->max()) ; rj->setMax(d->max()) ;
...@@ -106,7 +108,7 @@ bool rational_fitter_parallel::fit_data(const data* dat, function* fit, const ar ...@@ -106,7 +108,7 @@ bool rational_fitter_parallel::fit_data(const data* dat, function* fit, const ar
int nb_sol_found = 0; int nb_sol_found = 0;
int np, nq ; int np, nq ;
#pragma omp parallel for // #pragma omp parallel for
for(int j=1; j<i; ++j) for(int j=1; j<i; ++j)
{ {
int temp_np = i - j; int temp_np = i - j;
...@@ -118,7 +120,7 @@ bool rational_fitter_parallel::fit_data(const data* dat, function* fit, const ar ...@@ -118,7 +120,7 @@ bool rational_fitter_parallel::fit_data(const data* dat, function* fit, const ar
bool is_fitted = fit_data(d, temp_np, temp_nq, rs[omp_get_thread_num()], p, q, delta); bool is_fitted = fit_data(d, temp_np, temp_nq, rs[omp_get_thread_num()], p, q, delta);
if(is_fitted) if(is_fitted)
{ {
#pragma omp critical #pragma omp critical
{ {
++nb_sol_found ; ++nb_sol_found ;
if(delta < min_delta) if(delta < min_delta)
...@@ -195,29 +197,35 @@ bool rational_fitter_parallel::fit_data(const vertical_segment* d, int np, int n ...@@ -195,29 +197,35 @@ bool rational_fitter_parallel::fit_data(const vertical_segment* d, int np, int n
quadratic_program qp(np, nq); quadratic_program qp(np, nq);
#ifndef TODO_PUT_IN_METHOD #ifndef TODO_PUT_IN_METHOD
for(int i=0; i<d->size()/10; ++i) for(int i=0; i<d->size()/100; ++i)
{ {
// Create two vector of constraints // Create two vector of constraints
vec c1(n), c2(n); vec c1(n), c2(n);
get_constraint(10*i, np, nq, ny, d, r, c1, c2); get_constraint(100*i, np, nq, ny, d, r, c1, c2);
qp.add_constraints(c1); qp.add_constraints(c1);
qp.add_constraints(c2); qp.add_constraints(c2);
} }
#endif #endif
while(true) while(qp.nb_constraints() < 2*m)
{ {
#ifdef DEBUG
std::cout << "<<DEBUG>> number of constraints = " << qp.nb_constraints() << std::endl ;
#endif
QuadProgPP::Vector<double> x(n); QuadProgPP::Vector<double> x(n);
bool solves_qp = qp.solve_program(x, delta, p, q); bool solves_qp = qp.solve_program(x, delta, p, q);
r->update(p, q);
if(solves_qp) if(solves_qp)
{ {
if(qp.test_constraints(ny, r, d))
{
#ifdef DEBUG #ifdef DEBUG
std::cout << "<<INFO>> got solution " << *r << std::endl ; std::cout << "<<INFO>> got solution " << *r << std::endl ;
#endif #endif
/* /*
int current = 0, i=0; int current = 0, i=0;
while(i < 100 && current < m) while(i < 100 && current < m)
{ {
...@@ -234,16 +242,20 @@ bool rational_fitter_parallel::fit_data(const vertical_segment* d, int np, int n ...@@ -234,16 +242,20 @@ bool rational_fitter_parallel::fit_data(const vertical_segment* d, int np, int n
++i; ++i;
current = next; current = next;
} }
*/ */
return qp.test_constraints(r, d); return true;
} }
else }
else if(!solves_qp)
{ {
#ifdef DEBUG
std::cout << "<<DEBUG>> not enough coefficients" << std::endl;
#endif
return false; return false;
} }
} }
std::cerr << "<<ERROR>> should not atteign this part of the code" << __FILE__ << ":" << __LINE__ << std::endl;
return false; return false;
} }
......
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