LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
aoi_lcfss_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_LCFSS_MGI1_H
6#define LINE_API_AOI_LCFSS_MGI1_H
7
8/**
9 * @file
10 * @ingroup api_aoi
11 * Mean and peak Age of Information of an M/GI/1 non-preemptive LCFS queue with
12 * set-aside (LCFS-S).
13 *
14 * Templated port of matlab/src/api/aoi/aoi_lcfss_mgi1.m, cross-checked against
15 * jar/src/main/java/jline/api/aoi/Aoi_lcfss_mgi1.java (identical).
16 *
17 * E[B] = E[H]/(1-rho), E[B^2] = E[H^2]/(1-rho)^3 (M/G/1 busy period)
18 * E[A] = 1/lambda + E[H] + lambda E[H^2] / (2 (1-rho)^2)
19 * E[Apeak] = 1/lambda + E[H] + lambda E[B^2] / (2 E[B])
20 *
21 * from Inoue et al. (2019, Section V).
22 *
23 * The service-time LST is NOT used: the formula depends on the service
24 * distribution only through its first two moments, so the port takes E_H and
25 * E_H2 and nothing else. (The MATLAB and Java signatures both accept an LST
26 * argument and both ignore it -- see the report note.) Everything is rational
27 * in lambda, E_H and E_H2, so both means are exact in the field.
28 *
29 * MATLAB returns an empty LST handle for this discipline, which the port
30 * reports as has_lst = false.
31 */
32
34#include "line/num/number.h"
35#include "line/util/error.h"
36
37namespace line {
38namespace aoi {
39
40/**
41 * @brief Mean and peak Age of Information of an M/GI/1 non-preemptive LCFS
42 * queue with set-aside (LCFS-S).
43 *
44 * @param lambda arrival rate, > 0
45 * @param E_H mean service time, > 0
46 * @param E_H2 second raw moment of the service time, >= E_H^2
47 * @return [meanAoI, peakAoI], no LST
48 */
49template <class T>
50AoiLstResult<T> aoi_lcfss_mgi1(const T& lambda, const T& E_H, const T& E_H2) {
51 detail::require_positive(lambda, "aoi_lcfss_mgi1", "the arrival rate lambda");
52 detail::require_positive(E_H, "aoi_lcfss_mgi1", "the mean service time E_H");
53 if (E_H2 < E_H * E_H) throw InputError("aoi_lcfss_mgi1: E_H2 must be at least E_H^2");
54 const T one = num_traits<T>::from_int(1), two = num_traits<T>::from_int(2);
55 const T rho = lambda * E_H;
56 detail::require_stable(rho, "aoi_lcfss_mgi1");
57
58 const T E_Y = one / lambda;
59 const T E_B = E_H / (one - rho);
60 const T E_B2 = E_H2 / num_pow_int(T(one - rho), 3);
61
62 const T meanAoI = E_Y + E_H + lambda * E_H2 / (two * (one - rho) * (one - rho));
63 const T peakAoI = E_Y + E_H + lambda * E_B2 / (two * E_B);
64 return {meanAoI, peakAoI, Lst<T>(), false};
65}
66
67} // namespace aoi
68} // namespace line
69
70#endif // LINE_API_AOI_LCFSS_MGI1_H
Shared return types and arithmetic helpers for the templated Age of Information port.
InputError(const std::string &what)
Definition error.h:39
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_lcfss_mgi1(const T &lambda, const T &E_H, const T &E_H2)
Mean and peak Age of Information of an M/GI/1 non-preemptive LCFS queue with set-aside (LCFS-S).
T num_pow_int(const T &base, unsigned e)
Integer power, valid in any field (no transcendental requirement).
Definition number.h:192
Number-type abstraction for the templated API port.
[meanAoI, lstAoI, peakAoI], mirroring jline.api.aoi.AoiLstResult.
Definition aoi_types.h:58