LINE Solver
MATLAB API documentation
Loading...
Searching...
No Matches
mamap2m_fit.m
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.
9%
10% Input
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])
18% Output
19% - MMAP: fitted MAMAP[m]
20
21if nargin == 2
22 % by default equal weights
23 % when weights are equal, F+B is preferred over F+S and B+S
24 fbsWeights = [1 1 1];
25end
26
27fbWeights = [fbsWeights(1), fbsWeights(2)];
28fsWeights = [fbsWeights(1), fbsWeights(3)];
29bsWeights = [fbsWeights(2), fbsWeights(3)];
30
31gammatol = 1e-4;
32degentol = 1e-8;
33
34if length(P) > 2
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);
37 return;
38end
39
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);
43 return;
44end
45
46% fit underlying AMAP(2)
47[~,MAPS] = amap2_fit_gamma(M1, M2, M3, GAMMA);
48
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);
56 if ~isempty(MAPS2)
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});
60 end
61 MAPS = MAPS2;
62 else
63 % Fallback: fit as marked Poisson
64 fprintf('Fitting MAMAP(2,m): fitting marked Poisson because the underlying process has one state\n');
65 MAP = MAPS{1};
66 m = length(P);
67 MMAP = cell(1,2+m);
68 MMAP{1} = MAP{1};
69 MMAP{2} = MAP{2};
70 for c = 1:m
71 MMAP{2+c} = MMAP{2} .* P(c);
72 end
73 return;
74 end
75end
76
77MMAPS = cell(1,length(MAPS));
78ERRORS = zeros(1,length(MAPS));
79for j = 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
85 degen = 1;
86 if GAMMA > 0
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);
97 elseif r2 < degentol
98 % canonical APH(2)
99 MMAPS{j} = maph2m_fit_multiclass(MAPS{j}, P, B);
100 else
101 degen = 0;
102 end
103 else
104 if (1-r2) < degentol
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);
113 elseif r2 < degentol
114 if fbsWeights(1) >= fbsWeights(2)
115 % fit forward or sigma
116 MMAPS{j} = mamap22_fit_fs_multiclass(MAPS{j}, P, F, S, [], fsWeights);
117 else
118 % fit backward or sigma
119 MMAPS{j} = mamap22_fit_bs_multiclass(MAPS{j}, P, B, S, [], bsWeights);
120 end
121 else
122 degen = 0;
123 end
124 end
125 % handle non-degenerate cases according to user preference
126 if ~degen
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);
133 else
134 % prefer backward and sigma
135 MMAPS{j} = mamap22_fit_bs_multiclass(MAPS{j}, P, B, S, [], bsWeights);
136 end
137 end
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;
145end
146
147% pick the best fit
148[~,BEST] = min(ERRORS);
149MMAP = MMAPS{BEST};
150
151end