LSS2

C++ Library containing some ODE and PDE solvers


Project maintained by MichalSara99 Hosted on GitHub Pages — Theme by mattgraham

Back

Boundary and initial/terminal conditions conventions

Boundary Conditions

LSS supports three types of boundary conditions: Dirichlet, Neumann and Robin. All solvers except for specific ones (so far only Heston type) allow any combination of these.

ODE Solvers

In what follows solution_ode represents a solution of an ODE and boundary_point_ode represents a point in which we evaluate a boundary condition. Let us consider following simple 2nd order ODE

ode

Dirichlet Boundary

LSS assumes Dirichlet boundary of following form

dirichlet_ode

Specifically, if we have following Dirichlet boundary:

dirichlat_exampl_ode

then in code we write:

  #include <lss/boundary/dirichlet_1d.hpp>

  auto const dirichlet =  3.1415; 
  
  // build boundary conditions from above function:
  auto const &boundary_ptr = lss::dirichlet_1d_builder().value(dirichlet).build();

Neumann Boundary

LSS assumes Neumann boundary of following form

neumann_ode

Specifically, if we have following Neumann boundary:

neumann_exampl_ode

then in code we write:

  #include <lss/boundary/neumann_1d.hpp>

  auto const neumann = -1.0;
  
  // build boundary conditions from above function:
  auto const &boundary_ptr = lss::neumann_1d_builder().value(neumann).build();

Note -1.0 rather then 1.0. We must pay attention to the aforementioned convention or we get completely different solution.

Robin Boundary

LSS assumes Robin boundary of following form

robin_ode

Specifically, if we have following Robin boundary:

robin_exampl_ode

then in code we write:

  #include <lss/boundary/robin_1d.hpp>

  auto const robin_first =  2.0; 
  auto const robin_second =  0.0;
  
  // build boundary conditions from above function:
  auto const &boundary_ptr = lss::robin_1d_builder()
                                  .values(robin_first,robin_second)
                                  .build();

1D PDE Solvers

In what follows solution_1d_pde represents a solution of 1D PDE and boundary_point_1d_pde represents a point in which we evaluate a boundary condition and initial_point_1d_pde represents a time at which we evaluate an initial/terminal condition. Let us consider following 1D PDE (heat equation)

pde_1d

Dirichlet Boundary

LSS assumes Dirichlet boundary of following form

dirichlet_1d_pde

Specifically, if we have following Dirichlet boundary:

dirichlet_exampl_1d_pde

then in code we write:

  #include <lss/boundary/dirichlet_1d.hpp>

  auto const &dirichlet = [](double t) { return 2*t; }; 
  
  // build boundary conditions from above function:
  auto const &boundary_ptr = lss::dirichlet_1d_builder().value(dirichlet).build();

Neumann Boundary

LSS assumes Neumann boundary of following form

neumann_1d_pde

Specifically, if we have following Neumann boundary:

neumann_exampl_1d_pde

then in code we write:

  #include <lss/boundary/neumann_1d.hpp>

  auto const neumann = [](double t) { return -2.0*t; }; 
  
  // build boundary conditions from above function:
  auto const &boundary_ptr = lss::neumann_1d_builder().value(neumann).build();

Note -2.0t rather then 2.0t. We must pay attention to the aforementioned convention or we get completely different solution.

Robin Boundary

LSS assumes Robin boundary of following form

robin_1d_pde

Specifically, if we have following Robin boundary:

robin_exampl_1d_pde

then in code we write:

  #include <lss/boundary/robin_1d.hpp>

  auto const robin_first =  [](double t) { return 2*t; }; 
  auto const robin_second = [](double t) { return 0.0; };
  
  // build boundary conditions from above function:
  auto const &boundary_ptr = lss::robin_1d_builder()
                                  .values(robin_first,robin_second)
                                  .build();

Initial/Terminal Condition for 1D PDEs

Initial/terminal condition follows similar pattern.

initial_1d_pde

which for

initial_exampl_1d_pde

translates into C++ code

  #include <lss/pde/configs/heat_initial_data_config_1d.hpp>

  // strike
  auto const strike = 20.0;
  // terminal condition function (payoff of call):
  auto terminal_condition = [=](double x) { return std::max<double>(0.0, x - strike); };

  // build initial data config:
  auto const &heat_init_data_ptr =
        lss::heat_initial_data_config_1d_builder().condition(terminal_condition).build();


Note that builder lss::heat_initial_data_config_1d_builder() is used for either initial or terminal condition.

In case we have two initial/terminal conditions (as in case of wave type equations)

initial_first_1d_pde_w

initial_second_1d_pde_w

we will have for

initial_first_exampl_1d_pde_w

initial_second_exampl_1d_pde_w

C++ code

  #include <lss/pde/configs/wave_initial_data_config_1d.hpp>

  // initial condition:
  auto first_condition = [](double x) { return std::sin(pi() * x); };
  auto second_condition = [](double x) { return 0.0; };
  auto const wave_init_data_ptr = std::make_shared<wave_initial_data_config_1d>(initial_condition, second_condition);


Back