Logo
Fully annotated reference manual - version 1.8.12
Loading...
Searching...
No Matches
Functions
transitionmatrix.cpp File Reference
#include "toplevelfixture.hpp"
#include <boost/make_shared.hpp>
#include <boost/test/unit_test.hpp>
#include <qle/math/matrixfunctions.hpp>
#include <qle/models/transitionmatrix.hpp>
#include <ql/math/comparison.hpp>

Go to the source code of this file.

Functions

 BOOST_AUTO_TEST_CASE (testGenerator)
 

Function Documentation

◆ BOOST_AUTO_TEST_CASE()

BOOST_AUTO_TEST_CASE ( testGenerator  )

Definition at line 61 of file transitionmatrix.cpp.

61 {
62
64 BOOST_CHECK(true);
65 return;
66 }
67
68 BOOST_TEST_MESSAGE("Testing transition matrix generator computation...");
69
70 // cf. Alexander Kreinin and Marina Sidelnikova, "Regularization Algorithms for Transition Matrices"
71 // table 1 (Moody's average rating transition matrix of all corporates, 1980-1999)
72
73 // clang-format off
74 Real transDataRaw[] = {
75 // Aaa Aa A Baa Ba B C Default
76 0.8588, 0.0976, 0.0048, 0.0000, 0.0003, 0.0000, 0.0000, 0.0000, // Aaa
77 0.0092, 0.8487, 0.0964, 0.0036, 0.0015, 0.0002, 0.0000, 0.0004, // Aa
78 0.0008, 0.0224, 0.8624, 0.0609, 0.0077, 0.0021, 0.0000, 0.0002, // A
79 0.0008, 0.0037, 0.0602, 0.7916, 0.0648, 0.0130, 0.0011, 0.0019, // Baa
80 0.0003, 0.0008, 0.0046, 0.0402, 0.7676, 0.0788, 0.0047, 0.0140, // Ba
81 0.0001, 0.0004, 0.0016, 0.0053, 0.0586, 0.7607, 0.0274, 0.0660, // B
82 0.0000, 0.0000, 0.0000, 0.0100, 0.0279, 0.0538, 0.5674, 0.2535, // C
83 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 1.0000 // Default
84 };
85 // clang-format on
86 std::vector<Real> transData(transDataRaw, transDataRaw + 8 * 8);
87
88 Matrix trans(8, 8, 0.0);
89 for (Size i = 0; i < 8; ++i) {
90 for (Size j = 0; j < 8; ++j) {
91 trans[i][j] = transData[i * 8 + j];
92 }
93 }
94 BOOST_TEST_MESSAGE("Original Transition Matrix =\n" << trans);
95
96 // sanitise matrix
97
98 Matrix transSan(trans);
100 BOOST_TEST_MESSAGE("Sanitised Transition Matrix =\n" << transSan);
101 for (Size i = 0; i < transSan.rows(); ++i) {
102 Real sum = 0.0;
103 for (Size j = 0; j < transSan.columns(); ++j) {
104 if (i != j)
105 BOOST_CHECK_CLOSE(trans[i][j], transSan[i][j], 1E-8);
106 sum += transSan[i][j];
107 }
108 BOOST_CHECK_CLOSE(sum, 1.0, 1E-8);
109 }
110 BOOST_CHECK_NO_THROW(checkTransitionMatrix(transSan));
111
112 // compute generator
113
114 Matrix ltr = QuantExt::Logm(transSan);
115 BOOST_TEST_MESSAGE("Log Transition Matrix=\n" << ltr);
116
117 Matrix gen = generator(transSan);
118 BOOST_TEST_MESSAGE("Generator =\n" << gen);
119 BOOST_CHECK_NO_THROW(checkGeneratorMatrix(gen));
120
121 // compute approxmiate 1y transition matrix
122
123 Matrix approx1y = QuantExt::Expm(gen);
124 BOOST_TEST_MESSAGE("Approximate Transition Matrix =\n" << approx1y);
125 checkTransitionMatrix(approx1y);
126
127 // check results from table 5
128
129 Real rowDist[] = {6.769E-4, 0.032E-4, 1.021E-4, 0.0, 0.0, 0.0, 6.475E-4, 0.0};
130 Matrix diff1 = gen - ltr;
131
132 for (Size i = 0; i < 7; ++i) {
133 Real dist = normEucl(diff1.row_begin(i), diff1.row_end(i));
134 BOOST_TEST_MESSAGE("row " << i << " reference result " << rowDist[i] << " actual result " << dist);
135 if (QuantLib::close_enough(rowDist[i], 0.0)) {
136 BOOST_CHECK(dist < 100 * QL_EPSILON);
137 } else
138 // 2% rel. diff. to value in paper
139 BOOST_CHECK_CLOSE(dist, rowDist[i], 2.0);
140 }
141
142 // check results from table 7
143
144 Matrix diff2 = approx1y - transSan;
145 // 1% rel. diff. to value in paper
146 BOOST_CHECK_CLOSE(normMax(diff2.begin(), diff2.end()), 4.599E-4, 1.0);
147 BOOST_CHECK_CLOSE(normMad(diff2.begin(), diff2.end()), 0.382E-4, 1.0);
148
149} // testGenerator
QuantLib::Matrix Logm(const QuantLib::Matrix &m)
QuantLib::Matrix Expm(const QuantLib::Matrix &m)
bool supports_Logm()
bool supports_Expm()
void checkTransitionMatrix(const Matrix &t)
check if the matrix is a transition matrix, i.e. row sums are 1 and entries are non-negative
void checkGeneratorMatrix(const Matrix &g)
check if the matrix is a generator matirx, i.e. row sums are 0 and non-diagonal elements are non-nega...
Real sum(const Cash &c, const Cash &d)
Definition: bondbasket.cpp:107
Matrix generator(const Matrix &t, const Real horizon)
void sanitiseTransitionMatrix(Matrix &m)
+ Here is the call graph for this function: