TermStructCovarianceModelFromLIBORCovarianceModelParametric.java
/*
* (c) Copyright Christian P. Fries, Germany. Contact: email@christian-fries.de.
*
* Created on 22.12.2016
*/
package net.finmath.montecarlo.interestrate.models.covariance;
import net.finmath.montecarlo.interestrate.TermStructureModel;
import net.finmath.stochastic.RandomVariable;
import net.finmath.time.TimeDiscretization;
/**
* @author Christian Fries
*
* @version 1.0
*/
public class TermStructCovarianceModelFromLIBORCovarianceModelParametric extends TermStructureCovarianceModelParametric {
private final TermStructureTenorTimeScaling tenorTimeScalingModel;
private final AbstractLIBORCovarianceModelParametric covarianceModel;
/**
* @param tenorTimeScalingModel The model used for the tenor time re-scaling (providing the scaling coefficients).
* @param covarianceModel The model implementing AbstractLIBORCovarianceModelParametric.
*/
public TermStructCovarianceModelFromLIBORCovarianceModelParametric(final TermStructureTenorTimeScaling tenorTimeScalingModel, final AbstractLIBORCovarianceModelParametric covarianceModel) {
this.tenorTimeScalingModel = tenorTimeScalingModel;
this.covarianceModel = covarianceModel;
}
@Override
public double getScaledTenorTime(final double periodStart, final double periodEnd) {
if(tenorTimeScalingModel == null) {
return periodEnd-periodStart;
}
return tenorTimeScalingModel.getScaledTenorTime(periodStart, periodEnd);
}
@Override
public RandomVariable[] getFactorLoading(final double time, final double periodStart, final double periodEnd, final TimeDiscretization periodDiscretization, final RandomVariable[] realizationAtTimeIndex, final TermStructureModel model) {
final TimeDiscretization liborPeriodDiscretization = covarianceModel.getLiborPeriodDiscretization();
final int periodStartIndex = liborPeriodDiscretization.getTimeIndex(periodStart);
final int periodEndIndex = liborPeriodDiscretization.getTimeIndex(periodEnd);
final RandomVariable[] factorLoadings = covarianceModel.getFactorLoading(time, periodStartIndex, null);
if(periodEndIndex > periodStartIndex+1) {
// Need to sum factor loadings
for(int factorIndex = 0; factorIndex<factorLoadings.length; factorIndex++) {
factorLoadings[factorIndex] = factorLoadings[factorIndex].mult(liborPeriodDiscretization.getTimeStep(periodStartIndex));
}
for(int periodIndex = periodStartIndex+1; periodIndex<periodEndIndex; periodIndex++) {
final RandomVariable[] factorLoadingsForPeriod = covarianceModel.getFactorLoading(time, periodStartIndex, null);
final double periodLength = liborPeriodDiscretization.getTimeStep(periodIndex);
for(int factorIndex = 0; factorIndex<factorLoadings.length; factorIndex++) {
factorLoadings[factorIndex] = factorLoadings[factorIndex].addProduct(factorLoadingsForPeriod[factorIndex], periodLength);
}
}
for(int factorIndex = 0; factorIndex<factorLoadings.length; factorIndex++) {
factorLoadings[factorIndex] = factorLoadings[factorIndex].div(periodEnd-periodStart);
}
}
int componentIndex = periodDiscretization.getTimeIndex(periodStart);
if(componentIndex < 0) {
componentIndex = -componentIndex-1-1;
}
int componentIndex2 = periodDiscretization.getTimeIndex(periodEnd);
if(componentIndex2 < 0) {
componentIndex2 = -componentIndex2-1;
}
if(componentIndex != componentIndex2-1) {
throw new IllegalArgumentException();
}
/*
* for(int factorIndex = 0; factorIndex<factorLoadings.length; factorIndex++) {
factorLoadings[factorIndex] = factorLoadings[factorIndex].div(realizationAtTimeIndex[componentIndex].mult(periodDiscretization.getTimeStep(componentIndex)).exp());
}
*/
return factorLoadings;
}
@Override
public int getNumberOfFactors() {
return covarianceModel.getNumberOfFactors();
}
@Override
public double[] getParameter() {
if(tenorTimeScalingModel == null) {
return covarianceModel.getParameterAsDouble();
}
final double[] tenorTimeScalingParameter = tenorTimeScalingModel.getParameter();
final double[] covarianceParameter = covarianceModel.getParameterAsDouble();
final double[] parameter = new double[tenorTimeScalingParameter.length + covarianceParameter.length];
System.arraycopy(tenorTimeScalingParameter, 0, parameter, 0, tenorTimeScalingParameter.length);
System.arraycopy(covarianceParameter, 0, parameter, tenorTimeScalingParameter.length, covarianceParameter.length);
return parameter;
}
@Override
public TermStructureCovarianceModelParametric getCloneWithModifiedParameters(final double[] parameters) {
if(tenorTimeScalingModel == null) {
return new TermStructCovarianceModelFromLIBORCovarianceModelParametric(null, covarianceModel.getCloneWithModifiedParameters(parameters));
}
final double[] tenorTimeScalingParameter = tenorTimeScalingModel.getParameter();
final double[] covarianceParameter = covarianceModel.getParameterAsDouble();
System.arraycopy(parameters, 0, tenorTimeScalingParameter, 0, tenorTimeScalingParameter.length);
System.arraycopy(parameters, tenorTimeScalingParameter.length, covarianceParameter, 0, covarianceParameter.length);
return new TermStructCovarianceModelFromLIBORCovarianceModelParametric(tenorTimeScalingModel.getCloneWithModifiedParameters(tenorTimeScalingParameter), covarianceModel.getCloneWithModifiedParameters(covarianceParameter));
}
@Override
public TermStructureCovarianceModelParametric clone() {
return new TermStructCovarianceModelFromLIBORCovarianceModelParametric(tenorTimeScalingModel.clone(), (AbstractLIBORCovarianceModelParametric) covarianceModel.clone());
}
}