2

I am looking for a C/C++ library which does evaluate and execute math expressions. Python would be a good start but since C-Python or PyPy have a GIL this is no solution. Clang would have worked since it is very fast and even creates native processor instructions but using an entire compiler for only this goal is too much in my opinion.

Requirements:

  • Can evaluate math expressions
  • Works in multi-threaded environments
  • Creates jitted output (optional)

Any suggestion is appreciated

  • 1
    What kind of mathematical expressions do you want to support? Python's "eval" isn't really intended for mathematical operations, it just runs Python code inline. I think you should take a look at the SageMath C/C++ Library Interfaces if only to find out what software/libraries to take a look at. – 0x01 Mar 15 '18 at 20:25
  • I agree, and eval is too 'evil'. Thanks for the suggestion! – HelloWorld Mar 15 '18 at 21:24
1

I know of three libraries for this task. Pretty sure none of those do JIT.

  • GNU libmatheval

    Uses a parser based on yacc and bison. Can evaluate simple mathematical expressions with few predefined functions and symbols. Is a C library which has to be compiled and linked against. License: 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 Matheval

    Uses Boost.Spirit and Boost.Fusion to parse and evaluate. Has support for all of C++11's standard math library functions. Defines a few constants. Single file header-only template library, requires C++11, compile-time will be of the order of seconds due to Boost.Spirit. License: Boost. (disclaimer: I'm the author)

    #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

    A true monster with almost 40000 lines in a single header file. It implements a complete state machine including things like logical operations, control structures, and even file IO. Compilation time is even longer than with 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';
    }
    

If you need more than just mathematical expressions, consider embedding an extension language into your program, such as Lua (for which there exists LuaJIT).

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.