1function [maph,fB] = maph2m_fit_multiclass(
aph,p,B,classWeights)
2% Performs approximate fitting of a MAPH given the underlying APH(2),
3% the
class probabilities (always fitted exactly), the backward moments,
4% and the one-step
class transition probabilities.
6% -
aph: second-order APH underlying the MAPH[m]
7% - p: vector of
class probabilities
8% - B: vector of backward moments
9% - classWeights: optional vector of weights
for each class
11% - maph: fitted MAPH[m]
12% - fB: vector of optimal feasible backward moments
14if (size(
aph{1},1) ~= 2)
15 error(
'Underlying APH must be of second-order.');
18 error(
'Underlying APH must be acyclic');
20if (
aph{2}(1,2) ~= 0 ||
aph{2}(2,2) ~= 0)
21 error(
'Underlying APH must be in canonical acyclic form');
24m3a_printf(
'Fitting MAPH(2,m)\n');
30if nargin == 3 || isempty(classWeights)
31 classWeights = ones(k,1);
39% get parameters of the underlying AMAP(2)
44% set tolerance constants
50if abs(1-r1) < degentol
53 m3a_printf(
'Fitting MAPH(2,m): detected degenerate form\n');
55 % only one degree of freedom: match
class probabilites
65 % coefficients: q(j,c) = F(c) * q_b(j,c) + q_0(j,c)
70 q_b(1,c) = p(c) * ( 1/(h2*(r1 - 1)) );
71 q_0(1,c) = p(c) * ( -(h1 + h2)/(h2*(r1 - 1)) );
73 q_b(2,c) = p(c) * ( 1/(h2*r1) );
74 q_0(2,c) = p(c) * ( -h1/(h2*r1) );
77 % inequality constraints
82 row = ((c-1)*4+(j-1)*2);
85 A(row+1,col+1) = q_b(j,c);
86 b(row+1) = 1 - q_0(j,c);
88 A(row+2,col+1) = - q_b(j,c);
93 % equality constraints
97 % equality constraints
100 beq(j) = beq(j) - q_0(j,c);
109 backwardWeight = classWeights(c);
110 H(base+1,base+1) = 2/B(c)^2 * backwardWeight;
111 h(base+1) = -2/B(c) * backwardWeight;
114 % solve optimization problem
118 m3a_printf(
'Fitting MAPH(2,m): B(%d) = %f -> %f\n', c, B(c), fB(c));
121 % compute parameters of D11,D12,...,D1k
125 q(j,c) = fB(c) * q_b(j,c) + q_0(j,c);
131% check parameter feasibility
133 if ~(isfeasible(q(1,:)) && isfeasible(q(2,:)))
134 error(
'Fitting MAPH(2,m): Feasibility could not be restored');
137% parameters feasible within feastol: restrict to [0,1]
141% compute D11,D12,...,D1k
143 maph{2+c} = maph{2} .* [q(1,c) 0; q(2,c) 0];
146% the degenerate branch above matches the
class probabilities only and never
147% runs the solver, so fB
is still unset there: report the backward moments the
148% fitted MAPH actually realizes, which
is what the caller ranks the forms by
150 fB = mmap_backward_moment(maph, 1);
153 function feas = isfeasible(qj)
154 feas = min(qj) >= -feastol && sum(qj) <= (1+feastol);
157 function QJ = fix(qj)
160 QJ(cc) = max(qj(cc),0);
166 m3a_printf('Fitting MAPH(2,m): running quadratic programming solver...\n');
167 options = optimset('Algorithm','interior-point-convex','Display','none');
168 %[x,fx,xflag] = quadprog(H, h, A, b, Aeq, beq, [], [], [], options);
169 lb = 1e-6*ones( size(A,2),1);
170 ub = 1e6*ones( size(A,2),1);
171 [x,fx,xflag]=QP(H, h, A, b, Aeq, beq, lb, ub, options);
173 error('Quadratic programming solver failed: %d\n', exit);
175 fit_error = fx + length(x);
176 m3a_printf('Fitting MAPH(2,m): error = %f\n', fit_error);