Commit fc6add90 authored by Laurent Belcour's avatar Laurent Belcour

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

but the streaming algorithm is dumb.
parent bdf57e7e
......@@ -9,7 +9,7 @@
class quadratic_program
{
public:
public:
//! \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) { }
......@@ -155,7 +155,7 @@ public:
}
//! \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;
for(int n=0; n<data->size(); ++n)
......@@ -164,19 +164,57 @@ public:
data->get(n, x, yl, yu);
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++;
vec cu, cl;
get_constraint(x, yl, yu, ny, r, cu, cl);
add_constraints(cu);
add_constraints(cl);
}
}
#ifdef DEBUG
std::cout << "<<TRACE>> " << nb_failed << " constraints where not satified." << std::endl;
#endif
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.
//! This method works only for a single color channel ny !
static int next_unmatching_constraint(int i, int ny, const rational_function* r,
......@@ -196,7 +234,7 @@ public:
return data->size();
}
protected:
protected:
int _np, _nq ;
QuadProgPP::Matrix<double> CI;
......
......@@ -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);
std::cout << "<<INFO>> N in [" << _min_np << ", " << _max_np << "]" << std::endl ;
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() ;
QTime time ;
time.start() ;
......@@ -82,6 +83,7 @@ bool rational_fitter_parallel::fit_data(const data* dat, function* fit, const ar
#ifdef DEBUG
std::cout << "<<DEBUG>> will use " << nb_cores << " threads to compute the quadratic programs" << std::endl ;
#endif
omp_set_num_threads(nb_cores) ;
std::vector<rational_function*> rs;
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
rational_function* rj = dynamic_cast<rational_function*>(plugins_manager::get_function(args["func"]));
rj->setDimX(d->dimX()) ;
rj->setDimY(d->dimY()) ;
rj->setDimY(1) ;
rj->setMin(d->min()) ;
rj->setMax(d->max()) ;
......@@ -106,7 +108,7 @@ bool rational_fitter_parallel::fit_data(const data* dat, function* fit, const ar
int nb_sol_found = 0;
int np, nq ;
#pragma omp parallel for
// #pragma omp parallel for
for(int j=1; j<i; ++j)
{
int temp_np = i - j;
......@@ -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);
if(is_fitted)
{
#pragma omp critical
#pragma omp critical
{
++nb_sol_found ;
if(delta < min_delta)
......@@ -195,29 +197,35 @@ bool rational_fitter_parallel::fit_data(const vertical_segment* d, int np, int n
quadratic_program qp(np, nq);
#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
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(c2);
}
#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);
bool solves_qp = qp.solve_program(x, delta, p, q);
r->update(p, q);
if(solves_qp)
{
if(qp.test_constraints(ny, r, d))
{
#ifdef DEBUG
std::cout << "<<INFO>> got solution " << *r << std::endl ;
#endif
/*
/*
int current = 0, i=0;
while(i < 100 && current < m)
{
......@@ -234,16 +242,20 @@ bool rational_fitter_parallel::fit_data(const vertical_segment* d, int np, int n
++i;
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;
}
}
std::cerr << "<<ERROR>> should not atteign this part of the code" << __FILE__ << ":" << __LINE__ << std::endl;
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