1function [alpha, T] = aoi_dist2ph(proc)
2%AOI_DIST2PH Convert LINE process representation to PH format
for aoi-fluid
4% [alpha, T] = AOI_DIST2PH(proc)
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.
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)
15% proc (cell): LINE process representation {D0, D1} where:
16% D0: Sub-generator matrix (like T in PH)
17% D1: Completion/transition matrix
20% alpha: Initial probability row vector
21% T: Sub-generator matrix
23% See also: aoi_extract_params, solveBufferless, solveSingleBuffer
25% Copyright (c) 2012-2026, Imperial College London
28if isempty(proc) || ~iscell(proc) || length(proc) < 2
29 error('aoi_dist2ph:InvalidInput
', 'proc must be a cell array {D0, D1}
');
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');
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');
47% T
is the sub-generator (D0 in MAP notation)
50% Compute stationary distribution of the underlying CTMC
51% The full generator
is Q = D0 + D1
54% Check if Q
is a proper generator (rows should sum to ~0)
56if max(abs(rowSums)) > 1e-10
57 % Q
is not a proper generator, normalize
59 Q(i, i) = Q(i, i) - rowSums(i);
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]
70% Ensure pi
is non-negative and normalized
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';
82 alpha = numerator / sum(numerator);
84 % Fallback: use stationary distribution
88% Ensure alpha
is a row vector
91% Normalize to ensure sum = 1
92alpha = alpha / sum(alpha);
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)
100 error('aoi_dist2ph:InvalidSubGenerator', 'T(%d,%d) = %g > 0, expected non-positive', i, i, T(i, i));