package net.sf.openrocket.optimization.general.multidim; import java.util.ArrayList; import java.util.List; import net.sf.openrocket.optimization.general.Point; import net.sf.openrocket.util.MathUtil; /** * A helper class to create search patterns. * * @author Sampo Niskanen <sampo.niskanen@iki.fi> */ public class SearchPattern { /** * Create a square search pattern with the specified dimensionality. * * @param dimensionality the dimensionality */ public static List<Point> square(int dimensionality) { List<Point> pattern = new ArrayList<Point>(dimensionality); for (int i = 0; i < dimensionality; i++) { double[] p = new double[dimensionality]; p[i] = 1.0; pattern.add(new Point(p)); } return pattern; } /** * Create a regular simplex search pattern with the specified dimensionality. * * @param dimensionality the dimensionality */ public static List<Point> regularSimplex(int dimensionality) { if (dimensionality <= 0) { throw new IllegalArgumentException("Illegal dimensionality " + dimensionality); } List<Point> pattern = new ArrayList<Point>(dimensionality); double[] coordinates = new double[dimensionality]; double dot = -1.0 / dimensionality; /* * First construct an origin-centered regular simplex. * http://en.wikipedia.org/wiki/Simplex#Cartesian_coordinates_for_regular_n-dimensional_simplex_in_Rn */ for (int i = 0; i < dimensionality; i++) { // Compute the next point coordinate double value = 1; for (int j = 0; j < i; j++) { value -= MathUtil.pow2(coordinates[j]); } value = MathUtil.safeSqrt(value); coordinates[i] = value; pattern.add(new Point(coordinates)); // Compute the i-coordinate for all next points value = dot; for (int j = 0; j < i; j++) { value -= MathUtil.pow2(coordinates[j]); } value = value / coordinates[i]; coordinates[i] = value; } // Minimum point Point min = pattern.get(dimensionality - 1); min = min.set(dimensionality - 1, -min.get(dimensionality - 1)); /* * Shift simplex to have a corner at the origin and scale to unit length. */ if (dimensionality > 1) { double scale = 1.0 / (pattern.get(1).sub(pattern.get(0)).length()); for (int i = 0; i < dimensionality; i++) { Point p = pattern.get(i); p = p.sub(min).mul(scale); pattern.set(i, p); } } return pattern; } }