/// <summary> /// Finds (dimension + 1) initial points. /// </summary> /// <param name="extremes"></param> /// <returns></returns> private List <int> FindInitialPoints() { var bigNumber = maxima.Sum() * NumOfDimensions * NumberOfVertices; // the first two points are taken from the dimension that had the fewest extremes // well, in most cases there will only be 2 in all dimensions: one min and one max // but a lot of engineering part shapes are nice and square and can have hundreds of // parallel vertices at the extremes var vertex1 = boundingBoxPoints[indexOfDimensionWithLeastExtremes].First(); // these are min and max vertices along var vertex2 = boundingBoxPoints[indexOfDimensionWithLeastExtremes].Last(); // the dimension that had the fewest points boundingBoxPoints[indexOfDimensionWithLeastExtremes].RemoveAt(0); boundingBoxPoints[indexOfDimensionWithLeastExtremes].RemoveAt(boundingBoxPoints[indexOfDimensionWithLeastExtremes].Count - 1); var initialPoints = new List <int> { vertex1, vertex2 }; VertexVisited[vertex1] = VertexVisited[vertex2] = true; CurrentVertex = vertex1; UpdateCenter(); CurrentVertex = vertex2; UpdateCenter(); var edgeVectors = new double[NumOfDimensions][]; edgeVectors[0] = MathHelper.VectorBetweenVertices(vertex2, vertex1); // now the remaining vertices are just combined in one big list var extremes = boundingBoxPoints.SelectMany(x => x).ToList(); // otherwise find the remaining points by maximizing the initial simplex volume var index = 1; while (index < NumOfDimensions && extremes.Any()) { var bestVertex = -1; var bestEdgeVector = new double[] { }; var maxVolume = 0.0; for (var i = extremes.Count - 1; i >= 0; i--) { // count backwards in order to remove potential duplicates var vIndex = extremes[i]; if (initialPoints.Contains(vIndex)) { extremes.RemoveAt(i); } else { edgeVectors[index] = MathHelper.VectorBetweenVertices(vIndex, vertex1); var volume = MathHelper.GetSimplexVolume(edgeVectors, index, bigNumber); if (maxVolume < volume) { maxVolume = volume; bestVertex = vIndex; bestEdgeVector = edgeVectors[index]; } } } extremes.Remove(bestVertex); if (bestVertex == -1) { break; } initialPoints.Add(bestVertex); edgeVectors[index++] = bestEdgeVector; CurrentVertex = bestVertex; UpdateCenter(); } // hmm, there are not enough points on the bounding box to make a simplex. It is rare but entirely possibly. // As an extreme, the bounding box can be made in n dimensions from only 2 unique points. When we can't find // enough unique points, we start again with ALL the vertices. The following is a near replica of the code // above, but instead of extremes, we consider "allVertices". if (initialPoints.Count <= NumOfDimensions) { var allVertices = Enumerable.Range(0, NumberOfVertices).ToList(); while (index < NumOfDimensions && allVertices.Any()) { var bestVertex = -1; var bestEdgeVector = new double[] { }; var maxVolume = 0.0; for (var i = allVertices.Count - 1; i >= 0; i--) { // count backwards in order to remove potential duplicates var vIndex = allVertices[i]; if (initialPoints.Contains(vIndex)) { allVertices.RemoveAt(i); } else { edgeVectors[index] = MathHelper.VectorBetweenVertices(vIndex, vertex1); var volume = MathHelper.GetSimplexVolume(edgeVectors, index, bigNumber); if (maxVolume < volume) { maxVolume = volume; bestVertex = vIndex; bestEdgeVector = edgeVectors[index]; } } } allVertices.Remove(bestVertex); if (bestVertex == -1) { break; } initialPoints.Add(bestVertex); edgeVectors[index++] = bestEdgeVector; CurrentVertex = bestVertex; UpdateCenter(); } } if (initialPoints.Count <= NumOfDimensions) { throw new ArgumentException("The input data is degenerate. It appears to exist in " + NumOfDimensions + " dimensions, but it is a " + (NumOfDimensions - 1) + " dimensional set (i.e. the point of collinear," + " coplanar, or co-hyperplanar.)"); } return(initialPoints); }
private List <int> FindInitialPoints() { double bigNumber = maxima.Sum() * (double)NumOfDimensions * (double)NumberOfVertices; int num = boundingBoxPoints[indexOfDimensionWithLeastExtremes].First(); int num2 = boundingBoxPoints[indexOfDimensionWithLeastExtremes].Last(); boundingBoxPoints[indexOfDimensionWithLeastExtremes].RemoveAt(0); boundingBoxPoints[indexOfDimensionWithLeastExtremes].RemoveAt(boundingBoxPoints[indexOfDimensionWithLeastExtremes].Count - 1); List <int> list = new List <int>(); list.Add(num); list.Add(num2); List <int> list2 = list; VertexVisited[num] = (VertexVisited[num2] = true); CurrentVertex = num; UpdateCenter(); CurrentVertex = num2; UpdateCenter(); double[][] array = new double[NumOfDimensions][]; array[0] = mathHelper.VectorBetweenVertices(num2, num); List <int> list3 = boundingBoxPoints.SelectMany((List <int> x) => x).ToList(); int num3 = 1; while (num3 < NumOfDimensions) { if (!list3.Any()) { break; } int num4 = -1; double[] array2 = new double[0]; double num5 = 0.0; for (int num6 = list3.Count - 1; num6 >= 0; num6--) { int num7 = list3[num6]; if (list2.Contains(num7)) { list3.RemoveAt(num6); } else { array[num3] = mathHelper.VectorBetweenVertices(num7, num); double simplexVolume = mathHelper.GetSimplexVolume(array, num3, bigNumber); if (num5 < simplexVolume) { num5 = simplexVolume; num4 = num7; array2 = array[num3]; } } } list3.Remove(num4); if (num4 == -1) { break; } list2.Add(num4); array[num3++] = array2; CurrentVertex = num4; UpdateCenter(); } if (list2.Count <= NumOfDimensions) { List <int> list4 = Enumerable.Range(0, NumberOfVertices).ToList(); while (num3 < NumOfDimensions) { if (!list4.Any()) { break; } int num9 = -1; double[] array3 = new double[0]; double num10 = 0.0; for (int num11 = list4.Count - 1; num11 >= 0; num11--) { int num12 = list4[num11]; if (list2.Contains(num12)) { list4.RemoveAt(num11); } else { array[num3] = mathHelper.VectorBetweenVertices(num12, num); double simplexVolume2 = mathHelper.GetSimplexVolume(array, num3, bigNumber); if (num10 < simplexVolume2) { num10 = simplexVolume2; num9 = num12; array3 = array[num3]; } } } list4.Remove(num9); if (num9 == -1) { break; } list2.Add(num9); array[num3++] = array3; CurrentVertex = num9; UpdateCenter(); } } if (list2.Count <= NumOfDimensions && IsLifted) { List <int> list5 = Enumerable.Range(0, NumberOfVertices).ToList(); while (num3 < NumOfDimensions) { if (!list5.Any()) { break; } int num14 = -1; double[] array4 = new double[0]; double num15 = 0.0; for (int num16 = list5.Count - 1; num16 >= 0; num16--) { int num17 = list5[num16]; if (list2.Contains(num17)) { list5.RemoveAt(num16); } else { mathHelper.RandomOffsetToLift(num17); array[num3] = mathHelper.VectorBetweenVertices(num17, num); double simplexVolume3 = mathHelper.GetSimplexVolume(array, num3, bigNumber); if (num15 < simplexVolume3) { num15 = simplexVolume3; num14 = num17; array4 = array[num3]; } } } list5.Remove(num14); if (num14 == -1) { break; } list2.Add(num14); array[num3++] = array4; CurrentVertex = num14; UpdateCenter(); } } if (list2.Count <= NumOfDimensions && IsLifted) { throw new ArgumentException("The input data is degenerate. It appears to exist in " + NumOfDimensions + " dimensions, but it is a " + (NumOfDimensions - 1) + " dimensional set (i.e. the point of collinear, coplanar, or co-hyperplanar.)"); } return(list2); }