/** * Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies * * Please see distribution for license. */ package com.opengamma.analytics.math.minimization; import static com.opengamma.analytics.math.minimization.MinimizationTestFunctions.COUPLED_ROSENBROCK; import static com.opengamma.analytics.math.minimization.MinimizationTestFunctions.COUPLED_ROSENBROCK_GRAD; import static com.opengamma.analytics.math.minimization.MinimizationTestFunctions.ROSENBROCK; import static com.opengamma.analytics.math.minimization.MinimizationTestFunctions.ROSENBROCK_GRAD; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.testng.annotations.Test; import com.opengamma.analytics.math.function.Function1D; import com.opengamma.analytics.math.matrix.DoubleMatrix1D; import com.opengamma.util.monitor.OperationTimer; import com.opengamma.util.test.TestGroup; /** * Test. */ @Test(groups = TestGroup.UNIT) public class MultidimensionalMinimizerSpeedTest { private static final Logger s_logger = LoggerFactory.getLogger(MultidimensionalMinimizerSpeedTest.class); private static final int HOTSPOT_WARMUP_CYCLES = 0; private static final int BENCHMARK_CYCLES = 1; private static double EPS = 1e-8; private static ScalarMinimizer LINE_MINIMIZER = new BrentMinimizer1D(); private final static NelderMeadDownhillSimplexMinimizer SIMPLEX_MINIMIZER = new NelderMeadDownhillSimplexMinimizer(); private static ConjugateDirectionVectorMinimizer CONJUGATE_DIRECTION_MINIMIZER = new ConjugateDirectionVectorMinimizer(LINE_MINIMIZER, EPS, 10000); private static ConjugateGradientVectorMinimizer CONJUGATE_GRADIENT_MINIMIZER = new ConjugateGradientVectorMinimizer(LINE_MINIMIZER, EPS, 500); private static QuasiNewtonVectorMinimizer QUASI_NEWTON_MINIMISER = new QuasiNewtonVectorMinimizer(); @Test public void testWithoutGradientInfo1() { final DoubleMatrix1D start = new DoubleMatrix1D(new double[] {-1.0, 1.0}); doHotSpot(SIMPLEX_MINIMIZER, "Simplex - rosenbrock ", ROSENBROCK, null, start); doHotSpot(CONJUGATE_DIRECTION_MINIMIZER, "Conjugate direction - rosenbrock ", ROSENBROCK, null, start); doHotSpot(CONJUGATE_GRADIENT_MINIMIZER, "Conjugate Gradient - rosenbrock (no grad info)", ROSENBROCK, null, start); //Quasi Newton not working without gradient // doHotSpot(QUASI_NEWTON_MINIMISER, "Quasi Newton - rosenbrock (no grad info)", ROSENBROCK, null, start); } @Test public void testWithGradientInfo1() { final DoubleMatrix1D start = new DoubleMatrix1D(new double[] {-1.0, 1.0}); doHotSpot(CONJUGATE_GRADIENT_MINIMIZER, "Conjugate Gradient - rosenbrock", ROSENBROCK, ROSENBROCK_GRAD, start); doHotSpot(QUASI_NEWTON_MINIMISER, "Quasi Newton - rosenbrock", ROSENBROCK, ROSENBROCK_GRAD, start); } @Test public void testWithoutGradientInfo2() { final DoubleMatrix1D start = new DoubleMatrix1D(new double[] {-1.0, 1.0, -1.0, 1.0, -1.0, 1.0, 1.0}); doHotSpot(SIMPLEX_MINIMIZER, "Simplex - coupled rosenbrock ", COUPLED_ROSENBROCK, null, start); //Conjugate direction takes too long //doHotSpot(CONJUGATE_DIRECTION_MINIMIZER, "Conjugate direction - coupled rosenbrock", COUPLED_ROSENBROCK, null, // start); doHotSpot(CONJUGATE_GRADIENT_MINIMIZER, "Conjugate Gradient - coupled rosenbrock (no grad info)", COUPLED_ROSENBROCK, null, start); //Quasi Newton not working without gradient // doHotSpot(QUASI_NEWTON_MINIMISER, "Quasi Newton - rosenbrock (no grad info)", COUPLED_ROSENBROCK, null, start); } @Test public void testWithGradientInfo2() { final DoubleMatrix1D start = new DoubleMatrix1D(new double[] {-1.0, 1.0}); doHotSpot(CONJUGATE_GRADIENT_MINIMIZER, "Conjugate Gradient - coupled rosenbrock", COUPLED_ROSENBROCK, COUPLED_ROSENBROCK_GRAD, start); doHotSpot(QUASI_NEWTON_MINIMISER, "Quasi Newton - coupled rosenbrock", COUPLED_ROSENBROCK, COUPLED_ROSENBROCK_GRAD, start); } private void doHotSpot(final Minimizer<Function1D<DoubleMatrix1D, Double>, DoubleMatrix1D> minimizer, final String name, final Function1D<DoubleMatrix1D, Double> function, final Function1D<DoubleMatrix1D, DoubleMatrix1D> grad, final DoubleMatrix1D startPosition) { for (int i = 0; i < HOTSPOT_WARMUP_CYCLES; i++) { doTest(minimizer, function, grad, startPosition); } if (BENCHMARK_CYCLES > 0) { final OperationTimer timer = new OperationTimer(s_logger, "processing {} cycles on " + name, BENCHMARK_CYCLES); for (int i = 0; i < BENCHMARK_CYCLES; i++) { doTest(minimizer, function, grad, startPosition); } timer.finished(); } } private void doTest(final Minimizer<Function1D<DoubleMatrix1D, Double>, DoubleMatrix1D> minimizer, final Function1D<DoubleMatrix1D, Double> function, final Function1D<DoubleMatrix1D, DoubleMatrix1D> grad, final DoubleMatrix1D startPosition) { if (grad == null || !(minimizer instanceof MinimizerWithGradient)) { minimizer.minimize(function, startPosition); } else { @SuppressWarnings("unchecked") final MinimizerWithGradient<Function1D<DoubleMatrix1D, Double>, Function1D<DoubleMatrix1D, DoubleMatrix1D>, DoubleMatrix1D> minwithGrad = (MinimizerWithGradient<Function1D<DoubleMatrix1D, Double>, Function1D<DoubleMatrix1D, DoubleMatrix1D>, DoubleMatrix1D>) minimizer; minwithGrad.minimize(function, grad, startPosition); } } }