1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.math4.legacy.optim.nonlinear.scalar.noderiv;
18
19 import java.util.Comparator;
20 import java.util.List;
21 import java.util.ArrayList;
22 import java.util.Collections;
23 import java.util.function.UnaryOperator;
24 import java.util.function.DoublePredicate;
25 import org.apache.commons.rng.UniformRandomProvider;
26 import org.apache.commons.rng.simple.RandomSource;
27 import org.apache.commons.rng.sampling.distribution.ContinuousSampler;
28 import org.apache.commons.rng.sampling.distribution.ContinuousUniformSampler;
29 import org.apache.commons.math4.legacy.analysis.MultivariateFunction;
30 import org.apache.commons.math4.legacy.optim.PointValuePair;
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55 public class HedarFukushimaTransform
56 implements Simplex.TransformFactory {
57
58 private final double sigma;
59
60 private final ContinuousSampler alphaSampler;
61
62 private final boolean noShrink;
63
64
65
66
67
68
69
70 public HedarFukushimaTransform(double sigma,
71 UniformRandomProvider rng) {
72 if (sigma <= 0 ||
73 sigma > 1) {
74 throw new IllegalArgumentException("Shrink factor out of range: " +
75 sigma);
76 }
77
78 this.sigma = sigma;
79 alphaSampler = ContinuousUniformSampler.of(rng, 0.9, 1.1);
80 noShrink = sigma == 1d;
81 }
82
83
84
85
86
87
88 public HedarFukushimaTransform(double sigma) {
89 this(sigma, RandomSource.KISS.create());
90 }
91
92
93
94
95 public HedarFukushimaTransform() {
96 this(1d);
97 }
98
99
100 @Override
101 public UnaryOperator<Simplex> create(final MultivariateFunction evaluationFunction,
102 final Comparator<PointValuePair> comparator,
103 final DoublePredicate saAcceptance) {
104 if (saAcceptance == null) {
105 throw new IllegalArgumentException("Missing SA acceptance test");
106 }
107
108 return original -> transform(original,
109 saAcceptance,
110 evaluationFunction,
111 comparator);
112 }
113
114
115
116
117
118
119
120
121
122
123 private Simplex transform(Simplex original,
124 DoublePredicate sa,
125 MultivariateFunction eval,
126 Comparator<PointValuePair> comp) {
127 final int size = original.getSize();
128
129 final PointValuePair best = original.get(0);
130 final double bestValue = best.getValue();
131
132 for (int k = 1; k < size; k++) {
133
134 final List<PointValuePair> reflected = reflectPoints(original, k, eval);
135 Collections.sort(reflected, comp);
136
137
138
139 final PointValuePair candidate = reflected.get(0);
140 final boolean candidateIsBetter = comp.compare(candidate, best) < 0;
141 final boolean candidateIsAccepted = candidateIsBetter ||
142 sa.test(candidate.getValue() - bestValue);
143
144 if (candidateIsAccepted) {
145
146 return original.replaceLast(reflected);
147 }
148 }
149
150
151 return noShrink ?
152 original :
153 original.shrink(sigma, eval);
154 }
155
156
157
158
159
160
161
162
163
164
165
166
167 private List<PointValuePair> reflectPoints(Simplex simplex,
168 int nPoints,
169 MultivariateFunction eval) {
170 final int size = simplex.getSize();
171 if (nPoints < 1 ||
172 nPoints >= size) {
173 throw new IllegalArgumentException("Out of range: " + nPoints);
174 }
175
176 final int nCentroid = size - nPoints;
177 final List<PointValuePair> centroidList = simplex.asList(0, nCentroid);
178 final List<PointValuePair> reflectList = simplex.asList(nCentroid, size);
179
180 final double[] centroid = Simplex.centroid(centroidList);
181
182 final List<PointValuePair> reflected = new ArrayList<>(nPoints);
183 for (int i = 0; i < reflectList.size(); i++) {
184 reflected.add(newReflectedPoint(reflectList.get(i),
185 centroid,
186 eval));
187 }
188
189 return reflected;
190 }
191
192
193
194
195
196
197
198
199 private PointValuePair newReflectedPoint(PointValuePair point,
200 double[] centroid,
201 MultivariateFunction eval) {
202 final double alpha = alphaSampler.sample();
203 return Simplex.newPoint(centroid,
204 -alpha,
205 point.getPoint(),
206 eval);
207 }
208
209
210 @Override
211 public String toString() {
212 return "Hedar-Fukushima [s=" + sigma + "]";
213 }
214 }