Commit 52ad5d49 authored by pacanows's avatar pacanows
Browse files

Merge

parents b5091114 776d1577
......@@ -22,22 +22,24 @@ class data : public parametrized
virtual void load(const std::string& filename) = 0 ;
virtual void load(const std::string& filename, const arguments& args) = 0 ;
// Save the data to a file
virtual void save(const std::string& filename) const
{
std::ofstream file(filename.c_str(), std::ios_base::trunc);
file << "#DIM " << _nX << " " << _nY << std::endl;
for(int i=0; i<size(); ++i)
{
vec x = this->get(i);
for(int j=0; j<_nX+_nY; ++j)
{
file << x[j] << "\t";
}
file << std::endl;
}
file.close();
}
// Save the data to a file
virtual void save(const std::string& filename) const
{
std::ofstream file(filename.c_str(), std::ios_base::trunc);
file << "#DIM " << _nX << " " << _nY << std::endl;
file << "PARAM_IN " << params::get_name(input_parametrization()) << std::endl;
file << "PARAM_OUT " << params::get_name(output_parametrization()) << std::endl;
for(int i=0; i<size(); ++i)
{
vec x = this->get(i);
for(int j=0; j<_nX+_nY; ++j)
{
file << x[j] << "\t";
}
file << std::endl;
}
file.close();
}
// Acces to data
virtual vec get(int i) const = 0 ;
......
......@@ -430,6 +430,7 @@ bool compound_function::load(std::istream& in)
nb_good++;
}
}
std::cout << "<<DEBUG>> number of correct function loaded in compound: " << nb_good << " / " << fs.size() << std::endl;
return nb_good > 0;
}
......
......@@ -354,3 +354,52 @@ class product_function : public nonlinear_function
nonlinear_function *f1, *f2;
};
class cosine_function : public nonlinear_function
{
public:
// Set the input parametrization to CARTESIAN to reduce the number
// of transformations in a compound object.
cosine_function()
{
setParametrization(params::CARTESIAN);
setDimX(6);
}
// Overload the function operator
virtual vec operator()(const vec& x) const
{
return value(x);
}
virtual vec value(const vec& x) const
{
vec res(dimY());
for(int i=0; i<dimY(); ++i) { res[i] = ((x[2] > 0.0) ? x[2] : 0.0) * ((x[5] > 0.0) ? x[5] : 0.0); }
return res;
}
//! \brief Number of parameters to this non-linear function
virtual int nbParameters() const
{
return 0;
}
//! Get the vector of parameters for the function
vec parameters() const
{
vec res(1);
return res;
}
//! Update the vector of parameters for the function
void setParameters(const vec&)
{
}
//! Obtain the derivatives of the function with respect to the
//! parameters.
vec parametersJacobian(const vec&) const
{
vec jac(1);
return jac;
}
};
......@@ -24,6 +24,7 @@ std::map<params::input, const param_info> create_map()
/* 2D Params */
_map.insert(std::make_pair<params::input, const param_info>(params::RUSIN_TH_TD, param_info("RUSIN_TH_TD", 2, "Radialy symmetric Half angle parametrization")));
_map.insert(std::make_pair<params::input, const param_info>(params::ISOTROPIC_TV_PROJ_DPHI, param_info("ISOTROPIC_TV_PROJ_DPHI", 2, "Isoptropic projected phi parametrization without a light direction.")));
_map.insert(std::make_pair<params::input, const param_info>(params::RETRO_TL_TVL_PROJ_DPHI, param_info("RETRO_TVL_PROJ_DPHI", 2, "Isoptropic projected phi parametrization around the retro direction.")));
/* 3D Params */
_map.insert(std::make_pair<params::input, const param_info>(params::RUSIN_TH_TD_PD, param_info("RUSIN_TH_TD_PD", 3, "Isotropic Half angle parametrization")));
......@@ -31,6 +32,7 @@ std::map<params::input, const param_info> create_map()
_map.insert(std::make_pair<params::input, const param_info>(params::RUSIN_VH, param_info("RUSIN_VH", 3, "Vector representation of the Half angle only")));
_map.insert(std::make_pair<params::input, const param_info>(params::SCHLICK_VK, param_info("SCHLICK_VH", 3, "Vector representation of the Back angle only")));
_map.insert(std::make_pair<params::input, const param_info>(params::ISOTROPIC_TL_TV_PROJ_DPHI, param_info("ISOTROPIC_TL_TV_PROJ_DPHI", 3, "Isoptropic projected phi parametrization.")));
_map.insert(std::make_pair<params::input, const param_info>(params::SCHLICK_TL_TK_PROJ_DPHI, param_info("SCHLICK_TL_TK_PROJ_DPHI", 3, "Isoptropic projected phi parametrization centered around the back vector.")));
/* 4D Params */
_map.insert(std::make_pair<params::input, const param_info>(params::RUSIN_TH_PH_TD_PD, param_info("RUSIN_TH_PH_TD_PD", 4, "Complete Half angle parametrization")));
......@@ -170,6 +172,28 @@ void params::to_cartesian(const double* invec, params::input intype,
outvec[3] = sin(invec[0]);
outvec[4] = 0.0;
outvec[5] = cos(invec[0]);
}
break;
case SCHLICK_TL_TK_PROJ_DPHI:
NOT_IMPLEMENTED();
break;
case RETRO_TL_TVL_PROJ_DPHI:
{
const double theta = std::fabs(sqrt(invec[1]*invec[1] + invec[2]*invec[2]) - invec[0]);
if(theta > 0.0)
{
outvec[0] = (invec[1]/theta)*sin(theta);
outvec[1] = (invec[2]/theta)*sin(theta);
}
else
{
outvec[0] = 0.0;
outvec[1] = 0.0;
}
outvec[2] = cos(theta);
outvec[3] = sin(invec[0]);
outvec[4] = 0.0;
outvec[5] = cos(invec[0]);
}
break;
......@@ -334,6 +358,19 @@ void params::from_cartesian(const double* invec, params::input outtype,
outvec[0] = theta_l;
outvec[1] = theta_v * cos(dphi);
outvec[2] = theta_v * sin(dphi);
}
break;
case SCHLICK_TL_TK_PROJ_DPHI:
{
const double vkx = invec[0]-invec[3];
const double vky = invec[1]-invec[4];
const double vkz = invec[2]+invec[5];
const double norm = sqrt(vkx*vkx + vky*vky + vkz*vkz);
const double theta_k = acos(vkz / norm);
const double dphi = atan2(invec[4], invec[3]) - atan2(vky/norm, vkx/norm);
outvec[0] = acos(invec[5]);
outvec[1] = theta_k * cos(dphi);
outvec[2] = theta_k * sin(dphi);
}
break;
......@@ -397,7 +434,7 @@ params::input params::parse_input(const std::string& txt)
{
if(txt.compare(it->second.name) == 0)
{
std::cout << "<<INFO>> parsed input parametrization " << it->second.name << std::endl;
std::cout << "<<INFO>> parsed input parametrization " << it->second.name << " from name \"" << txt << "\"" << std::endl;
return it->first;
}
}
......@@ -405,6 +442,34 @@ params::input params::parse_input(const std::string& txt)
std::cout << "<<INFO>> the input parametrization is UNKNOWN_INPUT" << std::endl;
return params::UNKNOWN_INPUT;
}
params::output params::parse_output(const std::string& txt)
{
if(txt == std::string("ENERGY"))
{
return params::ENERGY;
}
else if(txt == std::string("INV_STERADIAN"))
{
return params::INV_STERADIAN;
}
else if(txt == std::string("INV_STERADIAN_COSINE_FACTOR"))
{
return params::INV_STERADIAN_COSINE_FACTOR;
}
else if(txt == std::string("RGB_COLOR"))
{
return params::RGB_COLOR;
}
else if(txt == std::string("XYZ_COLOR"))
{
return params::XYZ_COLOR;
}
else
{
return params::UNKNOWN_OUTPUT;
}
}
std::string params::get_name(const params::input param)
{
......
......@@ -52,10 +52,20 @@ class params
SCHLICK_TK_PK, /*!< Schlick's back vector parametrization */
SCHLICK_VK, /*!< Schlick's back vector */
SCHLICK_TL_TK_PROJ_DPHI,/*!< 3D Parametrization where the phi component is projected and
the parametrization is centered around the back direction.
\f$[\theta_L, x, y] = [\theta_L, \theta_K \cos(\phi_K), \theta_K \sin(\phi_K)]\f$*/
COS_TK, /*!< Schlick's back vector dot product with the normal */
RETRO_TL_TVL_PROJ_DPHI,/*!< 2D Parametrization where the phi component is projected and
the parametrization is centered around the retro direction
\f$[x, y] = [\theta_{VL} \cos(\Delta\phi), \theta_{VL}
\sin(\Delta\phi)]\f$.*/
STEREOGRAPHIC, /*!< Stereographic projection of the Light and View vectors */
SPHERICAL_TL_PL_TV_PV, /*!< Light and View vectors represented in spherical coordinates */
COS_TLV, /*!< Dot product between the Light and View vector */
COS_TLR, /*!< Dot product between the Light and Reflected vector */
......@@ -70,7 +80,7 @@ class params
\theta_v \sin(\Delta\phi).\f$]*/
ISOTROPIC_TD_PD, /*!< Difference between two directions such as R and H */
BARYCENTRIC_ALPHA_SIGMA, /*!< Barycentric parametrization defined in Stark et alL [2004].
BARYCENTRIC_ALPHA_SIGMA, /*!< Barycentric parametrization defined in Stark et al. [2004].
Coordinates are: \f$[\alpha, \sigma] = [{1\over 2}(1 - \vec{l}\vec{v}),
(1-(\vec{h}.\vec{n})^2)(1 - \alpha)]\f$ */
......@@ -102,22 +112,21 @@ class params
//! \brief parse a string to provide a parametrization type.
static params::input parse_input(const std::string& txt);
//! \brief parse a string to provide a parametrization type.
static params::output parse_output(const std::string& txt);
//! \brief look for the string associated with a parametrization
//! type.
static std::string get_name(const params::input param);
//! \brief parse a string to provide a parametrization type.
static params::output parse_output(const std::string& txt)
{
if(txt == std::string("ENERGY"))
{
return params::ENERGY;
}
else
{
return params::UNKNOWN_OUTPUT;
}
}
//! \brief look for the string associated with a parametrization
//! type.
//! \todo Finish this implementation. It requires another static
//! object.
static std::string get_name(const params::output param)
{
return std::string("UNKNOWN_OUTPUT");
}
//! \brief static function for input type convertion. This
//! function allocate the resulting vector.
......@@ -215,6 +224,25 @@ class params
}
}
//! \brief Is the value stored weighted by a cosine factor
static bool is_cosine_weighted(params::output t)
{
switch(t)
{
case params::INV_STERADIAN_COSINE_FACTOR:
return true;
break;
case params::INV_STERADIAN:
case params::ENERGY:
case params::RGB_COLOR:
case params::XYZ_COLOR:
default:
return false;
break;
}
}
//! \brief from the 4D definition of a half vector parametrization,
//! export the cartesian coordinates.
static void half_to_cartesian(double theta_h, double phi_h,
......
......@@ -374,7 +374,15 @@ function* plugins_manager::get_function(const arguments& args)
}
}
/*
// Correction of the data by 1/cosine(theta_L)
if(args.is_defined("data-correct-cosine"))
{
nonlinear_function* cosine = new cosine_function();
func = new product_function(cosine, dynamic_cast<nonlinear_function*>(func));
}
// End of correction
*/
return func;
}
data* plugins_manager::get_data(const std::string& n)
......
......@@ -98,15 +98,24 @@ void vertical_segment::load(const std::string& filename, const arguments& args)
linestream >> v[i] ;
// /*
// Correction of the data by 1/cosine(theta_L)
double factor = 1.0;
if(args.is_defined("data-correct-cosine"))
{
double cart[6];
params::convert(&v[0], input_parametrization(), params::CARTESIAN, cart);
factor = 1.0/cart[5];
if(cart[5] > 0.0 && cart[2] > 0.0)
{
factor = 1.0/cart[5]*cart[2];
}
else
{
continue;
}
}
// End of correction
// */
for(int i=0; i<dimY(); ++i)
{
......@@ -179,6 +188,9 @@ void vertical_segment::load(const std::string& filename, const arguments& args)
}
}
}
if(args.is_defined("data-correct-cosine"))
save("/tmp/data-corrected.dat");
std::cout << "<<INFO>> loaded file \"" << filename << "\"" << std::endl ;
std::cout << "<<INFO>> data inside " << _min << " ... " << _max << std::endl ;
......
......@@ -29,7 +29,14 @@ vec abc_function::value(const vec& x) const
for(int i=0; i<dimY(); ++i)
{
res[i] = _a[i] / pow(1.0 + _b[i]*hn, _c[i]);
if(hn > 0.0 && hn < 1.0)
{
res[i] = _a[i] / pow(1.0 + _b[i]*hn, _c[i]);
}
else
{
res[i] = 0.0;
}
}
return res;
}
......
......@@ -160,17 +160,42 @@ vec diffuse_function::parametersJacobian(const vec& x) const
void diffuse_function::bootstrap(const data* d, const arguments& args)
{
{/*
// Set the diffuse component
vec x0 = d->get(0);
for(int i=0; i<d->dimY(); ++i)
_kd[i] = x0[d->dimX() + i];
if(params::is_cosine_weighted(d->output_parametrization()))
{
vec cart(6);
for(int i=0; i<d->dimY(); ++i)
_kd[i] = std::numeric_limits<double>::max();
for(int i=1; i<d->size(); ++i)
for(int i=1; i<d->size(); ++i)
{
vec x = d->get(i);
params::convert(&x[0], d->input_parametrization(), params::CARTESIAN, &cart[0]);
double cosine = (cart[2] > 0.0 ? cart[2] : 0.0) * (cart[5] > 0.0 ? cart[5] : 0.0);
if(cosine > 0.0)
{
for(int j=0; j<d->dimY(); ++j)
{
_kd[j] = std::min(x[d->dimX() + j] / cosine, _kd[j]);
}
}
}
}
else
*/
{
vec xi = d->get(i);
for(int j=0; j<d->dimY(); ++j)
_kd[j] = std::min(xi[d->dimX() + j], _kd[j]);
for(int i=0; i<d->dimY(); ++i)
_kd[i] = std::numeric_limits<double>::max();
for(int i=0; i<d->size(); ++i)
{
vec xi = d->get(i);
for(int j=0; j<d->dimY(); ++j)
_kd[j] = std::min(xi[d->dimX() + j], _kd[j]);
}
}
std::cout << "<<INFO>> found diffuse: " << _kd << std::endl;
......
......@@ -32,6 +32,7 @@
#include <core/function.h>
#include <core/fitter.h>
#include <core/plugins_manager.h>
#include <core/vertical_segment.h>
#include <iostream>
#include <vector>
......@@ -46,10 +47,30 @@ int main(int argc, char** argv)
arguments args(argc, argv) ;
if(args.is_defined("help")) {
std::cout << "<<HELP>> data2data --input data.file --output data.file --out-data exporter.so --in-data importer.so" << std::endl ;
std::cout << " - input, output, out-data are mandatory parameters" << std::endl ;
std::cout << "Usage: data2data [options] --input data.file --output data.file" << std::endl ;
std::cout << "Convert a data object to another data object."<< std::endl ;
std::cout << std::endl;
std::cout << "Mandatory arguments:" << std::endl;
std::cout << " --input [filename]" << std::endl;
std::cout << " --output [filename]" << std::endl;
std::cout << std::endl;
std::cout << "Optional arguments:" << std::endl;
std::cout << " --out-data [filename] Name of the plugin used to save the outputed data file" << std::endl ;
std::cout << " If none is provided, the exporter will export in ALTA" << std::endl ;
std::cout << " by default." << std::endl ;
std::cout << " --in-data [filename] Name of the plugin used to load the input data file" << std::endl ;
std::cout << " If none is provided, the exporter will export in ALTA" << std::endl ;
std::cout << " by default." << std::endl ;
std::cout << " --param [NAME] Name of the parametrization used to output data when" << std::endl;
std::cout << " No output data plugin is specified. Please see " << std::endl;
std::cout << " --help-params for the list of available " << std::endl ;
std::cout << " parametrizations." << std::endl ;
return 0 ;
}
if(args.is_defined("help-params")) {
params::print_input_params();
return 0;
}
if(! args.is_defined("input")) {
std::cerr << "<<ERROR>> the input filename is not defined" << std::endl ;
......@@ -70,25 +91,61 @@ int main(int argc, char** argv)
// Import data
data* d_in = NULL ;
d_in = plugins_manager::get_data(args["in-data"]) ;
d_in->load(args["input"]);
d_in->load(args["input"], args);
data* d_out = NULL;
d_out = plugins_manager::get_data(args["out-data"]) ;
if(d_out->dimY() != d_in->dimY())
if(d_in == NULL && d_out == NULL)
{
std::cerr << "<<ERROR>> data types have incompatible output dimensions" << std::endl;
std::cerr << "<<ERROR>> cannot import or export data" << std::endl ;
return 1;
}
if(d_in != NULL && d_out != NULL)
if(dynamic_cast<vertical_segment*>(d_out) != NULL)
{
params::input param = params::parse_input(args["param"]);
if(param == params::UNKNOWN_INPUT)
{
std::cerr << "<<ERROR>> unable to parse the parametrization" << std::endl;
return -1;
}
d_out->setParametrization(param);
d_out->setDimX(params::dimension(param));
d_out->setDimY(d_in->dimY());
std::cout << "<<INFO>> output DIM = " << d_out->dimX() << ", " << d_out->dimY() << std::endl;
vec temp(d_out->dimX() + d_out->dimY());
for(int i=0; i<d_in->size(); ++i)
{
// Copy the input vector
vec x = d_in->get(i);
params::convert(&x[0], d_in->parametrization(), d_out->parametrization(), &temp[0]);
for(int j=0; j<d_in->dimY(); ++j)
{
temp[d_out->dimX() + j] = x[d_in->dimX() + j];
}
d_out->set(temp);
}
}
else
{
if(d_out->dimY() != d_in->dimY())
{
std::cerr << "<<ERROR>> data types have incompatible output dimensions" << std::endl;
}
vec temp(d_in->dimX());
for(int i=0; i<d_out->size(); ++i)
{
// Copy the input vector
vec x = d_out->get(i);
params::convert(&x[0], d_out->parametrization(), d_in->parametrization(), &temp[0]);
vec y = d_in->value(temp);
for(int j=0; j<d_in->dimY(); ++j)
......@@ -98,14 +155,7 @@ int main(int argc, char** argv)
d_out->set(x);
}
d_out->save(args["output"]);
return 0 ;
}
else
{
std::cerr << "<<ERROR>> cannot import or export data" << std::endl ;
return 1;
}
d_out->save(args["output"]);
return 0 ;
}
......@@ -35,8 +35,22 @@ int main(int argc, char** argv)
arguments args(argc, argv) ;
if(args.is_defined("help")) {
std::cout << "Usage: data2moments --input data.file --output gnuplot.file --data loader.so" << std::endl ;
std::cout << " -> input, output and data are mandatory parameters" << std::endl ;
std::cout << "Usage: data2moments [options] --input data.file --output gnuplot.file" << std::endl ;
std::cout << "Compute the statistical moments, up to order 4, on the data file" << std::endl ;
std::cout << std::endl;
std::cout << "Mandatory arguments:" << std::endl;
std::cout << " --input [filename]" << std::endl;
std::cout << " --output [filename]" << std::endl;
std::cout << " --data [filename] You must provide a data loader that provides" << std::endl;
std::cout << " interpolation mechanism." << std::endl;
std::cout << std::endl;
std::cout << "Optional arguments:" << std::endl;
std::cout << " --samples [int, int, ...] Number of samples per dimension used to compute" << std::endl;
std::cout << " the moments. This vector must have the same" << std::endl;
std::cout << " size as the number of dimensions of the input" << std::endl;
std::cout << " space." << std::endl;
std::cout << " --dim [int, int] Indices of the two dimensions used to evaluate" << std::endl;
std::cout << " the moments." << std::endl;
return 0 ;
}
......@@ -107,21 +121,36 @@ int main(int argc, char** argv)
vec k_yyyy(nY);
#ifndef OLD
// Number of elements per dimension
std::vector<int> dim;
if(args.is_defined("dim"))
// Number of elements per samplesension
std::vector<int> samples;
if(args.is_defined("samples"))
{
dim = args.get_vec<int>("dim");
assert(dim.size() == nX);
samples = args.get_vec<int>("samples");
assert(samples.size() == nX);
}
else
{
for(int i=0; i<nX; ++i)
{
dim.push_back(100);
samples.push_back(100);
}
}
std::vector<int> dim;
if(