/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.math.impl.util;
import java.util.function.Function;
import org.apache.commons.math3.analysis.MultivariateFunction;
import org.apache.commons.math3.analysis.UnivariateFunction;
import org.apache.commons.math3.analysis.differentiation.DerivativeStructure;
import org.apache.commons.math3.analysis.differentiation.UnivariateDifferentiableFunction;
import org.apache.commons.math3.analysis.polynomials.PolynomialFunctionLagrangeForm;
import org.apache.commons.math3.complex.Complex;
import org.apache.commons.math3.exception.DimensionMismatchException;
import org.apache.commons.math3.exception.NonMonotonicSequenceException;
import org.apache.commons.math3.exception.NumberIsTooSmallException;
import org.apache.commons.math3.linear.Array2DRowRealMatrix;
import org.apache.commons.math3.linear.ArrayRealVector;
import org.apache.commons.math3.linear.RealMatrix;
import org.apache.commons.math3.linear.RealVector;
import org.apache.commons.math3.optim.PointValuePair;
import com.opengamma.strata.collect.ArgChecker;
import com.opengamma.strata.collect.array.DoubleArray;
import com.opengamma.strata.collect.array.DoubleMatrix;
import com.opengamma.strata.math.MathException;
import com.opengamma.strata.math.impl.ComplexNumber;
import com.opengamma.strata.math.impl.function.DoubleFunction1D;
/**
* Utility class for converting OpenGamma mathematical objects into
* <a href="http://commons.apache.org/math/api-2.1/index.html">Commons</a> objects and vice versa.
*/
public final class CommonsMathWrapper {
// restricted constructor
private CommonsMathWrapper() {
}
//-------------------------------------------------------------------------
/**
* Wraps a function.
*
* @param f an OG 1-D function mapping doubles onto doubles
* @return a Commons univariate real function
*/
public static UnivariateFunction wrapUnivariate(Function<Double, Double> f) {
ArgChecker.notNull(f, "f");
return f::apply;
}
/**
* Wraps a function.
*
* @param f an OG 1-D function mapping doubles onto doubles
* @return a Commons univariate real function
*/
public static MultivariateFunction wrapMultivariate(Function<Double, Double> f) {
ArgChecker.notNull(f, "f");
return point -> f.apply(point[0]);
}
/**
* Wraps a function.
*
* @param f an OG 1-D function mapping vectors of doubles onto doubles
* @return a Commons multivariate real function
*/
public static MultivariateFunction wrapMultivariateVector(Function<DoubleArray, Double> f) {
ArgChecker.notNull(f, "f");
return point -> f.apply(DoubleArray.copyOf(point));
}
//-------------------------------------------------------------------------
/**
* Wraps a matrix.
*
* @param x an OG 2-D matrix of doubles
* @return a Commons matrix
*/
public static RealMatrix wrap(DoubleMatrix x) {
ArgChecker.notNull(x, "x");
return new Array2DRowRealMatrix(x.toArrayUnsafe());
}
/**
* Wraps a matrix.
*
* @param x an OG 1-D vector of doubles
* @return a Commons matrix
*/
public static RealMatrix wrapAsMatrix(DoubleArray x) {
ArgChecker.notNull(x, "x");
int n = x.size();
double[][] y = new double[n][1];
for (int i = 0; i < n; i++) {
y[i][0] = x.get(i);
}
return new Array2DRowRealMatrix(x.toArrayUnsafe()); // cloned in Array2DRowRealMatrix constructor
}
/**
* Unwraps a matrix.
*
* @param x a Commons matrix
* @return an OG 2-D matrix of doubles
*/
public static DoubleMatrix unwrap(RealMatrix x) {
ArgChecker.notNull(x, "x");
return DoubleMatrix.ofUnsafe(x.getData());
}
//-------------------------------------------------------------------------
/**
* Wraps a vector.
*
* @param x an OG vector of doubles
* @return a Commons vector
*/
public static RealVector wrap(DoubleArray x) {
ArgChecker.notNull(x, "x");
return new ArrayRealVector(x.toArrayUnsafe()); // cloned in ArrayRealVector constructor
}
/**
* Unwraps a vector.
*
* @param x a Commons vector
* @return an OG 1-D matrix of doubles
*/
public static DoubleArray unwrap(RealVector x) {
ArgChecker.notNull(x, "x");
return DoubleArray.ofUnsafe(x.toArray());
}
//-------------------------------------------------------------------------
/**
* Wraps a complex number.
*
* @param z An OG complex number
* @return a Commons complex number
*/
public static Complex wrap(ComplexNumber z) {
ArgChecker.notNull(z, "z");
return new Complex(z.getReal(), z.getImaginary());
}
//-------------------------------------------------------------------------
/**
* Unwraps a Lagrange.
*
* @param lagrange a Commons polynomial in Lagrange form
* @return an OG 1-D function mapping doubles to doubles
*/
public static Function<Double, Double> unwrap(PolynomialFunctionLagrangeForm lagrange) {
ArgChecker.notNull(lagrange, "lagrange");
return new Function<Double, Double>() {
@Override
public Double apply(Double x) {
try {
return lagrange.value(x);
} catch (DimensionMismatchException | NonMonotonicSequenceException | NumberIsTooSmallException e) {
throw new MathException(e);
}
}
};
}
/**
* Unwraps a pair.
*
* @param x a Commons pair of <i>(x, f(x))</i>
* @return a matrix of double with the <i>x</i> as the first element and <i>f(x)</i> the second
*/
public static double[] unwrap(PointValuePair x) {
ArgChecker.notNull(x, "x");
return x.getPoint();
}
/**
* Wraps a differentiable univariate real function.
*
* @param f an OG 1-D function mapping doubles to doubles
* @return a Commons differentiable univariate real function
*/
public static UnivariateDifferentiableFunction wrapDifferentiable(DoubleFunction1D f) {
ArgChecker.notNull(f, "f");
return new UnivariateDifferentiableFunction() {
@Override
public double value(double x) {
return f.applyAsDouble(x);
}
@Override
public DerivativeStructure value(DerivativeStructure t) throws DimensionMismatchException {
throw new IllegalArgumentException("Not implemented yet");
}
};
}
}