Skip to main content

avoid infinity from logarithmic function in the objective

Answered

Comments

5 comments

  • Official comment
    Simranjit Kaur
    • Gurobi Staff
    This post is more than three years old. Some information may not be up to date. For current information, please check the Gurobi Documentation or Knowledge Base. If you need more help, please create a new post in the community forum. Or why not try our AI Gurobot?.
  • Maliheh Aramon
    • Gurobi Staff

    Hi Jiazhen, 

    Gurobi solves both convex and non-convex QCPs and uses the barrier algorithm for solving the convex QCP. Therefore, we highly recommend using Gurobi directly to solve your problem. That being said, let us address your question.

    If the barrier function is represented correctly, it should be impossible for the values of the \(\mu\) variables to equal zero because \(- \gamma y = -\gamma log(\mu)\) would then equal \(\infty\). This cannot happen in a minimization problem. There is likely another issue. 

    Let us look at the qcp.py problem as a concrete example below. The example problem has the optimal objective function of 0.326992. Note that this is a maximization problem.

    \[\begin{align} \max & ~~x \\ \text{s.t.} & ~~x+y+z = 1 \\  & x^2 + y^2  \leq z^2 \\ & x^2 \leq yz  \\ & x, y, z \geq 0\end{align}\]

    The logarithmic barrier function associated with the above optimization problem is:

    \[\begin{align} B(\gamma) : \max & ~~x + \gamma \big[\ln(z^2 - x^2 -y^2) + \ln(yz - x^2)+ \ln(x) + \ln(y) + \ln(z)\big] \\ \text{s.t. } &  ~~x+y+z = 1 \end{align}\]

    Here \(\gamma\) is a positive scalar and as it approaches 0, the solution of \(B(\gamma)\) should converge to the solution of the qcp.py example problem. 

    Running the code snippet (copied below) shows that the value of the objective function  \(B(\gamma)\)  approaches the objective function of the qcp.py example problem as the \(\gamma\) decreases.

    gamma:1 -- obj: -91.776410
    gamma:0.1 -- obj: -8.883347
    gamma:0.01 -- obj: -0.594040
    gamma:0.001 -- obj: 0.234890
    gamma:0.0001 -- obj: 0.317783
    gamma:1e-05 -- obj: 0.326073
    gamma:1e-06 -- obj: 0.326901
    def solve_barrier_function():
    def solve_per_mu(gamma):
    model = gurobipy.Model("")

    x = model.addVar(name="x")
    y = model.addVar(name="y")
    z = model.addVar(name="z")
    logx = model.addVar(lb=-GRB.INFINITY, name="logx")
    logy = model.addVar(lb=-GRB.INFINITY, name="logy")
    logz = model.addVar(lb=-GRB.INFINITY, name="logz")

    # Auxiliary variables
    w = model.addVar(name="w")
    v = model.addVar(name="v")
    logw = model.addVar(lb=-GRB.INFINITY, name="logw")
    logv = model.addVar(lb=-GRB.INFINITY, name="logv")

    # Set barrier objective
    obj = 1.0 * x + gamma * (logw + logv + logx + logy + logz)
    model.setObjective(obj, GRB.MAXIMIZE)

    # Add constraint: x+y+z=1
    model.addConstr(x + y + z == 1, "c0")

    # Add barrier functions associated with non-negativity constraints
    model.addGenConstrLog(x, logx)
    model.addGenConstrLog(y, logy)
    model.addGenConstrLog(z, logz)

    # Add w=z^2-x^2-y^2 (this quadratic equality constraint makes the
    # problem non-convex)
    model.addConstr(w == z ** 2 - x ** 2 - y ** 2, "w=z^2-x^2-y^2")

    # Add barrier associated with z^2-x^2-y^2 >= 0
    model.addGenConstrLog(w, logw)

    # Define v=yz-x^2 (this quadratic equality constraint makes the
    # problem non-convex)
    model.addConstr(v == y * z - x ** 2, "v=yz-x^2")

    # Add barrier associated with yz-x^2 >= 0
    model.addGenConstrLog(v, logv)

    model.params.NonConvex = 2
    model.params.OutputFlag = 0

    model.optimize()
    print(f"gamma:{gamma} -- obj: {model.objVal:.6f}")

    for gamma in [1, 0.1, 0.01, 0.001, 0.0001, 0.00001, 0.000001]:
    solve_per_mu(gamma)

    I would like to emphasize again that it is much more efficient and numerically stable to use Gurobi directly.

    Best regards,

    Maliheh

    0
  • Jiazhen Zhou
    • Gurobi-versary
    • First Question
    • First Comment

    Hi Maliheh,

     

    Thank you for this illustrative example. In running this example, however, there are still active constraints. In particular, variable \(v\) is zero for all \(\gamma\). Following is the printed results for \(v\) and \(\log(v)\):

    gamma:1 -- obj: -91.776408
    v:0.0 logv:-23.025850929940457
    Changed value of parameter NonConvex to 2
    Prev: -1 Min: -1 Max: 2 Default: -1
    gamma:0.1 -- obj: -8.883347
    v:0.0 logv:-23.025850929940457
    Changed value of parameter NonConvex to 2
    Prev: -1 Min: -1 Max: 2 Default: -1
    gamma:0.01 -- obj: -0.594041
    v:0.0 logv:-23.02585092994046
    Changed value of parameter NonConvex to 2
    Prev: -1 Min: -1 Max: 2 Default: -1
    gamma:0.001 -- obj: 0.234891
    v:0.0 logv:-23.025850929940457
    Changed value of parameter NonConvex to 2
    Prev: -1 Min: -1 Max: 2 Default: -1
    gamma:0.0001 -- obj: 0.317784
    v:0.0 logv:-23.025850929940457
    Changed value of parameter NonConvex to 2
    Prev: -1 Min: -1 Max: 2 Default: -1
    gamma:1e-05 -- obj: 0.326073
    v:0.0 logv:-23.025850929940457
    Changed value of parameter NonConvex to 2
    Prev: -1 Min: -1 Max: 2 Default: -1
    gamma:1e-06 -- obj: 0.326902
    v:0.0 logv:-23.025850929940457

     

    Do you think it is due to some precision setting for the log function or some other general setting for the model?

     

    Thank you again for the help!

     

    Best,

    Jiazhen

    0
  • Maliheh Aramon
    • Gurobi Staff

    Hi Jiazhen,

    Running the snippet code posted before results into \(\texttt{v}\) being equal to \(10^{-10}\) and not zero. The log value that you posted is the \(log(10^{-10})\). When running the code, I get the following:

    gamma:1 -- obj: -91.776410
    v: 1e-10 -- logv: -23.02585092993819
    gamma:0.1 -- obj: -8.883347
    v: 1e-10 -- logv: -23.02585092993819
    gamma:0.01 -- obj: -0.594040
    v: 1e-10 -- logv: -23.02585092993819
    gamma:0.001 -- obj: 0.234890
    v: 1e-10 -- logv: -23.02585092994046
    gamma:0.0001 -- obj: 0.317783
    v: 1e-10 -- logv: -23.02585092994046
    gamma:1e-05 -- obj: 0.326073
    v: 1e-10 -- logv: -23.02585092993819
    gamma:1e-06 -- obj: 0.326901
    v: 1e-10 -- logv: -23.02585092993819

    Maybe your print function prints up to a certain decimal value.

    Best regards,

    Maliheh

    0
  • Jiazhen Zhou
    • Gurobi-versary
    • First Question
    • First Comment

    I changed the tolerance of the problem and it is showing the same results as yours.

     

    Thank you, Maliheh!

     

    Jiazhen

    0

Post is closed for comments.