/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.math.surface;
import java.util.Arrays;
import org.apache.commons.lang.Validate;
import com.opengamma.analytics.math.curve.Curve;
import com.opengamma.analytics.math.curve.CurveShiftFunctionFactory;
/**
* Shifts an {@link InterpolatedFromCurvesSurfaceAdditiveShiftFunction}. 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 InterpolatedFromCurvesSurfaceAdditiveShiftFunction implements SurfaceShiftFunction<InterpolatedFromCurvesDoublesSurface> {
/**
* {@inheritDoc}
*/
@Override
public InterpolatedFromCurvesDoublesSurface evaluate(final InterpolatedFromCurvesDoublesSurface surface, final double shift) {
Validate.notNull(surface, "surface");
return evaluate(surface, shift, "PARALLEL_SHIFT_" + surface.getName());
}
/**
* {@inheritDoc}
*/
@SuppressWarnings("unchecked")
@Override
public InterpolatedFromCurvesDoublesSurface evaluate(final InterpolatedFromCurvesDoublesSurface surface, final double shift, final String newName) {
Validate.notNull(surface, "surface");
final boolean xzCurves = surface.isXZCurves();
final double[] points = surface.getPoints();
final Curve<Double, Double>[] curves = surface.getCurves();
final int n = curves.length;
final Curve<Double, Double>[] newCurves = new Curve[curves.length];
for (int i = 0; i < n; i++) {
newCurves[i] = CurveShiftFunctionFactory.getShiftedCurve(curves[i], shift);
}
return InterpolatedFromCurvesDoublesSurface.from(xzCurves, points, newCurves, surface.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 InterpolatedFromCurvesDoublesSurface evaluate(final InterpolatedFromCurvesDoublesSurface surface, final double x, final double y, final double shift) {
Validate.notNull(surface, "surface");
return evaluate(surface, x, y, 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 InterpolatedFromCurvesDoublesSurface evaluate(final InterpolatedFromCurvesDoublesSurface surface, final double x, final double y, final double shift, final String newName) {
Validate.notNull(surface, "surface");
final boolean xzCurves = surface.isXZCurves();
final double[] points = surface.getPoints();
if (xzCurves) {
final int index = Arrays.binarySearch(points, y);
final Curve<Double, Double>[] curves = surface.getCurves();
if (index >= 0) {
final Curve<Double, Double>[] newCurves = Arrays.copyOf(surface.getCurves(), points.length);
newCurves[index] = CurveShiftFunctionFactory.getShiftedCurve(curves[index], x, shift);
return InterpolatedFromCurvesDoublesSurface.fromSorted(xzCurves, points, newCurves, surface.getInterpolator(), newName);
}
throw new UnsupportedOperationException("Cannot get shift for y-value not in original list of curves: asked for " + y);
}
final int index = Arrays.binarySearch(points, x);
final Curve<Double, Double>[] curves = surface.getCurves();
if (index >= 0) {
final Curve<Double, Double>[] newCurves = Arrays.copyOf(surface.getCurves(), points.length);
newCurves[index] = CurveShiftFunctionFactory.getShiftedCurve(curves[index], y, shift);
return InterpolatedFromCurvesDoublesSurface.fromSorted(xzCurves, points, newCurves, surface.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 InterpolatedFromCurvesDoublesSurface evaluate(final InterpolatedFromCurvesDoublesSurface surface, final double[] xShift, final double[] yShift, final double[] shift) {
Validate.notNull(surface, "surface");
return evaluate(surface, xShift, yShift, 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 InterpolatedFromCurvesDoublesSurface evaluate(final InterpolatedFromCurvesDoublesSurface surface, final double[] xShift, final double[] yShift, final double[] shift, final String newName) {
Validate.notNull(surface, "surface");
Validate.notNull(xShift, "x shifts");
Validate.notNull(yShift, "y shifts");
Validate.notNull(shift, "shifts");
final int n = xShift.length;
if (n == 0) {
return InterpolatedFromCurvesDoublesSurface.from(surface.isXZCurves(), surface.getPoints(), surface.getCurves(), surface.getInterpolator(), newName);
}
Validate.isTrue(n == yShift.length && n == shift.length);
final boolean xzCurves = surface.isXZCurves();
final double[] points = surface.getPoints();
if (xzCurves) {
final Curve<Double, Double>[] newCurves = Arrays.copyOf(surface.getCurves(), points.length);
for (int i = 0; i < n; i++) {
final int index = Arrays.binarySearch(points, yShift[i]);
boolean foundValue = false;
if (index >= 0) {
newCurves[index] = CurveShiftFunctionFactory.getShiftedCurve(newCurves[index], xShift[i], shift[i]);
foundValue = true;
}
if (!foundValue) {
throw new UnsupportedOperationException("Cannot get shift for y-value not in original list of curves: asked for " + yShift[i]);
}
}
return InterpolatedFromCurvesDoublesSurface.fromSorted(xzCurves, points, newCurves, surface.getInterpolator(), newName);
}
final Curve<Double, Double>[] newCurves = Arrays.copyOf(surface.getCurves(), points.length);
for (int i = 0; i < n; i++) {
final int index = Arrays.binarySearch(points, xShift[i]);
boolean foundValue = false;
if (index >= 0) {
newCurves[index] = CurveShiftFunctionFactory.getShiftedCurve(newCurves[index], yShift[i], shift[i]);
foundValue = true;
}
if (!foundValue) {
throw new UnsupportedOperationException("Cannot get shift for x-value not in original list of curves: asked for " + xShift[i]);
}
}
return InterpolatedFromCurvesDoublesSurface.fromSorted(xzCurves, points, newCurves, surface.getInterpolator(), newName);
}
}