//! Solve least square problem using numerix solver public Vector perform(ref LeastSquareProblem lsProblem) { double eps = accuracy_; // wrap the least square problem in an optimization function LeastSquareFunction lsf = new LeastSquareFunction(lsProblem); // define optimization problem Problem P = new Problem(lsf, c_, initialValue_); // minimize EndCriteria ec = new EndCriteria(maxIterations_, Math.Min(maxIterations_ / 2, 100), eps, eps, eps); exitFlag_ = (int)om_.minimize(P, ec); results_ = P.currentValue(); resnorm_ = P.functionValue(); bestAccuracy_ = P.functionValue(); return(results_); }
// curve optimization called here- adjust optimization parameters here internal void calculate() { FittingCost costFunction = costFunction_; Constraint constraint = new NoConstraint(); // start with the guess solution, if it exists Vector x = new Vector(size(), 0.0); if (!curve_.guessSolution_.empty()) { x = curve_.guessSolution_; } if (curve_.maxEvaluations_ == 0) { //Don't calculate, simply use given parameters to provide a fitted curve. //This turns the fittedbonddiscountcurve into an evaluator of the parametric //curve, for example allowing to use the parameters for a credit spread curve //calculated with bonds in one currency to be coupled to a discount curve in //another currency. return; } //workaround for backwards compatibility OptimizationMethod optimization = optimizationMethod_; if (optimization == null) { optimization = new Simplex(curve_.simplexLambda_); } Problem problem = new Problem(costFunction, constraint, x); double rootEpsilon = curve_.accuracy_; double functionEpsilon = curve_.accuracy_; double gradientNormEpsilon = curve_.accuracy_; EndCriteria endCriteria = new EndCriteria(curve_.maxEvaluations_, curve_.maxStationaryStateIterations_, rootEpsilon, functionEpsilon, gradientNormEpsilon); optimization.minimize(problem, endCriteria); solution_ = problem.currentValue(); numberOfIterations_ = problem.functionEvaluation(); costValue_ = problem.functionValue(); // save the results as the guess solution, in case of recalculation curve_.guessSolution_ = solution_; }
public override EndCriteria.Type minimize(Problem P, EndCriteria endCriteria) { // Initializations double ftol = endCriteria.functionEpsilon(); int maxStationaryStateIterations_ = endCriteria.maxStationaryStateIterations(); EndCriteria.Type ecType = EndCriteria.Type.None; // reset end criteria P.reset(); // reset problem Vector x_ = P.currentValue(); // store the starting point int iterationNumber_ = 0; // dimension line search lineSearch_.searchDirection = new Vector(x_.size()); bool done = false; // function and squared norm of gradient values double fnew, fold, gold2; double fdiff; // classical initial value for line-search step double t = 1.0; // Set gradient g at the size of the optimization problem // search direction int sz = lineSearch_.searchDirection.size(); Vector prevGradient = new Vector(sz), d = new Vector(sz), sddiff = new Vector(sz), direction = new Vector(sz); // Initialize cost function, gradient prevGradient and search direction P.setFunctionValue(P.valueAndGradient(ref prevGradient, x_)); P.setGradientNormValue(Vector.DotProduct(prevGradient, prevGradient)); lineSearch_.searchDirection = prevGradient * -1; bool first_time = true; // Loop over iterations do { // Linesearch if (!first_time) { prevGradient = lineSearch_.lastGradient(); } t = (lineSearch_.value(P, ref ecType, endCriteria, t)); // don't throw: it can fail just because maxIterations exceeded if (lineSearch_.succeed()) { // Updates // New point x_ = lineSearch_.lastX(); // New function value fold = P.functionValue(); P.setFunctionValue(lineSearch_.lastFunctionValue()); // New gradient and search direction vectors // orthogonalization coef gold2 = P.gradientNormValue(); P.setGradientNormValue(lineSearch_.lastGradientNorm2()); // conjugate gradient search direction direction = getUpdatedDirection(P, gold2, prevGradient); sddiff = direction - lineSearch_.searchDirection; lineSearch_.searchDirection = direction; // Now compute accuracy and check end criteria // Numerical Recipes exit strategy on fx (see NR in C++, p.423) fnew = P.functionValue(); fdiff = 2.0 * Math.Abs(fnew - fold) / (Math.Abs(fnew) + Math.Abs(fold) + Const.QL_EPSILON); if (fdiff < ftol || endCriteria.checkMaxIterations(iterationNumber_, ref ecType)) { endCriteria.checkStationaryFunctionValue(0.0, 0.0, ref maxStationaryStateIterations_, ref ecType); endCriteria.checkMaxIterations(iterationNumber_, ref ecType); return(ecType); } P.setCurrentValue(x_); // update problem current value ++iterationNumber_; // Increase iteration number first_time = false; } else { done = true; } }while (!done); P.setCurrentValue(x_); return(ecType); }