Recovering different form from JuMP model

If I have a model that I know represents the LP

min c'x
s.t. Ax<=b

how can I extract (A, b, c) from the model?
I know JuMP._nlp_objective_function will give me the objective function, but I actually need the vector c because I later use it explicitly when calculating gradients.

I think I know how I extract (A, b) in this case, but just to confirm: b= ._standard_form_matrix(model)[3] (because there are no simple constraints on x) and I get Ahat=._standard_form_matrix(model)[1]. Then I just remove the columns corresponding to A=Ahat[1:end-length(b)]

There’s no simple way.

This question has some code to help. The solve_pdhg function provides A, b, c (for Ax = b):

You shouldn’t rely on th JuMP._standard_form_matrix function. Function beginning with _ are private and may change or be delete at any point.

This questio keeps coming up, so I should add an answer to the documentation: Suggestions for documentation improvements · Issue #2348 · jump-dev/JuMP.jl · GitHub

1 Like

I guess this may help. @odow

using JuMP
import MathOptInterface

const MOI = MathOptInterface

function extract_matrices(model::JuMP.Model)
    num_vars = length(all_variables(model))
    constraints = all_constraints(model, JuMP.AffExpr, MOI.LessThan{Float64})
    num_cons = length(constraints)

    A = zeros(num_cons, num_vars)
    B = zeros(num_cons)
    C = zeros(num_vars)

    # Extract the constraint matrix (A) and the right-hand side vector (B)
    for (i, con) in enumerate(constraints)
        constraint_object = JuMP.constraint_object(con)
        constraint_function = constraint_object.func
        for (var, coeff) in constraint_function.terms
            A[i, index(var).value] = coeff
        end
        B[i] = constraint_object.set.upper
    end

    # Extract the cost vector (C)
    objective_function = JuMP.objective_function(model)
    for (i, var) in enumerate(all_variables(model))
        if haskey(objective_function.terms, var)
            C[i] = objective_function.terms[var]
        end
    end

    return A, B, C
end
2 Likes

To cover QP and QCP problems as well:

function extract_matrices(model::Model)
    num_vars = length(all_variables(model))
    constraints = all_constraints(model, JuMP.AffExpr, MOI.LessThan{Float64})
    quad_constraints = all_constraints(model, JuMP.GenericQuadExpr{Float64, JuMP.VariableRef}, MOI.LessThan{Float64})
    num_cons = length(constraints)
    num_quad_cons = length(quad_constraints)

    A = spzeros(num_cons, num_vars)
    B = spzeros(num_cons)
    C = spzeros(num_vars)
    Q = spzeros(num_vars, num_vars)
    Q_constraints = Vector{SparseMatrixCSC{Float64, Int}}()
    b_constraints = spzeros(num_quad_cons)

    # Extract the constraint matrix (A) and the right-hand side vector (B)
    for (i, con) in enumerate(constraints)
        constraint_function = JuMP.constraint_object(con).func
        for var in keys(constraint_function.terms)
            A[i, index(var).value] = constraint_function.terms[var]
        end
        B[i] = JuMP.constraint_object(con).set.upper
    end

    # Extract quadratic constraints
    for (i, con) in enumerate(quad_constraints)
        quad_constraint_function = JuMP.constraint_object(con).func
        quad_constraint = spzeros(num_vars, num_vars)
        b_constraints[i] = JuMP.constraint_object(con).set.upper - quad_constraint_function.aff.constant
        for (quad_var, coeff) in quad_constraint_function.terms
            quad_constraint[index(getfield(quad_var, 1)).value, index(getfield(quad_var, 2)).value] = coeff
        end
        push!(Q_constraints, quad_constraint)
    end

    # Extract the cost vector (C) and the quadratic matrix (Q)
    objective_function = JuMP.objective_function(model)
    if isa(objective_function, JuMP.QuadExpr)
        for var in keys(objective_function.aff.terms)
            C[index(var).value] = objective_function.aff.terms[var]
        end
        for (quad_var, coeff) in objective_function.terms
            Q[index(getfield(quad_var, 1)).value, index(getfield(quad_var, 2)).value] = coeff
            Q[index(getfield(quad_var, 2)).value, index(getfield(quad_var, 1)).value] = coeff
        end
    else
        for var in keys(objective_function.terms)
            C[index(var).value] = objective_function.terms[var]
        end
    end

    return A, B, C, Q, Q_constraints, b_constraints
end
3 Likes