/**
* Copyright (C) 2012 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.math.curve;
import java.util.Map;
import org.apache.commons.lang.ArrayUtils;
import org.joda.beans.Bean;
import org.joda.beans.BeanBuilder;
import org.joda.beans.BeanDefinition;
import org.joda.beans.JodaBeanUtils;
import org.joda.beans.MetaProperty;
import org.joda.beans.Property;
import org.joda.beans.PropertyDefinition;
import org.joda.beans.impl.direct.DirectBeanBuilder;
import org.joda.beans.impl.direct.DirectMetaProperty;
import org.joda.beans.impl.direct.DirectMetaPropertyMap;
import com.opengamma.analytics.math.interpolation.Interpolator1D;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.ParallelArrayBinarySort;
/**
* A curve that is defined by a set of nodal points (i.e. <i>x-y</i> data) and an interpolator
* to return values of <i>y</i> for values of <i>x</i> that do not lie on nodal <i>x</i> values.
* One extra node point with a set value is added (called anchor point).
* The value is often 0.0 (rate anchor) or 1.0 (discount factor anchor).
* This is used in particular for spread curves; without anchor points, each curve in the
* spread could be shifted in opposite directions for the same total result.
* To anchor is used to remove the translation indetermination.
*/
@BeanDefinition
public final class DoublesCurveInterpolatedAnchor extends InterpolatedDoublesCurve {
/**
* The anchor index.
* The index in the x value of the anchor.
*/
@PropertyDefinition(get = "manual", set = "private")
private int _anchorIndex;
//-------------------------------------------------------------------------
/**
* Private constructor.
*
* @param xData The sorted xData, including the anchor.
* @param yData The yData, including the anchor.
* @param anchorIndex The index in the xData at which the anchor is located.
* @param interpolator The interpolator.
* @param name The curve name.
*/
private DoublesCurveInterpolatedAnchor(double[] xData, double[] yData, int anchorIndex, Interpolator1D interpolator, String name) {
super(xData, yData, interpolator, true, name);
_anchorIndex = anchorIndex;
}
/**
* Constructor.
*
* @param xData The x data without the anchor.
* @param yData The y data.
* @param anchor The anchor point. Should not be in xData.
* @param interpolator The interpolator.
* @param name The curve name.
* @return The curve.
*/
public static DoublesCurveInterpolatedAnchor from(double[] xData, double[] yData, double anchor, Interpolator1D interpolator, String name) {
ArgumentChecker.notNull(xData, "X data");
int xLength = xData.length;
ArgumentChecker.notNull(yData, "Y data");
ArgumentChecker.isTrue(xLength == yData.length, "Data of incorrect length.");
double[] xExtended = new double[xLength + 1];
double[] yExtended = new double[xLength + 1];
System.arraycopy(xData, 0, xExtended, 0, xLength);
xExtended[xLength] = anchor;
System.arraycopy(yData, 0, yExtended, 0, xLength);
ParallelArrayBinarySort.parallelBinarySort(xExtended, yExtended);
int anchorIndex = ArrayUtils.indexOf(xExtended, anchor);
return new DoublesCurveInterpolatedAnchor(xExtended, yExtended, anchorIndex, interpolator, name);
}
/**
* Constructor.
*
* @param xData The x data without the anchor.
* @param yData The y data.
* @param anchor The anchor point. Should not be in xData.
* @param anchorValue The anchor point value.
* @param interpolator The interpolator.
* @param name The curve name.
* @return The curve.
*/
public static DoublesCurveInterpolatedAnchor from(double[] xData, double[] yData, double anchor, double anchorValue, Interpolator1D interpolator, String name) {
ArgumentChecker.notNull(xData, "X data");
int xLength = xData.length;
ArgumentChecker.notNull(yData, "Y data");
ArgumentChecker.isTrue(xLength == yData.length, "Data of incorrect length.");
double[] xExtended = new double[xLength + 1];
double[] yExtended = new double[xLength + 1];
System.arraycopy(xData, 0, xExtended, 0, xLength);
xExtended[xLength] = anchor;
System.arraycopy(yData, 0, yExtended, 0, xLength);
yExtended[xLength] = anchorValue;
ParallelArrayBinarySort.parallelBinarySort(xExtended, yExtended);
int anchorIndex = ArrayUtils.indexOf(xExtended, anchor);
return new DoublesCurveInterpolatedAnchor(xExtended, yExtended, anchorIndex, interpolator, name);
}
//-------------------------------------------------------------------------
/**
* Constructor for Joda-Beans.
*/
protected DoublesCurveInterpolatedAnchor() {
}
//-------------------------------------------------------------------------
/**
* Gets the anchor index.
*
* @return the index
*/
public int getAnchorIndex() {
return _anchorIndex;
}
@Override
public int size() {
return super.size() - 1; // To take the anchor into account.
}
/**
* The sensitivity is the sensitivity of the underlying interpolated .
*
* @param x the value for which the sensitivity is computed, not null
* @return the sensitivity, not null
*/
@Override
public Double[] getYValueParameterSensitivity(Double x) {
ArgumentChecker.notNull(x, "x");
Double[] sensitivityWithAnchor = super.getYValueParameterSensitivity(x);
Double[] sensitivity = new Double[sensitivityWithAnchor.length - 1];
System.arraycopy(sensitivityWithAnchor, 0, sensitivity, 0, _anchorIndex);
System.arraycopy(sensitivityWithAnchor, _anchorIndex + 1, sensitivity, _anchorIndex, sensitivityWithAnchor.length - _anchorIndex - 1);
return sensitivity;
}
//-------------------------------------------------------------------------
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
DoublesCurveInterpolatedAnchor other = (DoublesCurveInterpolatedAnchor) obj;
if (_anchorIndex != other._anchorIndex) {
return false;
}
return true;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + _anchorIndex;
return result;
}
//------------------------- AUTOGENERATED START -------------------------
///CLOVER:OFF
/**
* The meta-bean for {@code DoublesCurveInterpolatedAnchor}.
* @return the meta-bean, not null
*/
public static DoublesCurveInterpolatedAnchor.Meta meta() {
return DoublesCurveInterpolatedAnchor.Meta.INSTANCE;
}
static {
JodaBeanUtils.registerMetaBean(DoublesCurveInterpolatedAnchor.Meta.INSTANCE);
}
@Override
public DoublesCurveInterpolatedAnchor.Meta metaBean() {
return DoublesCurveInterpolatedAnchor.Meta.INSTANCE;
}
//-----------------------------------------------------------------------
/**
* Sets the anchor index.
* The index in the x value of the anchor.
* @param anchorIndex the new value of the property
*/
private void setAnchorIndex(int anchorIndex) {
this._anchorIndex = anchorIndex;
}
/**
* Gets the the {@code anchorIndex} property.
* The index in the x value of the anchor.
* @return the property, not null
*/
public Property<Integer> anchorIndex() {
return metaBean().anchorIndex().createProperty(this);
}
//-----------------------------------------------------------------------
@Override
public DoublesCurveInterpolatedAnchor clone() {
return JodaBeanUtils.cloneAlways(this);
}
@Override
public String toString() {
StringBuilder buf = new StringBuilder(64);
buf.append("DoublesCurveInterpolatedAnchor{");
int len = buf.length();
toString(buf);
if (buf.length() > len) {
buf.setLength(buf.length() - 2);
}
buf.append('}');
return buf.toString();
}
@Override
protected void toString(StringBuilder buf) {
super.toString(buf);
buf.append("anchorIndex").append('=').append(JodaBeanUtils.toString(getAnchorIndex())).append(',').append(' ');
}
//-----------------------------------------------------------------------
/**
* The meta-bean for {@code DoublesCurveInterpolatedAnchor}.
*/
public static final class Meta extends InterpolatedDoublesCurve.Meta {
/**
* The singleton instance of the meta-bean.
*/
static final Meta INSTANCE = new Meta();
/**
* The meta-property for the {@code anchorIndex} property.
*/
private final MetaProperty<Integer> _anchorIndex = DirectMetaProperty.ofReadWrite(
this, "anchorIndex", DoublesCurveInterpolatedAnchor.class, Integer.TYPE);
/**
* The meta-properties.
*/
private final Map<String, MetaProperty<?>> _metaPropertyMap$ = new DirectMetaPropertyMap(
this, (DirectMetaPropertyMap) super.metaPropertyMap(),
"anchorIndex");
/**
* Restricted constructor.
*/
private Meta() {
}
@Override
protected MetaProperty<?> metaPropertyGet(String propertyName) {
switch (propertyName.hashCode()) {
case -1564745955: // anchorIndex
return _anchorIndex;
}
return super.metaPropertyGet(propertyName);
}
@Override
public BeanBuilder<? extends DoublesCurveInterpolatedAnchor> builder() {
return new DirectBeanBuilder<DoublesCurveInterpolatedAnchor>(new DoublesCurveInterpolatedAnchor());
}
@Override
public Class<? extends DoublesCurveInterpolatedAnchor> beanType() {
return DoublesCurveInterpolatedAnchor.class;
}
@Override
public Map<String, MetaProperty<?>> metaPropertyMap() {
return _metaPropertyMap$;
}
//-----------------------------------------------------------------------
/**
* The meta-property for the {@code anchorIndex} property.
* @return the meta-property, not null
*/
public MetaProperty<Integer> anchorIndex() {
return _anchorIndex;
}
//-----------------------------------------------------------------------
@Override
protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
switch (propertyName.hashCode()) {
case -1564745955: // anchorIndex
return ((DoublesCurveInterpolatedAnchor) bean).getAnchorIndex();
}
return super.propertyGet(bean, propertyName, quiet);
}
@Override
protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
switch (propertyName.hashCode()) {
case -1564745955: // anchorIndex
((DoublesCurveInterpolatedAnchor) bean).setAnchorIndex((Integer) newValue);
return;
}
super.propertySet(bean, propertyName, newValue, quiet);
}
}
///CLOVER:ON
//-------------------------- AUTOGENERATED END --------------------------
}