/**
* Copyright (C) 2014 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.math.cube;
import static com.google.common.collect.Lists.newArrayList;
import java.util.Collection;
import java.util.List;
import org.apache.commons.lang.Validate;
import com.opengamma.util.tuple.Quadruple;
import com.opengamma.util.tuple.Triple;
/**
* A cube that is defined by a set of nodal points (i.e. <i>(x, y, z)</i> data). Any attempt to find a <i>z</i> value
* for which there is no <i>(x, y)</i> nodal point will result in failure.
* @param <X> type of <i>x</i> data points
* @param <Y> type of <i>y</i> data points
* @param <Z> type of <i>z</i> data points
* @param <V> type of <i>v</i> data points
*/
public class NodalCube<X, Y, Z, V> extends Cube<X, Y, Z, V> {
private final X[] _xData;
private final Y[] _yData;
private final Z[] _zData;
private final V[] _vData;
private final String _name;
/**
* @param points A collection of data points, not null
* @param name A cube name
*/
public NodalCube(Collection<Quadruple<X, Y, Z, V>> points, String name) {
List<X> xData = newArrayList();
List<Y> yData = newArrayList();
List<Z> zData = newArrayList();
List<V> vData = newArrayList();
for (Quadruple<X, Y, Z, V> point : points) {
xData.add(point.getFirst());
yData.add(point.getSecond());
zData.add(point.getThird());
vData.add(point.getFourth());
}
_xData = (X[]) xData.toArray();
_yData = (Y[]) yData.toArray();
_zData = (Z[]) zData.toArray();
_vData = (V[]) vData.toArray();
_name = name;
}
/**
* @param xData An array of <i>x</i> data points, not null
* @param yData An array of <i>y</i> data points, not null, contains same number of entries as <i>x</i>
* @param zData An array of <i>z</i> data points, not null, contains same number of entries as <i>x</i>
* @param vData An array of <i>v</i> data points, not null, contains same number of entries as <i>x</i>
* @param <X> type of <i>x</i> data points
* @param <Y> type of <i>y</i> data points
* @param <Z> type of <i>z</i> data points
* @param <V> type of <i>v</i> data points
* @return A nodal cube with automatically-generated name
*/
public static <X, Y, Z, V> NodalCube from(final X[] xData, final Y[] yData, final Z[] zData, final V[] vData) {
return new NodalCube(xData, yData, zData, vData);
}
/**
* @param xData A list of <i>x</i> data points, not null
* @param yData A list of <i>y</i> data points, not null, contains same number of entries as <i>x</i>
* @param zData A list of <i>z</i> data points, not null, contains same number of entries as <i>x</i>
* @param vData An array of <i>v</i> data points, not null, contains same number of entries as <i>x</i>
* @param <X> type of <i>x</i> data points
* @param <Y> type of <i>y</i> data points
* @param <Z> type of <i>z</i> data points
* @param <V> type of <i>v</i> data points
* @return A nodal cube with automatically-generated name
*/
public static <X, Y, Z, V> NodalCube from(final List<X> xData, final List<Y> yData, final List<Z> zData, final List<V> vData) {
return new NodalCube(xData, yData, zData, vData);
}
/**
* @param xData An array of <i>x</i> data points, not null
* @param yData An array of <i>y</i> data points, not null, contains same number of entries as <i>x</i>
* @param zData An array of <i>z</i> data points, not null, contains same number of entries as <i>x</i>
* @param vData An array of <i>v</i> data points, not null, contains same number of entries as <i>x</i>
* @param <X> type of <i>x</i> data points
* @param <Y> type of <i>y</i> data points
* @param <Z> type of <i>z</i> data points
* @param <V> type of <i>v</i> data points
* @param name The name of the cube
* @return A nodal cube with automatically-generated name
*/
public static <X, Y, Z, V> NodalCube from(final X[] xData, final Y[] yData, final Z[] zData, final V[] vData, final String name) {
return new NodalCube(xData, yData, zData, vData, name);
}
/**
* @param xData A list of <i>x</i> data points, not null
* @param yData A list of <i>y</i> data points, not null, contains same number of entries as <i>x</i>
* @param zData A list of <i>z</i> data points, not null, contains same number of entries as <i>x</i>
* @param vData An array of <i>v</i> data points, not null, contains same number of entries as <i>x</i>
* @param <X> type of <i>x</i> data points
* @param <Y> type of <i>y</i> data points
* @param <Z> type of <i>z</i> data points
* @param <V> type of <i>v</i> data points
* @param name The name of the cube
* @return A nodal cube with automatically-generated name
*/
public static <X, Y, Z, V> NodalCube from(final List<X> xData, final List<Y> yData, final List<Z> zData, final List<V> vData, final String name) {
return new NodalCube(xData, yData, zData, vData, name);
}
/**
* @param xData An array of <i>x</i> data points, not null
* @param yData An array of <i>y</i> data points, not null, contains same number of entries as <i>x</i>
* @param zData An array of <i>z</i> data points, not null, contains same number of entries as <i>x</i>
* @param vData An array of <i>v</i> data points, not null, contains same number of entries as <i>x</i>
*/
public NodalCube(final X[] xData, final Y[] yData, final Z[] zData, final V[] vData) {
this(xData, yData, zData, vData, null);
}
/**
* @param xData A list of <i>x</i> data points, not null
* @param yData A list of <i>y</i> data points, not null, contains same number of entries as <i>x</i>
* @param zData A list of <i>z</i> data points, not null, contains same number of entries as <i>x</i>
* @param vData An array of <i>v</i> data points, not null, contains same number of entries as <i>x</i>
*/
public NodalCube(final List<X> xData, final List<Y> yData, final List<Z> zData, final List<V> vData) {
this(xData, yData, zData, vData, null);
}
/**
* @param xData An array of <i>x</i> data points, not null
* @param yData An array of <i>y</i> data points, not null, contains same number of entries as <i>x</i>
* @param zData An array of <i>z</i> data points, not null, contains same number of entries as <i>x</i>
* @param vData An array of <i>v</i> data points, not null, contains same number of entries as <i>x</i>
* @param name The name of the cube
*/
public NodalCube(final X[] xData, final Y[] yData, final Z[] zData, final V[] vData,
final String name) {
_xData = xData;
_yData = yData;
_zData = zData;
_vData = vData;
_name = name;
}
/**
* @param xData A list of <i>x</i> data points, not null
* @param yData A list of <i>y</i> data points, not null, contains same number of entries as <i>x</i>
* @param zData A list of <i>z</i> data points, not null, contains same number of entries as <i>x</i>
* @param vData An array of <i>v</i> data points, not null, contains same number of entries as <i>x</i>
* @param name The name of the cube
*/
public NodalCube(final List<X> xData, final List<Y> yData, final List<Z> zData, final List<V> vData,
final String name) {
_xData = (X[]) xData.toArray();
_yData = (Y[]) yData.toArray();
_zData = (Z[]) zData.toArray();
_vData = (V[]) vData.toArray();
_name = name;
}
/**
* {@inheritDoc}
* @throws IllegalArgumentException If the <i>(x, y, z)</i> value is not a nodal point
*/
@Override
public V getValue(final X x, final Y y, final Z z) {
Validate.notNull(x, "x");
Validate.notNull(y, "y");
Validate.notNull(y, "z");
final X[] xArray = getXData();
final Y[] yArray = getYData();
final Z[] zArray = getZData();
final int n = size();
for (int i = 0; i < n; i++) {
if (xArray[i].equals(x) && yArray[i].equals(y) && zArray[i].equals(z)) {
return getValues()[i];
}
}
throw new IllegalArgumentException("No x-y-z data in cube for (" + x + ", " + y + ", " + z + ")");
}
/**
* {@inheritDoc}
* @throws IllegalArgumentException If the <i>(x, y, z)</i> value is not a nodal point
*/
@Override
public V getValue(final Triple<X, Y, Z> xyz) {
Validate.notNull(xyz, "x-y-z triple");
return getValue(xyz.getFirst(), xyz.getSecond(), xyz.getThird());
}
@Override
public X[] getXData() {
return _xData;
}
@Override
public Y[] getYData() {
return _yData;
}
@Override
public Z[] getZData() {
return _zData;
}
@Override
public V[] getValues() {
return _vData;
}
@Override
public int size() {
return _vData.length;
}
@Override
public String getName() {
return _name;
}
}