/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.math.cube;
import java.util.HashMap;
import java.util.Map;
/**
* Contains methods for performing shifts on {@link Cube} without needing to know the exact type of the cube.
*/
public class CubeShiftFunctionFactory {
/** Additive shift function for {@link ConstantDoublesCube} */
public static final ConstantCubeAdditiveShiftFunction CONSTANT_ADDITIVE = new ConstantCubeAdditiveShiftFunction();
/** Multiplicative shift function for {@link ConstantDoublesCube} */
public static final ConstantCubeMultiplicativeShiftFunction CONSTANT_MULTIPLICATIVE = new ConstantCubeMultiplicativeShiftFunction();
/** Additive shift function for {@link FunctionalDoublesCube} */
public static final FunctionalCubeAdditiveShiftFunction FUNCTIONAL_ADDITIVE = new FunctionalCubeAdditiveShiftFunction();
/** Multiplicative shift function for {@link FunctionalDoublesCube} */
public static final FunctionalCubeMultiplicativeShiftFunction FUNCTIONAL_MULTIPLICATIVE = new FunctionalCubeMultiplicativeShiftFunction();
/** Additive shift function for {@link InterpolatedDoublesCube} */
public static final InterpolatedCubeAdditiveShiftFunction INTERPOLATED_ADDITIVE = new InterpolatedCubeAdditiveShiftFunction();
/** Multiplicative shift function for {@link InterpolatedDoublesCube} */
public static final InterpolatedCubeMultiplicativeShiftFunction INTERPOLATED_MULTIPLICATIVE = new InterpolatedCubeMultiplicativeShiftFunction();
/** Additive shift function for {@link InterpolatedFromSurfacesDoublesCube} */
public static final InterpolatedFromSurfacesCubeAdditiveShiftFunction INTERPOLATED_FROM_CURVES_ADDITIVE = new InterpolatedFromSurfacesCubeAdditiveShiftFunction();
/** Additive shift function for {@link NodalDoublesCube} */
public static final NodalCubeAdditiveShiftFunction NODAL_ADDITIVE = new NodalCubeAdditiveShiftFunction();
/** Multiplicative shift function for {@link NodalDoublesCube} */
public static final NodalCubeMultiplicativeShiftFunction NODAL_MULTIPLICATIVE = new NodalCubeMultiplicativeShiftFunction();
private static final Map<Class<?>, CubeShiftFunction<?>> s_instances = new HashMap<>();
static {
s_instances.put(ConstantCubeAdditiveShiftFunction.class, CONSTANT_ADDITIVE);
s_instances.put(ConstantCubeMultiplicativeShiftFunction.class, CONSTANT_MULTIPLICATIVE);
s_instances.put(FunctionalCubeAdditiveShiftFunction.class, FUNCTIONAL_ADDITIVE);
s_instances.put(FunctionalCubeMultiplicativeShiftFunction.class, FUNCTIONAL_MULTIPLICATIVE);
s_instances.put(InterpolatedCubeAdditiveShiftFunction.class, INTERPOLATED_ADDITIVE);
s_instances.put(InterpolatedCubeMultiplicativeShiftFunction.class, INTERPOLATED_MULTIPLICATIVE);
s_instances.put(InterpolatedFromSurfacesCubeAdditiveShiftFunction.class, INTERPOLATED_FROM_CURVES_ADDITIVE);
s_instances.put(NodalCubeAdditiveShiftFunction.class, NODAL_ADDITIVE);
s_instances.put(NodalCubeMultiplicativeShiftFunction.class, NODAL_MULTIPLICATIVE);
}
/**
* Gets the function for a class type.
* @param clazz The class
* @return The function
* @throws IllegalArgumentException If the function is not one of the static instances
*/
public static CubeShiftFunction<?> getFunction(final Class<?> clazz) {
final CubeShiftFunction<?> f = s_instances.get(clazz);
if (f == null) {
throw new IllegalArgumentException("Could not get function for " + clazz.getName());
}
return f;
}
/**
* For a cube Cube<Double, Double, Double, Double>, return a parallel-shifted cube.
* @param cube The original cube
* @param shift The shift
* @param useAdditive true if the shift is additive, false if the shift is multiplicative (i.e. a percentage shift)
* @return A shifted cube with automatically-generated name
* @throws IllegalArgumentException If the cube type is not constant, functional, interpolated, nodal or spread
*/
public static Cube<Double, Double, Double, Double> getShiftedCube(final Cube<Double, Double, Double, Double> cube, final double shift, final boolean useAdditive) {
if (cube instanceof ConstantDoublesCube) {
return useAdditive ? CONSTANT_ADDITIVE.evaluate((ConstantDoublesCube) cube, shift) : CONSTANT_MULTIPLICATIVE
.evaluate((ConstantDoublesCube) cube, shift);
}
if (cube instanceof FunctionalDoublesCube) {
return useAdditive ? FUNCTIONAL_ADDITIVE.evaluate((FunctionalDoublesCube) cube, shift) : FUNCTIONAL_MULTIPLICATIVE.evaluate(
(FunctionalDoublesCube) cube, shift);
}
if (cube instanceof InterpolatedDoublesCube) {
return useAdditive ? INTERPOLATED_ADDITIVE.evaluate((InterpolatedDoublesCube) cube, shift) : INTERPOLATED_MULTIPLICATIVE.evaluate(
(InterpolatedDoublesCube) cube, shift);
}
if (cube instanceof InterpolatedFromSurfacesDoublesCube && useAdditive) {
return INTERPOLATED_FROM_CURVES_ADDITIVE.evaluate((InterpolatedFromSurfacesDoublesCube) cube, shift);
}
if (cube instanceof NodalDoublesCube) {
return useAdditive ? NODAL_ADDITIVE.evaluate((NodalDoublesCube) cube, shift) : NODAL_MULTIPLICATIVE.evaluate((NodalDoublesCube) cube, shift);
}
throw new IllegalArgumentException("Do not have a cube shift function for cube " + cube.getClass());
}
/**
* For a cube Cube<Double, Double, Double, Double>, return a cube shifted at one point.
* @param cube The original cube
* @param x The <i>x</i> value of the shift
* @param y The <i>y</i> value of the shift
* @param z The <i>z</i> value of the shift
* @param shift The shift
* @param useAdditive true if the shift is additive, false if the shift is multiplicative (i.e. a percentage shift)
* @return A shifted cube with automatically-generated name
* @throws IllegalArgumentException If the cube type is not constant, functional, interpolated, nodal or spread
*/
public static Cube<Double, Double, Double, Double> getShiftedCube(final Cube<Double, Double, Double, Double> cube, final double x, final double y, final double z, final double shift,
final boolean useAdditive) {
if (cube instanceof ConstantDoublesCube) {
throw new UnsupportedOperationException("Cannot shift a single point on a constant curve");
}
if (cube instanceof FunctionalDoublesCube) {
throw new UnsupportedOperationException("Cannot shift a single point on a functional curve");
}
if (cube instanceof InterpolatedDoublesCube) {
return useAdditive ? INTERPOLATED_ADDITIVE.evaluate((InterpolatedDoublesCube) cube, x, y, z, shift) : INTERPOLATED_MULTIPLICATIVE.evaluate(
(InterpolatedDoublesCube) cube, x, y, z, shift);
}
if (cube instanceof InterpolatedFromSurfacesDoublesCube && useAdditive) {
return INTERPOLATED_FROM_CURVES_ADDITIVE.evaluate((InterpolatedFromSurfacesDoublesCube) cube, x, y, z, shift);
}
if (cube instanceof NodalDoublesCube) {
return useAdditive ? NODAL_ADDITIVE.evaluate((NodalDoublesCube) cube, x, y, z, shift) : NODAL_MULTIPLICATIVE
.evaluate((NodalDoublesCube) cube, x, y, z, shift);
}
throw new IllegalArgumentException("Do not have a cube shift function for cube " + cube.getClass());
}
/**
* For a cube Cube<Double, Double, Double, Double>, return a parallel-shifted cube.
* @param cube The original cube
* @param x An array of <i>x</i> values to shift
* @param y An array of <i>y</i> values to shift
* @param z An array of <i>z</i> values to shift
* @param shift The shifts
* @param useAdditive true if the shift is additive, false if the shift is multiplicative (i.e. a percentage shift)
* @return A shifted cube with an automatically-generated name
* @throws IllegalArgumentException If the cube type is not constant, functional, interpolated, nodal or spread
*/
public static Cube<Double, Double, Double, Double> getShiftedCube(final Cube<Double, Double, Double, Double> cube, final double[] x, final double[] y, final double[] z,
final double[] shift, final boolean useAdditive) {
if (cube instanceof ConstantDoublesCube) {
throw new UnsupportedOperationException("Cannot parallel shift a constant curve");
}
if (cube instanceof FunctionalDoublesCube) {
throw new UnsupportedOperationException("Cannot parallel shift a functional curve");
}
if (cube instanceof InterpolatedDoublesCube) {
return useAdditive ? INTERPOLATED_ADDITIVE.evaluate((InterpolatedDoublesCube) cube, x, y, z, shift) : INTERPOLATED_MULTIPLICATIVE.evaluate(
(InterpolatedDoublesCube) cube, x, y, z, shift);
}
if (cube instanceof InterpolatedFromSurfacesDoublesCube && useAdditive) {
return INTERPOLATED_FROM_CURVES_ADDITIVE.evaluate((InterpolatedFromSurfacesDoublesCube) cube, x, y, z, shift);
}
if (cube instanceof NodalDoublesCube) {
return useAdditive ? NODAL_ADDITIVE.evaluate((NodalDoublesCube) cube, x, y, z, shift) : NODAL_MULTIPLICATIVE
.evaluate((NodalDoublesCube) cube, x, y, z, shift);
}
throw new IllegalArgumentException("Do not have a cube shift function for cube " + cube.getClass());
}
/**
* For a cube Cube<Double, Double, Double, Double>, return a parallel-shifted cube.
* @param cube The original cube
* @param shift The shift
* @param newName The name of the shifted cube
* @param useAdditive true if the shift is additive, false if the shift is multiplicative (i.e. a percentage shift)
* @return A shifted cube
* @throws IllegalArgumentException If the cube type is not constant, functional, interpolated, nodal or spread
*/
public static Cube<Double, Double, Double, Double> getShiftedCube(final Cube<Double, Double, Double, Double> cube, final double shift, final String newName,
final boolean useAdditive) {
if (cube instanceof ConstantDoublesCube) {
return useAdditive ? CONSTANT_ADDITIVE.evaluate((ConstantDoublesCube) cube, shift, newName) : CONSTANT_MULTIPLICATIVE.evaluate(
(ConstantDoublesCube) cube, shift, newName);
}
if (cube instanceof FunctionalDoublesCube) {
return useAdditive ? FUNCTIONAL_ADDITIVE.evaluate((FunctionalDoublesCube) cube, shift, newName) : FUNCTIONAL_MULTIPLICATIVE.evaluate(
(FunctionalDoublesCube) cube, shift, newName);
}
if (cube instanceof InterpolatedDoublesCube) {
return useAdditive ? INTERPOLATED_ADDITIVE.evaluate((InterpolatedDoublesCube) cube, shift, newName) : INTERPOLATED_MULTIPLICATIVE.evaluate(
(InterpolatedDoublesCube) cube, shift, newName);
}
if (cube instanceof InterpolatedFromSurfacesDoublesCube && useAdditive) {
return INTERPOLATED_FROM_CURVES_ADDITIVE.evaluate((InterpolatedFromSurfacesDoublesCube) cube, shift, newName);
}
if (cube instanceof NodalDoublesCube) {
return useAdditive ? NODAL_ADDITIVE.evaluate((NodalDoublesCube) cube, shift, newName) : NODAL_MULTIPLICATIVE.evaluate((NodalDoublesCube) cube, shift,
newName);
}
throw new IllegalArgumentException("Do not have a cube shift function for cube " + cube.getClass());
}
/**
* For a cube Cube<Double, Double, Double, Double>, return a cube shifted at one point.
* @param cube The original cube
* @param x The <i>x</i> value of the shift
* @param y The <i>y</i> value of the shift
* @param z The <i>z</i> value of the shift
* @param shift The shift
* @param newName The name of the new cube
* @param useAdditive true if the shift is additive, false if the shift is multiplicative (i.e. a percentage shift)
* @return A shifted cube
* @throws IllegalArgumentException If the cube type is not constant, functional, interpolated, nodal or spread
*/
public static Cube<Double, Double, Double, Double> getShiftedCube(final Cube<Double, Double, Double, Double> cube, final double x, final double y, final double z, final double shift,
final String newName, final boolean useAdditive) {
if (cube instanceof ConstantDoublesCube) {
throw new UnsupportedOperationException("Cannot shift a single point on a constant curve");
}
if (cube instanceof FunctionalDoublesCube) {
throw new UnsupportedOperationException("Cannot shift a single point on a functional curve");
}
if (cube instanceof InterpolatedDoublesCube) {
return useAdditive ? INTERPOLATED_ADDITIVE.evaluate((InterpolatedDoublesCube) cube, x, y, z, shift, newName) : INTERPOLATED_MULTIPLICATIVE.evaluate(
(InterpolatedDoublesCube) cube, x, y, z, shift, newName);
}
if (cube instanceof InterpolatedFromSurfacesDoublesCube && useAdditive) {
return INTERPOLATED_FROM_CURVES_ADDITIVE.evaluate((InterpolatedFromSurfacesDoublesCube) cube, x, y, z, shift, newName);
}
if (cube instanceof NodalDoublesCube) {
return useAdditive ? NODAL_ADDITIVE.evaluate((NodalDoublesCube) cube, x, y, z, shift, newName) : NODAL_MULTIPLICATIVE.evaluate((NodalDoublesCube) cube, x,
y, z, shift, newName);
}
throw new IllegalArgumentException("Do not have a cube shift function for cube " + cube.getClass());
}
/**
* For a cube Cube<Double, Double, Double, Double>, return a parallel-shifted cube.
* @param cube The original cube
* @param x An array of <i>x</i> values to shift
* @param y An array of <i>y</i> values to shift
* @param z An array of <i>z</i> values to shift
* @param shift The shifts
* @param newName The name of the shifted cube
* @param useAdditive true if the shift is additive, false if the shift is multiplicative (i.e. a percentage shift)
* @return A shifted cube
* @throws IllegalArgumentException If the cube type is not constant, functional, interpolated, nodal or spread
*/
public static Cube<Double, Double, Double, Double> getShiftedCube(final Cube<Double, Double, Double, Double> cube, final double[] x, final double[] y, final double[] z,
final double[] shift, final String newName, final boolean useAdditive) {
if (cube instanceof ConstantDoublesCube) {
throw new UnsupportedOperationException("Cannot parallel shift a constant curve");
}
if (cube instanceof FunctionalDoublesCube) {
throw new UnsupportedOperationException("Cannot parallel shift a functional curve");
}
if (cube instanceof InterpolatedDoublesCube) {
return useAdditive ? INTERPOLATED_ADDITIVE.evaluate((InterpolatedDoublesCube) cube, x, y, z, shift, newName) : INTERPOLATED_MULTIPLICATIVE.evaluate(
(InterpolatedDoublesCube) cube, x, y, z, shift, newName);
}
if (cube instanceof InterpolatedFromSurfacesDoublesCube && useAdditive) {
return INTERPOLATED_FROM_CURVES_ADDITIVE.evaluate((InterpolatedFromSurfacesDoublesCube) cube, x, y, z, shift, newName);
}
if (cube instanceof NodalDoublesCube) {
return useAdditive ? NODAL_ADDITIVE.evaluate((NodalDoublesCube) cube, x, y, z, shift, newName) : NODAL_MULTIPLICATIVE.evaluate((NodalDoublesCube) cube, x,
y, z, shift, newName);
}
throw new IllegalArgumentException("Do not have a cube shift function for cube " + cube.getClass());
}
}