Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
55 changes: 35 additions & 20 deletions src/discount.jl
Original file line number Diff line number Diff line change
Expand Up @@ -56,9 +56,13 @@ end

Calculates the discount factor to be used for a time period `t`
using a fixed 'discount_rate`. There are two types of discounting
available, either discounting to the start of the time period
or calculating an approximate value for the average discount factor
over the whole time period (`type="avg"`).
available, either discounting to the start of the strategic period
containing the time period (`type="start"`) or calculating an approximate
value for the average discount factor over the whole strategic period.
The average can be calculated either as a continuous average (`type="avg"`) or
as a discrete average that discounts to the start of each year (`type="avg_year"`).
The `timeunit_to_year` parameter is used to convert the time units of
strategic periods in the time structure to years (default value = 1.0).
"""
function discount(
t::TimePeriod,
Expand All @@ -77,15 +81,14 @@ function discount(disc::Discounter, t::TimePeriod; type = "start", timeunit_to_y
end

function discount_avg(discount_rate, start_year, duration_years)
if discount_rate > 0
δ = 1 / (1 + discount_rate)
m =
(δ^start_year - δ^(start_year + duration_years)) / log(1 + discount_rate) /
duration_years
return m
else
return 1.0
end
δ = 1 / (1 + discount_rate)
return (δ^start_year - δ^(start_year + duration_years)) / log(1 + discount_rate) /
duration_years
end

function discount_avg_year(discount_rate, start_year, duration_years)
δ = 1 / (1 + discount_rate)
return sum(δ^(start_year + i) for i in 0:(duration_years-1)) / duration_years
end

function discount_start(discount_rate, start_year)
Expand All @@ -100,22 +103,34 @@ function discount(
type = "start",
timeunit_to_year = 1.0,
)
start_year = _to_year(_start_strat(sp, ts), timeunit_to_year)
duration_years = _to_year(duration_strat(sp), timeunit_to_year)

if type == "start"
return discount_start(discount_rate, start_year)
elseif type == "avg"
return discount_avg(discount_rate, start_year, duration_years)
discount_factor = 1.0
if discount_rate > 0
start_year = _to_year(_start_strat(sp, ts), timeunit_to_year)
duration_years = _to_year(duration_strat(sp), timeunit_to_year)
if type == "start"
discount_factor = discount_start(discount_rate, start_year)
elseif type == "avg"
discount_factor = discount_avg(discount_rate, start_year, duration_years)
elseif type == "avg_year"
discount_factor = discount_avg_year(discount_rate, start_year, duration_years)
end
end
return discount_factor
end

"""
objective_weight(t, time_struct, discount_rate; type, timeunit_to_year)

Returns an overall weight to be used for a time period `t`
in the objective function considering both discounting,
probability and possible multiplicity.
probability and possible multiplicity. There are two types of discounting
available, either discounting to the start of the strategic period
containing the time period (`type="start"`) or calculating an approximate
value for the average discount factor over the whole strategic period.
The average can be calculated either as a continuous average (`type="avg"`) or
as a discrete average that discounts to the start of each year (`type="avg_year"`).
The `timeunit_to_year` parameter is used to convert the time units of
strategic periods in the time structure to years (default value = 1.0).
"""
function objective_weight(
t::TimePeriod,
Expand Down
21 changes: 18 additions & 3 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1335,15 +1335,30 @@ end
@test discount(disc, t) == δ^(i - 1)
end

@test sum(
discount(sp, uniform_years, 0.06; type = "avg_year") for
sp in strat_periods(uniform_years)
) ≈ 7.8017 atol = 1e-3

@test sum(objective_weight(t, disc) for t in uniform_years) ≈ 8.435 atol = 1e-3

uniform_day = SimpleTimes(24, 1)
periods = TwoLevel(10, 8760, uniform_day)
periods = TwoLevel(10, 5 * 8760, uniform_day)

@test sum(
objective_weight(sp, periods, 0.04; timeunit_to_year = 1 / 8760, type = "start") for
sp in strat_periods(periods)
) ≈ 4.825 atol = 1e-3

@test sum(
objective_weight(sp, periods, 0.04; timeunit_to_year = 1 / 8760, type = "avg_year")
for sp in strat_periods(periods)
) ≈ 4.468 atol = 1e-3

@test sum(
objective_weight(sp, periods, 0.04; timeunit_to_year = 1 / 8760) for
objective_weight(sp, periods, 0.04; timeunit_to_year = 1 / 8760, type = "avg") for
sp in strat_periods(periods)
) ≈ 8.435 atol = 1e-3
) ≈ 4.382 atol = 1e-3

uniform_day = SimpleTimes(24, 1u"hr")
periods_unit = TwoLevel(10, 365.125u"d", uniform_day)
Expand Down