LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
aoi_lcfspr_mgi1.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2026, QORE Lab, Imperial College London
3 * All rights reserved.
4 */
5#ifndef LINE_API_AOI_LCFSPR_MGI1_H
6#define LINE_API_AOI_LCFSPR_MGI1_H
7
8/**
9 * @file
10 * @ingroup api_aoi
11 * Mean Age of Information, its transform and the peak age of an M/GI/1
12 * preemptive LCFS queue.
13 *
14 * Templated port of matlab/src/api/aoi/aoi_lcfspr_mgi1.m, cross-checked
15 * against jar/src/main/java/jline/api/aoi/Aoi_lcfspr_mgi1.java (identical).
16 *
17 * E[A] = 1/(lambda H*(lambda))
18 * q = P(S < Y) = H*(lambda)
19 * E[Apeak] = -H*'(lambda)/H*(lambda) + 1/(lambda H*(lambda))
20 * A*(s) = lambda H*(s+lambda) / (s + lambda H*(s+lambda))
21 *
22 * Looking back from any instant, each earlier update is delivered iff its
23 * service ends before the next arrival, so the age is a geometric sum of
24 * Exp(lambda) gaps ending at the first delivered update. The old 1/lambda + E[H]
25 * and lambda/(s+lambda) H*(s) hold only for exponential service.
26 *
27 * static_assert(num_traits<T>::has_transcendental) -- the peak age uses
28 * MATLAB's finite-difference derivative of H* at lambda, with step
29 * 1e-6 max(1,lambda). The mean and the transform are exact wherever H* is.
30 */
31
33#include "line/num/number.h"
34#include "line/util/error.h"
35
36namespace line {
37namespace aoi {
38
39/**
40 * @brief Mean Age of Information, its transform and the peak age of an M/GI/1
41 * preemptive LCFS queue.
42 *
43 * @param lambda arrival rate, > 0
44 * @param H_lst LST of the service time
45 * @param E_H mean service time, > 0
46 * @return [meanAoI, peakAoI, A*(s)]
47 */
48template <class T>
49AoiLstResult<T> aoi_lcfspr_mgi1(const T& lambda, const Lst<T>& H_lst, const T& E_H) {
51 "aoi_lcfspr_mgi1 requires transcendental arithmetic");
52 detail::require_positive(lambda, "aoi_lcfspr_mgi1", "the arrival rate lambda");
53 detail::require_positive(E_H, "aoi_lcfspr_mgi1", "the mean service time E_H");
54 if (!H_lst) throw InputError("aoi_lcfspr_mgi1: the service-time LST must be callable");
55 const T one = num_traits<T>::from_int(1);
56 const T rho = lambda * E_H;
57 detail::require_stable(rho, "aoi_lcfspr_mgi1");
58
59 const T dHstar = detail::lst_derivative<T>(H_lst, lambda);
60 const T Hlam = H_lst(lambda);
61 if (Hlam == num_traits<T>::from_int(0))
62 throw NumericError("aoi_lcfspr_mgi1: H*(lambda) = 0, no update ever completes");
63 const T meanAoI = one / (lambda * Hlam);
64 const T peakAoI = -dHstar / Hlam + one / (lambda * Hlam);
65
66 Lst<T> lstAoI = [lambda, H_lst](const T& s) {
67 const T f = lambda * H_lst(T(s + lambda));
68 return T(f / (s + f)); // A*(0) = 1 identically
69 };
70 return {meanAoI, peakAoI, lstAoI, true};
71}
72
73} // namespace aoi
74} // namespace line
75
76#endif // LINE_API_AOI_LCFSPR_MGI1_H
Shared return types and arithmetic helpers for the templated Age of Information port.
InputError(const std::string &what)
Definition error.h:39
NumericError(const std::string &what)
Definition error.h:45
The exception types the port throws.
std::function< T(const T &)> Lst
A Laplace-Stieltjes transform evaluated at real arguments.
Definition aoi_types.h:41
AoiLstResult< T > aoi_lcfspr_mgi1(const T &lambda, const Lst< T > &H_lst, const T &E_H)
Mean Age of Information, its transform and the peak age of an M/GI/1 preemptive LCFS queue.
Conservation laws of a layered queueing network, enumerated from its structure.
Definition aoi_dist2ph.h:52
Number-type abstraction for the templated API port.
[meanAoI, lstAoI, peakAoI], mirroring jline.api.aoi.AoiLstResult.
Definition aoi_types.h:59