/src/quantlib/ql/math/matrixutilities/getcovariance.hpp
Line | Count | Source |
1 | | /* -*- mode: c++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
2 | | |
3 | | /* |
4 | | Copyright (C) 2003, 2004, 2009 Ferdinando Ametrano |
5 | | Copyright (C) 2000, 2001, 2002, 2003 RiskMap 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 | | <https://www.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 getcovariance.hpp |
22 | | \brief Covariance matrix calculation |
23 | | */ |
24 | | |
25 | | #ifndef quantlib_montecarlo_get_covariance_h |
26 | | #define quantlib_montecarlo_get_covariance_h |
27 | | |
28 | | #include <ql/math/matrix.hpp> |
29 | | #include <ql/utilities/dataformatters.hpp> |
30 | | #include <ql/math/matrixutilities/pseudosqrt.hpp> |
31 | | |
32 | | namespace QuantLib { |
33 | | |
34 | | //! Calculation of covariance from correlation and standard deviations |
35 | | /*! Combines the correlation matrix and the vector of standard deviations |
36 | | to return the covariance matrix. |
37 | | |
38 | | Note that only the symmetric part of the correlation matrix is |
39 | | used. Also it is assumed that the diagonal member of the |
40 | | correlation matrix equals one. |
41 | | |
42 | | \pre The correlation matrix must be symmetric with the diagonal |
43 | | members equal to one. |
44 | | |
45 | | \test tested on know values and cross checked with |
46 | | CovarianceDecomposition |
47 | | */ |
48 | | template<class DataIterator> |
49 | | Matrix getCovariance(DataIterator stdDevBegin, |
50 | | DataIterator stdDevEnd, |
51 | | const Matrix& corr, |
52 | 0 | Real tolerance = 1.0e-12){ |
53 | 0 | Size size = std::distance(stdDevBegin, stdDevEnd); |
54 | 0 | QL_REQUIRE(corr.rows() == size, |
55 | 0 | "dimension mismatch between volatilities (" << size << |
56 | 0 | ") and correlation rows (" << corr.rows() << ")"); |
57 | 0 | QL_REQUIRE(corr.columns() == size, |
58 | 0 | "correlation matrix is not square: " << size << |
59 | 0 | " rows and " << corr.columns() << " columns"); |
60 | | |
61 | 0 | Matrix covariance(size,size); |
62 | 0 | Size i, j; |
63 | 0 | DataIterator iIt, jIt; |
64 | 0 | for (i=0, iIt=stdDevBegin; i<size; ++i, ++iIt){ |
65 | 0 | for (j=0, jIt=stdDevBegin; j<i; ++j, ++jIt){ |
66 | 0 | QL_REQUIRE(std::fabs(corr[i][j]-corr[j][i]) <= tolerance, |
67 | 0 | "correlation matrix not symmetric:" |
68 | 0 | << "\nc[" << i << "," << j << "] = " << corr[i][j] |
69 | 0 | << "\nc[" << j << "," << i << "] = " << corr[j][i]); |
70 | 0 | covariance[i][i] = (*iIt) * (*iIt); |
71 | 0 | covariance[i][j] = (*iIt) * (*jIt) * |
72 | 0 | 0.5 * (corr[i][j] + corr[j][i]); |
73 | 0 | covariance[j][i] = covariance[i][j]; |
74 | 0 | } |
75 | 0 | QL_REQUIRE(std::fabs(corr[i][i]-1.0) <= tolerance, |
76 | 0 | "invalid correlation matrix, " |
77 | 0 | << "diagonal element of the " << io::ordinal(i+1) |
78 | 0 | << " row is " << corr[i][i] << " instead of 1.0"); |
79 | 0 | covariance[i][i] = (*iIt) * (*iIt); |
80 | 0 | } |
81 | 0 | return covariance; |
82 | 0 | } Unexecuted instantiation: QuantLib::Matrix QuantLib::getCovariance<double*>(double*, double*, QuantLib::Matrix const&, double) Unexecuted instantiation: QuantLib::Matrix QuantLib::getCovariance<double const*>(double const*, double const*, QuantLib::Matrix const&, double) |
83 | | |
84 | | //! Covariance decomposition into correlation and variances |
85 | | /*! Extracts the correlation matrix and the vector of variances |
86 | | out of the input covariance matrix. |
87 | | |
88 | | Note that only the lower symmetric part of the covariance matrix is |
89 | | used. |
90 | | |
91 | | \pre The covariance matrix must be symmetric. |
92 | | |
93 | | \test cross checked with getCovariance |
94 | | */ |
95 | | class CovarianceDecomposition { |
96 | | public: |
97 | | /*! \pre covarianceMatrix must be symmetric */ |
98 | | CovarianceDecomposition( |
99 | | const Matrix& covarianceMatrix, |
100 | | Real tolerance = 1.0e-12); |
101 | | /*! returns the variances Array */ |
102 | 0 | const Array& variances() const { return variances_; } |
103 | | /*! returns the standard deviations Array */ |
104 | 0 | const Array& standardDeviations() const {return stdDevs_; } |
105 | | /*! returns the correlation matrix */ |
106 | 0 | const Matrix& correlationMatrix() const { return correlationMatrix_; } |
107 | | private: |
108 | | Array variances_, stdDevs_; |
109 | | Matrix correlationMatrix_; |
110 | | }; |
111 | | |
112 | | } |
113 | | |
114 | | |
115 | | #endif |