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 |
---|---|
result_add.bin | result_sub.bin |
---|---|
result_mul.bin | result_div.bin |
---|---|
いずれも正しく計算されていました(ImageJでの計算結果と比較)。この程度の要素数であれば,計算も瞬殺した。
ビルトインされている演算子や関数など
何というか,フツーに思いつく演算子や関数はひと通り組み込まれている感じです。
本家サイトにも一覧表示されていますが,こちらのリポジトリの方が見やすいかも。
本家サイトの計算例を見ると,単純な四則演算だけでなく,数式というよりコードに近いものも書けて,フィルタ処理や離散フーリエ変換なども実行できるようで,かなり汎用的です。
最後に
名だたる企業がフツーに使っているようです。
"ExprTk" "数式" でググっても,まともな日本語サイトは2件しかヒットしないけど。
以上