std::vector<std::vector<double> > qlMatrixToVv(const QuantLib::Matrix &m) { std::vector<std::vector<double> > vv; for(unsigned int r=0; r<m.rows(); ++r) { std::vector<double> v; for(unsigned int c=0; c<m.columns(); ++c) { v.push_back(m[r][c]); } vv.push_back(v); } return vv; }
boost::shared_ptr<VolatilityRateSource> VolatilitySurfaceMoneyness::parallelBump(double spread) { vector<Date> newDates; QuantLib::Matrix volatilitySubset; getRolledVariables(anchorDate, newDates, volatilitySubset); Matrix spreadMatrix = Matrix(volatilitySubset.rows(), volatilitySubset.columns(), spread); Matrix bumpedVolMatrix = volatilitySubset + spreadMatrix; return boost::shared_ptr<VolatilityRateSource>(new VolatilitySurfaceMoneyness(anchorDate, newDates, strikeDimension, bumpedVolMatrix, interpolatorType, allowExtrapolation)); }
//! YY TODO: Now prefer to keep the algorithm clear, so it is highly inefficient. To improve latter. QuantLib::Matrix PCA::doPCA(const QuantLib::Matrix& originalMatrix, size_t reducedRank, bool normalizeDiagonal) // YY TODO: change it to boost::optional<bool> { size_t fullRank = originalMatrix.rows(); assert(fullRank > reducedRank); //! decompose the original matrix QuantLib::SymmetricSchurDecomposition ssd(originalMatrix); // here it check if the matrix is squared, symetric. QuantLib::Array eigenvalues = ssd.eigenvalues(); QuantLib::Matrix eigenvectors = ssd.eigenvectors(); assert(checkEigenvalue(eigenvalues, reducedRank)); //! construct the reducedRank matrix QuantLib::Array D(reducedRank); for(size_t i=0; i<D.size(); ++i) { D[i] = std::sqrt(eigenvalues[i]); } //! normalize the diagonal of the reducedRank matrix. QuantLib::Array diagonalNormalizeFactor(fullRank); if(normalizeDiagonal) { for(size_t i=0; i<fullRank; ++i) { diagonalNormalizeFactor[i] = 0.0; for(size_t j=0; j<reducedRank; ++j) { diagonalNormalizeFactor[i] += eigenvalues[j]*eigenvectors[i][j]*eigenvectors[i][j]; } diagonalNormalizeFactor[i] = sqrt(diagonalNormalizeFactor[i]); } } else { for(size_t i=0; i<fullRank; ++i) { diagonalNormalizeFactor[i] = 1.0; } } QuantLib::Matrix U(fullRank,reducedRank,0.0); for(size_t i=0; i<fullRank; ++i) { for(size_t j=0; j<reducedRank; ++j) { U[i][j] = eigenvectors[i][j]*D[j]/diagonalNormalizeFactor[i]; } } return U; }
void VolatiltiySurfaceRateSource::setInputs(Date anchorDateInput, vector<Date> observationDatesInput, vector<double> strikeDimensionInput, QuantLib::Matrix volatilityInput, SurfaceInterpolatorType interpolatorTypeInput, bool extrapolateInput) { if (observationDatesInput.size() == 0 || strikeDimensionInput.size() == 0 || volatilityInput.rows() * volatilityInput.columns() == 0) { observationDates = vector<Date>(); strikeDimension = vector<double>(); volatility = Matrix(0,0); return; } anchorDate = anchorDateInput; dayCounter = boost::shared_ptr<DayCounter>(new Actual365Fixed()); allowExtrapolation = extrapolateInput; strikeDimension = strikeDimensionInput; observationDates = observationDatesInput; if (observationDates[0] > anchorDate) { observationDates.insert(observationDates.begin(), anchorDate); volatility = QuantLib::Matrix(volatilityInput.rows(), volatilityInput.columns()+1); for (size_t i = 0; i < volatilityInput.rows(); ++i) { volatility[i][0] = volatilityInput[i][0]; for (size_t j = 0; j < volatilityInput.columns(); ++j) { volatility[i][j+1] = volatilityInput[i][j]; } } } else { volatility = volatilityInput; } time.clear(); for (size_t i = 0; i < observationDates.size(); ++i) { double yf = dayCounter->yearFraction(anchorDate, observationDates[i]); time.push_back(yf); } if (observationDates.size() > 0) { finalDate = observationDates.back(); } else { finalDate = Date(01,Jan,1901); } setInterpolatorType(interpolatorTypeInput); }
void matrixToOper(const QuantLib::Matrix &m, OPER &xMatrix) { if (m.empty()) { xMatrix.xltype = xltypeErr; xMatrix.val.err = xlerrNA; return; } xMatrix.val.array.rows = m.rows(); xMatrix.val.array.columns = m.columns(); xMatrix.val.array.lparray = new OPER[xMatrix.val.array.rows * xMatrix.val.array.columns]; xMatrix.xltype = xltypeMulti | xlbitDLLFree; for (unsigned int i=0; i<m.rows(); ++i) for (unsigned int j=0; j<m.columns(); ++j) scalarToOper(m[i][j], xMatrix.val.array.lparray[i * m.columns() + j]); }