Exprtk的异常行为

时间:2018-11-24 16:50:46

标签: c++ gsl exprtk

我正在用Exprtk类创建一个对象,以模仿要在运行时定义并用于GSL算法的m个变量的n维函数。但是,在尝试评估5维身份时,某些变量碰巧没有初始化,而其他变量确实没有初始化。

使用以下文件main.cpp,custom_function.h和custom_function.hpp,结果是出乎意料的:输出文件应具有六列相等的数字,从0到19。但是,只有第一列(显而易见的是,索引)和最后一个(变量v)恰好是他们应该做的。我尝试在调用e [i] .value()之前打印x的值,但它们是我所期望的。

问题似乎出在operator()定义内的e [i]调用上,这掩盖了我确实无法弄清楚的Exprtk对象的错误用法(解析的代码直接来自其中一个实例)或Exprtk中的错误,这种情况不太可能发生。

有人有主意吗?

编辑: 我发现问题更普遍了,移至here

编辑2:上面链接中的解决方案,重新分配了向量,并且其指针无效。

主要是:

#include"custom_function.h"

#include <fstream>

using namespace std;

int main()
{  
  custom_function f;

  void* p;

  // defining the function: an identity
  f.set_expression("A * x");
  f.set_expression("A * y");
  f.set_expression("A * z");
  f.set_expression("A * w");
  f.set_expression("A * v");

  f.set_constant("A", 1.);

  f.set_variable("x");
  f.set_variable("y");
  f.set_variable("z");
  f.set_variable("w");
  f.set_variable("v");

  // parse the expression
  f.done();

  gsl_vector *input = gsl_vector_calloc (5), *output = gsl_vector_calloc (5);


  ofstream o("out.txt");
  // printing out some output
  for (double i = 0.; i<20; i+=1)
  {
    gsl_vector_set_all(input, i);
    f(input, p, output); // calling the identity and setting output
    o << i << " " << gsl_vector_get(output, 0) << " " <<    gsl_vector_get(output, 1) << " " << gsl_vector_get(output, 2) << " " << gsl_vector_get(output, 3) << " " << gsl_vector_get(output, 4)  << endl;
  }
  return 0;
  }

当对象具有文件头时

#ifndef custom_function_h
#define custom_function_h

#include<vector>
#include<string>
#include<iostream>

#include"exprtk.hpp"
#include <gsl/gsl_vector.h>

class custom_function
{
// private members
 size_t n=0, m=0; // a n-dim function of m variables
 std::vector<std::string> expression; // the expression to be interpreted
 exprtk::symbol_table<double> s; // the table of the variables and constants
 std::vector<exprtk::expression<double>> e; // the expressions where to register the string and to extract numerical values. n are needed.
 exprtk::parser<double> p; // the parser
 std::vector<double> x; // internal vector of variables.  
 bool is_done = false; // true if done is called

 public:
 custom_function();
 ~custom_function();
 void set_constant(std::string, double); // sets a string to be a constant in the expression given
 void set_variable(std::string); // sets string to be a variable name, and uploads m
 void set_expression(std::string); // sets an entire output of the function, and uploads n
 void done(); // uploads the gsl function and vector
 void operator() (const gsl_vector*, void*, gsl_vector*); // definition of the function in the gsl way
};

#include"custom_function.hpp"


#endif

和定义

#include"custom_function.h"

 custom_function::custom_function()
 {
 }

 custom_function::~custom_function()
 {
 }

 void custom_function::set_constant(std::string name, double val)
 {
   s.add_constant(name, val); // adds a constant in the symbol table
   return;
 }

 void custom_function::set_variable(std::string name)
 {
   x.push_back(0); // adds a member in the internal vector
   s.add_variable(name, x[m++]);
   return;
 }

 void custom_function::set_expression(std::string name)
 {
   expression.push_back(name); // adds the expression
   n++;
   return;
 }

 void custom_function::done()
 {  
    exprtk::expression<double> exp;
    exp.register_symbol_table(s);

    for (int i = 0; i < n; i++)
   {
      if (p.compile(expression[i],exp))
         e.push_back(exp);
      else
        std::cerr << "Error in " << expression[i] << std::endl;
   }

   is_done = true;
   return;
 }

 void custom_function::operator() (const gsl_vector* in, void * par, gsl_vector * f) 
 {
   if (is_done)
   {
     for (int i=0; i<m; i++)
       x[i]=gsl_vector_get(in, i); // setting the input to x

     for (int i=0; i<n; i++)
       gsl_vector_set(f, i, e[i].value()); // setting the output vector  
   }
   else 
     gsl_vector_set_zero(f); // set all zero if not initialized

   return;
}

0 个答案:

没有答案