├── .circleci └── config.yml ├── Makefile ├── exprtk.hpp ├── exprtk_american_option_binomial_model.cpp ├── exprtk_archimedes_pi.cpp ├── exprtk_arithmetic_evaluator.cpp ├── exprtk_binomial_coefficient.cpp ├── exprtk_bsm_benchmark.cpp ├── exprtk_calc.cpp ├── exprtk_collatz.cpp ├── exprtk_compilation_timeout.cpp ├── exprtk_degree_trigonometry_example.cpp ├── exprtk_e_10kdigits.cpp ├── exprtk_exprgen.cpp ├── exprtk_extract_dependents.cpp ├── exprtk_factorize_fermat.cpp ├── exprtk_factorize_pollard.cpp ├── exprtk_fizzbuzz.cpp ├── exprtk_funcall_benchmark.cpp ├── exprtk_game_of_life.cpp ├── exprtk_gcd.cpp ├── exprtk_gnuplot.cpp ├── exprtk_gnuplot_multi.cpp ├── exprtk_groups_examples.cpp ├── exprtk_immutable_symbol_table_example.cpp ├── exprtk_import_packages.cpp ├── exprtk_instruction_primer.cpp ├── exprtk_jump_diffusion_process.cpp ├── exprtk_loop_timeout_rtc.cpp ├── exprtk_magic_square.cpp ├── exprtk_mandelbrot.cpp ├── exprtk_max_subarray_sum.cpp ├── exprtk_maze_generator.cpp ├── exprtk_miller_rabin_primality_test.cpp ├── exprtk_montecarlo_e.cpp ├── exprtk_montecarlo_option_pricing_model.cpp ├── exprtk_montecarlo_pi.cpp ├── exprtk_naive_primes.cpp ├── exprtk_normal_random_marsaglia_method.cpp ├── exprtk_nqueens_problem.cpp ├── exprtk_nthroot_bisection.cpp ├── exprtk_ornstein_uhlenbeck_process.cpp ├── exprtk_pascals_triangle.cpp ├── exprtk_pi_10kdigits.cpp ├── exprtk_prime_sieve.cpp ├── exprtk_prime_sieve_vectorized.cpp ├── exprtk_pyramid.cpp ├── exprtk_pythagorean_triples.cpp ├── exprtk_recursive_fibonacci.cpp ├── exprtk_repl.cpp ├── exprtk_riddle.cpp ├── exprtk_rtc_overhead.cpp ├── exprtk_str_funcs.hpp ├── exprtk_sudoku_solver.cpp ├── exprtk_sumofprimes.cpp ├── exprtk_symtab_functions.cpp ├── exprtk_testgen.cpp ├── exprtk_tower_of_hanoi.cpp ├── exprtk_truthtable_gen.cpp ├── exprtk_vector_benchmark.cpp ├── exprtk_vector_benchmark_multithreaded.cpp ├── exprtk_vector_resize_example.cpp ├── exprtk_vector_resize_inline_example.cpp ├── exprtk_vectorized_binomial_model.cpp ├── exprtk_vectornorm.cpp ├── exprtk_wiener_process_pi.cpp ├── license.txt └── readme.md /.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 | 12 | build_gcc_10: 13 | docker: 14 | - image: gcc:10 15 | steps: 16 | - checkout 17 | - run: c++ --version 18 | - run: make all -j 2 19 | 20 | build_gcc_11: 21 | docker: 22 | - image: gcc:11 23 | steps: 24 | - checkout 25 | - run: c++ --version 26 | - run: make all -j 2 27 | 28 | build_gcc_12: 29 | docker: 30 | - image: gcc:12 31 | steps: 32 | - checkout 33 | - run: c++ --version 34 | - run: make all -j 2 35 | 36 | build_gcc_latest: 37 | docker: 38 | - image: gcc:latest 39 | steps: 40 | - checkout 41 | - run: c++ --version 42 | - run: make all -j 2 43 | 44 | workflows: 45 | version: 2 46 | build_and_test: 47 | jobs: 48 | - build_gcc_09 49 | - build_gcc_10 50 | - build_gcc_11 51 | - build_gcc_12 52 | - build_gcc_latest 53 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # 2 | # ************************************************************** 3 | # * C++ Mathematical Expression Toolkit Library * 4 | # * * 5 | # * Extra Examples * 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 | COMPILER := -c++ 21 | #COMPILER := -clang++ 22 | OPTIMIZATION_OPT := -O2 -DNDEBUG 23 | BASE_OPTIONS = -pedantic-errors -Wall -Wextra -Werror -Wno-long-long 24 | OPTIONS = $(BASE_OPTIONS) $(OPTIMIZATION_OPT) 25 | LINKER_OPT = -L/usr/lib -lstdc++ -lm 26 | BUILD_SRC := $(sort $(wildcard exprtk_*.cpp)) 27 | BUILD_LIST := $(BUILD_SRC:%.cpp=%) 28 | 29 | all: $(BUILD_LIST) 30 | 31 | $(BUILD_LIST) : %: %.cpp exprtk.hpp 32 | $(COMPILER) $(OPTIONS) -o $@ $@.cpp $(LINKER_OPT) 33 | 34 | strip_bin : 35 | @for f in $(BUILD_LIST); do if [ -f $$f ]; then strip -s $$f; echo $$f; fi done; 36 | 37 | valgrind : 38 | @for f in $(BUILD_LIST); do \ 39 | if [ -f $$f ]; then \ 40 | cmd="valgrind --leak-check=full --show-reachable=yes --track-origins=yes --log-file=$$f.log -v ./$$f"; \ 41 | echo $$cmd; \ 42 | $$cmd; \ 43 | fi done; 44 | 45 | clean: 46 | rm -f core.* *~ *.o *.bak *stackdump gmon.out *.gcda *.gcno *.gcnor *.gch 47 | -------------------------------------------------------------------------------- /exprtk_american_option_binomial_model.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * American Option Binomial Pricing Model * 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 american_option_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 american_option_binomial_model_program = 34 | " var dt := t / n; " 35 | " var z := exp(r * dt); " 36 | " var u := exp(v * sqrt(dt)); " 37 | " var p_up := (z * u - 1) / (u^2 - 1); " 38 | " var p_down := 1 - p_up; " 39 | " var discount := 1 / z; " 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^(2 * i - n); " 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 | " var base_price_at_node := s * u^(2 * i - j); " 60 | " " 61 | " var intrinsic_value := " 62 | " switch " 63 | " { " 64 | " case callput_flag == 'call' : base_price_at_node - k; " 65 | " case callput_flag == 'put' : k - base_price_at_node; " 66 | " }; " 67 | " " 68 | " var expected_value := discount * " 69 | " (p_up * option_price[i + 1] + p_down * option_price[i]); " 70 | " " 71 | " option_price[i] := max(expected_value, intrinsic_value); " 72 | " } " 73 | " }; " 74 | " " 75 | " option_price[0]; "; 76 | 77 | T s = T( 100.00); // Spot / Stock / Underlying / Base price 78 | T k = T( 110.00); // Strike price 79 | T v = T( 0.30); // Volatility 80 | T t = T( 2.22); // Years to maturity 81 | T r = T( 0.05); // Risk free rate 82 | T n = T(1000.00); // Number of time steps 83 | 84 | std::string callput_flag; 85 | 86 | symbol_table_t symbol_table(symbol_table_t::e_immutable); 87 | symbol_table.add_variable("s", s); 88 | symbol_table.add_variable("k", k); 89 | symbol_table.add_variable("t", t); 90 | symbol_table.add_variable("r", r); 91 | symbol_table.add_variable("v", v); 92 | symbol_table.add_constant("n", n); 93 | symbol_table.add_stringvar("callput_flag",callput_flag); 94 | 95 | expression_t expression; 96 | expression.register_symbol_table(symbol_table); 97 | 98 | parser_t parser; 99 | parser.compile(american_option_binomial_model_program,expression); 100 | 101 | callput_flag = "call"; 102 | 103 | const T binomial_call_option_price = expression.value(); 104 | 105 | callput_flag = "put"; 106 | 107 | const T binomial_put_option_price = expression.value(); 108 | 109 | printf("American BinomialPrice(call, %5.3f, %5.3f, %5.3f, %5.3f, %5.3f) = %22.18f\n", 110 | s, k, t, r, v, 111 | binomial_call_option_price); 112 | 113 | printf("American BinomialPrice(put , %5.3f, %5.3f, %5.3f, %5.3f, %5.3f) = %22.18f\n", 114 | s, k, t, r, v, 115 | binomial_put_option_price); 116 | 117 | // American option put-call 'parity': s - k < call - put < s - k * e^(-rt) 118 | const T callput_diff = (binomial_call_option_price - binomial_put_option_price); 119 | const T basestrike_diff = s - k; 120 | const T basepv_diff = s - k * std::exp(-r * t); 121 | const bool put_call_parity = (basestrike_diff < callput_diff) && 122 | (callput_diff < basepv_diff ) ; 123 | 124 | const T call_price_r0 = binomial_put_option_price + basestrike_diff; 125 | const T call_price_r1 = binomial_put_option_price + basepv_diff; 126 | 127 | const T put_price_r0 = binomial_call_option_price - basepv_diff; 128 | const T put_price_r1 = binomial_call_option_price - basestrike_diff; 129 | 130 | printf("Put-Call parity: %s\n", put_call_parity ? "True" : "False"); 131 | 132 | printf("Call price range: %7.4f < %7.4f < %7.4f\n", 133 | call_price_r0, 134 | binomial_call_option_price, 135 | call_price_r1); 136 | 137 | printf("Put price range: %7.4f < %7.4f < %7.4f\n", 138 | put_price_r0, 139 | binomial_put_option_price, 140 | put_price_r1); 141 | } 142 | 143 | int main() 144 | { 145 | american_option_binomial_option_pricing_model(); 146 | return 0; 147 | } 148 | -------------------------------------------------------------------------------- /exprtk_archimedes_pi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Archimedes Approximation Of Pi * 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 archimedes_pi() 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 | exprtk::rtl::io::println println("%25.23f"); 36 | 37 | symbol_table_t symbol_table; 38 | 39 | symbol_table.add_function("println", println); 40 | symbol_table.add_constants(); 41 | 42 | compositor_t compositor(symbol_table); 43 | 44 | compositor.add( 45 | function_t("archimedes_pi") 46 | .var("iterations") 47 | .expression 48 | ( 49 | " var s := 1.0; " 50 | " var approx_pi := 0.0; " 51 | " " 52 | " for (var i := 0; i < iterations; i += 1) " 53 | " { " 54 | " var n := 6 * 2^i; " 55 | " var s2 := (s / 2)^2; " 56 | " var t := sqrt(1 - s2); " 57 | " var q := 1 - t; " 58 | " var p := n * s; " 59 | " " 60 | " approx_pi := p / 2; " 61 | " s := sqrt(q^2 + s2); " 62 | " }; " 63 | " " 64 | " approx_pi; " 65 | )); 66 | 67 | const std::string archimedes_pi_program = 68 | " const var n := 30; " 69 | " " 70 | " for (var i := 1; i <= n; i += 1) " 71 | " { " 72 | " var approx_pi := archimedes_pi(i); " 73 | " var abs_error := abs(approx_pi - pi); " 74 | " " 75 | " println('approx pi: ', approx_pi, ' abs error:', abs_error); " 76 | " } "; 77 | 78 | expression_t expression; 79 | expression.register_symbol_table(symbol_table); 80 | 81 | parser_t parser; 82 | parser.compile(archimedes_pi_program,expression); 83 | 84 | expression.value(); 85 | } 86 | 87 | int main() 88 | { 89 | archimedes_pi(); 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /exprtk_arithmetic_evaluator.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Basic Arithmetic Expression Parser And Evaluator * 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 is_operator_func(const unsigned char c) 55 | { 56 | return ('+' == c) || ('-' == c) || 57 | ('*' == c) || ('/' == c) ; 58 | } 59 | 60 | template 61 | T to_num_func(const unsigned char c) 62 | { 63 | return static_cast(c - '0'); 64 | } 65 | 66 | template 67 | void basic_arithmetic_parser_evaluator() 68 | { 69 | typedef exprtk::symbol_table symbol_table_t; 70 | typedef exprtk::expression expression_t; 71 | typedef exprtk::parser parser_t; 72 | 73 | const std::string arithmetic_parser_evaluator_program = 74 | " var curr_val := 0; " 75 | " var prev_val := 0; " 76 | " var result := 0; " 77 | " var op := '+'; " 78 | " " 79 | " for (var i := 0; i < expression[]; i += 1) " 80 | " { " 81 | " var c := expression[i : i + 1]; " 82 | " " 83 | " if (is_digit(c)) " 84 | " { " 85 | " curr_val := curr_val * 10 + to_num(c); " 86 | " }; " 87 | " " 88 | " if (is_opr(c) or (i == expression[] - 1)) " 89 | " { " 90 | " prev_val := " 91 | " switch " 92 | " { " 93 | " case op == '+' : " 94 | " ~{ " 95 | " result += prev_val; " 96 | " curr_val; " 97 | " }; " 98 | " " 99 | " case op == '-' : " 100 | " ~{ " 101 | " result += prev_val; " 102 | " -curr_val; " 103 | " }; " 104 | " " 105 | " case op == '*' : prev_val * curr_val; " 106 | " case op == '/' : prev_val / curr_val; " 107 | " }; " 108 | " " 109 | " curr_val := 0; " 110 | " op := c; " 111 | " } " 112 | " }; " 113 | " " 114 | " result += prev_val; " 115 | " " 116 | " println(result, ' = ', expression); " 117 | " "; 118 | 119 | std::string arithmetic_expression; 120 | 121 | char_process > isdigit; 122 | char_process > tonum; 123 | char_process > isopr; 124 | exprtk::rtl::io::println println; 125 | 126 | symbol_table_t symbol_table; 127 | symbol_table.add_stringvar("expression", arithmetic_expression); 128 | symbol_table.add_function ("println" , println ); 129 | symbol_table.add_function ("is_digit" , isdigit ); 130 | symbol_table.add_function ("is_opr" , isopr ); 131 | symbol_table.add_function ("to_num" , tonum ); 132 | 133 | expression_t expression; 134 | expression.register_symbol_table(symbol_table); 135 | 136 | parser_t parser; 137 | parser.compile(arithmetic_parser_evaluator_program, expression); 138 | 139 | /* 140 | Note: Expressions can be comprised of integers, 141 | basic arithmetic operators (+, -, *, /), 142 | and shall not contain parenthesises. 143 | */ 144 | const std::vector arithmetic_expressions = 145 | { 146 | "5 + 18 / 3", 147 | "4 + 3 * 15", 148 | "1 - 2 + 52 / 2 - 81 / 3", 149 | }; 150 | 151 | for (const auto& expr : arithmetic_expressions) 152 | { 153 | arithmetic_expression = expr; 154 | expression.value(); 155 | } 156 | } 157 | 158 | int main() 159 | { 160 | basic_arithmetic_parser_evaluator(); 161 | return 0; 162 | } 163 | -------------------------------------------------------------------------------- /exprtk_binomial_coefficient.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Binomial Coefficient (n-choose-r) * 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 | inline T ncr_println(T n, T r, T ncr) 28 | { 29 | printf("ncr(%2d,%2d) = %2llu\n", 30 | static_cast(n), 31 | static_cast(r), 32 | static_cast(ncr)); 33 | 34 | return T(0); 35 | } 36 | 37 | template 38 | void n_choose_r() 39 | { 40 | typedef exprtk::symbol_table symbol_table_t; 41 | typedef exprtk::expression expression_t; 42 | typedef exprtk::parser parser_t; 43 | typedef exprtk::function_compositor compositor_t; 44 | typedef typename compositor_t::function function_t; 45 | 46 | symbol_table_t symbol_table; 47 | symbol_table.add_function("println",ncr_println); 48 | 49 | compositor_t compositor(symbol_table); 50 | 51 | // define function: ncr(n,r) 52 | compositor.add( 53 | function_t("ncr") 54 | .vars("n", "r") 55 | .expression 56 | ( 57 | " switch " 58 | " { " 59 | " case n <= r : 1; " 60 | " case r <= 0 : 1; " 61 | " default : ncr(n - 1, r - 1) + " 62 | " ncr(n - 1, r ) ; " 63 | " } " 64 | )); 65 | 66 | const std::string ncr_program = 67 | " var n := 25; " 68 | " for (var r := 1; r < n; r += 1) " 69 | " { " 70 | " println(n, r, ncr(n,r)); " 71 | " }; "; 72 | 73 | expression_t expression; 74 | expression.register_symbol_table(symbol_table); 75 | 76 | parser_t parser; 77 | parser.compile(ncr_program,expression); 78 | 79 | expression.value(); 80 | } 81 | 82 | int main() 83 | { 84 | n_choose_r(); 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /exprtk_calc.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Simple Calculator Example * 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 | int main() 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 | 34 | for ( ; ; ) 35 | { 36 | double x = 1.0; 37 | double y = 2.0; 38 | double z = 3.0; 39 | double w = 4.0; 40 | double u = 5.0; 41 | double v = 6.0; 42 | 43 | symbol_table_t symbol_table; 44 | symbol_table.add_variable("x",x); 45 | symbol_table.add_variable("y",y); 46 | symbol_table.add_variable("z",z); 47 | symbol_table.add_variable("w",w); 48 | symbol_table.add_variable("u",u); 49 | symbol_table.add_variable("v",v); 50 | symbol_table.add_constants(); 51 | 52 | expression_t expression; 53 | expression.register_symbol_table(symbol_table); 54 | 55 | std::string expression_str; 56 | 57 | printf(">> "); 58 | std::getline(std::cin,expression_str); 59 | 60 | if (expression_str.empty()) 61 | continue; 62 | else if ("exit" == expression_str) 63 | break; 64 | else if ("quit" == expression_str) 65 | break; 66 | 67 | parser_t parser; 68 | 69 | if (!parser.compile(expression_str,expression)) 70 | { 71 | printf("Error: %s\tExpression: %s\n", 72 | parser.error().c_str(), 73 | expression_str.c_str()); 74 | 75 | for (std::size_t i = 0; i < parser.error_count(); ++i) 76 | { 77 | err_t error = parser.get_error(i); 78 | printf("Error: %02d Pos: %02d Type: [%14s] Message: %s\tExpression: %s\n", 79 | static_cast(i), 80 | static_cast(error.token.position), 81 | exprtk::parser_error::to_str(error.mode).c_str(), 82 | error.diagnostic.c_str(), 83 | expression_str.c_str()); 84 | } 85 | 86 | continue; 87 | } 88 | 89 | double result = expression.value(); 90 | 91 | printf("result: %20.10f\n",result); 92 | } 93 | 94 | return 0; 95 | } 96 | -------------------------------------------------------------------------------- /exprtk_collatz.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Collatz Example * 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 collatz() 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 | exprtk::rtl::io::print print("%3.0f "); 36 | 37 | symbol_table_t symbol_table; 38 | symbol_table.add_function("print",print); 39 | 40 | compositor_t compositor(symbol_table); 41 | 42 | // define function: collatz_trace(x) 43 | compositor.add( 44 | function_t("collatz_trace") 45 | .var("x") 46 | .expression 47 | ( 48 | " while (x > 1) " 49 | " { " 50 | " x := (x % 2 == 0) ? x / 2 : 3x + 1; " 51 | " print(x); " 52 | " } " 53 | )); 54 | 55 | const std::string collatz_program = 56 | " x := 0; " 57 | " repeat " 58 | " print(x += 1); " 59 | " collatz_trace(x); " 60 | " print('\n\n'); " 61 | " until (x > 100); " 62 | " println; "; 63 | 64 | expression_t expression; 65 | expression.register_symbol_table(symbol_table); 66 | 67 | parser_t parser; 68 | parser.enable_unknown_symbol_resolver(); 69 | parser.compile(collatz_program,expression); 70 | 71 | expression.value(); 72 | } 73 | 74 | int main() 75 | { 76 | collatz(); 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /exprtk_compilation_timeout.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Compilation Timeout Check * 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 | struct compilation_timeout_check final : public exprtk::compilation_check 28 | { 29 | static constexpr std::size_t max_iters_per_check = 10000; 30 | 31 | bool continue_compilation(compilation_context& context) override 32 | { 33 | if (++iterations_ >= max_iters_per_check) 34 | { 35 | if (std::chrono::steady_clock::now() >= timeout_tp_) 36 | { 37 | context.error_message = "Compilation has timed-out"; 38 | return false; 39 | } 40 | 41 | iterations_ = 0; 42 | } 43 | 44 | return true; 45 | } 46 | 47 | using time_point_t = std::chrono::time_point; 48 | 49 | void set_timeout_time(const time_point_t& timeout_tp) 50 | { 51 | timeout_tp_ = timeout_tp; 52 | } 53 | 54 | std::size_t iterations_ = max_iters_per_check; 55 | time_point_t timeout_tp_; 56 | }; 57 | 58 | template 59 | void compilation_timeout_check_example() 60 | { 61 | typedef exprtk::symbol_table symbol_table_t; 62 | typedef exprtk::expression expression_t; 63 | typedef exprtk::parser parser_t; 64 | 65 | const std::string base_expression_string = 66 | "x := " 67 | "((1 /1) * sin( 2 * pi * f * t) + (1 /3) * sin( 6 * pi * f * t)+" 68 | " (1 /5) * sin(10 * pi * f * t) + (1 /7) * sin(14 * pi * f * t)+" 69 | " (1 /9) * sin(18 * pi * f * t) + (1/11) * sin(22 * pi * f * t)+" 70 | " (1/13) * sin(26 * pi * f * t) + (1/15) * sin(30 * pi * f * t)+" 71 | " (1/17) * sin(34 * pi * f * t) + (1/19) * sin(38 * pi * f * t)+" 72 | " (1/21) * sin(42 * pi * f * t) + (1/23) * sin(46 * pi * f * t)+" 73 | " (1/25) * sin(50 * pi * f * t) + (1/27) * sin(54 * pi * f * t));"; 74 | 75 | std::string large_expression_string = "var x := 0;"; 76 | 77 | for (std::size_t i = 0; i < 60000; ++i) 78 | { 79 | large_expression_string += base_expression_string; 80 | } 81 | 82 | static const T pi = T(3.141592653589793238462643383279502); 83 | 84 | const T f = pi / T(10); 85 | const T a = T(10); 86 | T t = T(0); 87 | 88 | symbol_table_t symbol_table; 89 | symbol_table.add_variable("t",t); 90 | symbol_table.add_constant("f",f); 91 | symbol_table.add_constant("a",a); 92 | symbol_table.add_constants(); 93 | 94 | expression_t expression; 95 | expression.register_symbol_table(symbol_table); 96 | 97 | compilation_timeout_check compilation_timeout_chck; 98 | 99 | parser_t parser; 100 | parser.register_compilation_timeout_check(compilation_timeout_chck); 101 | 102 | const auto max_duration = std::chrono::seconds(8); 103 | const auto timeout_tp = std::chrono::steady_clock::now() + max_duration; 104 | compilation_timeout_chck.set_timeout_time(timeout_tp); 105 | 106 | if (!parser.compile(large_expression_string, expression)) 107 | { 108 | printf("Error: %s\t\n", parser.error().c_str()); 109 | return; 110 | } 111 | } 112 | 113 | int main() 114 | { 115 | compilation_timeout_check_example(); 116 | return 0; 117 | } 118 | -------------------------------------------------------------------------------- /exprtk_degree_trigonometry_example.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Trigonometry In Degrees Example * 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 sine_deg final : public exprtk::ifunction 28 | { 29 | using exprtk::ifunction::operator(); 30 | 31 | sine_deg() : exprtk::ifunction(1) {} 32 | 33 | inline T operator()(const T& v) override 34 | { 35 | return std::sin((v * T(exprtk::details::numeric::constant::pi)) / T(180)); 36 | } 37 | }; 38 | 39 | template 40 | struct cosine_deg final : public exprtk::ifunction 41 | { 42 | using exprtk::ifunction::operator(); 43 | 44 | cosine_deg() : exprtk::ifunction(1) {} 45 | 46 | inline T operator()(const T& v) override 47 | { 48 | return std::cos((v * T(exprtk::details::numeric::constant::pi)) / T(180)); 49 | } 50 | }; 51 | 52 | template 53 | void exprtk_degree_trigonometry_example() 54 | { 55 | typedef exprtk::symbol_table symbol_table_t; 56 | typedef exprtk::expression expression_t; 57 | typedef exprtk::parser parser_t; 58 | typedef typename parser_t::settings_store settings_t; 59 | 60 | sine_deg sine; 61 | cosine_deg cosine; 62 | 63 | exprtk::rtl::io::package io_package; 64 | 65 | symbol_table_t symbol_table; 66 | 67 | symbol_table.add_package (io_package ); 68 | symbol_table.add_reserved_function("sin", sine ); 69 | symbol_table.add_reserved_function("cos", cosine); 70 | 71 | typedef typename parser_t::settings_store settings_t; 72 | 73 | parser_t parser; 74 | 75 | // Disable the ExprTk internal sine/cosine functions 76 | parser.settings() 77 | .disable_base_function(settings_t::e_bf_sin) 78 | .disable_base_function(settings_t::e_bf_cos); 79 | 80 | const std::string trigonometry_program = 81 | " println('sin(30) = ', sin(30)); " 82 | " println('cos(30) = ', cos(30)); " 83 | " println('sin(45) = ', sin(45)); " 84 | " println('cos(45) = ', cos(45)); " 85 | " println('sin(60) = ', sin(60)); " 86 | " println('cos(60) = ', cos(60)); "; 87 | 88 | expression_t expression; 89 | expression.register_symbol_table(symbol_table); 90 | 91 | parser.compile(trigonometry_program,expression); 92 | 93 | expression.value(); 94 | } 95 | 96 | int main() 97 | { 98 | exprtk_degree_trigonometry_example(); 99 | return 0; 100 | } 101 | -------------------------------------------------------------------------------- /exprtk_e_10kdigits.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Ten Thousand Digits Of E via Spigot Algorithm * 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 e_10k_digits() 28 | { 29 | typedef exprtk::symbol_table symbol_table_t; 30 | typedef exprtk::expression expression_t; 31 | typedef exprtk::parser parser_t; 32 | 33 | symbol_table_t symbol_table; 34 | 35 | symbol_table.add_function("print", 36 | [](T t) -> T 37 | { 38 | printf("%1d",static_cast(t)); 39 | return T(1); 40 | }); 41 | 42 | const std::string e_10k_digits_spigot = 43 | " const var num_digits := 10000; " 44 | " var a[num_digits] := [2:1]; " 45 | " var b[num_digits] := [1]; " 46 | " " 47 | " print(2); " 48 | " " 49 | " for (var digit := 0; digit < num_digits; digit += 1) " 50 | " { " 51 | " b *= 10; " 52 | " " 53 | " for (var i := (b[] - 1); i > 0; i -= 1) " 54 | " { " 55 | " var q := floor(b[i] / a[i]); " 56 | " var r := floor(b[i] % a[i]); " 57 | " b[i - 1] := b[i - 1] + q; " 58 | " b[i] := r; " 59 | " }; " 60 | " " 61 | " print(floor(b[0] / a[0])); " 62 | " " 63 | " b[0] %= a[0]; " 64 | " } "; 65 | 66 | expression_t expression; 67 | expression.register_symbol_table(symbol_table); 68 | 69 | parser_t parser; 70 | parser.compile(e_10k_digits_spigot,expression); 71 | 72 | expression.value(); 73 | } 74 | 75 | int main() 76 | { 77 | e_10k_digits(); 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /exprtk_extract_dependents.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Extract Expression Dependents * 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 extract_expression_dependents() 28 | { 29 | const std::string expression = "a * sin(3x) + foo(abs(y - z) / w)"; 30 | 31 | exprtk::symbol_table symbol_table; 32 | 33 | /* 34 | Note: Add any functions that are not part of the standard set 35 | of ExprTk functions 36 | */ 37 | symbol_table.add_function("foo",[](T /*t*/)->T { return T(0); }); 38 | 39 | std::deque variable_list; 40 | std::deque function_list; 41 | 42 | if (!exprtk::collect_variables(expression, symbol_table, variable_list)) 43 | { 44 | printf("Error: Failed to collect variables for expression: %s\n",expression.c_str()); 45 | variable_list.clear(); 46 | } 47 | 48 | if (!exprtk::collect_functions(expression, symbol_table, function_list)) 49 | { 50 | printf("Error: Failed to collect functions for expression: %s\n",expression.c_str()); 51 | function_list.clear(); 52 | } 53 | 54 | for (const auto& var : variable_list) 55 | { 56 | printf("variable: %s\n",var.c_str()); 57 | } 58 | 59 | for (const auto& func : function_list) 60 | { 61 | printf("function: %s\n",func.c_str()); 62 | } 63 | } 64 | 65 | int main() 66 | { 67 | extract_expression_dependents(); 68 | return 0; 69 | } 70 | 71 | 72 | /* 73 | 74 | Build: 75 | c++ -pedantic-errors -Wall -Wextra -Werror -o exprtk_extract_dependents exprtk_extract_dependents.cpp -L/usr/lib -lstdc++ -lm 76 | 77 | */ 78 | -------------------------------------------------------------------------------- /exprtk_factorize_fermat.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Fermat's Factorization Example * 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 factorize_fermats_method() 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 | // Form: n = p*q where p,q are prime 36 | T composites[] = 37 | { 38 | 199203677, 779234623, 843093203, 883543291, 1197162971, 1282615157, 1368190717, 39 | 1552390397, 1765737859, 1800091571, 1878769589, 1993904873, 2257133471, 2520523529, 40 | 2579094799, 2853450949, 2935025369, 3095780533, 3164132249, 3408963511, 4260042859, 41 | 4608613981, 4654875857, 5085931997, 6064982771, 7278175081, 7289187463, 9206112101 42 | }; 43 | 44 | exprtk::rtl::io::println println; 45 | 46 | symbol_table_t symbol_table; 47 | 48 | symbol_table.add_vector ("composites", composites); 49 | symbol_table.add_function("println" , println ); 50 | 51 | compositor_t compositor(symbol_table); 52 | 53 | compositor.add(function_t() 54 | .name("is_square") 55 | .var("x") 56 | .expression 57 | ( 58 | " var s := sqrt(x); " 59 | " var t := trunc(s); " 60 | " (s - t) == 0; " 61 | )); 62 | 63 | compositor.add(function_t() 64 | .name("fermat") 65 | .var("n") 66 | .expression 67 | ( 68 | " if (n == 0) " 69 | " { " 70 | " return [0]; " 71 | " } " 72 | " else if ((n % 2) == 0) " 73 | " { " 74 | " return [n / 2]; " 75 | " }; " 76 | " " 77 | " var a := ceil(sqrt(n)); " 78 | " " 79 | " while (not(is_square(a^2 - n))) " 80 | " { " 81 | " a += 1; " 82 | " }; " 83 | " " 84 | " var b := sqrt(a^2 - n); " 85 | " " 86 | " a - b; " 87 | )); 88 | 89 | const std::string factorize_composites_program = 90 | " for (var i := 0; i < composites[]; i += 1) " 91 | " { " 92 | " var n := composites[i]; " 93 | " var factor0 := fermat(n); " 94 | " var factor1 := n / factor0; " 95 | " " 96 | " if ((factor0 * factor1 == n) and (factor0 != 1)) " 97 | " { " 98 | " println('n: ', n, ' factors: { ', factor0 ,' , ', factor1 ,' } '); " 99 | " } " 100 | " else " 101 | " { " 102 | " println('failed to factorize ', n); " 103 | " } " 104 | " } " 105 | " "; 106 | expression_t expression; 107 | expression.register_symbol_table(symbol_table); 108 | 109 | parser_t parser; 110 | parser.compile(factorize_composites_program,expression); 111 | 112 | expression.value(); 113 | } 114 | 115 | int main() 116 | { 117 | factorize_fermats_method(); 118 | return 0; 119 | } 120 | -------------------------------------------------------------------------------- /exprtk_factorize_pollard.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Pollard's Rho Factorization Example * 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 factorize_pollards_rho() 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 | // Form: n = p*q where p,q are prime 36 | T composites[] = 37 | { 38 | 199203677, 779234623, 843093203, 883543291, 1197162971, 39 | 1282615157, 1552390397, 1765737859, 1878769589, 1993904873, 40 | 2257133471, 2520523529, 2579094799, 2853450949, 2935025369, 41 | 3095780533, 3164132249, 3408963511, 4260042859, 4608613981, 42 | 4654875857, 5085931997, 7278175081, 7289187463, 9206112101 43 | }; 44 | 45 | exprtk::rtl::io::println println; 46 | 47 | symbol_table_t symbol_table; 48 | 49 | symbol_table.add_vector ("composites", composites); 50 | symbol_table.add_function("println" , println ); 51 | 52 | compositor_t compositor(symbol_table); 53 | 54 | compositor.add(function_t() 55 | .name("gcd") 56 | .var("x") .var("y") 57 | .expression 58 | ( 59 | " x := abs(x); " 60 | " y := abs(y); " 61 | " while (0 != y) " 62 | " { " 63 | " var r := x % y; " 64 | " x := y; " 65 | " y := r; " 66 | " }; " 67 | " x " 68 | )); 69 | 70 | compositor.add(function_t() 71 | .name("pollard_rho") 72 | .var("n") 73 | .expression 74 | ( 75 | " var c := 10; " 76 | " var a1 := 1 + c; " 77 | " var a2 := 11 + c; " 78 | " " 79 | " while (gcd(n, a2 - a1) == 1) " 80 | " { " 81 | " /* The Tortoise */ " 82 | " a1 := (a1^2 + c) % n; " 83 | " " 84 | " /* The Hare */ " 85 | " a2 := (a2^2 + c) % n; " 86 | " a2 := (a2^2 + c) % n; " 87 | " }; " 88 | " " 89 | " var g := gcd(n, a2 - a1); " 90 | " " 91 | " n / g " 92 | )); 93 | 94 | const std::string factorize_composites_program = 95 | " for (var i := 0; i < composites[]; i += 1) " 96 | " { " 97 | " var n := composites[i]; " 98 | " var factor0 := pollard_rho(n); " 99 | " var factor1 := n / factor0; " 100 | " " 101 | " if ((factor0 * factor1 == n) and (factor0 != 1)) " 102 | " { " 103 | " println('n: ', n, ' factors: { ', factor0 ,' , ', factor1 ,' } '); " 104 | " } " 105 | " else " 106 | " { " 107 | " println('failed to factorize ', n); " 108 | " } " 109 | " } " 110 | " "; 111 | expression_t expression; 112 | expression.register_symbol_table(symbol_table); 113 | 114 | parser_t parser; 115 | parser.compile(factorize_composites_program,expression); 116 | 117 | expression.value(); 118 | } 119 | 120 | int main() 121 | { 122 | factorize_pollards_rho(); 123 | return 0; 124 | } 125 | -------------------------------------------------------------------------------- /exprtk_fizzbuzz.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Fizz-Buzz Example * 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 fizzbuzz() 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 fizzbuzz_program = 34 | " var x := 1; " 35 | " repeat " 36 | " var div3 := ((x % 3) == 0); " 37 | " var div5 := ((x % 5) == 0); " 38 | " [*] " 39 | " { " 40 | " case div3 : print('fizz'); " 41 | " case div5 : print('buzz'); " 42 | " case div3 nor div5 : print(x); " 43 | " }; " 44 | " print('\n') " 45 | " until ((x += 1) > 100); "; 46 | 47 | exprtk::rtl::io::print print; 48 | 49 | symbol_table_t symbol_table; 50 | symbol_table.add_function("print",print); 51 | 52 | expression_t expression; 53 | expression.register_symbol_table(symbol_table); 54 | 55 | parser_t parser; 56 | parser.compile(fizzbuzz_program,expression); 57 | 58 | expression.value(); 59 | } 60 | 61 | int main() 62 | { 63 | fizzbuzz(); 64 | return 0; 65 | } 66 | -------------------------------------------------------------------------------- /exprtk_funcall_benchmark.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Function Call Benchmark (Custom vs Composite vs Native) * 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 func0 : public exprtk::ifunction 28 | { 29 | using exprtk::ifunction::operator(); 30 | 31 | func0() 32 | : exprtk::ifunction(2) 33 | {} 34 | 35 | inline T operator()(const T& v1, const T& v2) 36 | { 37 | return T(1) + std::cos(v1 * v2) / T(3); 38 | } 39 | }; 40 | 41 | template 42 | inline T func1(T v1, T v2) 43 | { 44 | return T(1) + std::cos(v1 * v2) / T(3); 45 | } 46 | 47 | template 48 | void function_call_benchmark01() 49 | { 50 | typedef exprtk::symbol_table symbol_table_t; 51 | typedef exprtk::expression expression_t; 52 | typedef exprtk::parser parser_t; 53 | typedef exprtk::function_compositor compositor_t; 54 | typedef typename compositor_t::function function_t; 55 | 56 | T v1 = T(1); 57 | T v2 = T(2); 58 | 59 | func0 f0; 60 | 61 | symbol_table_t symbol_table; 62 | 63 | symbol_table.add_constants(); 64 | 65 | symbol_table.add_variable("v1" , v1 ); 66 | symbol_table.add_variable("v2" , v2 ); 67 | symbol_table.add_function("func0", f0 ); 68 | symbol_table.add_function("func1", func1); 69 | 70 | compositor_t compositor(symbol_table); 71 | 72 | compositor.add( 73 | function_t("func2") 74 | .var("v1").var("v2") 75 | .expression(" 1 + cos(v1 * v2) / 3;")); 76 | 77 | const std::string program0 = "func0(v1,v2);"; 78 | const std::string program1 = "func1(v1,v2);"; 79 | const std::string program2 = "func2(v1,v2);"; 80 | 81 | expression_t expression0(symbol_table); 82 | expression_t expression1(symbol_table); 83 | expression_t expression2(symbol_table); 84 | 85 | parser_t parser; 86 | 87 | if (!parser.compile(program0,expression0)) 88 | { 89 | printf("Error: %s\tExpression: %s\n", 90 | parser.error().c_str(), 91 | program0.c_str()); 92 | 93 | return; 94 | } 95 | 96 | if (!parser.compile(program1,expression1)) 97 | { 98 | printf("Error: %s\tExpression: %s\n", 99 | parser.error().c_str(), 100 | program1.c_str()); 101 | 102 | return; 103 | } 104 | 105 | if (!parser.compile(program2,expression2)) 106 | { 107 | printf("Error: %s\tExpression: %s\n", 108 | parser.error().c_str(), 109 | program1.c_str()); 110 | 111 | return; 112 | } 113 | 114 | const std::size_t rounds = 100000000; 115 | 116 | { 117 | T total = T(0); 118 | 119 | exprtk::timer timer; 120 | timer.start(); 121 | 122 | for (std::size_t r = 0; r < rounds; ++r) 123 | { 124 | total += expression0.value(); 125 | std::swap(v1,v2); 126 | } 127 | 128 | timer.stop(); 129 | 130 | printf("[custom function] Total time: %8.3fsec\tRate: %15.3f\tTotal:%20.5f\n", 131 | timer.time(), 132 | rounds / timer.time(), 133 | total); 134 | } 135 | 136 | { 137 | T total = T(0); 138 | 139 | exprtk::timer timer; 140 | timer.start(); 141 | 142 | for (std::size_t r = 0; r < rounds; ++r) 143 | { 144 | total += expression1.value(); 145 | std::swap(v1,v2); 146 | } 147 | 148 | timer.stop(); 149 | 150 | printf("[free function ] Total time: %8.3fsec\tRate: %15.3f\tTotal:%20.5f\n", 151 | timer.time(), 152 | rounds / timer.time(), 153 | total); 154 | } 155 | 156 | { 157 | T total = T(0); 158 | 159 | exprtk::timer timer; 160 | timer.start(); 161 | 162 | for (std::size_t r = 0; r < rounds; ++r) 163 | { 164 | total += expression2.value(); 165 | std::swap(v1,v2); 166 | } 167 | 168 | timer.stop(); 169 | 170 | printf("[compositor ] Total time: %8.3fsec\tRate: %15.3f\tTotal:%20.5f\n", 171 | timer.time(), 172 | rounds / timer.time(), 173 | total); 174 | } 175 | 176 | { 177 | T total = T(0); 178 | 179 | exprtk::timer timer; 180 | timer.start(); 181 | 182 | for (std::size_t r = 0; r < rounds; ++r) 183 | { 184 | total += func1(v1,v2); 185 | std::swap(v1,v2); 186 | } 187 | 188 | timer.stop(); 189 | 190 | printf("[native ] Total time: %8.3fsec\tRate: %15.3f\tTotal:%20.5f\n", 191 | timer.time(), 192 | rounds / timer.time(), 193 | total); 194 | } 195 | } 196 | 197 | int main() 198 | { 199 | function_call_benchmark01(); 200 | return 0; 201 | } 202 | -------------------------------------------------------------------------------- /exprtk_gcd.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Greatest Common Divisor Example * 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 | T gcd_println(T x, T y, T z) 28 | { 29 | printf("gcd(%2d,%2d) = %2d\n", 30 | static_cast(x), 31 | static_cast(y), 32 | static_cast(z)); 33 | 34 | return T(0); 35 | } 36 | 37 | template 38 | void gcd() 39 | { 40 | typedef exprtk::symbol_table symbol_table_t; 41 | typedef exprtk::expression expression_t; 42 | typedef exprtk::parser parser_t; 43 | typedef exprtk::function_compositor compositor_t; 44 | typedef typename compositor_t::function function_t; 45 | 46 | symbol_table_t symbol_table; 47 | symbol_table.add_function("println",gcd_println); 48 | 49 | compositor_t compositor(symbol_table); 50 | 51 | // define function: gcd(x,y) 52 | compositor.add( 53 | function_t("gcd") 54 | .vars("x","y") 55 | .expression 56 | ( 57 | " switch " 58 | " { " 59 | " case 0 = x : 0; " 60 | " case 0 = y : x; " 61 | " case x = y : x; " 62 | " case x > y : gcd(x - y, y); " 63 | " default : gcd(x, y - x); " 64 | " } " 65 | )); 66 | 67 | const std::string gcd_program = 68 | " i := 0; " 69 | " while ((i += 1) < 100) " 70 | " { " 71 | " j := 0; " 72 | " repeat " 73 | " println(i, j, gcd(i,j)); " 74 | " until ((j += 1) >= 100); " 75 | " }; "; 76 | 77 | expression_t expression; 78 | expression.register_symbol_table(symbol_table); 79 | 80 | parser_t parser; 81 | parser.enable_unknown_symbol_resolver(); 82 | parser.compile(gcd_program,expression); 83 | 84 | expression.value(); 85 | } 86 | 87 | int main() 88 | { 89 | gcd(); 90 | return 0; 91 | } 92 | -------------------------------------------------------------------------------- /exprtk_gnuplot.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk GNUPlot Example * 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 | class exprtk_gnuplot_fx 30 | { 31 | public: 32 | 33 | exprtk_gnuplot_fx() 34 | : min_x_(0.0) 35 | , max_x_(0.0) 36 | , min_y_(0.0) 37 | , max_y_(0.0) 38 | {} 39 | 40 | exprtk_gnuplot_fx& set_title(const std::string& title) 41 | { 42 | title_ = title; 43 | return *this; 44 | } 45 | 46 | exprtk_gnuplot_fx& set_domain(const double min_x, const double max_x) 47 | { 48 | min_x_ = min_x; 49 | max_x_ = max_x; 50 | return *this; 51 | } 52 | 53 | exprtk_gnuplot_fx& set_expression(const std::string& expression) 54 | { 55 | expression_ = expression; 56 | return *this; 57 | } 58 | 59 | bool plot() 60 | { 61 | if (!generate_data()) 62 | return false; 63 | else 64 | return generate_gp_script(); 65 | } 66 | 67 | private: 68 | 69 | bool generate_gp_script() 70 | { 71 | std::ofstream stream("plot.gp"); 72 | 73 | if (!stream) 74 | { 75 | return false; 76 | } 77 | 78 | stream << "set term png\n"; 79 | stream << "set output 'plot.png'\n"; 80 | stream << "set xrange[" << min_x_ << ":" << max_x_ <<"]\n"; 81 | stream << "set yrange[" << min_y_ << ":" << max_y_ <<"]\n"; 82 | stream << "set xzeroaxis\n"; 83 | stream << "set yzeroaxis\n"; 84 | stream << "plot 'data.dat' using 1:2:(1.0) smooth unique title '" << title_ <<"'\n"; 85 | 86 | return true; 87 | } 88 | 89 | bool generate_data() 90 | { 91 | typedef exprtk::symbol_table symbol_table_t; 92 | typedef exprtk::expression expression_t; 93 | typedef exprtk::parser parser_t; 94 | 95 | double x = 0.0; 96 | 97 | symbol_table_t symbol_table; 98 | symbol_table.add_constants(); 99 | symbol_table.add_variable("x",x); 100 | 101 | expression_t expression; 102 | expression.register_symbol_table(symbol_table); 103 | 104 | parser_t parser; 105 | 106 | if (!parser.compile(expression_,expression)) 107 | { 108 | return false; 109 | } 110 | 111 | std::ofstream stream("data.dat"); 112 | 113 | if (!stream) 114 | { 115 | return false; 116 | } 117 | 118 | min_y_ = +std::numeric_limits::max(); 119 | max_y_ = -std::numeric_limits::max(); 120 | 121 | stream << std::setprecision(10); 122 | 123 | const double increment = std::min(0.00005,std::abs(max_x_ - min_x_) / 1000.0); 124 | 125 | for (x = min_x_; x <= max_x_; x += increment) 126 | { 127 | const double y = expression.value(); 128 | 129 | if (y < min_y_) min_y_ = y; 130 | else if (y > max_y_) max_y_ = y; 131 | 132 | stream << x << "\t" << y << "\n"; 133 | } 134 | 135 | const double diff_y = std::abs(max_y_ - min_y_); 136 | const double perc7_5 = diff_y * 0.075; //7.5% 137 | 138 | min_y_ -= perc7_5; 139 | max_y_ += perc7_5; 140 | 141 | return true; 142 | } 143 | 144 | std::string title_; 145 | std::string expression_; 146 | double min_x_; 147 | double max_x_; 148 | double min_y_; 149 | double max_y_; 150 | }; 151 | 152 | int main() 153 | { 154 | exprtk_gnuplot_fx plotter; 155 | 156 | plotter 157 | .set_expression("clamp(-1.0,sin(2 * pi * x) + cos(x / 2 * pi),+1.0)") 158 | .set_domain(-5,+5) 159 | .set_title("ExprTk GNUPlot Example"); 160 | 161 | plotter.plot(); 162 | 163 | return 0; 164 | } 165 | 166 | 167 | /* 168 | Build and Run: 169 | 1. c++ -ansi -pedantic-errors -Wall -Wextra -Werror -Wno-long-long -O3 -DNDEBUG -o exprtk_gnuplot exprtk_gnuplot.cpp -lstdc++ 170 | 2. ./exprtk_gnuplot 171 | 3. gnuplot plot.gp 172 | */ 173 | -------------------------------------------------------------------------------- /exprtk_gnuplot_multi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk GNUPlot Multi-Curve Example * 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 | class exprtk_gnuplot_fx; 30 | 31 | class exprtk_fx_curve 32 | { 33 | public: 34 | 35 | friend class exprtk_gnuplot_fx; 36 | 37 | exprtk_fx_curve& set_title(const std::string& title) 38 | { 39 | title_ = title; 40 | return *this; 41 | } 42 | 43 | exprtk_fx_curve& set_domain(const double min_x, const double max_x) 44 | { 45 | min_x_ = min_x; 46 | max_x_ = max_x; 47 | return *this; 48 | } 49 | 50 | exprtk_fx_curve& set_expression(const std::string& expression) 51 | { 52 | expression_ = expression; 53 | return *this; 54 | } 55 | 56 | private: 57 | 58 | std::string title_; 59 | std::string expression_; 60 | double min_x_; 61 | double max_x_; 62 | double min_y_; 63 | double max_y_; 64 | }; 65 | 66 | class exprtk_gnuplot_fx 67 | { 68 | public: 69 | 70 | bool plot() 71 | { 72 | for (std::size_t i = 0; i < curve_list_.size(); ++i) 73 | { 74 | if (!generate_data(i,curve_list_[i])) 75 | return false; 76 | } 77 | 78 | return generate_gp_script(); 79 | } 80 | 81 | exprtk_gnuplot_fx& add_curve(const exprtk_fx_curve& curve) 82 | { 83 | curve_list_.push_back(curve); 84 | return *this; 85 | } 86 | 87 | private: 88 | 89 | bool generate_gp_script() 90 | { 91 | std::ofstream stream("plot.gp"); 92 | 93 | if (!stream) 94 | { 95 | return false; 96 | } 97 | 98 | double min_x = +std::numeric_limits::max(); 99 | double max_x = -std::numeric_limits::max(); 100 | double min_y = +std::numeric_limits::max(); 101 | double max_y = -std::numeric_limits::max(); 102 | 103 | for (std::size_t i = 0; i < curve_list_.size(); ++i) 104 | { 105 | exprtk_fx_curve& curve = curve_list_[i]; 106 | 107 | if (curve.min_x_ < min_x) min_x = curve.min_x_; 108 | if (curve.max_x_ > max_x) max_x = curve.max_x_; 109 | if (curve.min_y_ < min_y) min_y = curve.min_y_; 110 | if (curve.max_y_ > max_y) max_y = curve.max_y_; 111 | } 112 | 113 | stream << "set term png\n"; 114 | stream << "set output 'plot.png'\n"; 115 | stream << "set xrange[" << min_x << ":" << max_x <<"]\n"; 116 | stream << "set yrange[" << min_y << ":" << max_y <<"]\n"; 117 | stream << "set xzeroaxis\n"; 118 | stream << "set yzeroaxis\n"; 119 | stream << "plot \\\n"; 120 | 121 | for (std::size_t i = 0; i < curve_list_.size(); ++i) 122 | { 123 | stream << "'data.dat" << i << "' using 1:2:(1.0) smooth unique title '" << curve_list_[i].title_; 124 | stream << (((i + 1) < curve_list_.size()) ? "',\\\n" : "'\n"); 125 | } 126 | 127 | return true; 128 | } 129 | 130 | bool generate_data(const std::size_t index, exprtk_fx_curve& curve) 131 | { 132 | typedef exprtk::symbol_table symbol_table_t; 133 | typedef exprtk::expression expression_t; 134 | typedef exprtk::parser parser_t; 135 | 136 | double x = 0.0; 137 | 138 | symbol_table_t symbol_table; 139 | symbol_table.add_constants(); 140 | symbol_table.add_variable("x",x); 141 | 142 | expression_t expression; 143 | expression.register_symbol_table(symbol_table); 144 | 145 | parser_t parser; 146 | 147 | if (!parser.compile(curve.expression_,expression)) 148 | { 149 | return false; 150 | } 151 | 152 | const std::string file_name = std::string("data.dat") + (char)('0' + index); 153 | 154 | std::ofstream stream(file_name.c_str()); 155 | 156 | if (!stream) 157 | { 158 | return false; 159 | } 160 | 161 | curve.min_y_ = +std::numeric_limits::max(); 162 | curve.max_y_ = -std::numeric_limits::max(); 163 | 164 | stream << std::setprecision(10); 165 | 166 | const double increment = std::min(0.00005,std::abs(curve.max_x_ - curve.min_x_) / 1000.0); 167 | 168 | for (x = curve.min_x_; x <= curve.max_x_; x += increment) 169 | { 170 | const double y = expression.value(); 171 | 172 | if (y < curve.min_y_) curve.min_y_ = y; 173 | else if (y > curve.max_y_) curve.max_y_ = y; 174 | 175 | stream << x << "\t" << y << "\n"; 176 | } 177 | 178 | const double diff_y = std::abs(curve.max_y_ - curve.min_y_); 179 | const double perc7_5 = diff_y * 0.075; //7.5% 180 | 181 | curve.min_y_ -= perc7_5; 182 | curve.max_y_ += perc7_5; 183 | 184 | return true; 185 | } 186 | 187 | std::deque curve_list_; 188 | }; 189 | 190 | int main() 191 | { 192 | exprtk_gnuplot_fx plotter; 193 | 194 | plotter 195 | .add_curve( 196 | exprtk_fx_curve() 197 | .set_expression("sin(2 * pi * x) + cos(x / 2 * pi)") 198 | .set_domain(-5,+5) 199 | .set_title("ExprTk Curve 1")) 200 | 201 | .add_curve( 202 | exprtk_fx_curve() 203 | .set_expression("clamp(-1.0,sin(2 * pi * x) + cos(x / 2 * pi),+1.0)") 204 | .set_domain(-5,+5) 205 | .set_title("ExprTk Curve 2")); 206 | 207 | plotter.plot(); 208 | 209 | return 0; 210 | } 211 | 212 | 213 | /* 214 | Build and Run: 215 | 1. c++ -pedantic-errors -Wall -Wextra -Werror -Wno-long-long -O3 -DNDEBUG -o exprtk_gnuplot_multi exprtk_gnuplot_multi.cpp -lstdc++ 216 | 2. ./exprtk_gnuplot_multi 217 | 3. gnuplot plot.gp 218 | */ 219 | -------------------------------------------------------------------------------- /exprtk_immutable_symbol_table_example.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Immutable Symbol Table Example * 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 | template 30 | void immutable_symtab_example() 31 | { 32 | typedef exprtk::symbol_table symbol_table_t; 33 | typedef exprtk::expression expression_t; 34 | typedef exprtk::parser parser_t; 35 | 36 | T x = 1.1; 37 | T y = 2.2; 38 | T z = 3.3; 39 | T w = 4.4; 40 | 41 | symbol_table_t mutable_symbol_table; 42 | symbol_table_t immutable_symbol_table(symbol_table_t::symtab_mutability_type::e_immutable); 43 | 44 | mutable_symbol_table.add_variable("x", x); 45 | mutable_symbol_table.add_variable("y", y); 46 | 47 | immutable_symbol_table.add_variable("z", z); 48 | immutable_symbol_table.add_variable("w", w); 49 | 50 | expression_t expression; 51 | expression.register_symbol_table(immutable_symbol_table); 52 | expression.register_symbol_table(mutable_symbol_table ); 53 | 54 | parser_t parser; 55 | 56 | const std::vector expressions = 57 | { 58 | "x := y + (z / w)", // ok - will compile 59 | "y := y / x + (z / w)", // ok - will compile 60 | "z := y + x - w", // Error - will not compile 61 | "z == (w := y / x)", // Error - will not compile 62 | }; 63 | 64 | for (const auto& expression_str : expressions) 65 | { 66 | 67 | if (!parser.compile(expression_str, expression)) 68 | { 69 | for (std::size_t error_idx = 0; error_idx < parser.error_count(); ++error_idx) 70 | { 71 | const auto error = parser.get_error(error_idx); 72 | 73 | printf("Error: %02d Pos: %02d Type: [%14s] Message: %s\tExpression: %s\n", 74 | static_cast(error_idx), 75 | static_cast(error.token.position), 76 | exprtk::parser_error::to_str(error.mode).c_str(), 77 | error.diagnostic.c_str(), 78 | expression_str.c_str()); 79 | } 80 | 81 | continue; 82 | } 83 | 84 | // Modify all the variables from both the immutable 85 | // and mutable symbol tables 86 | 87 | x += 1.1; 88 | y += 2.2; 89 | z += 3.3; 90 | w += 4.4; 91 | 92 | expression.value(); 93 | } 94 | 95 | return; 96 | } 97 | 98 | int main() 99 | { 100 | immutable_symtab_example(); 101 | return 0; 102 | } 103 | 104 | 105 | -------------------------------------------------------------------------------- /exprtk_import_packages.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Import Packages Examples * 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 | class import_packages : public exprtk::igeneric_function 29 | { 30 | public: 31 | 32 | typedef typename exprtk::igeneric_function igfun_t; 33 | typedef typename igfun_t::parameter_list_t parameter_list_t; 34 | typedef typename igfun_t::generic_type generic_type; 35 | typedef typename generic_type::scalar_view scalar_t; 36 | typedef typename generic_type::string_view string_t; 37 | typedef exprtk::symbol_table symbol_table_t; 38 | typedef std::function import_func_t; 39 | typedef std::map package_map_t; 40 | 41 | using igfun_t::operator(); 42 | 43 | import_packages(symbol_table_t& symbol_table) 44 | : igfun_t("S") 45 | , symbol_table_(symbol_table) 46 | { 47 | igfun_t::has_side_effects() = false; 48 | 49 | package_map_.emplace( 50 | "exprtk.rtl.io" , 51 | [&](symbol_table_t& symbtab) -> bool { return symbtab.add_package(io_package); }); 52 | 53 | package_map_.emplace( 54 | "exprtk.rtl.io.file", 55 | [&](symbol_table_t& symbtab) -> bool { return symbtab.add_package(file_package); }); 56 | 57 | package_map_.emplace( 58 | "exprtk.rtl.vecops" , 59 | [&](symbol_table_t& symbtab) -> bool { return symbtab.add_package(vector_package); }); 60 | } 61 | 62 | inline T operator()(parameter_list_t parameters) override 63 | { 64 | const string_t package(parameters[0]); 65 | 66 | const auto itr = package_map_.find(exprtk::to_str(package)); 67 | 68 | if (package_map_.end() == itr) 69 | { 70 | return T(0); 71 | } 72 | 73 | return itr->second(symbol_table_) ? T(1) : T(0); 74 | } 75 | 76 | private: 77 | 78 | symbol_table_t& symbol_table_; 79 | package_map_t package_map_; 80 | exprtk::rtl::io::package io_package; 81 | exprtk::rtl::io::file::package file_package; 82 | exprtk::rtl::vecops::package vector_package; 83 | }; 84 | 85 | template 86 | void import_package_example() 87 | { 88 | typedef exprtk::symbol_table symbol_table_t; 89 | typedef exprtk::expression expression_t; 90 | typedef exprtk::parser parser_t; 91 | 92 | symbol_table_t symbol_table; 93 | 94 | import_packages import_package(symbol_table); 95 | 96 | symbol_table.add_function("import",import_package); 97 | 98 | expression_t expression; 99 | expression.register_symbol_table(symbol_table); 100 | 101 | parser_t parser; 102 | 103 | const std::string import_packages_program = 104 | " import('exprtk.rtl.io' ); " 105 | " import('exprtk.rtl.io.file'); " 106 | " import('exprtk.rtl.vecops' ); " 107 | " " 108 | " var v[7] := [1:1]; " 109 | " " 110 | " println('v: ', v); " 111 | " " 112 | " reverse(v); " 113 | " " 114 | " println('reversed v: ', v); " 115 | " "; 116 | 117 | parser.compile(import_packages_program, expression); 118 | 119 | expression.value(); 120 | } 121 | 122 | int main() 123 | { 124 | import_package_example(); 125 | return 0; 126 | } 127 | -------------------------------------------------------------------------------- /exprtk_jump_diffusion_process.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Merton Jump Diffusion Process Option Pricing Model * 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 european_option_merton_jump_diffusion_process() 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 european_option_merton_jump_diffusion_process_program = 36 | " var lambda_t := lambda * t; " 37 | " var v_sqr := v^2; " 38 | " var sigmaJ_sqr := sigmaJ^2; " 39 | " " 40 | " var option_price := 0; " 41 | " var factorial := 1; " 42 | " " 43 | " for (var i := 0; i < n; i += 1) " 44 | " { " 45 | " var prob := exp(-lambda_t) * lambda_t^i / factorial; " 46 | " var r_i := r - lambda * muJ + (i / t) * log(1 + muJ); " 47 | " var sigma_i := sqrt(v_sqr + (i * sigmaJ_sqr) / t); " 48 | " " 49 | " option_price += " 50 | " switch " 51 | " { " 52 | " case callput_flag == 'call' : prob * bsm_call(s, k, r_i, t, sigma_i); " 53 | " case callput_flag == 'put' : prob * bsm_put (s, k, r_i, t, sigma_i); " 54 | " }; " 55 | " " 56 | " factorial *= (i > 1) ? i : 1; " 57 | " }; " 58 | " " 59 | " option_price; "; 60 | 61 | T s = T(100.00); // Spot / Stock / Underlying / Base price 62 | T k = T(110.00); // Strike price 63 | T v = T( 0.30); // Volatility 64 | T t = T( 2.22); // Years to maturity 65 | T r = T( 0.05); // Risk free rate 66 | T lambda = T(0.0001); // Jump intensity (average jumps per year) 67 | T muJ = T( -0.05); // Mean jump size (negative for downward jumps) 68 | T sigmaJ = T( 0.30); // Standard deviation of the jump size 69 | T n = T( 50.00); // Number of terms in the Poisson sum 70 | 71 | std::string callput_flag; 72 | 73 | symbol_table_t symbol_table(symbol_table_t::e_immutable); 74 | symbol_table.add_variable ("s" , s ); 75 | symbol_table.add_variable ("k" , k ); 76 | symbol_table.add_variable ("v" , v ); 77 | symbol_table.add_variable ("t" , t ); 78 | symbol_table.add_variable ("r" , r ); 79 | symbol_table.add_variable ("lambda", lambda); 80 | symbol_table.add_variable ("muJ" , muJ ); 81 | symbol_table.add_variable ("sigmaJ", sigmaJ); 82 | symbol_table.add_variable ("n" , n ); 83 | symbol_table.add_stringvar("callput_flag",callput_flag); 84 | symbol_table.add_pi(); 85 | 86 | compositor_t compositor(symbol_table); 87 | 88 | compositor.add( 89 | function_t("bsm_call") 90 | .vars("s", "k", "r", "t", "v") 91 | .expression 92 | ( 93 | " var d1 := (log(s / k) + (r + v^2 / 2) * t) / (v * sqrt(t)); " 94 | " var d2 := d1 - v * sqrt(t); " 95 | " s * ncdf(d1) - k * exp(-r * t) * ncdf(d2); " 96 | )); 97 | 98 | compositor.add( 99 | function_t("bsm_put") 100 | .vars("s", "k", "r", "t", "v") 101 | .expression 102 | ( 103 | " var d1 := (log(s / k) + (r + v^2 / 2) * t) / (v * sqrt(t)); " 104 | " var d2 := d1 - v * sqrt(t); " 105 | " k * exp(-r * t) * ncdf(-d2) - s * ncdf(-d1); " 106 | )); 107 | 108 | expression_t expression; 109 | expression.register_symbol_table(symbol_table); 110 | 111 | parser_t parser; 112 | parser.compile(european_option_merton_jump_diffusion_process_program, expression); 113 | 114 | callput_flag = "call"; 115 | 116 | const T jdp_call_option_price = expression.value(); 117 | 118 | callput_flag = "put"; 119 | 120 | const T jdp_put_option_price = expression.value(); 121 | 122 | printf("JDPPrice(%4s, %5.3f, %5.3f, %5.3f, %5.3f, %5.3f) = %10.6f\n", 123 | "call", 124 | s, k, t, r, v, 125 | jdp_call_option_price); 126 | 127 | printf("JDPPrice(%4s, %5.3f, %5.3f, %5.3f, %5.3f, %5.3f) = %10.6f\n", 128 | "put", 129 | s, k, t, r, v, 130 | jdp_put_option_price); 131 | 132 | const T put_call_parity_diff = 133 | (jdp_call_option_price - jdp_put_option_price) - 134 | (s - k * std::exp(-r * t)); 135 | 136 | printf("Put-Call parity difference: %20.17f\n", put_call_parity_diff); 137 | } 138 | 139 | int main() 140 | { 141 | european_option_merton_jump_diffusion_process(); 142 | return 0; 143 | } 144 | -------------------------------------------------------------------------------- /exprtk_loop_timeout_rtc.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Loop Timeout RTC * 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 | struct timeout_rtc_handler final : public exprtk::loop_runtime_check 28 | { 29 | timeout_rtc_handler() 30 | : exprtk::loop_runtime_check() 31 | {} 32 | 33 | class timeout_exception final : public std::runtime_error 34 | { 35 | public: 36 | 37 | timeout_exception(const std::string& what = "") 38 | : std::runtime_error(what) 39 | {} 40 | }; 41 | 42 | using time_point_t = std::chrono::time_point; 43 | 44 | void set_timeout_time(const time_point_t& timeout_tp) 45 | { 46 | timeout_tp_ = timeout_tp; 47 | } 48 | 49 | bool check() override 50 | { 51 | static constexpr std::size_t max_iters_per_check = 100000; 52 | 53 | if (++iterations_ >= max_iters_per_check) 54 | { 55 | if (std::chrono::steady_clock::now() >= timeout_tp_) 56 | { 57 | return false; 58 | } 59 | 60 | iterations_ = 0; 61 | } 62 | 63 | return true; 64 | } 65 | 66 | void handle_runtime_violation(const violation_context&) override 67 | { 68 | throw timeout_exception("Loop run-time timeout violation."); 69 | } 70 | 71 | std::size_t iterations_ = 0; 72 | time_point_t timeout_tp_; 73 | }; 74 | 75 | struct vector_access_rtc final : public exprtk::vector_access_runtime_check 76 | { 77 | bool handle_runtime_violation(violation_context&) override 78 | { 79 | throw std::runtime_error("Runtime vector access violation."); 80 | return false; 81 | } 82 | }; 83 | 84 | template 85 | void loop_timeout_rtc() 86 | { 87 | typedef exprtk::expression expression_t; 88 | typedef exprtk::parser parser_t; 89 | typedef exprtk::loop_runtime_check loop_runtime_check_t; 90 | 91 | const std::string sieve_of_eratosthenes_program = 92 | " var sieve[10^8] := [false]; " 93 | " var m := trunc(sqrt(sieve[])); " 94 | " " 95 | " sieve[0] := true; " 96 | " sieve[1] := true; " 97 | " " 98 | " for (var i := 0; i <= m; i += 1) " 99 | " { " 100 | " if (false == sieve[i]) " 101 | " { " 102 | " for (var j := i^2; j < sieve[]; j += i) " 103 | " { " 104 | " sieve[j] := true; " 105 | " } " 106 | " } " 107 | " }; " 108 | " " 109 | " var prime_count := sieve[] - sum(sieve); " 110 | " " 111 | " prime_count == 5761455; "; 112 | 113 | timeout_rtc_handler loop_runtime_check; 114 | loop_runtime_check.loop_set = loop_runtime_check_t::e_all_loops; 115 | loop_runtime_check.max_loop_iterations = 116 | static_cast(10e8 * std::log10(std::log10(10e8))); // O(n) = nlog(log(n)) 117 | 118 | vector_access_rtc vec_rtc; 119 | 120 | expression_t expression; 121 | 122 | parser_t parser; 123 | 124 | parser.register_loop_runtime_check(loop_runtime_check); 125 | parser.register_vector_access_runtime_check(vec_rtc); 126 | 127 | parser.compile(sieve_of_eratosthenes_program,expression); 128 | 129 | const auto max_duration = std::chrono::seconds(1); 130 | const auto timeout_tp = std::chrono::steady_clock::now() + max_duration; 131 | loop_runtime_check.set_timeout_time(timeout_tp); 132 | 133 | try 134 | { 135 | expression.value(); 136 | } 137 | catch (timeout_rtc_handler::timeout_exception& /*toe*/) 138 | { 139 | printf("Timeout Exception\n"); 140 | } 141 | catch (std::runtime_error& rte) 142 | { 143 | printf("Exception: %s\n",rte.what()); 144 | } 145 | 146 | parser.clear_loop_runtime_check(); 147 | } 148 | 149 | int main() 150 | { 151 | loop_timeout_rtc(); 152 | return 0; 153 | } 154 | -------------------------------------------------------------------------------- /exprtk_magic_square.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Magic Square * 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 magic_square() 27 | { 28 | typedef exprtk::symbol_table symbol_table_t; 29 | typedef exprtk::expression expression_t; 30 | typedef exprtk::parser parser_t; 31 | typedef exprtk::function_compositor compositor_t; 32 | typedef typename compositor_t::function function_t; 33 | 34 | const T n = T(15); 35 | std::vector square(static_cast(n * n), T(0)); 36 | 37 | exprtk::rtl::io::package io_package; 38 | 39 | symbol_table_t symbol_table; 40 | symbol_table.add_constant("n", n); 41 | symbol_table.add_vector ("square", square); 42 | symbol_table.add_function("print_digit", 43 | [](T v) ->T 44 | { printf(" %03d ",static_cast(v)); return 0; }); 45 | symbol_table.add_package (io_package); 46 | 47 | compositor_t compositor(symbol_table); 48 | 49 | compositor.load_variables(true); 50 | compositor.load_vectors (true); 51 | 52 | compositor.add( 53 | function_t("get_square") 54 | .vars("col", "row") 55 | .expression 56 | ( " square[row * n + col]; " )); 57 | 58 | compositor.add( 59 | function_t("set_square") 60 | .vars("col", "row", "value") 61 | .expression 62 | ( " square[row * n + col] := value; " )); 63 | 64 | compositor.add( 65 | function_t("display_magic_square") 66 | .expression 67 | ( 68 | " for (var row := 0; row < n; row += 1) " 69 | " { " 70 | " for (var col := 0; col < n; col += 1) " 71 | " { " 72 | " print_digit(get_square(col,row)); " 73 | " }; " 74 | " " 75 | " println(''); " 76 | " } " 77 | )); 78 | 79 | const std::string magic_square_program = 80 | " var num := 1; " 81 | " var i := 0; " 82 | " var j := floor(n / 2); " 83 | " " 84 | " while (num <= (n * n)) " 85 | " { " 86 | " set_square(i, j, num); " 87 | " num += 1; " 88 | " " 89 | " var i_next := (i - 1 + n) % n; " 90 | " var j_next := (j + 1) % n; " 91 | " " 92 | " if (get_square(i_next, j_next) != 0) " 93 | " { " 94 | " i := (i + 1) % n; " 95 | " } " 96 | " else " 97 | " { " 98 | " i := i_next; " 99 | " j := j_next; " 100 | " } " 101 | " }; " 102 | " " 103 | " println('sum: ', n * (n^2 + 1) / 2); " 104 | " " 105 | " display_magic_square(); "; 106 | 107 | expression_t expression; 108 | expression.register_symbol_table(symbol_table); 109 | 110 | parser_t parser; 111 | parser.compile(magic_square_program,expression); 112 | 113 | expression.value(); 114 | } 115 | 116 | int main() 117 | { 118 | magic_square(); 119 | return 0; 120 | } 121 | -------------------------------------------------------------------------------- /exprtk_mandelbrot.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Mandelbrot Fractal Generator Example * 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 | inline T putch(T v) 28 | { 29 | printf("%c",static_cast(v)); 30 | return T(0); 31 | } 32 | 33 | template 34 | void mandelbrot() 35 | { 36 | typedef exprtk::symbol_table symbol_table_t; 37 | typedef exprtk::expression expression_t; 38 | typedef exprtk::parser parser_t; 39 | 40 | const std::string mandelbrot_program = 41 | " width := 118; " 42 | " height := 41; " 43 | " imag_max := +1; " 44 | " imag_min := -1; " 45 | " real_max := +1; " 46 | " real_min := -2.5; " 47 | " x_step := (real_max - real_min) / width; " 48 | " y_step := (imag_max - imag_min) / height; " 49 | " " 50 | " for (var y := 0; y < height; y += 1) " 51 | " { " 52 | " imag := imag_min + (y_step * y); " 53 | " " 54 | " for (var x := 0; x < width; x += 1) " 55 | " { " 56 | " real := real_min + x_step * x; " 57 | " z_real := real; " 58 | " z_imag := imag; " 59 | " " 60 | " for (var n := 0; n < 30; n += 1) " 61 | " { " 62 | " a := z_real^2; " 63 | " b := z_imag^2; " 64 | " plot_value := n; " 65 | " " 66 | " if ((a + b) < 4) " 67 | " { " 68 | " z_imag := 2 * z_real * z_imag + imag; " 69 | " z_real := a - b + real; " 70 | " } " 71 | " else " 72 | " break; " 73 | " }; " 74 | " " 75 | " putch(61 - plot_value); " 76 | " }; " 77 | " " 78 | " println() " 79 | " } "; 80 | 81 | exprtk::rtl::io::println println; 82 | 83 | symbol_table_t symbol_table; 84 | symbol_table.add_function("putch" , putch ); 85 | symbol_table.add_function("println", println); 86 | 87 | expression_t expression; 88 | expression.register_symbol_table(symbol_table); 89 | 90 | parser_t parser; 91 | parser.enable_unknown_symbol_resolver(); 92 | parser.compile(mandelbrot_program,expression); 93 | 94 | expression.value(); 95 | } 96 | 97 | int main() 98 | { 99 | mandelbrot(); 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /exprtk_max_subarray_sum.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Maximum Subarray Problem * 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 max_subarray_sum() 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 max_subarray_sum_program = 34 | " var zero := 0; " 35 | " var curr_sum := 0; " 36 | " var curr_start := 0; " 37 | " " 38 | " for (var i := 0; i < vec[]; i += 1) " 39 | " { " 40 | " curr_sum += vec[i]; " 41 | " " 42 | " if (curr_sum < zero) " 43 | " { " 44 | " curr_sum := 0; " 45 | " curr_start := i + 1; " 46 | " } " 47 | " else if (curr_sum > max_sum) " 48 | " { " 49 | " max_sum := curr_sum; " 50 | " max_start := curr_start; " 51 | " max_end := i; " 52 | " } " 53 | " } "; 54 | 55 | T max_sum = T(0); 56 | T max_start = T(0); 57 | T max_end = T(0); 58 | 59 | T vec[] = { T(-1), T(-2), T(3), T(5), T(6), T(-2), T(-1), T(4), T(-4), T(2), T(-1) }; 60 | 61 | symbol_table_t symbol_table; 62 | 63 | symbol_table.add_variable("max_sum" , max_sum ); 64 | symbol_table.add_variable("max_start", max_start); 65 | symbol_table.add_variable("max_end" , max_end ); 66 | symbol_table.add_vector ("vec" , vec ); 67 | 68 | expression_t expression; 69 | expression.register_symbol_table(symbol_table); 70 | 71 | parser_t parser; 72 | parser.compile(max_subarray_sum_program,expression); 73 | 74 | expression.value(); 75 | 76 | if (max_start <= max_end) 77 | { 78 | printf("Max sum: %10.3f \n", max_sum); 79 | printf("Start index: %4d\n", static_cast(max_start)); 80 | printf("End index: %4d\n", static_cast(max_end )); 81 | 82 | for (int i = static_cast(max_start); i <= static_cast(max_end); ++i) 83 | { 84 | printf("%5.3f ",vec[i]); 85 | } 86 | 87 | printf("\n"); 88 | } 89 | else 90 | printf("No maximum sum found.\n"); 91 | } 92 | 93 | int main() 94 | { 95 | max_subarray_sum(); 96 | return 0; 97 | } 98 | -------------------------------------------------------------------------------- /exprtk_montecarlo_e.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Approximation of e via Monte-Carlo Method * 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_e() 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_e_program = 52 | " var max_samples := 10^8; " 53 | " var trials := 0; " 54 | " " 55 | " for (var i := 0; i < max_samples; i += 1) " 56 | " { " 57 | " var rand_sum := 0; " 58 | " repeat " 59 | " rand_sum += rnd_01; " 60 | " trials += 1; " 61 | " until (rand_sum > 1); " 62 | " }; " 63 | " " 64 | " trials / max_samples; "; 65 | 66 | rnd_01 rnd01; 67 | 68 | symbol_table_t symbol_table; 69 | symbol_table.add_function("rnd_01",rnd01); 70 | 71 | expression_t expression; 72 | expression.register_symbol_table(symbol_table); 73 | 74 | parser_t parser; 75 | parser.compile(monte_carlo_e_program,expression); 76 | 77 | const T approximate_e = expression.value(); 78 | 79 | const T real_e = T(2.718281828459045235360287471352662); // or close enough... 80 | 81 | printf("e ~ %20.17f\terror: %20.17f\n", 82 | approximate_e, 83 | std::abs(real_e - approximate_e)); 84 | } 85 | 86 | int main() 87 | { 88 | monte_carlo_e(); 89 | return 0; 90 | } 91 | -------------------------------------------------------------------------------- /exprtk_montecarlo_option_pricing_model.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Monte-Carlo Based European Option Pricing Model * 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 | template 30 | struct normal_distribution final : public exprtk::ifunction 31 | { 32 | using exprtk::ifunction::operator(); 33 | 34 | normal_distribution() 35 | : exprtk::ifunction(2) 36 | { 37 | std::random_device device; 38 | std::array seed; 39 | std::generate_n(seed.data(), seed.size(), std::ref(device)); 40 | std::seed_seq seq(std::begin(seed), std::end(seed)); 41 | generator.seed(seq); 42 | } 43 | 44 | inline T operator()(const T& mean, const T& stddev) override 45 | { 46 | std::normal_distribution distribution{mean, stddev}; 47 | return distribution(generator); 48 | } 49 | 50 | std::mt19937 generator; 51 | }; 52 | 53 | template 54 | void exprtk_montecarlo_option_pricing_model() 55 | { 56 | typedef exprtk::symbol_table symbol_table_t; 57 | typedef exprtk::expression expression_t; 58 | typedef exprtk::parser parser_t; 59 | 60 | const std::string exprtk_montecarlo_option_pricing_model_program = 61 | " var payoff_sum := 0; " 62 | " var sqrt_t := sqrt(t); " 63 | " " 64 | " for (var i := 0; i < n; i += 1) " 65 | " { " 66 | " var s_t := s * exp((r - v^2 / 2) * t + v * sqrt_t * normal(0,1)); " 67 | " payoff_sum += " 68 | " switch " 69 | " { " 70 | " case callput_flag == 'call' : max(s_t - k, 0); " 71 | " case callput_flag == 'put' : max(k - s_t, 0); " 72 | " }; " 73 | " }; " 74 | " " 75 | " exp(-r * t) * payoff_sum / n; "; 76 | 77 | T s = T(100.00); // Spot / Stock / Underlying / Base price 78 | T k = T(110.00); // Strike price 79 | T v = T( 0.30); // Volatility 80 | T t = T( 2.22); // Years to maturity 81 | T r = T( 0.05); // Risk free rate 82 | T n = T( 2.0e7); // Number of simulations 83 | 84 | std::string callput_flag; 85 | 86 | normal_distribution normal; 87 | 88 | symbol_table_t symbol_table(symbol_table_t::e_immutable); 89 | symbol_table.add_variable("s",s); 90 | symbol_table.add_variable("k",k); 91 | symbol_table.add_variable("t",t); 92 | symbol_table.add_variable("r",r); 93 | symbol_table.add_variable("v",v); 94 | symbol_table.add_constant("n",n); 95 | symbol_table.add_stringvar("callput_flag", callput_flag); 96 | symbol_table.add_function ("normal" , normal ); 97 | 98 | expression_t expression; 99 | expression.register_symbol_table(symbol_table); 100 | 101 | parser_t parser; 102 | parser.compile(exprtk_montecarlo_option_pricing_model_program, expression); 103 | 104 | callput_flag = "call"; 105 | 106 | const T montecarlo_call_option_price = expression.value(); 107 | 108 | callput_flag = "put"; 109 | 110 | const T montecarlo_put_option_price = expression.value(); 111 | 112 | printf("MCOptionPrice(call, %5.3f, %5.3f, %5.3f, %5.3f, %5.3f) = %10.6f\n", 113 | s, k, t, r, v, 114 | montecarlo_call_option_price); 115 | 116 | printf("MCOptionPrice(put , %5.3f, %5.3f, %5.3f, %5.3f, %5.3f) = %10.6f\n", 117 | s, k, t, r, v, 118 | montecarlo_put_option_price); 119 | 120 | const double put_call_parity_diff = 121 | (montecarlo_call_option_price - montecarlo_put_option_price) - 122 | (s - k * std::exp(-r * t)); 123 | 124 | printf("Put-Call parity difference: %20.17f\n", put_call_parity_diff); 125 | } 126 | 127 | int main() 128 | { 129 | exprtk_montecarlo_option_pricing_model(); 130 | return 0; 131 | } 132 | -------------------------------------------------------------------------------- /exprtk_montecarlo_pi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Approximation of Pi via Monte-Carlo Method * 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 max_samples := 5 * 10^7; " 53 | " var count := 0; " 54 | " " 55 | " for (var i := 0; i < max_samples; i += 1) " 56 | " { " 57 | " if ((rnd_01^2 + rnd_01^2) <= 1) " 58 | " count += 1; " 59 | " }; " 60 | " " 61 | " (4 * count) / max_samples; "; 62 | 63 | rnd_01 rnd01; 64 | 65 | symbol_table_t symbol_table; 66 | symbol_table.add_function("rnd_01",rnd01); 67 | 68 | expression_t expression; 69 | expression.register_symbol_table(symbol_table); 70 | 71 | parser_t parser; 72 | parser.compile(monte_carlo_pi_program,expression); 73 | 74 | const T approximate_pi = expression.value(); 75 | 76 | const T real_pi = T(3.141592653589793238462643383279502); // or close enough... 77 | 78 | printf("pi ~ %20.17f\terror: %20.17f\n", 79 | approximate_pi, 80 | std::abs(real_pi - approximate_pi)); 81 | } 82 | 83 | int main() 84 | { 85 | monte_carlo_pi(); 86 | return 0; 87 | } 88 | -------------------------------------------------------------------------------- /exprtk_naive_primes.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Primes Via The Naive Method * 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_via_naive_method() 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 | compositor_t compositor; 36 | 37 | compositor.add( 38 | function_t("is_prime") 39 | .var("x") 40 | .expression 41 | ( 42 | " switch " 43 | " { " 44 | " case x <= 1 : return [false]; " 45 | " case frac(x) != 0 : return [false]; " 46 | " case x == 2 : return [true ]; " 47 | " default : " 48 | " { " 49 | " var prime_lut[81] := " 50 | " { " 51 | " 2, 3, 5, 7, 11, 13, 17, 19, 23, " 52 | " 29, 31, 37, 41, 43, 47, 53, 59, 61, " 53 | " 67, 71, 73, 79, 83, 89, 97, 101, 103, " 54 | " 107, 109, 113, 127, 131, 137, 139, 149, 151, " 55 | " 157, 163, 167, 173, 179, 181, 191, 193, 197, " 56 | " 199, 211, 223, 227, 229, 233, 239, 241, 251, " 57 | " 257, 263, 269, 271, 277, 281, 283, 293, 307, " 58 | " 311, 313, 317, 331, 337, 347, 349, 353, 359, " 59 | " 367, 373, 379, 383, 389, 397, 401, 409, 419 " 60 | " }; " 61 | " " 62 | " var upper_bound := min(x - 1, trunc(sqrt(x)) + 1); " 63 | " " 64 | " for (var i := 0; i < prime_lut[]; i += 1) " 65 | " { " 66 | " if (prime_lut[i] >= upper_bound) " 67 | " return [true]; " 68 | " else if ((x % prime_lut[i]) == 0) " 69 | " return [false]; " 70 | " }; " 71 | " " 72 | " var lower_bound := prime_lut[prime_lut[] - 1] + 2; " 73 | " " 74 | " for (var i := lower_bound; i < upper_bound; i += 2) " 75 | " { " 76 | " if ((x % i) == 0) " 77 | " { " 78 | " return [false]; " 79 | " } " 80 | " } " 81 | " }; " 82 | " }; " 83 | " " 84 | " return [true]; " 85 | )); 86 | 87 | const std::string primes_via_naive_method_program = 88 | " for (var i := 1; i < 10000; i += 1) " 89 | " { " 90 | " if (is_prime(i)) " 91 | " { " 92 | " println(i, ' is prime'); " 93 | " } " 94 | " }; "; 95 | 96 | exprtk::rtl::io::println println; 97 | 98 | symbol_table_t& symbol_table = compositor.symbol_table(); 99 | symbol_table.add_function("println",println); 100 | 101 | expression_t expression; 102 | expression.register_symbol_table(symbol_table); 103 | 104 | parser_t parser; 105 | parser.compile(primes_via_naive_method_program,expression); 106 | 107 | expression.value(); 108 | } 109 | 110 | int main() 111 | { 112 | primes_via_naive_method(); 113 | return 0; 114 | } 115 | -------------------------------------------------------------------------------- /exprtk_normal_random_marsaglia_method.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Normal Random Variables Via Marsaglia Method * 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 | template 30 | struct uniform_random_01 final : public exprtk::ifunction 31 | { 32 | using exprtk::ifunction::operator(); 33 | 34 | uniform_random_01() 35 | : exprtk::ifunction(0) 36 | { 37 | std::random_device device; 38 | std::array seed; 39 | std::generate_n(seed.data(), seed.size(), std::ref(device)); 40 | std::seed_seq seq(std::begin(seed), std::end(seed)); 41 | generator.seed(seq); 42 | } 43 | 44 | inline T operator()() override 45 | { 46 | return distribution(generator); 47 | } 48 | 49 | std::mt19937 generator; 50 | std::uniform_real_distribution distribution{ T(0), T(1) }; 51 | }; 52 | 53 | template 54 | void normal_random_marsaglia_method() 55 | { 56 | typedef exprtk::symbol_table symbol_table_t; 57 | typedef exprtk::expression expression_t; 58 | typedef exprtk::parser parser_t; 59 | typedef exprtk::function_compositor compositor_t; 60 | typedef typename compositor_t::function function_t; 61 | 62 | exprtk::rtl::io::println println; 63 | uniform_random_01 unirandom; 64 | 65 | symbol_table_t symbol_table; 66 | symbol_table.add_function("println", println ); 67 | symbol_table.add_function("random" , unirandom); 68 | symbol_table.add_constants(); 69 | 70 | compositor_t compositor(symbol_table); 71 | 72 | compositor.add( 73 | function_t("normal_distribution") 74 | .vars("mean", "stddev") 75 | .expression 76 | ( 77 | " var u := 0; " 78 | " var v := 0; " 79 | " var s := 0; " 80 | " " 81 | " repeat " 82 | " u := random() * 2 - 1; " 83 | " v := random() * 2 - 1; " 84 | " s := u^2 + v^2; " 85 | " until (s > 0 and s < 1); " 86 | " " 87 | " s := sqrt(-2 * log(s) / s); " 88 | " mean + stddev * u * s; " 89 | )); 90 | 91 | const std::string normal_random_marsaglia_method_program = 92 | " const var mean := pi; " 93 | " const var stddev := 3 * mean / 2; " 94 | " const var num_samples := 1e7; " 95 | " var values[num_samples] := [normal_distribution(mean, stddev)]; " 96 | " " 97 | " var sample_mean := avg(values); " 98 | " var sample_stddev := sqrt(sum([values - sample_mean]^2) / values[]); " 99 | " " 100 | " println('sample mean: ', sample_mean , ' error: ', abs(sample_mean - mean)); " 101 | " println('sample stddev: ', sample_stddev, ' error: ', abs(sample_stddev - stddev)); " 102 | " " 103 | " "; 104 | 105 | expression_t expression; 106 | expression.register_symbol_table(symbol_table); 107 | 108 | parser_t parser; 109 | parser.compile(normal_random_marsaglia_method_program,expression); 110 | 111 | expression.value(); 112 | } 113 | 114 | int main() 115 | { 116 | normal_random_marsaglia_method(); 117 | return 0; 118 | } 119 | -------------------------------------------------------------------------------- /exprtk_nqueens_problem.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk N-Queens Problem * 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 sudoku_solver() 27 | { 28 | typedef exprtk::symbol_table symbol_table_t; 29 | typedef exprtk::expression expression_t; 30 | typedef exprtk::parser parser_t; 31 | typedef exprtk::function_compositor compositor_t; 32 | typedef typename compositor_t::function function_t; 33 | 34 | const T n = T(15); 35 | std::vector board(static_cast(n), T(- 1)); 36 | 37 | exprtk::rtl::io::package io_package; 38 | 39 | symbol_table_t symbol_table; 40 | symbol_table.add_constant("n" , n ); 41 | symbol_table.add_vector ("board" , board); 42 | symbol_table.add_package (io_package); 43 | 44 | compositor_t compositor(symbol_table); 45 | 46 | compositor.load_variables(true); 47 | compositor.load_vectors (true); 48 | 49 | compositor.add( 50 | function_t("display_board") 51 | .expression 52 | ( 53 | " for (var row := 0; row < n; row += 1) " 54 | " { " 55 | " for (var col := 0; col < n; col += 1) " 56 | " { " 57 | " print((board[row] == col) ? ' Q ' : ' . '); " 58 | " }; " 59 | " " 60 | " println(''); " 61 | " } " 62 | )); 63 | 64 | compositor.add( 65 | function_t("is_valid") 66 | .vars("row", "col") 67 | .expression 68 | ( 69 | " for (var i := 0; i < row; i += 1) " 70 | " { " 71 | " if ( " 72 | " (board[i] == col) or " 73 | " (abs(board[i] - col) == abs(i - row)) " 74 | " ) " 75 | " { " 76 | " return [false]; " 77 | " } " 78 | " }; " 79 | " " 80 | " return [true]; " 81 | )); 82 | 83 | compositor.add( 84 | function_t("solve_nqueens") 85 | .var("row") 86 | .expression 87 | ( 88 | " if (row == n) " 89 | " { " 90 | " return [true]; " 91 | " }; " 92 | " " 93 | " for (var col := 0; col < n; col += 1) " 94 | " { " 95 | " if (is_valid(row, col)) " 96 | " { " 97 | " board[row] := col; " 98 | " " 99 | " if (solve_nqueens(row + 1)) " 100 | " { " 101 | " return [true]; " 102 | " } " 103 | " } " 104 | " }; " 105 | " " 106 | " return [false]; " 107 | )); 108 | 109 | const std::string sudoku_solver_program = 110 | " if (solve_nqueens(0)) " 111 | " { " 112 | " println('N-Queens Puzzle Solved!'); " 113 | " } " 114 | " else " 115 | " { " 116 | " println('Error: Failed to solve n-queens puzzle.'); " 117 | " }; " 118 | " " 119 | " display_board(); "; 120 | 121 | expression_t expression; 122 | expression.register_symbol_table(symbol_table); 123 | 124 | parser_t parser; 125 | parser.compile(sudoku_solver_program,expression); 126 | 127 | expression.value(); 128 | } 129 | 130 | int main() 131 | { 132 | sudoku_solver(); 133 | return 0; 134 | } 135 | -------------------------------------------------------------------------------- /exprtk_nthroot_bisection.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Nth-Root via Bisection Method * 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 nthroot_via_bisection() 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 | const std::string nthroot_via_bisection_program = 37 | " for (var x := -30; x <= 30; x += 1) " 38 | " { " 39 | " println('[', x, ']', " 40 | " ' sqrt = ', nthroot(x,2), " 41 | " ' cbrt = ', nthroot(x,3)); " 42 | " } "; 43 | 44 | exprtk::rtl::io::println println; 45 | 46 | symbol_table_t symbol_table; 47 | symbol_table.add_function("println",println); 48 | 49 | compositor_t compositor(symbol_table); 50 | 51 | // define function: nthroot(x,n) 52 | compositor.add( 53 | function_t("nthroot") 54 | .var("x") 55 | .var("n") 56 | .expression 57 | ( 58 | " if (abs(frac(n)) > 0) " 59 | " return [null]; " 60 | " else if (x < 0 and (n % 2 == 0)) " 61 | " return [null]; " 62 | " " 63 | " var lo := min(0,x); " 64 | " var hi := max(0,x); " 65 | " " 66 | " while (true) " 67 | " { " 68 | " var mid := avg(lo,hi); " 69 | " var y := pow(mid,n); " 70 | " " 71 | " if (equal(y, x)) " 72 | " break [mid]; " 73 | " else if (y < x) " 74 | " lo := mid; " 75 | " else " 76 | " hi := mid; " 77 | " }; " 78 | )); 79 | 80 | expression_t expression; 81 | expression.register_symbol_table(symbol_table); 82 | 83 | parser_t parser; 84 | parser.compile(nthroot_via_bisection_program, expression); 85 | 86 | expression.value(); 87 | } 88 | 89 | int main() 90 | { 91 | nthroot_via_bisection(); 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /exprtk_ornstein_uhlenbeck_process.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Ornstein-Uhlenbeck Process * 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 | template 30 | struct normal_distribution final : public exprtk::ifunction 31 | { 32 | using exprtk::ifunction::operator(); 33 | 34 | normal_distribution() 35 | : exprtk::ifunction(2) 36 | { 37 | std::random_device device; 38 | std::array seed; 39 | std::generate_n(seed.data(), seed.size(), std::ref(device)); 40 | std::seed_seq seq(std::begin(seed), std::end(seed)); 41 | generator.seed(seq); 42 | } 43 | 44 | inline T operator()(const T& mean, const T& stddev) override 45 | { 46 | std::normal_distribution distribution{mean, stddev}; 47 | return distribution(generator); 48 | } 49 | 50 | std::mt19937 generator; 51 | }; 52 | 53 | template 54 | void ornstein_uhlenbeck_process() 55 | { 56 | typedef exprtk::symbol_table symbol_table_t; 57 | typedef exprtk::expression expression_t; 58 | typedef exprtk::parser parser_t; 59 | 60 | const std::string ornstein_uhlenbeck_process_program = 61 | " const var mu := 1; " 62 | " const var sigma := 0.4; " 63 | " const var theta := 2; " 64 | " const var tau := 1 / theta; " 65 | " const var T := 10 * tau; " 66 | " const var dt := 0.01 * tau; " 67 | " const var num_steps := floor(T / dt); " 68 | " const var stddev := sqrt(sigma^2 / (2 * theta) * (1 - exp(-2 * theta * dt))); " 69 | " const var x_0 := 1.0; " 70 | " " 71 | " var x[num_steps] := [0]; " 72 | " " 73 | " x[0] := x_0; " 74 | " " 75 | " for (var i := 0; i < num_steps - 1; i += 1) " 76 | " { " 77 | " var mean := x[i] * exp(-theta * dt) + mu * (1 - exp(-theta * dt)); " 78 | " " 79 | " x[i + 1] := normal(mean,stddev); " 80 | " }; " 81 | " " 82 | " " 83 | " for (var i := 0; i < x[]; i += 1) " 84 | " { " 85 | " println(i * dt, '\t', x[i]); " 86 | " } "; 87 | 88 | 89 | exprtk::rtl::io::println println; 90 | normal_distribution normal; 91 | 92 | symbol_table_t symbol_table; 93 | symbol_table.add_function("println", println); 94 | symbol_table.add_function("normal" , normal ); 95 | 96 | expression_t expression; 97 | expression.register_symbol_table(symbol_table); 98 | 99 | parser_t parser; 100 | parser.compile(ornstein_uhlenbeck_process_program,expression); 101 | 102 | expression.value(); 103 | } 104 | 105 | int main() 106 | { 107 | ornstein_uhlenbeck_process(); 108 | return 0; 109 | } 110 | -------------------------------------------------------------------------------- /exprtk_pascals_triangle.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Pascal's Triangle * 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 pascals_triangle() 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 | exprtk::rtl::io::package io_package; 36 | 37 | symbol_table_t symbol_table; 38 | symbol_table.add_package(io_package); 39 | symbol_table.add_function("print_coeff", 40 | [](T t) 41 | { 42 | printf("%6d", static_cast(t)); 43 | return T(0); 44 | }); 45 | 46 | compositor_t compositor(symbol_table); 47 | 48 | compositor.add( 49 | function_t("n_choose_k") 50 | .vars("n","k") 51 | .expression 52 | ( 53 | " switch " 54 | " { " 55 | " case n <= k : 1; " 56 | " case k <= 0 : 1; " 57 | " default : n_choose_k(n - 1, k - 1) + " 58 | " n_choose_k(n - 1, k ) ; " 59 | " } " 60 | )); 61 | 62 | const std::string pascals_triangle_program = 63 | " const var rows := 20; " 64 | " " 65 | " for (var n := 0; n < rows; n += 1) " 66 | " { " 67 | " for (var s := 0; s <= (rows - n) - 2; s += 1) " 68 | " { " 69 | " print(' '); " 70 | " }; " 71 | " " 72 | " for (var k := 0; k <= n; k += 1) " 73 | " { " 74 | " print_coeff(n_choose_k(n,k)); " 75 | " }; " 76 | " " 77 | " println(); " 78 | " } "; 79 | 80 | expression_t expression; 81 | expression.register_symbol_table(symbol_table); 82 | 83 | parser_t parser; 84 | parser.compile(pascals_triangle_program,expression); 85 | 86 | expression.value(); 87 | } 88 | 89 | int main() 90 | { 91 | pascals_triangle(); 92 | return 0; 93 | } 94 | -------------------------------------------------------------------------------- /exprtk_pi_10kdigits.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Ten Thousand Digits Of Pi via Spigot Algorithm * 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 pi_10k_digits() 28 | { 29 | typedef exprtk::symbol_table symbol_table_t; 30 | typedef exprtk::expression expression_t; 31 | typedef exprtk::parser parser_t; 32 | 33 | symbol_table_t symbol_table; 34 | 35 | symbol_table.add_function("print", 36 | [](T t) -> T 37 | { 38 | printf("%1d",static_cast(t)); 39 | return T(1); 40 | }); 41 | 42 | const std::string pi_10k_digits_spigot = 43 | " const var num_digits := 10000; " 44 | " const var offset := 14; " 45 | " var a[3.5 * num_digits + offset]; " 46 | " var size := a[] - offset; " 47 | " var d := 0; " 48 | " var c := 0; " 49 | " var h := 0; " 50 | " var f := size / 3.5; " 51 | " " 52 | " for (var x := 0; x < size ; x += offset) " 53 | " { " 54 | " var b := size - x - 1; " 55 | " var g := 2 * b; " 56 | " " 57 | " d %= f; " 58 | " c := d; " 59 | " " 60 | " while (g > 0) " 61 | " { " 62 | " var k := floor(b); " 63 | " var i := (h > 0) ? a[k] : floor(f / 5); " 64 | " d := (d * b) + (f * i); " 65 | " g -= 1; " 66 | " b -= 1; " 67 | " a[k] := d % g; " 68 | " d := floor(d / g); " 69 | " g := 2 * b; " 70 | " }; " 71 | " " 72 | " var v := c + floor((1 * d) / f); " 73 | " " 74 | " for (var j := 1000; j >= 1; j := j / 10) " 75 | " { " 76 | " print(floor(v / j)); " 77 | " v %= j; " 78 | " }; " 79 | " " 80 | " h := 1; " 81 | " } "; 82 | 83 | expression_t expression; 84 | expression.register_symbol_table(symbol_table); 85 | 86 | parser_t parser; 87 | parser.compile(pi_10k_digits_spigot,expression); 88 | 89 | expression.value(); 90 | } 91 | 92 | int main() 93 | { 94 | pi_10k_digits(); 95 | return 0; 96 | } 97 | -------------------------------------------------------------------------------- /exprtk_prime_sieve.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Sieve Of Eratosthenes * 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 sieve_of_eratosthenes() 28 | { 29 | typedef exprtk::expression expression_t; 30 | typedef exprtk::parser parser_t; 31 | 32 | const std::string sieve_of_eratosthenes_program = 33 | " var sieve[10^8] := [false]; " 34 | " var m := trunc(sqrt(sieve[])); " 35 | " " 36 | " sieve[0] := true; " 37 | " sieve[1] := true; " 38 | " " 39 | " for (var i := 0; i <= m; i += 1) " 40 | " { " 41 | " if (false == sieve[i]) " 42 | " { " 43 | " for (var j := i^2; j < sieve[]; j += i) " 44 | " { " 45 | " sieve[j] := true; " 46 | " } " 47 | " } " 48 | " }; " 49 | " " 50 | " var prime_count := sieve[] - sum(sieve); " 51 | " " 52 | " prime_count == 5761455; "; 53 | 54 | expression_t expression; 55 | 56 | parser_t parser; 57 | parser.compile(sieve_of_eratosthenes_program,expression); 58 | 59 | exprtk::timer timer; 60 | timer.start(); 61 | 62 | const T result = expression.value(); 63 | 64 | timer.stop(); 65 | 66 | printf("Result: %8.3f\n",result); 67 | 68 | printf("Total time: %8.3fsec\n",timer.time()); 69 | } 70 | 71 | int main() 72 | { 73 | sieve_of_eratosthenes(); 74 | return 0; 75 | } 76 | -------------------------------------------------------------------------------- /exprtk_prime_sieve_vectorized.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Sieve Of Eratosthenes Vectorized * 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 sieve_of_eratosthenes_vectorized() 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 sieve_of_eratosthenes_program = 34 | " var sieve[10^8] := [false]; " 35 | " var m := trunc(sqrt(sieve[])); " 36 | " " 37 | " sieve[0] := true; " 38 | " sieve[1] := true; " 39 | " " 40 | " for (var i := 0; i <= m; i += 1) " 41 | " { " 42 | " if (false == sieve[i]) " 43 | " { " 44 | " assign(sieve, true, i^2, sieve[] - 1, i); " 45 | " } " 46 | " }; " 47 | " " 48 | " var prime_count := sieve[] - sum(sieve); " 49 | " " 50 | " prime_count == 5761455; "; 51 | 52 | symbol_table_t symbol_table; 53 | exprtk::rtl::vecops::package vector_package; 54 | 55 | symbol_table.add_package(vector_package); 56 | 57 | expression_t expression; 58 | expression.register_symbol_table(symbol_table); 59 | 60 | parser_t parser; 61 | parser.compile(sieve_of_eratosthenes_program,expression); 62 | 63 | exprtk::timer timer; 64 | timer.start(); 65 | 66 | const T result = expression.value(); 67 | 68 | timer.stop(); 69 | 70 | printf("Result: %8.3f\n",result); 71 | 72 | printf("Total time: %8.3fsec\n",timer.time()); 73 | } 74 | 75 | int main() 76 | { 77 | sieve_of_eratosthenes_vectorized(); 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /exprtk_pyramid.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Pyramid * 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 pyramid() 28 | { 29 | typedef exprtk::symbol_table symbol_table_t; 30 | typedef exprtk::expression expression_t; 31 | typedef exprtk::parser parser_t; 32 | 33 | exprtk::rtl::io::package io_package; 34 | 35 | symbol_table_t symbol_table; 36 | 37 | symbol_table.add_package(io_package); 38 | 39 | const std::string pyramid_program = 40 | " const var n := 30; " 41 | " " 42 | " for (var i := 0; i < n; i += 1) " 43 | " { " 44 | " for (var j := 0; j < n - i - 1; j += 1) " 45 | " { " 46 | " print(' '); " 47 | " }; " 48 | " " 49 | " for (var j := 0; j < 2 * i + 1; j += 1) " 50 | " { " 51 | " print('*'); " 52 | " }; " 53 | " " 54 | " println(); " 55 | " } "; 56 | 57 | expression_t expression; 58 | expression.register_symbol_table(symbol_table); 59 | 60 | parser_t parser; 61 | parser.compile(pyramid_program,expression); 62 | 63 | expression.value(); 64 | } 65 | 66 | int main() 67 | { 68 | pyramid(); 69 | return 0; 70 | } 71 | -------------------------------------------------------------------------------- /exprtk_pythagorean_triples.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Pythagorean Triples * 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 exprtk_pythagorean_triples() 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 pythagorean_triples_program = 34 | " const var num_triples := 1000; " 35 | " var triple_count := 0; " 36 | " var n := 2; " 37 | " " 38 | " while (true) " 39 | " { " 40 | " for (var i := 1; i < n; i += 1) " 41 | " { " 42 | " var a := n^2 - i^2; " 43 | " var b := 2 * n * i; " 44 | " var c := n^2 + i^2; " 45 | " " 46 | " if (a > b) a <=> b; " 47 | " if (b > c) b <=> c; " 48 | " if (a > b) a <=> b; " 49 | " " 50 | " println('(', a ,',', b ,',', c ,')'); " 51 | " " 52 | " if ((triple_count += 1) >= num_triples) " 53 | " { " 54 | " return []; " 55 | " }; " 56 | " }; " 57 | " " 58 | " n += 1; " 59 | " } "; 60 | 61 | exprtk::rtl::io::println println; 62 | 63 | symbol_table_t symbol_table; 64 | symbol_table.add_function ("println", println); 65 | 66 | expression_t expression; 67 | expression.register_symbol_table(symbol_table); 68 | 69 | parser_t parser; 70 | parser.compile(pythagorean_triples_program, expression); 71 | 72 | expression.value(); 73 | } 74 | 75 | int main() 76 | { 77 | exprtk_pythagorean_triples(); 78 | return 0; 79 | } 80 | -------------------------------------------------------------------------------- /exprtk_recursive_fibonacci.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Recursive Fibonacci Example * 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 recursive_fibonacci_example() 27 | { 28 | typedef exprtk::symbol_table symbol_table_t; 29 | typedef exprtk::expression expression_t; 30 | typedef exprtk::parser parser_t; 31 | typedef exprtk::function_compositor compositor_t; 32 | typedef typename compositor_t::function function_t; 33 | 34 | exprtk::rtl::io::package io_package; 35 | 36 | symbol_table_t symbol_table; 37 | 38 | symbol_table.add_package(io_package); 39 | 40 | compositor_t compositor(symbol_table); 41 | 42 | compositor.add( 43 | function_t("fibonacci") 44 | .var("n") 45 | .expression 46 | ( " (n < 2) ? n : fibonacci(n - 1) + fibonacci(n - 2); " )); 47 | 48 | 49 | const std::string fibonacci_program = 50 | " const var n := 35; " 51 | " " 52 | " for (var i := 0; i <= n; i += 1) " 53 | " { " 54 | " var fib_i := fibonacci(i); " 55 | " println('fib(',i,') = ', fib_i); " 56 | " } "; 57 | 58 | expression_t expression; 59 | expression.register_symbol_table(symbol_table); 60 | 61 | parser_t parser; 62 | parser.compile(fibonacci_program,expression); 63 | 64 | exprtk::timer timer; 65 | timer.start(); 66 | 67 | expression.value(); 68 | 69 | timer.stop(); 70 | 71 | printf("Total time: %8.4fsec\n",timer.time()); 72 | } 73 | 74 | int main() 75 | { 76 | recursive_fibonacci_example(); 77 | return 0; 78 | } 79 | -------------------------------------------------------------------------------- /exprtk_riddle.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Logical Deduction Riddle * 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 | /* 21 | 22 | The Broken Window Riddle 23 | 24 | A window has been broken, there are 5 suspects (Annie, Betsy, Chloe, 25 | Tori and Zoey). Each suspect is asked who they think broke the window. 26 | 27 | The following is each suspect's statement: 28 | 29 | Tori : It wasn't Zoey, It was Annie 30 | Annie: It wasn't Betsy, It wasn't Zoey 31 | Betsy: It was Zoey, It wasn't Tori 32 | Chloe: It was Betsy, It was Annie 33 | Zoey : It was Chloe, It wasn't Tori 34 | 35 | Given each of the suspects spoke only one lie and one truth, and only 36 | one person is responsible for the broken window: 37 | 38 | Who then was it that broke the window? 39 | 40 | */ 41 | 42 | #include 43 | 44 | #include "exprtk.hpp" 45 | 46 | 47 | template 48 | void logical_deducation_riddle() 49 | { 50 | typedef exprtk::symbol_table symbol_table_t; 51 | typedef exprtk::expression expression_t; 52 | typedef exprtk::parser parser_t; 53 | typedef exprtk::function_compositor compositor_t; 54 | typedef typename compositor_t::function function_t; 55 | 56 | symbol_table_t symbol_table; 57 | 58 | exprtk::rtl::io::println println; 59 | 60 | symbol_table.add_function("println", println); 61 | 62 | compositor_t compositor(symbol_table); 63 | 64 | compositor.add(function_t() 65 | .name("constraint") 66 | .var("person_x").var("person_y") 67 | .expression 68 | ( 69 | " person_x xor person_y; " 70 | )); 71 | 72 | const std::string logical_deducation_riddle_program = 73 | " const var number_of_culprits := 1; " 74 | " " 75 | " for (var Tori := false; Tori <= true; Tori += true) " 76 | " { " 77 | " for (var Annie := false; Annie <= true; Annie += true) " 78 | " { " 79 | " for (var Betsy := false; Betsy <= true; Betsy += true) " 80 | " { " 81 | " for (var Chloe := false; Chloe <= true; Chloe += true) " 82 | " { " 83 | " for (var Zoey := false; Zoey <= true; Zoey += true) " 84 | " { " 85 | " if (sum(Annie, Betsy, Chloe, Tori, Zoey) != number_of_culprits) " 86 | " continue; " 87 | " " 88 | " var solution := " 89 | " constraint( not(Zoey) , Annie ) and /* Tori */ " 90 | " constraint( not(Betsy) , not(Zoey) ) and /* Annie */ " 91 | " constraint( Zoey , not(Tori) ) and /* Betsy */ " 92 | " constraint( Betsy , Annie ) and /* Chloe */ " 93 | " constraint( Chloe , not(Tori) ) ; /* Zoey */ " 94 | " " 95 | " if (solution == true) " 96 | " { " 97 | " var culprit := ''; " 98 | " [*] " 99 | " { " 100 | " case Annie : culprit := 'Annie'; " 101 | " case Betsy : culprit := 'Betsy'; " 102 | " case Chloe : culprit := 'Chloe'; " 103 | " case Tori : culprit := 'Tori' ; " 104 | " case Zoey : culprit := 'Zoey' ; " 105 | " }; " 106 | " " 107 | " println(culprit,' broke the window!'); " 108 | " } " 109 | " } " 110 | " } " 111 | " } " 112 | " } " 113 | " } " 114 | " "; 115 | 116 | expression_t expression; 117 | expression.register_symbol_table(symbol_table); 118 | 119 | parser_t parser; 120 | parser.compile(logical_deducation_riddle_program,expression); 121 | 122 | expression.value(); 123 | } 124 | 125 | int main() 126 | { 127 | logical_deducation_riddle(); 128 | return 0; 129 | } 130 | -------------------------------------------------------------------------------- /exprtk_str_funcs.hpp: -------------------------------------------------------------------------------- 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 | #ifndef INCLUDE_EXPRTK_STR_FUNCS_HPP 20 | #define INCLUDE_EXPRTK_STR_FUNCS_HPP 21 | 22 | 23 | #include "exprtk.hpp" 24 | 25 | 26 | namespace exprtk 27 | { 28 | namespace helper 29 | { 30 | namespace details 31 | { 32 | template 33 | struct igf_impl : public exprtk::igeneric_function 34 | { 35 | typedef typename igeneric_function::parameter_list_t parameter_list_t; 36 | 37 | igf_impl(const std::string& param_sequence = "") 38 | : exprtk::igeneric_function(param_sequence) 39 | {} 40 | 41 | inline T operator()(parameter_list_t parameters) 42 | { 43 | return Process::execute(parameters); 44 | } 45 | }; 46 | 47 | struct toupper_impl {}; 48 | struct tolower_impl {}; 49 | struct trim_leading_ws_impl {}; 50 | struct trim_trailing_ws_impl{}; 51 | struct trim_ws_impl {}; 52 | struct trim_leading_impl {}; 53 | struct trim_trailing_impl {}; 54 | struct trim_impl {}; 55 | struct sort_impl {}; 56 | struct remove_impl {}; 57 | struct removec_impl {}; 58 | struct to_str_impl {}; 59 | struct rotate_l_impl {}; 60 | struct rotate_r_impl {}; 61 | struct join_impl {}; 62 | struct alphabet_uc_impl {}; 63 | struct alphabet_lc_impl {}; 64 | struct digits_impl {}; 65 | struct odd_digits_impl {}; 66 | struct even_digits_impl {}; 67 | } 68 | } 69 | } // namespace exprtk 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /exprtk_sumofprimes.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Summation of Prime Factors * 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 sum_of_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 | symbol_table_t symbol_table; 36 | 37 | compositor_t compositor(symbol_table); 38 | 39 | // define function: sum_of_primes(z) 40 | compositor.add( 41 | function_t("sum_of_primes") 42 | .var("z") 43 | .expression( 44 | " var i := 2; " 45 | " var total := 0; " 46 | " while (z > 1) " 47 | " { " 48 | " if (0 == (z % i)) " 49 | " { " 50 | " total += i; " 51 | " z /= i; " 52 | " } " 53 | " else " 54 | " i += 1; " 55 | " }; " 56 | " total; ")); 57 | 58 | exprtk::rtl::io::println println; 59 | 60 | symbol_table.add_function("println",println); 61 | 62 | const std::string sum_of_prime_factors_program = 63 | " for (var i := 1; i <= 100; i += 1) " 64 | " { " 65 | " println(i, sum_of_primes(i)); " 66 | " } "; 67 | 68 | expression_t expression; 69 | expression.register_symbol_table(symbol_table); 70 | 71 | parser_t parser; 72 | parser.compile(sum_of_prime_factors_program,expression); 73 | 74 | expression.value(); 75 | } 76 | 77 | int main() 78 | { 79 | sum_of_primes(); 80 | return 0; 81 | } 82 | -------------------------------------------------------------------------------- /exprtk_symtab_functions.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Symbol Table Function Names Example * 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 final : 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 | inline T operator()(const T& v1, const T& v2) override 36 | { 37 | return T(1) + (v1 * v2) / T(3); 38 | } 39 | }; 40 | 41 | template 42 | inline T myotherfunc(T v0, T v1, T v2) 43 | { 44 | return std::abs(v0 - v1) * v2; 45 | } 46 | 47 | template 48 | void symbol_table_function_names() 49 | { 50 | typedef exprtk::symbol_table symbol_table_t; 51 | 52 | symbol_table_t symbol_table; 53 | 54 | myfunc mf; 55 | 56 | symbol_table.add_function("f1",[](T v0) -> T { return v0;}); 57 | symbol_table.add_function("f2",[](T v0, T v1) -> T{ return v0 / v1;}); 58 | 59 | symbol_table.add_function("myfunc" , mf ); 60 | symbol_table.add_function("otherfunc", myotherfunc); 61 | 62 | for (const auto& func : symbol_table.get_function_list()) 63 | { 64 | printf("function: %s\n",func.c_str()); 65 | } 66 | } 67 | 68 | int main() 69 | { 70 | symbol_table_function_names(); 71 | return 0; 72 | } 73 | -------------------------------------------------------------------------------- /exprtk_testgen.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Evaluated Test Expression Generator * 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 | /* 28 | Example usage: 29 | echo "x:=11.1237567810735" > base0.tmp 30 | echo "y:=13.1239567810735" >> base0.tmp 31 | echo "z:=15.1233567810735" >> base0.tmp 32 | echo "w:=19.1235567810735" >> base0.tmp 33 | ./exprtk_exprgen > base1.tmp 34 | cat base1.tmp | sed 's/[{(,)}]//g' | awk ' !x[$0]++' > base2.tmp 35 | cat base0.tmp base1.tmp base2.tmp > exprtk_functional_ext_test.tmp 36 | ./exprtk_testgen exprtk_functional_ext_test.tmp > exprtk_functional_ext_test_`date "+%Y%m%d%H%M%S"`.txt 37 | 38 | */ 39 | 40 | 41 | template class Sequence> 43 | inline std::size_t load_expressions(const std::string& file_name, 44 | Sequence& sequence) 45 | { 46 | std::ifstream stream(file_name.c_str()); 47 | if (!stream) return 0; 48 | std::string buffer; 49 | buffer.reserve(1024); 50 | std::size_t line_count = 0; 51 | while (std::getline(stream,buffer)) 52 | { 53 | if (buffer.empty()) 54 | continue; 55 | else if ('#' == buffer[0]) 56 | continue; 57 | ++line_count; 58 | sequence.push_back(buffer); 59 | } 60 | 61 | return line_count; 62 | } 63 | 64 | template 65 | inline bool test_gen(const std::string& expr_file) 66 | { 67 | typedef exprtk::expression expression_t; 68 | 69 | T x = T(0); 70 | T y = T(0); 71 | T z = T(0); 72 | T w = T(0); 73 | 74 | exprtk::polynomial poly01; 75 | exprtk::polynomial poly02; 76 | exprtk::polynomial poly03; 77 | exprtk::polynomial poly04; 78 | exprtk::polynomial poly05; 79 | exprtk::polynomial poly06; 80 | exprtk::polynomial poly07; 81 | exprtk::polynomial poly08; 82 | exprtk::polynomial poly09; 83 | exprtk::polynomial poly10; 84 | exprtk::polynomial poly11; 85 | exprtk::polynomial poly12; 86 | 87 | exprtk::symbol_table symbol_table; 88 | symbol_table.add_constants(); 89 | symbol_table.add_variable("x",x); 90 | symbol_table.add_variable("y",y); 91 | symbol_table.add_variable("z",z); 92 | symbol_table.add_variable("w",w); 93 | symbol_table.add_function("poly01", poly01); 94 | symbol_table.add_function("poly02", poly02); 95 | symbol_table.add_function("poly03", poly03); 96 | symbol_table.add_function("poly04", poly04); 97 | symbol_table.add_function("poly05", poly05); 98 | symbol_table.add_function("poly06", poly06); 99 | symbol_table.add_function("poly07", poly07); 100 | symbol_table.add_function("poly08", poly08); 101 | symbol_table.add_function("poly09", poly09); 102 | symbol_table.add_function("poly10", poly10); 103 | symbol_table.add_function("poly11", poly11); 104 | symbol_table.add_function("poly12", poly12); 105 | 106 | expression_t expression; 107 | expression.register_symbol_table(symbol_table); 108 | 109 | exprtk::parser parser; 110 | 111 | std::deque expr_str_list; 112 | 113 | if (0 == load_expressions(expr_file,expr_str_list)) 114 | { 115 | return true; 116 | } 117 | 118 | std::deque > expression_list; 119 | 120 | bool load_success = true; 121 | 122 | for (std::size_t i = 0; i < expr_str_list.size(); ++i) 123 | { 124 | exprtk::expression current_expression; 125 | 126 | current_expression.register_symbol_table(symbol_table); 127 | 128 | if (!parser.compile(expr_str_list[i],current_expression)) 129 | { 130 | load_success = false; 131 | printf("test_gen() - Error: %s Expression: %s\n", 132 | parser.error().c_str(), 133 | expr_str_list[i].c_str()); 134 | } 135 | else 136 | expression_list.push_back(current_expression); 137 | } 138 | 139 | if (!load_success) 140 | return false; 141 | 142 | for (std::size_t i = 0; i < expression_list.size(); ++i) 143 | { 144 | T result = expression_list[i].value(); 145 | 146 | printf("equal((%050.30f),(%s))\n", 147 | result, 148 | expr_str_list[i].c_str()); 149 | } 150 | 151 | return true; 152 | } 153 | 154 | int main(int argc, char* argv[]) 155 | { 156 | if (argc != 2) 157 | { 158 | printf("usage: exprtk_testgen \n"); 159 | return 1; 160 | } 161 | 162 | const std::string file_name = argv[1]; 163 | test_gen(file_name); 164 | 165 | return 0; 166 | } 167 | -------------------------------------------------------------------------------- /exprtk_tower_of_hanoi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Tower Of Hanoi Example * 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 tower_of_hanoi_example() 27 | { 28 | typedef exprtk::symbol_table symbol_table_t; 29 | typedef exprtk::expression expression_t; 30 | typedef exprtk::parser parser_t; 31 | typedef exprtk::function_compositor compositor_t; 32 | typedef typename compositor_t::function function_t; 33 | 34 | std::vector disks = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; 35 | 36 | exprtk::rtl::io::package io_package; 37 | 38 | symbol_table_t symbol_table; 39 | symbol_table.add_vector ("disks", disks); 40 | symbol_table.add_package(io_package); 41 | 42 | compositor_t compositor(symbol_table); 43 | 44 | compositor.load_variables(true); 45 | compositor.load_vectors (true); 46 | 47 | compositor.add( 48 | function_t("move_disk") 49 | .vars("disk", "src_rod", "dest_rod") 50 | .expression 51 | ( 52 | "println('Move disk', disk ,' from rod[', src_rod ,'] to rod[', dest_rod ,']');" 53 | )); 54 | 55 | compositor.add( 56 | function_t("tower_of_hanoi") 57 | .vars("n", "src", "dest", "aux") 58 | .expression 59 | ( 60 | " if (n == 1) " 61 | " { " 62 | " move_disk(disks[0], src, dest); " 63 | " return [true]; " 64 | " }; " 65 | " " 66 | " tower_of_hanoi(n - 1, src, aux, dest); " 67 | " " 68 | " move_disk(disks[n - 1], src, dest); " 69 | " " 70 | " tower_of_hanoi(n - 1, aux, dest, src); " 71 | " " 72 | )); 73 | 74 | const std::string tower_of_hanoi_program = 75 | " tower_of_hanoi(disks[], 1, 2, 3); "; 76 | 77 | expression_t expression; 78 | expression.register_symbol_table(symbol_table); 79 | 80 | parser_t parser; 81 | parser.compile(tower_of_hanoi_program,expression); 82 | 83 | expression.value(); 84 | } 85 | 86 | int main() 87 | { 88 | tower_of_hanoi_example(); 89 | return 0; 90 | } 91 | 92 | 93 | -------------------------------------------------------------------------------- /exprtk_truthtable_gen.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk Truth Table Generator * 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 truth_table_generator(const std::string& boolean_expression) 29 | { 30 | typedef exprtk::symbol_table symbol_table_t; 31 | typedef exprtk::expression expression_t; 32 | typedef exprtk::parser parser_t; 33 | typedef exprtk::parser_error::type err_t; 34 | typedef typename parser_t::settings_store settings_t; 35 | 36 | symbol_table_t symbol_table; 37 | 38 | expression_t expression; 39 | expression.register_symbol_table(symbol_table); 40 | 41 | static const std::size_t compile_options = 42 | settings_t::e_replacer + 43 | settings_t::e_joiner + 44 | settings_t::e_numeric_check + 45 | settings_t::e_bracket_check + 46 | settings_t::e_sequence_check + 47 | settings_t::e_strength_reduction + 48 | settings_t::e_disable_usr_on_rsrvd; 49 | 50 | parser_t parser(settings_t(compile_options) 51 | .disable_all_base_functions () 52 | .disable_all_control_structures()); 53 | 54 | parser.enable_unknown_symbol_resolver(); 55 | 56 | parser.dec().collect_variables() = true; 57 | parser.dec().collect_functions() = true; 58 | 59 | if (!parser.compile(boolean_expression,expression)) 60 | { 61 | printf("Error: %s\tExpression: %s\n", 62 | parser.error().c_str(), 63 | boolean_expression.c_str()); 64 | 65 | for (std::size_t i = 0; i < parser.error_count(); ++i) 66 | { 67 | err_t error = parser.get_error(i); 68 | 69 | printf("Error: %02d Position: %02d " 70 | "Type: [%s] " 71 | "Message: %s " 72 | "Expression: %s\n", 73 | static_cast(i), 74 | static_cast(error.token.position), 75 | exprtk::parser_error::to_str(error.mode).c_str(), 76 | error.diagnostic.c_str(), 77 | boolean_expression.c_str()); 78 | 79 | exprtk::parser_error::update_error(error,boolean_expression); 80 | 81 | printf("Error[%02d] at line: %d column: %d\n", 82 | static_cast(i), 83 | static_cast(error.line_no), 84 | static_cast(error.column_no)); 85 | } 86 | 87 | return; 88 | } 89 | 90 | typedef typename parser_t::dependent_entity_collector::symbol_t dec_symbol_t; 91 | 92 | std::deque symbol_list; 93 | 94 | parser.dec().symbols(symbol_list); 95 | 96 | if (symbol_list.empty()) 97 | { 98 | printf("Error: No variables found to build truth table.\n"); 99 | return; 100 | } 101 | 102 | for (std::size_t i = 0; i < symbol_list.size(); ++i) 103 | { 104 | if (exprtk::details::imatch(symbol_list[i].first,"not")) 105 | { 106 | symbol_list.erase(symbol_list.begin() + i); 107 | 108 | if (i >= symbol_list.size()) 109 | break; 110 | } 111 | 112 | if (parser_t::e_st_function == symbol_list[i].second) 113 | { 114 | printf("Error: call to function '%s' not allowed.\n",symbol_list[i].first.c_str()); 115 | return; 116 | } 117 | } 118 | 119 | if (symbol_list.size() > 32) 120 | { 121 | printf("Error: no more than 32 unique variables allowed.\n"); 122 | return; 123 | } 124 | 125 | unsigned int upper_bound = 1 << symbol_list.size(); 126 | 127 | const int index_width = static_cast(std::ceil(std::log10(upper_bound))); 128 | 129 | // Print truth table header 130 | printf(" #%s ",std::string(index_width - 1,' ').c_str()); 131 | 132 | for (std::size_t i = 0; i < symbol_list.size(); ++i) 133 | { 134 | printf("| %s ",symbol_list[i].first.c_str()); 135 | } 136 | 137 | printf("| %s \n",boolean_expression.c_str()); 138 | 139 | for (std::size_t i = 0; i < upper_bound; ++i) 140 | { 141 | for (std::size_t j = 0; j < symbol_list.size(); ++j) 142 | { 143 | symbol_table.get_variable(symbol_list[j].first)->ref() = T((i & (1 << (symbol_list.size() - j - 1))) ? 0 : 1); 144 | } 145 | 146 | const std::size_t result = static_cast(expression.value()); 147 | 148 | printf(" %*d ", index_width, static_cast(i)); 149 | 150 | for (std::size_t j = 0; j < symbol_list.size(); ++j) 151 | { 152 | printf("| %d ",static_cast(symbol_table.get_variable(symbol_list[j].first)->value())); 153 | } 154 | 155 | printf("| %d \n", static_cast(result)); 156 | } 157 | } 158 | 159 | int main(int argc, char* argv[]) 160 | { 161 | if (2 != argc) 162 | { 163 | printf("usage: exprtk_truthtable_gen \n"); 164 | return 1; 165 | } 166 | 167 | truth_table_generator(argv[1]); 168 | 169 | return 0; 170 | } 171 | 172 | /* 173 | Examples: 174 | ./exprtk_truthtable_gen 'A and B or C or not(D)' 175 | ./exprtk_truthtable_gen '(A and not(B)) nor not(C xor D)' 176 | ./exprtk_truthtable_gen '(A nand not(B or C)) xor not(D xor E)' 177 | */ 178 | -------------------------------------------------------------------------------- /exprtk_vector_resize_example.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Vector Resize Example * 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 vector_resize_example() 29 | { 30 | typedef exprtk::symbol_table symbol_table_t; 31 | typedef exprtk::expression expression_t; 32 | typedef exprtk::parser parser_t; 33 | 34 | std::vector v0 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; 35 | std::vector v1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; 36 | 37 | exprtk::vector_view vv = exprtk::make_vector_view(v0, v0.size()); 38 | 39 | T n = T(0); 40 | 41 | symbol_table_t symbol_table; 42 | symbol_table.add_variable("n", n); 43 | symbol_table.add_vector ("v", vv); 44 | 45 | expression_t expression; 46 | expression.register_symbol_table(symbol_table); 47 | 48 | parser_t parser; 49 | 50 | const std::string vector_resize_expression = 51 | " sum(v) == ((v[]^2 + v[]) / 2) and sum(2v) == (n^2 + n)"; 52 | 53 | if (!parser.compile(vector_resize_expression, expression)) 54 | { 55 | printf("Error: %s\tExpression: %s\n", 56 | parser.error().c_str(), 57 | vector_resize_expression.c_str()); 58 | return; 59 | } 60 | 61 | for (std::size_t i = 1; i <= vv.base_size(); ++i) 62 | { 63 | vv.set_size(i); 64 | vv.rebase(i % 2 ? v0.data() : v1.data()); 65 | 66 | n = T(i); 67 | 68 | const T result = expression.value(); 69 | 70 | if (result != T(1)) 71 | { 72 | printf("Error: vector size: %d\n", static_cast(i)); 73 | } 74 | } 75 | } 76 | 77 | int main() 78 | { 79 | vector_resize_example(); 80 | return 0; 81 | } 82 | 83 | 84 | /* 85 | Build: 86 | c++ -pedantic-errors -Wall -Wextra -Werror -O3 -DNDEBUG -o vector_resize_example01 vector_resize_example01.cpp -L/usr/lib -lstdc++ -lm 87 | */ 88 | -------------------------------------------------------------------------------- /exprtk_vector_resize_inline_example.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Vector Resize Inline Within Expression Example * 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 my_vv_size_handler_t final : 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 | typedef typename generic_type::scalar_view scalar_t; 38 | typedef exprtk::vector_view* vv_ptr_t; 39 | typedef std::map map_t; 40 | 41 | using exprtk::igeneric_function::operator(); 42 | 43 | my_vv_size_handler_t() 44 | : exprtk::igeneric_function("VT") 45 | {} 46 | 47 | inline T operator()(parameter_list_t parameters) override 48 | { 49 | vector_t vector(parameters[0]); 50 | size_t new_size = static_cast(scalar_t(parameters[1])()); 51 | void* key = static_cast(&vector[0]); 52 | 53 | typename map_t::iterator itr = vector_map_.find(key); 54 | 55 | if (itr == vector_map_.end()) 56 | { 57 | printf("my_vv_size_handler - Error: failed to find vector_view for address: %p\n",key); 58 | return T(0); 59 | } 60 | 61 | exprtk::vector_view& vv = *itr->second; 62 | 63 | if (vv.base_size() < new_size) 64 | { 65 | printf("my_vv_size_handler - Error: vector_view for address: %p new size of %d greater than base_size of %d\n", 66 | key, 67 | static_cast(new_size), 68 | static_cast(vv.base_size())); 69 | return T(0); 70 | } 71 | 72 | return vv.set_size(new_size) ? T(1) : T(0); 73 | } 74 | 75 | void register_vector_view(exprtk::vector_view& vec_view) 76 | { 77 | vector_map_[vec_view.data()] = &vec_view; 78 | } 79 | 80 | private: 81 | 82 | map_t vector_map_; 83 | }; 84 | 85 | template 86 | void vector_inline_resize_example() 87 | { 88 | typedef exprtk::symbol_table symbol_table_t; 89 | typedef exprtk::expression expression_t; 90 | typedef exprtk::parser parser_t; 91 | 92 | const std::string inline_resize_expression = 93 | " var vec_original_size := v[]; " 94 | " " 95 | " for (var i := 1; i <= 2 * vec_original_size; i += 1) " 96 | " { " 97 | " if (resize(v,i) == true and v[] == i and sum(2v) == (i^2 + i)) " 98 | " { " 99 | " println('Success: set size: ', i ,' v[] = ', v[]); " 100 | " } " 101 | " else " 102 | " { " 103 | " println('Error: Failed to resize vector v to size: ', i); " 104 | " } " 105 | " }; "; 106 | 107 | std::vector v0 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; 108 | std::vector v1 = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 }; 109 | 110 | exprtk::vector_view vv = exprtk::make_vector_view(v0, v0.size()); 111 | 112 | 113 | exprtk::rtl::io::package io_package; 114 | 115 | my_vv_size_handler_t vv_size_handler; 116 | vv_size_handler.register_vector_view(vv); 117 | 118 | symbol_table_t symbol_table; 119 | symbol_table.add_vector ("v", vv); 120 | symbol_table.add_function("resize", vv_size_handler); 121 | symbol_table.add_package (io_package); 122 | 123 | expression_t expression; 124 | expression.register_symbol_table(symbol_table); 125 | 126 | parser_t parser; 127 | 128 | if (!parser.compile(inline_resize_expression, expression)) 129 | { 130 | printf("Error: %s\tExpression: %s\n", 131 | parser.error().c_str(), 132 | inline_resize_expression.c_str()); 133 | return; 134 | } 135 | 136 | vv.rebase(v0.data()); 137 | vv_size_handler.register_vector_view(vv); 138 | expression.value(); 139 | 140 | vv.rebase(v1.data()); 141 | vv_size_handler.register_vector_view(vv); 142 | expression.value(); 143 | } 144 | 145 | int main() 146 | { 147 | vector_inline_resize_example(); 148 | return 0; 149 | } 150 | 151 | 152 | /* 153 | Build: 154 | c++ -pedantic-errors -Wall -Wextra -Werror -O3 -DNDEBUG -o exprtk_vector_inline_resize_example exprtk_vector_inline_resize_example.cpp -L/usr/lib -lstdc++ -lm 155 | */ 156 | -------------------------------------------------------------------------------- /exprtk_vectorized_binomial_model.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Vectorized Binomial Option Pricing Model * 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 vectorized_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 u_inv := 1 / u; " 39 | " var p_up := (z - u_inv) / (u - u_inv); " 40 | " var p_down := 1 - p_up; " 41 | " " 42 | " var option_price[n + 1] := [0]; " 43 | " " 44 | " for (var i := 0; i <= n; i += 1) " 45 | " { " 46 | " var base_price := s * u^(n - 2i); " 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 | " var p_u_zinv := z_inv * p_up; " 56 | " var p_d_zinv := z_inv * p_down; " 57 | " " 58 | " for (var j := n - 1; j >= 0; j -= 1) " 59 | " { " 60 | " /* y_i <- a * x_i + b * y_(i+1) i:[0,j] */ " 61 | " axpbsy(p_u_zinv, option_price, " 62 | " p_d_zinv, 1, option_price, " 63 | " 0, j); " 64 | " }; " 65 | " " 66 | " option_price[0]; "; 67 | 68 | 69 | T s = T( 100.00); // Spot / Stock / Underlying / Base price 70 | T k = T( 110.00); // Strike price 71 | T v = T( 0.30); // Volatility 72 | T t = T( 2.22); // Years to maturity 73 | T r = T( 0.05); // Risk free rate 74 | T n = T(2000.00); // Number of time steps 75 | 76 | std::string callput_flag; 77 | 78 | exprtk::rtl::vecops::package vecops_package; 79 | 80 | symbol_table_t symbol_table; 81 | symbol_table.add_variable("s",s); 82 | symbol_table.add_variable("k",k); 83 | symbol_table.add_variable("t",t); 84 | symbol_table.add_variable("r",r); 85 | symbol_table.add_variable("v",v); 86 | symbol_table.add_constant("n",n); 87 | symbol_table.add_stringvar("callput_flag",callput_flag); 88 | symbol_table.add_package(vecops_package); 89 | 90 | expression_t expression; 91 | expression.register_symbol_table(symbol_table); 92 | 93 | parser_t parser; 94 | parser.compile(european_option_binomial_model_program,expression); 95 | 96 | const std::size_t rounds = 2000; 97 | 98 | T binomial_call_option_price = T(0); 99 | T binomial_put_option_price = T(0); 100 | 101 | { 102 | callput_flag = "call"; 103 | 104 | exprtk::timer timer; 105 | timer.start(); 106 | 107 | for (std::size_t i = 0; i < rounds; ++i) 108 | { 109 | binomial_call_option_price = expression.value(); 110 | } 111 | 112 | timer.stop(); 113 | 114 | printf("BinomialOptionPrice(Type: %4s, BasePx: %5.3f, Strike: %5.3f, Time: %5.3f, RFR: %5.3f, Vol: %5.3f, Steps: %4.1f) = %10.6f " 115 | "total time: %6.3fsec rate: %6.3fcalc/sec\n", 116 | callput_flag.c_str(), 117 | s, k, t, r, v, n, 118 | binomial_call_option_price, 119 | timer.time(), 120 | rounds / timer.time()); 121 | } 122 | 123 | { 124 | callput_flag = "put"; 125 | 126 | exprtk::timer timer; 127 | timer.start(); 128 | 129 | for (std::size_t i = 0; i < rounds; ++i) 130 | { 131 | binomial_put_option_price = expression.value(); 132 | } 133 | 134 | timer.stop(); 135 | 136 | printf("BinomialOptionPrice(Type: %4s, BasePx: %5.3f, Strike: %5.3f, Time: %5.3f, RFR: %5.3f, Vol: %5.3f, Steps: %4.1f) = %10.6f " 137 | "total time: %6.3fsec rate: %6.3fcalc/sec\n", 138 | callput_flag.c_str(), 139 | s, k, t, r, v, n, 140 | binomial_put_option_price, 141 | timer.time(), 142 | rounds / timer.time()); 143 | } 144 | 145 | const T put_call_parity_diff = 146 | (binomial_call_option_price - binomial_put_option_price) - 147 | (s - k * std::exp(-r * t)); 148 | 149 | printf("Put-Call parity difference: %20.17f\n", put_call_parity_diff); 150 | } 151 | 152 | int main() 153 | { 154 | vectorized_binomial_option_pricing_model(); 155 | return 0; 156 | } 157 | -------------------------------------------------------------------------------- /exprtk_vectornorm.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * ExprTk L-Norm Of A Vector * 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 norm : public exprtk::igeneric_function 30 | { 31 | typedef typename exprtk::igeneric_function igfun_t; 32 | typedef typename igfun_t::parameter_list_t parameter_list_t; 33 | typedef typename igfun_t::generic_type generic_type; 34 | typedef typename generic_type::scalar_view scalar_t; 35 | typedef typename generic_type::vector_view vector_t; 36 | 37 | using exprtk::igeneric_function::operator(); 38 | 39 | norm() 40 | : exprtk::igeneric_function("V|VTT|VT|VTTT") 41 | /* 42 | Overloads: 43 | 0. V - vector 44 | 1. VTT - vector, r0, r1 45 | 2. VT - vector, l-power 46 | 3. VTTT - vector, l-power, r0, r1 47 | */ 48 | {} 49 | 50 | inline T operator()(const std::size_t& ps_index, parameter_list_t parameters) 51 | { 52 | unsigned int l = 2; 53 | 54 | // Determine the l-power 55 | if ( 56 | (2 == ps_index) || 57 | (3 == ps_index) 58 | ) 59 | { 60 | if (!scalar_t(parameters[1]).to_uint(l)) 61 | return std::numeric_limits::quiet_NaN(); 62 | } 63 | 64 | const vector_t vec(parameters[0]); 65 | 66 | std::size_t r0 = 0; 67 | std::size_t r1 = vec.size() - 1; 68 | 69 | // Determine the range over the vector 70 | if ( 71 | (1 == ps_index) || 72 | (3 == ps_index) 73 | ) 74 | { 75 | if (!scalar_t(parameters[(1 == ps_index) ? 1 : 2]).to_uint(r0)) 76 | return std::numeric_limits::quiet_NaN(); 77 | 78 | if (!scalar_t(parameters[(1 == ps_index) ? 2 : 3]).to_uint(r1)) 79 | return std::numeric_limits::quiet_NaN(); 80 | } 81 | 82 | switch (l) 83 | { 84 | #define norm_def(N) case N : return norm_impl(vec,r0,r1); 85 | norm_def( 1) norm_def( 2) norm_def( 3) norm_def( 4) 86 | norm_def( 5) norm_def( 6) norm_def( 7) norm_def( 8) 87 | norm_def( 9) norm_def(10) norm_def(11) norm_def(12) 88 | norm_def(13) norm_def(14) norm_def(15) norm_def(16) 89 | norm_def(17) norm_def(18) norm_def(19) norm_def(20) 90 | norm_def(21) norm_def(22) norm_def(23) norm_def(24) 91 | norm_def(25) norm_def(26) norm_def(27) norm_def(28) 92 | norm_def(29) norm_def(30) norm_def(31) norm_def(32) 93 | default : return norm_impl(vec,l,r0,r1); 94 | } 95 | } 96 | 97 | template 98 | inline T norm_impl(const vector_t& vector, const std::size_t r0, const std::size_t r1) 99 | { 100 | T sum = T(0); 101 | 102 | for (std::size_t i = r0; i <= r1; ++i) 103 | { 104 | sum += exprtk::details::numeric::fast_exp::result(std::abs(vector[i])); 105 | } 106 | 107 | switch (Pow) 108 | { 109 | case 1 : return sum; 110 | case 2 : return exprtk::details::numeric::sqrt(sum); 111 | default : return exprtk::details::numeric::pow(sum, T(1) / Pow); 112 | } 113 | } 114 | 115 | inline T norm_impl(const vector_t& vector, unsigned int pow, const std::size_t r0, const std::size_t r1) 116 | { 117 | T sum = T(0); 118 | 119 | for (std::size_t i = r0; i <= r1; ++i) 120 | { 121 | sum += exprtk::details::numeric::pow(std::abs(vector[i]),T(pow)); 122 | } 123 | 124 | return exprtk::details::numeric::pow(sum,T(1) / pow); 125 | } 126 | }; 127 | 128 | template 129 | void norm_of_vector() 130 | { 131 | typedef exprtk::symbol_table symbol_table_t; 132 | typedef exprtk::expression expression_t; 133 | typedef exprtk::parser parser_t; 134 | 135 | T x[] = { T(1), T(2), T(3), T(4), T(5) }; 136 | 137 | std::vector y; 138 | 139 | y.push_back(T(5)); y.push_back(T(6)); 140 | y.push_back(T(7)); y.push_back(T(8)); 141 | y.push_back(T(9)); y.push_back(T(0)); 142 | 143 | symbol_table_t symbol_table; 144 | symbol_table.add_vector("x", x); 145 | symbol_table.add_vector("y", y); 146 | 147 | norm norm_; 148 | 149 | symbol_table.add_function("norm",norm_); 150 | 151 | const std::string vector_norm_program[] = 152 | { 153 | " norm(x) ", 154 | " norm(x,1) ", 155 | " norm(x,2) ", 156 | " norm(x,3) ", 157 | " norm(x,4) ", 158 | " norm(x,5) ", 159 | " norm(2x+1) ", 160 | " norm(2x+1,1) ", 161 | " norm(2x+1,2) ", 162 | " norm(2x+1,3) ", 163 | " norm(2x+1,4) ", 164 | " norm(2x+1,5) ", 165 | " norm(2x+y/3-4) ", 166 | " norm(2x+y/3-4,1) ", 167 | " norm(2x+y/3-4,2) ", 168 | " norm(2x+y/3-4,3) ", 169 | " norm(2x+y/3-4,4) ", 170 | " norm(2x+y/3-4,5) " 171 | }; 172 | 173 | const std::size_t vecnorm_program_size = sizeof(vector_norm_program) / sizeof(std::string); 174 | 175 | parser_t parser; 176 | 177 | for (std::size_t i = 0; i < vecnorm_program_size; ++i) 178 | { 179 | expression_t expression; 180 | expression.register_symbol_table(symbol_table); 181 | 182 | parser.compile(vector_norm_program[i], expression); 183 | 184 | printf("%s = %15.8f\n", 185 | vector_norm_program[i].c_str(), 186 | expression.value()); 187 | } 188 | } 189 | 190 | int main() 191 | { 192 | norm_of_vector(); 193 | return 0; 194 | } 195 | -------------------------------------------------------------------------------- /exprtk_wiener_process_pi.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | ************************************************************** 3 | * C++ Mathematical Expression Toolkit Library * 4 | * * 5 | * Approximation of Pi via Wiener process based Monte Carlo * 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 wiener_process_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 wiener_process_pi_program = 52 | " var w[10^4] := [0]; " 53 | " " 54 | " for (var i := 0; i < w[]; i += 1) " 55 | " { " 56 | " var x[10^4] := [(rnd_01 < 1 / 2) ? -1 : 1]; " 57 | " w[i] := sum(x); " 58 | " } " 59 | " " 60 | " (2 * w[]) / avg(abs(w))^2; "; 61 | 62 | rnd_01 rnd01; 63 | 64 | symbol_table_t symbol_table; 65 | symbol_table.add_function("rnd_01",rnd01); 66 | 67 | expression_t expression; 68 | expression.register_symbol_table(symbol_table); 69 | 70 | parser_t parser; 71 | parser.compile(wiener_process_pi_program,expression); 72 | 73 | const T approximate_pi = expression.value(); 74 | 75 | const T real_pi = T(3.141592653589793238462643383279502); // or close enough... 76 | 77 | printf("pi ~ %20.17f\terror: %20.17f\n", 78 | approximate_pi, 79 | std::abs(real_pi - approximate_pi)); 80 | } 81 | 82 | int main() 83 | { 84 | wiener_process_pi(); 85 | return 0; 86 | } 87 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /readme.md: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ArashPartow/exprtk-extras/da54cca937b737aa4dae3c8b7a4cefc12f4542c4/readme.md --------------------------------------------------------------------------------