// File: /workspace/github_cpp_makefile_star2_O2/ArashPartow[P]exprtk-extras/exprtk_ornstein_uhlenbeck_process.cpp
// Function: void ornstein_uhlenbeck_process<double>()
void ornstein_uhlenbeck_process()
{
   typedef exprtk::symbol_table<T> symbol_table_t;
   typedef exprtk::expression<T>   expression_t;
   typedef exprtk::parser<T>       parser_t;

   const std::string ornstein_uhlenbeck_process_program =
      " const var mu        := 1;                                                        "
      " const var sigma     := 0.4;                                                      "
      " const var theta     := 2;                                                        "
      " const var tau       := 1 / theta;                                                "
      " const var T         := 10 * tau;                                                 "
      " const var dt        := 0.01 * tau;                                               "
      " const var num_steps := floor(T / dt);                                            "
      " const var stddev    := sqrt(sigma^2 / (2 * theta) * (1 - exp(-2 * theta * dt))); "
      " const var x_0       := 1.0;                                                      "
      "                                                                                  "
      " var x[num_steps] := [0];                                                         "
      "                                                                                  "
      " x[0] := x_0;                                                                     "
      "                                                                                  "
      " for (var i := 0; i < num_steps - 1; i += 1)                                      "
      " {                                                                                "
      "    var mean := x[i] * exp(-theta * dt) + mu * (1 - exp(-theta * dt));            "
      "                                                                                  "
      "    x[i + 1] := normal(mean,stddev);                                              "
      " };                                                                               "
      "                                                                                  "
      "                                                                                  "
      " for (var i := 0; i < x[]; i += 1)                                                "
      " {                                                                                "
      "    println(i * dt, '\t', x[i]);                                                  "
      " }                                                                                ";


   exprtk::rtl::io::println<T> println;
   normal_distribution<T>      normal;

   symbol_table_t symbol_table;
   symbol_table.add_function("println", println);
   symbol_table.add_function("normal" , normal );

   expression_t expression;
   expression.register_symbol_table(symbol_table);

   parser_t parser;
   parser.compile(ornstein_uhlenbeck_process_program,expression);

   expression.value();
}

// Assembly:
pushq %rbx
subq $0x1ee0, %rsp           # imm = 0x1EE0
leaq 0x12bdb3(%rip), %rsi    # 0x23c115
leaq 0x30(%rsp), %rdi
leaq 0xb30(%rsp), %rdx
callq 0x110318
leaq 0x12c5ee(%rip), %rsi    # 0x23c969
leaq 0xb30(%rsp), %rdi
leaq 0x208(%rsp), %rdx
callq 0x110318
leaq 0x50(%rsp), %rdi
leaq 0xb30(%rsp), %rsi
callq 0x110630
leaq 0xb30(%rsp), %rdi
callq 0x10e618
leaq 0xb30(%rsp), %rdi
callq 0x1106c2
leaq 0x8(%rsp), %rdi
pushq $0x1
popq %rsi
callq 0x11078e
leaq 0x12c5a0(%rip), %rsi    # 0x23c970
leaq 0x208(%rsp), %rdi
leaq 0xb8(%rsp), %rdx
callq 0x110318
leaq 0x8(%rsp), %rdi
leaq 0x208(%rsp), %rsi
leaq 0x50(%rsp), %rdx
callq 0x1107b2
leaq 0x208(%rsp), %rdi
callq 0x10e618
leaq 0x12c568(%rip), %rsi    # 0x23c978
leaq 0x208(%rsp), %rdi
leaq 0xb8(%rsp), %rdx
callq 0x110318
leaq 0x8(%rsp), %rdi
leaq 0x208(%rsp), %rsi
leaq 0xb30(%rsp), %rdx
callq 0x11087a
leaq 0x208(%rsp), %rdi
callq 0x10e618
leaq 0x10(%rsp), %rdi
callq 0x1108da
leaq 0x10(%rsp), %rdi
leaq 0x8(%rsp), %rsi
callq 0x11093a
leaq 0xb8(%rsp), %rdi
pushq $0x7f
popq %rsi
callq 0x110996
leaq 0x208(%rsp), %rdi
leaq 0xb8(%rsp), %rsi
callq 0x110aa6
leaq 0xb8(%rsp), %rdi
callq 0x1110be
leaq 0x208(%rsp), %rdi
leaq 0x30(%rsp), %rsi
leaq 0x10(%rsp), %rdx
callq 0x111106
movq 0x10(%rsp), %rax
movq 0x8(%rax), %rdi
movq (%rdi), %rax
callq *0x18(%rax)
leaq 0x208(%rsp), %rdi
callq 0x111588
leaq 0x10(%rsp), %rdi
callq 0x1116c2
leaq 0x8(%rsp), %rdi
callq 0x1116d8
leaq 0x50(%rsp), %rdi
callq 0x11171c
leaq 0x30(%rsp), %rdi
callq 0x10e618
addq $0x1ee0, %rsp           # imm = 0x1EE0
popq %rbx
retq
movq %rax, %rbx
leaq 0xb8(%rsp), %rdi
callq 0x1110be
jmp 0x11055f
jmp 0x11050f
movq %rax, %rbx
jmp 0x11055f
jmp 0x11052c
jmp 0x11051a
jmp 0x11052c
movq %rax, %rbx
leaq 0x208(%rsp), %rdi
callq 0x10e618
jmp 0x110569
movq %rax, %rbx
jmp 0x110569
jmp 0x110533
movq %rax, %rbx
jmp 0x110573
movq %rax, %rbx
leaq 0xb30(%rsp), %rdi
callq 0x10e618
jmp 0x11057d
movq %rax, %rbx
jmp 0x11057d
movq %rax, %rbx
leaq 0x208(%rsp), %rdi
callq 0x111588
leaq 0x10(%rsp), %rdi
callq 0x1116c2
leaq 0x8(%rsp), %rdi
callq 0x1116d8
leaq 0x50(%rsp), %rdi
callq 0x11171c
leaq 0x30(%rsp), %rdi
callq 0x10e618
movq %rbx, %rdi
callq 0x10e340