public override IpoptBoolType eval_jac_g(Int32 n, Double[] x, IpoptBoolType new_x, Int32 m, Int32 nele_jac, Int32[] iRow, Int32[] jCol, Double[] values, IntPtr p_user_data) { if (values == null) { for (var i = 0; i < iRow.Length; i++) { iRow[i] = this._jacobian.iRow[i]; } for (var i = 0; i < jCol.Length; i++) { jCol[i] = this._jacobian.jCol[i]; } } else { if (this._refreshJac) { this._jacobian = this._jacobianHelper.UpdateJacobian(x, this._constraints, this._jacobian); } //else //{ for (var i = 0; i < values.Length; i++) { values[i] = this._jacobian.values[i]; } //} } return(IpoptBoolType.True); }
public Jacobian UpdateJacobian(Double[] averageValues, Func <Double[], Double[]> constraints, Jacobian originalJacobian) { //i: constraints //j: variables var iRow = originalJacobian.iRow; var jCol = originalJacobian.jCol; var values = new Double[originalJacobian.values.Length]; var originalConstraintValues = constraints(averageValues); const Double disturbance = 1e-6; var globalIndex = 0; for (var j = 0; j < averageValues.Length; j++) { var averageValue = averageValues[j]; var originalValue = averageValue; if (Math.Abs(averageValue) < disturbance) { averageValues[j] = disturbance; } else { averageValues[j] = averageValue * (1 + disturbance); } var updatedConstraintValues = constraints(averageValues); var toUpdate = jCol.Select((d, i) => new { index = i, jj = d }) .Where(d => d.jj == j) .Select(d => d.index) .ToList(); foreach (var index in toUpdate) { var constraintNumber = iRow[index]; var diff = updatedConstraintValues[constraintNumber] - originalConstraintValues[constraintNumber]; var gradient = diff / (averageValues[j] - originalValue); values[globalIndex] = gradient; var minGradient = 1e-12; if (Math.Abs(gradient) < minGradient) { values[globalIndex] = minGradient; if (gradient < 0) { values[globalIndex] = -values[globalIndex]; } } globalIndex++; } averageValues[j] = originalValue; } var computeJacobian = new Jacobian { iRow = iRow, jCol = jCol, values = values }; return(computeJacobian); }
public IpoptReconciliationProblem(JacobianHelper jacobianHelper, Double[] lowerBounds, Double[] upperBounds, Double[] constraintLowerBounds, Double[] constraintUpperBounds, Func <Double[], Double[]> constraints, Jacobian jacobian, IpoptParams ipoptParams, Action <IterationResult> callback) : base( lowerBounds.Length, lowerBounds, upperBounds, constraintLowerBounds.Length, constraintLowerBounds, constraintUpperBounds, jacobian.iRow.Length, 0, true, true, true) { this._jacobianHelper = jacobianHelper; this._constraints = constraints; this._jacobian = jacobian; this._callback = callback; this.SetOptions(ipoptParams); }
private static SolverResult Solve(JacobianHelper jacobianHelper, Double[] lowerBounds, Double[] upperBounds, Double[] cLowerBounds, Double[] cUpperBoundsBounds, Func <Double[], Double[]> constraintCallback, Jacobian jac, IpoptParams ipoptParams, Double[] avg, Double[] stdDev) { var res = new SolverResult(new Double[0], -1); using (var sut = new IpoptReconciliationProblem(jacobianHelper, lowerBounds, upperBounds, cLowerBounds, cUpperBoundsBounds, constraintCallback, jac, ipoptParams, ir => { })) { res = sut.Solve(avg, stdDev); } return(res); }
public Jacobian ComputeJacobian(Double[] averageValues, Func <Double[], Double[]> constraints) { var iRow = new List <Int32>(); var jCol = new List <Int32>(); var values = new List <Double>(); var originalConstraintValues = constraints(averageValues); for (var j = 0; j < averageValues.Length; j++) { var averageValue = averageValues[j]; var originalValue = averageValue; averageValues[j] = averageValue * (1 + 1e-9); if (Math.Abs(averageValues[j]) < Double.Epsilon) { averageValues[j] = 1e-9; } var updatedConstraintValues = constraints(averageValues); for (var i = 0; i < updatedConstraintValues.Length; i++) { var diff = updatedConstraintValues[i] - originalConstraintValues[i]; if (Math.Abs(diff) >= Double.Epsilon) { iRow.Add(i); jCol.Add(j); values.Add(diff / (averageValues[j] - originalValue)); } } averageValues[j] = originalValue; } var computeJacobian = new Jacobian { iRow = iRow.ToArray(), jCol = jCol.ToArray(), values = values.ToArray() }; return(computeJacobian); }