1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math.optimization.direct;
19
20 import junit.framework.Test;
21 import junit.framework.TestCase;
22 import junit.framework.TestSuite;
23
24 import org.apache.commons.math.ConvergenceException;
25 import org.apache.commons.math.FunctionEvaluationException;
26 import org.apache.commons.math.analysis.MultivariateRealFunction;
27 import org.apache.commons.math.optimization.GoalType;
28 import org.apache.commons.math.optimization.RealPointValuePair;
29 import org.apache.commons.math.optimization.SimpleScalarValueChecker;
30
31 public class MultiDirectionalTest
32 extends TestCase {
33
34 public MultiDirectionalTest(String name) {
35 super(name);
36 }
37
38 public void testFunctionEvaluationExceptions() {
39 MultivariateRealFunction wrong =
40 new MultivariateRealFunction() {
41 private static final long serialVersionUID = 4751314470965489371L;
42 public double value(double[] x) throws FunctionEvaluationException {
43 if (x[0] < 0) {
44 throw new FunctionEvaluationException(x, "{0}", "oops");
45 } else if (x[0] > 1) {
46 throw new FunctionEvaluationException(new RuntimeException("oops"), x);
47 } else {
48 return x[0] * (1 - x[0]);
49 }
50 }
51 };
52 try {
53 MultiDirectional optimizer = new MultiDirectional(0.9, 1.9);
54 optimizer.optimize(wrong, GoalType.MINIMIZE, new double[] { -1.0 });
55 fail("an exception should have been thrown");
56 } catch (FunctionEvaluationException ce) {
57
58 assertNull(ce.getCause());
59 } catch (Exception e) {
60 fail("wrong exception caught: " + e.getMessage());
61 }
62 try {
63 MultiDirectional optimizer = new MultiDirectional(0.9, 1.9);
64 optimizer.optimize(wrong, GoalType.MINIMIZE, new double[] { +2.0 });
65 fail("an exception should have been thrown");
66 } catch (FunctionEvaluationException ce) {
67
68 assertNotNull(ce.getCause());
69 } catch (Exception e) {
70 fail("wrong exception caught: " + e.getMessage());
71 }
72 }
73
74 public void testMinimizeMaximize()
75 throws FunctionEvaluationException, ConvergenceException {
76
77
78 final double xM = -3.841947088256863675365;
79 final double yM = -1.391745200270734924416;
80 final double xP = 0.2286682237349059125691;
81 final double yP = -yM;
82 final double valueXmYm = 0.2373295333134216789769;
83 final double valueXmYp = -valueXmYm;
84 final double valueXpYm = -0.7290400707055187115322;
85 final double valueXpYp = -valueXpYm;
86 MultivariateRealFunction fourExtrema = new MultivariateRealFunction() {
87 private static final long serialVersionUID = -7039124064449091152L;
88 public double value(double[] variables) throws FunctionEvaluationException {
89 final double x = variables[0];
90 final double y = variables[1];
91 return ((x == 0) || (y == 0)) ? 0 : (Math.atan(x) * Math.atan(x + 2) * Math.atan(y) * Math.atan(y) / (x * y));
92 }
93 };
94
95 MultiDirectional optimizer = new MultiDirectional();
96 optimizer.setConvergenceChecker(new SimpleScalarValueChecker(1.0e-10, 1.0e-30));
97 optimizer.setMaxIterations(200);
98 optimizer.setStartConfiguration(new double[] { 0.2, 0.2 });
99 RealPointValuePair optimum;
100
101
102 optimum = optimizer.optimize(fourExtrema, GoalType.MINIMIZE, new double[] { -3.0, 0 });
103 assertEquals(xM, optimum.getPoint()[0], 4.0e-6);
104 assertEquals(yP, optimum.getPoint()[1], 3.0e-6);
105 assertEquals(valueXmYp, optimum.getValue(), 8.0e-13);
106 assertTrue(optimizer.getEvaluations() > 120);
107 assertTrue(optimizer.getEvaluations() < 150);
108
109 optimum = optimizer.optimize(fourExtrema, GoalType.MINIMIZE, new double[] { +1, 0 });
110 assertEquals(xP, optimum.getPoint()[0], 2.0e-8);
111 assertEquals(yM, optimum.getPoint()[1], 3.0e-6);
112 assertEquals(valueXpYm, optimum.getValue(), 2.0e-12);
113 assertTrue(optimizer.getEvaluations() > 120);
114 assertTrue(optimizer.getEvaluations() < 150);
115
116
117 optimum = optimizer.optimize(fourExtrema, GoalType.MAXIMIZE, new double[] { -3.0, 0.0 });
118 assertEquals(xM, optimum.getPoint()[0], 7.0e-7);
119 assertEquals(yM, optimum.getPoint()[1], 3.0e-7);
120 assertEquals(valueXmYm, optimum.getValue(), 2.0e-14);
121 assertTrue(optimizer.getEvaluations() > 120);
122 assertTrue(optimizer.getEvaluations() < 150);
123
124 optimum = optimizer.optimize(fourExtrema, GoalType.MAXIMIZE, new double[] { +1, 0 });
125 assertEquals(xP, optimum.getPoint()[0], 2.0e-8);
126 assertEquals(yP, optimum.getPoint()[1], 3.0e-6);
127 assertEquals(valueXpYp, optimum.getValue(), 2.0e-12);
128 assertTrue(optimizer.getEvaluations() > 120);
129 assertTrue(optimizer.getEvaluations() < 150);
130
131 }
132
133 public void testRosenbrock()
134 throws FunctionEvaluationException, ConvergenceException {
135
136 MultivariateRealFunction rosenbrock =
137 new MultivariateRealFunction() {
138 private static final long serialVersionUID = -9044950469615237490L;
139 public double value(double[] x) throws FunctionEvaluationException {
140 ++count;
141 double a = x[1] - x[0] * x[0];
142 double b = 1.0 - x[0];
143 return 100 * a * a + b * b;
144 }
145 };
146
147 count = 0;
148 MultiDirectional optimizer = new MultiDirectional();
149 optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1, 1.0e-3));
150 optimizer.setMaxIterations(100);
151 optimizer.setStartConfiguration(new double[][] {
152 { -1.2, 1.0 }, { 0.9, 1.2 } , { 3.5, -2.3 }
153 });
154 RealPointValuePair optimum =
155 optimizer.optimize(rosenbrock, GoalType.MINIMIZE, new double[] { -1.2, 1.0 });
156
157 assertEquals(count, optimizer.getEvaluations());
158 assertTrue(optimizer.getEvaluations() > 70);
159 assertTrue(optimizer.getEvaluations() < 100);
160 assertTrue(optimum.getValue() > 1.0e-2);
161
162 }
163
164 public void testPowell()
165 throws FunctionEvaluationException, ConvergenceException {
166
167 MultivariateRealFunction powell =
168 new MultivariateRealFunction() {
169 private static final long serialVersionUID = -832162886102041840L;
170 public double value(double[] x) throws FunctionEvaluationException {
171 ++count;
172 double a = x[0] + 10 * x[1];
173 double b = x[2] - x[3];
174 double c = x[1] - 2 * x[2];
175 double d = x[0] - x[3];
176 return a * a + 5 * b * b + c * c * c * c + 10 * d * d * d * d;
177 }
178 };
179
180 count = 0;
181 MultiDirectional optimizer = new MultiDirectional();
182 optimizer.setConvergenceChecker(new SimpleScalarValueChecker(-1.0, 1.0e-3));
183 optimizer.setMaxIterations(1000);
184 RealPointValuePair optimum =
185 optimizer.optimize(powell, GoalType.MINIMIZE, new double[] { 3.0, -1.0, 0.0, 1.0 });
186 assertEquals(count, optimizer.getEvaluations());
187 assertTrue(optimizer.getEvaluations() > 800);
188 assertTrue(optimizer.getEvaluations() < 900);
189 assertTrue(optimum.getValue() > 1.0e-2);
190
191 }
192
193 public static Test suite() {
194 return new TestSuite(MultiDirectionalTest.class);
195 }
196
197 private int count;
198
199 }