LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
qsys_mapg1.m
1function result = qsys_mapg1(D0, D1, serviceMoments, varargin)
2% QSYS_MAPG1 Analyzes a MAP/G/1 queue using BUTools MMAPPH1FCFS.
3%
4% RESULT = QSYS_MAPG1(D0, D1, SERVICEMOMENTS) analyzes a MAP/G/1 queue with:
5% D0 - MAP hidden transition matrix (n x n)
6% D1 - MAP arrival transition matrix (n x n)
7% SERVICEMOMENTS - First k raw moments of service time [E[S], E[S^2], ...]
8% (k = 2 or 3 for best accuracy)
9%
10% The general service time is fitted to a Phase-Type distribution using
11% moment matching before analysis.
12%
13% RESULT = QSYS_MAPG1(..., 'numQLMoms', K) computes K queue length moments
14% RESULT = QSYS_MAPG1(..., 'numQLProbs', N) computes N queue length probs
15% RESULT = QSYS_MAPG1(..., 'numSTMoms', K) computes K sojourn time moments
16%
17% Returns a struct with fields:
18% meanQueueLength - Mean number of customers in system
19% meanWaitingTime - Mean waiting time in queue
20% meanSojournTime - Mean sojourn time (waiting + service)
21% utilization - Server utilization
22% queueLengthDist - Queue length distribution P(Q=n)
23% queueLengthMoments- Raw moments of queue length
24% sojournTimeMoments- Raw moments of sojourn time
25% analyzer - Name of analyzer used
26%
27% See also MMAPPH1FCFS, APHFrom3Moments, qsys_mapph1
28
29% Parse optional arguments
30p = inputParser;
31addParameter(p, 'numQLMoms', 3);
32addParameter(p, 'numQLProbs', 100);
33addParameter(p, 'numSTMoms', 3);
34parse(p, varargin{:});
35
36numQLMoms = p.Results.numQLMoms;
37numQLProbs = p.Results.numQLProbs;
38numSTMoms = p.Results.numSTMoms;
39
40% Fit service distribution to PH using moment matching
41[sigma, S] = fitServiceToPH(serviceMoments);
42
43% Build arrival MMAP structure for BUTools (single class)
44D = {D0, D1};
45
46% Service parameters as cell arrays
47sigmaCell = {sigma};
48SCell = {S};
49
50% Call BUTools solver
51[ncMoms, ncDistr, stMoms] = MMAPPH1FCFS(D, sigmaCell, SCell, ...
52 'ncMoms', numQLMoms, 'ncDistr', numQLProbs, 'stMoms', numSTMoms);
53
54% Compute utilization from arrival and service rates
55theta = ctmc_solve(D0 + D1);
56lambda = sum(theta * D1);
57
58meanService = serviceMoments(1);
59mu = 1.0 / meanService;
60rho = lambda / mu;
61
62% Extract results
63if ~isempty(ncMoms)
64 meanQL = ncMoms(1);
65else
66 meanQL = 0;
67end
68
69if ~isempty(stMoms)
70 meanST = stMoms(1);
71else
72 meanST = 0;
73end
74
75% Waiting time = sojourn time - service time
76meanWT = max(0, meanST - meanService);
77
78% Build result struct
79result = struct();
80result.meanQueueLength = meanQL;
81result.meanWaitingTime = meanWT;
82result.meanSojournTime = meanST;
83result.utilization = rho;
84result.queueLengthDist = ncDistr;
85result.queueLengthMoments = ncMoms;
86result.sojournTimeMoments = stMoms;
87result.analyzer = 'BUTools:MMAPPH1FCFS';
88
89end
90
91function [sigma, S] = fitServiceToPH(moments)
92% FITSERVICETOPH Fits a general service time distribution to PH.
93%
94% Uses moment matching with APHFrom3Moments when 3 moments are available,
95% otherwise falls back to simpler approximations.
96
97m1 = moments(1);
98
99if length(moments) >= 3
100 % Use APH from 3 moments for best accuracy
101 try
102 [sigma, S] = APHFrom3Moments(moments(1:3));
103 catch
104 % Fallback to 2-phase PH
105 try
106 [sigma, S] = PH2From3Moments(moments(1:3));
107 catch
108 % Ultimate fallback to exponential
109 [sigma, S] = createExponentialPH(m1);
110 end
111 end
112elseif length(moments) >= 2
113 % Use 2 moments - create PH(2) with matching mean and variance
114 m2 = moments(2);
115 cv2 = m2 / (m1 * m1) - 1.0; % Squared coefficient of variation
116
117 if cv2 <= 0
118 % Deterministic or near-deterministic: use Erlang approximation
119 k = max(1, round(1.0 / max(cv2, 0.01)));
120 [sigma, S] = createErlangPH(m1, k);
121 elseif cv2 < 1
122 % Hypoexponential: use Erlang-k approximation
123 k = max(2, round(1.0 / cv2));
124 [sigma, S] = createErlangPH(m1, k);
125 elseif cv2 == 1
126 % Exponential
127 [sigma, S] = createExponentialPH(m1);
128 else
129 % Hyperexponential: use 2-phase hyperexponential
130 [sigma, S] = createHyperexp2PH(m1, cv2);
131 end
132else
133 % Only mean provided - use exponential
134 [sigma, S] = createExponentialPH(m1);
135end
136
137end
138
139function [sigma, S] = createExponentialPH(mean)
140% Creates an exponential PH distribution.
141sigma = 1;
142S = -1.0 / mean;
143end
144
145function [sigma, S] = createErlangPH(mean, k)
146% Creates an Erlang-k PH distribution.
147mu = k / mean;
148sigma = zeros(1, k);
149sigma(1) = 1.0;
150
151S = zeros(k, k);
152for i = 1:k
153 S(i, i) = -mu;
154 if i < k
155 S(i, i+1) = mu;
156 end
157end
158end
159
160function [sigma, S] = createHyperexp2PH(mean, cv2)
161% Creates a 2-phase hyperexponential with matched mean and cv2.
162
163% Balanced means approach
164cv = sqrt(cv2);
165p = 0.5 * (1.0 + sqrt((cv2 - 1.0) / (cv2 + 1.0)));
166lambda1 = 2.0 * p / mean;
167lambda2 = 2.0 * (1.0 - p) / mean;
168
169sigma = [p, 1.0 - p];
170S = diag([-lambda1, -lambda2]);
171end