Skip to content

SMM Model output is misaligned with time points #1496

@kilianvolmer

Description

@kilianvolmer

Bug description

The advance function of the SMM model operates directly on the last values (m_result.get_last_values()). These values, however, are aligned with the time point when they were first created, leading to changes being accounted to earlier time points than they actually happen.

Additionally, at the end of the simulation, the last state is copied into a new last state for tmax giving the impression that nothing changed between the last stored time point and tmax, which is not generally true.

To be more precise: Let $t_e$ be the time of the first event, $t_0, t_\max$ as usual and $dt > t_\max - t_0$. Then we will have three output times and state vectors: $t_0$ with the initial state, $t_e$ with the last state (because it is created at $t_e$ and then all subsequent changes are directly done on it, and $t_\max$ with the last state again.

Version

Any

To reproduce

Use the following file as smm.cpp:

/*
* Copyright (C) 2020-2026 MEmilio
*
* Authors: Julia Bicker, René Schmieding, Kilian Volmer
*
* Contact: Martin J. Kuehn <Martin.Kuehn@DLR.de>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
*     http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#include "memilio/config.h"
#include "memilio/epidemiology/age_group.h"
#include "smm/simulation.h"
#include "smm/model.h"
#include "smm/parameters.h"
#include "memilio/data/analyze_result.h"

enum class InfectionState
{
    S,
    E,
    C,
    I,
    R,
    D,
    Count
};

struct Species : public mio::Index<Species> {
    Species(size_t val)
        : Index<Species>(val)
    {
    }
};

int main()
{
    using Age    = mio::AgeGroup;
    using Status = mio::Index<InfectionState, Age, Species>;
    using mio::regions::Region;
    using enum InfectionState;

    /* Example how to run the stochastic metapopulation models with four regions. Within each region we differentiate by
       age groups, species and infection states. The infection states are S, E, C, I, R, D. For the number of age groups
       and species we choose: */
    const size_t num_regions    = 1;
    const size_t num_age_groups = 1;
    const size_t num_species    = 1;
    using Model                 = mio::smm::Model<ScalarType, InfectionState, Status, Region>;

    ScalarType numE = 100, numC = 40, numI = 100, numR = 0, numD = 0;

    Model model(Status{Count, Age(num_age_groups), Species(num_species)}, Region(num_regions));
    //Population are distributed uniformly to the four regions
    for (size_t r = 0; r < num_regions; ++r) {
        model.populations[{Region(r), S, Age(0), Species(0)}] =
            (10000 - numE - numC - numI - numR - numD) / num_regions;
        model.populations[{Region(r), E, Age(0), Species(0)}] = numE / num_regions;
        model.populations[{Region(r), C, Age(0), Species(0)}] = numC / num_regions;
        model.populations[{Region(r), I, Age(0), Species(0)}] = numI / num_regions;
        model.populations[{Region(r), R, Age(0), Species(0)}] = numR / num_regions;
        model.populations[{Region(r), D, Age(0), Species(0)}] = numD / num_regions;
    }

    using AR = mio::smm::AdoptionRates<ScalarType, Status, Region>;

    //Set infection state adoption rates. Adoptions only happen within a region.
    AR::Type adoption_rates;
    for (size_t r = 0; r < num_regions; ++r) {
        adoption_rates.push_back({{S, Age(0), Species(0)},
                                  {E, Age(0), Species(0)},
                                  Region(r),
                                  0.1,
                                  {{{C, Age(0), Species(0)}, 1}, {{I, Age(0), Species(0)}, 0.5}}});
        adoption_rates.push_back({{C, Age(0), Species(0)}, {R, Age(0), Species(0)}, Region(r), 0.2 / 3., {}});
        adoption_rates.push_back({{E, Age(0), Species(0)}, {C, Age(0), Species(0)}, Region(r), 1.0 / 5., {}});
        adoption_rates.push_back({{C, Age(0), Species(0)}, {I, Age(0), Species(0)}, Region(r), 0.8 / 3., {}});
        adoption_rates.push_back({{I, Age(0), Species(0)}, {R, Age(0), Species(0)}, Region(r), 0.99 / 5., {}});
        adoption_rates.push_back({{I, Age(0), Species(0)}, {D, Age(0), Species(0)}, Region(r), 0.01 / 5., {}});
    }

    model.parameters.get<AR>() = adoption_rates;

    ScalarType dt   = 1.0;
    ScalarType tmax = 2.0;

    auto sim = mio::smm::Simulation(model, 0.0, dt);
    sim.advance(tmax);

    // auto interpolated_results = mio::interpolate_simulation_result(sim.get_result());
    sim.get_result().print_table({"S", "E", "C", "I", "R", "D "});
}

and add the following line to smm/simulation.h:103:
mio::log_info("Time: {}, Event: {}", current_time, next_event);

Relevant log output

