/**
* 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.Arrays;
import org.apache.commons.lang.Validate;
import com.opengamma.analytics.math.Plane;
import com.opengamma.analytics.math.surface.Surface;
import com.opengamma.analytics.math.surface.SurfaceShiftFunctionFactory;
/**
* Shifts an {@link InterpolatedFromSurfacesCubeAdditiveShiftFunction}. If an <i>x</i> (<i>y</i>) shift does not coincide with the one of the <i>x</i> (<i>y</i>) values
* of the intersection of the curves with the axis, an exception is thrown.
*/
public class InterpolatedFromSurfacesCubeAdditiveShiftFunction implements CubeShiftFunction<InterpolatedFromSurfacesDoublesCube> {
/**
* {@inheritDoc}
*/
@Override
public InterpolatedFromSurfacesDoublesCube evaluate(final InterpolatedFromSurfacesDoublesCube surface, final double shift) {
Validate.notNull(surface, "surface");
return evaluate(surface, shift, "PARALLEL_SHIFT_" + surface.getName());
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@Override
public InterpolatedFromSurfacesDoublesCube evaluate(final InterpolatedFromSurfacesDoublesCube cube, final double shift, final String newName) {
Validate.notNull(cube, "cube");
final double[] points = cube.getPoints();
final Surface<Double, Double, Double>[] surfaces = cube.getSurfaces();
final int n = surfaces.length;
final Surface<Double, Double, Double>[] newSurfaces = new Surface[surfaces.length];
for (int i = 0; i < n; i++) {
newSurfaces[i] = SurfaceShiftFunctionFactory.getShiftedSurface(surfaces[i], shift, true);
}
return InterpolatedFromSurfacesDoublesCube.from(cube.getPlane(), points, newSurfaces, cube.getInterpolator(), newName);
}
/**
* {@inheritDoc}
* @throws UnsupportedOperationException If the <i>x</i> (<i>y</i>) position of the shift does not coincide with one of the <i>x</i> (<i>y</i>) intersections
* of the curves with the axis
*/
@Override
public InterpolatedFromSurfacesDoublesCube evaluate(final InterpolatedFromSurfacesDoublesCube surface, final double x, final double y, final double z, final double shift) {
Validate.notNull(surface, "surface");
return evaluate(surface, x, y, z, shift, "SINGLE_SHIFT_" + surface.getName());
}
/**
* {@inheritDoc}
* @throws UnsupportedOperationException If the <i>x</i> (<i>y</i>) position of the shift does not coincide with one of the <i>x</i> (<i>y</i>) intersections
* of the curves with the axis
*/
@Override
public InterpolatedFromSurfacesDoublesCube evaluate(final InterpolatedFromSurfacesDoublesCube cube, final double x, final double y, final double z, final double shift, final String newName) {
Validate.notNull(cube, "cube");
final double[] points = cube.getPoints();
if (cube.getPlane() == Plane.ZX) {
final int index = Arrays.binarySearch(points, y);
final Surface<Double, Double, Double>[] surfaces = cube.getSurfaces();
if (index >= 0) {
final Surface<Double, Double, Double>[] newSurfaces = Arrays.copyOf(cube.getSurfaces(), points.length);
newSurfaces[index] = SurfaceShiftFunctionFactory.getShiftedSurface(surfaces[index], x, z, shift, true);
return InterpolatedFromSurfacesDoublesCube.fromSorted(cube.getPlane(), points, newSurfaces, cube.getInterpolator(), newName);
}
throw new UnsupportedOperationException("Cannot get shift for y-value not in original list of curves: asked for " + y);
} else if (cube.getPlane() == Plane.XY) {
final int index = Arrays.binarySearch(points, z);
final Surface<Double, Double, Double>[] surfaces = cube.getSurfaces();
if (index >= 0) {
final Surface<Double, Double, Double>[] newSurfaces = Arrays.copyOf(cube.getSurfaces(), points.length);
newSurfaces[index] = SurfaceShiftFunctionFactory.getShiftedSurface(surfaces[index], x, y, shift, true);
return InterpolatedFromSurfacesDoublesCube.fromSorted(cube.getPlane(), points, newSurfaces, cube.getInterpolator(), newName);
}
throw new UnsupportedOperationException("Cannot get shift for z-value not in original list of curves: asked for " + z);
} else {
final int index = Arrays.binarySearch(points, x);
final Surface<Double, Double, Double>[] surfaces = cube.getSurfaces();
if (index >= 0) {
final Surface<Double, Double, Double>[] newSurfaces = Arrays.copyOf(cube.getSurfaces(), points.length);
newSurfaces[index] = SurfaceShiftFunctionFactory.getShiftedSurface(surfaces[index], y, z, shift, true);
return InterpolatedFromSurfacesDoublesCube.fromSorted(cube.getPlane(), points, newSurfaces, cube.getInterpolator(), newName);
}
throw new UnsupportedOperationException("Cannot get shift for x-value not in original list of curves: asked for " + x);
}
}
/**
* {@inheritDoc}
* @throws UnsupportedOperationException If the <i>x</i> (<i>y</i>) positions of the shifts do not coincide with one of the <i>x</i> (<i>y</i>) intersections
* of the curves with the axis
*/
@Override
public InterpolatedFromSurfacesDoublesCube evaluate(final InterpolatedFromSurfacesDoublesCube surface, final double[] xShift, final double[] yShift, final double[] zShift, final double[] shift) {
Validate.notNull(surface, "surface");
return evaluate(surface, xShift, yShift, zShift, shift, "MULTIPLE_SHIFT_" + surface.getName());
}
/**
* {@inheritDoc}
* @throws UnsupportedOperationException If the <i>x</i> (<i>y</i>) positions of the shifts do not coincide with one of the <i>x</i> (<i>y</i>) intersections
* of the curves with the axis
*/
@Override
public InterpolatedFromSurfacesDoublesCube evaluate(final InterpolatedFromSurfacesDoublesCube cube, final double[] xShift, final double[] yShift, final double[] zShift, final double[] shift,
final String newName) {
Validate.notNull(cube, "surface");
Validate.notNull(xShift, "x shifts");
Validate.notNull(yShift, "y shifts");
Validate.notNull(yShift, "z shifts");
Validate.notNull(shift, "shifts");
final int n = xShift.length;
if (n == 0) {
return InterpolatedFromSurfacesDoublesCube.from(cube.getPlane(), cube.getPoints(), cube.getSurfaces(), cube.getInterpolator(), newName);
}
Validate.isTrue(n == yShift.length && n == shift.length);
final double[] points = cube.getPoints();
if (cube.getPlane() == Plane.ZX) {
final Surface<Double, Double, Double>[] newSurfaces = Arrays.copyOf(cube.getSurfaces(), points.length);
for (int i = 0; i < n; i++) {
final int index = Arrays.binarySearch(points, yShift[i]);
boolean foundValue = false;
if (index >= 0) {
newSurfaces[index] = SurfaceShiftFunctionFactory.getShiftedSurface(newSurfaces[index], xShift[i], zShift[i], shift[i], true);
foundValue = true;
}
if (!foundValue) {
throw new UnsupportedOperationException("Cannot get shift for y-value not in original list of curves: asked for " + yShift[i]);
}
}
return InterpolatedFromSurfacesDoublesCube.fromSorted(cube.getPlane(), points, newSurfaces, cube.getInterpolator(), newName);
} else if (cube.getPlane() == Plane.XY) {
final Surface<Double, Double, Double>[] newSurfaces = Arrays.copyOf(cube.getSurfaces(), points.length);
for (int i = 0; i < n; i++) {
final int index = Arrays.binarySearch(points, zShift[i]);
boolean foundValue = false;
if (index >= 0) {
newSurfaces[index] = SurfaceShiftFunctionFactory.getShiftedSurface(newSurfaces[index], xShift[i], yShift[i], shift[i], true);
foundValue = true;
}
if (!foundValue) {
throw new UnsupportedOperationException("Cannot get shift for z-value not in original list of curves: asked for " + zShift[i]);
}
}
return InterpolatedFromSurfacesDoublesCube.fromSorted(cube.getPlane(), points, newSurfaces, cube.getInterpolator(), newName);
} else {
final Surface<Double, Double, Double>[] newSurfaces = Arrays.copyOf(cube.getSurfaces(), points.length);
for (int i = 0; i < n; i++) {
final int index = Arrays.binarySearch(points, xShift[i]);
boolean foundValue = false;
if (index >= 0) {
newSurfaces[index] = SurfaceShiftFunctionFactory.getShiftedSurface(newSurfaces[index], yShift[i], zShift[i], shift[i], true);
foundValue = true;
}
if (!foundValue) {
throw new UnsupportedOperationException("Cannot get shift for x-value not in original list of curves: asked for " + xShift[i]);
}
}
return InterpolatedFromSurfacesDoublesCube.fromSorted(cube.getPlane(), points, newSurfaces, cube.getInterpolator(), newName);
}
}
}