/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.financial.curve.interestrate.generator;
import java.util.Arrays;
import com.opengamma.analytics.financial.interestrate.InstrumentDerivative;
import com.opengamma.analytics.financial.interestrate.YieldCurveBundle;
import com.opengamma.analytics.financial.model.interestrate.curve.YieldAndDiscountAddZeroSpreadCurve;
import com.opengamma.analytics.financial.model.interestrate.curve.YieldAndDiscountCurve;
import com.opengamma.analytics.financial.provider.description.interestrate.MulticurveProviderInterface;
import com.opengamma.util.ArgumentChecker;
/**
* Store the details and generate the required curve. The curve is the sum (or difference) of the curves
* (operation on the continuously-compounded zero-coupon rates) produced by the array of generators.
* The number of parameter for each curve is imposed.
* The generated curve is a YieldAndDiscountAddZeroSpreadCurve.
*/
@SuppressWarnings("deprecation")
public class GeneratorCurveAddYieldNb extends GeneratorYDCurve {
/**
* The array of generators describing the different parts of the spread curve.
*/
private final GeneratorYDCurve[] _generators;
/**
* The number of parameter associated to each generator.
*/
private final int[] _nbParameters;
/**
* The total number of parameters (sum of _nbParameters).
*/
private int _totalNbParameters;
/**
* If true, the rate of all curves, except the first one, will be subtracted from the first one. If false, all the rates are added.
*/
private final boolean _substract;
/**
* The number of generators.
*/
private final int _nbGenerators;
/**
* Constructor.
* @param generators The array of constructors for the component curves.
* @param nbParameters The number of parameter associated to each generator.
* @param substract If true, the rate of all curves, except the first one, will be subtracted from the first one. If false, all the rates are added.
*/
public GeneratorCurveAddYieldNb(final GeneratorYDCurve[] generators, final int[] nbParameters, final boolean substract) {
ArgumentChecker.notNull(generators, "Generators");
_generators = generators;
ArgumentChecker.isTrue(generators.length == nbParameters.length, "Number of parameters should be the same a number of generatros.");
_nbParameters = nbParameters;
_totalNbParameters = 0;
for (final int nbParameter : nbParameters) {
_totalNbParameters += nbParameter;
}
_nbGenerators = generators.length;
_substract = substract;
}
@Override
public int getNumberOfParameter() {
int nbParam = 0;
for (int loopgen = 0; loopgen < _nbGenerators; loopgen++) {
nbParam += _generators[loopgen].getNumberOfParameter();
}
return nbParam;
}
@Override
public YieldAndDiscountCurve generateCurve(final String name, final double[] x) {
ArgumentChecker.isTrue(x.length == getNumberOfParameter(), "Incorrect number of parameters");
final YieldAndDiscountCurve[] underlyingCurves = new YieldAndDiscountCurve[_nbGenerators];
int index = 0;
for (int loopgen = 0; loopgen < _nbGenerators; loopgen++) {
final double[] paramCurve = Arrays.copyOfRange(x, index, index + _generators[loopgen].getNumberOfParameter());
index += _generators[loopgen].getNumberOfParameter();
underlyingCurves[loopgen] = _generators[loopgen].generateCurve(name + "-" + loopgen, paramCurve);
}
return new YieldAndDiscountAddZeroSpreadCurve(name, _substract, underlyingCurves);
}
/**
* {@inheritDoc}
* @deprecated Curve builders that use and populate {@link YieldCurveBundle}s are deprecated.
*/
@Deprecated
@Override
public YieldAndDiscountCurve generateCurve(final String name, final YieldCurveBundle bundle, final double[] parameters) {
return generateCurve(name, parameters);
}
@Override
public YieldAndDiscountCurve generateCurve(final String name, final MulticurveProviderInterface multicurve, final double[] parameters) {
return generateCurve(name, parameters);
}
/**
* Create the final generators.
* The relevant array of instrument is passed to each generator. For all the generator, except the first, the last instrument of the
* previous generator is also passed as an indication of the previous part (can be used in "anchor" for example).
* @param data The array of instrument used to construct the curve.
* @return The final generator.
*/
@Override
public GeneratorYDCurve finalGenerator(final Object data) {
ArgumentChecker.isTrue(data instanceof InstrumentDerivative[], "data should be an array of InstrumentDerivative");
final InstrumentDerivative[] instruments = (InstrumentDerivative[]) data;
ArgumentChecker.isTrue(instruments.length == _totalNbParameters, "The data should have the size prescribed by the _nbParameters");
final GeneratorYDCurve[] finalGenerator = new GeneratorYDCurve[_nbGenerators];
int nbDataUsed = 0;
final InstrumentDerivative[] instruments0 = new InstrumentDerivative[_nbParameters[0]];
System.arraycopy(instruments, 0, instruments0, 0, _nbParameters[0]);
finalGenerator[0] = _generators[0].finalGenerator(instruments0);
nbDataUsed += _nbParameters[0];
for (int loopgen = 1; loopgen < _nbParameters.length; loopgen++) {
final InstrumentDerivative[] instrumentsCurrent = new InstrumentDerivative[_nbParameters[loopgen] + 1];
System.arraycopy(instruments, nbDataUsed - 1, instrumentsCurrent, 0, _nbParameters[loopgen] + 1);
finalGenerator[loopgen] = _generators[loopgen].finalGenerator(instrumentsCurrent);
nbDataUsed += _nbParameters[loopgen];
}
return new GeneratorCurveAddYield(finalGenerator, _substract);
}
@Override
public double[] initialGuess(final double[] rates) {
final double[] guess = new double[rates.length];
int nbDataUsed = 0;
int nbParam = 0;
for (int loopgen = 0; loopgen < _nbGenerators; loopgen++) {
nbParam = _generators[loopgen].getNumberOfParameter();
final double[] tmp = new double[nbParam];
System.arraycopy(rates, nbDataUsed, tmp, 0, nbParam);
System.arraycopy(_generators[loopgen].initialGuess(tmp), 0, guess, nbDataUsed, nbParam);
nbDataUsed += nbParam;
}
return guess;
}
}