Skip to content

Discount Rate Formulation

This chapter defines how discount rates are incorporated into the Novomodelo SDDP solver: the discounted Bellman equation, stage-dependent discount factors, effect on the future cost variable θ\theta, cumulative discounting, and the effect on lower/upper bound computation.

For the reserved cyclic-mode formulation (where discounting would be required for convergence), see Horizon Modes.

For notation conventions (index sets, parameters, decision variables, dual variables), see Notation Conventions.

The discount factor dt→t+1∈(0,1]d_{t \to t+1} \in (0, 1] captures the time value of money, where future costs are valued less than present costs. This is essential for:

  1. Infinite horizon problems: Ensuring convergence of the value function in cyclic (infinite-horizon) policy graphs, a reserved design (see Horizon Modes)
  2. Economic consistency: Reflecting opportunity cost of capital

The standard risk-neutral Bellman recursion with discount factor dt→t+1d_{t \to t+1} is:

Vt(xt−1)=Eωt[min⁡(xt,ut)∈Xt(xt−1,ωt){ct(xt,ut)+dt→t+1⋅Vt+1(xt)}]V_t(x_{t-1}) = \mathbb{E}_{\omega_t}\left[\min_{(x_t, u_t) \in \mathcal{X}_t(x_{t-1}, \omega_t)} \left\{ c_t(x_t, u_t) + d_{t \to t+1} \cdot V_{t+1}(x_t) \right\}\right]

where:

  • ct(xt,ut)c_t(x_t, u_t) is the immediate cost at stage tt
  • Vt+1(xt)V_{t+1}(x_t) is the future cost function (cost-to-go)
  • dt→t+1d_{t \to t+1} is the discount factor for the transition from stage tt to t+1t+1

Each stage tt has an annual rate rtr_t: the study’s global rate rannualr_{annual}, unless the stage declares its own rate. Δt\Delta t is the duration of stage tt in years, its whole number of days divided by 365.25.

dt→t+1=(1+rt)−Δtd_{t \to t+1} = (1 + r_t)^{-\Delta t}

The rate and the duration are those of the source stage tt, whose future cost the factor discounts. A zero rate gives dt→t+1=1d_{t \to t+1} = 1.

The rates are set for the study and, optionally, per stage; the Configure tab under Implementation in Novomodelo lists the fields.

The discount factor is applied to the future cost variable θ\theta in the stage tt objective, not to the cut coefficients:

Qt(xt−1,ωt)=min⁡xt,ut,θ{ct(xt,ut)+dt→t+1⋅θ}Q_t(x_{t-1}, \omega_t) = \min_{x_t, u_t, \theta} \left\{ c_t(x_t, u_t) + d_{t \to t+1} \cdot \theta \right\}

subject to all standard constraints (load balance, hydro balance, etc.) and Benders cuts:

θ≥β0,i+∑hβi,hv⋅vh+∑h,ℓβi,h,ℓlag⋅ah,ℓ∀i\theta \geq \beta_{0,i} + \sum_{h} \beta^v_{i,h} \cdot v_h + \sum_{h,\ell} \beta^{lag}_{i,h,\ell} \cdot a_{h,\ell} \quad \forall i

The cut coefficients (β0,i,βi,hv,βi,h,ℓlag)(\beta_{0,i}, \beta^v_{i,h}, \beta^{lag}_{i,h,\ell}) are the undiscounted values from the backward pass. When the study has in-transit water or anticipated thermals, the cut also carries terms on the in-transit buckets and the commitment-ring slots, undiscounted in the same way. Cuts are stored and managed in undiscounted form — the discount factor appears only in the objective coefficient of θ\theta. See Cut Management for cut generation and aggregation details.

The cumulative discount factor of stage tt carries a cost incurred at stage tt to its present value at stage 1:

