1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.commons.math.optimization;
19
20 /**
21 * This class implements the multi-directional direct search method.
22 *
23 * @version $Revision: 620312 $ $Date: 2008-02-10 12:28:59 -0700 (Sun, 10 Feb 2008) $
24 * @see NelderMead
25 * @since 1.2
26 */
27 public class MultiDirectional
28 extends DirectSearchOptimizer {
29
30 /** Build a multi-directional optimizer with default coefficients.
31 * <p>The default values are 2.0 for khi and 0.5 for gamma.</p>
32 */
33 public MultiDirectional() {
34 super();
35 this.khi = 2.0;
36 this.gamma = 0.5;
37 }
38
39 /** Build a multi-directional optimizer with specified coefficients.
40 * @param khi expansion coefficient
41 * @param gamma contraction coefficient
42 */
43 public MultiDirectional(double khi, double gamma) {
44 super();
45 this.khi = khi;
46 this.gamma = gamma;
47 }
48
49 /** Compute the next simplex of the algorithm.
50 * @exception CostException if the function cannot be evaluated at
51 * some point
52 */
53 protected void iterateSimplex()
54 throws CostException {
55
56 while (true) {
57
58 // save the original vertex
59 PointCostPair[] original = simplex;
60 double originalCost = original[0].getCost();
61
62 // perform a reflection step
63 double reflectedCost = evaluateNewSimplex(original, 1.0);
64 if (reflectedCost < originalCost) {
65
66 // compute the expanded simplex
67 PointCostPair[] reflected = simplex;
68 double expandedCost = evaluateNewSimplex(original, khi);
69 if (reflectedCost <= expandedCost) {
70 // accept the reflected simplex
71 simplex = reflected;
72 }
73
74 return;
75
76 }
77
78 // compute the contracted simplex
79 double contractedCost = evaluateNewSimplex(original, gamma);
80 if (contractedCost < originalCost) {
81 // accept the contracted simplex
82 return;
83 }
84
85 }
86
87 }
88
89 /** Compute and evaluate a new simplex.
90 * @param original original simplex (to be preserved)
91 * @param coeff linear coefficient
92 * @return smallest cost in the transformed simplex
93 * @exception CostException if the function cannot be evaluated at
94 * some point
95 */
96 private double evaluateNewSimplex(PointCostPair[] original, double coeff)
97 throws CostException {
98
99 double[] xSmallest = original[0].getPoint();
100 int n = xSmallest.length;
101
102 // create the linearly transformed simplex
103 simplex = new PointCostPair[n + 1];
104 simplex[0] = original[0];
105 for (int i = 1; i <= n; ++i) {
106 double[] xOriginal = original[i].getPoint();
107 double[] xTransformed = new double[n];
108 for (int j = 0; j < n; ++j) {
109 xTransformed[j] = xSmallest[j] + coeff * (xSmallest[j] - xOriginal[j]);
110 }
111 simplex[i] = new PointCostPair(xTransformed, Double.NaN);
112 }
113
114 // evaluate it
115 evaluateSimplex();
116 return simplex[0].getCost();
117
118 }
119
120 /** Expansion coefficient. */
121 private double khi;
122
123 /** Contraction coefficient. */
124 private double gamma;
125
126 }