我正在用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;
}