double PowellMethod(double lambdaInit, double lambdaDelta, double eps1, double eps2, ExMatrix xVector, ExMatrix sVector) { double[] lambda, f; lambda = new double[3]; f = new double[3]; lambda[0] = lambdaInit; while (true) { lambda[1] = lambda[0] + lambdaDelta; f[0] = func.GetValue(xVector + sVector * lambda[0]); f[1] = func.GetValue(xVector + sVector * lambda[1]); if (f[0] > f[1]) { lambda[2] = lambda[0] + 2 * lambdaDelta; } else { lambda[2] = lambda[0] - lambdaDelta; } f[2] = func.GetValue(xVector + sVector * lambda[2]); while (true) { double lambdaMin = lambda[0], fMin = f[0]; for (int i = 0; i < 3; i++) { if (f[i] <= fMin) { fMin = f[i]; lambdaMin = lambda[i]; } } double lambdaOpt = 0.5 * (lambda[1] * lambda[1] - lambda[2] * lambda[2]) * f[0] + (lambda[2] * lambda[2] - lambda[0] * lambda[0]) * f[1] + (lambda[0] * lambda[0] - lambda[1] * lambda[1]) * f[2]; double denominator = (lambda[1] - lambda[2]) * f[0] + (lambda[2] - lambda[0]) * f[1] + (lambda[0] - lambda[1]) * f[2]; if (denominator == 0) { lambda[0] = lambdaMin; break; } lambdaOpt /= denominator; double fOpt = func.GetValue(xVector + sVector * lambdaOpt); if (Math.Abs((fMin - fOpt) / fOpt) < eps1 && Math.Abs((lambdaMin - lambdaOpt) / lambdaOpt) < eps2) { return(lambdaOpt); } else { if (lambdaOpt >= lambda[0] && lambdaOpt <= lambda[2]) { double[] lambdaArr = new double[4]; double lambdaBest; for (int i = 0; i < 3; i++) { lambdaArr[i] = lambda[i]; } if (fMin < fOpt) { lambdaBest = lambdaMin; lambdaArr[3] = lambdaOpt; } else { lambdaBest = lambdaOpt; lambdaArr[3] = lambdaMin; } lambda[1] = lambdaBest; double delta1 = double.MaxValue; double delta2 = double.MaxValue; for (int i = 0; i < 4; i++) { double curDelta = lambdaBest - lambdaArr[i]; if (curDelta > 0 && curDelta < delta1) { lambda[0] = lambdaArr[i]; delta1 = curDelta; } curDelta *= -1; if (curDelta > 0 && curDelta < delta2) { lambda[2] = lambdaArr[i]; delta2 = curDelta; } } } else { lambda[0] = lambdaOpt; break; } } } } }
public virtual double GetValue(ExMatrix x) { return(0); }
public ExMatrix(ExMatrix matr) { m = matr.m; n = matr.n; this.elements = (double[, ])matr.elements.Clone(); }