1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.hipparchus.optim.nonlinear.vector.constrained;
18
19 import org.hipparchus.exception.MathIllegalArgumentException;
20 import org.hipparchus.optim.InitialGuess;
21 import org.hipparchus.optim.nonlinear.scalar.ObjectiveFunction;
22 import org.junit.jupiter.api.Test;
23
24 import static org.junit.jupiter.api.Assertions.assertEquals;
25 import static org.junit.jupiter.api.Assertions.assertNotNull;
26 import static org.junit.jupiter.api.Assertions.assertTrue;
27 import static org.junit.jupiter.api.Assertions.fail;
28
29 class ADMMQPOptimizerTest extends AbstractConstrainedOptimizerTest {
30
31 protected ConstraintOptimizer buildOptimizer() {
32 return new ADMMQPOptimizer();
33 }
34
35 @Test
36 void test1() {
37 QuadraticFunction q = new QuadraticFunction(new double[][] { { 4.0, -2.0 }, { -2.0, 4.0 } },
38 new double[] { 6.0, 0.0 },
39 0.0);
40
41
42 LinearEqualityConstraint eqc = new LinearEqualityConstraint(new double[][] { { 0.0, 1.0 } },
43 new double[] { 1.0 });
44
45
46
47 LinearInequalityConstraint ineqc = new LinearInequalityConstraint(new double[][] { { 1.0, 0.0 }, { 0.0, 1.0 }, { 1.0, 1.0 } },
48 new double[] { 0.0, 0.0, 2.0 });
49
50
51 doTestProblem(new double[] { 1, 1 }, 2.5e-5,
52 new double[] { -6, 0, 0, 8 }, 2.6e-4,
53 8, 2.0e-4,
54 new ObjectiveFunction(q),
55 null,
56 eqc, ineqc);
57
58 }
59
60 @Test
61 void test2() {
62 QuadraticFunction q = new QuadraticFunction(new double[][] { { 6.0, 2.0 }, { 2.0, 8.0 } },
63 new double[] { 5.0, 1.0 },
64 0.0);
65
66
67 LinearEqualityConstraint eqc = new LinearEqualityConstraint(new double[][] { { 1.0, 2.0 } },
68 new double[] { 1.0 });
69
70
71 LinearInequalityConstraint ineqc = new LinearInequalityConstraint(new double[][] { { 1.0, 0.0 }, { 0.0, 1.0 } },
72 new double[] { 0.0, 0.0 });
73
74
75 doTestProblem(new double[] { 0, 0.5 }, 1.1e-5,
76 new double[] { 2.5, 3.5, 0 }, 8.5e-6,
77 1.5, 6.3e-5,
78 new ObjectiveFunction(q),
79 null,
80 eqc, ineqc);
81
82 }
83
84 @Test
85 void testBounded() {
86 QuadraticFunction q = new QuadraticFunction(new double[][] { { 1.0, 0.0 }, { 0, 1.0 } },
87 new double[] { -3.0, -1.0 },
88 5.0);
89
90
91 LinearBoundedConstraint ineqc = new LinearBoundedConstraint(new double[][] { { 1.0, 0.0 },{ 0.0, 1.0 }},
92 new double[] { 0.0,0.0 }, new double[] { 2.0,2.0 });
93
94
95 doTestProblem(new double[] { 2, 1 }, 4.6e-6,
96 new double[] { 1, 0 }, 3.1e-5,
97 0.5, 4.6e-6,
98 new ObjectiveFunction(q),
99 null,
100 ineqc);
101
102 }
103
104 @Test
105 void testOptimizeWithGuess() {
106
107 final ADMMQPOptimizer optimizer = createOptimizerOnSimpleProblem(false, false);
108 optimizer.parseOptimizationData(new InitialGuess(new double[2]));
109
110
111 final LagrangeSolution solution = optimizer.optimize();
112
113
114 assertNotNull(optimizer.getConvergenceChecker());
115 assertTrue(optimizer.isConverged());
116 assertEquals(0., solution.getValue(), 0);
117 }
118
119 @Test
120 void testOptimizeWithoutScaling() {
121
122 final ADMMQPOptimizer optimizer = createOptimizerOnSimpleProblem(false, false);
123
124
125 final LagrangeSolution solution = optimizer.optimize();
126
127
128 assertNotNull(optimizer.getConvergenceChecker());
129 assertTrue(optimizer.isConverged());
130 assertEquals(0., solution.getValue(), 0);
131 }
132
133 @Test
134 void testOptimizeWithPolishWithScaling() {
135
136 final ADMMQPOptimizer optimizer = createOptimizerOnSimpleProblem(true, true);
137
138
139 final LagrangeSolution solution = optimizer.optimize();
140
141
142 assertNotNull(optimizer.getConvergenceChecker());
143 assertTrue(optimizer.isConverged());
144 assertEquals(0., solution.getValue(), 0);
145 }
146
147 @Test
148 void testOptimizeWithPolishWithoutScaling() {
149
150 final ADMMQPOptimizer optimizer = createOptimizerOnSimpleProblem(true, false);
151
152
153 final LagrangeSolution solution = optimizer.optimize();
154
155
156 assertNotNull(optimizer.getConvergenceChecker());
157 assertTrue(optimizer.isConverged());
158 assertEquals(0., solution.getValue(), 0);
159 }
160
161 private ADMMQPOptimizer createOptimizerOnSimpleProblem(final boolean polishing, final boolean scaling) {
162 final QuadraticFunction q = new QuadraticFunction(new double[][] { { 1.0, 0.0 }, { 0.0, 1.0 } },
163 new double[] { 0.0, 0.0 }, 0.0);
164 final LinearEqualityConstraint eqc = new LinearEqualityConstraint(new double[][] { { 1.0, 1.0 } },
165 new double[] { 0.0 });
166
167 final ADMMQPOption option = new ADMMQPOption();
168 option.setPolishing(polishing);
169 option.setScaling(scaling);
170
171 final ADMMQPOptimizer optimizer = new ADMMQPOptimizer();
172 optimizer.parseOptimizationData(new ObjectiveFunction(q), eqc, option);
173 return optimizer;
174 }
175
176 @Test
177 void testParseOptimizationDataException() {
178
179 final ADMMQPOptimizer testSQPOptimizer = new ADMMQPOptimizer();
180 final EqualityConstraint equalityConstraint = new LinearEqualityConstraint(new double[1][1], new double[1]);
181 final QuadraticFunction multivariateFunction = new QuadraticFunction(new double[1][1], new double[1], 0);
182 final ObjectiveFunction objectiveFunction = new ObjectiveFunction(multivariateFunction);
183
184 try {
185 testSQPOptimizer.parseOptimizationData(objectiveFunction, equalityConstraint);
186 fail();
187 } catch (final MathIllegalArgumentException exception) {
188 assertEquals("rank of constraints must be lesser than domain dimension, but 1 >= 1",
189 exception.getMessage());
190 }
191 }
192
193 }