d1→t=∏t′=1t−1dt′→t′+1,d1→1=1d_{1 \to t} = \prod_{t'=1}^{t-1} d_{t' \to t'+1}, \qquad d_{1 \to 1} = 1

The present value at stage 1 of a cost ctc_t incurred at stage tt is d1→t ctd_{1 \to t} \, c_t.

For stages t1≤t2t_1 \le t_2, the discount from stage t2t_2 back to stage t1t_1 is

dt1→t2=d1→t2/d1→t1d_{t_1 \to t_2} = d_{1 \to t_2} / d_{1 \to t_1}

In this arrow form, dt→t+1d_{t \to t+1} is the one-step factor of §3 and d1→td_{1 \to t} the cumulative factor. A cost incurred at stage t2t_2 and charged in the stage-t1t_1 objective is multiplied by dt1→t2d_{t_1 \to t_2}. An anticipated thermal’s commitment cost is charged at its decision stage and discounted from its delivery stage in this way (State Augmentation §5).

Past the last study stage TT, the cumulative factor continues over the declared post-study stages, at the global rate rannualr_{annual} on each post-study stage’s duration. The horizon is bridged by the last study stage’s one-step factor, d1→T+1=d1→T dT→T+1d_{1 \to T+1} = d_{1 \to T} \, d_{T \to T+1}, so the continuation equals the factor a horizon covering the post-study stages would give. Post-Study Boundary & Chained Studies prices deliveries past the horizon with this extended factor.

Each stage objective multiplies θ\theta by its one-step factor dt→t+1d_{t \to t+1} (§4), so a cost entered in the stage-tt objective reaches stage 1 multiplied by d1→td_{1 \to t} exactly once. A cost charged at stage t1t_1 for stage t2t_2 reaches stage 1 multiplied by d1→t1 dt1→t2=d1→t2d_{1 \to t_1} \, d_{t_1 \to t_2} = d_{1 \to t_2}, the cumulative factor of the stage t2t_2 at which it is incurred. Charging it with d1→t2d_{1 \to t_2} in the stage-t1t_1 objective would discount it twice: it would reach stage 1 multiplied by d1→t1 d1→t2d_{1 \to t_1} \, d_{1 \to t_2}.

The lower bound z‾k\underline{z}^k at iteration kk is the first stage’s risk-adjusted value over its openings at the initial state x0x_0 (Upper Bound Evaluation — Lower bound). In each opening’s first-stage problem the future cost variable θ1\theta_1 enters the objective with the one-step factor d1→2d_{1 \to 2}, and each later stage’s factor carries its cost to stage 1 once (§4), so the lower bound is stated in stage 1 present value.

7 Upper Bound (Simulation) with Discounting

Section titled “7 Upper Bound (Simulation) with Discounting”

When simulating the policy to estimate the upper bound:

zˉk=1M∑m=1M∑t=1Td1→t⋅ct(x^tk,m)\bar{z}^k = \frac{1}{M} \sum_{m=1}^{M} \sum_{t=1}^{T} d_{1 \to t} \cdot c_t(\hat{x}_t^{k,m})

Each stage’s immediate cost is explicitly discounted to stage 1 present value using the cumulative discount factor.

For stopping rules that use these bounds, see Stopping Rules.

Both the lower bound z‾\underline{z} and upper bound zˉ\bar{z} represent total expected cost expressed in present value at stage 1:

  • A cost ctc_t incurred at stage tt enters both bounds as d1→t ctd_{1 \to t}\, c_t
  • Comparisons between bounds and between iterations are valid because they use consistent discounting
  • The simulation output records each stage’s immediate cost in that stage’s own monetary units (not discounted to stage 1) together with its cumulative factor d1→td_{1 \to t} (Simulation Output)

The methodology above defines the stage discount factor and the cumulative discount; the tab below covers how Novomodelo’s software surface configures the rates.

Novomodelo reads the discount rates from stages.json: the global rate on the policy_graph object and, optionally, a rate per stage. The factors the rates produce are defined in §3 Stage Discount Factor and §5 Cumulative Discounting above. The full file reference is stages.json.

FieldTypeRequiredDescription
policy_graph.annual_discount_ratenumberYesThe global annual rate, >= 0.0; a negative value is rejected at load. It is the rate of every stage without its own rate and of every post-study stage.
stages[].annual_discount_rate_overridenumber or nullNoThe stage’s own annual rate; an absent or null value uses the global rate.
policy_graph.transitions[].annual_discount_rate_overridenumber or nullNoStage-chain dialect only (no policy_graph.nodes[]): the rate folds onto the edge’s source stage, and the stage field wins when both are set. Under policy_graph.nodes[] it is rejected with an InvalidValue error that points to the stage field.

The global rate is a required key of the policy_graph object (excerpt of stages.json):

{
"policy_graph": {
"type": "finite_horizon",
"annual_discount_rate": 0.06,
"transitions": [
{ "source_id": 0, "target_id": 1, "probability": 1.0 },
{ "source_id": 1, "target_id": 2, "probability": 1.0 }
]
}
}

The canonical spelling of a per-stage rate is the stage’s own key. In this stages excerpt, stage 1 takes the annual rate 0.1 in place of the global rate:

{
"stages": [
{
"id": 1,
"start_date": "2024-02-01",
"end_date": "2024-03-01",
"blocks": [{ "id": 0, "name": "SINGLE", "hours": 696 }],
"num_openings": 10,
"annual_discount_rate_override": 0.1
}
]
}

As an alternative to the stage key, a policy_graph.transitions entry in the stage-chain dialect may carry the same rate for the stage it leaves; this entry gives stage 1 the rate 0.1:

{
"source_id": 1,
"target_id": 2,
"probability": 1.0,
"annual_discount_rate_override": 0.1
}

A rate of 0.0 means no discounting for the stages it governs; the post-study stages of post_study_stages.json declare no rate and use the global rate.

  • SDDP Algorithm — Core Bellman equation and forward/backward pass structure that discount rates modify
  • Cut Management — Cut coefficients remain undiscounted; discount applied to θ\theta in objective
  • Stopping Rules — Convergence criteria using discounted lower/upper bounds
  • Upper Bound Evaluation — Inner approximation uses discounted vertex values
  • Horizon Modes — Finite (supported) vs. reserved cyclic policy graphs; the reserved cyclic-mode formal structure (season function, cycle convergence inequality, season-indexed cut pool, fixed-point Bellman operator)
  • Notation Conventions — Index sets, parameters, decision variables, and dual variables used throughout