# How to express an objective with L1-norm in JuMP.jl?

**URL:** <https://discourse.julialang.org/t/how-to-express-an-objective-with-l1-norm-in-jump-jl/91387>\
**Category:** Optimization (Mathematical)\
**Tags:** jump, optimization\
**Created:** [December 7, 2022, 8:10pm UTC](https://discourse.julialang.org/t/how-to-express-an-objective-with-l1-norm-in-jump-jl/91387 "2022-12-07T20:10:44Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [December 7, 2022, 8:10pm UTC](https://discourse.julialang.org/t/how-to-express-an-objective-with-l1-norm-in-jump-jl/91387/1 "2022-12-07T20:10:44Z")

</div>

I learned about the [NormOneCone](https://jump.dev/JuMP.jl/stable/moi/reference/standard_form/#MathOptInterface.NormOneCone), which can be used to add L1 constraints to a model. How to minimize the L1 norm of a vector of residuals? Tried `@objective(model, Min, sum(abs.(x)))` but it is not recognized by JuMP.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:** [December 7, 2022, 8:14pm UTC](https://discourse.julialang.org/t/how-to-express-an-objective-with-l1-norm-in-jump-jl/91387/2 "2022-12-07T20:14:00Z")

</div>

I’m literally adding this to the documentation right now: [[docs] add more tips and tricks for linear programs by odow · Pull Request #3144 · jump-dev/JuMP.jl · GitHub](https://github.com/jump-dev/JuMP.jl/pull/3144) 😄

```julia
@variable(model, t)
@constraint(model, [t; x] in MOI.NormOneCone(1 + length(x)))
@objective(model, Min, t) 

```

---

<div class="post-metadata">

**Author:** ![baggepinnen](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/baggepinnen/32/693_2.png) [@baggepinnen](https://discourse.julialang.org/u/baggepinnen)\
**Post date:** [December 7, 2022, 8:35pm UTC](https://discourse.julialang.org/t/how-to-express-an-objective-with-l1-norm-in-jump-jl/91387/3 "2022-12-07T20:35:59Z")

</div>

I recall jump understanding this automatically a long time ago, is there a reason it doesn’t doesn’t nowadays? If feels like a mechanical transformation that a mathematical modeling language could do for the user?

---

<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:** [December 7, 2022, 8:55pm UTC](https://discourse.julialang.org/t/how-to-express-an-objective-with-l1-norm-in-jump-jl/91387/4 "2022-12-07T20:55:05Z")

</div>

JuMP used to recognize `norm{x}` as a second-order cone. But we don’t do that anymore. I don’t think we every supported `abs`.

Recognizing and reformulating arbitrary nonlinear expressions is a tricky business. Currently, our main problem is that we don’t have a data structure to store `sum(abs.(x))`. But [WIP: [Nonlinear] begin experiments with NonlinearExpr by odow · Pull Request #3106 · jump-dev/JuMP.jl · GitHub](https://github.com/jump-dev/JuMP.jl/pull/3106) is a work-in-progress.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [December 13, 2022, 10:24pm UTC](https://discourse.julialang.org/t/how-to-express-an-objective-with-l1-norm-in-jump-jl/91387/5 "2022-12-13T22:24:55Z")

</div>

@odow can you please confirm the syntax for minimizing f(x) + \lambda ||x||\_1? The snippet of code you shared above does not consider the L1-norm as a penalty term with penalty \lambda \> 0.

---

<div class="post-metadata">

**Author:** ![juliohm](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/juliohm/32/215266_2.png) [@juliohm](https://discourse.julialang.org/u/juliohm)\
**Post date:** [December 13, 2022, 10:33pm UTC](https://discourse.julialang.org/t/how-to-express-an-objective-with-l1-norm-in-jump-jl/91387/6 "2022-12-13T22:33:21Z")

</div>

> [@odow](#):
>
> Recognizing and reformulating arbitrary nonlinear expressions is a tricky business

Any lessons to learn from disciplined convex programming and Convex.jl in particular? It would be super nice if JuMP.jl had more sugar syntax for all kinds of terms (when that is possible).

---

<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:** [December 13, 2022, 10:39pm UTC](https://discourse.julialang.org/t/how-to-express-an-objective-with-l1-norm-in-jump-jl/91387/7 "2022-12-13T22:39:41Z")

</div>

From [Tips and tricks · JuMP](https://jump.dev/JuMP.jl/dev/tutorials/linear/tips_and_tricks/#L1-norm), `t` is the L1-norm, so you’d do something like:

```julia
@objective(model, Min, f(x) + lambda * t)

```

---

<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:** [December 13, 2022, 10:42pm UTC](https://discourse.julialang.org/t/how-to-express-an-objective-with-l1-norm-in-jump-jl/91387/8 "2022-12-13T22:42:06Z")

</div>

> Any lessons to learn from disciplined convex programming and Convex.jl in particular? It would be super nice if JuMP.jl had more sugar syntax for all kinds of terms (when that is possible).

Convex builds an expression tree of the entire problem, with each node in the tree annotated with metadata like bounds, convexity, and monotonicity, and then it uses that information to deduce convexity of the entire problem. Because of the metadata, you’re only allowed to use a fixed number of “atoms” that Convex.jl has defined the metadata for.

It’s more of a tricky engineering challenge than a tricky conceptual challenge. At the moment, the design of Convex.jl is orthogonal to that of JuMP.
