LongMemory.jl: Generating, Estimating, and Forecasting Long Memory Models in Julia

Benchmarks

Abstract

LongMemory.jl is a package for time series long memory modelling in Julia. The package provides functions for generating long memory, estimating the parameters of the models, and simulation. Generating methods include fractional differencing, stochastic error duration, and cross-sectional aggregation. Estimators include those inspired by the log-periodogram regression and parametric ones. This notebook provides benchmarks for the LongMemory.jl package including against current alternatives. The package is closely related to the R packages LongMemoryTS and fracdiff.

Citation

If you use this package in your research, please cite it as:

Vera-Valdés, J.E. (2024). “LongMemory.jl: Generating, Estimating, and Forecasting Long Memory Models in Julia”. arXiv 2401.14077. https://arxiv.org/abs/2401.14077

@article{VERAVALDES2024a,
title = {LongMemory.jl: Generating, Estimating, and Forecasting Long Memory Models in Julia},
year = {2024},
author = {Vera-Valdés, J.E.},
journal = {arXiv preprint arXiv:2401.14077},
url = {https://arxiv.org/abs/2401.14077}
}

Loading packages

Loading the package and setting a seed

using LongMemory, BenchmarkTools, RCall, Random
Random.seed!(1234)
TaskLocalRNG()

Long memory generation

The fi_gen() function, which uses the cumulative method.

@benchmark fi_gen(10000, 0.2)
BenchmarkTools.Trial: 6135 samples with 1 evaluation.
 Range (minmax):  548.300 μs  8.784 ms   GC (min … max): 0.00% … 84.61%
 Time  (median):     609.200 μs                GC (median):    0.00%
 Time  (mean ± σ):   809.529 μs ± 445.738 μs   GC (mean ± σ):  6.60% ±  9.47%
  ▆█▄▃▂▂▁▁    ▁▁▁▂▃▂▂ ▁▁▁ ▁                                   ▁
  ████████▇█████████████████▇▆▇▇▅▅▆▅▄▄▅▅▅▅▄▆▇▇▇█▇▇▇▆▇▆▇▆▆▇▄▆▅ █
  548 μs        Histogram: log(frequency) by time       2.33 ms <
 Memory estimate: 2.58 MiB, allocs estimate: 44.

R: benchmarking the fracdiff.sim() function.

Loading the R packages. The R package fracdiff is used for fractional differencing generation using fracdiff::fracdiff.sim(). Benchmarking the fractional differencing generation by the R package fracdiff using RCall.

R"library(fracdiff)"
@benchmark R"fracdiff::fracdiff.sim(10000, d = 0.2)"
BenchmarkTools.Trial: 51 samples with 1 evaluation.
 Range (minmax):  98.229 ms105.197 ms   GC (min … max): 0.00% … 0.00%
 Time  (median):     98.957 ms                GC (median):    0.00%
 Time  (mean ± σ):   99.429 ms ±   1.301 ms   GC (mean ± σ):  0.00% ± 0.00%
   ▁▆▁ ▁ █         ▁                                      
  ▄███▇█▇█▇█▄▁▄▄▄▄▁▁▁▇▁█▄▄▄▁▄▁▄▁▄▄▁▁▁▁▁▁▁▁▄▄▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▄ ▁
  98.2 ms         Histogram: frequency by time          103 ms <
 Memory estimate: 1.02 KiB, allocs estimate: 37.

For comparison purposes, the following benchmark is done in R using the microbenchmark package.

R"library(microbenchmark)"
R"microbenchmark(fracdiff::fracdiff.sim(10000, d = 0.2), times = 33)"
RObject{VecSxp}
Unit: milliseconds
                                   expr     min      lq     mean  median
 fracdiff::fracdiff.sim(10000, d = 0.2) 97.9438 98.2633 98.50093 98.3475
      uq     max neval
 98.6261 99.6666    33

Note that the times are similar. Hence, for ease of use, the next benchmarks are done using BenchmarkTools.

Fractional differencing

The fi_gen() function

@benchmark fracdiff(randn(10000,1), 0.2)
BenchmarkTools.Trial: 7629 samples with 1 evaluation.
 Range (minmax):  534.700 μs  4.278 ms   GC (min … max): 0.00% … 82.68%
 Time  (median):     567.200 μs                GC (median):    0.00%
 Time  (mean ± σ):   651.414 μs ± 248.458 μs   GC (mean ± σ):  5.20% ±  9.91%
  ▄█▅▃▂▁▁▁▁                              ▁▂▂                  ▁
  █████████▇█▇▇▅▅▅▄▄▄▃▅▅▅▆▅▅▆▅▆▄▄▄▃▆███▇▇█████▇███▇▆▇▅▅▅▆▄▅▅▅ █
  535 μs        Histogram: log(frequency) by time        1.4 ms <
 Memory estimate: 2.58 MiB, allocs estimate: 44.

R: fracdiff::diffseries()

The R package fracdiff is used for fractional differencing using fracdiff::diffseries().

@benchmark R"fracdiff::diffseries(rnorm(10000), d = 0.2)"
BenchmarkTools.Trial: 2565 samples with 1 evaluation.
 Range (minmax):  1.585 ms44.979 ms   GC (min … max): 0.00% … 0.00%
 Time  (median):     1.756 ms               GC (median):    0.00%
 Time  (mean ± σ):   1.945 ms ±  1.214 ms   GC (mean ± σ):  0.00% ± 0.00%
   ▅█                                                        
  ▅██▄▃▅▄▃▃▂▂▂▂▂▂▂▁▂▂▂▂▁▁▁▂▂▂▂▂▁▁▁▁▁▁▂▁▁▂▁▂▂▂▂▁▂▂▂▁▂▂▂▂▂▂▂ ▂
  1.58 ms        Histogram: frequency by time        5.26 ms <
 Memory estimate: 1.02 KiB, allocs estimate: 37.

R: LongMemoryTS:fdiff()

Loading the R package LongMemoryTS. The LongMemoryTS::fdiff() function is used for fractional differencing.

R"library(LongMemoryTS)"
@benchmark R"LongMemoryTS::fdiff(rnorm(10000), 0.2)"
BenchmarkTools.Trial: 1432 samples with 1 evaluation.
 Range (minmax):  3.082 ms42.873 ms   GC (min … max): 0.00% … 0.00%
 Time  (median):     3.271 ms               GC (median):    0.00%
 Time  (mean ± σ):   3.494 ms ±  1.231 ms   GC (mean ± σ):  0.00% ± 0.00%
   ▅█                                                        
  ▅██▆▅▄▃▃▃▃▃▃▂▂▂▂▂▂▂▂▂▂▂▁▂▁▂▁▁▁▁▁▁▂▂▁▁▁▂▁▁▁▁▂▂▂▂▂▂▂▂▂▂▂▁▂ ▃
  3.08 ms        Histogram: frequency by time        6.67 ms <
 Memory estimate: 1.02 KiB, allocs estimate: 37.

Comparing accuracy

t = 20
x = randn(t,1)
d = 0.2

fd_LongMemoryjl = fracdiff(x, d)
fd_fracdiff = R"fracdiff::diffseries($x, d = $d)"[1:t]
fd_LongMemoryTS = R"LongMemoryTS::fdiff($x, d = $d)"[1:t]

[fd_LongMemoryjl fd_fracdiff fd_LongMemoryTS]
20×3 Matrix{Float64}:
  1.56774     1.53168     1.56774
  0.232034    0.20318     0.232034
 -1.8105     -1.83647    -1.8105
 -0.503704   -0.527942   -0.503704
  1.33832     1.31529     1.33832
  0.882536    0.860431    0.882536
  1.14611     1.12474     1.14611
 -3.29925    -3.32001    -3.29925
  0.0745282   0.0542897   0.0745282
  0.441823    0.422035    0.441823
  0.410045    0.390652    0.410045
 -0.683177   -0.702217   -0.683177
 -0.607066   -0.625789   -0.607066
 -0.454029   -0.472464   -0.454029
  1.1894      1.17123     1.1894
  0.187175    0.169246    0.187175
  1.75967     1.74196     1.75967
 -0.547967   -0.565464   -0.547967
 -1.58271    -1.60001    -1.58271
  0.616853    0.599732    0.616853

Long memory estimation

Data generation.

x = fi_gen(1000, 0.4);

The gph_est() function

@benchmark gph_est(x; m = 0.5)
BenchmarkTools.Trial: 10000 samples with 1 evaluation.
 Range (minmax):  28.000 μs 2.978 ms   GC (min … max): 0.00% … 49.13%
 Time  (median):     33.700 μs               GC (median):    0.00%
 Time  (mean ± σ):   40.695 μs ± 96.307 μs   GC (mean ± σ):  4.35% ±  1.83%
   ▁▁▁▇█                                                      
  ▂█████▆▅▄▄▄▄▂▂▂▂▂▂▂▂▂▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ▂
  28 μs           Histogram: frequency by time        85.8 μs <
 Memory estimate: 66.48 KiB, allocs estimate: 43.

LongMemoryTS: gph()

@benchmark R"LongMemoryTS::gph($x, m = floor(1000^0.5))"
BenchmarkTools.Trial: 10000 samples with 1 evaluation.
 Range (minmax):  135.100 μs  7.234 ms   GC (min … max): 0.00% … 0.00%
 Time  (median):     149.600 μs                GC (median):    0.00%
 Time  (mean ± σ):   175.848 μs ± 153.573 μs   GC (mean ± σ):  0.00% ± 0.00%
   ▆█▃                                                           
  ▆███▄▃▃▃▂▃▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ▂
  135 μs           Histogram: frequency by time          366 μs <
 Memory estimate: 2.66 KiB, allocs estimate: 104.

fracdiff: fdGPH()

@benchmark R"fracdiff::fdGPH($x)"
BenchmarkTools.Trial: 707 samples with 1 evaluation.
 Range (minmax):  5.054 ms34.624 ms   GC (min … max): 0.00% … 0.00%
 Time  (median):     5.979 ms               GC (median):    0.00%
 Time  (mean ± σ):   7.071 ms ±  3.428 ms   GC (mean ± σ):  0.00% ± 0.00%
  ▄█                                                         
  ██▃▂▂▃▄▆▄▂▂▂▂▂▂▂▂▁▁▂▁▁▁▁▁▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▂ ▂
  5.05 ms        Histogram: frequency by time        31.3 ms <
 Memory estimate: 2.66 KiB, allocs estimate: 104.

Comparing accuracy

gph_LongMemoryjl = gph_est(x; m = 0.5)
gph_LongMemoryTS = R"LongMemoryTS::gph(X = $x, m = floor(1000^0.5))"[1]
gph_fracdiff = R"fracdiff::fdGPH($x)$d"[1]

[gph_LongMemoryjl gph_LongMemoryTS gph_fracdiff]
1×3 Matrix{Float64}:
 0.502649  0.502884  0.502884