/* * (c) Copyright Christian P. Fries, Germany. All rights reserved. Contact: email@christian-fries.de. * * Created on 20.05.2006 */ package net.finmath.montecarlo.interestrate.modelplugins; import java.util.ArrayList; import net.finmath.montecarlo.RandomVariable; import net.finmath.stochastic.RandomVariableInterface; import net.finmath.time.TimeDiscretizationInterface; /** * Implements a simple volatility model using given piece-wise constant values on * a given discretization grid. * * @author Christian Fries */ public class LIBORVolatilityModelFromGivenMatrix extends LIBORVolatilityModel { private final double[][] volatility; /** * A cache for the parameter associated with this model, it is only used when getParameter is * called repeatedly. */ private transient double[] parameter = null; /** * Creates a simple volatility model using given piece-wise constant values on * a given discretization grid. * * @param timeDiscretization Discretization of simulation time. * @param liborPeriodDiscretization Discretization of tenor times. * @param volatility Volatility matrix volatility[timeIndex][componentIndex] where timeIndex the index of the start time in timeDiscretization and componentIndex from liborPeriodDiscretization */ public LIBORVolatilityModelFromGivenMatrix( TimeDiscretizationInterface timeDiscretization, TimeDiscretizationInterface liborPeriodDiscretization, double[][] volatility) { super(timeDiscretization, liborPeriodDiscretization); this.volatility = volatility; } /* (non-Javadoc) * @see net.finmath.montecarlo.interestrate.modelplugins.LIBORVolatilityModel#getVolatility(int, int) */ @Override public RandomVariableInterface getVolatility(int timeIndex, int component) { return new RandomVariable(getTimeDiscretization().getTime(timeIndex),volatility[timeIndex][component]); } @Override public double[] getParameter() { synchronized (this) { if(parameter == null) { ArrayList<Double> parameterArray = new ArrayList<Double>(); for(int timeIndex = 0; timeIndex<getTimeDiscretization().getNumberOfTimeSteps(); timeIndex++) { for(int liborPeriodIndex = 0; liborPeriodIndex< getLiborPeriodDiscretization().getNumberOfTimeSteps(); liborPeriodIndex++) { if(getTimeDiscretization().getTime(timeIndex) < getLiborPeriodDiscretization().getTime(liborPeriodIndex) ) { parameterArray.add(volatility[timeIndex][liborPeriodIndex]); } } } parameter = new double[parameterArray.size()]; for(int i=0; i<parameter.length; i++) parameter[i] = parameterArray.get(i); } } return parameter; } @Override public void setParameter(double[] parameter) { this.parameter = null; // Invalidate cache int parameterIndex = 0; for(int timeIndex = 0; timeIndex<getTimeDiscretization().getNumberOfTimeSteps(); timeIndex++) { for(int liborPeriodIndex = 0; liborPeriodIndex< getLiborPeriodDiscretization().getNumberOfTimeSteps(); liborPeriodIndex++) { if(getTimeDiscretization().getTime(timeIndex) < getLiborPeriodDiscretization().getTime(liborPeriodIndex) ) { volatility[timeIndex][liborPeriodIndex] = Math.max(parameter[parameterIndex++],0.0); } } } return; } @Override public Object clone() { // Clone the outer array. double[][] newVolatilityArray = (double[][]) volatility.clone(); // Clone the contents of the array int rows = newVolatilityArray.length; for(int row=0;row<rows;row++){ newVolatilityArray[row] = (double[]) newVolatilityArray[row].clone(); } return new LIBORVolatilityModelFromGivenMatrix( getTimeDiscretization(), getLiborPeriodDiscretization(), newVolatilityArray); } }