# Why SDDP.jl can not work together with nonlinear optimizer like juniper

**URL:** <https://discourse.julialang.org/t/why-sddp-jl-can-not-work-together-with-nonlinear-optimizer-like-juniper/83559>\
**Category:** Optimization (Mathematical)\
**Tags:** jump\
**Created:** [June 30, 2022, 9:27am UTC](https://discourse.julialang.org/t/why-sddp-jl-can-not-work-together-with-nonlinear-optimizer-like-juniper/83559 "2022-06-30T09:27:52Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![chenr86](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chenr86/32/36785_2.png) [@chenr86](https://discourse.julialang.org/u/chenr86)\
**Post date:** [June 30, 2022, 9:27am UTC](https://discourse.julialang.org/t/why-sddp-jl-can-not-work-together-with-nonlinear-optimizer-like-juniper/83559/1 "2022-06-30T09:27:52Z")

</div>

Hello,

I’m using JuMP.jl and Juniper.jl to solve a MINLP problem. Now I attempt to consider the uncertainty in some of the constraints by consulting theory guide of SDDP.jl. But I can’t understand how SDDP.jl deal with uncertainty source, just like in the example:

```julia
using SDDP, GLPK

model = SDDP.LinearPolicyGraph(
    stages = 3,
    sense = :Min,
    lower_bound = 0.0,
    optimizer = GLPK.Optimizer,
) do subproblem, t
    # Define the state variable.
    @variable(subproblem, 0 <= volume <= 200, SDDP.State, initial_value = 200)
    # Define the control variables.
    @variables(subproblem, begin
        thermal_generation >= 0
        hydro_generation >= 0
        hydro_spill >= 0
        inflow
    end)
    # Define the constraints
    @constraints(
        subproblem,
        begin
            volume.out == volume.in + inflow - hydro_generation - hydro_spill
            thermal_generation + hydro_generation == 150.0
        end
    )
    fuel_cost = [50.0, 100.0, 150.0]
    # Parameterize the subproblem.
    Ω = [
        (inflow = 0.0, fuel_multiplier = 1.5),
        (inflow = 50.0, fuel_multiplier = 1.0),
        (inflow = 100.0, fuel_multiplier = 0.75),
    ]
    SDDP.parameterize(subproblem, Ω, [1 / 3, 1 / 3, 1 / 3]) do ω
        JuMP.fix(inflow, ω.inflow)
        @stageobjective(
            subproblem,
            ω.fuel_multiplier * fuel_cost[t] * thermal_generation
        )
    end
end

```

Can someone explain the functionality of the loop of omega with `SDDP.parameterize`?

And I am wondering if this is why SDDP.jl can not work with nonlinear optimizer. Is it possible to modify the binary of SDDP.jl to make it compatible with nonlinear optimizer? If the answer is yes, how can I do that?

Ru

---

<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 30, 2022, 6:54pm UTC](https://discourse.julialang.org/t/why-sddp-jl-can-not-work-together-with-nonlinear-optimizer-like-juniper/83559/2 "2022-06-30T18:54:12Z")

</div>

Same answer: [SDDP: how to use Juniper.jl for optimizer - #4 by odow](https://discourse.julialang.org/t/sddp-how-to-use-juniper-jl-for-optimizer/82719/4)

SDDP.jl is not intended for MINLPs. It requires convex problems.

---

<div class="post-metadata">

**Author:** ![chenr86](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chenr86/32/36785_2.png) [@chenr86](https://discourse.julialang.org/u/chenr86)\
**Post date:** [July 1, 2022, 1:16am UTC](https://discourse.julialang.org/t/why-sddp-jl-can-not-work-together-with-nonlinear-optimizer-like-juniper/83559/3 "2022-07-01T01:16:45Z")

</div>

Can you explain the effect of loop of omega with `SDDP.parameterize`? Why it can simulate the uncertainty of inflow? I don’t see the influence of probability` [1/3, 1/3, 1/3]`

---

<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:** [July 1, 2022, 1:28am UTC](https://discourse.julialang.org/t/why-sddp-jl-can-not-work-together-with-nonlinear-optimizer-like-juniper/83559/4 "2022-07-01T01:28:38Z")

</div>

`SDDP.parameterize` is used to model the node-wise independent random variables. In this case, it maps over the sample space `Ω` with probabilities given by the probability vector `[1 / 3, 1 / 3, 1 / 3]`, and then for each element ω it runs the inner part of the `do ... end`.

Documentation:

- [An introduction to SDDP.jl · SDDP.jl](https://odow.github.io/SDDP.jl/stable/tutorial/basic/01_first_steps/)
- [Introductory theory · SDDP.jl](https://odow.github.io/SDDP.jl/stable/tutorial/theory/21_theory_intro/)

But again, you should note that if you have a MINLP, SDDP.jl is the wrong tool for the job.

---

<div class="post-metadata">

**Author:** ![chenr86](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/chenr86/32/36785_2.png) [@chenr86](https://discourse.julialang.org/u/chenr86)\
**Post date:** [July 1, 2022, 1:40am UTC](https://discourse.julialang.org/t/why-sddp-jl-can-not-work-together-with-nonlinear-optimizer-like-juniper/83559/5 "2022-07-01T01:40:03Z")

</div>

Thanks for your kind hint. I know it’s better not to use SDDP.jl. What I am trying to do is to understand how SDDP.jl deal with uncertainty source. And then I will implement the uncertainty effect into my JuMP code, which solves a MINLP. It seems that I can achieve my goal by declaring a struct `Uncertainty` and looping over the sample space `omega`. Is it 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:** [July 1, 2022, 1:56am UTC](https://discourse.julialang.org/t/why-sddp-jl-can-not-work-together-with-nonlinear-optimizer-like-juniper/83559/6 "2022-07-01T01:56:28Z")

</div>

> It seems that I can achieve my goal by declaring a struct `Uncertainty` and looping over the sample space `omega`

No. SDDP.jl doesn’t add uncertainty to a JuMP model in a generic way that you could easily replicate. (At a high-level, it creates a struct that stores the probability information and the callback to modify the JuMP model given a realization of the uncertainty. But the JuMP model at all times is still deterministic. The way we deal with the uncertainty is part of the larger algorithm.)

If you want to add uncertainty to your own code, you’ll have to do something different, like sample average approximation. If it’s multistage and you’re solving the deterministic equivalent, you’ll additionally need non-anticipativity constraints etc.
