LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
aoi_dist2ph.m
1function [alpha, T] = aoi_dist2ph(proc)
2%AOI_DIST2PH Convert LINE process representation to PH format for aoi-fluid
3%
4% [alpha, T] = AOI_DIST2PH(proc)
5%
6% Converts LINE's {D0, D1} MAP representation to (alpha, T) PH format
7% where alpha is the initial probability vector and T is the sub-generator matrix.
8%
9% In PH representation:
10% - alpha: Row vector of initial probabilities (sums to 1)
11% - T: Sub-generator matrix (negative diagonal, non-negative off-diagonal)
12% - Absorption rates: -T * ones(n,1)
13%
14% Parameters:
15% proc (cell): LINE process representation {D0, D1} where:
16% D0: Sub-generator matrix (like T in PH)
17% D1: Completion/transition matrix
18%
19% Returns:
20% alpha: Initial probability row vector
21% T: Sub-generator matrix
22%
23% See also: aoi_extract_params, solveBufferless, solveSingleBuffer
24
25% Copyright (c) 2012-2026, Imperial College London
26% All rights reserved.
27
28if isempty(proc) || ~iscell(proc) || length(proc) < 2
29 error('aoi_dist2ph:InvalidInput', 'proc must be a cell array {D0, D1}');
30end
31
32D0 = proc{1};
33D1 = proc{2};
34
35% Check for NaN (disabled class)
36if any(isnan(D0(:))) || any(isnan(D1(:)))
37 error('aoi_dist2ph:DisabledClass', 'Process contains NaN - class may be disabled');
38end
39
40% Get dimensions
41n = size(D0, 1);
42
43if n ~= size(D0, 2) || n ~= size(D1, 1) || n ~= size(D1, 2)
44 error('aoi_dist2ph:DimensionMismatch', 'D0 and D1 must be square matrices of the same size');
45end
46
47% T is the sub-generator (D0 in MAP notation)
48T = D0;
49
50% Compute stationary distribution of the underlying CTMC
51% The full generator is Q = D0 + D1
52Q = D0 + D1;
53
54% Check if Q is a proper generator (rows should sum to ~0)
55rowSums = sum(Q, 2);
56if max(abs(rowSums)) > 1e-10
57 % Q is not a proper generator, normalize
58 for i = 1:n
59 Q(i, i) = Q(i, i) - rowSums(i);
60 end
61end
62
63% Compute stationary distribution pi of Q
64% pi * Q = 0 and sum(pi) = 1
65% Solve [Q'; ones(1,n)] * [pi'; 1] = [zeros(n,1); 1]
66A = [Q'; ones(1, n)];
67b = [zeros(n, 1); 1];
68pi = (A \ b)';
69
70% Ensure pi is non-negative and normalized
71pi = max(pi, 0);
72pi = pi / sum(pi);
73
74% Initial probability alpha is the stationary distribution weighted by
75% the probability of starting in each phase after a completion
76% For a renewal process: alpha = pi * D1 / (pi * D1 * ones)
77% This gives the probability of starting in each phase
78completionRates = D1 * ones(n, 1);
79numerator = pi .* completionRates';
80
81if sum(numerator) > 0
82 alpha = numerator / sum(numerator);
83else
84 % Fallback: use stationary distribution
85 alpha = pi;
86end
87
88% Ensure alpha is a row vector
89alpha = alpha(:)';
90
91% Normalize to ensure sum = 1
92alpha = alpha / sum(alpha);
93
94% Validate T is a proper sub-generator
95% - Diagonal elements should be non-positive
96% - Off-diagonal elements should be non-negative
97% - Row sums should be non-positive (not zero, since it's a sub-generator)
98for i = 1:n
99 if T(i, i) > 0
100 error('aoi_dist2ph:InvalidSubGenerator', 'T(%d,%d) = %g > 0, expected non-positive', i, i, T(i, i));
101 end
102end
103
104end