До сих пор я использовал эту библиотеку исключительно для обработки выражений, которые выдают значения типа , для которых библиотека работает безупречно, определяя типы
Код: Выделить всё
typedef exprtk::symbol_table symbol_table_t;
typedef exprtk::expression expression_t;
typedef exprtk::parser parser_t;
Код: Выделить всё
struct readInExpression
{
double a, b;
symbol_table_t symbol_table;
expression_t expression;
};
Код: Выделить всё
double my_function(double a, double b) {
return a+b;
}
Код: Выделить всё
void readInFromFile(readInExpression* f, parser_t* p) {
std::string file = "xyz.txt";
std::ifstream ifs(file);
std::string content( (std::istreambuf_iterator(ifs) ),
(std::istreambuf_iterator() ) );
f->symbol_table.add_variable("a",f->a);
f->symbol_table.add_variable("b",f->b);
f->symbol_table.add_function("my_function",my_function);
f->expression.register_symbol_table(f->symbol_table);
p->compile(content,f->expression);
}
Код: Выделить всё
double evaluateFile(readInExpression* f, double a, double b) {
f->a = a;
f->b = b;
return f->expression.value();
}
Код: Выделить всё
2*m*A0(m*m) + Complex(1.0,2.0)*B0(M*M,0.0,m*m)
Их можно оценить численно в C с помощью LoopTools, где следует отметить, что они принимают комплексные значения для определенных значений a, b и в. Простая замена на std::complex в приведенных выше определениях типов приводит к множеству ошибок при компиляции. Я не уверен, способна ли библиотека ExprTk вообще обрабатывать комплексные числа. Я знаю, что она не может работать с пользовательскими классами, но, насколько я понимаю, она должна иметь возможность обрабатывать собственные типы данных (как я обнаружил здесь, ExprTk умею хотя бы разбираться с векторами, но учитывая сложность выражений, которые мне нужно обрабатывать, не думаю, что получится как-то переписать все в виде векторов, в частности из-за разницы в выполнении алгебры с комплексными числами и векторы). Обратите внимание, что я также не могу разделить выражения на действительную и мнимую часть, поскольку мне приходится вычислять выражения для множества различных значений переменных.
Хотя я имел дело с комплексными числами и упомянутыми функциями A0 (a) и B0(a,b,c) в текстовых файлах раньше, я решил эту проблему, просто включив файлы .txt в C, используя #include "xyz.txt"< /code>, реализованный в соответствующей функции, что, однако, кажется невозможным, учитывая размер имеющихся текстовых файлов (компилятор выдает ошибку, если я попытаюсь это сделать).
Кто-нибудь знает, может ли ExprTk работать с комплексными числами и как это сделать? (Мы будем очень признательны за MWE.) Если это не так, может ли кто-нибудь здесь предложить другой математический анализатор, который удобен для пользователя и может работать с комплексными числами типа std::complex, по адресу в то же время позволяет определять пользовательские функции, которые сами возвращают такие сложные значения?
A MWE:
Код: Выделить всё
/************/
/* Includes */
/************/
#include // Input and Output on the console
#include // Input and Output to files
#include // In order to work with strings -- needed to loop through the Mathematica output files
#include "exprtk.hpp" // Parser to evaluate string expressions as mathematical/arithmetic input
#include // Simple Math Stuff
#include // GSL math stuff
#include // Complex Numbers
/**********/
/* Parser */
/**********/
// Type definitions for the parser
typedef exprtk::symbol_table symbol_table_t; // (%)
typedef exprtk::expression expression_t; // (%)
typedef exprtk::parser parser_t; // (%)
/* This struct is used to store certain information of the Mathematica files in
order to later evaluate them for different variables with the parser library. */
struct readInExpression
{
double a,b; // (%)
symbol_table_t symbol_table;
// Instantiate expression
expression_t expression;
};
/* Global variable where the read-in file/parser is stored. */
readInExpression file;
parser_t parser;
/*******************/
/* Custom function */
/*******************/
double my_function(double a, double b) {
return a+b;
}
/***********************************/
/* Converting Mathematica Notation */
/***********************************/
/* Mathematica prints complex numbers as Complex(x,y), so we need a function to convert to C++ standard. */
std::complex Complex(double a, double b) { // (%)
std::complex c(a,b);
return c;
}
/************************************/
/* Processing the Mathematica Files */
/************************************/
double evaluateFileDoubleValuedInclude(double a, double b) {
return
#include "xyz.txt"
;
}
std::complex evaluateFileComplexValuedInclude(double a, double b) {
return
#include "xyzC.txt"
;
}
void readInFromFile(readInExpression* f, parser_t* p) {
std::string file = "xyz.txt"; // (%)
std::ifstream ifs(file);
std::string content( (std::istreambuf_iterator(ifs) ),
(std::istreambuf_iterator() ) );
// Register variables with the symbol_table
f->symbol_table.add_variable("a",f->a);
f->symbol_table.add_variable("b",f->b);
// Add custom functions to the evaluation list (see definition above)
f->symbol_table.add_function("my_function",my_function); // (%)
// f->symbol_table.add_function("Complex",Complex); // (%)
// Register symbol_table to instantiated expression
f->expression.register_symbol_table(f->symbol_table);
// Compile the expression with the instantiate parser
p->compile(content,f->expression);
}
std::complex evaluateFile(readInExpression* f, double a, double b) { // (%)
// Set the values of the struct to the input values
f->a = a;
f->b = b;
// Evaluate the result for the upper values
return f->expression.value();
}
int main() {
exprtk::symbol_table st1; // Works
exprtk::expression e1; // Works
// exprtk::parser p1; // Throws an error
double a = 2.0;
double b = 3.0;
std::cout
Подробнее здесь: [url]https://stackoverflow.com/questions/67423988/math-parser-for-complex-numbers-in-c-exprtk[/url]