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

Reformating of rational function done, now I need to update all

the plugin to the according format.
parent be73d84a
......@@ -288,7 +288,7 @@ class parametrized
{
return;
}
else if(_out_param == params::UNKNOWN_INPUT)
else if(_out_param == params::UNKNOWN_OUTPUT)
{
_out_param = new_param;
}
......
......@@ -8,7 +8,7 @@
#include <algorithm>
#include <cmath>
#ifdef NEW
#ifndef NEW
rational_function_1d::rational_function_1d()
{
}
......@@ -296,6 +296,461 @@ std::ostream& operator<< (std::ostream& out, const rational_function_1d& r)
return out ;
}
rational_function::rational_function() : np(0), nq(0)
{
}
rational_function::rational_function(int np, int nq) : np(np), nq(nq)
{
}
//! \todo clean memory here
rational_function::~rational_function()
{
}
void rational_function::update(int i, rational_function_1d* r)
{
rs[i] = r;
}
rational_function_1d* rational_function::get(int i)
{
// Check for consistency in the index of color channel
if(i < _nY)
{
if(rs[i] == NULL)
{
rs[i] = new rational_function_1d(np, nq);
rs[i]->setDimX(dimX());
rs[i]->setDimY(dimY());
rs[i]->setMin(getMin()) ;
rs[i]->setMax(getMax()) ;
}
return rs[i];
}
else
{
std::cout << "<<ERROR>> tried to access out of bound 1D RF" << std::endl;
return NULL;
}
}
rational_function_1d* rational_function::get(int i) const
{
// Check for consistency in the index of color channel
if(i < _nY)
{
return rs[i];
}
else
{
std::cout << "<<ERROR>> tried to access out of bound 1D RF" << std::endl;
return NULL;
}
}
// Overload the function operator
vec rational_function::value(const vec& x) const
{
vec res(_nY) ;
for(int k=0; k<_nY; ++k)
{
res[k] = rs[k]->value(x)[0] ;
}
return res ;
}
// IO function to text files
void rational_function::load(const std::string& filename)
{
std::ifstream file(filename.c_str()) ;
if(!file.is_open())
{
std::cerr << "<<ERROR>> unable to open file \"" << filename << "\"" << std::endl ;
throw ;
}
int nX, nY ;
vec xmin, xmax ;
int i = 0, j = 0;
while(file.good())
{
std::string line ;
std::getline(file, line) ;
std::stringstream linestream(line) ;
// Discard incorrect lines
if(linestream.peek() == '#')
{
linestream.ignore(1) ;
std::string comment ;
linestream >> comment ;
if(comment == std::string("DIM"))
{
linestream >> nX >> nY ;
setDimX(nX) ;
setDimY(nY) ;
xmin.resize(nX) ;
xmax.resize(nX) ;
for(int k=0; k<nX; ++k)
xmax[k] = 1.0;
setMin(xmin) ;
setMax(xmax) ;
}
else if(comment == std::string("NP"))
{
linestream >> np ;
//a.resize(np*nY);
}
else if(comment == std::string("NQ"))
{
linestream >> nq ;
//b.resize(nq*nY);
}
else if(comment == std::string("INPUT_PARAM"))
{
std::string param;
linestream >> param ;
setParametrization(params::parse_input(param));
}
continue ;
}
else if(line.empty())
{
continue ;
}
else if(j < nY)
{
int index ; double val ;
// Accessing the index
for(int k=0; k<nX; ++k) {
linestream >> index ;
}
// Accessing the value
linestream >> val ;
/*! \todo
if(i < np)
{
a[i + np*j] = val ;
}
else
{
b[i-np + nq*j] = val ;
}
if(i < np+nq) {
++i ;
} else {
i = 0 ;
++j ;
}
*/
}
}
/*
for(int i=0; i<a.size(); ++i) {
std::cout << a[i] << "\t" ;
}
for(int i=0; i<b.size(); ++i) {
std::cout << b[i] << "\t" ;
}
*/
}
//! \todo it should handle parametrization
void rational_function::save_matlab(const std::string& filename, const arguments& args) const
{
std::ofstream file(filename.c_str(), std::ios_base::trunc);
file << "function y = brdf(x)" << std::endl;
file << std::endl;
file << "\ts = [";
for(int i=0; i<dimX(); ++i)
{
file << 1.0 / (_max[i]-_min[i]);
if(i < dimX()-1)
{
file << ", ";
}
}
file << "];" << std::endl;
file << "\tc = [";
for(int i=0; i<dimX(); ++i)
{
file << _min[i];
if(i < dimX()-1)
{
file << ", ";
}
}
file << "];" << std::endl;
file << std::endl ;
// Export each color channel independantly
for(int j=0; j<dimY(); ++j)
{
// Export the numerator of the jth color channel
file << "\tp(" << j+1 << ",:) = ";
for(unsigned int i=0; i<np; ++i)
{
/*! \todo
if(i > 0 && a[np*j + i] >= 0.0)
file << " + ";
else if(a[np*j + i] < 0.0)
file << " " ;
file << a[np*j + i];
std::vector<int> degree = index2degree(i);
for(unsigned int k=0; k<degree.size(); ++k)
{
file << ".*legendrepoly(" << degree[k] << ", 2.0*((x(" << k+1 << ",:)"
<< "-c(" << k+1 << "))*s(" << k+1 << ") - 0.5))" ;
}
*/
}
file << ";" << std::endl;
// Export the denominator of the jth color channel
file << "\tq(" << j+1 << ",:) = ";
for(unsigned int i=0; i<nq; ++i)
{
/*! \todo
if(i > 0 && b[np*j + i] >= 0.0)
file << " + ";
else if(b[np*j + i] < 0.0)
file << " " ;
file << b[np*j + i] ;
std::vector<int> degree = index2degree(i);
for(unsigned int k=0; k<degree.size(); ++k)
{
file << ".*legendrepoly(" << degree[k] << ", 2.0*((x(" << k+1 << ",:)"
<< "-c(" << k+1 << "))*s(" << k+1 << ") - 0.5))" ;
}
*/
}
file << ";" << std::endl;
file << "\ty(" << j+1 << ",:) = p./q;" << std::endl;
if(j < dimY()-1)
{
file << std::endl;
}
}
file << "endfunction" << std::endl;
file.close() ;
}
//! \todo it should handle parametrization
void rational_function::save_cpp(const std::string& filename, const arguments& args) const
{
std::ofstream file(filename.c_str(), std::ios_base::trunc);
file << "double s[" << dimX() << "] = {";
for(int i=0; i<dimX(); ++i)
{
file << 1.0 / (_max[i]-_min[i]);
if(i < dimX()-1)
{
file << ", ";
}
}
file << "};" << std::endl;
file << "double c[" << dimX() << "] = {";
for(int i=0; i<dimX(); ++i)
{
file << _min[i];
if(i < dimX()-1)
{
file << ", ";
}
}
file << "};" << std::endl;
file << std::endl ;
file << "// The Legendre polynomial of order i evaluated in x" << std::endl;
file << "double l(double x, int i)" << std::endl;
file << "{" << std::endl;
file << " if(i == 0)" << std::endl;
file << " {" << std::endl;
file << " return 1;" << std::endl;
file << " }" << std::endl;
file << " else if(i == 1)" << std::endl;
file << " {" << std::endl;
file << " return x;" << std::endl;
file << " }" << std::endl;
file << " else" << std::endl;
file << " {" << std::endl;
file << " return ((2*i-1)*x*l(x, i-1) - (i-1)*l(x, i-2)) / (double)i ;" << std::endl;
file << " }" << std::endl;
file << "}" << std::endl;
file << std::endl;
file << "void brdf(double* x, double* y)" << std::endl;
file << "{" << std::endl;
file << "\tdouble p, q;" << std::endl;
// Export each color channel independantly
for(int j=0; j<dimY(); ++j)
{
// Export the numerator of the jth color channel
file << "\tp = ";
for(unsigned int i=0; i<np; ++i)
{
/*! \todo
if(i > 0 && a[np*j + i] >= 0.0)
{
file << " + ";
}
file << a[np*j + i];
std::vector<int> degree = index2degree(i);
for(unsigned int k=0; k<degree.size(); ++k)
{
file << "*l(2.0*((x[" << k << "]-c[" << k << "])*s[" << k << "] - 0.5), " << degree[k] << ")" ;
}
*/
}
file << ";" << std::endl;
// Export the denominator of the jth color channel
file << "\tq = ";
for(unsigned int i=0; i<nq; ++i)
{
/*! \todo
if(i > 0 && b[np*j + i] >= 0.0)
file << " + ";
else if(b[np*j + i] < 0.0)
file << " " ;
file << b[np*j + i] ;
std::vector<int> degree = index2degree(i);
for(unsigned int k=0; k<degree.size(); ++k)
{
file << "*l(2.0*((x[" << k << "]-c[" << k << "])*s[" << k << "] - 0.5), " << degree[k] << ")" ;
}
*/
}
file << ";" << std::endl;
file << "\ty[" << j << "] = p/q;" << std::endl;
if(j < dimY()-1)
{
file << std::endl;
}
}
file << "}" << std::endl;
file.close() ;
}
void rational_function::save_gnuplot(const std::string& filename, const data* d, const arguments& args) const
{
std::ofstream file(filename.c_str(), std::ios_base::trunc);
for(int i=0; i<d->size(); ++i)
{
vec v = d->get(i) ;
// vec y1 ; y1.assign(d->dimY(), 0.0) ;
// for(int k=0; k<d->dimY(); ++k) { y1[k] = v[d->dimX() + k] ; }
vec y2 = value(v) ;
for(int u=0; u<d->dimX(); ++u)
file << v[u] << "\t" ;
for(int u=0; u<d->dimY(); ++u)
file << y2[u] << "\t" ;
file << std::endl ;
}
file.close();
}
void rational_function::save(const std::string& filename) const
{
std::ofstream file(filename.c_str(), std::ios_base::trunc);
file << "#DIM " << _nX << " " << _nY << std::endl ;
file << "#NP " << np << std::endl ;
file << "#NQ " << nq << std::endl ;
file << "#BASIS LEGENDRE" << std::endl ;
file << "#INPUT_PARAM " << params::get_name(this->parametrization()) << std::endl;
for(int k=0; k<_nY; ++k)
{
/*
for(unsigned int i=0; i<np; ++i)
{
std::vector<int> index = index2degree(i) ;
for(unsigned int j=0; j<index.size(); ++j)
{
file << index[j] << "\t" ;
}
file << a[i+np*k] << std::endl ;
}
*/
/*
for(unsigned int i=0; i<nq; ++i)
{
std::vector<int> index = index2degree(i) ;
for(unsigned int j=0; j<index.size(); ++j)
{
file << index[j] << "\t" ;
}
file << b[i+nq*k] << std::endl ;
}
*/
}
}
std::ostream& operator<< (std::ostream& out, rational_function& r)
{
for(int i=0; i<r.dimY(); ++i)
{
rational_function_1d* rf = r.get(i);
out << "dimension " << i << ": ";
if(rf != NULL)
{
out << *rf << std::endl;
}
else
{
out << "[NULL]" << std::endl;
}
}
return out ;
}
#else
......
......@@ -15,7 +15,7 @@
//! \todo template this
#ifdef NEW
#ifndef NEW
class rational_function_1d : public function
{
public: // methods
......@@ -57,15 +57,16 @@ class rational_function_1d : public function
// STL stream ouput
friend std::ostream& operator<< (std::ostream& out, const rational_function_1d& r) ;
//! Convert a 1D index into a vector of degree for a
//! multinomial coeffcient. The resulting vector v should
//! be used as prod_k x[k]^v[k] for the monomial basis
std::vector<int> index2degree(int i) const ;
protected: // functions
//! Convert a 1D index into a vector of degree for a
//! multinomial coeffcient. The resulting vector v should
//! be used as prod_k x[k]^v[k] for the monomial basis
std::vector<int> index2degree(int i) const ;
static int estimate_dk(int k, int d);
static void populate(std::vector<int>& vec, int N, int M, int j);
static void populate(std::vector<int>& vec, int N, int M, int j);
protected: // data
......@@ -75,22 +76,20 @@ class rational_function_1d : public function
std::vector<double> a ;
std::vector<double> b ;
} ;
/*
// Prior definition for the standard output declaration
template<class RF1D> class rational_function_t ;
template<class RF1D> std::ostream& operator<< (std::ostream& out, rational_function_t<RF1D>& r) ;
*/
template<class RF1D> class rational_function_t : public QObject, public function
/*template<class RF1D>*/ class rational_function : public function
{
Q_OBJECT
Q_INTERFACES(function)
public: // methods
rational_function_t() ;
rational_function_t(int np, int nq) ;
rational_function_t(const std::vector<double>& a, const std::vector<double>& b) ;
virtual ~rational_function_t() ;
rational_function() ;
rational_function(int np, int nq) ;
rational_function(const std::vector<double>& a, const std::vector<double>& b) ;
virtual ~rational_function() ;
// Overload the function operator
virtual vec value(const vec& x) const ;
......@@ -100,14 +99,15 @@ template<class RF1D> class rational_function_t : public QObject, public function
virtual void load(const std::string& filename) ;
// Update the function
virtual void update(int i, RF1D* r) ;
virtual void update(int i, rational_function_1d* r) ;
//! Get the 1D function associated with color channel i. If no one exist, this
//! function allocates a new element. If i > nY, it returns NULL.
virtual RF1D* get(int i) ;
virtual rational_function_1d* get(int i) ;
virtual rational_function_1d* get(int i) const ;
// STL stream ouput
friend std::ostream& operator<< <> (std::ostream& out, rational_function_t<RF1D>& r) ;
friend std::ostream& operator<<(std::ostream& out, rational_function& r) ;
//! \brief Output the rational function as a gnuplot file. It requires
//! the data object to output the function at the input location only.
......@@ -136,7 +136,7 @@ template<class RF1D> class rational_function_t : public QObject, public function
// Store the y \in R rational functions. Each channel is a distinct polynomial
// and should be fitted separately.
std::vector<RF1D*> rs ;
std::vector<rational_function_1d*> rs ;
// Size of the polynomials
//! \todo Change it by a more adaptive scheme, with different np, nq per color
......@@ -145,15 +145,15 @@ template<class RF1D> class rational_function_t : public QObject, public function
} ;
#include "rational_function.inl"
/*
typedef rational_function_t<rational_function_1d> rational_function;
*/
#else
class rational_function : public QObject, public function
{
class rational_function : /*public QObject,*/ public function
{/*
Q_OBJECT
Q_INTERFACES(function)
*/
public: // methods
rational_function() ;
......
template <class RF1D>
rational_function_t<RF1D>::rational_function_t() : np(0), nq(0)
{
}
template <class RF1D>
rational_function_t<RF1D>::rational_function_t(int np, int nq) : np(np), nq(nq)
{
}
//! \todo clean memory here
template <class RF1D>
rational_function_t<RF1D>::~rational_function_t()
{
}