61 {
62
64 BOOST_CHECK(true);
65 return;
66 }
67
68 BOOST_TEST_MESSAGE("Testing transition matrix generator computation...");
69
70
71
72
73
74 Real transDataRaw[] = {
75
76 0.8588, 0.0976, 0.0048, 0.0000, 0.0003, 0.0000, 0.0000, 0.0000,
77 0.0092, 0.8487, 0.0964, 0.0036, 0.0015, 0.0002, 0.0000, 0.0004,
78 0.0008, 0.0224, 0.8624, 0.0609, 0.0077, 0.0021, 0.0000, 0.0002,
79 0.0008, 0.0037, 0.0602, 0.7916, 0.0648, 0.0130, 0.0011, 0.0019,
80 0.0003, 0.0008, 0.0046, 0.0402, 0.7676, 0.0788, 0.0047, 0.0140,
81 0.0001, 0.0004, 0.0016, 0.0053, 0.0586, 0.7607, 0.0274, 0.0660,
82 0.0000, 0.0000, 0.0000, 0.0100, 0.0279, 0.0538, 0.5674, 0.2535,
83 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 0.0000, 1.0000
84 };
85
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
97
98 Matrix transSan(trans);
100 BOOST_TEST_MESSAGE("Sanitised Transition Matrix =\n" << transSan);
101 for (Size i = 0; i < transSan.rows(); ++i) {
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 }
111
112
113
115 BOOST_TEST_MESSAGE("Log Transition Matrix=\n" << ltr);
116
118 BOOST_TEST_MESSAGE("Generator =\n" << gen);
120
121
122
124 BOOST_TEST_MESSAGE("Approximate Transition Matrix =\n" << approx1y);
126
127
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
139 BOOST_CHECK_CLOSE(dist, rowDist[i], 2.0);
140 }
141
142
143
144 Matrix diff2 = approx1y - transSan;
145
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}
QuantLib::Matrix Logm(const QuantLib::Matrix &m)
QuantLib::Matrix Expm(const QuantLib::Matrix &m)
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)
Matrix generator(const Matrix &t, const Real horizon)
void sanitiseTransitionMatrix(Matrix &m)