Skip to content

TimeProfile addition/subtraction #91

Description

@Zetison

Can support for addition and subtraction for TimeProfile's be added?

One could implement this by

+(a::FixedProfile{T}, b::FixedProfile{T}) where {T} = FixedProfile(a.val + b.val)
function +(a::OperationalProfile{T}, b::OperationalProfile{T}) where {T}
    return OperationalProfile(a.vals .+ b.vals)
end
function +(a::StrategicProfile{T}, b::StrategicProfile{T}) where {T}
    return StrategicProfile(a.vals .+ b.vals)
end
function +(a::ScenarioProfile{T}, b::ScenarioProfile{T}) where {T}
    return ScenarioProfile(a.vals .+ b.vals)
end
function +(a::RepresentativeProfile{T}, b::RepresentativeProfile{T}) where {T}
    return RepresentativeProfile(a.vals .+ b.vals)
end

-(a::TimeProfile{T}, b::TimeProfile{T}) where {T} = a + (-b)

or one could implement length(::TimeProfile) and iterate(::TimeProfile) with the .+ and .- convention.

Activity

  1. JulStraus commented on Mar 23, 2026

    @JulStraus
    Collaborator

    The proposed approach would work at least the way I see it. What are your thoughts @trulsf ? I do not see any issue with incorporating these, except for cases in which the profiles have different lengths.

    In this case, we would need to have also @assert to check that the profiles have the same length. The error message for different length is:

    prof_1 = OperationalProfile([1, 2, 3])
    prof_2 = OperationalProfile([1, 2, 3, 6])
    
    prof_1 + prof_2
    
    ERROR: DimensionMismatch: arrays could not be broadcast to a common size: a has axes Base.OneTo(3) and b has axes Base.OneTo(4)

    Do we consider the error message to be sufficiently descriptive?

  2. trulsf commented on Mar 24, 2026

    @trulsf
    Member

    I have also felt had the need for this quite recently, so maybe there is a need to add it.

    For me the logical behavior is to ensure that

    (prof1 + prof2)[t] == prof1[t] + prof2[t]

    With the current practice of handling too short operational profiles by repeating the last entry, we need to consider this also when adding, e.g. we should have

    OperationalProfile([1, 2, 3]) + OperationalProfile([1, 2, 3, 6]) == OperationalProfile([2, 3, 6, 9])
    

    We should also think through whether we should support combinations of profiles like OperationalProfile + FixedProfile.

    There may also be some challenges if presented with more complex profiles on a strategic, scenario or representative level, e.g.

    op = OperationalProfile([1, 2, 3])
    rp = RepresentativeProfile([op, op])
    sp1 = StrategicProfile([rp, op])
    sp2 = StrategicProfile([op, op])
    sp1 + sp2

    The suggested implementation would generate a MethodError, but it is possible to imagine ways to define this by adding the OperationalProfile to each of the profiles of the RepresentativeProfile

  3. JulStraus commented on Mar 24, 2026

    @JulStraus
    Collaborator

    With the current practice of handling too short operational profiles by repeating the last entry, we need to consider this also when adding, e.g. we should have

    I am more inclined to remove this and instead provide an error if the profile is too short for the time structure. The current approach can, especially in the case of OperationalProfile, lead to potential problems if people are not aware of this behavior.

  4. trulsf commented on Mar 26, 2026

    @trulsf
    Member

    I have opened a PR with changes in line with the one proposed here. @Zetison Please join the discussion there if you have suggestions for improvement.

  5. trulsf commented on Apr 13, 2026

    @trulsf
    Member

    PR is now merged (#92 ).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions