@@ -117,17 +117,18 @@ function f!(du, u, p, t)
117117end
118118
119119function hawkes_problem(
120- p,
121- agg;
122- u = [0.0],
123- tspan = (0.0, 50.0),
124- save_positions = (false, true),
125- g = [[1]],
126- use_recursion = false
120+ p,
121+ agg;
122+ vr_agg = VR_FRM(),
123+ u = [0.0],
124+ tspan = (0.0, 50.0),
125+ save_positions = (false, true),
126+ g = [[1]],
127+ use_recursion = false,
127128)
128129 oprob = ODEProblem(f!, u, tspan, p)
129130 jumps = hawkes_jump(u, g; use_recursion)
130- jprob = JumpProblem(oprob, agg, jumps...; save_positions = save_positions)
131+ jprob = JumpProblem(oprob, agg, jumps...; vr_aggregator = vr_agg, save_positions = save_positions)
131132 return jprob
132133end
133134```
@@ -845,6 +846,100 @@ let fig = plot(
845846end
846847```
847848
849+ # Benchmarking Variable Rate Aggregators
850+
851+ We benchmark the variable rate aggregators (`VR_Direct`, `VR_DirectFW`, `VR_FRM`) for the Multivariate Hawkes process, using the same setup as above: networks from `1` to `50` nodes, `tspan=(0.0, 25.0)`, `\lambda=0.5`, `\alpha=0.1`, `\beta=5.0`, and 50 trajectories with a 10-second limit per configuration. We test both recursive and brute-force formulations.
852+
853+ ```julia
854+ vr_aggs = [
855+ (VR_Direct(), Tsit5(), false, "VR_Direct (brute-force)"),
856+ (VR_DirectFW(), Tsit5(), false, "VR_DirectFW (brute-force)"),
857+ (VR_FRM(), Tsit5(), false, "VR_FRM (brute-force)"),
858+ (VR_Direct(), Tsit5(), true, "VR_Direct (recursive)"),
859+ (VR_DirectFW(), Tsit5(), true, "VR_DirectFW (recursive)"),
860+ (VR_FRM(), Tsit5(), true, "VR_FRM (recursive)"),
861+ ]
862+
863+ tspan = (0.0, 25.0)
864+ p = (0.5, 0.1, 5.0)
865+ Vs = append!([1], 5:5:95)
866+ Gs = [erdos_renyi(V, 0.2, seed = 6221) for V in Vs]
867+
868+ vr_bs = Vector{Vector{BenchmarkTools.Trial}}()
869+
870+ for (vr_agg, stepper, use_recursion, label) in vr_aggs
871+ @info label
872+ global _stepper = stepper
873+ push!(vr_bs, Vector{BenchmarkTools.Trial}())
874+ _vr_bs = vr_bs[end]
875+ for (i, G) in enumerate(Gs)
876+ local g = [neighbors(G, i) for i in 1:nv(G)]
877+ local u = [0.0 for i in 1:nv(G)]
878+ if use_recursion
879+ global h = zeros(eltype(tspan), nv(G))
880+ global urate = zeros(eltype(u), nv(G))
881+ global ϕ = zeros(eltype(tspan), nv(G))
882+ _p = (p[1], p[2], p[3], h, urate, ϕ)
883+ else
884+ global h = [eltype(tspan)[] for _ in 1:nv(G)]
885+ global urate = zeros(eltype(u), nv(G))
886+ _p = (p[1], p[2], p[3], h, urate)
887+ end
888+ global jump_prob = hawkes_problem(_p, Direct(); vr_agg, u, tspan, g, use_recursion)
889+ trial = try
890+ if use_recursion
891+ @benchmark(
892+ solve(jump_prob, _stepper),
893+ setup = (h .= 0; urate .= 0; ϕ .= 0),
894+ samples = 50,
895+ evals = 1,
896+ seconds = 10,
897+ )
898+ else
899+ @benchmark(
900+ solve(jump_prob, _stepper),
901+ setup = ([empty!(_h) for _h in h]; urate .= 0),
902+ samples = 50,
903+ evals = 1,
904+ seconds = 10,
905+ )
906+ end
907+ catch e
908+ BenchmarkTools.Trial(
909+ BenchmarkTools.Parameters(samples=50, evals=1, seconds=10),
910+ )
911+ end
912+ push!(_vr_bs, trial)
913+ if (nv(G) == 1 || nv(G) % 10 == 0)
914+ median_time =
915+ length(trial) > 0 ? "$(BenchmarkTools.prettytime(median(trial.times)))" : "nan"
916+ println("algo=$label, V=$(nv(G)), length=$(length(trial.times)), median time=$median_time")
917+ end
918+ end
919+ end
920+ ```
921+
922+ ```julia
923+ let fig = plot(
924+ yscale = :log10,
925+ xlabel = "V",
926+ ylabel = "Time (ns)",
927+ legend_position = :outertopright,
928+ )
929+ for (i, (vr_agg, _, use_recursion, label)) in enumerate(vr_aggs)
930+ _bs, _Vs = [], []
931+ for (j, b) in enumerate(vr_bs[i])
932+ if length(b) == 50
933+ push!(_bs, median(b.times))
934+ push!(_Vs, Vs[j])
935+ end
936+ end
937+ plot!(_Vs, _bs, label=label)
938+ end
939+ title!("Variable Rate Simulations, 50 samples: nodes × time")
940+ end
941+ ```
942+
848943# References
849944
850945[1] D. J. Daley and D. Vere-Jones. An Introduction to the Theory of Point Processes: Volume I: Elementary Theory and Methods. Probability and Its Applications, An Introduction to the Theory of Point Processes. Springer-Verlag, 2 edition. doi:10.1007/b97277.
0 commit comments