1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

数式パーサーライブラリ ExprTk (C++)

Posted at

ExprTk

ExprTkはC++の数式パーサーライブラリ(MIT License)です。昨日,その存在を知りました。

四則演算のサンプルコード

例えば,2つのバイナリファイルを変数x,yとして,(ExprTkのビルトイン機能の範囲で)x,yを含む任意の数式を評価し,評価結果をバイナルファイルに出力するコードはこんな感じになります。Copilotに書いてもらって,ほんの少し修正しました。

array_calc.cpp
#include <iostream>
#include <fstream>
#include <string>
#include "exprtk.hpp"

// Define the expression parser
typedef float T;
typedef exprtk::symbol_table<T> symbol_table_t;
typedef exprtk::expression<T> expression_t;
typedef exprtk::parser<T> parser_t;

int main(int argc, char* argv[])
{
    if (argc != 5)
    {
        std::cerr << "Example usage: " << argv[0] << " file_x.bin file_y.bin \"x+y\" result.bin" << std::endl;
        return 1;
    }

    // Parse command line arguments
    std::string expr_str = argv[3];
    std::string output_file = argv[4];

    // Load binary files
    std::ifstream file_x(argv[1], std::ios::binary);
    std::ifstream file_y(argv[2], std::ios::binary);
    std::ofstream result_file(output_file, std::ios::binary);

    if (!file_x || !file_y || !result_file)
    {
        std::cerr << "Error: opening files." << std::endl;
        return 1;
    }

    // Create expression parser
    symbol_table_t symbol_table;
    T x_val, y_val;
    symbol_table.add_variable("x", x_val);
    symbol_table.add_variable("y", y_val);

    expression_t expression;
    expression.register_symbol_table(symbol_table);

    parser_t parser;
    if (parser.compile(expr_str, expression) == false)
    {
        std::cerr << "Error: compiling expression." << std::endl;
        return 1;
    }

    // Evaluate expression for each pair of values
    while (file_x.read(reinterpret_cast<char*>(&x_val), sizeof(T)) &&
           file_y.read(reinterpret_cast<char*>(&y_val), sizeof(T)))
    {
        T result = expression.value();

        result_file.write(reinterpret_cast<const char*>(&result), sizeof(T));
    }

    std::cout << "Calculation completed. Results written to " << output_file << std::endl;

    return 0;
}

"開発者コマンド プロンプト for VS2015"を立ち上げて,こちらのコマンドでビルドしました。

ビルドコマンド
cl.exe array_calc.cpp /O2 /EHsc /bigobj

四則演算してみた

試しに,2つのfloat型のバイナリファイル(要素数200×200の画像)の四則演算をしてみました。

実行コマンド
array_calc.exe image1.bin image2.bin "x+y" result_add.bin
array_calc.exe image1.bin image2.bin "x-y" result_sub.bin
array_calc.exe image1.bin image2.bin "x*y" result_mul.bin
array_calc.exe image1.bin image2.bin "(y>0)?(x/y):0" result_div.bin

三項演算子(?:)も普通に使えます。

image1.bin image2.bin
image.png image.png
result_add.bin result_sub.bin
image.png image.png
result_mul.bin result_div.bin
image.png image.png

いずれも正しく計算されていました(ImageJでの計算結果と比較)。この程度の要素数であれば,計算も瞬殺した。

ビルトインされている演算子や関数など

何というか,フツーに思いつく演算子や関数はひと通り組み込まれている感じです。
本家サイトにも一覧表示されていますが,こちらのリポジトリの方が見やすいかも。

本家サイトの計算例を見ると,単純な四則演算だけでなく,数式というよりコードに近いものも書けて,フィルタ処理や離散フーリエ変換なども実行できるようで,かなり汎用的です。

最後に

名だたる企業がフツーに使っているようです。
"ExprTk" "数式" でググっても,まともな日本語サイトは2件しかヒットしないけど。

image.png

以上

1
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?