protected override Matrix CalculateUpdate(int freeValuesCount, int xLength, Vector originalData, ConstraintRefContainer cons, Matrix n, Vector grad, Vector deltaX) { var gammatDotN = new Vector(xLength); var firstSecond = new Matrix(xLength, xLength); var deltaXDotGammatDotN = new Matrix(xLength, xLength); var gammatDotDeltaXt = new Matrix(xLength, xLength); var gradnew = new Vector(xLength); for (var i = 0; i < freeValuesCount; i++) { gradnew[i] = cons.Grad(originalData, i); } Vector gamma = gradnew - grad; double bottom = deltaX * gamma; //make sure that bottom is never 0 if (bottom < 1e-9) { bottom = 1e-9; } for (var i = 0; i < xLength; i++) { gammatDotN[i] = 0; for (var j = 0; j < freeValuesCount; j++) { gammatDotN[i] += gamma[j] * n[i, j]; } } double gammatDotNDotGamma = gammatDotN * gamma; var firstTerm = 1 + gammatDotNDotGamma / bottom; for (var i = 0; i < freeValuesCount; i++) { for (var j = 0; j < freeValuesCount; j++) { firstSecond[i, j] = ((deltaX[j] * deltaX[i]) / bottom) * firstTerm; deltaXDotGammatDotN[i, j] = deltaX[i] * gammatDotN[j]; gammatDotDeltaXt[i, j] = gamma[i] * deltaX[j]; } } Matrix nDotGammaDotDeltaXt = n * gammatDotDeltaXt; //Now calculate the BFGS update on N n = n + firstSecond - (deltaXDotGammatDotN + nDotGammaDotDeltaXt) * (1 / bottom); return(n); }
protected override Matrix CalculateUpdate(int freeValuesCount, int xLength, Vector originalData, ConstraintRefContainer cons, Matrix n, Vector grad, Vector deltaX) { var firstTerm = new Matrix(xLength, xLength); var gradnew = new Vector(xLength); for (var i = 0; i < freeValuesCount; i++) { gradnew[i] = cons.Grad(originalData, i); } Vector gamma = gradnew - grad; double bottom = deltaX * gamma; //make sure that bottom is never 0 if (bottom < 1e-9) { bottom = 1e-9; } double gammatDotNDotGamma = 0.0; for (var i = 0; i < xLength; i++) { for (var j = 0; j < freeValuesCount; j++) { gammatDotNDotGamma += gamma[j] * n[i, j] * gamma[i]; } } if (gammatDotNDotGamma < 1e-9) { gammatDotNDotGamma = 1e-9; } var secondTerm = new Matrix(xLength, xLength); for (var i = 0; i < freeValuesCount; i++) { for (var j = 0; j < freeValuesCount; j++) { firstTerm[i, j] = (deltaX[i] * deltaX[j]) / bottom; secondTerm[i, j] = n[i, j] * gamma[i] * gamma[j] * n[i, j] * (1 / gammatDotNDotGamma); } } //Now calculate the DFP update on N n = n + firstTerm - secondTerm; return(n); }
public int SolveRef(ref Vector originalData, int freeValuesCount, ConstraintRefContainer cons, double isFine) { var xLength = originalData.Count; //Save the original parameters for later. var origSolution1 = new Vector(originalData); var convergence = isFine > 0.1 ? XconvergenceFine : XconvergenceRough; //Calculate Function at the starting point: var f0 = cons.Calc(originalData); if (f0 < SmallF) { return(0); } //Calculate the gradient at the starting point: var grad = new Vector(xLength); //The gradient vector (1xn) for (var j = 0; j < freeValuesCount; j++) { grad[j] = cons.Grad(originalData, j); } //Initialize N and calculate s var n = Matrix.Identity(xLength, xLength); var s = -grad; var fnew = f0 + 1; var xold = new Vector(originalData); //Storage for the previous design variables ///////////////////////////////////////////////////////// //// Calculate first step ///////////////////////////////////////////////////////// //Make the initial position alpha1 double alpha1 = 0; ////Take a step of alpha=1 as alpha2 double alpha2 = 1; double f1 = fnew; var alphaStar = LineSearch(cons, xold, s, f1, alpha2, alpha1); originalData = xold + alphaStar * s; fnew = cons.Calc(originalData); ///////////////////////////////////// // end of first step ///////////////////////////////////// var deltaX = new Vector(xLength); var gradnew = new Vector(xLength); double deltaXnorm = 1; var iterations = 1; deltaX = originalData - xold; while (deltaXnorm > convergence && fnew > SmallF && iterations < MaxIterations * xold.Count) { n = CalculateUpdate(freeValuesCount, xLength, originalData, cons, n, grad, deltaX); ////// line search + next steps ///// for (var i = 0; i < freeValuesCount; i++) { gradnew[i] = cons.Grad(originalData, i); } s = n * (-gradnew); //copy newest values to the xold xold = originalData; f1 = fnew; alphaStar = LineSearch(cons, xold, s, f1, alpha2, alpha1); originalData = xold + alphaStar * s; fnew = cons.Calc(originalData); deltaX = originalData - xold; grad = new Vector(gradnew); deltaXnorm = deltaX.Norm(); iterations++; } // End of function double validSolution = isFine < 0.1 ? ValidSolutionFine : ValidSoltuionRough; if (fnew < validSolution) { return(0); } originalData = origSolution1; return(1); }