com.opengamma.strata.math.impl.integration.RombergIntegrator1D Maven / Gradle / Ivy
Show all versions of strata-math Show documentation
/*
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.strata.math.impl.integration;
import java.util.function.Function;
import org.apache.commons.math3.analysis.integration.RombergIntegrator;
import org.apache.commons.math3.analysis.integration.UnivariateIntegrator;
import org.apache.commons.math3.exception.MathIllegalArgumentException;
import org.apache.commons.math3.exception.MaxCountExceededException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.opengamma.strata.collect.ArgChecker;
import com.opengamma.strata.math.MathException;
import com.opengamma.strata.math.impl.util.CommonsMathWrapper;
/**
*
* Romberg's method estimates an integral by repeatedly using Richardson extrapolation
* on the extended trapezium rule {@link ExtendedTrapezoidIntegrator1D}.
*
* This class is a wrapper for the
* Commons Math library implementation
* of Romberg integration.
*/
public class RombergIntegrator1D extends Integrator1D {
private static final Logger log = LoggerFactory.getLogger(RombergIntegrator1D.class);
private static final int MAX_EVAL = 10000;
private final UnivariateIntegrator integrator = new RombergIntegrator();
/**
* Romberg integration method. Note that the Commons implementation fails if the lower bound is larger than the upper -
* in this case, the bounds are reversed and the result negated.
* @param f The function to integrate, not null
* @param lower The lower bound, not null
* @param upper The upper bound, not null
* @return The result of the integration
*/
@Override
public Double integrate(Function f, Double lower, Double upper) {
ArgChecker.notNull(f, "f");
ArgChecker.notNull(lower, "lower bound");
ArgChecker.notNull(upper, "upper bound");
try {
if (lower < upper) {
return integrator.integrate(MAX_EVAL, CommonsMathWrapper.wrapUnivariate(f), lower, upper);
}
log.info("Upper bound was less than lower bound; swapping bounds and negating result");
return -integrator.integrate(MAX_EVAL, CommonsMathWrapper.wrapUnivariate(f), upper, lower);
} catch (MaxCountExceededException | MathIllegalArgumentException e) {
throw new MathException(e);
}
}
}