Skip to content

Commit 78491df

Browse files
committed
Merge pull request #45 from leclere/correct-forwardpassnumber-use
[FIX] fix use of param.forwardPassNumber and extract_vector_from_3Dmatrix
2 parents bdbd9ff + bbf2884 commit 78491df

File tree

4 files changed

+45
-46
lines changed

4 files changed

+45
-46
lines changed

src/SDDPoptimize.jl

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ function run_SDDP(model::SPModel,
9292

9393
# Build given number of scenarios according to distribution
9494
# law specified in model.noises:
95-
aleas = simulate_scenarios(model.noises ,
95+
noise_scenarios = simulate_scenarios(model.noises ,
9696
(model.stageNumber-1,
9797
param.forwardPassNumber,
9898
model.dimNoises))
@@ -102,7 +102,7 @@ function run_SDDP(model::SPModel,
102102
param,
103103
V,
104104
problems,
105-
aleas)
105+
noise_scenarios)
106106

107107
# Backward pass
108108
backward_pass!(model,
@@ -115,23 +115,25 @@ function run_SDDP(model::SPModel,
115115
returnValueFunctions)
116116

117117
iteration_count += 1
118-
upb = upper_bound(costs)
119118

120-
V0 = get_bellman_value(model, param, 1, V[1], model.initialState)
121119

122-
time = toq()
120+
123121

124122
if (display > 0) && (iteration_count%display==0)
125123
println("Pass number ", iteration_count,
126-
"\tEstimation of upper-bound: ", upb,
127-
"\tLower-bound: ", V0,
128-
"\tTime: ", time)
124+
"\tEstimation of upper-bound: ", upper_bound(costs),
125+
"\tLower-bound: ", get_bellman_value(model, param, 1, V[1], model.initialState),
126+
"\tTime: ", toq())
129127
end
130128

131129
end
132130

133131
# Estimate upper bound with a great number of simulations:
134132
if (display>0)
133+
upb = upper_bound(costs)
134+
V0 = get_bellman_value(model, param, 1, V[1], model.initialState)
135+
time = toq()
136+
135137
println("Estimate upper-bound with Monte-Carlo ...")
136138
upb, costs = estimate_upper_bound(model, param, V, problems)
137139
println("Estimation of upper-bound: ", upb,
@@ -172,12 +174,9 @@ Float64 (estimation of the upper bound)
172174
"""
173175
function estimate_upper_bound(model, param, V, problems, n_simulation=1000)
174176

175-
n_fpn = param.forwardPassNumber
176-
param.forwardPassNumber = n_simulation
177-
178177
aleas = simulate_scenarios(model.noises ,
179178
(model.stageNumber-1,
180-
param.forwardPassNumber,
179+
n_simulation,
181180
model.dimNoises))
182181

183182
costs, stockTrajectories, _ = forward_simulations(model,
@@ -186,9 +185,6 @@ function estimate_upper_bound(model, param, V, problems, n_simulation=1000)
186185
problems,
187186
aleas)
188187

189-
190-
param.forwardPassNumber = n_fpn
191-
192188
return upper_bound(costs), costs
193189
end
194190

@@ -463,4 +459,4 @@ function add_cuts_to_model!(model::SPModel, t::Int64, problem::JuMP.Model, V::Po
463459
lambda = vec(V.lambdas[i, :])
464460
@addConstraint(problem, V.betas[i] + dot(lambda, model.dynamics(t, x, u, w)) <= alpha)
465461
end
466-
end
462+
end

src/forwardBackwardIterations.jl

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ Parameters:
2727
Linear model used to approximate each value function
2828
2929
- xi (Array{float})
30-
the noise scenarios on which we simulate, each line being one scenario.
31-
Generated if not given.
30+
the noise scenarios on which we simulate, each column being one scenario :
31+
xi[t,k,:] is the alea at time t of scenario k.
3232
3333
- returnCosts (Bool)
3434
return the cost of each simulated scenario if true
@@ -47,12 +47,12 @@ Returns (according to the last parameters):
4747
If returnCosts=false, return nothing
4848
4949
- stocks (Array{float})
50-
the simulated stock trajectories. stocks(k,t,:) is the stock for
50+
the simulated stock trajectories. stocks(t,k,:) is the stock for
5151
scenario k at time t.
5252
5353
- controls (Array{Float64, 3})
54-
55-
54+
the simulated controls trajectories. controls(t,k,:) is the control for
55+
scenario k at time t.
5656
"""
5757
function forward_simulations(model::SPModel,
5858
param::SDDPparameters,
@@ -65,26 +65,28 @@ function forward_simulations(model::SPModel,
6565

6666
# TODO: verify that loops are in the same order
6767
T = model.stageNumber
68-
stocks = zeros(T, param.forwardPassNumber, model.dimStates)
68+
nb_forward = size(xi)[2]
69+
70+
stocks = zeros(T, nb_forward, model.dimStates)
6971
# We got T - 1 control, as terminal state is included into the total number
7072
# of stages.
71-
controls = zeros(T - 1, param.forwardPassNumber, model.dimControls)
73+
controls = zeros(T - 1, nb_forward, model.dimControls)
7274

7375
# Set first value of stocks equal to x0:
74-
for i in 1:param.forwardPassNumber
75-
stocks[1, i, :] = model.initialState
76+
for k in 1:nb_forward
77+
stocks[1, k, :] = model.initialState
7678
end
7779

7880
costs = nothing
7981
if returnCosts
80-
costs = zeros(param.forwardPassNumber)
82+
costs = zeros(nb_forward)
8183
end
8284

8385
for t=1:T-1
84-
for k = 1:param.forwardPassNumber
86+
for k = 1:nb_forward
8587

86-
state_t = extract_vector_from_3Dmatrix(stocks, k, t)
87-
alea_t = extract_vector_from_3Dmatrix(xi, k, t)
88+
state_t = extract_vector_from_3Dmatrix(stocks, t, k)
89+
alea_t = extract_vector_from_3Dmatrix(xi, t, k)
8890

8991
status, nextstep = solve_one_step_one_alea(
9092
model,
@@ -190,7 +192,7 @@ Parameters:
190192
Linear model used to approximate each value function
191193
192194
- stockTrajectories (Array{Float64,3})
193-
stockTrajectories[k,t,:] is the vector of stock where the cut is computed
195+
stockTrajectories[t,k,:] is the vector of stock where the cut is computed
194196
for scenario k and time t.
195197
196198
- law (Array{NoiseLaw})
@@ -218,21 +220,22 @@ function backward_pass!(model::SPModel,
218220
updateV=false)
219221

220222
T = model.stageNumber
221-
223+
nb_forward = size(stockTrajectories)[2]
224+
222225
# Estimation of initial cost:
223226
V0 = 0.
224227

225228
costs::Vector{Float64} = zeros(1)
226-
costs_npass = zeros(Float64, param.forwardPassNumber)
229+
costs_npass = zeros(Float64, nb_forward)
227230
state_t = zeros(Float64, model.dimStates)
228231

229232
for t = T-1:-1:1
230233
costs = zeros(law[t].supportSize)
231234

232-
for k = 1:param.forwardPassNumber
235+
for k = 1:nb_forward
233236

234237
subgradient_array = zeros(Float64, model.dimStates, law[t].supportSize)
235-
state_t = extract_vector_from_3Dmatrix(stockTrajectories, k, t)
238+
state_t = extract_vector_from_3Dmatrix(stockTrajectories, t, k)
236239

237240
for w in 1:law[t].supportSize
238241

src/utils.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ function extract_vector_from_3Dmatrix(input_array::Array{Float64, 3},
9696
ny::Int64)
9797

9898
state_dimension = size(input_array)[3]
99-
return reshape(input_array[ny, nx, :], state_dimension)
99+
return reshape(input_array[nx, ny, :], state_dimension)
100100
end
101101

102102

test/runtests.jl

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -45,9 +45,10 @@ end
4545
facts("Utils functions") do
4646
# Test extraction of vector in array:
4747
arr = rand(4, 4, 2)
48-
vec = StochDynamicProgramming.extract_vector_from_3Dmatrix(arr, 2, 1)
49-
@fact typeof(vec) --> Vector{Float64}
50-
@fact size(vec) --> (2,)
48+
v = StochDynamicProgramming.extract_vector_from_3Dmatrix(arr, 2, 1)
49+
@fact typeof(v) --> Vector{Float64}
50+
@fact size(v) --> (2,)
51+
@fact v --> vec(arr[2, 1,:])
5152

5253
# Test upper bound calculation:
5354
cost = rand(10)
@@ -108,7 +109,7 @@ facts("SDDP algorithm: 1D case") do
108109
cost,
109110
dynamic, laws)
110111
# Generate scenarios for forward simulations:
111-
aleas = simulate_scenarios(model.noises,
112+
noise_scenarios = simulate_scenarios(model.noises,
112113
(model.stageNumber,
113114
params.forwardPassNumber,
114115
model.dimNoises))
@@ -135,7 +136,7 @@ facts("SDDP algorithm: 1D case") do
135136
n_simulations)[1]
136137
@fact typeof(upb) --> Float64
137138

138-
sddp_costs, stocks = forward_simulations(model, params, V, pbs, aleas)
139+
sddp_costs, stocks = forward_simulations(model, params, V, pbs, noise_scenarios)
139140

140141
# Compare sddp cost with those given by extensive formulation:
141142
ef_cost = StochDynamicProgramming.extensive_formulation(model,params)
@@ -148,7 +149,7 @@ facts("SDDP algorithm: 1D case") do
148149
# Test hot start with previously computed value functions:
149150
V, pbs = solve_SDDP(model, params, 0, V)
150151
# Test if costs are roughly the same:
151-
sddp_costs2, stocks = forward_simulations(model, params, V, pbs, aleas)
152+
sddp_costs2, stocks = forward_simulations(model, params, V, pbs, noise_scenarios)
152153
@fact mean(sddp_costs) --> roughly(mean(sddp_costs2))
153154
end
154155

@@ -244,13 +245,12 @@ facts("SDDP algorithm: 2D case") do
244245

245246

246247
# Test a simulation upon given scenarios:
247-
params.forwardPassNumber = n_simulations
248-
aleas = simulate_scenarios(model.noises,
248+
noise_scenarios = simulate_scenarios(model.noises,
249249
(model.stageNumber,
250-
params.forwardPassNumber,
250+
n_simulations,
251251
model.dimNoises))
252252

253-
sddp_costs, stocks = forward_simulations(model, params, V, pbs, aleas)
253+
sddp_costs, stocks = forward_simulations(model, params, V, pbs, noise_scenarios)
254254

255255
# Compare sddp cost with those given by extensive formulation:
256256
ef_cost = StochDynamicProgramming.extensive_formulation(model,params)
@@ -495,4 +495,4 @@ facts("SDP algorithm") do
495495
@fact ((state_ref[1]<=state_neighbor[1])==(value_bar_ref[1]<=value_bar_neighbor[1])) --> true
496496
end
497497

498-
end
498+
end

0 commit comments

Comments
 (0)