Commit 63d7a216 authored by Laurent Belcour's avatar Laurent Belcour
Browse files

Currently implementing the product function

parent b9c33da6
#include "function.h"
#include "common.h"
#include "params.h"
#include "plugins_manager.h"
/*--- Functions implementation ----*/
......@@ -412,3 +413,177 @@ void compound_function::bootstrap(const ::data* d, const arguments& args)
}
}
}
/*--- Product functions implementation ----*/
product_function::product_function()
{
}
product_function::product_function(nonlinear_function* g1, nonlinear_function* g2)
{
this->f1 = g1;
this->f2 = g2;
}
vec product_function::operator()(const vec& x) const
{
return value(x);
}
vec product_function::value(const vec& x) const
{
// Get the first function value
vec f1res = f1->value(x);
// Convert input space to the 2nd function parametreization
vec xf2(f2->dimX());
params::convert(&x[0], f1->input_parametrization(), f2->input_parametrization(), &xf2[0]);
vec f2res = f2->value(xf2);
return product(f1res, f2res);
}
bool product_function::load(std::istream& in)
{
bool loaded_f1,loaded_f2;
std::streampos pos = in.tellg();
// Load the first function
if(f1 != NULL)
{
loaded_f1 = f1->load(in);
if(! loaded_f1)
{
in.seekg(pos);
}
}
pos = in.tellg();
// Load the second function
if(f2 != NULL)
{
loaded_f2 = f2->load(in);
if(! loaded_f2)
{
in.seekg(pos);
}
}
return loaded_f1 || loaded_f2;
}
void product_function::bootstrap(const data* d, const arguments& args)
{
const bool global_bootstrap = args.is_defined("bootstrap");
// Check if the bootstrap is global
if(global_bootstrap)
{
if(args.is_vec("bootstrap"))
{
vec p = args.get_vec("bootstrap", nbParameters());
setParameters(p);
}
else
{
std::ifstream file;
file.open(args["bootstrap"].c_str()) ;
if(file.is_open())
{
// Skip the header
std::string line ;
do
{
std::getline(file, line) ;
}
while(line != "#ALTA HEADER END");
std::streampos pos = file.tellg();
// If the first function cannot be loaded, put the input stream
// in the previous state and bootstrap normaly this function.
if(!f1->load(file))
{
file.seekg(pos);
// Bootstrap the function as if it was not loaded
f1->bootstrap(d, args);
}
// If the second function cannot be loaded, put the input stream
// in the previous state and bootstrap normaly this function.
if(!f2->load(file))
{
file.seekg(pos);
// Bootstrap the function as if it was not loaded
f2->bootstrap(d, args);
}
}
else
{
std::cerr << "<<ERROR>> you must provide a vector of parameters or a file to load with the bootstrap" << std::endl;
}
}
}
else
{
f1->bootstrap(d, args);
f2->bootstrap(d, args);
}
}
void product_function::setDimX(int nX)
{
f1->setDimX(nX);
f2->setDimX(nX);
}
void product_function::setDimY(int nY)
{
f1->setDimY(nY);
f2->setDimY(nY);
}
void product_function::setMin(const vec& min)
{
f1->setMin(min);
f2->setMin(min);
}
void product_function::setMax(const vec& max)
{
f1->setMax(max);
f2->setMax(max);
}
int product_function::nbParameters() const
{
return f1->nbParameters() + f2->nbParameters();
}
vec product_function::parameters() const
{
int nb_f1_params = f1->nbParameters();
int nb_f2_params = f2->nbParameters();
int nb_params = nb_f1_params + nb_f2_params;
vec params(nb_params);
vec f1_params = f1->parameters();
for(int i=0; i<nb_f1_params; ++i)
{
params[i] = f1_params[i];
}
vec f2_params = parameters();
for(int i=0; i<nb_f2_params; ++i)
{
params[i+nb_f1_params] = f2_params[i];
}
return params;
}
......@@ -524,6 +524,58 @@ class compound_function: public nonlinear_function
};
/*! \brief A product of nonlinear functions. This class aims to simplify the
* fitting and progressive fitting of Fresnel effects that can be separated
* from the main lobe.
* \ingroup core
*/
class product_function : public nonlinear_function
{
public: // methods
//! \brief Empty constructor of the product function
product_function();
//! \brief Constructor of the product function, affect the two function
//! to already created nonlinear_function objects.
product_function(nonlinear_function* g1, nonlinear_function* g2);
//! \brief Overload the function operator, directly call the value function.
virtual vec operator()(const vec& x) const;
//! \brief Return the product between the value of function f1 and function
//! f2. The input parameter x should be in the parametrization of f1. This
//! function will do the conversion before getting f2's value.
virtual vec value(const vec& x) const;
//! \brief Load the two functions in order f1, then f2. If one of the
//! function cannot be loaded, this function will continue. It will only
//! return false if both functions cannot be loaded.
virtual bool load(std::istream& in);
//! \brief Provide a first rough fit of the function.
virtual void bootstrap(const data* d, const arguments& args);
// Set the dimension of the input/output space of the function
virtual void setDimX(int nX);
virtual void setDimY(int nY);
// Acces to the domain of definition of the function
virtual void setMin(const vec& min);
virtual void setMax(const vec& max);
//! \brief Number of parameters to this non-linear function
virtual int nbParameters() const;
//! \biref Get the vector of parameters for the function
virtual vec parameters() const;
private: // data
// Function composing the product
nonlinear_function *f1, *f2;
};
/*! \brief A Fresnel interface
* \ingroup core
* \todo Change it to a product_function instead
......@@ -541,10 +593,10 @@ class fresnel : public nonlinear_function
{
vec fres = fresnelValue(x);
// Convert input space to the function
vec xf(f->dimX());
params::convert(&x[0], params::CARTESIAN, f->input_parametrization(), &xf[0]);
vec func = f->value(xf);
// Convert input space to the function
vec xf(f->dimX());
params::convert(&x[0], params::CARTESIAN, f->input_parametrization(), &xf[0]);
vec func = f->value(xf);
return product(fres, func);
}
......
Supports Markdown
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