-
Summary:When using I'm wondering if the current behavior is as-intended, in which case I will work around it, or if this is not as-intended and is a matter of a (hopefully) straightforward patch. Details:I'm attempting to use scaling factors to scale some variables in a large-scale NLP. I've reduced the issue down to a trivial linear program, expressed in Pyomo: import pyomo.environ as pyo
m = pyo.ConcreteModel()
factor = 1.0e-12
m.x = pyo.Var(bounds=(0.5*factor, 1.5*factor), initialize=factor)
m.scaling_factor = pyo.Suffix(direction=pyo.Suffix.EXPORT)
m.scaling_factor[m.x] = 1./factor
m.o = pyo.Objective(expr=m.x/factor)
ipopt = pyo.SolverFactory("ipopt")
ipopt.options["print_level"] = 8
ipopt.options["nlp_scaling_method"] = "user-scaling"
ipopt.solve(m, tee=True, symbolic_solver_labels=True)
print(f"optimal value: {m.x.value}") Or in math:
Notice that I'm scaling the variable x by The optimal solution reported by Ipopt:
which is well outside, in relative terms, to the original lower bound of Looking at the log for Ipopt, what's apparently happening is that Eqn. (35) in the implementation paper is applied to the unscaled variable bounds, which are then scaled. Below is some sample output:
For this problem, it would be better to scale the variable bounds and then apply Eqn. (35) from the implementation paper. Doing this by-hand (setting |
Beta Was this translation helpful? Give feedback.
Replies: 1 comment
-
I cannot say whether things were intentional or not, but I presume that to change this, one would touch Ipopt/src/Algorithm/IpOrigIpoptNLP.cpp Lines 231 to 348 in a62679d To avoid too many changes, a possible way would be to compute the amount of bound relaxation on the scaled bounds and then scale them back to the original problem and apply them to the original bounds. There should be an option to choose between computing the bound relaxation on the original and the scaled bounds. |
Beta Was this translation helpful? Give feedback.
I cannot say whether things were intentional or not, but I presume that to change this, one would touch
OrigIpoptNLP::InitializeStructures()
. This is where the scaling is computed and the bounds are relaxed:Ipopt/src/Algorithm/IpOrigIpoptNLP.cpp
Lines 231 to 348 in a62679d