memilio/cpp/build$ ./bin/smm_example 
[2026-02-24 18:43:53.395] [info] Time: 4.6098857853520016e-05, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 0.013114737526979224, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.02822700956364611, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 0.06522404465292476, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.07621089557219274, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.09153176956553341, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.11622322734887447, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.13786714686636078, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.158567079151411, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.16753622427461495, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.16924187749671582, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.1759530535510909, Event: 0
[2026-02-24 18:43:53.395] [info] Time: 0.1778026542603898, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.18325998925889236, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.18489859156001798, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.19198282803511976, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.20962422795384378, Event: 0
[2026-02-24 18:43:53.395] [info] Time: 0.2120644297611682, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.22073354934691136, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.22122234137813074, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 0.25738034716780905, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.2601026575594206, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.26190500670360195, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 0.2619368978088259, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.2710151383492625, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.27247910989833907, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.28271921288182794, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.28736722017381, Event: 1
[2026-02-24 18:43:53.395] [info] Time: 0.3156412077898553, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 0.3193465802665762, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.3220146916075397, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.32762064555442044, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.3300799258728723, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.3302014648760544, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.33821343934365283, Event: 1
[2026-02-24 18:43:53.395] [info] Time: 0.3419303453284519, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.3441457477253259, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.3448235203194033, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.35770172029216274, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 0.3618931910366481, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.38720872799205097, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 0.38782265286681816, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.399410784324946, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.43366481830383485, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 0.43846866004522467, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.465448826199623, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.4689343840258804, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 0.48021930723734396, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.4924735134617665, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 0.5128992898673137, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.5487500406743524, Event: 0
[2026-02-24 18:43:53.395] [info] Time: 0.5835933573214551, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 0.5999460113141136, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.6193698200439834, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.6337577843646659, Event: 1
[2026-02-24 18:43:53.395] [info] Time: 0.6414737139620401, Event: 1
[2026-02-24 18:43:53.395] [info] Time: 0.68747042267237, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.6969075750683437, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 0.703690321762835, Event: 1
[2026-02-24 18:43:53.395] [info] Time: 0.7149818736089968, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.7350421806121711, Event: 1
[2026-02-24 18:43:53.395] [info] Time: 0.7363918457622716, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.7533400187526819, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.8031805282318634, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.8303839751296711, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.8372255986474588, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 0.8439029950520883, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 0.9031965107718831, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 0.967128879754877, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.9744140214518046, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 0.9752070352426253, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 0.9766024163060892, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.0030143348079155, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 1.0074190513213697, Event: 0
[2026-02-24 18:43:53.395] [info] Time: 1.019091793006389, Event: 0
[2026-02-24 18:43:53.395] [info] Time: 1.0268816671944088, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 1.0381007953649894, Event: 0
[2026-02-24 18:43:53.395] [info] Time: 1.0696914981101584, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.0891961160468149, Event: 0
[2026-02-24 18:43:53.395] [info] Time: 1.0933022726168729, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.1016084000363964, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.1168025772714918, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 1.119751894739845, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 1.1244950474462698, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 1.124963055905289, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.140776921882378, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.154548697512311, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 1.197267968334036, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 1.212087348393622, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 1.2188918928666428, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 1.3027757555242405, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 1.307817889037045, Event: 0
[2026-02-24 18:43:53.395] [info] Time: 1.329593892704922, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.3364251289654216, Event: 0
[2026-02-24 18:43:53.395] [info] Time: 1.3494258349556854, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 1.372177167554798, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.387354999175714, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.3989643027397358, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 1.4020566528094562, Event: 1
[2026-02-24 18:43:53.395] [info] Time: 1.4226639129884653, Event: 0
[2026-02-24 18:43:53.395] [info] Time: 1.4451242157642061, Event: 1
[2026-02-24 18:43:53.395] [info] Time: 1.4459356276679836, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.4473062888881674, Event: 0
[2026-02-24 18:43:53.395] [info] Time: 1.4783499698133231, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 1.478394478515484, Event: 0
[2026-02-24 18:43:53.395] [info] Time: 1.4864100592417357, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.4888681469642409, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.5011828481987595, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.503735616037313, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.510767268345772, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 1.5114151803361247, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 1.5122867151598105, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 1.5313755904231587, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.5531464636815373, Event: 0
[2026-02-24 18:43:53.395] [info] Time: 1.5850909302598244, Event: 0
[2026-02-24 18:43:53.395] [info] Time: 1.5876042898581593, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.596094472574478, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 1.6092405223385369, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 1.6282075978159234, Event: 0
[2026-02-24 18:43:53.395] [info] Time: 1.6343078129608164, Event: 1
[2026-02-24 18:43:53.395] [info] Time: 1.6457405968198737, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 1.6469954460845986, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 1.677193671927801, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 1.6902916752694703, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 1.6920025655638231, Event: 0
[2026-02-24 18:43:53.395] [info] Time: 1.708567308912416, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 1.7256669989501265, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 1.7788570974527085, Event: 0
[2026-02-24 18:43:53.395] [info] Time: 1.7798116993633246, Event: 3
[2026-02-24 18:43:53.395] [info] Time: 1.7855123601275384, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 1.790312056315613, Event: 1
[2026-02-24 18:43:53.395] [info] Time: 1.7963900413899911, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.8041211101820063, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 1.833940363652369, Event: 0
[2026-02-24 18:43:53.395] [info] Time: 1.8349088198812447, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.8708617513973662, Event: 0
[2026-02-24 18:43:53.395] [info] Time: 1.886229261964354, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.896141173573215, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.9380729573623927, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.9477029981500664, Event: 2
[2026-02-24 18:43:53.395] [info] Time: 1.957747965258782, Event: 4
[2026-02-24 18:43:53.395] [info] Time: 1.9692600373165199, Event: 0

Time             S                E                C                I                R                D               
         0.00000       9760.00000        100.00000         40.00000        100.00000          0.00000          0.00000
         0.00005       9757.00000         78.00000         44.00000         92.00000         29.00000          0.00000
         1.00301       9740.00000         74.00000         47.00000         92.00000         47.00000          0.00000
         2.00000       9740.00000         74.00000         47.00000         92.00000         47.00000          0.00000

Add any relevant information, e.g. used compiler, screenshots.

Checklist

  • Attached labels, especially loc:: or model:: labels.
  • Linked to project

Metadata

Metadata

Assignees

No one assigned

    Labels

    class::bugBugs found in the softwareprio::criticalThe priority of this task is very high. This issue is critical for continuation.

    Type

    Projects

    Status

    ✅ Done (Sprint)

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions