1function
MMAP = mamap2m_fit(M1, M2, M3, GAMMA,
P, F, B, S, fbsWeights)
2% Fits a MAPH(2,m) or A MAMAP(2,m) that matches the provided
3% characteristics. Three characteristics of the marked process are matched
4% either exactly or approximately. Among these, the
class probabilities are
5% always matched exactly. The remaining two characteristics, by
default,
6% are the forward and backward moments, unless the underlying AMAP(2)
is
7% degenerate. Different pairs of characteristics can be chosen by
8% specifying higher weights in the optional parameter fbsWeights.
11% - M1,M2,M3: moments of the inter-arrival times
12% - GAMMA: auto-correlation decay rate of the inter-arrival times
13% -
P: class probabilities
14% - F: first-order forward moments
15% - B: first-order backward moments
16% - fbsWeights: the weight assigned to forward moments, backward moments
17% and class transition probabilities (default: [1, 1, 1])
19% -
MMAP: fitted MAMAP[m]
22 % by default equal weights
23 % when weights are equal, F+B
is preferred over F+S and B+S
27fbWeights = [fbsWeights(1), fbsWeights(2)];
28fsWeights = [fbsWeights(1), fbsWeights(3)];
29bsWeights = [fbsWeights(2), fbsWeights(3)];
35 fprintf('Fitting MAMAP(2,m): fitting F+B because m > 2\n');
36 MMAP = mamap2m_fit_gamma_fb(M1, M2, M3, GAMMA,
P, F, B);
40if abs(GAMMA) < gammatol
41 fprintf('Fitting MAMAP(2,m): fitting MAPH because gamma = %e\n', GAMMA);
42 MMAP = maph2m_fit(M1, M2, M3,
P, B);
46% fit underlying AMAP(2)
47[~,MAPS] = amap2_fit_gamma(M1, M2, M3, GAMMA);
49% If the underlying process
is Poisson (1 state), try to convert to a
50% second-order process for more degrees of freedom in the marked process
51if length(MAPS) == 1 && size(MAPS{1}{1},1) == 1
52 % Perturb moments slightly above exponential to get 2-state AMAP(2)
53 M2a = M2 * (1 + 1e-4);
54 M3a = M3 * (M2a/M2)^(3/2); % scale M3 proportionally
55 MAPS2 = amap2_fitall_gamma(M1, M2a, M3a, GAMMA);
57 fprintf('Fitting MAMAP(2,m): converting Poisson to second-order process\n');
58 for j = 1:length(MAPS2)
59 MAPS2{j} = map_normalize(MAPS2{j});
63 % Fallback: fit as marked Poisson
64 fprintf(
'Fitting MAMAP(2,m): fitting marked Poisson because the underlying process has one state\n');
77MMAPS = cell(1,length(MAPS));
78ERRORS = zeros(1,length(MAPS));
80 h1 = -1/MAPS{j}{1}(1,1);
81 h2 = -1/MAPS{j}{1}(2,2);
82 r1 = h1*MAPS{j}{1}(1,2);
83 r2 = h2*MAPS{j}{2}(2,2);
84 % detect and handle degenerate cases
87 if r1 < degentol || (1-r2) < degentol
88 error(
'Should not happen');
89 elseif abs(h2-h1*r2) < degentol
90 MMAPS{j} = mamap22_fit_fs_multiclass(MAPS{j},
P, F, S, [], fsWeights);
91 elseif abs(h1 - h2 + h2*r1) < degentol
92 MMAPS{j} = mamap22_fit_bs_multiclass(MAPS{j},
P, B, S, [], bsWeights);
93 elseif (1-r1) < degentol
94 % non-canonical APH(2)
95 % only forward can be fitted
96 MMAPS{j} = mamap22_fit_fs_multiclass(MAPS{j},
P, F, S, [], fsWeights);
99 MMAPS{j} = maph2m_fit_multiclass(MAPS{j},
P, B);
105 error(
'Should not happen');
106 elseif abs(h1 - h2 - h1*r1 + h1*r1*r2) < degentol
107 MMAPS{j} = mamap22_fit_fs_multiclass(MAPS{j},
P, F, S, [], fsWeights);
108 elseif abs(h1 - h2 + h2*r1) < degentol
109 MMAPS{j} = mamap22_fit_bs_multiclass(MAPS{j},
P, B, S, [], bsWeights);
110 elseif r2 < degentol && (1-r1) < degentol
111 % degenerate canonical APH(2)
112 MMAPS{j} = maph2m_fit_multiclass(MAPS{j},
P, B);
114 if fbsWeights(1) >= fbsWeights(2)
115 % fit forward or sigma
116 MMAPS{j} = mamap22_fit_fs_multiclass(MAPS{j},
P, F, S, [], fsWeights);
118 % fit backward or sigma
119 MMAPS{j} = mamap22_fit_bs_multiclass(MAPS{j},
P, B, S, [], bsWeights);
125 % handle non-degenerate cases according to user preference
127 if fbsWeights(1) >= fbsWeights(3) && fbsWeights(2) >= fbsWeights(3)
128 % prefer forward and backward
129 MMAPS{j} = mamap2m_fit_fb_multiclass(MAPS{j},
P, F, B, [], fbWeights);
130 elseif fbsWeights(1) >= fbsWeights(2)
131 % prefer forward and sigma
132 MMAPS{j} = mamap22_fit_fs_multiclass(MAPS{j},
P, F, S, [], fsWeights);
134 % prefer backward and sigma
135 MMAPS{j} = mamap22_fit_bs_multiclass(MAPS{j},
P, B, S, [], bsWeights);
138 % compute fitting error
139 fF = mmap_forward_moment(MMAPS{j}, 1);
140 fB = mmap_backward_moment(MMAPS{j}, 1);
141 fS = mmap_sigma(MMAPS{j});
142 ERRORS(j) = fbsWeights(1) * (F(1)/fF(1)-1)^2 + ...
143 fbsWeights(2) * (B(1)/fB(1)-1)^2 + ...
144 fbsWeights(3) * (S(1,1)/fS(1,1)-1)^2;
148[~,BEST] = min(ERRORS);