Is time in continuous ABM model is really continuous?

Hello. everyone ,

I’m working with eventbasedmodel for continuous time. Initially i thought in case of continuous time unlike standard ABM time step doesn’t goes like 0, 1,2, 3, 4, 5…but something like 0.0, 0.1, 0.2, 0.3, 0.4…5.0 if dt is 0.1. But I dont think thats the case. It feels continuous time model also just follow same steps but just add dt to the step which seems really weird as I dont understand the point here ?

It will be really helpful if someone can clear this up. Thank you :slight_smile:

Below is time output for my model. dt = 0.01, steps = 60, agent_timing = 0.1

60×1 DataFrame
 Row │ time    
     │ Float64 
─────┼─────────
   1 │    0.0
   2 │    1.0
   3 │    2.0
   4 │    3.01
   5 │    4.02
   6 │    5.03
   7 │    6.04
   8 │    7.05
   9 │    8.06
  10 │    9.07
  11 │   10.08
  12 │   11.09
  13 │   12.1
  14 │   13.11
  15 │   14.12
  16 │   15.13
  17 │   16.13
  18 │   17.13
  19 │   18.13
  20 │   19.13
  21 │   20.13
  22 │   21.13
  23 │   22.13
  24 │   23.13
  25 │   24.13
  26 │   25.13
  27 │   26.13
  28 │   27.13
  29 │   28.13
  30 │   29.13
  31 │   30.13
  32 │   31.13
  33 │   32.13
  34 │   33.14
  35 │   34.15
  36 │   35.16
  37 │   36.17
  38 │   37.18
  39 │   38.19
  40 │   39.2
  41 │   40.21
  42 │   41.22
  43 │   42.23
  44 │   43.24
  45 │   44.25
  46 │   45.26
  47 │   46.27
  48 │   47.28
  49 │   48.29
  50 │   49.3
  51 │   50.31
  52 │   51.32
  53 │   52.33
  54 │   53.34
  55 │   54.35
  56 │   55.36
  57 │   56.37
  58 │   57.38
  59 │   58.39
  60 │   59.4

I also tried run!(....... when = 0.1, dt = 0.1) which does the job I guess but still there are irregularities. eg - timepoint 0.6 …0.8…2.0 etc. are missing .

535×1 DataFrame
 Row │ time    
     │ Float64 
─────┼─────────
   1 │     0.0
   2 │     0.1
   3 │     0.2
   4 │     0.3
   5 │     0.5
   6 │     0.7
   7 │     0.9
   8 │     1.1
   9 │     1.2
  10 │     1.3
  11 │     1.4
  12 │     1.5
  13 │     1.6
  14 │     1.7
  15 │     1.8
  16 │     1.9
  17 │     2.1
  18 │     2.2
  19 │     2.3
  20 │     2.4
  21 │     2.5
  22 │     2.6
  23 │     2.7
  24 │     2.8
  25 │     2.9
  26 │     3.0
  27 │     3.1
  28 │     3.2
  29 │     3.3
  30 │     3.4
  31 │     3.5
  32 │     3.6
  33 │     3.7
  34 │     3.8
  ⋮  │    ⋮
 502 │    56.7
 503 │    56.8
 504 │    56.9
 505 │    57.0
 506 │    57.1
 507 │    57.2
 508 │    57.3
 509 │    57.4
 510 │    57.5
 511 │    57.6
 512 │    57.7
 513 │    57.8
 514 │    57.9
 515 │    58.0
 516 │    58.1
 517 │    58.2
 518 │    58.3
 519 │    58.4
 520 │    58.5
 521 │    58.6
 522 │    58.7
 523 │    58.8
 524 │    58.9
 525 │    59.0
 526 │    59.1
 527 │    59.2
 528 │    59.3
 529 │    59.4
 530 │    59.5
 531 │    59.6
 532 │    59.7
 533 │    59.8
 534 │    59.9
 535 │    60.0
467 rows omitted

There are two bits happening at the same time here.

As you can see in the documentation, the relevant part is the when keyword argument:
API · Agents.jl! This determines ‘when’ the solution is actually stored. This allows you to compute the simulation with much smaller timesteps dt but to save storage since storing all time-steps could become too memory-consuming in some cases.

If you change when = 0.0 or when = (model, t) -> true, you should get all the time steps that were actually used.

Regarding the question of whether this is continuous in time. It is very common that continuous in-time models are discretized in a way that formally yields a discrete-time model. It’s the same for ordinary differential equations. If you need to know the value between two time-steps you might use interpolation. In practice, this is not really an issue. But you are, of course, right that this is kind-off is a discrete system where the time is multiplied by dt. :wink:


The second small comment: The floating point representation of 0.1 is not exactly 0.1 since it does not have a finite representation in base 2 (binary). Therefore, if you add 0.1 a few times, it might lead to tiny round-off errors, which cause the behavior that the solution is stored at 3.01 instead of 3.0.

1 Like