30 const ext::shared_ptr<PiecewiseConstantCorrelation>& corr,
31 const std::vector<ext::shared_ptr<
33 displacedSwapVariances,
34 const std::vector<Volatility>& mktCapletVols,
35 const ext::shared_ptr<CurveState>& cs,
37 const std::vector<Real>&
alpha,
41 mktCapletVols, cs, displacement),
42 alpha_(
alpha), lowestRoot_(lowestRoot),
43 useFullApprox_(useFullApprox) {
47 ") and alpha (" <<
alpha.size() <<
")");
54 const std::vector<ext::shared_ptr<
56 displacedSwapVariances,
57 const std::vector<Volatility>& capletVols,
61 const std::vector<Real>&
alpha,
69 std::vector<Matrix>& swapCovariancePseudoRoots) {
72 displacedSwapVariances, capletVols, cs);
76 const std::vector<Time>& rateTimes = evolution.
rateTimes();
79 "number of factors (" << numberOfFactors <<
80 ") cannot be greater than numberOfRates (" <<
81 numberOfRates <<
")");
83 "number of factors (" << numberOfFactors <<
84 ") must be greater than zero");
87 Real extraMultiplier = useFullAprox ? 1.0 : 0.0;
90 std::vector<Matrix> corrPseudo(corr.
times().size());
91 for (
Size i=0; i<corrPseudo.size(); ++i)
105 Matrix swapTimeInhomogeneousVariances(numberOfSteps, numberOfRates, 0.0);
106 std::vector<Real> originalVariances(numberOfRates, 0.0);
107 std::vector<Real> modifiedVariances(numberOfRates, 0.0);
108 const std::vector<Time>& evolutionTimes = evolution.
evolutionTimes();
109 for (
Size i=0; i<numberOfSteps; ++i) {
110 Real s = (i==0 ? 0.0 : evolutionTimes[i-1]);
111 for (
Size j=i; j<numberOfRates; ++j) {
112 const std::vector<Real>& var = displacedSwapVariances[j]->variances();
113 originalVariances[j]+=var[i];
114 swapTimeInhomogeneousVariances[i][j] = var[i]/
116 modifiedVariances[j]+=swapTimeInhomogeneousVariances[i][j];
120 for (
Size i=0; i<numberOfSteps; ++i)
121 for (
Size j=i; j<numberOfRates; ++j)
122 swapTimeInhomogeneousVariances[i][j] *= originalVariances[j]/
123 modifiedVariances[j];
128 std::vector<Matrix> CovarianceSwapPseudos(numberOfSteps);
129 std::vector<Matrix> CovarianceSwapCovs(numberOfSteps);
130 std::vector<Matrix> CovarianceSwapMarginalCovs(numberOfSteps);
132 for (
Size i=0; i<numberOfSteps; ++i) {
133 CovarianceSwapPseudos[i] = corrPseudo[i];
134 for (
Size j=0; j<numberOfRates; ++j)
135 for (
Size k=0; k < CovarianceSwapPseudos[i].columns(); ++k)
136 CovarianceSwapPseudos[i][j][k] *=
137 std::sqrt(swapTimeInhomogeneousVariances[i][j]);
139 CovarianceSwapMarginalCovs[i] = CovarianceSwapPseudos[i] *
142 CovarianceSwapCovs[i] = CovarianceSwapMarginalCovs[i];
144 CovarianceSwapCovs[i]+= CovarianceSwapCovs[i-1];
149 std::vector<Real> totVariance(numberOfRates, 0.0);
150 std::vector<Real> almostTotVariance(numberOfRates, 0.0);
151 std::vector<Real> almostTotCovariance(numberOfRates, 0.0);
152 std::vector<Real> leftCovariance(numberOfRates, 0.0);
153 for (
Size i=0; i<numberOfRates; ++i) {
154 for (
Size jj=0; jj<=i; ++jj)
155 totVariance[i] += displacedSwapVariances[i]->variances()[jj];
157 for (j=0; j<=static_cast<Integer>(i)-1; ++j)
158 almostTotVariance[i] += swapTimeInhomogeneousVariances[j][i];
159 for (j=0; j<=static_cast<Integer>(i)-2; ++j) {
160 const Matrix& thisPseudo = corrPseudo[j];
161 Real correlation = 0.0;
162 for (
Size k=0; k<numberOfFactors; ++k)
163 correlation += thisPseudo[i-1][k]*thisPseudo[i][k];
164 almostTotCovariance[i] += correlation *
165 std::sqrt(swapTimeInhomogeneousVariances[j][i] *
166 swapTimeInhomogeneousVariances[j][i-1]);
169 const Matrix& thisPseudo = corrPseudo[j];
170 Real correlation = 0.0;
171 for (
Size k=0; k<numberOfFactors; ++k)
172 correlation += thisPseudo[i-1][k]*thisPseudo[i][k];
173 leftCovariance[i] = correlation *
174 std::sqrt(swapTimeInhomogeneousVariances[j][i] *
175 swapTimeInhomogeneousVariances[j][i-1]);
182 std::vector<Real> a(numberOfSteps, 1.0);
184 std::vector<Real>
b(numberOfSteps);
186 b[0]=displacedSwapVariances[0]->variances()[0]/swapTimeInhomogeneousVariances[0][0];
188 for (
Size i=1; i<numberOfSteps; ++i) {
191 for (; j <= static_cast<Integer>(i)-2; j++)
192 swapTimeInhomogeneousVariances[j][i-1]*= a[i-1]*a[i-1];
193 swapTimeInhomogeneousVariances[j][i-1]*=
b[i-1]*
b[i-1];
195 Real w0 = invertedZedMatrix[i-1][i-1];
196 Real w1 = -invertedZedMatrix[i-1][i];
197 Real v1t1 = capletVols[i-1]*capletVols[i-1]*rateTimes[i-1];
200 Real extraConstantPart =0.0;
202 for (
Size k = i+1; k < numberOfSteps; ++k)
203 for (
Size l = i+1; l < numberOfSteps; ++l)
204 extraConstantPart+=invertedZedMatrix[i-1][k] *
205 CovarianceSwapCovs[i-1][k][l] *
206 invertedZedMatrix[i-1][l];
211 for (
Size k = i+1; k < numberOfSteps; ++k)
215 extraConstantPart+=invertedZedMatrix[i-1][i-1] *
216 CovarianceSwapCovs[i-2][i-1][k] *
217 invertedZedMatrix[i-1][k]*a[i-1];
219 extraConstantPart+=invertedZedMatrix[i-1][k] *
220 CovarianceSwapCovs[i-2][k][i-1] *
221 invertedZedMatrix[i-1][i-1]*a[i-1];
224 extraConstantPart+=invertedZedMatrix[i-1][i-1] *
225 CovarianceSwapMarginalCovs[i-1][i-1][k] *
226 invertedZedMatrix[i-1][k]*
b[i-1];
228 extraConstantPart+=invertedZedMatrix[i-1][k] *
229 CovarianceSwapCovs[i-1][k][i-1] *
230 invertedZedMatrix[i-1][i-1]*
b[i-1];
235 Real extraLinearPart=0.0;
236 for (
Size k = i+1; k < numberOfSteps; ++k)
238 extraLinearPart+=invertedZedMatrix[i-1][k] *
239 CovarianceSwapCovs[i-1][k][i] *
240 invertedZedMatrix[i-1][i];
242 extraLinearPart+=invertedZedMatrix[i-1][i] *
243 CovarianceSwapCovs[i-1][i][k] *
244 invertedZedMatrix[i-1][k];
249 Real constantPart = w0*w0*totVariance[i-1] +
250 extraConstantPart*extraMultiplier-v1t1;
251 Real linearPart = -2*w0*w1*(a[i-1]*almostTotCovariance[i] +
252 b[i-1]*leftCovariance[i]) +extraLinearPart*extraMultiplier ;
253 Real quadraticPart = w1*w1*almostTotVariance[i];
254 Real disc = linearPart*linearPart-4.0*constantPart*quadraticPart;
256 Real root, minimum = -linearPart/(2.0*quadraticPart);
257 bool rightUsed =
false;
262 }
else if (lowestRoot) {
263 root = (-linearPart-std::sqrt(disc))/(2.0*quadraticPart);
266 root = (-linearPart-std::sqrt(disc))/(2.0*quadraticPart);
269 root = (-linearPart+std::sqrt(disc))/(2.0*quadraticPart);
273 Real varianceFound = root*root*almostTotVariance[i];
274 Real varianceToFind = totVariance[i]-varianceFound;
275 Real mult = varianceToFind/swapTimeInhomogeneousVariances[i][i];
276 if (mult<=0.0 && rightUsed) {
277 root = (-linearPart-std::sqrt(disc))/(2.0*quadraticPart);
278 varianceFound = root*root*almostTotVariance[i];
279 varianceToFind = totVariance[i]-varianceFound;
280 mult = varianceToFind/swapTimeInhomogeneousVariances[i][i];
292 b[i]=std::sqrt(mult);
296 "negative root -- it should have not happened");
303 for (; j <= static_cast<Integer>(i)-2; j++)
304 swapTimeInhomogeneousVariances[j][i-1]*= a[i-1]*a[i-1];
305 swapTimeInhomogeneousVariances[j][i-1]*=
b[i-1]*
b[i-1];
309 swapCovariancePseudoRoots.resize(numberOfSteps);
310 for (
Size k=0; k<numberOfSteps; ++k) {
311 swapCovariancePseudoRoots[k] = corrPseudo[k];
312 for (
Size j=0; j<numberOfRates; ++j) {
313 Real coeff = std::sqrt(swapTimeInhomogeneousVariances[k][j]);
314 for (
Size i=0; i<numberOfFactors; ++i)
315 swapCovariancePseudoRoots[k][j][i]*=coeff;
317 QL_ENSURE(swapCovariancePseudoRoots[k].rows()==numberOfRates,
319 <<
" abcd vol wrong number of rows: "
320 << swapCovariancePseudoRoots[k].rows()
321 <<
" instead of " << numberOfRates);
322 QL_ENSURE(swapCovariancePseudoRoots[k].columns()==numberOfFactors,
324 <<
" abcd vol wrong number of columns: "
325 << swapCovariancePseudoRoots[k].columns()
326 <<
" instead of " << numberOfFactors);
ext::shared_ptr< PiecewiseConstantCorrelation > corr_
ext::shared_ptr< CurveState > cs_
static void performChecks(const EvolutionDescription &evolution, const PiecewiseConstantCorrelation &corr, const std::vector< ext::shared_ptr< PiecewiseConstantVariance > > &displacedSwapVariances, const std::vector< Volatility > &mktCapletVols, const CurveState &cs)
std::vector< ext::shared_ptr< PiecewiseConstantVariance > > displacedSwapVariances_
std::vector< Volatility > usedCapletVols_
EvolutionDescription evolution_
std::vector< Matrix > swapCovariancePseudoRoots_
Natural calibrationImpl_(Natural numberOfFactors, Natural, Real) override
std::vector< Real > alpha_
static Natural calibrationFunction(const EvolutionDescription &evolution, const PiecewiseConstantCorrelation &corr, const std::vector< ext::shared_ptr< PiecewiseConstantVariance > > &displacedSwapVariances, const std::vector< Volatility > &capletVols, const CurveState &cs, Spread displacement, const std::vector< Real > &alpha, bool lowestRoot, bool useFullApprox, Size numberOfFactors, std::vector< Matrix > &swapCovariancePseudoRoots)
CTSMMCapletOriginalCalibration(const EvolutionDescription &evolution, const ext::shared_ptr< PiecewiseConstantCorrelation > &corr, const std::vector< ext::shared_ptr< PiecewiseConstantVariance > > &displacedSwapVariances, const std::vector< Volatility > &capletVols, const ext::shared_ptr< CurveState > &cs, Spread displacement, const std::vector< Real > &alpha, bool lowestRoot, bool useFullApprox)
Curve state for market-model simulations
Market-model evolution description.
Size numberOfRates() const
const std::vector< Time > & rateTimes() const
const std::vector< Time > & evolutionTimes() const
Size numberOfSteps() const
Matrix used in linear algebra.
virtual const Matrix & correlation(Size i) const
virtual const std::vector< Time > & times() const =0
static Matrix coterminalSwapZedMatrix(const CurveState &cs, Spread displacement)
#define QL_ENSURE(condition, message)
throw an error if the given post-condition is not verified
#define QL_REQUIRE(condition, message)
throw an error if the given pre-condition is not verified
ext::function< Real(Real)> b
unsigned QL_INTEGER Natural
positive integer
QL_INTEGER Integer
integer number
Real Spread
spreads on interest rates
std::size_t Size
size of a container
Matrix rankReducedSqrt(const Matrix &matrix, Size maxRank, Real componentRetainedPercentage, SalvagingAlgorithm::Type sa)
Matrix transpose(const Matrix &m)
Matrix inverse(const Matrix &m)
pseudo square root of a real symmetric matrix
Utility functions for mapping between swap rate and forward rate.