LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
sn_map_modulation.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_SN_SN_MAP_MODULATION_H
6
#define LINE_API_SN_SN_MAP_MODULATION_H
7
8
/**
9
* @file
10
* @ingroup api_sn
11
* Port of matlab/src/api/sn/sn_map_modulation.m.
12
*
13
* Every MAP-like process in the model, collected as the modulating environment
14
* it really is: `map2renv` turns this list into a random-environment model, in
15
* which the MAP's phase process is the environment stage and the network runs
16
* at the rate that stage selects.
17
*
18
* MARKED PROCESSES. When a station's arrival is a marked MAP (an MMAP), the
19
* classes it marks share ONE modulating phase process, so they are reported as
20
* a SINGLE entry carrying (D0, D1^(1), ..., D1^(C)) over the marked class set,
21
* not as one entry per class. Splitting them would give each class its own
22
* independent environment and lose exactly the correlation the MMAP encodes.
23
*
24
* `is_mmpp` records whether every mark block is diagonal: a diagonal D1 means
25
* an arrival never changes the phase, which is the MMPP special case whose
26
* environment is the phase process alone.
27
*
28
* ARITHMETIC: field. A Frobenius norm comparison, no transcendental.
29
*/
30
31
#include <cmath>
32
#include <cstddef>
33
#include <string>
34
#include <vector>
35
36
#include "
line/lang/qn/network_struct.h
"
37
#include "
line/num/number.h
"
38
39
namespace
line
{
40
namespace
api
{
41
42
/** One modulating process: which station and classes it drives, and its blocks. */
43
template
<
class
T>
44
struct
SnMapModulation
{
45
std::size_t
ist
= 0;
///< 1-based station
46
std::size_t
node
= 0;
///< 1-based node
47
bool
arrival
=
false
;
///< true at a Source, false for a service process
48
std::vector<std::size_t>
classes
;
///< 1-based classes this process drives
49
Matrix<T>
D0
;
50
std::vector<Matrix<T>>
D1
;
///< one block per entry of `classes`
51
std::size_t
order
= 0;
///< phases of the modulating process
52
bool
is_mmpp
=
false
;
///< every D1 block is diagonal
53
};
54
55
namespace
detail {
56
57
/** `norm(D1 - diag(diag(D1)),'fro') <= Zero * max(1, norm(D1,'fro'))`. */
58
template
<
class
T>
59
bool
sn_map_is_diagonal(
const
Matrix<T>
& D1) {
60
double
off = 0.0, all = 0.0;
61
for
(std::size_t a = 0; a < D1.
rows
(); ++a)
62
for
(std::size_t b = 0; b < D1.
cols
(); ++b) {
63
const
double
v =
num_traits<T>::to_double
(D1(a, b));
64
all += v * v;
65
if
(a != b) off += v * v;
66
}
67
return
std::sqrt(off) <=
lang::GlobalConstants::Zero
* std::max(1.0, std::sqrt(all));
68
}
69
70
}
// namespace detail
71
72
template
<
class
T>
73
std::vector<SnMapModulation<T>>
sn_map_modulation
(
const
qn::NetworkStruct<T>
&
sn
) {
74
std::vector<SnMapModulation<T>> mods;
75
for
(std::size_t ist = 1; ist <=
sn
.nstations; ++ist) {
76
const
std::size_t nd =
sn
.station_to_node[ist - 1];
77
const
bool
arrival =
78
nd != 0 &&
sn
.nodes[nd - 1].nodetype == qn::NodeType::Source;
79
const
std::vector<std::size_t>& marks =
sn
.stations[ist - 1].marked_classes;
80
std::vector<bool> done(
sn
.nclasses,
false
);
81
for
(std::size_t r = 1; r <=
sn
.nclasses; ++r) {
82
if
(done[r - 1])
continue
;
83
const
lang::ProcessType
pt =
sn
.service[ist - 1][r - 1].type;
84
if
(!(pt ==
lang::ProcessType::MAP
|| pt ==
lang::ProcessType::MMPP2
||
85
pt ==
lang::ProcessType::MMAP
))
86
continue
;
87
const
lang::Distrib<T>
& d =
sn
.service[ist - 1][r - 1];
88
if
(d.
disabled
|| d.
D0
.rows() == 0)
continue
;
89
bool
is_marked =
false
;
90
for
(std::size_t c : marks)
91
if
(c == r) is_marked =
true
;
92
SnMapModulation<T>
m;
93
m.
ist
= ist;
94
m.
node
= nd;
95
m.
arrival
= arrival;
96
if
(is_marked && !marks.empty()) {
97
// one entry for the whole marked set, carried by the block list
98
// of the FIRST marked class -- the reference's "carrier"
99
const
lang::Distrib<T>
& carrier =
sn
.service[ist - 1][marks[0] - 1];
100
if
(carrier.
Dmark
.size() < marks.size())
101
throw
InputError
(
102
"sn_map_modulation: the marked arrival process at station "
+
103
std::to_string(ist) +
" carries "
+
104
std::to_string(carrier.
Dmark
.size()) +
" mark matrices for "
+
105
std::to_string(marks.size()) +
106
" marked classes; the (D0,D1,D1^(1),...,D1^(C)) form is required"
);
107
m.
classes
= marks;
108
m.
D0
= carrier.
D0
;
109
m.
is_mmpp
=
true
;
110
for
(std::size_t k = 0; k < marks.size(); ++k) {
111
m.
D1
.push_back(carrier.
Dmark
[k]);
112
if
(!detail::sn_map_is_diagonal(carrier.
Dmark
[k])) m.
is_mmpp
=
false
;
113
done[marks[k] - 1] =
true
;
114
}
115
m.
order
= carrier.
D0
.rows();
116
}
else
{
117
m.
classes
.push_back(r);
118
m.
D0
= d.
D0
;
119
m.
D1
.push_back(d.
D1
);
120
m.
order
= d.
D0
.rows();
121
m.
is_mmpp
= detail::sn_map_is_diagonal(d.
D1
);
122
done[r - 1] =
true
;
123
}
124
mods.push_back(m);
125
}
126
}
127
return
mods;
128
}
129
130
}
// namespace api
131
}
// namespace line
132
133
#endif
// LINE_API_SN_SN_MAP_MODULATION_H
line::InputError::InputError
InputError(const std::string &what)
Definition
error.h:39
line::Matrix
Definition
matrix.h:56
line::Matrix::cols
std::size_t cols() const
Definition
matrix.h:90
line::Matrix::rows
std::size_t rows() const
Definition
matrix.h:89
line::qn::NetworkStruct
A network plus its refreshed NetworkStruct.
Definition
network_struct.h:838
line::api
Definition
infer_fmlps.h:69
line::api::sn_map_modulation
std::vector< SnMapModulation< T > > sn_map_modulation(const qn::NetworkStruct< T > &sn)
Definition
sn_map_modulation.h:73
line::lang::ProcessType
ProcessType
Distribution kinds, with the values of MATLAB ProcessType.
Definition
lang_types.h:483
line::lang::ProcessType::MMAP
@ MMAP
Definition
lang_types.h:520
line::lang::ProcessType::MAP
@ MAP
Definition
lang_types.h:489
line::lang::ProcessType::MMPP2
@ MMPP2
Definition
lang_types.h:495
line::sn
Definition
sn_gd_balance.h:42
line
Definition
aoi_dist2ph.h:52
network_struct.h
A queueing network and its refreshed NetworkStruct.
number.h
Number-type abstraction for the templated API port.
line::api::SnMapModulation
One modulating process: which station and classes it drives, and its blocks.
Definition
sn_map_modulation.h:44
line::api::SnMapModulation::classes
std::vector< std::size_t > classes
1-based classes this process drives
Definition
sn_map_modulation.h:48
line::api::SnMapModulation::node
std::size_t node
1-based node
Definition
sn_map_modulation.h:46
line::api::SnMapModulation::arrival
bool arrival
true at a Source, false for a service process
Definition
sn_map_modulation.h:47
line::api::SnMapModulation::D1
std::vector< Matrix< T > > D1
one block per entry of classes
Definition
sn_map_modulation.h:50
line::api::SnMapModulation::order
std::size_t order
phases of the modulating process
Definition
sn_map_modulation.h:51
line::api::SnMapModulation::is_mmpp
bool is_mmpp
every D1 block is diagonal
Definition
sn_map_modulation.h:52
line::api::SnMapModulation::ist
std::size_t ist
1-based station
Definition
sn_map_modulation.h:45
line::api::SnMapModulation::D0
Matrix< T > D0
Definition
sn_map_modulation.h:49
line::lang::Distrib
Definition
lang_types.h:716
line::lang::Distrib::D0
Matrix< T > D0
The (D0,D1) pair when the type carries one directly.
Definition
lang_types.h:759
line::lang::Distrib::disabled
bool disabled
Definition
lang_types.h:732
line::lang::Distrib::Dmark
std::vector< Matrix< T > > Dmark
MMAP per-class D1 blocks / BMAP per-batch-size blocks; empty otherwise.
Definition
lang_types.h:761
line::lang::Distrib::D1
Matrix< T > D1
Definition
lang_types.h:759
line::lang::GlobalConstants::Zero
static constexpr double Zero
Definition
lang_types.h:670
line::num_traits
Definition
number.h:111
include
line
api
sn
sn_map_modulation.h
Generated by
1.18.0