├── .circleci └── config.yml ├── Makefile ├── exprtk.hpp ├── exprtk_benchmark.cpp ├── exprtk_functional_ext_test.txt ├── exprtk_functional_test.txt ├── exprtk_simple_example_01.cpp ├── exprtk_simple_example_02.cpp ├── exprtk_simple_example_03.cpp ├── exprtk_simple_example_04.cpp ├── exprtk_simple_example_05.cpp ├── exprtk_simple_example_06.cpp ├── exprtk_simple_example_07.cpp ├── exprtk_simple_example_08.cpp ├── exprtk_simple_example_09.cpp ├── exprtk_simple_example_10.cpp ├── exprtk_simple_example_11.cpp ├── exprtk_simple_example_12.cpp ├── exprtk_simple_example_13.cpp ├── exprtk_simple_example_14.cpp ├── exprtk_simple_example_15.cpp ├── exprtk_simple_example_16.cpp ├── exprtk_simple_example_17.cpp ├── exprtk_simple_example_18.cpp ├── exprtk_simple_example_19.cpp ├── exprtk_simple_example_20.cpp ├── exprtk_simple_example_21.cpp ├── exprtk_simple_example_22.cpp ├── exprtk_simple_example_23.cpp ├── exprtk_simple_example_24.cpp ├── exprtk_test.cpp ├── license.txt └── readme.txt /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 2 | jobs: 3 | 4 | build_gcc_09: 5 | docker: 6 | - image: gcc:9 7 | steps: 8 | - checkout 9 | - run: c++ --version 10 | - run: make all -j 2 11 | - run: ./exprtk_test 12 | 13 | build_gcc_10: 14 | docker: 15 | - image: gcc:10 16 | steps: 17 | - checkout 18 | - run: c++ --version 19 | - run: make all -j 2 20 | - run: ./exprtk_test 21 | 22 | build_gcc_11: 23 | docker: 24 | - image: gcc:11 25 | steps: 26 | - checkout 27 | - run: c++ --version 28 | - run: make all -j 2 29 | - run: ./exprtk_test 30 | 31 | build_gcc_12: 32 | docker: 33 | - image: gcc:12 34 | steps: 35 | - checkout 36 | - run: c++ --version 37 | - run: make all -j 2 38 | - run: ./exprtk_test 39 | 40 | build_gcc_13: 41 | docker: 42 | - image: gcc:13 43 | steps: 44 | - checkout 45 | - run: c++ --version 46 | - run: make all -j 2 47 | - run: ./exprtk_test 48 | 49 | build_gcc_latest: 50 | docker: 51 | - image: gcc:latest 52 | steps: 53 | - checkout 54 | - run: c++ --version 55 | - run: make all -j 2 56 | - run: ./exprtk_test 57 | 58 | workflows: 59 | version: 2 60 | build_and_test: 61 | jobs: 62 | - build_gcc_09: 63 | filters: 64 | branches: 65 | only: 66 | - master 67 | - release 68 | 69 | - build_gcc_10: 70 | filters: 71 | branches: 72 | only: 73 | - master 74 | - release 75 | 76 | - build_gcc_11: 77 | filters: 78 | branches: 79 | only: 80 | - master 81 | - release 82 | 83 | - build_gcc_12: 84 | filters: 85 | branches: 86 | only: 87 | - master 88 | - release 89 | 90 | - build_gcc_13: 91 | filters: 92 | branches: 93 | only: 94 | - master 95 | - release 96 | 97 | - build_gcc_latest: 98 | filters: 99 | branches: 100 | only: 101 | - master 102 | - release 103 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # ************************************************************** 3 | # * C++ Mathematical Expression Toolkit Library * 4 | # * * 5 | # * Author: Arash Partow (1999-2024) * 6 | # * URL: https://www.partow.net/programming/exprtk/index.html * 7 | # * * 8 | # * Copyright notice: * 9 | # * Free use of the Mathematical Expression Toolkit Library is * 10 | # * permitted under the guidelines and in accordance with the * 11 | # * most current version of the MIT License. * 12 | # * https://www.opensource.org/licenses/MIT * 13 | # * SPDX-License-Identifier: MIT * 14 | # * * 15 | # ************************************************************** 16 | # 17 | 18 | 19 | COMPILER := -c++ 20 | #COMPILER := -clang++ 21 | OPTIMIZATION_OPT := -O2 -DNDEBUG 22 | BASE_OPTIONS := -pedantic-errors -Wall -Wextra -Werror -Wno-long-long 23 | OPTIONS := $(BASE_OPTIONS) $(OPTIMIZATION_OPT) 24 | LINKER_OPT := -L/usr/lib -lstdc++ -lm 25 | ASAN_OPT := -g -fsanitize=address -fno-omit-frame-pointer 26 | MSAN_OPT := -g -fsanitize=memory -fno-omit-frame-pointer 27 | LSAN_OPT := -g -fsanitize=leak -fno-omit-frame-pointer 28 | USAN_OPT := -g -fsanitize=undefined -fno-omit-frame-pointer 29 | BUILD_SRC := $(sort $(wildcard exprtk_*.cpp)) 30 | BUILD_LIST := $(BUILD_SRC:%.cpp=%) 31 | 32 | 33 | all: $(BUILD_LIST) 34 | 35 | $(BUILD_LIST) : %: %.cpp exprtk.hpp 36 | $(COMPILER) $(OPTIONS) -o $@ $@.cpp $(LINKER_OPT) 37 | 38 | strip_bin : 39 | @for f in $(BUILD_LIST); do if [ -f $$f ]; then strip -s $$f; echo $$f; fi done; 40 | 41 | valgrind : 42 | @for f in $(BUILD_LIST); do \ 43 | if [ -f $$f ]; then \ 44 | cmd="valgrind --leak-check=full --show-reachable=yes --track-origins=yes --log-file=$$f.log -v ./$$f"; \ 45 | echo $$cmd; \ 46 | $$cmd; \ 47 | fi done; 48 | 49 | pgo: exprtk_benchmark.cpp exprtk.hpp 50 | $(COMPILER) $(BASE_OPTIONS) -O3 -DNDEBUG -march=native -fprofile-generate -o exprtk_benchmark exprtk_benchmark.cpp $(LINKER_OPT) 51 | ./exprtk_benchmark 52 | $(COMPILER) $(BASE_OPTIONS) -O3 -DNDEBUG -march=native -fprofile-use -o exprtk_benchmark exprtk_benchmark.cpp $(LINKER_OPT) 53 | 54 | clean: 55 | rm -f core.* *~ *.o *.bak *stackdump gmon.out *.gcda *.gcno *.gcnor *.gch 56 | -------------------------------------------------------------------------------- /exprtk_benchmark.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk vs Native Benchmarks * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | 26 | #include "exprtk.hpp" 27 | 28 | 29 | const std::string global_expression_list[] = 30 | { 31 | "(y + x)", 32 | "2 * (y + x)", 33 | "(2 * y + 2 * x)", 34 | "((1.23 * x^2) / y) - 123.123", 35 | "(y + x / y) * (x - y / x)", 36 | "x / ((x + y) + (x - y)) / y", 37 | "1 - ((x * y) + (y / x)) - 3", 38 | "(5.5 + x) + (2 * x - 2 / 3 * y) * (x / 3 + y / 4) + (y + 7.7)", 39 | "1.1x^1 + 2.2y^2 - 3.3x^3 + 4.4y^15 - 5.5x^23 + 6.6y^55", 40 | "sin(2 * x) + cos(pi / y)", 41 | "1 - sin(2 * x) + cos(pi / y)", 42 | "sqrt(111.111 - sin(2 * x) + cos(pi / y) / 333.333)", 43 | "(x^2 / sin(2 * pi / y)) - x / 2", 44 | "x + (cos(y - sin(2 / x * pi)) - sin(x - cos(2 * y / pi))) - y", 45 | "clamp(-1.0, sin(2 * pi * x) + cos(y / 2 * pi), +1.0)", 46 | "max(3.33, min(sqrt(1 - sin(2 * x) + cos(pi / y) / 3), 1.11))", 47 | "if((y + (x * 2.2)) <= (x + y + 1.1), x - y, x * y) + 2 * pi / x" 48 | }; 49 | 50 | const std::size_t global_expression_list_size = sizeof(global_expression_list) / sizeof(std::string); 51 | 52 | static const double global_lower_bound_x = -100.0; 53 | static const double global_lower_bound_y = -100.0; 54 | static const double global_upper_bound_x = +100.0; 55 | static const double global_upper_bound_y = +100.0; 56 | static const double global_delta = 0.0111; 57 | 58 | 59 | template class Sequence> 62 | bool load_expression(exprtk::symbol_table& symbol_table, 63 | Sequence,Allocator>& expr_seq) 64 | { 65 | exprtk::parser parser; 66 | 67 | for (std::size_t i = 0; i < global_expression_list_size; ++i) 68 | { 69 | exprtk::expression expression; 70 | expression.register_symbol_table(symbol_table); 71 | 72 | if (!parser.compile(global_expression_list[i],expression)) 73 | { 74 | printf("[load_expression] - Parser Error: %s\tExpression: %s\n", 75 | parser.error().c_str(), 76 | global_expression_list[i].c_str()); 77 | 78 | return false; 79 | } 80 | 81 | expr_seq.push_back(expression); 82 | } 83 | 84 | return true; 85 | } 86 | 87 | template 88 | void run_exprtk_benchmark(T& x, T& y, 89 | exprtk::expression& expression, 90 | const std::string& expr_string) 91 | { 92 | T total = T(0); 93 | unsigned int count = 0; 94 | 95 | exprtk::timer timer; 96 | timer.start(); 97 | 98 | for (x = global_lower_bound_x; x <= global_upper_bound_x; x += global_delta) 99 | { 100 | for (y = global_lower_bound_y; y <= global_upper_bound_y; y += global_delta) 101 | { 102 | total += expression.value(); 103 | ++count; 104 | } 105 | } 106 | 107 | timer.stop(); 108 | 109 | if (T(0) != total) 110 | printf("[exprtk] Total Time:%12.8f Rate:%14.3fevals/sec Expression: %s\n", 111 | timer.time(), 112 | count / timer.time(), 113 | expr_string.c_str()); 114 | else 115 | printf("run_exprtk_benchmark() - Error running benchmark for expression: %s\n",expr_string.c_str()); 116 | } 117 | 118 | template struct native; 119 | 120 | template 121 | void run_native_benchmark(T& x, T& y, NativeFunction f, const std::string& expr_string) 122 | { 123 | T total = T(0); 124 | unsigned int count = 0; 125 | 126 | exprtk::timer timer; 127 | timer.start(); 128 | 129 | for (x = global_lower_bound_x; x <= global_upper_bound_x; x += global_delta) 130 | { 131 | for (y = global_lower_bound_y; y <= global_upper_bound_y; y += global_delta) 132 | { 133 | total += f(x,y); 134 | ++count; 135 | } 136 | } 137 | 138 | timer.stop(); 139 | 140 | if (T(0) != total) 141 | printf("[native] Total Time:%12.8f Rate:%14.3fevals/sec Expression: %s\n", 142 | timer.time(), 143 | count / timer.time(), 144 | expr_string.c_str()); 145 | else 146 | printf("run_native_benchmark() - Error running benchmark for expression: %s\n",expr_string.c_str()); 147 | } 148 | 149 | template 150 | bool run_parse_benchmark(exprtk::symbol_table& symbol_table) 151 | { 152 | static const std::size_t rounds = 100000; 153 | exprtk::parser parser; 154 | exprtk::expression expression; 155 | 156 | expression.register_symbol_table(symbol_table); 157 | 158 | for (std::size_t i = 0; i < global_expression_list_size; ++i) 159 | { 160 | exprtk::timer timer; 161 | timer.start(); 162 | 163 | for (std::size_t r = 0; r < rounds; ++r) 164 | { 165 | if (!parser.compile(global_expression_list[i],expression)) 166 | { 167 | printf("[run_parse_benchmark] - Parser Error: %s\tExpression: %s\n", 168 | parser.error().c_str(), 169 | global_expression_list[i].c_str()); 170 | 171 | return false; 172 | } 173 | } 174 | 175 | timer.stop(); 176 | 177 | printf("[parse] Total Time:%12.8f Rate:%14.3fparse/sec Expression: %s\n", 178 | timer.time(), 179 | rounds / timer.time(), 180 | global_expression_list[i].c_str()); 181 | } 182 | 183 | return true; 184 | } 185 | 186 | const double pi = 3.141592653589793238462643383279502; 187 | 188 | template 189 | struct native 190 | { 191 | typedef typename exprtk::details::functor_t functor_t; 192 | typedef typename functor_t::Type Type; 193 | 194 | static inline T avg(Type x, Type y) 195 | { 196 | return (x + y) / T(2); 197 | } 198 | 199 | static inline T clamp(const Type l, const Type v, const Type u) 200 | { 201 | return ((v < l) ? l : ((v > u) ? u : v)); 202 | } 203 | 204 | static inline T func00(Type x, Type y) 205 | { 206 | return (y + x); 207 | } 208 | 209 | static inline T func01(Type x, Type y) 210 | { 211 | return T(2) * (y + x); 212 | } 213 | 214 | static inline T func02(Type x, Type y) 215 | { 216 | return (T(2) * y + T(2) * x); 217 | } 218 | 219 | static inline T func03(Type x, Type y) 220 | { 221 | return ((T(1.23) * (x * x)) / y) - T(123.123); 222 | } 223 | 224 | static inline T func04(Type x, Type y) 225 | { 226 | return (y + x / y) * (x - y / x); 227 | } 228 | 229 | static inline T func05(Type x, Type y) 230 | { 231 | return x / ((x + y) + (x - y)) / y; 232 | } 233 | 234 | static inline T func06(Type x, Type y) 235 | { 236 | return T(1) - ((x * y) + (y / x)) - T(3); 237 | } 238 | 239 | static inline T func07(Type x, Type y) 240 | { 241 | return (T(5.5) + x) + (T(2) * x - T(2) / T(3) * y) * (x / T(3) + y / T(4)) + (y + T(7.7)); 242 | } 243 | 244 | static inline T func08(Type x, Type y) 245 | { 246 | using namespace std; 247 | return (T(1.1)*pow(x,T(1))+T(2.2)*pow(y,T(2))-T(3.3)*pow(x,T(3))+T(4.4)*pow(y,T(15))-T(5.5)*pow(x,T(23))+T(6.6)*pow(y,T(55))); 248 | } 249 | 250 | static inline T func09(Type x, Type y) 251 | { 252 | return std::sin(T(2) * x) + std::cos(pi / y); 253 | } 254 | 255 | static inline T func10(Type x, Type y) 256 | { 257 | return T(1) - std::sin(T(2) * x) + std::cos(pi / y); 258 | } 259 | 260 | static inline T func11(Type x, Type y) 261 | { 262 | return std::sqrt(T(111.111) - std::sin(T(2) * x) + std::cos(pi / y) / T(333.333)); 263 | } 264 | 265 | static inline T func12(Type x, Type y) 266 | { 267 | return ((x * x) / std::sin(T(2) * pi / y)) - x / T(2); 268 | } 269 | 270 | static inline T func13(Type x, Type y) 271 | { 272 | return (x + (std::cos(y - std::sin(T(2) / x * pi)) - std::sin(x - std::cos(T(2) * y / pi))) - y); 273 | } 274 | 275 | static inline T func14(Type x, Type y) 276 | { 277 | return clamp(T(-1), std::sin(T(2) * pi * x) + std::cos(y / T(2) * pi), + T(1)); 278 | } 279 | 280 | static inline T func15(Type x, Type y) 281 | { 282 | return std::max(T(3.33), std::min(sqrt(T(1) - std::sin(T(2) * x) + std::cos(pi / y) / T(3)), T(1.11))); 283 | } 284 | 285 | static inline T func16(Type x, Type y) 286 | { 287 | return (((y + (x * T(2.2))) <= (x + y + T(1.1))) ? x - y : x * y) + T(2) * pi / x; 288 | } 289 | }; 290 | 291 | double pgo_primer(); 292 | void perform_file_based_benchmark(const std::string& file_name, const std::size_t& rounds = 100000); 293 | 294 | int main(int argc, char* argv[]) 295 | { 296 | if (argc >= 2) 297 | { 298 | const std::string file_name = argv[1]; 299 | 300 | if (argc == 2) 301 | perform_file_based_benchmark(file_name); 302 | else 303 | perform_file_based_benchmark(file_name,atoi(argv[2])); 304 | 305 | return 0; 306 | } 307 | 308 | pgo_primer(); 309 | 310 | double x = 0; 311 | double y = 0; 312 | 313 | exprtk::symbol_table symbol_table; 314 | symbol_table.add_constants(); 315 | symbol_table.add_variable("x",x); 316 | symbol_table.add_variable("y",y); 317 | 318 | std::deque > compiled_expr_list; 319 | 320 | if (!load_expression(symbol_table,compiled_expr_list)) 321 | { 322 | return 1; 323 | } 324 | 325 | { 326 | printf("--- EXPRTK ---\n"); 327 | for (std::size_t i = 0; i < compiled_expr_list.size(); ++i) 328 | { 329 | run_exprtk_benchmark(x,y,compiled_expr_list[i],global_expression_list[i]); 330 | } 331 | } 332 | 333 | { 334 | printf("--- NATIVE ---\n"); 335 | run_native_benchmark(x, y, native::func00,global_expression_list[ 0]); 336 | run_native_benchmark(x, y, native::func01,global_expression_list[ 1]); 337 | run_native_benchmark(x, y, native::func02,global_expression_list[ 2]); 338 | run_native_benchmark(x, y, native::func03,global_expression_list[ 3]); 339 | run_native_benchmark(x, y, native::func04,global_expression_list[ 4]); 340 | run_native_benchmark(x, y, native::func05,global_expression_list[ 5]); 341 | run_native_benchmark(x, y, native::func06,global_expression_list[ 6]); 342 | run_native_benchmark(x, y, native::func07,global_expression_list[ 7]); 343 | run_native_benchmark(x, y, native::func08,global_expression_list[ 8]); 344 | run_native_benchmark(x, y, native::func09,global_expression_list[ 9]); 345 | run_native_benchmark(x, y, native::func10,global_expression_list[10]); 346 | run_native_benchmark(x, y, native::func11,global_expression_list[11]); 347 | run_native_benchmark(x, y, native::func12,global_expression_list[12]); 348 | run_native_benchmark(x, y, native::func13,global_expression_list[13]); 349 | run_native_benchmark(x, y, native::func14,global_expression_list[14]); 350 | run_native_benchmark(x, y, native::func15,global_expression_list[15]); 351 | run_native_benchmark(x, y, native::func16,global_expression_list[16]); 352 | } 353 | 354 | { 355 | printf("--- PARSE ----\n"); 356 | run_parse_benchmark(symbol_table); 357 | } 358 | 359 | return 0; 360 | } 361 | 362 | double pgo_primer() 363 | { 364 | static const double lower_bound_x = -50.0; 365 | static const double lower_bound_y = -50.0; 366 | static const double upper_bound_x = +50.0; 367 | static const double upper_bound_y = +50.0; 368 | static const double delta = 0.07; 369 | 370 | double total = 0.0; 371 | 372 | for (double x = lower_bound_x; x <= upper_bound_x; x += delta) 373 | { 374 | for (double y = lower_bound_y; y <= upper_bound_y; y += delta) 375 | { 376 | total += native::func00(x,y); 377 | total += native::func01(x,y); 378 | total += native::func02(x,y); 379 | total += native::func03(x,y); 380 | total += native::func04(x,y); 381 | total += native::func05(x,y); 382 | total += native::func06(x,y); 383 | total += native::func07(x,y); 384 | total += native::func08(x,y); 385 | total += native::func09(x,y); 386 | total += native::func10(x,y); 387 | total += native::func11(x,y); 388 | total += native::func12(x,y); 389 | total += native::func13(x,y); 390 | total += native::func14(x,y); 391 | total += native::func15(x,y); 392 | total += native::func16(x,y); 393 | } 394 | } 395 | 396 | return total; 397 | } 398 | 399 | inline std::size_t load_expression_file(const std::string& file_name, std::deque& expression_list) 400 | { 401 | std::ifstream stream(file_name.c_str()); 402 | 403 | if (!stream) return 0; 404 | 405 | std::string buffer; 406 | buffer.reserve(1024); 407 | std::size_t line_count = 0; 408 | 409 | while (std::getline(stream,buffer)) 410 | { 411 | if (buffer.empty()) 412 | continue; 413 | else if ('#' == buffer[0]) 414 | continue; 415 | 416 | ++line_count; 417 | expression_list.push_back(buffer); 418 | } 419 | 420 | return line_count; 421 | } 422 | 423 | void perform_file_based_benchmark(const std::string& file_name, const std::size_t& rounds) 424 | { 425 | std::deque expr_str_list; 426 | 427 | if (0 == load_expression_file(file_name,expr_str_list)) 428 | { 429 | printf("Failed to load any expressions from: %s\n", file_name.c_str()); 430 | return; 431 | } 432 | 433 | typedef exprtk::symbol_table symbol_table_t; 434 | typedef exprtk::expression expression_t; 435 | typedef exprtk::parser parser_t; 436 | 437 | std::deque expression_list; 438 | 439 | symbol_table_t symbol_table; 440 | 441 | double a = 1.1; 442 | double b = 2.2; 443 | double c = 3.3; 444 | double x = 2.123456; 445 | double y = 3.123456; 446 | double z = 4.123456; 447 | double w = 5.123456; 448 | 449 | exprtk::rtl::vecops::package vector_package; 450 | 451 | symbol_table.add_variable("a", a); 452 | symbol_table.add_variable("b", b); 453 | symbol_table.add_variable("c", c); 454 | 455 | symbol_table.add_variable("x", x); 456 | symbol_table.add_variable("y", y); 457 | symbol_table.add_variable("z", z); 458 | symbol_table.add_variable("w", w); 459 | 460 | exprtk::polynomial poly01; 461 | exprtk::polynomial poly02; 462 | exprtk::polynomial poly03; 463 | exprtk::polynomial poly04; 464 | exprtk::polynomial poly05; 465 | exprtk::polynomial poly06; 466 | exprtk::polynomial poly07; 467 | exprtk::polynomial poly08; 468 | exprtk::polynomial poly09; 469 | exprtk::polynomial poly10; 470 | exprtk::polynomial poly11; 471 | exprtk::polynomial poly12; 472 | 473 | symbol_table.add_function("poly01", poly01); 474 | symbol_table.add_function("poly02", poly02); 475 | symbol_table.add_function("poly03", poly03); 476 | symbol_table.add_function("poly04", poly04); 477 | symbol_table.add_function("poly05", poly05); 478 | symbol_table.add_function("poly06", poly06); 479 | symbol_table.add_function("poly07", poly07); 480 | symbol_table.add_function("poly08", poly08); 481 | symbol_table.add_function("poly09", poly09); 482 | symbol_table.add_function("poly10", poly10); 483 | symbol_table.add_function("poly11", poly11); 484 | symbol_table.add_function("poly12", poly12); 485 | 486 | symbol_table.add_package(vector_package); 487 | 488 | 489 | static double e = exprtk::details::numeric::constant::e; 490 | symbol_table.add_variable("e", e, true); 491 | 492 | symbol_table.add_constants(); 493 | 494 | { 495 | parser_t parser; 496 | 497 | for (std::size_t i = 0; i < expr_str_list.size(); ++i) 498 | { 499 | expression_t expression; 500 | expression.register_symbol_table(symbol_table); 501 | 502 | if (!parser.compile(expr_str_list[i],expression)) 503 | { 504 | printf("[perform_file_based_benchmark] - Parser Error: %s\tExpression: %s\n", 505 | parser.error().c_str(), 506 | expr_str_list[i].c_str()); 507 | 508 | return; 509 | } 510 | 511 | expression_list.push_back(expression); 512 | } 513 | } 514 | 515 | exprtk::timer total_timer; 516 | exprtk::timer timer; 517 | 518 | double single_eval_total_time = 0.0; 519 | 520 | total_timer.start(); 521 | 522 | for (std::size_t i = 0; i < expression_list.size(); ++i) 523 | { 524 | expression_t& expression = expression_list[i]; 525 | 526 | a = 1.1; 527 | b = 2.2; 528 | c = 3.3; 529 | x = 2.123456; 530 | y = 3.123456; 531 | z = 4.123456; 532 | w = 5.123456; 533 | 534 | timer.start(); 535 | double sum = 0.0; 536 | 537 | for (std::size_t r = 0; r < rounds; ++r) 538 | { 539 | sum += expression.value(); 540 | std::swap(a,b); 541 | std::swap(x,y); 542 | } 543 | 544 | timer.stop(); 545 | 546 | printf("Expression %3d of %3d %9.3f ns\t%10d ns\t(%30.10f) '%s'\n", 547 | static_cast(i + 1), 548 | static_cast(expression_list.size()), 549 | (timer.time() * 1000000000.0) / (1.0 * rounds), 550 | static_cast(timer.time() * 1000000000.0), 551 | sum, 552 | expr_str_list[i].c_str()); 553 | 554 | fflush(stdout); 555 | 556 | single_eval_total_time += (timer.time() * 1000000000.0) / (1.0 * rounds); 557 | } 558 | 559 | total_timer.stop(); 560 | 561 | printf("[*] Number Of Evals: %15.0f\n", 562 | rounds * (expression_list.size() * 1.0)); 563 | 564 | printf("[*] Total Time: %9.3fsec\n", 565 | total_timer.time()); 566 | 567 | printf("[*] Total Single Eval Time: %9.3fms\n", 568 | single_eval_total_time / 1000000.0); 569 | } 570 | -------------------------------------------------------------------------------- /exprtk_simple_example_01.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 01 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | 23 | #include "exprtk.hpp" 24 | 25 | 26 | template 27 | void trig_function() 28 | { 29 | typedef exprtk::symbol_table symbol_table_t; 30 | typedef exprtk::expression expression_t; 31 | typedef exprtk::parser parser_t; 32 | 33 | const std::string expression_string = 34 | "clamp(-1.0, sin(2 * pi * x) + cos(x / 2 * pi), +1.0)"; 35 | 36 | T x; 37 | 38 | symbol_table_t symbol_table; 39 | symbol_table.add_variable("x",x); 40 | symbol_table.add_constants(); 41 | 42 | expression_t expression; 43 | expression.register_symbol_table(symbol_table); 44 | 45 | parser_t parser; 46 | parser.compile(expression_string,expression); 47 | 48 | for (x = T(-5); x <= T(+5); x += T(0.001)) 49 | { 50 | const T y = expression.value(); 51 | printf("%19.15f\t%19.15f\n", x, y); 52 | } 53 | } 54 | 55 | int main() 56 | { 57 | trig_function(); 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /exprtk_simple_example_02.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 02 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | 23 | #include "exprtk.hpp" 24 | 25 | 26 | template 27 | void square_wave() 28 | { 29 | typedef exprtk::symbol_table symbol_table_t; 30 | typedef exprtk::expression expression_t; 31 | typedef exprtk::parser parser_t; 32 | 33 | const std::string expression_string = 34 | "a *(4 / pi) * " 35 | "((1 / 1) * sin( 2 * pi * f * t) + (1 / 3) * sin( 6 * pi * f * t) + " 36 | " (1 / 5) * sin(10 * pi * f * t) + (1 / 7) * sin(14 * pi * f * t) + " 37 | " (1 / 9) * sin(18 * pi * f * t) + (1 / 11) * sin(22 * pi * f * t) + " 38 | " (1 / 13) * sin(26 * pi * f * t) + (1 / 15) * sin(30 * pi * f * t) + " 39 | " (1 / 17) * sin(34 * pi * f * t) + (1 / 19) * sin(38 * pi * f * t) + " 40 | " (1 / 21) * sin(42 * pi * f * t) + (1 / 23) * sin(46 * pi * f * t) + " 41 | " (1 / 25) * sin(50 * pi * f * t) + (1 / 27) * sin(54 * pi * f * t)) "; 42 | 43 | static const T pi = T(3.141592653589793238462643383279502); 44 | 45 | const T f = pi / T(10); 46 | const T a = T(10); 47 | T t = T(0); 48 | 49 | symbol_table_t symbol_table; 50 | symbol_table.add_variable("t",t); 51 | symbol_table.add_constant("f",f); 52 | symbol_table.add_constant("a",a); 53 | symbol_table.add_constants(); 54 | 55 | expression_t expression; 56 | expression.register_symbol_table(symbol_table); 57 | 58 | parser_t parser; 59 | parser.compile(expression_string,expression); 60 | 61 | const T delta = (T(4) * pi) / T(1000); 62 | 63 | for (t = (T(-2) * pi); t <= (T(+2) * pi); t += delta) 64 | { 65 | const T result = expression.value(); 66 | printf("%19.15f\t%19.15f\n", t, result); 67 | } 68 | } 69 | 70 | int main() 71 | { 72 | square_wave(); 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /exprtk_simple_example_03.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 03 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | 23 | #include "exprtk.hpp" 24 | 25 | 26 | template 27 | void polynomial() 28 | { 29 | typedef exprtk::symbol_table symbol_table_t; 30 | typedef exprtk::expression expression_t; 31 | typedef exprtk::parser parser_t; 32 | 33 | const std::string expression_string = 34 | "25x^5 - 35x^4 - 15x^3 + 40x^2 - 15x + 1"; 35 | 36 | const T r0 = T(0); 37 | const T r1 = T(1); 38 | T x = T(0); 39 | 40 | symbol_table_t symbol_table; 41 | symbol_table.add_variable("x",x); 42 | 43 | expression_t expression; 44 | expression.register_symbol_table(symbol_table); 45 | 46 | parser_t parser; 47 | parser.compile(expression_string,expression); 48 | 49 | const T delta = T(1.0 / 100.0); 50 | 51 | for (x = r0; x <= r1; x += delta) 52 | { 53 | printf("%19.15f\t%19.15f\n", x, expression.value()); 54 | } 55 | } 56 | 57 | int main() 58 | { 59 | polynomial(); 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /exprtk_simple_example_04.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 04 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | 23 | #include "exprtk.hpp" 24 | 25 | 26 | template 27 | void fibonacci() 28 | { 29 | typedef exprtk::symbol_table symbol_table_t; 30 | typedef exprtk::expression expression_t; 31 | typedef exprtk::parser parser_t; 32 | typedef exprtk::function_compositor compositor_t; 33 | typedef typename compositor_t::function function_t; 34 | 35 | T x = T(0); 36 | 37 | compositor_t compositor; 38 | 39 | compositor.add( 40 | function_t("fibonacci") 41 | .var("x") 42 | .expression 43 | ( 44 | " switch " 45 | " { " 46 | " case x == 0 : 0; " 47 | " case x == 1 : 1; " 48 | " default : " 49 | " { " 50 | " var prev := 0; " 51 | " var curr := 1; " 52 | " while ((x -= 1) > 0) " 53 | " { " 54 | " var temp := prev; " 55 | " prev := curr; " 56 | " curr += temp; " 57 | " }; " 58 | " }; " 59 | " } " 60 | )); 61 | 62 | symbol_table_t& symbol_table = compositor.symbol_table(); 63 | symbol_table.add_constants(); 64 | symbol_table.add_variable("x",x); 65 | 66 | std::string expression_str = "fibonacci(x)"; 67 | 68 | expression_t expression; 69 | expression.register_symbol_table(symbol_table); 70 | 71 | parser_t parser; 72 | parser.compile(expression_str,expression); 73 | 74 | for (std::size_t i = 0; i < 40; ++i) 75 | { 76 | x = static_cast(i); 77 | 78 | const T result = expression.value(); 79 | 80 | printf("fibonacci(%3d) = %10.0f\n", 81 | static_cast(i), 82 | result); 83 | } 84 | } 85 | 86 | int main() 87 | { 88 | fibonacci(); 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /exprtk_simple_example_05.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 05 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | 23 | #include "exprtk.hpp" 24 | 25 | 26 | template 27 | struct myfunc : public exprtk::ifunction 28 | { 29 | using exprtk::ifunction::operator(); 30 | 31 | myfunc() 32 | : exprtk::ifunction(2) 33 | { exprtk::disable_has_side_effects(*this); } 34 | 35 | T operator()(const T& v1, const T& v2) 36 | { 37 | return T(1) + (v1 * v2) / T(3); 38 | } 39 | }; 40 | 41 | template 42 | T myotherfunc(T v0, T v1, T v2) 43 | { 44 | return std::abs(v0 - v1) * v2; 45 | } 46 | 47 | template 48 | void custom_function() 49 | { 50 | typedef exprtk::symbol_table symbol_table_t; 51 | typedef exprtk::expression expression_t; 52 | typedef exprtk::parser parser_t; 53 | 54 | const std::string expression_string = 55 | "myfunc(sin(x / pi), otherfunc(3 * y, x / 2, x * y))"; 56 | 57 | T x = T(1); 58 | T y = T(2); 59 | myfunc mf; 60 | 61 | symbol_table_t symbol_table; 62 | symbol_table.add_variable("x",x); 63 | symbol_table.add_variable("y",y); 64 | symbol_table.add_function("myfunc",mf); 65 | symbol_table.add_function("otherfunc",myotherfunc); 66 | symbol_table.add_constants(); 67 | 68 | expression_t expression; 69 | expression.register_symbol_table(symbol_table); 70 | 71 | parser_t parser; 72 | parser.compile(expression_string,expression); 73 | 74 | const T result = expression.value(); 75 | printf("Result: %10.5f\n",result); 76 | } 77 | 78 | int main() 79 | { 80 | custom_function(); 81 | return 0; 82 | } 83 | -------------------------------------------------------------------------------- /exprtk_simple_example_06.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 06 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | 23 | #include "exprtk.hpp" 24 | 25 | 26 | template 27 | void vector_function() 28 | { 29 | typedef exprtk::symbol_table symbol_table_t; 30 | typedef exprtk::expression expression_t; 31 | typedef exprtk::parser parser_t; 32 | 33 | const std::string expression_string = 34 | " for (var i := 0; i < min(x[], y[], z[]); i += 1) " 35 | " { " 36 | " z[i] := 3sin(x[i]) + 2log(y[i]); " 37 | " } "; 38 | 39 | T x[] = { T(1.1), T(2.2), T(3.3), T(4.4), T(5.5) }; 40 | T y[] = { T(1.1), T(2.2), T(3.3), T(4.4), T(5.5) }; 41 | T z[] = { T(0.0), T(0.0), T(0.0), T(0.0), T(0.0) }; 42 | 43 | symbol_table_t symbol_table; 44 | symbol_table.add_vector("x",x); 45 | symbol_table.add_vector("y",y); 46 | symbol_table.add_vector("z",z); 47 | 48 | expression_t expression; 49 | expression.register_symbol_table(symbol_table); 50 | 51 | parser_t parser; 52 | parser.compile(expression_string,expression); 53 | 54 | expression.value(); 55 | } 56 | 57 | int main() 58 | { 59 | vector_function(); 60 | return 0; 61 | } 62 | -------------------------------------------------------------------------------- /exprtk_simple_example_07.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 07 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | 23 | #include "exprtk.hpp" 24 | 25 | 26 | template 27 | void logic() 28 | { 29 | typedef exprtk::symbol_table symbol_table_t; 30 | typedef exprtk::expression expression_t; 31 | typedef exprtk::parser parser_t; 32 | 33 | const std::string expression_string = "not(A and B) or C"; 34 | 35 | symbol_table_t symbol_table; 36 | symbol_table.create_variable("A"); 37 | symbol_table.create_variable("B"); 38 | symbol_table.create_variable("C"); 39 | 40 | expression_t expression; 41 | expression.register_symbol_table(symbol_table); 42 | 43 | parser_t parser; 44 | parser.compile(expression_string,expression); 45 | 46 | printf(" # | A | B | C | %s\n" 47 | "---+---+---+---+-%s\n", 48 | expression_string.c_str(), 49 | std::string(expression_string.size(),'-').c_str()); 50 | 51 | for (int i = 0; i < 8; ++i) 52 | { 53 | symbol_table.get_variable("A")->ref() = T((i & 0x01) ? 1 : 0); 54 | symbol_table.get_variable("B")->ref() = T((i & 0x02) ? 1 : 0); 55 | symbol_table.get_variable("C")->ref() = T((i & 0x04) ? 1 : 0); 56 | 57 | const int result = static_cast(expression.value()); 58 | 59 | printf(" %d | %d | %d | %d | %d \n", 60 | i, 61 | static_cast(symbol_table.get_variable("A")->value()), 62 | static_cast(symbol_table.get_variable("B")->value()), 63 | static_cast(symbol_table.get_variable("C")->value()), 64 | result); 65 | } 66 | } 67 | 68 | int main() 69 | { 70 | logic(); 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /exprtk_simple_example_08.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 08 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | 23 | #include "exprtk.hpp" 24 | 25 | 26 | template 27 | void composite() 28 | { 29 | typedef exprtk::symbol_table symbol_table_t; 30 | typedef exprtk::expression expression_t; 31 | typedef exprtk::parser parser_t; 32 | typedef exprtk::parser_error::type err_t; 33 | typedef exprtk::function_compositor compositor_t; 34 | typedef typename compositor_t::function function_t; 35 | 36 | T x = T(1); 37 | T y = T(2); 38 | 39 | compositor_t compositor; 40 | 41 | symbol_table_t& symbol_table = compositor.symbol_table(); 42 | symbol_table.add_constants(); 43 | symbol_table.add_variable("x",x); 44 | symbol_table.add_variable("y",y); 45 | 46 | compositor.add( 47 | function_t("f") // f(x) = sin(x / pi) 48 | .var("x") 49 | .expression( "sin(x / pi)" )); 50 | 51 | compositor.add( 52 | function_t("g") // g(x,y) = 3[f(x) + f(y)] 53 | .vars("x", "y") 54 | .expression( "3*[f(x) + f(y)]" )); 55 | 56 | std::string expression_string = "g(1 + f(x), f(y) / 2)"; 57 | 58 | expression_t expression; 59 | expression.register_symbol_table(symbol_table); 60 | 61 | parser_t parser; 62 | 63 | if (!parser.compile(expression_string,expression)) 64 | { 65 | printf("Error: %s\tExpression: %s\n", 66 | parser.error().c_str(), 67 | expression_string.c_str()); 68 | 69 | for (std::size_t i = 0; i < parser.error_count(); ++i) 70 | { 71 | const err_t error = parser.get_error(i); 72 | 73 | printf("Error: %02d Position: %02d Type: [%14s] Msg: %s\tExpression: %s\n", 74 | static_cast(i), 75 | static_cast(error.token.position), 76 | exprtk::parser_error::to_str(error.mode).c_str(), 77 | error.diagnostic.c_str(), 78 | expression_string.c_str()); 79 | } 80 | 81 | return; 82 | } 83 | 84 | const T result = expression.value(); 85 | 86 | printf("%s = %e\n", expression_string.c_str(), result); 87 | } 88 | 89 | int main() 90 | { 91 | composite(); 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /exprtk_simple_example_09.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 09 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | 23 | #include "exprtk.hpp" 24 | 25 | 26 | template 27 | void primes() 28 | { 29 | typedef exprtk::symbol_table symbol_table_t; 30 | typedef exprtk::expression expression_t; 31 | typedef exprtk::parser parser_t; 32 | typedef exprtk::function_compositor compositor_t; 33 | typedef typename compositor_t::function function_t; 34 | 35 | T x = T(0); 36 | 37 | symbol_table_t symbol_table; 38 | 39 | symbol_table.add_constants(); 40 | symbol_table.add_variable("x",x); 41 | 42 | compositor_t compositor(symbol_table); 43 | 44 | //Mode 1 - if statement based 45 | compositor.add( 46 | function_t("is_prime_impl1") 47 | .vars("x", "y") 48 | .expression 49 | ( 50 | " if (y == 1,true, " 51 | " if (0 == (x % y),false, " 52 | " is_prime_impl1(x,y - 1))) " 53 | )); 54 | 55 | compositor.add( 56 | function_t("is_prime1") 57 | .var("x") 58 | .expression 59 | ( 60 | " if (frac(x) != 0) " 61 | " return [false]; " 62 | " else if (x <= 0) " 63 | " return [false]; " 64 | " else " 65 | " is_prime_impl1(x,min(x - 1,trunc(sqrt(x)) + 1)); " 66 | )); 67 | 68 | //Mode 2 - switch statement based 69 | compositor.add( 70 | function_t("is_prime_impl2") 71 | .vars("x", "y") 72 | .expression 73 | ( 74 | " switch " 75 | " { " 76 | " case y == 1 : true; " 77 | " case (x % y) == 0 : false; " 78 | " default : is_prime_impl2(x,y - 1); " 79 | " } " 80 | )); 81 | 82 | compositor.add( 83 | function_t("is_prime2") 84 | .var("x") 85 | .expression 86 | ( 87 | " switch " 88 | " { " 89 | " case x <= 0 : false; " 90 | " case frac(x) != 0 : false; " 91 | " default : is_prime_impl2(x,min(x - 1,trunc(sqrt(x)) + 1)); " 92 | " } " 93 | )); 94 | 95 | //Mode 3 - switch statement and for-loop based 96 | compositor.add( 97 | function_t("is_prime3") 98 | .var("x") 99 | .expression 100 | ( 101 | " switch " 102 | " { " 103 | " case x <= 1 : return [false]; " 104 | " case frac(x) != 0 : return [false]; " 105 | " case x == 2 : return [true ]; " 106 | " }; " 107 | " " 108 | " var prime_lut[27] := " 109 | " { " 110 | " 2, 3, 5, 7, 11, 13, 17, 19, 23, " 111 | " 29, 31, 37, 41, 43, 47, 53, 59, 61, " 112 | " 67, 71, 73, 79, 83, 89, 97, 101, 103 " 113 | " }; " 114 | " " 115 | " var upper_bound := min(x - 1, trunc(sqrt(x)) + 1); " 116 | " " 117 | " for (var i := 0; i < prime_lut[]; i += 1) " 118 | " { " 119 | " if (prime_lut[i] >= upper_bound) " 120 | " return [true]; " 121 | " else if ((x % prime_lut[i]) == 0) " 122 | " return [false]; " 123 | " }; " 124 | " " 125 | " var lower_bound := prime_lut[prime_lut[] - 1] + 2; " 126 | " " 127 | " for (var i := lower_bound; i < upper_bound; i += 2) " 128 | " { " 129 | " if ((x % i) == 0) " 130 | " { " 131 | " return [false]; " 132 | " } " 133 | " }; " 134 | " " 135 | " return [true]; " 136 | )); 137 | 138 | std::string expression_str1 = "is_prime1(x)"; 139 | std::string expression_str2 = "is_prime2(x)"; 140 | std::string expression_str3 = "is_prime3(x)"; 141 | 142 | expression_t expression1; 143 | expression_t expression2; 144 | expression_t expression3; 145 | expression1.register_symbol_table(symbol_table); 146 | expression2.register_symbol_table(symbol_table); 147 | expression3.register_symbol_table(symbol_table); 148 | 149 | parser_t parser; 150 | 151 | parser.compile(expression_str1, expression1); 152 | parser.compile(expression_str2, expression2); 153 | parser.compile(expression_str3, expression3); 154 | 155 | for (std::size_t i = 0; i < 15000; ++i) 156 | { 157 | x = static_cast(i); 158 | 159 | const T result1 = expression1.value(); 160 | const T result2 = expression2.value(); 161 | const T result3 = expression3.value(); 162 | 163 | const bool results_concur = (result1 == result2) && 164 | (result1 == result3) ; 165 | 166 | printf("%03d Result1: %c Result2: %c Result3: %c " 167 | "Results Concur: %c\n", 168 | static_cast(i), 169 | (result1 == T(1)) ? 'T' : 'F', 170 | (result2 == T(1)) ? 'T' : 'F', 171 | (result3 == T(1)) ? 'T' : 'F', 172 | (results_concur) ? 'T' : 'F'); 173 | } 174 | } 175 | 176 | int main() 177 | { 178 | primes(); 179 | return 0; 180 | } 181 | -------------------------------------------------------------------------------- /exprtk_simple_example_10.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 10 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "exprtk.hpp" 25 | 26 | 27 | template 28 | void newton_sqrt() 29 | { 30 | typedef exprtk::symbol_table symbol_table_t; 31 | typedef exprtk::expression expression_t; 32 | typedef exprtk::parser parser_t; 33 | typedef exprtk::function_compositor compositor_t; 34 | typedef typename compositor_t::function function_t; 35 | 36 | T x = T(0); 37 | 38 | symbol_table_t symbol_table; 39 | 40 | symbol_table.add_constants(); 41 | symbol_table.add_variable("x",x); 42 | 43 | compositor_t compositor(symbol_table); 44 | 45 | compositor.add( 46 | function_t("newton_sqrt") 47 | .var("x") 48 | .expression 49 | ( 50 | " switch " 51 | " { " 52 | " case x < 0 : null; " 53 | " case x == 0 : 0; " 54 | " case x == 1 : 1; " 55 | " default: " 56 | " { " 57 | " var remaining_itrs := 100; " 58 | " var sqrt_x := x / 2; " 59 | " repeat " 60 | " if (equal(sqrt_x * sqrt_x, x)) " 61 | " break[sqrt_x]; " 62 | " else " 63 | " sqrt_x := (1 / 2) * (sqrt_x + (x / sqrt_x)); " 64 | " until ((remaining_itrs -= 1) <= 0); " 65 | " }; " 66 | " } " 67 | )); 68 | 69 | const std::string expression_str = "newton_sqrt(x)"; 70 | 71 | expression_t expression; 72 | expression.register_symbol_table(symbol_table); 73 | 74 | parser_t parser; 75 | parser.compile(expression_str,expression); 76 | 77 | for (x = T(0); x < T(500); x += T(0.5)) 78 | { 79 | const T result = expression.value(); 80 | const T real = std::sqrt(x); 81 | const T error = std::abs(result - real); 82 | 83 | const bool err_in_bound = error <= exprtk::details::numeric::constant::pi; 84 | 85 | printf("sqrt(%6.2f) - Result: %15.13f\tReal: %15.13f\tError: %18.16f EIB: %c\n", 86 | x, 87 | result, 88 | real, 89 | error, 90 | err_in_bound ? 'T' : 'F'); 91 | } 92 | } 93 | 94 | int main() 95 | { 96 | newton_sqrt(); 97 | return 0; 98 | } 99 | -------------------------------------------------------------------------------- /exprtk_simple_example_11.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 11 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | 23 | #include "exprtk.hpp" 24 | 25 | 26 | template 27 | void square_wave2() 28 | { 29 | typedef exprtk::symbol_table symbol_table_t; 30 | typedef exprtk::expression expression_t; 31 | typedef exprtk::parser parser_t; 32 | 33 | const std::string wave_program = 34 | " var r := 0; " 35 | " " 36 | " for (var i := 0; i < 1000; i += 1) " 37 | " { " 38 | " r += (1 / (2i + 1)) * sin((4i + 2) * pi * f * t); " 39 | " }; " 40 | " " 41 | " r *= a * (4 / pi); "; 42 | 43 | static const T pi = T(3.141592653589793238462643383279502); 44 | 45 | T f = pi / T(10); 46 | T t = T(0); 47 | T a = T(10); 48 | 49 | symbol_table_t symbol_table; 50 | symbol_table.add_variable("f",f); 51 | symbol_table.add_variable("t",t); 52 | symbol_table.add_variable("a",a); 53 | symbol_table.add_constants(); 54 | 55 | expression_t expression; 56 | expression.register_symbol_table(symbol_table); 57 | 58 | parser_t parser; 59 | parser.compile(wave_program,expression); 60 | 61 | const T delta = (T(4) * pi) / T(1000); 62 | 63 | for (t = (T(-2) * pi); t <= (T(+2) * pi); t += delta) 64 | { 65 | const T result = expression.value(); 66 | printf("%19.15f\t%19.15f\n", t, result); 67 | } 68 | } 69 | 70 | int main() 71 | { 72 | square_wave2(); 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /exprtk_simple_example_12.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 12 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | 22 | #include "exprtk.hpp" 23 | 24 | 25 | template 26 | void bubble_sort() 27 | { 28 | typedef exprtk::symbol_table symbol_table_t; 29 | typedef exprtk::expression expression_t; 30 | typedef exprtk::parser parser_t; 31 | 32 | const std::string bubblesort_program = 33 | " var upper_bound := v[]; " 34 | " " 35 | " repeat " 36 | " var new_upper_bound := 0; " 37 | " " 38 | " for (var i := 1; i < upper_bound; i += 1) " 39 | " { " 40 | " if (v[i - 1] > v[i]) " 41 | " { " 42 | " v[i - 1] <=> v[i]; " 43 | " new_upper_bound := i; " 44 | " }; " 45 | " }; " 46 | " " 47 | " upper_bound := new_upper_bound; " 48 | " " 49 | " until (upper_bound <= 1); "; 50 | 51 | T v[] = { T(9.1), T(2.2), T(1.3), T(5.4), T(7.5), T(4.6), T(3.7) }; 52 | 53 | symbol_table_t symbol_table; 54 | symbol_table.add_vector("v",v); 55 | 56 | expression_t expression; 57 | expression.register_symbol_table(symbol_table); 58 | 59 | parser_t parser; 60 | parser.compile(bubblesort_program,expression); 61 | 62 | expression.value(); 63 | } 64 | 65 | int main() 66 | { 67 | bubble_sort(); 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /exprtk_simple_example_13.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 13 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "exprtk.hpp" 26 | 27 | 28 | template 29 | void savitzky_golay_filter() 30 | { 31 | typedef exprtk::symbol_table symbol_table_t; 32 | typedef exprtk::expression expression_t; 33 | typedef exprtk::parser parser_t; 34 | 35 | const std::string sgfilter_program = 36 | " var weight[9] := " 37 | " { " 38 | " -21, 14, 39, " 39 | " 54, 59, 54, " 40 | " 39, 14, -21 " 41 | " }; " 42 | " " 43 | " if (v_in[] >= weight[]) " 44 | " { " 45 | " const var lower_bound := trunc(weight[] / 2); " 46 | " const var upper_bound := v_in[] - lower_bound; " 47 | " " 48 | " v_out := 0; " 49 | " " 50 | " for (var i := lower_bound; i < upper_bound; i += 1) " 51 | " { " 52 | " for (var j := -lower_bound; j <= lower_bound; j += 1) " 53 | " { " 54 | " v_out[i] += weight[j + lower_bound] * v_in[i + j]; " 55 | " }; " 56 | " }; " 57 | " " 58 | " v_out /= sum(weight); " 59 | " } "; 60 | 61 | const std::size_t n = 1024; 62 | 63 | std::vector v_in; 64 | std::vector v_out; 65 | 66 | const T pi = T(3.141592653589793238462643383279502); 67 | 68 | srand(static_cast(time(0))); 69 | 70 | // Generate a signal with noise. 71 | for (T t = T(-5); t <= T(+5); t += T(10.0 / n)) 72 | { 73 | const T noise = T(0.5 * (rand() / (RAND_MAX + 1.0) - 0.5)); 74 | v_in.push_back(sin(2.0 * pi * t) + noise); 75 | } 76 | 77 | v_out.resize(v_in.size()); 78 | 79 | symbol_table_t symbol_table; 80 | symbol_table.add_vector("v_in" , v_in ); 81 | symbol_table.add_vector("v_out", v_out); 82 | 83 | expression_t expression; 84 | expression.register_symbol_table(symbol_table); 85 | 86 | parser_t parser; 87 | parser.compile(sgfilter_program,expression); 88 | 89 | expression.value(); 90 | 91 | for (std::size_t i = 0; i < v_out.size(); ++i) 92 | { 93 | printf("%10.6f\t%10.6f\n", v_in[i], v_out[i]); 94 | } 95 | } 96 | 97 | int main() 98 | { 99 | savitzky_golay_filter(); 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /exprtk_simple_example_14.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 14 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | 23 | #include "exprtk.hpp" 24 | 25 | 26 | template 27 | void stddev_example() 28 | { 29 | typedef exprtk::expression expression_t; 30 | typedef exprtk::parser parser_t; 31 | 32 | const std::string stddev_program = 33 | " var x[25] := { " 34 | " 1, 2, 3, 4, 5, " 35 | " 6, 7, 8, 9, 10, " 36 | " 11, 12, 13, 14, 15, " 37 | " 16, 17, 18, 19, 20, " 38 | " 21, 22, 23, 24, 25 " 39 | " }; " 40 | " " 41 | " sqrt(sum([x - avg(x)]^2) / x[]) "; 42 | 43 | expression_t expression; 44 | 45 | parser_t parser; 46 | parser.compile(stddev_program,expression); 47 | 48 | const T stddev = expression.value(); 49 | 50 | printf("stddev(1..25) = %10.6f\n",stddev); 51 | } 52 | 53 | int main() 54 | { 55 | stddev_example(); 56 | return 0; 57 | } 58 | -------------------------------------------------------------------------------- /exprtk_simple_example_15.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 15 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | 23 | #include "exprtk.hpp" 24 | 25 | 26 | template 27 | void black_scholes_merton_model() 28 | { 29 | typedef exprtk::symbol_table symbol_table_t; 30 | typedef exprtk::expression expression_t; 31 | typedef exprtk::parser parser_t; 32 | 33 | const std::string bsm_model_program = 34 | " var d1 := (log(s / k) + (r + v^2 / 2) * t) / (v * sqrt(t)); " 35 | " var d2 := d1 - v * sqrt(t); " 36 | " " 37 | " if (callput_flag == 'call') " 38 | " s * ncdf(d1) - k * e^(-r * t) * ncdf(d2); " 39 | " else if (callput_flag == 'put') " 40 | " k * e^(-r * t) * ncdf(-d2) - s * ncdf(-d1); " 41 | " "; 42 | 43 | T s = T(60.00); // Spot / Stock / Underlying / Base price 44 | T k = T(65.00); // Strike price 45 | T v = T( 0.30); // Volatility 46 | T t = T( 0.25); // Years to maturity 47 | T r = T( 0.08); // Risk free rate 48 | 49 | std::string callput_flag; 50 | 51 | static const T e = exprtk::details::numeric::constant::e; 52 | 53 | symbol_table_t symbol_table; 54 | symbol_table.add_variable("s",s); 55 | symbol_table.add_variable("k",k); 56 | symbol_table.add_variable("t",t); 57 | symbol_table.add_variable("r",r); 58 | symbol_table.add_variable("v",v); 59 | symbol_table.add_constant("e",e); 60 | symbol_table.add_stringvar("callput_flag",callput_flag); 61 | 62 | expression_t expression; 63 | expression.register_symbol_table(symbol_table); 64 | 65 | parser_t parser; 66 | parser.compile(bsm_model_program,expression); 67 | 68 | callput_flag = "call"; 69 | 70 | const T bsm_call_option_price = expression.value(); 71 | 72 | callput_flag = "put"; 73 | 74 | const T bsm_put_option_price = expression.value(); 75 | 76 | printf("BSM(call, %5.3f, %5.3f, %5.3f, %5.3f, %5.3f) = %10.6f\n", 77 | s, k, t, r, v, 78 | bsm_call_option_price); 79 | 80 | printf("BSM(put , %5.3f, %5.3f, %5.3f, %5.3f, %5.3f) = %10.6f\n", 81 | s, k, t, r, v, 82 | bsm_put_option_price); 83 | 84 | const T put_call_parity_diff = 85 | (bsm_call_option_price - bsm_put_option_price) - 86 | (s - k * std::exp(-r * t)); 87 | 88 | printf("Put-Call parity difference: %20.17f\n", put_call_parity_diff); 89 | } 90 | 91 | int main() 92 | { 93 | black_scholes_merton_model(); 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /exprtk_simple_example_16.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 16 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | #include 23 | 24 | #include "exprtk.hpp" 25 | 26 | 27 | template 28 | void linear_least_squares() 29 | { 30 | typedef exprtk::symbol_table symbol_table_t; 31 | typedef exprtk::expression expression_t; 32 | typedef exprtk::parser parser_t; 33 | 34 | const std::string linear_least_squares_program = 35 | " if (x[] == y[]) " 36 | " { " 37 | " var mean_x := avg(x); " 38 | " var mean_y := avg(y); " 39 | " " 40 | " beta := sum((x - mean_x) * (y - mean_y)) / " 41 | " sum((x - mean_x)^2); " 42 | " " 43 | " alpha := mean_y - beta * mean_x; " 44 | " " 45 | " rmse := sqrt(sum((beta * x + alpha - y)^2) / y[]); " 46 | " } " 47 | " else " 48 | " { " 49 | " alpha := null; " 50 | " beta := null; " 51 | " rmse := null; " 52 | " } "; 53 | 54 | T x[] = { T(1.0), T(2.0), T(3.0), T(4.0), T(5.0), T(6.0), T(7.0), T(8.0), T(9.0), T(10) }; 55 | T y[] = { T(8.7), T(6.8), T(6.0), T(5.6), T(3.8), T(3.0), T(2.4), T(1.7), T(0.4), T(-1) }; 56 | 57 | T alpha = T(0); 58 | T beta = T(0); 59 | T rmse = T(0); 60 | 61 | symbol_table_t symbol_table; 62 | symbol_table.add_variable("alpha", alpha); 63 | symbol_table.add_variable("beta" , beta ); 64 | symbol_table.add_variable("rmse" , rmse ); 65 | symbol_table.add_vector ("x" , x ); 66 | symbol_table.add_vector ("y" , y ); 67 | 68 | expression_t expression; 69 | expression.register_symbol_table(symbol_table); 70 | 71 | parser_t parser; 72 | if (!parser.compile(linear_least_squares_program,expression)) 73 | { 74 | printf("error: %s\n",parser.error().c_str()); 75 | return; 76 | } 77 | 78 | expression.value(); 79 | 80 | printf("alpha: %15.12f\n", alpha); 81 | printf("beta: %15.12f\n", beta ); 82 | printf("rmse: %15.12f\n", rmse ); 83 | printf("y = %15.12fx + %15.12f\n", beta, alpha); 84 | } 85 | 86 | int main() 87 | { 88 | linear_least_squares(); 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /exprtk_simple_example_17.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 17 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "exprtk.hpp" 26 | 27 | 28 | template 29 | struct rnd_01 : public exprtk::ifunction 30 | { 31 | using exprtk::ifunction::operator(); 32 | 33 | rnd_01() : exprtk::ifunction(0) 34 | { ::srand(static_cast(time(NULL))); } 35 | 36 | inline T operator()() 37 | { 38 | // Note: Do not use this in production 39 | // Result is in the interval [0,1) 40 | return T(::rand() / T(RAND_MAX + 1.0)); 41 | } 42 | }; 43 | 44 | template 45 | void monte_carlo_pi() 46 | { 47 | typedef exprtk::symbol_table symbol_table_t; 48 | typedef exprtk::expression expression_t; 49 | typedef exprtk::parser parser_t; 50 | 51 | const std::string monte_carlo_pi_program = 52 | " var samples[2 * 10^8] := [(rnd_01^2 + rnd_01^2) <= 1]; " 53 | " 4 * sum(samples) / samples[]; "; 54 | 55 | rnd_01 rnd01; 56 | 57 | symbol_table_t symbol_table; 58 | symbol_table.add_function("rnd_01",rnd01); 59 | 60 | expression_t expression; 61 | expression.register_symbol_table(symbol_table); 62 | 63 | parser_t parser; 64 | parser.compile(monte_carlo_pi_program,expression); 65 | 66 | const T approximate_pi = expression.value(); 67 | 68 | const T real_pi = T(3.141592653589793238462643383279502); // or close enough... 69 | 70 | printf("pi ~ %20.17f\terror: %20.17f\n", 71 | approximate_pi, 72 | std::abs(real_pi - approximate_pi)); 73 | } 74 | 75 | int main() 76 | { 77 | monte_carlo_pi(); 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /exprtk_simple_example_18.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 18 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | 23 | #include "exprtk.hpp" 24 | 25 | 26 | template 27 | void file_io() 28 | { 29 | typedef exprtk::symbol_table symbol_table_t; 30 | typedef exprtk::expression expression_t; 31 | typedef exprtk::parser parser_t; 32 | 33 | const std::string fileio_program = 34 | " var file_name := 'file.txt'; " 35 | " var stream := null; " 36 | " " 37 | " if (stream := open(file_name,'w')) " 38 | " println('Successfully opened file: ' + file_name); " 39 | " else " 40 | " { " 41 | " println('Failed to open file: ' + file_name); " 42 | " return [false]; " 43 | " }; " 44 | " " 45 | " var s := 'Hello world...\n'; " 46 | " " 47 | " for (var i := 0; i < 10; i += 1) " 48 | " { " 49 | " write(stream,s); " 50 | " }; " 51 | " " 52 | " if (close(stream)) " 53 | " println('Sucessfully closed file: ' + file_name); " 54 | " else " 55 | " { " 56 | " println('Failed to close file: ' + file_name); " 57 | " return [false]; " 58 | " } "; 59 | 60 | exprtk::rtl::io::file::package fileio_package; 61 | exprtk::rtl::io::println println; 62 | 63 | symbol_table_t symbol_table; 64 | symbol_table.add_function("println",println); 65 | symbol_table.add_package (fileio_package ); 66 | 67 | expression_t expression; 68 | expression.register_symbol_table(symbol_table); 69 | 70 | parser_t parser; 71 | parser.compile(fileio_program,expression); 72 | 73 | printf("Result %10.3f\n",expression.value()); 74 | } 75 | 76 | int main() 77 | { 78 | file_io(); 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /exprtk_simple_example_19.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 19 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "exprtk.hpp" 26 | 27 | 28 | template 29 | class randu : public exprtk::igeneric_function 30 | { 31 | public: 32 | 33 | typedef typename exprtk::igeneric_function igfun_t; 34 | typedef typename igfun_t::parameter_list_t parameter_list_t; 35 | typedef typename igfun_t::generic_type generic_type; 36 | typedef typename generic_type::vector_view vector_t; 37 | 38 | using exprtk::igeneric_function::operator(); 39 | 40 | randu() 41 | : exprtk::igeneric_function("V|VTT") 42 | /* 43 | Overloads: 44 | 0. V - vector 45 | 1. VTT - vector, r0, r1 46 | */ 47 | { ::srand(static_cast(time(NULL))); } 48 | 49 | inline T operator()(const std::size_t& ps_index, parameter_list_t parameters) 50 | { 51 | vector_t v(parameters[0]); 52 | 53 | std::size_t r0 = 0; 54 | std::size_t r1 = v.size() - 1; 55 | 56 | using namespace exprtk::rtl::vecops::helper; 57 | 58 | if ( 59 | (1 == ps_index) && 60 | !load_vector_range::process(parameters, r0, r1, 1, 2, 0) 61 | ) 62 | return T(0); 63 | 64 | for (std::size_t i = r0; i <= r1; ++i) 65 | { 66 | v[i] = rnd(); 67 | } 68 | 69 | return T(1); 70 | } 71 | 72 | private: 73 | 74 | inline T rnd() 75 | { 76 | // Note: Do not use this in production 77 | // Result is in the interval [0,1) 78 | return T(::rand() / T(RAND_MAX + 1.0)); 79 | } 80 | }; 81 | 82 | template 83 | void vector_randu() 84 | { 85 | typedef exprtk::symbol_table symbol_table_t; 86 | typedef exprtk::expression expression_t; 87 | typedef exprtk::parser parser_t; 88 | 89 | const std::string vecrandu_program = 90 | " var noise[6] := [0]; " 91 | " " 92 | " if (randu(noise, 0, 5) == false) " 93 | " { " 94 | " println('Failed to generate noise'); " 95 | " return [false]; " 96 | " }; " 97 | " " 98 | " var noisy[noise[]] := signal + (noise - 1/2); " 99 | " " 100 | " for (var i := 0; i < noisy[]; i += 1) " 101 | " { " 102 | " println('noisy[',i,'] = ', noisy[i]); " 103 | " }; " 104 | " " 105 | " println('avg: ', avg(noisy)); " 106 | " "; 107 | 108 | T signal[] = { T(1.1), T(2.2), T(3.3), T(4.4), T(5.5), T(6.6), T(7.7) }; 109 | 110 | exprtk::rtl::io::println println; 111 | randu randu; 112 | 113 | symbol_table_t symbol_table; 114 | symbol_table.add_vector ("signal" , signal ); 115 | symbol_table.add_function("println", println); 116 | symbol_table.add_function("randu" , randu ); 117 | 118 | expression_t expression; 119 | expression.register_symbol_table(symbol_table); 120 | 121 | parser_t parser; 122 | parser.compile(vecrandu_program,expression); 123 | 124 | expression.value(); 125 | } 126 | 127 | int main() 128 | { 129 | vector_randu(); 130 | return 0; 131 | } 132 | -------------------------------------------------------------------------------- /exprtk_simple_example_20.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 20 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | #include 23 | #include 24 | 25 | #include "exprtk.hpp" 26 | 27 | 28 | struct vector_access_rtc : public exprtk::vector_access_runtime_check 29 | { 30 | typedef std::map map_t; 31 | map_t vector_map; 32 | 33 | bool handle_runtime_violation(violation_context& context) 34 | { 35 | const map_t::iterator itr = vector_map.find(static_cast(context.base_ptr)); 36 | const std::string vector_name = (itr != vector_map.end()) ? 37 | itr->second : "Unknown" ; 38 | 39 | printf("Runtime vector access violation\n" 40 | "Vector: %s base: %p end: %p access: %p typesize: %d\n", 41 | vector_name.c_str(), 42 | context.base_ptr , 43 | context.end_ptr , 44 | context.access_ptr , 45 | static_cast(context.type_size)); 46 | 47 | throw std::runtime_error 48 | ("Runtime vector access violation. Vector: " + vector_name); 49 | 50 | return false; 51 | } 52 | }; 53 | 54 | template 55 | void vector_overflow_example() 56 | { 57 | typedef exprtk::symbol_table symbol_table_t; 58 | typedef exprtk::expression expression_t; 59 | typedef exprtk::parser parser_t; 60 | 61 | const std::string expression_str = 62 | " for (var i := 0; i < max(v0[],v1[]); i += 1) " 63 | " { " 64 | " v0[i] := (2 * v0[i]) + (v1[i] / 3); " 65 | " } "; 66 | 67 | T v0[5 ] = { 0, 1, 2, 3, 4 }; 68 | T v1[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; 69 | 70 | vector_access_rtc vec_rtc; 71 | 72 | vec_rtc.vector_map[v0] = "v0"; 73 | vec_rtc.vector_map[v1] = "v1"; 74 | 75 | symbol_table_t symbol_table; 76 | expression_t expression; 77 | parser_t parser; 78 | 79 | symbol_table.add_vector("v0", v0); 80 | symbol_table.add_vector("v1", v1); 81 | 82 | expression.register_symbol_table(symbol_table); 83 | 84 | parser.register_vector_access_runtime_check(vec_rtc); 85 | 86 | if (!parser.compile(expression_str, expression)) 87 | { 88 | printf("Error: %s\tExpression: %s\n", 89 | parser.error().c_str(), 90 | expression_str.c_str()); 91 | 92 | return; 93 | } 94 | 95 | try 96 | { 97 | expression.value(); 98 | } 99 | catch(std::runtime_error& exception) 100 | { 101 | printf("Exception: %s\n",exception.what()); 102 | } 103 | } 104 | 105 | int main() 106 | { 107 | vector_overflow_example(); 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /exprtk_simple_example_21.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 21 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | 23 | #include "exprtk.hpp" 24 | 25 | 26 | template 27 | void binomial_option_pricing_model() 28 | { 29 | typedef exprtk::symbol_table symbol_table_t; 30 | typedef exprtk::expression expression_t; 31 | typedef exprtk::parser parser_t; 32 | 33 | const std::string european_option_binomial_model_program = 34 | " var dt := t / n; " 35 | " var z := exp(r * dt); " 36 | " var z_inv := 1 / z; " 37 | " var u := exp(v * sqrt(dt)); " 38 | " var p_up := (z * u - 1) / (u^2 - 1); " 39 | " var p_down := 1 - p_up; " 40 | " " 41 | " var option_price[n + 1] := [0]; " 42 | " " 43 | " for (var i := 0; i <= n; i += 1) " 44 | " { " 45 | " var base_price := s * u^(n - 2i); " 46 | " " 47 | " option_price[i] := " 48 | " switch " 49 | " { " 50 | " case callput_flag == 'call' : max(base_price - k, 0); " 51 | " case callput_flag == 'put' : max(k - base_price, 0); " 52 | " }; " 53 | " }; " 54 | " " 55 | " for (var j := n - 1; j >= 0; j -= 1) " 56 | " { " 57 | " for (var i := 0; i <= j; i += 1) " 58 | " { " 59 | " option_price[i] := z_inv * " 60 | " (p_up * option_price[i] + p_down * option_price[i + 1]); " 61 | " } " 62 | " }; " 63 | " " 64 | " option_price[0]; "; 65 | 66 | T s = T( 100.00); // Spot / Stock / Underlying / Base price 67 | T k = T( 110.00); // Strike price 68 | T v = T( 0.30); // Volatility 69 | T t = T( 2.22); // Years to maturity 70 | T r = T( 0.05); // Risk free rate 71 | T n = T(1000.00); // Number of time steps 72 | 73 | std::string callput_flag; 74 | 75 | symbol_table_t symbol_table; 76 | symbol_table.add_variable("s",s); 77 | symbol_table.add_variable("k",k); 78 | symbol_table.add_variable("t",t); 79 | symbol_table.add_variable("r",r); 80 | symbol_table.add_variable("v",v); 81 | symbol_table.add_constant("n",n); 82 | symbol_table.add_stringvar("callput_flag",callput_flag); 83 | 84 | expression_t expression; 85 | expression.register_symbol_table(symbol_table); 86 | 87 | parser_t parser; 88 | parser.compile(european_option_binomial_model_program,expression); 89 | 90 | callput_flag = "call"; 91 | 92 | const T binomial_call_option_price = expression.value(); 93 | 94 | callput_flag = "put"; 95 | 96 | const T binomial_put_option_price = expression.value(); 97 | 98 | printf("BinomialPrice(call, %5.3f, %5.3f, %5.3f, %5.3f, %5.3f) = %22.18f\n", 99 | s, k, t, r, v, 100 | binomial_call_option_price); 101 | 102 | printf("BinomialPrice(put , %5.3f, %5.3f, %5.3f, %5.3f, %5.3f) = %22.18f\n", 103 | s, k, t, r, v, 104 | binomial_put_option_price); 105 | 106 | const T put_call_parity_diff = 107 | (binomial_call_option_price - binomial_put_option_price) - 108 | (s - k * std::exp(-r * t)); 109 | 110 | printf("Put-Call parity difference: %20.17f\n", put_call_parity_diff); 111 | } 112 | 113 | int main() 114 | { 115 | binomial_option_pricing_model(); 116 | return 0; 117 | } 118 | -------------------------------------------------------------------------------- /exprtk_simple_example_22.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 22 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | 23 | #include "exprtk.hpp" 24 | 25 | 26 | template 27 | void compute_european_option_implied_volatility() 28 | { 29 | typedef exprtk::symbol_table symbol_table_t; 30 | typedef exprtk::expression expression_t; 31 | typedef exprtk::parser parser_t; 32 | typedef exprtk::function_compositor compositor_t; 33 | typedef typename compositor_t::function function_t; 34 | 35 | const std::string option_implied_volatility_program = 36 | " const var epsilon := 0.0000001; " 37 | " const var max_iters := 1000; " 38 | " " 39 | " var v := 0.5; /* Initial volatility guess */ " 40 | " var itr := 0; " 41 | " " 42 | " while ((itr += 1) <= max_iters) " 43 | " { " 44 | " var price := " 45 | " switch " 46 | " { " 47 | " case callput_flag == 'call' : bsm_call(s, k, r, t, v); " 48 | " case callput_flag == 'put' : bsm_put (s, k, r, t, v); " 49 | " }; " 50 | " " 51 | " var price_diff := price - target_price; " 52 | " " 53 | " if (abs(price_diff) <= epsilon) " 54 | " { " 55 | " break; " 56 | " }; " 57 | " " 58 | " var vega := bsm_vega(s, k, r, t, v); " 59 | " " 60 | " if (vega < epsilon) " 61 | " { " 62 | " itr := max_iters + 1; " 63 | " break; " 64 | " }; " 65 | " " 66 | " v -= price_diff / vega; " 67 | " }; " 68 | " " 69 | " itr <= max_iters ? v : null; "; 70 | 71 | T s = T(100.00); // Spot / Stock / Underlying / Base price 72 | T k = T(110.00); // Strike price 73 | T t = T( 2.22); // Years to maturity 74 | T r = T( 0.05); // Risk free rate 75 | T target_price = T( 0.00); 76 | 77 | std::string callput_flag; 78 | 79 | symbol_table_t symbol_table(symbol_table_t::e_immutable); 80 | symbol_table.add_variable("s",s); 81 | symbol_table.add_variable("k",k); 82 | symbol_table.add_variable("t",t); 83 | symbol_table.add_variable("r",r); 84 | symbol_table.add_stringvar("callput_flag",callput_flag); 85 | symbol_table.add_variable ("target_price",target_price); 86 | symbol_table.add_pi(); 87 | 88 | compositor_t compositor(symbol_table); 89 | 90 | compositor.add( 91 | function_t("bsm_call") 92 | .vars("s", "k", "r", "t", "v") 93 | .expression 94 | ( 95 | " var d1 := (log(s / k) + (r + v^2 / 2) * t) / (v * sqrt(t)); " 96 | " var d2 := d1 - v * sqrt(t); " 97 | " s * ncdf(d1) - k * exp(-r * t) * ncdf(d2); " 98 | )); 99 | 100 | compositor.add( 101 | function_t("bsm_put") 102 | .vars("s", "k", "r", "t", "v") 103 | .expression 104 | ( 105 | " var d1 := (log(s / k) + (r + v^2 / 2) * t) / (v * sqrt(t)); " 106 | " var d2 := d1 - v * sqrt(t); " 107 | " k * exp(-r * t) * ncdf(-d2) - s * ncdf(-d1); " 108 | )); 109 | 110 | compositor.add( 111 | function_t("bsm_vega") 112 | .vars("s", "k", "r", "t", "v") 113 | .expression 114 | ( 115 | " var d1 := (log(s / k) + (r + v^2 / 2) * t) / (v * sqrt(t)); " 116 | " s * exp(-d1^2 / 2) / sqrt(2pi) * sqrt(t); " 117 | )); 118 | 119 | expression_t expression; 120 | expression.register_symbol_table(symbol_table); 121 | 122 | parser_t parser; 123 | parser.compile(option_implied_volatility_program, expression); 124 | 125 | { 126 | callput_flag = "call"; 127 | target_price = T(18.339502); 128 | 129 | const T call_option_implied_vol = expression.value(); 130 | 131 | printf("Call Option(s: %5.3f, k: %5.3f, t: %5.3f, r: %5.3f) " 132 | "@ $%8.6f Implied volatility = %10.8f\n", 133 | s, k, t, r, target_price, call_option_implied_vol); 134 | } 135 | 136 | { 137 | callput_flag = "put"; 138 | target_price = T(16.782764); 139 | 140 | const T put_option_implied_vol = expression.value(); 141 | 142 | printf("Put Option(s: %5.3f, k: %5.3f, t: %5.3f, r: %5.3f) " 143 | "@ $%8.6f Implied volatility = %10.8f\n", 144 | s, k, t, r, target_price, put_option_implied_vol); 145 | } 146 | } 147 | 148 | int main() 149 | { 150 | compute_european_option_implied_volatility(); 151 | return 0; 152 | } 153 | -------------------------------------------------------------------------------- /exprtk_simple_example_23.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 23 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | 23 | #include "exprtk.hpp" 24 | 25 | 26 | template 27 | void real_1d_discrete_fourier_transform() 28 | { 29 | typedef exprtk::symbol_table symbol_table_t; 30 | typedef exprtk::expression expression_t; 31 | typedef exprtk::parser parser_t; 32 | typedef exprtk::function_compositor compositor_t; 33 | typedef typename compositor_t::function function_t; 34 | 35 | const T sampling_rate = 1024.0; // ~1KHz 36 | const T N = 8 * sampling_rate; // 8 seconds worth of samples 37 | 38 | std::vector input (static_cast(N),0.0); 39 | std::vector output(static_cast(N),0.0); 40 | 41 | exprtk::rtl::io::println println; 42 | 43 | symbol_table_t symbol_table; 44 | symbol_table.add_vector ("input" , input ); 45 | symbol_table.add_vector ("output" , output ); 46 | symbol_table.add_function ("println" , println ); 47 | symbol_table.add_constant ("N" , N ); 48 | symbol_table.add_constant ("sampling_rate", sampling_rate); 49 | symbol_table.add_pi(); 50 | 51 | compositor_t compositor(symbol_table); 52 | compositor.load_vectors(true); 53 | 54 | compositor.add( 55 | function_t("dft_1d_real") 56 | .var("N") 57 | .expression 58 | ( 59 | " for (var k := 0; k < N; k += 1) " 60 | " { " 61 | " var k_real := 0.0; " 62 | " var k_imag := 0.0; " 63 | " " 64 | " for (var i := 0; i < N; i += 1) " 65 | " { " 66 | " var theta := 2pi * k * i / N; " 67 | " k_real += input[i] * cos(theta); " 68 | " k_imag -= input[i] * sin(theta); " 69 | " }; " 70 | " " 71 | " output[k] := hypot(k_real,k_imag); " 72 | " } " 73 | )); 74 | 75 | const std::string dft_program = 76 | " " 77 | " /* " 78 | " Generate an aggregate waveform comprised of three " 79 | " sine waves of varying frequencies and amplitudes. " 80 | " */ " 81 | " const var num_waves := 3; " 82 | " " 83 | " var frequencies[num_waves] := { 111.125, 222.250, 333.375 }; /* Hz */ " 84 | " var amplitudes [num_waves] := { 11.111, 22.222, 33.333 }; /* Power */ " 85 | " " 86 | " for (var i := 0; i < N; i += 1) " 87 | " { " 88 | " var time := i / sampling_rate; " 89 | " " 90 | " for (var j := 0; j < frequencies[]; j += 1) " 91 | " { " 92 | " var frequency := frequencies[j]; " 93 | " var amplitude := amplitudes [j]; " 94 | " var theta := 2 * pi * frequency * time; " 95 | " " 96 | " input[i] += amplitude * sin(theta); " 97 | " } " 98 | " }; " 99 | " " 100 | " dft_1d_real(input[]); " 101 | " " 102 | " var freq_bin_size := sampling_rate / N; " 103 | " var max_bin := ceil(N / 2); " 104 | " var max_noise_level := 1e-6; " 105 | " " 106 | " /* Normalise amplitudes */ " 107 | " output /= max_bin; " 108 | " " 109 | " println('1D Real DFT Frequencies'); " 110 | " " 111 | " for (var k := 0; k < max_bin; k += 1) " 112 | " { " 113 | " if (output[k] > max_noise_level) " 114 | " { " 115 | " var freq_begin := k * freq_bin_size; " 116 | " var freq_end := freq_begin + freq_bin_size; " 117 | " " 118 | " println('Index: ', k,' ', " 119 | " 'Freq. range: [', freq_begin, 'Hz, ', freq_end, 'Hz) ', " 120 | " 'Amplitude: ', output[k]); " 121 | " } " 122 | " } " 123 | " "; 124 | 125 | expression_t expression; 126 | expression.register_symbol_table(symbol_table); 127 | 128 | parser_t parser; 129 | parser.compile(dft_program,expression); 130 | 131 | expression.value(); 132 | } 133 | 134 | int main() 135 | { 136 | real_1d_discrete_fourier_transform(); 137 | return 0; 138 | } 139 | -------------------------------------------------------------------------------- /exprtk_simple_example_24.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Simple Example 24 * 6 | * Author: Arash Partow (1999-2024) * 7 | * URL: https://www.partow.net/programming/exprtk/index.html * 8 | * * 9 | * Copyright notice: * 10 | * Free use of the Mathematical Expression Toolkit Library is * 11 | * permitted under the guidelines and in accordance with the * 12 | * most current version of the MIT License. * 13 | * https://www.opensource.org/licenses/MIT * 14 | * SPDX-License-Identifier: MIT * 15 | * * 16 | ************************************************************** 17 | */ 18 | 19 | 20 | #include 21 | #include 22 | 23 | #include "exprtk.hpp" 24 | 25 | 26 | template 27 | struct char_process : public exprtk::igeneric_function 28 | { 29 | typedef typename exprtk::igeneric_function igfun_t; 30 | typedef typename igfun_t::parameter_list_t parameter_list_t; 31 | typedef typename igfun_t::generic_type generic_type; 32 | typedef typename generic_type::string_view string_t; 33 | 34 | using exprtk::igeneric_function::operator(); 35 | 36 | char_process() 37 | : exprtk::igeneric_function("S") 38 | {} 39 | 40 | inline T operator()(parameter_list_t parameters) 41 | { 42 | const unsigned char c = string_t(parameters[0])[0]; 43 | return Process(c); 44 | } 45 | }; 46 | 47 | template 48 | T is_digit_func(const unsigned char c) 49 | { 50 | return (('0' <= c) && (c <= '9')) ? T(1) : T(0); 51 | } 52 | 53 | template 54 | T to_num_func(const unsigned char c) 55 | { 56 | return static_cast(c - '0'); 57 | } 58 | 59 | template 60 | void rpn_example() 61 | { 62 | typedef exprtk::symbol_table symbol_table_t; 63 | typedef exprtk::expression expression_t; 64 | typedef exprtk::parser parser_t; 65 | 66 | const std::string rpn_program = 67 | " var stack[1000] := [0]; " 68 | " var top_index := 0; " 69 | " " 70 | " for (var i := 0; i < rpn_expression[]; i += 1) " 71 | " { " 72 | " var c := rpn_expression[i : i + 1]; " 73 | " " 74 | " if (c == ' ') " 75 | " { " 76 | " continue; " 77 | " } " 78 | " else if (is_digit(c)) " 79 | " { " 80 | " stack[top_index] := to_num(c); " 81 | " top_index += 1; " 82 | " } " 83 | " else " 84 | " { " 85 | " var operator := c; " 86 | " var operand1 := stack[top_index - 2]; " 87 | " var operand2 := stack[top_index - 1]; " 88 | " top_index -= 2; " 89 | " " 90 | " switch " 91 | " { " 92 | " case operator == '+' : stack[top_index] := operand1 + operand2; " 93 | " case operator == '-' : stack[top_index] := operand1 - operand2; " 94 | " case operator == '*' : stack[top_index] := operand1 * operand2; " 95 | " case operator == '/' : stack[top_index] := operand1 / operand2; " 96 | " case operator == '^' : stack[top_index] := operand1 ^ operand2; " 97 | " }; " 98 | " " 99 | " top_index += 1; " 100 | " } " 101 | " }; " 102 | " " 103 | " println(stack[0], ' = ', rpn_expression); " 104 | " "; 105 | 106 | std::string rpn_expression; 107 | 108 | char_process > isdigit; 109 | char_process > tonum; 110 | exprtk::rtl::io::println println; 111 | 112 | symbol_table_t symbol_table; 113 | symbol_table.add_stringvar("rpn_expression", rpn_expression); 114 | symbol_table.add_function ("println" , println ); 115 | symbol_table.add_function ("is_digit" , isdigit ); 116 | symbol_table.add_function ("to_num" , tonum ); 117 | 118 | expression_t expression; 119 | expression.register_symbol_table(symbol_table); 120 | 121 | parser_t parser; 122 | parser.compile(rpn_program, expression); 123 | 124 | const std::string rpn_expressions[] = 125 | { 126 | "2 3 8 / ^ 4 6 * + 3 9 / -", // 2 ^ (3 / 8) + 4 * 6 - 3 / 9 127 | "1 2 / 6 5 2 - / * 7 +" , // (1 / 2) * (6 / (5 - 2)) + 7 128 | "1 2 * 3 / 4 * 5 / 6 *" , // ((((1 * 2) / 3) * 4) / 5) * 6 129 | "8 6 4 + * 2 /" // (8 * (6 + 4)) / 2 130 | }; 131 | 132 | for (std::size_t i = 0; i < sizeof(rpn_expressions) / sizeof(std::string); ++i) 133 | { 134 | rpn_expression = rpn_expressions[i]; 135 | expression.value(); 136 | } 137 | } 138 | 139 | int main() 140 | { 141 | rpn_example(); 142 | return 0; 143 | } 144 | -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 1999-2024 Arash Partow 4 | 5 | https://www.partow.net/programming/exprtk/index.html 6 | 7 | Permission is hereby granted, free of charge, to any person obtaining 8 | a copy of this software and associated documentation files (the 9 | "Software"), to deal in the Software without restriction, including 10 | without limitation the rights to use, copy, modify, merge, publish, 11 | distribute, sublicense, and/or sell copies of the Software, and to 12 | permit persons to whom the Software is furnished to do so, subject to 13 | the following conditions: 14 | 15 | The above copyright notice and this permission notice shall be 16 | included in all copies or substantial portions of the Software. 17 | 18 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 19 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 20 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 21 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 22 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 23 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 24 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 25 | --------------------------------------------------------------------------------