LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
fj_respt_vm.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_FJ_RESPT_VM_H
6#define LINE_API_FJ_RESPT_VM_H
7
8/**
9 * @file
10 * @ingroup api_fj
11 * Varma-Makowski light-traffic interpolation for the mean response time of a
12 * K-way fork-join system of M/M/1 branches.
13 *
14 * Templated port of matlab/src/api/fj/fj_respt_vm.m, cross-checked against
15 * FJ_respt.fj_respt_vm in jar/src/main/java/jline/api/fj/FJ_respt.java
16 * (identical).
17 *
18 * R_K = [ H_K + (A_K - H_K) rho ] / (mu - lambda)
19 * A_K = sum_{i=1..K} C(K,i) (-1)^{i-1} sum_{m=1..i} C(i,m) (m-1)! / i^{m+1}
20 *
21 * Every term is rational, so the whole interpolation is exact in the field.
22 * A_K is an alternating sum of binomial coefficients: at K = 30 the largest
23 * term is about 1e8 times the result, so in double roughly eight significant
24 * digits are lost to cancellation and by K = 60 nothing is left. The exact
25 * instantiation is the only way to evaluate A_K at those K, and the only way
26 * to measure the loss in the double one.
27 */
28
31#include "line/num/number.h"
32#include "line/util/error.h"
33
34namespace line {
35namespace fj {
36
37/**
38 * @brief Varma-Makowski light-traffic interpolation for the mean response
39 * time of a K-way fork-join system of M/M/1 branches.
40 *
41 * @param K number of parallel branches, K >= 1
42 * @param lambda arrival rate
43 * @param mu per-branch service rate
44 * @return approximate mean fork-join response time
45 */
46template <class T>
47T fj_respt_vm(unsigned K, const T& lambda, const T& mu) {
48 detail::require_positive_K(K, "fj_respt_vm");
49 const T one = num_traits<T>::from_int(1);
50 const T rho = lambda / mu;
51 if (rho >= one) throw NumericError("fj_respt_vm: unstable system, rho = lambda/mu >= 1");
52
53 const T H_K = fj_harmonic<T>(K);
54 T A_K = num_traits<T>::from_int(0);
55 for (unsigned i = 1; i <= K; ++i) {
56 const T ii = num_traits<T>::from_int(static_cast<long>(i));
57 T inner = num_traits<T>::from_int(0);
58 for (unsigned m = 1; m <= i; ++m)
59 inner += detail::fj_binom<T>(i, m) * num_factorial<T>(m - 1) / num_pow_int(ii, m + 1);
60 const T term = detail::fj_binom<T>(K, i) * inner;
61 if ((i - 1) % 2 == 0) A_K += term;
62 else A_K -= term;
63 }
64 return (H_K + (A_K - H_K) * rho) / (mu - lambda);
65}
66
67} // namespace fj
68} // namespace line
69
70#endif // LINE_API_FJ_RESPT_VM_H
NumericError(const std::string &what)
Definition error.h:45
The exception types the port throws.
Harmonic number H_K = sum_{k=1..K} 1/k.
Shared return types and arithmetic helpers for the templated fork-join port.
T fj_respt_vm(unsigned K, const T &lambda, const T &mu)
Varma-Makowski light-traffic interpolation for the mean response time of a K-way fork-join system of ...
Definition fj_respt_vm.h:47
T fj_harmonic(unsigned K)
Harmonic number H_K = sum_{k=1..K} 1/k.
Definition fj_harmonic.h:37
T num_factorial(unsigned n)
Factorial as a value of T.
Definition number.h:184
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.