Numerical Methods in Computational Finance. Daniel J. Duffy

Чтение книги онлайн.

Читать онлайн книгу Numerical Methods in Computational Finance - Daniel J. Duffy страница 41

Numerical Methods in Computational Finance - Daniel J. Duffy

Скачать книгу

can instantiate this class by calling its constructor, but we prefer to use a factory method (this is a design pattern) for added flexibility. Notice that we also use C++ smart pointers in order to avoid possible memory issues):

       std::shared_ptr<GeneralisedRiccati> CreateRiccati() { // Factory method, specific case const double P = 0.0; const double Q = -10.8; const double R = 0.5 * 2.44 * 2.44; const double eta = 0.96; const double lambda = 0.13;double A = 0.42; // Generalised Riccati auto p = [=](double x) {return P;};auto q = [=](double x) {return Q;}; auto r = [=](double x) {return R;}; auto n = [=](double x, double y) { return (lambda*y) / (eta - y); }; return std::shared_ptr<GeneralisedRiccati> (new GeneralisedRiccati (p, q, r, n)); }

      3.6.1 Finite Difference Schemes

       // Global arrays to hold (t, y) data for meshes of size dt and dt/2 // t and y arrays on mesh dt std::vector<double> tValues; std::vector<double> yValues; // t and y arrays on mesh dt/2 std::vector<double> t2Values; std::vector<double> y2Values; // 2nd order extrapolated values on mesh dt std::vector<double> yRichValues;

      The code for the schemes is:

      Some test code is:

       int main() { std::cout ≪ "How many steps (need many e.g. 300000?): "; std::cin ≫ NT; CurveEuler(); CurveRichardson(); std::cout ≪ "Value at T = " ≪ U ≪ " is " ≪ std::setprecision(7) ≪ yValues[yValues.size() - 1] ≪ ", press the ANY key " ≪ std::endl; std::cout ≪ "Richardson at T = " ≪ U ≪ " is " ≪RichValues[yRichValues.size() - 1] ≪ ", press the ANY key "; // Beautiful Excel output ExcelDriver xl; xl.MakeVisible(true); xl.CreateChart(tValues, yValues, std::string("Euler for Riccati")); xl.CreateChart (tValues, yRichValues, std::string("Richardson for Riccati")); return 0; }

       Case I: , .

       Case II: , .

      In general, the library needs approximately 100 function evaluations to reach this level of accuracy. The results for explicit Euler and the extrapolated scheme for cases I and II for NT = 300, 500, 1000 and 5000 are:

       Case I: (9.2746e-6, 1.113e-5), (1.0015e-5, 1.118e-5), (1.059e-5, 1.200e-5), (1.083e-5, 1.1206e-5).

       Case II: (0.0554, 0.0559), (0.0556, 0.0559), (0.0558, 0.0559), (0.05589, 0.0559).

      For a more complete discussion of Boost odeint, see Duffy (2018).

      We complete our discussion of finite difference methods for (3.10). The full problem is (3.11); (3.12) is a coupled system of equations, and it can be solved in different ways. The most effective approach at this stage is to use a production third-party ODE solver in C++.

      We have seen what scalar and vector ODEs are. Now we consider matrix ODEs.

      The Boost odeint library can be used to solve matrix ODEs, for example:

      where A, B and Y are n times n matrices.

      (3.26)upper Y left-parenthesis t right-parenthesis equals e Superscript italic upper A t Baseline upper C e Superscript italic upper B t Baseline comma where upper Y left-parenthesis 0 right-parenthesis equals upper C comma and upper C is a given matrix period

      A special case is when:

      (3.27)StartLayout 1st Row 1st Column Blank 2nd Column upper B equals 0 left-parenthesis zero matrix right-parenthesis 2nd Row 1st Column Blank 2nd Column upper C equals upper I left-parenthesis identity matrix right-parenthesis in which case we have the solution which is the 3rd Row 1st Column Blank 2nd Column italic exponential of a matrix colon EndLayout

      (3.28)upper Y left-parenthesis t right-parenthesis equals e Superscript italic upper A t Baseline period

      (3.29)StartLayout Enlarged left-brace 1st Row StartFraction italic d upper Y Over italic d t EndFraction equals italic upper A upper Y 2nd Row upper Y left-parenthesis 0 right-parenthesis equals upper C period EndLayout

      where C is a given matrix.

      We model this system by the following C++ class:

       namespace ublas = boost::numeric::ublas; using value_type = double; using state_type = boost::numeric::ublas::matrix<value_type>; class MatrixOde { private: // dB/dt = A*B, B(0) = C; ublas::matrix<value_type> A_; ublas::matrix<value_type>

Скачать книгу