private int SearchMinimumByDivision(LinearAlgebra.DoubleVector bound0, LinearAlgebra.DoubleVector bound1, int numberOfInitialDivisions) { double minValue = double.PositiveInfinity; int imin = -1; for (int i = 0; i <= numberOfInitialDivisions; i++) { double r = i / (double)numberOfInitialDivisions; double actValue = FunctionEvaluation(bound0 * (1 - r) + bound1 * r); if (actValue < minValue) { minValue = actValue; imin = i; } } return(imin); }
public LinearAlgebra.DoubleVector Search(LinearAlgebra.DoubleVector bound0, LinearAlgebra.DoubleVector bound1, int numberOfInitialDivisions, int numberOfSubsequentDivisions, int divisionDepth) { if (numberOfInitialDivisions < 2) { throw new ArgumentOutOfRangeException("Number of initial divisions must not smaller than 2"); } if (numberOfSubsequentDivisions < 2) { throw new ArgumentOutOfRangeException("Number of subsequent divisions must be not smaller than 2"); } int actualNumberOfDivisions = numberOfInitialDivisions; int imin = SearchMinimumByDivision(bound0, bound1, actualNumberOfDivisions); if (imin < 0) { throw new ArgumentOutOfRangeException("Function evaluation resulted in either all invalid or infinite function values"); } double r = imin / (double)actualNumberOfDivisions; double rstep = 1 / (double)actualNumberOfDivisions; double rmin = Math.Max(0, r - rstep); double rmax = Math.Min(1, r + rstep); DoubleVector xLeft = bound0 * (1 - rmin) + bound1 * rmin; DoubleVector xRight = bound0 * (1 - rmax) + bound1 * rmax; if (divisionDepth <= 0) { return(bound0 * (1 - r) + bound1 * r); } else if (numberOfSubsequentDivisions == 2) { DoubleVector xMiddle = bound0 * (1 - r) + bound1 * r; return(BinaryMinimumSearch(xLeft, FunctionEvaluation(xLeft), xMiddle, FunctionEvaluation(xMiddle), xRight, FunctionEvaluation(xRight), divisionDepth)); } else { return(SearchMinimumByRecursiveDivisions(xLeft, xRight, numberOfSubsequentDivisions, divisionDepth)); } }
public override LinearAlgebra.DoubleVector Search(LinearAlgebra.DoubleVector x, LinearAlgebra.DoubleVector direction, double step) { var retx = new DoubleVector(x); double oldVal = FunctionEvaluation(retx); double newVal = oldVal; // First find the initial direction double valPos = FunctionEvaluation(retx + direction * step); double valNeg = FunctionEvaluation(retx - direction * step); if (valPos >= oldVal && valNeg < oldVal) // we reverse the direction only if the other direction really gives the smaller result { retx -= direction * step; oldVal = valNeg; step = -step; } else if (valPos < oldVal) { retx += direction * step; oldVal = valPos; } // now iterate for (; ;) { retx += direction * step; newVal = FunctionEvaluation(retx); if (newVal > oldVal) { step /= -2; } else if (!(newVal != oldVal)) { break; } oldVal = newVal; } return(retx); }
public override LinearAlgebra.DoubleVector Search(LinearAlgebra.DoubleVector x, LinearAlgebra.DoubleVector direction, double step) { return(Search(x, x + direction * step, _numberOfInitialDivisions, _numberOfSubsequentDivisions, _divisionDepth)); }