create changelog entry
[debian/openrocket] / core / src / net / sf / openrocket / optimization / general / multidim / SearchPattern.java
1 package net.sf.openrocket.optimization.general.multidim;
2
3 import java.util.ArrayList;
4 import java.util.List;
5
6 import net.sf.openrocket.optimization.general.Point;
7 import net.sf.openrocket.util.MathUtil;
8
9 /**
10  * A helper class to create search patterns.
11  * 
12  * @author Sampo Niskanen <sampo.niskanen@iki.fi>
13  */
14 public class SearchPattern {
15         
16         /**
17          * Create a square search pattern with the specified dimensionality.
18          * 
19          * @param dimensionality        the dimensionality
20          */
21         public static List<Point> square(int dimensionality) {
22                 List<Point> pattern = new ArrayList<Point>(dimensionality);
23                 
24                 for (int i = 0; i < dimensionality; i++) {
25                         double[] p = new double[dimensionality];
26                         p[i] = 1.0;
27                         pattern.add(new Point(p));
28                 }
29                 return pattern;
30         }
31         
32         
33
34         /**
35          * Create a regular simplex search pattern with the specified dimensionality.
36          * 
37          * @param dimensionality        the dimensionality
38          */
39         public static List<Point> regularSimplex(int dimensionality) {
40                 if (dimensionality <= 0) {
41                         throw new IllegalArgumentException("Illegal dimensionality " + dimensionality);
42                 }
43                 
44                 List<Point> pattern = new ArrayList<Point>(dimensionality);
45                 
46                 double[] coordinates = new double[dimensionality];
47                 double dot = -1.0 / dimensionality;
48                 
49                 /*
50                  * First construct an origin-centered regular simplex.
51                  * http://en.wikipedia.org/wiki/Simplex#Cartesian_coordinates_for_regular_n-dimensional_simplex_in_Rn
52                  */
53
54                 for (int i = 0; i < dimensionality; i++) {
55                         // Compute the next point coordinate
56                         double value = 1;
57                         
58                         for (int j = 0; j < i; j++) {
59                                 value -= MathUtil.pow2(coordinates[j]);
60                         }
61                         value = MathUtil.safeSqrt(value);
62                         
63                         coordinates[i] = value;
64                         pattern.add(new Point(coordinates));
65                         
66                         // Compute the i-coordinate for all next points
67                         value = dot;
68                         for (int j = 0; j < i; j++) {
69                                 value -= MathUtil.pow2(coordinates[j]);
70                         }
71                         value = value / coordinates[i];
72                         
73                         coordinates[i] = value;
74                 }
75                 
76                 // Minimum point
77                 Point min = pattern.get(dimensionality - 1);
78                 min = min.set(dimensionality - 1, -min.get(dimensionality - 1));
79                 
80
81                 /*
82                  * Shift simplex to have a corner at the origin and scale to unit length.
83                  */
84                 if (dimensionality > 1) {
85                         double scale = 1.0 / (pattern.get(1).sub(pattern.get(0)).length());
86                         for (int i = 0; i < dimensionality; i++) {
87                                 Point p = pattern.get(i);
88                                 p = p.sub(min).mul(scale);
89                                 pattern.set(i, p);
90                         }
91                 }
92                 
93                 return pattern;
94         }
95 }