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.List;
20 import java.util.ArrayList;
21 import java.util.Comparator;
22 import java.util.function.UnaryOperator;
23 import java.util.function.DoublePredicate;
24
25 import org.apache.commons.math4.legacy.analysis.MultivariateFunction;
26 import org.apache.commons.math4.legacy.optim.PointValuePair;
27
28
29
30
31 public class MultiDirectionalTransform
32 implements Simplex.TransformFactory {
33
34 private static final double ALPHA = 1;
35
36 private static final double DEFAULT_GAMMA = 2;
37
38 private static final double DEFAULT_SIGMA = 0.5;
39
40 private final double gamma;
41
42 private final double sigma;
43
44
45
46
47
48 public MultiDirectionalTransform(double gamma,
49 double sigma) {
50 if (gamma < 1) {
51 throw new IllegalArgumentException("gamma: " + gamma);
52 }
53 if (sigma < 0 ||
54 sigma > 1) {
55 throw new IllegalArgumentException("sigma: " + sigma);
56 }
57
58 this.gamma = gamma;
59 this.sigma = sigma;
60 }
61
62
63
64
65 public MultiDirectionalTransform() {
66 this(DEFAULT_GAMMA,
67 DEFAULT_SIGMA);
68 }
69
70
71 @Override
72 public UnaryOperator<Simplex> create(final MultivariateFunction evaluationFunction,
73 final Comparator<PointValuePair> comparator,
74 final DoublePredicate sa) {
75 return original -> {
76 final PointValuePair best = original.get(0);
77
78
79 final Simplex reflectedSimplex = transform(original,
80 ALPHA,
81 comparator,
82 evaluationFunction);
83 final PointValuePair reflectedBest = reflectedSimplex.get(0);
84
85 if (comparator.compare(reflectedBest, best) < 0) {
86
87 final Simplex expandedSimplex = transform(original,
88 gamma,
89 comparator,
90 evaluationFunction);
91 final PointValuePair expandedBest = expandedSimplex.get(0);
92
93 if (comparator.compare(expandedBest, reflectedBest) <= 0 ||
94 (sa != null &&
95 sa.test(expandedBest.getValue() - reflectedBest.getValue()))) {
96 return expandedSimplex;
97 } else {
98 return reflectedSimplex;
99 }
100 } else {
101
102 return original.shrink(sigma, evaluationFunction);
103 }
104 };
105 }
106
107
108
109
110
111
112
113
114
115
116
117
118 private Simplex transform(Simplex original,
119 double coeff,
120 Comparator<PointValuePair> comp,
121 MultivariateFunction evalFunc) {
122
123
124 final int replSize = original.getSize() - 1;
125 final List<PointValuePair> replacement = new ArrayList<>();
126 final double[] bestPoint = original.get(0).getPoint();
127 for (int i = 0; i < replSize; i++) {
128 replacement.add(Simplex.newPoint(bestPoint,
129 -coeff,
130 original.get(i + 1).getPoint(),
131 evalFunc));
132 }
133
134 return original.replaceLast(replacement).evaluate(evalFunc, comp);
135 }
136
137
138 @Override
139 public String toString() {
140 return "Multidirectional [g=" + gamma +
141 " s=" + sigma + "]";
142 }
143 }