Why can't I set the `initial_value` to a matrix value when using `SDDP.jl`?

In the hydro-thermal scheduling example, if I define a matrix type state variable, I will not be able to set a matrix initial value to it:

using SDDP

graph = SDDP.LinearGraph(3)

function subproblem_builder(subproblem::Model, node::Int)
    # State variables
    # @variable(subproblem, 0 <= volume[1:2, 1:2] <= 200, SDDP.State, initial_value = 200) # OK
    @variable(subproblem, 0 <= volume[1:2, 1:2] <= 200, SDDP.State, initial_value = [200 200; 200 200]) # Not OK

    # Control variables
    @variables(subproblem, begin
        thermal_generation >= 0
        hydro_generation >= 0
        hydro_spill >= 0
    end)
    # Random variables
    @variable(subproblem, inflow)
    Ω = [0.0, 50.0, 100.0]
    P = [1 / 3, 1 / 3, 1 / 3]
    SDDP.parameterize(subproblem, Ω, P) do ω
        return JuMP.fix(inflow, ω)
    end


    # Transition function and constraints
    @expressions(
        subproblem,
        begin
            volume_out, [volume[i,j].out for i in 1:2, j in 1:2]
            volume_in, [volume[i,j].in for i in 1:2, j in 1:2]
        end
    )
    @constraints(
        subproblem,
        begin
            volume_out .== volume_in .- hydro_generation .- hydro_spill .+ inflow
            demand_constraint, hydro_generation + thermal_generation == 150
        end
    )
    # Stage-objective
    fuel_cost = [50, 100, 150]
    @stageobjective(subproblem, fuel_cost[node] * thermal_generation)
    return subproblem
end

model = SDDP.PolicyGraph(
    subproblem_builder,
    graph;
    sense = :Min,
    lower_bound = 0.0,
    optimizer = HiGHS.Optimizer,
)
ERROR: MethodError: no method matching isnan(::Matrix{Int64})

BTW, is there any better method to querying the out / in field from a matrix type state variable volume than [volume[i,j].out for i in 1:2, j in 1:2]?

Thanks!

The syntax is:

volume_start = [200 200; 200 200]
@variable(subproblem, 0 <= volume[i=1:2, j=1:2] <= 200, SDDP.State, initial_value = volume_start[i,j])

This syntax is not specific to SDDP. It applies to all JuMP variables.

julia> model = Model();

julia> @variable(model, x[1:2], start = [1, 2])
ERROR: At REPL[68]:1: `@variable(model, x[1:2], start = [1, 2])`: Passing arrays as variable starts without indexing them is not supported.

Instead of:
```julia
@variable(model, x[1:2], start = x0)
```
use
```julia
@variable(model, x[i=1:2], start = x0[i])
```
or
```julia
@variable(model, x[1:2])
set_start_value.(x, x0)
```

I guess I should improve the error message in SDDP.jl.

is there any better method to querying the out / in field from a matrix type state variable

getfield.(volume, :out) should work.

1 Like

Ah! I see! Thank you very much! :handshake: