Commit 5f852776 authored by pacanows's avatar pacanows

Merge

parents 02d1734f 4513913d
......@@ -64,20 +64,7 @@ class data : public parametrized
// Get data size, e.g. the number of samples to fit
virtual int size() const = 0 ;
// Get min and max input space values
virtual vec min() const = 0 ;
virtual vec max() const = 0 ;
// Get the size of the input X domain and output Y domain
virtual int dimX() const { return _nX ; }
virtual int dimY() const { return _nY ; }
protected: // data
// Dimensions of the data
int _nX, _nY ;
} ;
/*! \brief Change the parametrization of data to fit the parametrization of the
......@@ -168,21 +155,9 @@ class data_params : public data
return _data.size();
}
// Get min and max input space values
virtual vec min() const
{
return _min;
}
virtual vec max() const
{
return _max;
}
protected: // data
data_params::clustrering _clustering_method;
std::vector<vec> _data;
vec _min, _max;
};
......@@ -22,30 +22,6 @@ void function::bootstrap(const data*, const arguments& args)
}
}
// Acces to the domain of definition of the function
void function::setMin(const vec& min)
{
#ifdef DEBUG
assert(min.size() == _nX) ;
#endif
_min = min ;
}
void function::setMax(const vec& max)
{
#ifdef DEBUG
assert(max.size() == _nX) ;
#endif
_max = max ;
}
vec function::getMin() const
{
return _min ;
}
vec function::getMax() const
{
return _max ;
}
void function::save(const std::string& filename, const arguments& args) const
{
bool is_alta = !args.is_defined("export") || args["export"] == "alta";
......
......@@ -37,32 +37,6 @@ class function : public parametrized
//! example. The default behaviour is to load a function file.
virtual void bootstrap(const data*, const arguments& args);
//! Provide the dimension of the input space of the function
virtual int dimX() const { return _nX ; }
//! Provide the dimension of the output space of the function
virtual int dimY() const { return _nY ; }
//! Set the dimension of the input space of the function
virtual void setDimX(int nX) { _nX = nX ; }
//! Set the dimension of the output space of the function
virtual void setDimY(int nY) { _nY = nY ; }
/* DEFINITION DOMAIN OF THE FUNCTION */
//! \brief Set the minimum value the input can take
virtual void setMin(const vec& min) ;
//! \brief Set the maximum value the input can take
virtual void setMax(const vec& max) ;
//! \brief Get the minimum value the input can take
virtual vec getMin() const ;
//! \brief Get the maximum value the input can take
virtual vec getMax() const ;
/* IMPORT/EXPORT FUNCTIONS */
//! Load function specific files
......@@ -109,10 +83,6 @@ class function : public parametrized
protected: // data
// Dimension of the function & domain of definition.
int _nX, _nY ;
vec _min, _max ;
};
/*! \brief Non-linear function interface
......
......@@ -357,3 +357,27 @@ void params::print_input_params()
std::cout << it->second.name << std::endl;
}
}
// Acces to the domain of definition of the function
void parametrized::setMin(const vec& min)
{
#ifdef DEBUG
assert(min.size() == _nX) ;
#endif
_min = min ;
}
void parametrized::setMax(const vec& max)
{
#ifdef DEBUG
assert(max.size() == _nX) ;
#endif
_max = max ;
}
vec parametrized::min() const
{
return _min ;
}
vec parametrized::max() const
{
return _max ;
}
......@@ -8,6 +8,8 @@
#include <cassert>
#include <iostream>
#include "common.h"
/*! \class params
* \ingroup core
* \brief a static class allowing to change from one parametrization
......@@ -335,8 +337,41 @@ class parametrized
}
}
/* DIMENSION OF THE INPUT AND OUTPUT DOMAIN */
//! Provide the dimension of the input space of the function
virtual int dimX() const { return _nX ; }
//! Provide the dimension of the output space of the function
virtual int dimY() const { return _nY ; }
//! Set the dimension of the input space of the function
virtual void setDimX(int nX) { _nX = nX ; }
//! Set the dimension of the output space of the function
virtual void setDimY(int nY) { _nY = nY ; }
/* DEFINITION DOMAIN OF THE FUNCTION */
//! \brief Set the minimum value the input can take
virtual void setMin(const vec& min) ;
//! \brief Set the maximum value the input can take
virtual void setMax(const vec& max) ;
//! \brief Get the minimum value the input can take
virtual vec min() const ;
//! \brief Get the maximum value the input can take
virtual vec max() const ;
protected:
// Input and output parametrization
params::input _in_param ;
params::output _out_param ;
// Dimension of the function & domain of definition.
int _nX, _nY ;
vec _min, _max ;
};
......@@ -328,8 +328,8 @@ rational_function_1d* rational_function::get(int i)
// Test if the input domain is not empty. If one dimension of
// the input domain is a point, I manually inflate this dimension
// to avoid numerical issues.
vec _min = getMin();
vec _max = getMax();
vec _min = min();
vec _max = max();
for(int k=0; k<dimX(); ++k)
{
if(_min[k] == _max[k])
......
......@@ -21,7 +21,7 @@ class rational_function_1d : public function
public: // methods
rational_function_1d() ;
rational_function_1d(int np, int nq, bool separable = true) ;
rational_function_1d(int np, int nq, bool separable = false) ;
rational_function_1d(const vec& a, const vec& b) ;
virtual ~rational_function_1d() {}
......
......@@ -235,13 +235,3 @@ int vertical_segment::size() const
{
return _data.size() ;
}
vec vertical_segment::min() const
{
return _min ;
}
vec vertical_segment::max() const
{
return _max ;
}
......@@ -57,19 +57,10 @@ class vertical_segment : public data
// Get data size
virtual int size() const ;
// Get min and max input parameters
virtual vec min() const ;
virtual vec max() const ;
private: // data
// Store for each point of data, the upper
// and lower value
std::vector<vec> _data ;
// Store the min and max value on the input
// domain
vec _min, _max ;
} ;
#include "data.h"
#include <cstdio>
#include <cstdlib>
#include <cmath>
data_interpolant::data_interpolant()
{
_kdtree = new flann::Index< flann::L2<double> >(flann::KDTreeIndexParams(4));
_knn = 10;
}
data_interpolant::~data_interpolant()
{
delete _data;
delete _kdtree;
}
// Load data from a file
void data_interpolant::load(const std::string& filename)
{
// Load the data
_data->load(filename);
// Copy the informations
setDimX(_data->dimX());
setDimY(_data->dimY());
setMin(_data->min());
setMax(_data->max());
// Update the KDtreee by inserting all points
for(int i=0; i<_data->size(); ++i)
{
vec x = _data->get(i);
flann::Matrix<double> pts(&x[0], dimX(), 1);
_kdtree->addPoints(pts);
}
_kdtree->buildIndex();
}
void data_interpolant::load(const std::string& filename, const arguments&)
{
load(filename);
}
void data_interpolant::save(const std::string& filename) const
{
}
// Acces to data
vec data_interpolant::get(int id) const
{
vec res(dimX() + dimY()) ;
return res ;
}
vec data_interpolant::operator[](int i) const
{
return get(i) ;
}
//! \todo Test this function
void data_interpolant::set(vec x)
{
assert(x.size() == dimX());
}
vec data_interpolant::value(vec, vec) const
{
vec res(dimY());
std::cerr << "<<ERROR>> Deprecated function: " << __func__ << std::endl;
return res;
}
vec data_interpolant::value(vec x) const
{
vec res = vec::Zero(dimY());
// Query point
flann::Matrix<double> pts(&x[0], dimX(), 1);
std::vector< std::vector<int> > indices;
std::vector< std::vector<double> > dists;
_kdtree->knnSearch(pts, indices, dists, _knn, flann::SearchParams());
// Interpolate the value using the indices
double cum_dist = 0.0;
for(int i=0; i<indices[0].size(); ++i)
{
int indice = indices[0][i];
vec y = _data->get(indice);
for(int j=0; j<dimY(); ++j)
{
res[j] += dists[0][i] * y[dimX() + j];
}
cum_dist += dists[0][i];
}
for(int j=0; j<dimY(); ++j)
{
res[j] /= cum_dist;
}
return res;
}
// Get data size, e.g. the number of samples to fit
int data_interpolant::size() const
{
return _data->size();
}
ALTA_DLL_EXPORT data* provide_data()
{
return new data_interpolant();
}
#pragma once
#include <core/data.h>
#include <core/common.h>
#include <core/args.h>
#include <flann/flann.hpp>
/*! \brief Load a data file, but provide access to an interpolated version of
* the data points.
*
* <h2>Requirements:</h2>
* The FLANN library.
* On linux plateforms it can be obtained using the package manager:
* \verbatim
* sudo apt-get install libflann-dev
* \endverbatim
*/
class data_interpolant : public data
{
public: // methods
data_interpolant();
~data_interpolant();
// Load data from a file
virtual void load(const std::string& filename) ;
virtual void load(const std::string& filename, const arguments& args) ;
virtual void save(const std::string& filename) const ;
// Acces to data
virtual vec get(int i) const ;
virtual vec operator[](int i) const ;
virtual vec value(vec in, vec out) const;
virtual vec value(vec x) const;
// Set data
virtual void set(vec x);
// Get data size, e.g. the number of samples to fit
virtual int size() const ;
private: // data
// The data object used to load sparse points sets
data* _data;
// Interpolation
flann::Index< flann::L2<double> >* _kdtree;
flann::Matrix<double>* _points;
int _knn;
} ;
TEMPLATE = lib
CONFIG *= plugin \
eigen
DESTDIR = ../../build
INCLUDEPATH += ../..
HEADERS = data.h
SOURCES = data.cpp
LIBS += -L../../build \
-lcore
......@@ -3,5 +3,5 @@ env.Append(CPPPATH = ['../../../external/build/include', '../../'])
env.Append(LIBPATH = ['../../../external/build/lib', '../../build'])
sources = ['fitter.cpp']
libs = ['-lceres', '-lcore']
libs = ['-lceres', '-lglog', '-lgomp', '-lcore']
env.SharedLibrary('../../build/nonlinear_fitter_ceres', sources, LIBS=libs)
......@@ -28,5 +28,6 @@ SUBDIRS = \
nonlinear_function_isotropic_lafortune \
data_merl \
data_brdf_slice \
data_interpolant \
# data_astm
......@@ -99,8 +99,8 @@ rational_function_1d* rational_function_chebychev::get(int i)
// Test if the input domain is not empty. If one dimension of
// the input domain is a point, I manually inflate this dimension
// to avoid numerical issues.
vec _min = getMin();
vec _max = getMax();
vec _min = min();
vec _max = max();
for(int k=0; k<dimX(); ++k)
{
if(_min[k] == _max[k])
......
......@@ -54,8 +54,8 @@ class rational_function_legendre : public rational_function
// Test if the input domain is not empty. If one dimension of
// the input domain is a point, I manually inflate this dimension
// to avoid numerical issues.
vec _min = getMin();
vec _max = getMax();
vec _min = min();
vec _max = max();
for(int k=0; k<dimX(); ++k)
{
if(_min[k] == _max[k])
......
......@@ -15,189 +15,277 @@
int main(int argc, char** argv)
{
arguments args(argc, argv) ;
if(args.is_defined("help")) {
std::cout << "<<HELP>> data2moments --input data.file --output gnuplot.file --data loader.so" << std::endl ;
std::cout << " - input, output and data are mandatory parameters" << std::endl ;
return 0 ;
}
if(! args.is_defined("input")) {
std::cerr << "<<ERROR>> the input filename is not defined" << std::endl ;
return 1 ;
}
if(! args.is_defined("output")) {
std::cerr << "<<ERROR>> the output filename is not defined" << std::endl ;
return 1 ;
}
if(! args.is_defined("data")) {
std::cerr << "<<ERROR>> the data loader is not defined" << std::endl ;
return 1 ;
}
// Import data
data* d = NULL ;
d = plugins_manager::get_data(args["data"]) ;
d->load(args["input"]);
// Create output file
std::ofstream file(args["output"].c_str(), std::ios_base::trunc);
if(d != NULL)
{
// Data parametrization
params::input data_param = d->parametrization();
const int nX = d->dimX();
const int nY = d->dimY();
// Options
bool with_cosine = args.is_defined("cosine");
bool use_angular = args.is_defined("angular-moments");
// Normalisation factor for the integration
const int nb_theta_int = 90;
const int nb_phi_int = (use_angular) ? 2 : 360;
const double normalization = ((use_angular) ? M_PI : M_PI*M_PI) / (double)(nb_phi_int*nb_theta_int);
double in_angle[4] = {0.0, 0.0, 0.0, 0.0} ;
// Raw moments
vec m_0(nY);
vec m_x(nY);
vec m_y(nY);
vec m_xx(nY);
vec m_xy(nY);
vec m_yy(nY);
// Cumulants
vec k_x(nY);
vec k_y(nY);
vec k_xx(nY);
vec k_xy(nY);
vec k_yy(nY);
// The X and Y directions to compute the moments. This is an argument of the command
// line. The different directions can be: using stereographic coordinates, using the
// theta of the classical parametrization (the second coordinate is then 0).
vec xy(2);
for(int theta_in=0; theta_in<90; theta_in++)
{
in_angle[0] = theta_in * 0.5*M_PI / 90.0;
m_0 = vec::Zero(nY);
m_x = vec::Zero(nY);
m_y = vec::Zero(nY);
m_xx = vec::Zero(nY);
m_xy = vec::Zero(nY);
m_yy = vec::Zero(nY);
// Theta angle in [0 .. PI / 2]
for(int theta_out=0; theta_out<nb_theta_int; theta_out++)
{
in_angle[2] = theta_out * 0.5*M_PI / (double)nb_theta_int;
// Azimutal angle in [-PI .. PI]
for(int phi_out=0; phi_out<nb_phi_int; phi_out++)
{
in_angle[3] = phi_out * 2.0*M_PI / (double)nb_phi_int - M_PI;
vec in(nX), stereographics(4);
params::convert(in_angle, params::SPHERICAL_TL_PL_TV_PV, data_param, &in[0]);
if(use_angular)
{
xy[0] = (std::abs(in_angle[3]) < 0.5*M_PI) ? in_angle[2] : -in_angle[2];
xy[1] = 0.0;
}
else
{
params::convert(in_angle, params::SPHERICAL_TL_PL_TV_PV, params::STEREOGRAPHIC, &stereographics[0]);
xy[0] = stereographics[2];
xy[1] = stereographics[3];
}
// Copy the input vector
vec x = d->value(in);
for(int i=0; i<nY; ++i)
{
double val = x[i] * normalization;
if(!use_angular) {
val *= sin(in_angle[2]);
}
if(with_cosine)
{
val *= cos(in_angle[2]);
}
m_0[i] += val ;
m_x[i] += val * xy[0];
m_y[i] += val * xy[1];
m_xx[i] += val * xy[0] * xy[0];