1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math.optimization;
19
20 import java.util.Arrays;
21 import java.util.Comparator;
22
23 import org.apache.commons.math.ConvergenceException;
24 import org.apache.commons.math.FunctionEvaluationException;
25 import org.apache.commons.math.MathRuntimeException;
26 import org.apache.commons.math.analysis.DifferentiableMultivariateVectorialFunction;
27 import org.apache.commons.math.random.RandomVectorGenerator;
28
29
30
31
32
33
34
35
36
37
38
39
40 public class MultiStartDifferentiableMultivariateVectorialOptimizer
41 implements DifferentiableMultivariateVectorialOptimizer {
42
43
44 private static final long serialVersionUID = 9206382258980561530L;
45
46
47 private final DifferentiableMultivariateVectorialOptimizer optimizer;
48
49
50 private int maxIterations;
51
52
53 private int totalIterations;
54
55
56 private int maxEvaluations;
57
58
59 private int totalEvaluations;
60
61
62 private int totalJacobianEvaluations;
63
64
65 private int starts;
66
67
68 private RandomVectorGenerator generator;
69
70
71 private VectorialPointValuePair[] optima;
72
73
74
75
76
77
78
79
80
81 public MultiStartDifferentiableMultivariateVectorialOptimizer(
82 final DifferentiableMultivariateVectorialOptimizer optimizer,
83 final int starts,
84 final RandomVectorGenerator generator) {
85 this.optimizer = optimizer;
86 this.totalIterations = 0;
87 this.totalEvaluations = 0;
88 this.totalJacobianEvaluations = 0;
89 this.starts = starts;
90 this.generator = generator;
91 this.optima = null;
92 setMaxIterations(Integer.MAX_VALUE);
93 setMaxEvaluations(Integer.MAX_VALUE);
94 }
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123 public VectorialPointValuePair[] getOptima() throws IllegalStateException {
124 if (optima == null) {
125 throw MathRuntimeException.createIllegalStateException("no optimum computed yet");
126 }
127 return optima.clone();
128 }
129
130
131 public void setMaxIterations(int maxIterations) {
132 this.maxIterations = maxIterations;
133 }
134
135
136 public int getMaxIterations() {
137 return maxIterations;
138 }
139
140
141 public int getIterations() {
142 return totalIterations;
143 }
144
145
146 public void setMaxEvaluations(int maxEvaluations) {
147 this.maxEvaluations = maxEvaluations;
148 }
149
150
151 public int getMaxEvaluations() {
152 return maxEvaluations;
153 }
154
155
156 public int getEvaluations() {
157 return totalEvaluations;
158 }
159
160
161 public int getJacobianEvaluations() {
162 return totalJacobianEvaluations;
163 }
164
165
166 public void setConvergenceChecker(VectorialConvergenceChecker checker) {
167 optimizer.setConvergenceChecker(checker);
168 }
169
170
171 public VectorialConvergenceChecker getConvergenceChecker() {
172 return optimizer.getConvergenceChecker();
173 }
174
175
176 public VectorialPointValuePair optimize(final DifferentiableMultivariateVectorialFunction f,
177 final double[] target, final double[] weights,
178 final double[] startPoint)
179 throws FunctionEvaluationException, OptimizationException, IllegalArgumentException {
180
181 optima = new VectorialPointValuePair[starts];
182 totalIterations = 0;
183 totalEvaluations = 0;
184 totalJacobianEvaluations = 0;
185
186
187 for (int i = 0; i < starts; ++i) {
188
189 try {
190 optimizer.setMaxIterations(maxIterations - totalIterations);
191 optimizer.setMaxEvaluations(maxEvaluations - totalEvaluations);
192 optima[i] = optimizer.optimize(f, target, weights,
193 (i == 0) ? startPoint : generator.nextVector());
194 } catch (FunctionEvaluationException fee) {
195 optima[i] = null;
196 } catch (OptimizationException oe) {
197 optima[i] = null;
198 }
199
200 totalIterations += optimizer.getIterations();
201 totalEvaluations += optimizer.getEvaluations();
202 totalJacobianEvaluations += optimizer.getJacobianEvaluations();
203
204 }
205
206
207 Arrays.sort(optima, new Comparator<VectorialPointValuePair>() {
208 public int compare(final VectorialPointValuePair o1, final VectorialPointValuePair o2) {
209 if (o1 == null) {
210 return (o2 == null) ? 0 : +1;
211 } else if (o2 == null) {
212 return -1;
213 }
214 return Double.compare(weightedResidual(o1), weightedResidual(o2));
215 }
216 private double weightedResidual(final VectorialPointValuePair pv) {
217 final double[] value = pv.getValueRef();
218 double sum = 0;
219 for (int i = 0; i < value.length; ++i) {
220 final double ri = value[i] - target[i];
221 sum += weights[i] * ri * ri;
222 }
223 return sum;
224 }
225 });
226
227 if (optima[0] == null) {
228 throw new OptimizationException(
229 "none of the {0} start points lead to convergence",
230 starts);
231 }
232
233
234 return optima[0];
235
236 }
237
238 }