/**
* 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.io.Serializable;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Set;
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.DirectMetaProperty;
import org.joda.beans.impl.direct.DirectMetaPropertyMap;
import com.opengamma.util.ArgumentChecker;
import com.opengamma.util.ParallelArrayBinarySort;
import com.opengamma.util.tuple.DoublesPair;
/**
* Parent class for a family of curves where the data is stored as arrays.
* It is possible to construct a curve using either unsorted (in <i>x</i>) data or sorted (ascending in <i>x</i>).
* Note that if the constructor is told that unsorted data are sorted then no sorting will take place, which will give unpredictable results.
*/
@BeanDefinition
public abstract class ArraysDoublesCurve extends DoublesCurve implements Serializable {
/**
* The size of the data points.
*/
@PropertyDefinition(get = "private", set = "private")
private int _n;
/**
* The <i>x</i> values.
*/
@PropertyDefinition(validate = "notNull", get = "manual", set = "private")
private double[] _xData;
/**
* The <i>y</i> values.
*/
@PropertyDefinition(validate = "notNull", get = "manual", set = "private")
private double[] _yData;
/**
* The <i>x</i> values.
*/
@PropertyDefinition(get = "private", set = "private")
private Double[] _xDataObject;
/**
* The <i>y</i> values.
*/
@PropertyDefinition(get = "private", set = "private")
private Double[] _yDataObject;
/**
* Constructor for Joda-Beans.
*/
protected ArraysDoublesCurve() {
}
/**
* Creates an instance.
*
* @param xData the array of <i>x</i> data, not null
* @param yData the array of <i>y</i> data, contains same number of entries as <i>x</i>, not null
* @param isSorted whether the <i>x</i>-data is sorted ascending
*/
public ArraysDoublesCurve(final double[] xData, final double[] yData, final boolean isSorted) {
ArgumentChecker.notNull(xData, "x data");
ArgumentChecker.notNull(yData, "y data");
ArgumentChecker.isTrue(xData.length == yData.length, "x data size {} must be equal to y data size {}", xData.length, yData.length);
_n = xData.length;
_xData = Arrays.copyOf(xData, _n);
_yData = Arrays.copyOf(yData, _n);
if (!isSorted) {
ParallelArrayBinarySort.parallelBinarySort(_xData, _yData);
}
}
/**
* Creates an instance.
*
* @param xData the array of <i>x</i> data, not null
* @param yData the array of <i>y</i> data, contains same number of entries as <i>x</i>, not null
* @param isSorted whether the <i>x</i>-data is sorted ascending
*/
public ArraysDoublesCurve(final Double[] xData, final Double[] yData, final boolean isSorted) {
super();
ArgumentChecker.notNull(xData, "x data");
ArgumentChecker.notNull(yData, "y data");
_n = xData.length;
ArgumentChecker.isTrue(xData.length == yData.length, "x data size {} must be equal to y data size {}", xData.length, yData.length);
_xData = new double[_n];
_yData = new double[_n];
for (int i = 0; i < _n; i++) {
Double x = xData[i];
Double y = yData[i];
ArgumentChecker.notNull(x, "x");
ArgumentChecker.notNull(y, "y");
_xData[i] = x;
_yData[i] = y;
}
if (!isSorted) {
ParallelArrayBinarySort.parallelBinarySort(_xData, _yData);
}
}
/**
* Creates an instance.
*
* @param data the map of <i>x-y</i> data, not null
* @param isSorted whether the <i>x</i>-data is sorted ascending
*/
public ArraysDoublesCurve(final Map<Double, Double> data, final boolean isSorted) {
super();
ArgumentChecker.notNull(data, "data");
_n = data.size();
_xData = new double[_n];
_yData = new double[_n];
int i = 0;
for (final Map.Entry<Double, Double> entry : data.entrySet()) {
Double x = entry.getKey();
Double y = entry.getValue();
ArgumentChecker.notNull(x, "x");
ArgumentChecker.notNull(y, "y");
_xData[i] = x;
_yData[i++] = y;
}
if (!isSorted) {
ParallelArrayBinarySort.parallelBinarySort(_xData, _yData);
}
}
/**
* Creates an instance.
*
* @param data the array of pairs of <i>x-y</i> data, not null
* @param isSorted whether the <i>x</i>-data is sorted ascending
*/
public ArraysDoublesCurve(final DoublesPair[] data, final boolean isSorted) {
super();
ArgumentChecker.notNull(data, "data");
_n = data.length;
_xData = new double[_n];
_yData = new double[_n];
for (int i = 0; i < _n; i++) {
DoublesPair pair = data[i];
ArgumentChecker.notNull(pair, "pair");
_xData[i] = pair.first;
_yData[i] = pair.second;
}
if (!isSorted) {
ParallelArrayBinarySort.parallelBinarySort(_xData, _yData);
}
}
/**
* Creates an instance.
*
* @param data the set of pairs of <i>x-y</i> data, not null
* @param isSorted whether the <i>x</i>-data is sorted ascending
*/
public ArraysDoublesCurve(final Set<DoublesPair> data, final boolean isSorted) {
super();
ArgumentChecker.notNull(data, "data");
_n = data.size();
_xData = new double[_n];
_yData = new double[_n];
int i = 0;
for (final DoublesPair entry : data) {
ArgumentChecker.notNull(entry, "entry");
_xData[i] = entry.first;
_yData[i++] = entry.second;
}
if (!isSorted) {
ParallelArrayBinarySort.parallelBinarySort(_xData, _yData);
}
}
/**
* Creates an instance.
*
* @param xData the list of <i>x</i> data, not null
* @param yData the list of <i>y</i> data, contains same number of entries as <i>x</i>, not null
* @param isSorted whether the <i>x</i>-data is sorted ascending
*/
public ArraysDoublesCurve(final List<Double> xData, final List<Double> yData, final boolean isSorted) {
super();
ArgumentChecker.notNull(xData, "x data");
ArgumentChecker.notNull(yData, "y data");
ArgumentChecker.isTrue(xData.size() == yData.size(), "x data size {} must be equal to y data size {}", xData.size(), yData.size());
_n = xData.size();
_xData = new double[_n];
_yData = new double[_n];
for (int i = 0; i < _n; i++) {
Double x = xData.get(i);
Double y = yData.get(i);
ArgumentChecker.notNull(x, "x");
ArgumentChecker.notNull(y, "y");
_xData[i] = x;
_yData[i] = y;
}
if (!isSorted) {
ParallelArrayBinarySort.parallelBinarySort(_xData, _yData);
}
}
/**
* Creates an instance.
*
* @param data the list of pairs of <i>x-y</i> data, not null
* @param isSorted whether the <i>x</i>-data is sorted ascending
*/
public ArraysDoublesCurve(final List<DoublesPair> data, final boolean isSorted) {
super();
ArgumentChecker.notNull(data, "data");
ArgumentChecker.noNulls(data, "data");
_n = data.size();
_xData = new double[_n];
_yData = new double[_n];
int i = 0;
for (final DoublesPair pair : data) {
_xData[i] = pair.first;
_yData[i++] = pair.second;
}
if (!isSorted) {
ParallelArrayBinarySort.parallelBinarySort(_xData, _yData);
}
}
/**
* Creates an instance.
*
* @param xData the array of <i>x</i> data, not null
* @param yData the array of <i>y</i> data, contains same number of entries as <i>x</i>, not null
* @param isSorted whether the <i>x</i>-data is sorted ascending
* @param name the name of the curve, not null
*/
public ArraysDoublesCurve(final double[] xData, final double[] yData, final boolean isSorted, final String name) {
super(name);
ArgumentChecker.notNull(xData, "x data");
ArgumentChecker.notNull(yData, "y data");
ArgumentChecker.isTrue(xData.length == yData.length, "x data size {} must be equal to y data size {}", xData.length, yData.length);
_n = xData.length;
_xData = Arrays.copyOf(xData, _n);
_yData = Arrays.copyOf(yData, _n);
if (!isSorted) {
ParallelArrayBinarySort.parallelBinarySort(_xData, _yData);
}
}
/**
* Creates an instance.
*
* @param xData the array of <i>x</i> data, not null
* @param yData the array of <i>y</i> data, contains same number of entries as <i>x</i>, not null
* @param isSorted whether the <i>x</i>-data is sorted ascending
* @param name the name of the curve, not null
*/
public ArraysDoublesCurve(final Double[] xData, final Double[] yData, final boolean isSorted, final String name) {
super(name);
ArgumentChecker.notNull(xData, "x data");
_n = xData.length;
ArgumentChecker.notNull(yData, "y data");
ArgumentChecker.isTrue(xData.length == yData.length, "x data size {} must be equal to y data size {}", xData.length, yData.length);
_xData = new double[_n];
_yData = new double[_n];
for (int i = 0; i < _n; i++) {
ArgumentChecker.notNull(xData[i], "x");
ArgumentChecker.notNull(yData[i], "y");
_xData[i] = xData[i];
_yData[i] = yData[i];
}
if (!isSorted) {
ParallelArrayBinarySort.parallelBinarySort(_xData, _yData);
}
}
/**
* Creates an instance.
*
* @param data the map of <i>x-y</i> data, not null
* @param isSorted whether the <i>x</i>-data is sorted ascending
* @param name the name of the curve, not null
*/
public ArraysDoublesCurve(final Map<Double, Double> data, final boolean isSorted, final String name) {
super(name);
ArgumentChecker.notNull(data, "data");
_n = data.size();
_xData = new double[_n];
_yData = new double[_n];
int i = 0;
for (final Map.Entry<Double, Double> entry : data.entrySet()) {
ArgumentChecker.notNull(entry.getKey(), "x");
ArgumentChecker.notNull(entry.getValue(), "y");
_xData[i] = entry.getKey();
_yData[i++] = entry.getValue();
}
if (!isSorted) {
ParallelArrayBinarySort.parallelBinarySort(_xData, _yData);
}
}
/**
* Creates an instance.
*
* @param data the array of pairs of <i>x-y</i> data, not null
* @param isSorted whether the <i>x</i>-data is sorted ascending
* @param name the name of the curve, not null
*/
public ArraysDoublesCurve(final DoublesPair[] data, final boolean isSorted, final String name) {
super(name);
ArgumentChecker.notNull(data, "data");
ArgumentChecker.notNull(data, "data");
_n = data.length;
_xData = new double[_n];
_yData = new double[_n];
for (int i = 0; i < _n; i++) {
ArgumentChecker.notNull(data[i], "entry");
_xData[i] = data[i].first;
_yData[i] = data[i].second;
}
if (!isSorted) {
ParallelArrayBinarySort.parallelBinarySort(_xData, _yData);
}
}
/**
* Creates an instance.
*
* @param data the set of pairs of <i>x-y</i> data, not null
* @param isSorted whether the <i>x</i>-data is sorted ascending
* @param name the name of the curve, not null
*/
public ArraysDoublesCurve(final Set<DoublesPair> data, final boolean isSorted, final String name) {
super(name);
ArgumentChecker.notNull(data, "data");
_n = data.size();
_xData = new double[_n];
_yData = new double[_n];
int i = 0;
for (final DoublesPair entry : data) {
ArgumentChecker.notNull(entry, "entry");
_xData[i] = entry.first;
_yData[i++] = entry.second;
}
if (!isSorted) {
ParallelArrayBinarySort.parallelBinarySort(_xData, _yData);
}
}
/**
* Creates an instance.
*
* @param xData the list of <i>x</i> data, not null
* @param yData the list of <i>y</i> data, contains same number of entries as <i>x</i>, not null
* @param isSorted whether the <i>x</i>-data is sorted ascending
* @param name the name of the curve, not null
*/
public ArraysDoublesCurve(final List<Double> xData, final List<Double> yData, final boolean isSorted, final String name) {
super(name);
ArgumentChecker.notNull(xData, "x data");
ArgumentChecker.notNull(yData, "y data");
ArgumentChecker.isTrue(xData.size() == yData.size(), "x data size {} must be equal to y data size {}", xData.size(), yData.size());
_n = xData.size();
_xData = new double[_n];
_yData = new double[_n];
for (int i = 0; i < _n; i++) {
ArgumentChecker.notNull(xData.get(i), "x");
ArgumentChecker.notNull(yData.get(i), "y");
_xData[i] = xData.get(i);
_yData[i] = yData.get(i);
}
if (!isSorted) {
ParallelArrayBinarySort.parallelBinarySort(_xData, _yData);
}
}
/**
* Creates an instance.
*
* @param data the list of pairs of <i>x-y</i> data, not null
* @param isSorted whether the <i>x</i>-data is sorted ascending
* @param name the name of the curve, not null
*/
public ArraysDoublesCurve(final List<DoublesPair> data, final boolean isSorted, final String name) {
super(name);
ArgumentChecker.notNull(data, "data");
ArgumentChecker.noNulls(data, "data");
_n = data.size();
_xData = new double[_n];
_yData = new double[_n];
int i = 0;
for (final DoublesPair pair : data) {
_xData[i] = pair.first;
_yData[i++] = pair.second;
}
if (!isSorted) {
ParallelArrayBinarySort.parallelBinarySort(_xData, _yData);
}
}
//-------------------------------------------------------------------------
@Override
public synchronized Double[] getXData() {
if (_xDataObject != null) {
return _xDataObject;
}
_xDataObject = new Double[_n];
for (int i = 0; i < _n; i++) {
_xDataObject[i] = _xData[i];
}
return _xDataObject;
}
@Override
public synchronized Double[] getYData() {
if (_yDataObject != null) {
return _yDataObject;
}
_yDataObject = new Double[_n];
for (int i = 0; i < _n; i++) {
_yDataObject[i] = _yData[i];
}
return _yDataObject;
}
/**
* Returns the <i>x</i> data points as a primitive array.
*
* @return the <i>x</i> data, not null
*/
public double[] getXDataAsPrimitive() {
return _xData;
}
/**
* Returns the <i>y</i> data points as a primitive array.
*
* @return the <i>y</i> data, not null
*/
public double[] getYDataAsPrimitive() {
return _yData;
}
@Override
public int size() {
return _n;
}
//-------------------------------------------------------------------------
@Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (!super.equals(obj)) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final ArraysDoublesCurve other = (ArraysDoublesCurve) obj;
return ArrayUtils.isEquals(_xData, other._xData) && ArrayUtils.isEquals(_yData, other._yData);
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + Arrays.hashCode(_xData);
result = prime * result + Arrays.hashCode(_yData);
return result;
}
//------------------------- AUTOGENERATED START -------------------------
///CLOVER:OFF
/**
* The meta-bean for {@code ArraysDoublesCurve}.
* @return the meta-bean, not null
*/
public static ArraysDoublesCurve.Meta meta() {
return ArraysDoublesCurve.Meta.INSTANCE;
}
static {
JodaBeanUtils.registerMetaBean(ArraysDoublesCurve.Meta.INSTANCE);
}
@Override
public ArraysDoublesCurve.Meta metaBean() {
return ArraysDoublesCurve.Meta.INSTANCE;
}
//-----------------------------------------------------------------------
/**
* Gets the size of the data points.
* @return the value of the property
*/
private int getN() {
return _n;
}
/**
* Sets the size of the data points.
* @param n the new value of the property
*/
private void setN(int n) {
this._n = n;
}
/**
* Gets the the {@code n} property.
* @return the property, not null
*/
public final Property<Integer> n() {
return metaBean().n().createProperty(this);
}
//-----------------------------------------------------------------------
/**
* Sets the <i>x</i> values.
* @param xData the new value of the property, not null
*/
private void setXData(double[] xData) {
JodaBeanUtils.notNull(xData, "xData");
this._xData = xData;
}
/**
* Gets the the {@code xData} property.
* @return the property, not null
*/
public final Property<double[]> xData() {
return metaBean().xData().createProperty(this);
}
//-----------------------------------------------------------------------
/**
* Sets the <i>y</i> values.
* @param yData the new value of the property, not null
*/
private void setYData(double[] yData) {
JodaBeanUtils.notNull(yData, "yData");
this._yData = yData;
}
/**
* Gets the the {@code yData} property.
* @return the property, not null
*/
public final Property<double[]> yData() {
return metaBean().yData().createProperty(this);
}
//-----------------------------------------------------------------------
/**
* Gets the <i>x</i> values.
* @return the value of the property
*/
private Double[] getXDataObject() {
return _xDataObject;
}
/**
* Sets the <i>x</i> values.
* @param xDataObject the new value of the property
*/
private void setXDataObject(Double[] xDataObject) {
this._xDataObject = xDataObject;
}
/**
* Gets the the {@code xDataObject} property.
* @return the property, not null
*/
public final Property<Double[]> xDataObject() {
return metaBean().xDataObject().createProperty(this);
}
//-----------------------------------------------------------------------
/**
* Gets the <i>y</i> values.
* @return the value of the property
*/
private Double[] getYDataObject() {
return _yDataObject;
}
/**
* Sets the <i>y</i> values.
* @param yDataObject the new value of the property
*/
private void setYDataObject(Double[] yDataObject) {
this._yDataObject = yDataObject;
}
/**
* Gets the the {@code yDataObject} property.
* @return the property, not null
*/
public final Property<Double[]> yDataObject() {
return metaBean().yDataObject().createProperty(this);
}
//-----------------------------------------------------------------------
@Override
public String toString() {
StringBuilder buf = new StringBuilder(192);
buf.append("ArraysDoublesCurve{");
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("n").append('=').append(JodaBeanUtils.toString(getN())).append(',').append(' ');
buf.append("xData").append('=').append(JodaBeanUtils.toString(getXData())).append(',').append(' ');
buf.append("yData").append('=').append(JodaBeanUtils.toString(getYData())).append(',').append(' ');
buf.append("xDataObject").append('=').append(JodaBeanUtils.toString(getXDataObject())).append(',').append(' ');
buf.append("yDataObject").append('=').append(JodaBeanUtils.toString(getYDataObject())).append(',').append(' ');
}
//-----------------------------------------------------------------------
/**
* The meta-bean for {@code ArraysDoublesCurve}.
*/
public static class Meta extends DoublesCurve.Meta {
/**
* The singleton instance of the meta-bean.
*/
static final Meta INSTANCE = new Meta();
/**
* The meta-property for the {@code n} property.
*/
private final MetaProperty<Integer> _n = DirectMetaProperty.ofReadWrite(
this, "n", ArraysDoublesCurve.class, Integer.TYPE);
/**
* The meta-property for the {@code xData} property.
*/
private final MetaProperty<double[]> _xData = DirectMetaProperty.ofReadWrite(
this, "xData", ArraysDoublesCurve.class, double[].class);
/**
* The meta-property for the {@code yData} property.
*/
private final MetaProperty<double[]> _yData = DirectMetaProperty.ofReadWrite(
this, "yData", ArraysDoublesCurve.class, double[].class);
/**
* The meta-property for the {@code xDataObject} property.
*/
private final MetaProperty<Double[]> _xDataObject = DirectMetaProperty.ofReadWrite(
this, "xDataObject", ArraysDoublesCurve.class, Double[].class);
/**
* The meta-property for the {@code yDataObject} property.
*/
private final MetaProperty<Double[]> _yDataObject = DirectMetaProperty.ofReadWrite(
this, "yDataObject", ArraysDoublesCurve.class, Double[].class);
/**
* The meta-properties.
*/
private final Map<String, MetaProperty<?>> _metaPropertyMap$ = new DirectMetaPropertyMap(
this, (DirectMetaPropertyMap) super.metaPropertyMap(),
"n",
"xData",
"yData",
"xDataObject",
"yDataObject");
/**
* Restricted constructor.
*/
protected Meta() {
}
@Override
protected MetaProperty<?> metaPropertyGet(String propertyName) {
switch (propertyName.hashCode()) {
case 110: // n
return _n;
case 112945218: // xData
return _xData;
case 113868739: // yData
return _yData;
case -2041692639: // xDataObject
return _xDataObject;
case 456323298: // yDataObject
return _yDataObject;
}
return super.metaPropertyGet(propertyName);
}
@Override
public BeanBuilder<? extends ArraysDoublesCurve> builder() {
throw new UnsupportedOperationException("ArraysDoublesCurve is an abstract class");
}
@Override
public Class<? extends ArraysDoublesCurve> beanType() {
return ArraysDoublesCurve.class;
}
@Override
public Map<String, MetaProperty<?>> metaPropertyMap() {
return _metaPropertyMap$;
}
//-----------------------------------------------------------------------
/**
* The meta-property for the {@code n} property.
* @return the meta-property, not null
*/
public final MetaProperty<Integer> n() {
return _n;
}
/**
* The meta-property for the {@code xData} property.
* @return the meta-property, not null
*/
public final MetaProperty<double[]> xData() {
return _xData;
}
/**
* The meta-property for the {@code yData} property.
* @return the meta-property, not null
*/
public final MetaProperty<double[]> yData() {
return _yData;
}
/**
* The meta-property for the {@code xDataObject} property.
* @return the meta-property, not null
*/
public final MetaProperty<Double[]> xDataObject() {
return _xDataObject;
}
/**
* The meta-property for the {@code yDataObject} property.
* @return the meta-property, not null
*/
public final MetaProperty<Double[]> yDataObject() {
return _yDataObject;
}
//-----------------------------------------------------------------------
@Override
protected Object propertyGet(Bean bean, String propertyName, boolean quiet) {
switch (propertyName.hashCode()) {
case 110: // n
return ((ArraysDoublesCurve) bean).getN();
case 112945218: // xData
return ((ArraysDoublesCurve) bean).getXData();
case 113868739: // yData
return ((ArraysDoublesCurve) bean).getYData();
case -2041692639: // xDataObject
return ((ArraysDoublesCurve) bean).getXDataObject();
case 456323298: // yDataObject
return ((ArraysDoublesCurve) bean).getYDataObject();
}
return super.propertyGet(bean, propertyName, quiet);
}
@Override
protected void propertySet(Bean bean, String propertyName, Object newValue, boolean quiet) {
switch (propertyName.hashCode()) {
case 110: // n
((ArraysDoublesCurve) bean).setN((Integer) newValue);
return;
case 112945218: // xData
((ArraysDoublesCurve) bean).setXData((double[]) newValue);
return;
case 113868739: // yData
((ArraysDoublesCurve) bean).setYData((double[]) newValue);
return;
case -2041692639: // xDataObject
((ArraysDoublesCurve) bean).setXDataObject((Double[]) newValue);
return;
case 456323298: // yDataObject
((ArraysDoublesCurve) bean).setYDataObject((Double[]) newValue);
return;
}
super.propertySet(bean, propertyName, newValue, quiet);
}
@Override
protected void validate(Bean bean) {
JodaBeanUtils.notNull(((ArraysDoublesCurve) bean)._xData, "xData");
JodaBeanUtils.notNull(((ArraysDoublesCurve) bean)._yData, "yData");
super.validate(bean);
}
}
///CLOVER:ON
//-------------------------- AUTOGENERATED END --------------------------
}