Библиотека математических вычислений

Я ищу библиотеку C/C++, которая вычисляет и выполняет математические выражения. Python был бы хорошим началом, но поскольку C-Python или PyPy имеют GIL, это не решение. Clang сработал бы, так как он очень быстрый и даже создает собственные инструкции процессора, но использование всего компилятора только для этой цели, на мой взгляд, слишком много.

Требования:

  • Может оценивать математические выражения
  • Работает в многопоточных средах
  • Создает объединенный вывод ( необязательно )

Любое предложение приветствуется

Какие математические выражения вы хотите поддерживать? «eval» Python на самом деле не предназначен для математических операций, он просто запускает встроенный код Python. Я думаю, вам следует взглянуть на интерфейсы библиотек SageMath C/C++ хотя бы для того, чтобы узнать, на какое программное обеспечение/библиотеки обратить внимание.
Я согласен, и eval слишком «злой». Спасибо за предложение!

Ответы (1)

Я знаю три библиотеки для этой задачи. Почти уверен, что никто из них не делает JIT.

  • GNU libmatheval

    Использует парсер на основе yacc и bison. Может вычислять простые математические выражения с помощью нескольких предопределенных функций и символов. Это библиотека C, которая должна быть скомпилирована и слинкована. Лицензия: GPL

    #include <cassert>
    #include <iostream>
    #include <string>
    
    #include <matheval.h>
    
    int main() {
        std::string expr = "1+x";
        char *buf = const_cast<char*>(expr.c_str());
    
        void *f = evaluator_create (buf);
        assert(f);
    
        int x = 1;
        std::cout << evaluator_evaluate_x (f, x) << '\n';
    }
    
  • Повышение Матевал

    Использует Boost.Spirit и Boost.Fusion для анализа и оценки. Поддерживает все стандартные функции математической библиотеки C++11. Определяет несколько констант. Библиотека шаблонов только для заголовков одного файла, требуется C++11, время компиляции будет порядка секунд из-за Boost.Spirit. Лицензия: Boost. (отказ от ответственности: я автор)

    #include <iostream>
    #include <string>
    
    #include <matheval.hpp>
    
    int main() {
        std::string expr = "1+x";
        matheval::Parser<double> parser;
        parser.parse(expr);
        std::cout << parser.evaluate({std::make_pair("x",1)}) << '\n';
        // // or even simpler
        // matheval::parse<double>(expr,{std::make_pair("x",1)})
    }
    
  • ExprTk

    Настоящий монстр с почти 40000 строк в одном заголовочном файле. Он реализует полный конечный автомат, включая такие вещи, как логические операции, управляющие структуры и даже файловый ввод-вывод. Время компиляции даже больше, чем с Boost Matheval.

    #include <iostream>
    #include <string>
    
    #include <exprtk.hpp>
    
    int main() {
        std::string expr = "1+x";
    
        double x = 1;
        exprtk::symbol_table<double> symbol_table;
        symbol_table.add_variable("x",x);
    
        exprtk::expression<double> expression;
        expression.register_symbol_table(symbol_table);
    
        exprtk::parser<double> parser;
        parser.compile(expr,expression);
    
        std::cout << expression.value() << '\n';
    }
    

Если вам нужно нечто большее, чем просто математические выражения, рассмотрите возможность встраивания в вашу программу языка расширения, такого как Lua (для которого существует LuaJIT).