1
0
mirror of https://github.com/aportelli/LatAnalyze.git synced 2025-04-10 19:20:44 +01:00

DoubleFunction: more efficient call (less copies)

This commit is contained in:
Antonin Portelli 2014-02-21 01:18:22 +00:00
parent 0d0c0e6730
commit fc18acc4bb
6 changed files with 52 additions and 22 deletions

View File

@ -48,16 +48,10 @@ void CompiledDoubleFunction::setCode(const string &code)
} }
// function call /////////////////////////////////////////////////////////////// // function call ///////////////////////////////////////////////////////////////
double CompiledDoubleFunction::evaluate(const vector<double> &arg) const double CompiledDoubleFunction::operator()(const double *arg) const
{ {
double result; double result;
if (arg.size() != getNArg())
{
LATAN_ERROR(Size, "function argument vector has a wrong size (got " +
strFrom(arg.size()) + ", expected " + strFrom(getNArg()) +
")");
}
for (unsigned int i = 0; i < getNArg(); ++i) for (unsigned int i = 0; i < getNArg(); ++i)
{ {
context_->vTable["x_" + strFrom(i)] = arg[i]; context_->vTable["x_" + strFrom(i)] = arg[i];

View File

@ -45,10 +45,13 @@ public:
// access // access
void setCode(const std::string &code); void setCode(const std::string &code);
// function call // function call
virtual double evaluate(const std::vector<double> &arg) const; using DoubleFunction::operator();
// IO // IO
friend std::ostream & operator<<(std::ostream &out, friend std::ostream & operator<<(std::ostream &out,
CompiledDoubleFunction &f); CompiledDoubleFunction &f);
private:
// function call
virtual double operator()(const double *arg) const;
private: private:
std::shared_ptr<MathInterpreter> interpreter_; std::shared_ptr<MathInterpreter> interpreter_;
std::shared_ptr<RunContext> context_; std::shared_ptr<RunContext> context_;

View File

@ -61,25 +61,55 @@ unsigned int Function::getNArg(void) const
// constructor ///////////////////////////////////////////////////////////////// // constructor /////////////////////////////////////////////////////////////////
DoubleFunction::DoubleFunction(const unsigned nArg, vecFunc f) DoubleFunction::DoubleFunction(const unsigned nArg, vecFunc f)
: Function(nArg) : Function(nArg)
, buffer_(new vector<double>(nArg)) , buffer_(new DVec(nArg))
, f_(f) , f_(f)
{} {}
// function call /////////////////////////////////////////////////////////////// // function call ///////////////////////////////////////////////////////////////
double DoubleFunction::evaluate(const std::vector<double> &arg) const double DoubleFunction::operator()(const double *arg) const
{ {
return f_(arg); return f_(arg);
} }
double DoubleFunction::operator()(const DVec &arg) const
{
if (arg.size() != getNArg())
{
LATAN_ERROR(Size, "function argument vector has a wrong size (expected "
+ strFrom(getNArg()) + ", got " + strFrom(arg.size())
+ ")");
}
return (*this)(arg.data());
}
double DoubleFunction::operator()(const std::vector<double> &arg) const
{
if (arg.size() != getNArg())
{
LATAN_ERROR(Size, "function argument vector has a wrong size (expected "
+ strFrom(getNArg()) + ", got " + strFrom(arg.size())
+ ")");
}
return (*this)(arg.data());
}
double DoubleFunction::operator()(std::stack<double> &arg) const double DoubleFunction::operator()(std::stack<double> &arg) const
{ {
for (unsigned int i = 0; i < getNArg(); ++i) for (unsigned int i = 0; i < getNArg(); ++i)
{ {
(*buffer_)[getNArg() - i - 1] = arg.top(); if (arg.empty())
{
LATAN_ERROR(Size, "function argument stack has a wrong size (expected "
+ strFrom(getNArg()) + ", got " + strFrom(i)
+ ")");
}
(*buffer_)(getNArg() - i - 1) = arg.top();
arg.pop(); arg.pop();
} }
return this->evaluate(*buffer_); return (*this)(*buffer_);
} }
double DoubleFunction::operator()(const double x0, ...) const double DoubleFunction::operator()(const double x0, ...) const
@ -92,10 +122,10 @@ double DoubleFunction::operator()(const double x0, ...) const
va_start(va, x0); va_start(va, x0);
for (unsigned int i = 1; i < getNArg(); ++i) for (unsigned int i = 1; i < getNArg(); ++i)
{ {
(*buffer_)[i] = va_arg(va, double); (*buffer_)(i) = va_arg(va, double);
} }
va_end(va); va_end(va);
} }
return this->evaluate(*buffer_); return (*this)(*buffer_);
} }

View File

@ -25,7 +25,6 @@
#include <memory> #include <memory>
#include <stack> #include <stack>
#include <vector> #include <vector>
#include <cstdarg>
BEGIN_NAMESPACE BEGIN_NAMESPACE
@ -51,19 +50,23 @@ private:
class DoubleFunction: public Function class DoubleFunction: public Function
{ {
private: private:
typedef std::function<double(const std::vector<double> &)> vecFunc; typedef std::function<double(const double *)> vecFunc;
public: public:
// constructor // constructor
explicit DoubleFunction(const unsigned nArg, vecFunc f = nullptr); explicit DoubleFunction(const unsigned nArg, vecFunc f = nullptr);
// destructor // destructor
virtual ~DoubleFunction(void) = default; virtual ~DoubleFunction(void) = default;
// function call // function call
virtual double evaluate(const std::vector<double> &arg) const; double operator()(const DVec &arg) const;
double operator()(const std::vector<double> &arg) const;
double operator()(std::stack<double> &arg) const; double operator()(std::stack<double> &arg) const;
double operator()(const double x0, ...) const; double operator()(const double x0, ...) const;
protected:
// function call
virtual double operator()(const double *arg) const;
private: private:
std::shared_ptr<std::vector<double>> buffer_; std::shared_ptr<DVec> buffer_;
vecFunc f_; vecFunc f_;
}; };
END_NAMESPACE END_NAMESPACE

View File

@ -28,14 +28,14 @@ using namespace Latan;
******************************************************************************/ ******************************************************************************/
#define DEF_STD_FUNC_1ARG(name) \ #define DEF_STD_FUNC_1ARG(name) \
static double name##VecFunc(const vector<double> &arg)\ static double name##VecFunc(const double *arg)\
{\ {\
return (name)(arg[0]);\ return (name)(arg[0]);\
}\ }\
DoubleFunction STDMATH_NAMESPACE::name(1, &name##VecFunc); DoubleFunction STDMATH_NAMESPACE::name(1, &name##VecFunc);
#define DEF_STD_FUNC_2ARG(name) \ #define DEF_STD_FUNC_2ARG(name) \
static double name##VecFunc(const vector<double> &arg)\ static double name##VecFunc(const double *arg)\
{\ {\
return (name)(arg[0], arg[1]);\ return (name)(arg[0], arg[1]);\
}\ }\

View File

@ -47,7 +47,7 @@ MinuitMinimizer::MinuitFunction::MinuitFunction(const DoubleFunction &f)
double MinuitMinimizer::MinuitFunction::operator() double MinuitMinimizer::MinuitFunction::operator()
(const vector<double> &x) const (const vector<double> &x) const
{ {
return f_->evaluate(x); return (*f_)(x);
} }
double MinuitMinimizer::MinuitFunction::Up(void) const double MinuitMinimizer::MinuitFunction::Up(void) const