Commit 9eaf4d9b authored by Laurent Belcour's avatar Laurent Belcour

Correction of a bug in the DCA algorithm

parent 5daec09c
......@@ -62,10 +62,12 @@ vec lafortune_function::value(const vec& x) const
return res;
}
vec lafortune_function::value(const vec& x, const vec& p) const
vec lafortune_function::value(const vec& x, const vec& p)
{
// Test input parameters for correct size
// Test input parameters for correct size and update the
// values of the function.
assert(p.size() == nbParameters());
setParameters(p);
vec res(dimY());
......@@ -112,7 +114,10 @@ void lafortune_function::setNbLobes(int N)
_n = N;
// Update the length of the vectors
_C.resize(_n*_nY*3) ;
if(_isotropic)
_C.resize(_n*_nY*2) ;
else
_C.resize(_n*_nY*3) ;
_N.resize(_n*_nY) ;
}
......@@ -122,7 +127,10 @@ void lafortune_function::setDimY(int nY)
_nY = nY ;
// Update the length of the vectors
_C.resize(_n*_nY*3) ;
if(_isotropic)
_C.resize(_n*_nY*2) ;
else
_C.resize(_n*_nY*3) ;
_N.resize(_n*_nY) ;
_kd.resize(_nY);
......@@ -134,33 +142,47 @@ void lafortune_function::setDimY(int nY)
int lafortune_function::nbParameters() const
{
#ifdef FIT_DIFFUSE
return (4*_n+1)*dimY();
if(_isotropic)
return (3*_n+1)*dimY();
else
return (4*_n+1)*dimY();
#else
return (4*_n)*dimY();
if(_isotropic)
return (3*_n)*dimY();
else
return (4*_n)*dimY();
#endif
}
//! Get the vector of parameters for the function
vec lafortune_function::parameters() const
{
#ifdef FIT_DIFFUSE
vec res((4*_n+1)*dimY());
#else
vec res((4*_n)*dimY());
#endif
for(int n=0; n<_n; ++n)
for(int i=0; i<dimY(); ++i)
{
res[(n*dimY() + i)*4 + 0] = _C[(n*dimY() + i)*3 + 0];
res[(n*dimY() + i)*4 + 1] = _C[(n*dimY() + i)*3 + 1];
res[(n*dimY() + i)*4 + 2] = _C[(n*dimY() + i)*3 + 2];
res[(n*dimY() + i)*4 + 3] = _N[n*dimY() + i];
}
vec res(nbParameters());
for(int n=0; n<_n; ++n)
for(int i=0; i<dimY(); ++i)
{
if(_isotropic)
{
res[(n*dimY() + i)*3 + 0] = _C[(n*dimY() + i)*2 + 0];
res[(n*dimY() + i)*3 + 1] = _C[(n*dimY() + i)*2 + 1];
res[(n*dimY() + i)*3 + 2] = _N[n*dimY() + i];
}
else
{
res[(n*dimY() + i)*4 + 0] = _C[(n*dimY() + i)*3 + 0];
res[(n*dimY() + i)*4 + 1] = _C[(n*dimY() + i)*3 + 1];
res[(n*dimY() + i)*4 + 2] = _C[(n*dimY() + i)*3 + 2];
res[(n*dimY() + i)*4 + 3] = _N[n*dimY() + i];
}
}
#ifdef FIT_DIFFUSE
for(int i=0; i<dimY(); ++i)
{
res[4*_n*dimY() + i] = _kd[i];
if(_isotropic)
{
res[3*_n*dimY() + i] = _kd[i];
}
}
#endif
return res;
......
......@@ -32,12 +32,12 @@ class lafortune_function : public nonlinear_function, public QObject
public: // methods
lafortune_function() : _n(1) { }
lafortune_function() : _n(1), _isotropic(false) { }
// Overload the function operator
virtual vec operator()(const vec& x) const ;
virtual vec value(const vec& x) const ;
virtual vec value(const vec& x, const vec& p) const;
virtual vec value(const vec& x, const vec& p);
//! \brief Load function specific files
virtual void load(const std::string& filename) ;
......@@ -109,9 +109,18 @@ class lafortune_function : public nonlinear_function, public QObject
//! n for the color channel number c.
void getCurrentLobe(int n, int c, double& Cx, double& Cy, double& Cz, double& N) const
{
Cx = _C[(n*_nY + c)*3 + 0];
Cy = _C[(n*_nY + c)*3 + 1];
Cz = _C[(n*_nY + c)*3 + 2];
if(_isotropic)
{
Cx = _C[(n*_nY + c)*2 + 0];
Cy = Cx;
Cz = _C[(n*_nY + c)*2 + 1];
}
else
{
Cx = _C[(n*_nY + c)*3 + 0];
Cy = _C[(n*_nY + c)*3 + 1];
Cz = _C[(n*_nY + c)*3 + 2];
}
N = _N[n*_nY + c];
}
......@@ -122,5 +131,8 @@ class lafortune_function : public nonlinear_function, public QObject
int _n; // Number of lobes
vec _N, _C; // Lobes data
vec _kd; // Diffuse term
//!\brief Flags to get an isotropic lobe
bool _isotropic;
} ;
......@@ -8,7 +8,7 @@ SUBDIRS = \
rational_fitter_leastsquare \
rational_function_chebychev \
rational_fitter_matlab \
# rational_fitter_dca \
rational_fitter_dca \
nonlinear_levenberg_eigen \
nonlinear_function_phong \
nonlinear_function_lafortune \
......
......@@ -65,7 +65,7 @@ bool rational_fitter_dca::fit_data(const data* dat, function* fit, const argumen
QTime time ;
time.start() ;
if(fit_data(d, _max_np, _max_nq, r))
if(fit_data(d, _max_np, _max_nq, r, args))
{
int msec = time.elapsed() ;
int sec = (msec / 1000) % 60 ;
......@@ -110,14 +110,14 @@ double distance(const rational_function* f, const data* d)
}
// Bootstrap the DCA algorithm with an already done fit
void rational_fitter_dca::bootstrap(const data* d, int np, int nq, rational_function* fit, double& delta)
void rational_fitter_dca::bootstrap(const data* d, int np, int nq, rational_function* fit, double& delta, const arguments& args)
{
vec p(np*d->dimY());
vec q(nq*d->dimY());
if(args.is_defined("bootstrap"))
{
fit->load(args["bootstrap"];
fit->load(args["bootstrap"]);
}
else
{
......@@ -135,7 +135,7 @@ void rational_fitter_dca::bootstrap(const data* d, int np, int nq, rational_func
// 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 data* d, int np, int nq, rational_function* r)
bool rational_fitter_dca::fit_data(const data* d, int np, int nq, rational_function* r, const arguments& args)
{
// Size of the problem
int N = np+nq+1 ;
......@@ -145,7 +145,7 @@ bool rational_fitter_dca::fit_data(const data* d, int np, int nq, rational_funct
// Bootstrap the delta and rational function using the Papamarkos
// algorithm.
double delta = 0.0;
bootstrap(d, np, nq, r, delta);
bootstrap(d, np, nq, r, delta, args);
#ifdef DEBUG
std::cout << "<<DEBUG>> delta value after boostrap: " << delta << std::endl;
std::cout << "<<DEBUG>> r: " << *r << std::endl;
......
......@@ -47,12 +47,13 @@ class rational_fitter_dca : 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 data* d, int np, int nq, rational_function* fit) ;
virtual bool fit_data(const data* d, int np, int nq, 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 data* d, int np, int nq, rational_function* fit, double& delta) ;
void bootstrap(const data* d, int np, int nq, rational_function* fit, double& delta,
const arguments& args) ;
protected: // data
......
......@@ -11,14 +11,15 @@ if [ $use_relative -eq 1 ]; then
relative="--dt-relative"
fi
test_generated=1
test_kirby=1
test_generated=0
test_kirby=0
test_alta=1
test_merl=0
#fitter="matlab"
#fitter="quadprog"
fitter="cgal"
#fitter="parallel"
#fitter="cgal"
fitter="parallel"
fitter_args="--min-np 1 --np 100 --min-nq 1 --nq 100"
mkdir tests
......@@ -58,12 +59,27 @@ fi
## Test with ALTA internal data
##
if [ $test_alta -eq 1 ]; then
./build/data2brdf --input ../data/2d/matusik_merl/beige-fabric-double-cc-cos-th-td-90deg.dat --output tests/beige${function_append}.rational $function --fitter /build/librational_fitter_${fitter}.so ${fitter_args} --dt 0.5 --dt-relative > tests/beige${function_append}.out
## Beige matusik fitting only a 2D accumulation in the ROMEIRO param
##
echo "./build/data2brdf --input ../data/2d/matusik_merl/beige-fabric-double-cc-cos-th-td-90deg.dat --output tests/beige${function_append}.rational $function --fitter /build/librational_fitter_${fitter}.so ${fitter_args} --dt 0.5 --dt-relative > tests/beige${function_append}.out"
if [ $? -eq 0 ]; then
echo "Test beige matusik passed"
./build/brdf2gnuplot --input tests/beige${function_append}.rational $function --data ../data/2d/matusik_merl/beige-fabric-double-cc-cos-th-td-90deg.dat --output tests/output_beige.gnuplot > /dev/null
else
echo "Test beige matusik failed"
fi
# if [ $? -eq 0 ]; then
# echo "Test beige matusik passed"
# ./build/brdf2gnuplot --input tests/beige${function_append}.rational $function --data ../data/2d/matusik_merl/beige-fabric-double-cc-cos-th-td-90deg.dat --output tests/output_beige.gnuplot > /dev/null
# else
# echo "Test beige matusik failed"
# fi
## Beige matusik fitting only a 2D slice in the ROMEIRO param
##
echo "./build/data2brdf --input ../data/2d/matusik_merl/beige_fab_cos_th_td.dat --output tests/beige_fab${function_append}.rational $function --fitter /build/librational_fitter_${fitter}.so ${fitter_args} --dt 0.5 --dt-relative > tests/beige_fab${function_append}.out"
# if [ $? -eq 0 ]; then
# echo "Test beige matusik passed"
echo "./build/brdf2gnuplot --input tests/beige_fab${function_append}.rational $function --data ../data/2d/matusik_merl/beige_fab_cos_th_td.dat --output tests/output_beige_fab${function_append}.gnuplot > /dev/null"
# else
# echo "Test beige matusik failed"
# fi
fi
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