# Matrix-vector representation of a system of linear inequalities

**URL:** https://discourse.julialang.org/t/matrix-vector-representation-of-a-system-of-linear-inequalities/106188
**Category:** General Usage
**Tags:** question, symbolics
**Created:** [November 14, 2023, 8:42am UTC](https://discourse.julialang.org/t/matrix-vector-representation-of-a-system-of-linear-inequalities/106188 "2023-11-14T08:42:31Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![\_stla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/_stla/32/35613_2.png) [@\_stla](https://discourse.julialang.org/u/_stla)
#### Post date: [November 14, 2023, 8:42am UTC](https://discourse.julialang.org/t/matrix-vector-representation-of-a-system-of-linear-inequalities/106188/1 "2023-11-14T08:42:31Z")

</div>

Hello,

Consider for example this set of linear inequalities:

![zzzz1](https://global.discourse-cdn.com/julialang/original/3X/1/4/14cd6621c6f8a7d56b606bfa8d28d159e1644b81.png)

It is equivalent to:

![zzzz2](https://global.discourse-cdn.com/julialang/original/3X/9/b/9b156d91c6c4fb089204d01a845c79d23050c726.png)

and this can be represented as `A*[x;y;z] <= b` where the matrix `A` is given by the coefficients of the variables at the LHS and the vector `b` is the one made of the bounds at the RHS.

Is it possible and how to get `A` and `b` from given symbolic inequalities `-5 <= x`, `x <= 4`, etc…?

---

<div class="post-metadata">

### Author: ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)
#### Post date: [November 14, 2023, 10:25am UTC](https://discourse.julialang.org/t/matrix-vector-representation-of-a-system-of-linear-inequalities/106188/2 "2023-11-14T10:25:34Z")

</div>

There a ways to do this in JuMP, but they’re not documented: e.g.

> [@Get presolved model from Gurobi](https://discourse.julialang.org/t/get-presolved-model-from-gurobi/103827/6):
>
> There is an internal function to create a “standard form” version for inspecting the problem ## JuMP.jl/src/lp\_sensitivity2.jl: # Docstring: # Given a problem: # # r\_l \<= Ax \<= r\_u # c\_l \<= x \<= c\_u # # Return the standard form: # # [A -I] [x, y] = 0 # [c\_l, r\_l] \<= [x, y] \<= [c\_u, r\_u] # If you have an integral problem first do: undo\_relax = relax\_integrality(rmodel); then you can do s = JuMP.\_standard\_form\_matrix(rmodel) julia\> keys(s) (:columns, :lower, :upper, …

---

<div class="post-metadata">

### Author: ![\_stla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/_stla/32/35613_2.png) [@\_stla](https://discourse.julialang.org/u/_stla)
#### Post date: [November 14, 2023, 11:32am UTC](https://discourse.julialang.org/t/matrix-vector-representation-of-a-system-of-linear-inequalities/106188/3 "2023-11-14T11:32:26Z")

</div>

Thanks! This does not directly gives what I want but it should not be difficult to get what I want from these outputs:

```julia
using JuMP

model = Model()

@variable(model, x)
@variable(model, y)
@variable(model, z)

@constraint(model, x >= 0)
@constraint(model, x <= 10)
@constraint(model, y >= 0)
@constraint(model, y <= 20-x)
@constraint(model, z >= -5)
@constraint(model, z <= 30-x-y)

undo_relax = relax_integrality(model)

s = JuMP._standard_form_matrix(model)
m, p = size(s.A)
A = s.A[:,1:(p-m)]

```

```julia
julia> A
6×3 SparseArrays.SparseMatrixCSC{Float64, Int64} with 9 stored entries:
 1.0 ⋅ ⋅
  ⋅ 1.0 ⋅
  ⋅ ⋅ 1.0
 1.0 ⋅ ⋅
 1.0 1.0 ⋅
 1.0 1.0 1.0

julia> s.lower
9-element Vector{Float64}:
 -Inf
 -Inf
 -Inf
   0.0
   0.0
  -5.0
 -Inf
 -Inf
 -Inf

julia> s.upper
9-element Vector{Float64}:
 Inf
 Inf
 Inf
 Inf
 Inf
 Inf
 10.0
 20.0
 30.0

```

---

<div class="post-metadata">

### Author: ![\_stla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/_stla/32/35613_2.png) [@\_stla](https://discourse.julialang.org/u/_stla)
#### Post date: [November 14, 2023, 11:35am UTC](https://discourse.julialang.org/t/matrix-vector-representation-of-a-system-of-linear-inequalities/106188/4 "2023-11-14T11:35:19Z")

</div>

Hmm… I need the possibility to deal with `Rational` coefficients and bounds, and it seems that **JuMP** only returns some `Float64` stuff.

---

<div class="post-metadata">

### Author: ![\_stla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/_stla/32/35613_2.png) [@\_stla](https://discourse.julialang.org/u/_stla)
#### Post date: [November 14, 2023, 8:33pm UTC](https://discourse.julialang.org/t/matrix-vector-representation-of-a-system-of-linear-inequalities/106188/5 "2023-11-14T20:33:12Z")

</div>

Thanks to some help I got on SO, I have this feature in Python, with SymPy.

```python
def __getAb0(inequalities, symbols, required_type):
    # assumptions:
    # 1. all inequalities are written with the same relational: < or <= or > or >=
    # 2. For each inequality, LHS and RHS are linear in `symbols`
    def get_ineq_with_correct_type(i, required_type):
        if type(i) != required_type:
            i = i.reversed
        return i

    # extract all inequalities, process them so they are all of the same type and
    # terms containing `symbols` are on the LHS.
    ineq = []
    for i in inequalities:
        if isinstance(i, And):
            ineq.extend(
                [get_ineq_with_correct_type(a, required_type) for a in i.args]
            )
        else:
            ineq.append(get_ineq_with_correct_type(i, required_type))
    # at this point, all inequalities should be of the same type.
    # rewrite them as expressions: LHS - RHS
    equations = [i.lhs - i.rhs for i in ineq]
    return linear_eq_to_matrix(equations, symbols)

def getAb(inequalities, symbols):
    """
    Get the matrix-vector representation of a set of linear inequalities.

    Parameters
    ----------
    inequalities : list 
        list of symbolic inequalities
    symbols : list
        list of symbols

    Returns
    -------
    matrix
        The matrix of the coefficients of the inequalities.
    vector
        The vector made of the bounds of the inequalities.

    Examples
    --------
    >>> from pypolyhedralcubature.polyhedralcubature import getAb
    >>> from sympy.abc import x, y, z
    >>> # linear inequalities
    >>> i1 = (x >= -5) & (x <= 4)
    >>> i2 = (y >= -5) & (y <= 3 - x)
    >>> i3 = (z >= -10) & (z <= 6 - x - y)
    >>> # get matrix-vector representation of these inequalities
    >>> A, b = getAb([i1, i2, i3], [x, y, z])

    """
    A, b = __getAb0(inequalities, symbols, LessThan)
    return np.array(A), np.array(b)[:, 0]

```

No way to do something like that in Julia? 🤔

---

<div class="post-metadata">

### Author: ![jd-foster](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jd-foster/32/35824_2.png) [@jd-foster](https://discourse.julialang.org/u/jd-foster)
#### Post date: [November 15, 2023, 5:12am UTC](https://discourse.julialang.org/t/matrix-vector-representation-of-a-system-of-linear-inequalities/106188/6 "2023-11-15T05:12:30Z")

</div>

[GitHub - JuliaPy/SymPy.jl: Julia interface to SymPy via PyCall](https://github.com/JuliaPy/SymPy.jl) ?

---

<div class="post-metadata">

### Author: ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)
#### Post date: [November 15, 2023, 5:30am UTC](https://discourse.julialang.org/t/matrix-vector-representation-of-a-system-of-linear-inequalities/106188/7 "2023-11-15T05:30:43Z")

</div>

Perhaps it is time to make this a public function. People seem to keep wanting it

---

<div class="post-metadata">

### Author: ![\_stla](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/_stla/32/35613_2.png) [@\_stla](https://discourse.julialang.org/u/_stla)
#### Post date: [November 15, 2023, 9:10am UTC](https://discourse.julialang.org/t/matrix-vector-representation-of-a-system-of-linear-inequalities/106188/8 "2023-11-15T09:10:40Z")

</div>

Thanks. I’m aware of **SymPy.jl** but I have not been able to install it (on Windows). I don’t want to include a dependency with a potential difficulty in installing it.
