# How to define a lower triangular decision matrix

**URL:** <https://discourse.julialang.org/t/how-to-define-a-lower-triangular-decision-matrix/82677>\
**Category:** Optimization (Mathematical)\
**Created:** [June 13, 2022, 12:42pm UTC](https://discourse.julialang.org/t/how-to-define-a-lower-triangular-decision-matrix/82677 "2022-06-13T12:42:01Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tri](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tri/32/36918_2.png) [@Tri](https://discourse.julialang.org/u/Tri)\
**Post date:** [June 13, 2022, 12:42pm UTC](https://discourse.julialang.org/t/how-to-define-a-lower-triangular-decision-matrix/82677/1 "2022-06-13T12:42:01Z")

</div>

Is there an efficient way to define a lower triangular matrix (other than defining n by n matrix and adding a constraint that sets every upper triangular element to be zero).

I tried the following but it resulted in an error when I multiply it by another matrix B

> using JuMP  
> using LinearAlgebra  
> model = Model()  
> n = 5  
> @variable(model, A[i=1:n, j=1:i])  
> @variable(model, B[1:n, 1:n], Symmetric)  
> C = A \* B’

---

<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:** [June 13, 2022, 10:05pm UTC](https://discourse.julialang.org/t/how-to-define-a-lower-triangular-decision-matrix/82677/2 "2022-06-13T22:05:12Z")

</div>

You were pretty close:

```julia
using JuMP
import LinearAlgebra
model = Model()
@variable(model, A[1:3,1:3], Symmetric)
Al = LinearAlgebra.LowerTriangular(A)

julia> @expression(model, Al * [1, 2, 3])
3-element Vector{AffExpr}:
 A[1,1]
 A[1,2] + 2 A[2,2]
 A[1,3] + 2 A[2,3] + 3 A[3,3]

```

---

<div class="post-metadata">

**Author:** ![Tri](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tri/32/36918_2.png) [@Tri](https://discourse.julialang.org/u/Tri)\
**Post date:** [June 14, 2022, 12:27pm UTC](https://discourse.julialang.org/t/how-to-define-a-lower-triangular-decision-matrix/82677/4 "2022-06-14T12:27:02Z")

</div>

Great Thanks. I don’t see a need for A to be symmetric. Right?

---

<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:** [June 14, 2022, 10:21pm UTC](https://discourse.julialang.org/t/how-to-define-a-lower-triangular-decision-matrix/82677/5 "2022-06-14T22:21:45Z")

</div>

If you define `A` to be symmetric, JuMP will only add 6 variables, because it knows that `A[i, j]` is the same as `A[j, i]`. If you omit `Symmetric`, it will add 9 variables.

---

<div class="post-metadata">

**Author:** ![Tri](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tri/32/36918_2.png) [@Tri](https://discourse.julialang.org/u/Tri)\
**Post date:** [June 17, 2022, 5:46pm UTC](https://discourse.julialang.org/t/how-to-define-a-lower-triangular-decision-matrix/82677/6 "2022-06-17T17:46:51Z")

</div>

@odow I am still struggling to use this lower triangular matrix in my model. Here is what I’m trying to set up. I tried wrapping them into expression but that didn’t help. Any idea?

```julia
using JuMP
using LinearAlgebra
model = Model()
n=5
@variable(model, A[1:n,1:n], Symmetric)
Al = LowerTriangular(A)
@variable(model, B[1:n,1:n], Symmetric)
@variable(model, c[1:n])
X = Al * B + c * c'
# @expression(model, X, Al * B + c * c')

@variable(model, Q[1:n,1:n])
@variable(model, P[1:n,1:n])
Y = Q*P'
# @expression(model, Y, Q*P)
@constraint(model, X .== Y)

```

---

<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:** [June 18, 2022, 1:29am UTC](https://discourse.julialang.org/t/how-to-define-a-lower-triangular-decision-matrix/82677/7 "2022-06-18T01:29:05Z")

</div>

What’s the problem?

---

<div class="post-metadata">

**Author:** ![Tri](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tri/32/36918_2.png) [@Tri](https://discourse.julialang.org/u/Tri)\
**Post date:** [June 18, 2022, 5:10pm UTC](https://discourse.julialang.org/t/how-to-define-a-lower-triangular-decision-matrix/82677/8 "2022-06-18T17:10:29Z")

</div>

Do you mean in the code above? It gives me the following error

`ArgumentError: Cannot set a non-diagonal index in a symmetric matrix`

Apparently It doesn’t like multiplying the lower triangular matrix Al by another matrix B. I also tried to put them in expressions like what you did in your answer but that didn’t help.

---

<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:** [June 19, 2022, 3:35am UTC](https://discourse.julialang.org/t/how-to-define-a-lower-triangular-decision-matrix/82677/9 "2022-06-19T03:35:34Z")

</div>

Ah. Okay the issue is [LinearAlgebra matrix types and expressions · Issue #66 · jump-dev/MutableArithmetics.jl · GitHub](https://github.com/jump-dev/MutableArithmetics.jl/issues/66).

You can work around the problem as `Al = collect(LowerTriangular(A))`. But I should take another look at what would be required to fix this properly.

The underlying problem is that `LinearAlgebra` makes some assumptions about JuMP variables that aren’t true. For example, `VariableRef * VariableRef` is a `QuadExpr`, whereas `Float64 * Float64` is still a `Float64`.
