LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
getProbMarg.m
1function [Pmarg, logPmarg] = getProbMarg(self, node)
2% [PMARG, LOGPMARG] = GETPROBMARG(NODE)
3%
4% Probability distribution for TOTAL queue length at a station.
5% Returns P(n total jobs) for n=0,1,...,N, summing over all class combinations.
6%
7% Compare with getProbAggr: returns probability of a specific per-class
8% distribution, e.g., P(2 class-1, 1 class-2).
9%
10% Input:
11% node - Queue or node object
12%
13% Output:
14% Pmarg - Vector where Pmarg(n+1) = P(n total jobs at node)
15% logPmarg - Log probabilities for numerical stability
16
17if GlobalConstants.DummyMode
18 Pmarg = NaN;
19 logPmarg = NaN;
20 return
21end
22
23% Get network structure
24sn = self.getStruct;
25
26% Store original node parameter and convert to station index
27if isa(node, 'Node')
28 node_obj = node;
29 ist = sn.nodeToStation(node.index);
30else
31 % If given station index, need to find corresponding node
32 ist = node;
33 % Find node with this station index
34 for i = 1:length(sn.nodetype)
35 if sn.nodeToStation(i) == ist
36 node_obj = sn.nodes{i};
37 break;
38 end
39 end
40end
41
42% Get population and class information
43N = sn.njobs;
44if ~all(isfinite(N))
45 line_error(mfilename, 'getProbMarg not yet implemented for models with open classes.');
46end
47
48R = sn.nclasses; % Number of classes
49Ntotal = sum(N); % Total population
50
51% Initialize output vectors
52Pmarg = zeros(1, Ntotal + 1);
53logPmarg = -Inf * ones(1, Ntotal + 1);
54
55% For each possible total queue length
56for n = 0:Ntotal
57 % Enumerate all ways to partition n jobs across R classes
58 % subject to constraint: n_r <= N(r) for each class
59 partitions = generate_partitions(n, R, N);
60
61 % Sum probabilities over all partitions
62 log_prob_n = -Inf;
63 for p = 1:size(partitions, 1)
64 state_vec = partitions(p, :);
65
66 % Get probability for this specific class distribution
67 % Note: getProbAggr already supports LD models via pfqn_ncld
68 % Gets unnormalized values (we normalize at the end)
69 prob = self.getProbAggr(node_obj, state_vec);
70
71 if prob > 0
72 log_p = log(prob);
73 % Log-sum-exp trick for numerical stability
74 if isinf(log_prob_n)
75 log_prob_n = log_p;
76 else
77 log_prob_n = log_prob_n + log(1 + exp(log_p - log_prob_n));
78 end
79 end
80 end
81
82 % Store results
83 if isfinite(log_prob_n)
84 Pmarg(n + 1) = exp(log_prob_n);
85 logPmarg(n + 1) = log_prob_n;
86 else
87 Pmarg(n + 1) = 0;
88 logPmarg(n + 1) = -Inf;
89 end
90end
91
92% Normalize to ensure probabilities sum to 1
93total_prob = sum(Pmarg);
94if total_prob > 0 && abs(total_prob - 1.0) > 1e-10
95 Pmarg = Pmarg / total_prob;
96 logPmarg = logPmarg - log(total_prob);
97end
98
99end
100
101function partitions = generate_partitions(n, R, N_max)
102% GENERATE_PARTITIONS Enumerate all ways to partition n into R non-negative integers
103%
104% @param n Total to partition
105% @param R Number of parts
106% @param N_max Maximum value for each part (vector of length R)
107% @return partitions Matrix where each row is a valid partition
108
109if R == 1
110 % Base case: single class
111 if n <= N_max(1)
112 partitions = n;
113 else
114 partitions = zeros(0, 1);
115 end
116 return
117end
118
119% Recursive case: try all possible values for first class
120partitions = [];
121for n1 = 0:min(n, N_max(1))
122 % Recursively partition remaining jobs across remaining classes
123 sub_partitions = generate_partitions(n - n1, R - 1, N_max(2:end));
124
125 if ~isempty(sub_partitions)
126 % Prepend n1 to each sub-partition
127 partitions = [partitions; n1 * ones(size(sub_partitions, 1), 1), sub_partitions];
128 end
129end
130
131end
Definition mmt.m:92