Commit 3064dc42 authored by Laurent Belcour's avatar Laurent Belcour

Completing the Fresnel interface

parents 0e0fb8e7 846cd3be
......@@ -23,40 +23,57 @@ class arguments
// Constructor and destructor
arguments()
{
}
}
arguments(int argc, char** const argv)
{
std::string key ;
std::string data ;
for(int i=0; i<argc; ++i)
{
std::string temp(argv[i]) ;
std::string data ;
std::string key, data ;
if(temp.compare(0, 2, "--") == 0)
{
key = temp.substr(2, temp.size()-2) ;
int j = i+1;
#ifdef DEBUG_ARGS
std::cout << "<<DEBUG>> (" << i << ")" << key << " -> [ ";
#endif
int k = i+1;
int j = k;
while(j < argc)
{
std::string next(argv[j]) ;
if(next.compare(0, 2, "--") != 0)
if(next[0] == '[' || next[next.size()-1] == ']' || next.compare(0, 2, "--") != 0)
{
data.append(next) ;
if(j != k)
{
data.append(" ");
#ifdef DEBUG_ARGS
std::cout << " ";
#endif
}
data.append(next);
#ifdef DEBUG_ARGS
std::cout << "(" << j << ")" << next;
#endif
}
else
{
break ;
}
++j;
++i;
}
#ifdef DEBUG_ARGS
std::cout << "]" << std::endl;
#endif
}
_map.insert(std::pair<std::string, std::string>(key, data)) ;
}
}
~arguments()
{
}
}
~arguments()
{
}
//! \brief is the elements in the command line ?
bool is_defined(const std::string& key) const
......@@ -70,6 +87,23 @@ class arguments
return false ;
}
}
//! \brief is the data at the given key in a vector format?
//! No matter the type of the data, this function will test is the
//! mapped string is of type "[ .... ]".
//! It returns false if there is no associated entry.
bool is_vec(const std::string& key) const
{
if(_map.count(key) > 0)
{
return _map.find(key)->second[0] == '[' ;
}
else
{
return false ;
}
}
//! \brief access the element stored value
std::string operator[](const std::string& key) const
{
......@@ -131,13 +165,14 @@ class arguments
if(ppos != std::string::npos)
{
res[i] = atof(s.substr(pos, ppos).c_str());
res[i] = atof(s.substr(pos, ppos-pos).c_str());
pos = ppos+1;
++i;
}
else
{
res[i] = atof(s.substr(pos, ppos-1).c_str());
std::string temp = s.substr(pos, std::string::npos);
res[i] = atof(temp.substr(0, temp.size()-1).c_str());
pos = ppos;
++i;
}
......@@ -154,6 +189,40 @@ class arguments
return res;
}
std::vector<std::string> get_vec(const std::string& key) const
{
std::vector<std::string> res;
if(_map.count(key) > 0)
{
std::string s = _map.find(key)->second;
if(s[0] == '[') // Is an array of type [a, b, c]
{
size_t pos = 1;
while(pos != std::string::npos)
{
size_t ppos = s.find(',', pos);
if(ppos != std::string::npos)
{
std::string temp = s.substr(pos, ppos-pos);
res.push_back(temp);
pos = ppos+1;
}
else
{
std::string temp = s.substr(pos, std::string::npos);
temp = temp.substr(0, temp.size()-1);
res.push_back(temp);
pos = ppos;
}
}
}
}
return res;
}
private: // data
std::map<std::string, std::string> _map ;
......
......@@ -213,22 +213,22 @@ class nonlinear_function: public function
*/
class fresnel : public nonlinear_function
{
public: // methods
public: // methods
// Overload the function operator
virtual vec operator()(const vec& x) const
// Overload the function operator
virtual vec operator()(const vec& x) const
{
return f->value(x);
}
virtual vec value(const vec& x) const
virtual vec value(const vec& x) const
{
return f->value(x);
}
//! Load function specific files
virtual void load(const std::string& filename)
{
if(f != NULL)
//! Load function specific files
virtual void load(const std::string& filename)
{
if(f != NULL)
{
f->load(filename);
}
......@@ -236,8 +236,8 @@ class fresnel : public nonlinear_function
{
std::cout << "<<ERROR>> trying to load a Fresnel object with no base class" << std::endl;
}
}
}
//! Number of parameters to this non-linear function
virtual int nbParameters() const
{
......@@ -250,42 +250,60 @@ class fresnel : public nonlinear_function
int nb_func_params = f->nbParameters();
int nb_fres_params = nbFresnelParameters();
int nb_params = nb_func_params + nb_fres_params;
vec params(nb_params);
vec func_params = f->parameters();
for(int i=0; i<nb_func_params; ++i)
{
params[i] = func_params[i];
}
vec fres_params = getFresnelParameters();
for(int i=nb_func_params; i<nb_params; ++i)
{
params[i] = fres_params[i-nb_func_params];
}
return params;
}
//! Update the vector of parameters for the function
virtual void setParameters(const vec& p) = 0;
virtual void setParameters(const vec& p)
{
int nb_func_params = f->nbParameters();
int nb_fres_params = nbFresnelParameters();
vec func_params(nb_func_params);
for(int i=0; i<nb_func_params; ++i)
{
func_params[i] = p[i];
}
f->setParameters(func_params);
vec fres_params(nb_fres_params);
for(int i=0; i<nb_fres_params; ++i)
{
fres_params[i] = p[i+nb_func_params];
}
setFresnelParameters(fres_params);
}
//! \brief Obtain the derivatives of the function with respect to the
//! parameters.
virtual vec parametersJacobian(const vec& x) const = 0;
//! \brief set the value for the base function
void setBase(nonlinear_function* fin)
{
f = fin;
}
//! \brief set the value for the base function
void setBase(nonlinear_function* fin)
{
f = fin;
}
protected: // methods
protected: // methods
//! \brief the interface for the Fresnel code
virtual vec fresnelValue(const vec& x) const = 0;
//! \brief the interface for the Fresnel code
virtual vec fresnelValue(const vec& x) const = 0;
//! Number of parameters to this non-linear function
virtual int nbFresnelParameters() const = 0;
......@@ -299,8 +317,8 @@ class fresnel : public nonlinear_function
//! parameters.
virtual vec getFresnelParametersJacobian(const vec& x) const = 0;
protected: //data
protected: //data
//! the base object
nonlinear_function* f;
//! the base object
nonlinear_function* f;
};
......@@ -194,13 +194,43 @@ fitter* plugins_manager::get_fitter()
#endif
}
// Get instances of the function, the data and the
// fitter, select one based on the name. Return null
// if no one exist.
//
function* plugins_manager::get_function(const std::string& n)
arguments create_arguments(const std::string& n)
{
if(n.empty())
std::vector<std::string> cmd_vec;
std::stringstream stream(n);
#ifdef DEBUG_ARGS
std::cout << "<<DEBUG>> create argument vector: [";
#endif
while(stream.good())
{
std::string temp;
stream >> temp;
#ifdef DEBUG_ARGS
std::cout << temp << ", ";
#endif
cmd_vec.push_back(temp);
}
#ifdef DEBUG_ARGS
std::cout << "]" << std::endl;
#endif
int argc = cmd_vec.size();
char* argv[argc];
for(int i=0; i<argc; ++i)
{
argv[i] = &cmd_vec[i][0];
}
arguments current_args(argc, argv);
return current_args;
}
//! Get an instance of the function selected based on the name <em>n</em>.
//! Return NULL if no one exist.
function* plugins_manager::get_function(const arguments& args)
{
if(!args.is_defined("func"))
{
#ifdef DEBUG
std::cout << "<<DEBUG>> no function plugin specified, returning a rational function" << std::endl;
......@@ -208,46 +238,91 @@ function* plugins_manager::get_function(const std::string& n)
return new rational_function();
}
#ifdef USING_STATIC
/*
std::string file;
if(n[0] == '.')
{
file = n.substr(1, n.size()-1);
}
else
{
file = n;
}
// The function to be returned.
function* func = NULL;
QString path = QDir::currentPath() + QString(file.c_str()) ;
FunctionPrototype myFunction = open_library<FunctionPrototype>(path.toStdString(), "provide_function");
*/
FunctionPrototype myFunction = open_library<FunctionPrototype>(n, "provide_function");
if(myFunction != NULL)
if(args.is_vec("func"))
{
#ifdef DEBUG
std::cout << "<<DEBUG>> using function provider in file \"" << n << "\"" << std::endl;
#endif
return myFunction();
std::vector<std::string> args_vec = args.get_vec("func");
// Treating the case []
if(args_vec.size() == 0)
{
return NULL;
}
//! \todo create a <em>compound</em> class to store multiple
//! functions in it.
//! For each args_vec element, create a function object and add
//! it to the compound one.
std::string n("--func ");
n.append(args_vec[0]);
func = get_function(create_arguments(n));
//! return the compound class
}
else
{
std::cerr << "<<ERROR>> no function provider found in file \"" << n << "\"" << std::endl;
return new rational_function() ;
std::string filename = args["func"];
FunctionPrototype myFunction = open_library<FunctionPrototype>(filename, "provide_function");
if(myFunction != NULL)
{
#ifdef DEBUG
std::cout << "<<DEBUG>> using function provider in file \"" << filename << "\"" << std::endl;
#endif
func = myFunction();
}
else
{
std::cerr << "<<ERROR>> no function provider found in file \"" << filename << "\"" << std::endl;
return new rational_function() ;
}
}
#else
if(_functions.count(n) == 0)
{
return new rational_function() ;
}
else
{
return _functions.find(n)->second ;
}
#endif
// Treat the case of the Fresnel
if(args.is_defined("fresnel"))
{
// Cast into a non linear function, only those are permitted to use
// a Fresnel term.
nonlinear_function* nl_func = dynamic_cast<nonlinear_function*>(func);
if(nl_func == NULL)
{
std::cerr << "<<ERROR>> only non-linear function are permitted to use Fresnel" << std::endl;
return func;
}
std::cout << "<<DEBUG>> multiplying by a Fresnel term" << std::endl;
std::string n("--func ");
if(args.is_vec("fresnel"))
{
std::string temp = args["fresnel"];
n.append(temp.substr(1, temp.size()-2));
}
else
{
std::string fname = args["fresnel"];
if(fname.empty()) // Nothing to do except print error, no plugin defined
{
std::cerr << "<<ERROR>> Fresnel plugin not defined" << std::endl;
std::cerr << "<<ERROR>> using --fresnel alone is not permitted" << std::endl;
return func;
}
else // Case where the fresnel parameters is only the plugin filename
{
n.append(fname);
}
}
fresnel* func_fres = dynamic_cast<fresnel*>(get_function(create_arguments(n)));
func_fres->setBase(nl_func);
func = dynamic_cast<function*>(func_fres);
}
return func;
}
data* plugins_manager::get_data(const std::string& n)
{
......@@ -259,22 +334,6 @@ data* plugins_manager::get_data(const std::string& n)
return new vertical_segment();
}
#ifdef USING_STATIC
/*
std::string file;
if(n[0] == '.')
{
file = n.substr(1, n.size()-1);
}
else
{
file = n;
}
QString path = QDir::currentPath() + QString(file.c_str()) ;
DataPrototype myData = open_library<DataPrototype>(path.toStdString(), "provide_data");
*/
DataPrototype myData = open_library<DataPrototype>(n, "provide_data");
if(myData != NULL)
{
......@@ -288,17 +347,6 @@ data* plugins_manager::get_data(const std::string& n)
std::cerr << "<<ERROR>> no data provider found in file \"" << n << "\"" << std::endl;
return new vertical_segment() ;
}
#else
if(_functions.count(n) == 0)
{
return new vertical_segment() ;
}
else
{
return _datas.find(n)->second ;
}
#endif
}
fitter* plugins_manager::get_fitter(const std::string& n)
{
......@@ -310,23 +358,7 @@ fitter* plugins_manager::get_fitter(const std::string& n)
return NULL;
}
#ifdef USING_STATIC
/*
std::string file;
if(n[0] == '.')
{
file = n.substr(1, n.size()-1);
}
else
{
file = n;
}
QString path = QDir::currentPath() + QString(file.c_str()) ;
FitterPrototype myFitter = open_library<FitterPrototype>(path.toStdString(), "provide_fitter");
*/
FitterPrototype myFitter = open_library<FitterPrototype>(n, "provide_fitter");
FitterPrototype myFitter = open_library<FitterPrototype>(n, "provide_fitter");
if(myFitter != NULL)
{
#ifdef DEBUG
......@@ -339,20 +371,8 @@ fitter* plugins_manager::get_fitter(const std::string& n)
std::cerr << "<<ERROR>> no fitter provider found in file \"" << n << "\"" << std::endl;
return NULL ;
}
#else
if(_fitters.count(n) == 0)
{
return NULL ;
}
else
{
#ifdef DEBUG
std::cout << "<<DEBUG>> using \"" << n << "\"" << std::endl ;
#endif
return _fitters.find(n)->second ;
}
#endif
}
void plugins_manager::check_compatibility(data*& d, function*& f,
const arguments& args)
{
......
#pragma once
#pragma once
#include <map>
#include <string>
#include "args.h"
#include "function.h"
#include "data.h"
#include "fitter.h"
......@@ -45,7 +46,7 @@ class plugins_manager
#ifdef USING_STATIC
static
#endif
function* get_function(const std::string& n) ;
function* get_function(const arguments& args) ;
//! \brief get an instance of the data that is defined in the plugin with
//! filename n. Return null if no one exist.
......
......@@ -51,7 +51,7 @@ int main(int argc, char** argv)
d = manager.get_data(args["data"]) ;
function* f = NULL;
f = manager.get_function(args["func"]);
f = manager.get_function(args);
f->load(args["input"]);
// Modify function or data to provide coherent
......
......@@ -34,16 +34,7 @@ int main(int argc, char** argv)
return 1 ;
}
function* f = NULL;
if(args.is_defined("func"))
{
std::cout << "<<INFO>> Using plugin function \"" << args["func"] << "\"" << std::endl ;
f = manager.get_function(args["func"]) ;
}
else
{
f = manager.get_function() ;
}
function* f = manager.get_function(args) ;
data* d = NULL ;
if(args.is_defined("data"))
......@@ -72,7 +63,7 @@ int main(int argc, char** argv)
// Create output file
std::ofstream file(args["output"].c_str(), std::ios_base::trunc);
if(d != NULL)
if(d != NULL)
{
for(int i=0; i<d->size(); ++i)
{
......
......@@ -47,10 +47,17 @@ int main(int argc, char** argv)
// if(fitters.size() > 0 && datas.size() > 0 && functions.size() > 0)
{
fit->set_parameters(args) ;
function* f = plugins_manager::get_function(args["func"]);
function* f = plugins_manager::get_function(args);
data* d = plugins_manager::get_data(args["data"]);
d->load(args["input"], args);
if(f == NULL || d == NULL)
{
std::cerr << "<<ERROR>> no function or data object correctly defined" << std::endl;
return 1;
}
// Check the compatibility between the data and the function
plugins_manager::check_compatibility(d, f, args);
......
......@@ -84,7 +84,7 @@ int main(int argc, char** argv)
for(int i=0; i<d->dimY(); ++i)
{
double val = x[i] * cos(in_angle[2]);
double val = x[i] * cos(in_angle[2]);
rawm0[i] += val;
rawm1[i] += theta_out * val;
......
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