/src/quantlib/ql/methods/lattices/lattice2d.hpp
Line | Count | Source (jump to first uncovered line) |
1 | | /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | |
3 | | /* |
4 | | Copyright (C) 2001, 2002, 2003 Sadruddin Rejeb |
5 | | Copyright (C) 2005 StatPro Italia srl |
6 | | |
7 | | This file is part of QuantLib, a free-software/open-source library |
8 | | for financial quantitative analysts and developers - http://quantlib.org/ |
9 | | |
10 | | QuantLib is free software: you can redistribute it and/or modify it |
11 | | under the terms of the QuantLib license. You should have received a |
12 | | copy of the license along with this program; if not, please email |
13 | | <quantlib-dev@lists.sf.net>. The license is also available online at |
14 | | <http://quantlib.org/license.shtml>. |
15 | | |
16 | | This program is distributed in the hope that it will be useful, but WITHOUT |
17 | | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
18 | | FOR A PARTICULAR PURPOSE. See the license for more details. |
19 | | */ |
20 | | |
21 | | /*! \file lattice2d.hpp |
22 | | \brief Two-dimensional lattice class |
23 | | */ |
24 | | |
25 | | #ifndef quantlib_tree_lattice_2d_hpp |
26 | | #define quantlib_tree_lattice_2d_hpp |
27 | | |
28 | | #include <ql/math/matrix.hpp> |
29 | | #include <ql/methods/lattices/lattice.hpp> |
30 | | #include <ql/methods/lattices/trinomialtree.hpp> |
31 | | #include <utility> |
32 | | |
33 | | namespace QuantLib { |
34 | | |
35 | | //! Two-dimensional tree-based lattice. |
36 | | /*! This lattice is based on two trinomial trees and primarily used |
37 | | for the G2 short-rate model. |
38 | | |
39 | | \ingroup lattices |
40 | | */ |
41 | | template <class Impl, class T = TrinomialTree> |
42 | | class TreeLattice2D : public TreeLattice<Impl> { |
43 | | public: |
44 | | TreeLattice2D(const ext::shared_ptr<T>& tree1, ext::shared_ptr<T> tree2, Real correlation); |
45 | | |
46 | | Size size(Size i) const; |
47 | | Size descendant(Size i, Size index, Size branch) const; |
48 | | Real probability(Size i, Size index, Size branch) const; |
49 | | protected: |
50 | | ext::shared_ptr<T> tree1_, tree2_; |
51 | | // smelly |
52 | 0 | Array grid(Time) const override { QL_FAIL("not implemented"); } |
53 | | |
54 | | private: |
55 | | Matrix m_; |
56 | | Real rho_; |
57 | | }; |
58 | | |
59 | | |
60 | | // inline definitions |
61 | | |
62 | | template <class Impl, class T> |
63 | 0 | inline Size TreeLattice2D<Impl,T>::size(Size i) const { |
64 | 0 | return tree1_->size(i)*tree2_->size(i); |
65 | 0 | } |
66 | | |
67 | | |
68 | | // template definitions |
69 | | |
70 | | template <class Impl, class T> |
71 | | TreeLattice2D<Impl, T>::TreeLattice2D(const ext::shared_ptr<T>& tree1, |
72 | | ext::shared_ptr<T> tree2, |
73 | | Real correlation) |
74 | 0 | : TreeLattice<Impl>(tree1->timeGrid(), T::branches * T::branches), tree1_(tree1), |
75 | 0 | tree2_(std::move(tree2)), m_(T::branches, T::branches), rho_(std::fabs(correlation)) { |
76 | | |
77 | | // what happens here? |
78 | 0 | if (correlation < 0.0 && T::branches == 3) { |
79 | 0 | m_[0][0] = -1.0; |
80 | 0 | m_[0][1] = -4.0; |
81 | 0 | m_[0][2] = 5.0; |
82 | 0 | m_[1][0] = -4.0; |
83 | 0 | m_[1][1] = 8.0; |
84 | 0 | m_[1][2] = -4.0; |
85 | 0 | m_[2][0] = 5.0; |
86 | 0 | m_[2][1] = -4.0; |
87 | 0 | m_[2][2] = -1.0; |
88 | 0 | } else { |
89 | 0 | m_[0][0] = 5.0; |
90 | 0 | m_[0][1] = -4.0; |
91 | 0 | m_[0][2] = -1.0; |
92 | 0 | m_[1][0] = -4.0; |
93 | 0 | m_[1][1] = 8.0; |
94 | 0 | m_[1][2] = -4.0; |
95 | 0 | m_[2][0] = -1.0; |
96 | 0 | m_[2][1] = -4.0; |
97 | 0 | m_[2][2] = 5.0; |
98 | 0 | } |
99 | 0 | } |
100 | | |
101 | | |
102 | | template <class Impl, class T> |
103 | | Size TreeLattice2D<Impl,T>::descendant(Size i, Size index, |
104 | 0 | Size branch) const { |
105 | 0 | Size modulo = tree1_->size(i); |
106 | |
|
107 | 0 | Size index1 = index % modulo; |
108 | 0 | Size index2 = index / modulo; |
109 | 0 | Size branch1 = branch % T::branches; |
110 | 0 | Size branch2 = branch / T::branches; |
111 | |
|
112 | 0 | modulo = tree1_->size(i+1); |
113 | 0 | return tree1_->descendant(i, index1, branch1) + |
114 | 0 | tree2_->descendant(i, index2, branch2)*modulo; |
115 | 0 | } |
116 | | |
117 | | template <class Impl, class T> |
118 | | Real TreeLattice2D<Impl,T>::probability(Size i, Size index, |
119 | 0 | Size branch) const { |
120 | 0 | Size modulo = tree1_->size(i); |
121 | |
|
122 | 0 | Size index1 = index % modulo; |
123 | 0 | Size index2 = index / modulo; |
124 | 0 | Size branch1 = branch % T::branches; |
125 | 0 | Size branch2 = branch / T::branches; |
126 | |
|
127 | 0 | Real prob1 = tree1_->probability(i, index1, branch1); |
128 | 0 | Real prob2 = tree2_->probability(i, index2, branch2); |
129 | | // does the 36 below depend on T::branches? |
130 | 0 | return prob1*prob2 + rho_*(m_[branch1][branch2])/36.0; |
131 | 0 | } |
132 | | |
133 | | } |
134 | | |
135 | | |
136 | | #endif |