1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 package org.hipparchus.optim.nonlinear.scalar;
23
24 import org.hipparchus.analysis.MultivariateFunction;
25 import org.hipparchus.geometry.euclidean.twod.Vector2D;
26 import org.hipparchus.optim.InitialGuess;
27 import org.hipparchus.optim.MaxEval;
28 import org.hipparchus.optim.PointValuePair;
29 import org.hipparchus.optim.SimpleValueChecker;
30 import org.hipparchus.optim.nonlinear.scalar.gradient.CircleScalar;
31 import org.hipparchus.optim.nonlinear.scalar.gradient.NonLinearConjugateGradientOptimizer;
32 import org.hipparchus.optim.nonlinear.scalar.noderiv.NelderMeadSimplex;
33 import org.hipparchus.optim.nonlinear.scalar.noderiv.SimplexOptimizer;
34 import org.hipparchus.random.GaussianRandomGenerator;
35 import org.hipparchus.random.JDKRandomGenerator;
36 import org.hipparchus.random.RandomVectorGenerator;
37 import org.hipparchus.random.UncorrelatedRandomVectorGenerator;
38 import org.junit.jupiter.api.Test;
39
40 import static org.junit.jupiter.api.Assertions.assertEquals;
41 import static org.junit.jupiter.api.Assertions.assertTrue;
42
43 class MultiStartMultivariateOptimizerTest {
44 @Test
45 void testCircleFitting() {
46 CircleScalar circle = new CircleScalar();
47 circle.addPoint( 30.0, 68.0);
48 circle.addPoint( 50.0, -6.0);
49 circle.addPoint(110.0, -20.0);
50 circle.addPoint( 35.0, 15.0);
51 circle.addPoint( 45.0, 97.0);
52
53
54
55 GradientMultivariateOptimizer underlying
56 = new NonLinearConjugateGradientOptimizer(NonLinearConjugateGradientOptimizer.Formula.POLAK_RIBIERE,
57 new SimpleValueChecker(1e-10, 1e-10));
58 JDKRandomGenerator g = new JDKRandomGenerator();
59 g.setSeed(753289573253l);
60 RandomVectorGenerator generator
61 = new UncorrelatedRandomVectorGenerator(new double[] { 50, 50 },
62 new double[] { 10, 10 },
63 new GaussianRandomGenerator(g));
64 int nbStarts = 10;
65 MultiStartMultivariateOptimizer optimizer
66 = new MultiStartMultivariateOptimizer(underlying, nbStarts, generator);
67 PointValuePair optimum
68 = optimizer.optimize(new MaxEval(1000),
69 circle.getObjectiveFunction(),
70 circle.getObjectiveFunctionGradient(),
71 GoalType.MINIMIZE,
72 new InitialGuess(new double[] { 98.680, 47.345 }));
73 assertEquals(1000, optimizer.getMaxEvaluations());
74 PointValuePair[] optima = optimizer.getOptima();
75 assertEquals(nbStarts, optima.length);
76 for (PointValuePair o : optima) {
77
78 Vector2D center = new Vector2D(o.getPointRef()[0], o.getPointRef()[1]);
79 assertTrue(69.9592 < circle.getRadius(center));
80 assertTrue(69.9602 > circle.getRadius(center));
81 assertTrue(96.0745 < center.getX());
82 assertTrue(96.0762 > center.getX());
83 assertTrue(48.1344 < center.getY());
84 assertTrue(48.1354 > center.getY());
85 }
86
87 assertTrue(optimizer.getEvaluations() > 850);
88 assertTrue(optimizer.getEvaluations() < 900);
89
90 assertEquals(3.1267527, optimum.getValue(), 1e-8);
91 }
92
93 @Test
94 void testRosenbrock() {
95 Rosenbrock rosenbrock = new Rosenbrock();
96 SimplexOptimizer underlying
97 = new SimplexOptimizer(new SimpleValueChecker(-1, 1e-3));
98 NelderMeadSimplex simplex = new NelderMeadSimplex(new double[][] {
99 { -1.2, 1.0 },
100 { 0.9, 1.2 } ,
101 { 3.5, -2.3 }
102 });
103 JDKRandomGenerator g = new JDKRandomGenerator();
104 g.setSeed(16069223052l);
105 RandomVectorGenerator generator
106 = new UncorrelatedRandomVectorGenerator(2, new GaussianRandomGenerator(g));
107 int nbStarts = 10;
108 MultiStartMultivariateOptimizer optimizer
109 = new MultiStartMultivariateOptimizer(underlying, nbStarts, generator);
110 PointValuePair optimum
111 = optimizer.optimize(new MaxEval(1100),
112 new ObjectiveFunction(rosenbrock),
113 GoalType.MINIMIZE,
114 simplex,
115 new InitialGuess(new double[] { -1.2, 1.0 }));
116 assertEquals(nbStarts, optimizer.getOptima().length);
117
118 assertEquals(rosenbrock.getCount(), optimizer.getEvaluations());
119 assertTrue(optimizer.getEvaluations() > 900);
120 assertTrue(optimizer.getEvaluations() < 1200);
121 assertTrue(optimum.getValue() < 5e-5);
122 }
123
124 private static class Rosenbrock implements MultivariateFunction {
125 private int count;
126
127 public Rosenbrock() {
128 count = 0;
129 }
130
131 public double value(double[] x) {
132 ++count;
133 double a = x[1] - x[0] * x[0];
134 double b = 1 - x[0];
135 return 100 * a * a + b * b;
136 }
137
138 public int getCount() {
139 return count;
140 }
141 }
142 }