1function [mmap,fF,fS,exact] = mamap22_fit_fs_multiclass(
map,p,F,S,classWeights,fsWeights,adjust)
2% Performs approximate fitting of a
MMAP given the underlying AMAP(2),
3% the
class probabilities (always fitted exactly), the forward moments,
4% and the one-step
class transition probabilities.
6% -
map: second-order AMAP underlying the MAMAP[2]
7% - p: vector of
class probabilities
8% - F: vector of forward moments
9% - S: matrix of the
class transition probabilities
10% - classWeights: optional vector of weights
for each class
11% - fsWeights: optional 2-vector of weights of forward moments and the
12%
class transition probabilities
14% - mmap: fitted MAMAP[2]
15% - fF: vector of optimal feasible forward moments
16% - fS: vector of optimal feasible
class transition probabilities
18if (size(
map{1},1) ~= 2)
19 error('Underlying MAP must be of second-order.');
22 error('Underlying MAP must be acyclic');
26elseif (
map{2}(1,1) == 0)
29 error('Underlying MAP must be in canonical acyclic form');
32fprintf('Fitting MAMAP(2,2) F+S: form = %d\n', form);
37 error('Fitting MAMAP(2,2) F+S: only two
classes supported');
40% default weights to use in the objective function
41if nargin < 5 || isempty(classWeights)
42 classWeights = ones(k,1);
44if nargin < 6 || isempty(fsWeights)
45 fsWeights = ones(2,1);
56% get parameters of the underlying AMAP(2)
62% set tolerance constants
67% generate required coefficients
69 [G,U,Y] = mamap2m_can1_coefficients(h1,h2,r1,r2);
72 [E,V,Z] = mamap2m_can2_coefficients(h1,h2,r1,r2);
78if (form == 1 && (r1 < degentol || r2 > 1-degentol || abs(h1 - h2 + h2*r1) < degentol )) || ...
79 (form == 2 && (r2 > 1-degentol || abs(h1 - h2 + h2*r1) < degentol ))
81 % TODO: transform into a valid second-order Poisson process
83 % DEGENERATE PHASE_TYPE
84 fprintf(
'Fitting MAMAP(2,2) F+S: detected Poisson process\n');
86 %
return marked poisson process
92 mmap{2+c} = mmap{2} * p(c);
95 fF = mmap_forward_moment(mmap,1);
96 fS = mmap_sigma(mmap);
100elseif form == 2 && r2 < degentol && abs(1-r1) < degentol
102 % DEGENERATE PHASE_TYPE
103 fprintf(
'Fitting MAMAP(2,2) F+S: detected degenerate phase-type form\n');
105 % only one degree of freedom: match
class probabilites
110elseif form == 1 && r2 < degentol
112 % CANONICAL PHASE_TYPE
113 fprintf(
'Fitting MAMAP(2,2) F+S: detected canonical phase-type form\n');
115 % convert to phase-type
120 % the forward moments are always equal to the ordinary moments
121 % since the backward moments are not provided as arguments,
122 % we set the backward moments to the ordinary moments as well
123 % TODO:
if hypoexponential convert to non-canonical phase-type
125 B(1) = map_mean(
aph);
126 B(2) = map_mean(
aph);
127 warning(
'Fitting MAMAP(2,2) F+S: setting backward moments to ordinary moments, you should try to fit B+S');
129 mmap = maph2m_fit_multiclass(
aph, p, B, classWeights);
131 fF = mmap_forward_moment(mmap, 1);
132 fS = mmap_sigma(mmap);
136elseif (form == 1 && abs(1-r1) < degentol) || ...
137 (form == 2 && abs(1-r1) < degentol)
139 % NON-CANONICAL PHASE_TYPE
140 fprintf(
'Fitting MAMAP(2,2) F+S: detected non-canonical phase-type form\n');
142 % two degrees of freedom: fit p and F, not S
143 [q1,q2,q3] = fit_can1_degen(F(1));
145 %
if unfeasible, perform approximate fitting
146 if ~(isfeasible(q1) && isfeasible(q2) && isfeasible(q3))
147 % four inequalities, one variable
151 q2_F = - p(1) / (h1 * (r2-1));
152 q2_0 = + p(1) * h2 / (h1 * (r2-1));
153 q3_F = - p(1) / (h1 * r2);
154 q3_0 = + p(1) * (h1 + h2) / (h1 * r2);
171 fF1 = solve_quadprog();
172 % compute coefficient
173 [q1, q2, q3] = fit_can1_degen(fF1);
176elseif form == 2 && r2 < degentol
178 % DEGENERATE CASE FOR gamma < 0
179 fprintf(
'Fitting MAMAP(2,2) F+S: detected degenerate MMAP form\n');
181 if fsWeights(1) > fsWeights(2)
182 fprintf('Fitting MAMAP(2,2) F+S: fitting F\n');
183 [q1,q2,q3] = fit_can2_degen_forward(F(1));
184 if ~(isfeasible(q1) && isfeasible(q2) && isfeasible(q3))
185 % four inequalities, one variable
189 q1_F = - p(1) * (r1 - 2) / ((r1-1)*(h1-h2+h2*r1));
190 q1_0 = + p(1) * (r1 - 2)*(h1 + h2*r1) / ((r1-1)*(h1-h2+h2*r1));
191 q2_F = - p(1) * (r1 - 2) / ((h1-h2+h2*r1));
192 q2_0 = + p(1) * (r1 - 2)*h2 / ((h1-h2+h2*r1));
209 fF1 = solve_quadprog();
210 % compute coefficient
211 [q1,q2,q3] = fit_can2_degen_forward(fF1);
214 fprintf('Fitting MAMAP(2,2) F+S: fitting S\n');
215 [q1,q2,q3] = fit_can2_degen_transition(S(1,1));
216 if ~(isfeasible(q1) && isfeasible(q2) && isfeasible(q3))
217 % nonlinear constraints: use yalmip
218 varS11 = sdpvar(1,1);
219 options = sdpsettings('verbose',0);
220 boundS11 = [varS11 >= 0, varS11 <= p(1)^2];
221 q1lb = varS11 >= p(1)^2 * (1 - (1-r1)^2);
222 q2ub = varS11 >= p(1)^2 - (1 - p(1))^2;
223 constraints = [boundS11, q1lb, q2ub];
224 obj = (varS11 - S(1,1))^2;
225 sol = solvesdp(constraints, obj, options);
227 error('Fitting MAMAP(2,2) F+S: YALMIP = %s\n', sol.info);
229 fprintf('Fitting MAMAP(2,2) F+S: YALMIP objective = %f\n',
double(obj));
231 % compute coefficient
232 [q1,q2,q3] = fit_can2_degen_transition(
double(varS11));
238 % FULL FORM or "GOOD" poisson process
240 if (form == 1 && abs(h2-h1*r2) < degentol) || (form == 2 && abs(h1 - h2 - h1*r1 + h1*r1*r2) < degentol)
241 fprintf('Fitting MAMAP(2,2) F+S: detected fittable Poisson process\n')
244 [q1,q2,q3] = fit(F(1), S(1,1));
246 % options used to solve the nonlinear problem
247 use_linprog_prepass = 1;
249 optim_space = 'hybrid';
250 %optim_space = 'hybrid-z';
251 %optim_space = 'param';
252 %optim_space = '
char';
254 yalmip_nonlinear_opt = sdpsettings(...
256 'solver','bmibnb',...
260 'bmibnb.relgaptol',1e-3,...
261 'bmibnb.absgaptol',1e-6,...
262 'bmibnb.maxiter',1000,...
263 'bmibnb.lowrank', 1,...
264 'bmibnb.lpreduce',1,... % without this, crappy lower bounds for some problems
265 'bmibnb.pdtol',-1e-8,... % x >= if x > -pdtol
266 'bmibnb.eqtol',+1e-10,... % x == 0 if abs(x) < +eqtol
267 'bmibnb.roottight',1,...
268 'bmibnb.uppersolver','fmincon-standard',...
269 'fmincon.Algorithm','sqp',...
270 'fmincon.TolCon',1e-6,...
271 'fmincon.TolX',1e-6,...
272 'fmincon.GradObj','on',...
273 'fmincon.GradConstr','on',...
274 'fmincon.Hessian','off',...
275 'fmincon.LargeScale','off');
280 if isfeasible(q1) && isfeasible(q2) && isfeasible(q3)
281 fprintf('Fitting MAMAP(2,2) F+S: exact fit found\n');
284 [q1,q2,q3] = solve_nonlinear(optim_space);
287end % end if/then/else for degenerate forms
289% check parameter feasibility
290if adjust && ~(isfeasible(q1) && isfeasible(q2) && isfeasible(q3))
291 error('Fitting MAMAP(2,2) F+S: Feasibility could not be restored: q1 = %e, q2 = %e, q3 = %e', q1, q2, q3);
293% parameters feasible within feastol: restrict to [0,1]
298% compute D11,D12,...,D1k
300 mmap{2+1} = mmap{2} .* [q1 0; q2 q3];
301 mmap{2+2} = mmap{2} .* [1-q1 0; 1-q2 1-q3];
303 mmap{2+1} = mmap{2} .* [0 q1; q2 q3];
304 mmap{2+2} = mmap{2} .* [0 1-q1; 1-q2 1-q3];
307fF = mmap_forward_moment(mmap, 1);
308fS = mmap_sigma(mmap);
310 function feas = isfeasible(q)
311 feas = q >= -feastol && q <= (1+feastol);
314 function qfix = fix(q)
315 qfix = max(min(q,1),0);
318 function [q1,q2,q3] = fit_can1(vF1,vS11)
319 denum = p(1) * (U(5) * vF1 + U(6));
320 if abs(denum) < denumtol
325 q2 = (U(1) * vF1^2 * p(1)^2 + U(2) * vF1 * p(1)^2 + U(3) * vS11 + U(4) * p(1)^2)/denum;
326 q1 = -(G(15)*p(1) - vF1*G(3)*p(1) + (G(3)*G(14) - G(2)*G(15)) * q2)/Y(2);
327 q3 = +(G(13)*p(1) - vF1*G(1)*p(1) + (G(1)*G(14) - G(2)*G(13)) * q2)/Y(2);
331 function [q1,q2,q3] = fit_can1_degen(vF1)
332 q1 = p(1); % meangingless
if really degenerate
333 q2 = p(1) * (h2 - vF1) / (h1 * (r2-1));
334 q3 = p(1) * (h1 + h2 - vF1) / (h1 * r2);
337 function [q1,q2,q3] = fit_can2_degen_forward(vF1)
338 q1 = + p(1) * (r1 - 2)*(h1 + h2*r1 - vF1)/((r1-1)*(h1-h2+h2*r1));
339 q2 = - p(1) * (vF1 - h2)*(r1 - 2)/((h1-h2+h2*r1));
340 q3 = p(1); % meangingless
if really degenerate
343 function [q1,q2,q3] = fit_can2_degen_transition(vS11)
344 q1 = p(1) + (p(1)^2 - vS11)^(1/2)/(r1 - 1);
345 q2 = p(1) + (p(1)^2 - vS11)^(1/2);
346 q3 = p(1); % meangingless
if really degenerate
349 function [q1,q2,q3] = fit_can2(vF1,vS11)
350 denum = (V(5) * vF1 * p(1) + V(6) * p(1));
351 if abs(denum) < denumtol
356 q3 = (V(1) * vF1^2 * p(1)^2 + V(2) * vF1 * p(1)^2 + V(3) * p(1)^2 + V(4) * vS11)/denum;
357 q1 = -(E(13)*p(1) - vF1*E(2)*p(1) + (E(2)*E(14) - E(3)*E(13)) * q3)/Z(2);
358 q2 = +(E(12)*p(1) - vF1*E(1)*p(1) + (E(1)*E(14) - E(3)*E(12)) * q3)/Z(2);
362 function [pexp,pFexp,Sexp] = get_characteristics(q1,q2,q3)
364 pexp = G(1)*q1+G(2)*q2+G(3)*q3;
365 pFexp = G(13)*q1+G(14)*q2+G(15)*q3;
366 Sexp = G(4)*q1^2 + G(5)*q1*q2 + G(6)*q1*q3 + G(7)*q2^2 + G(8)*q2*q3 + G(9)*q3^2;
368 pexp = E(1)*q1+E(2)*q2+E(3)*q3;
369 pFexp = (E(12)*q1+E(13)*q2+E(14)*q3);
370 Sexp = E(4)*q1*q2 + E(5)*q1*q3 + E(6)*q2^2 + E(7)*q2*q3 + E(8)*q3^2;
374 function opt = get_yalmip_linear_options()
375 % we
do not set solver so that YALMIP picks the best
376 opt = sdpsettings(
'verbose',0);
379 function [q1,q2,q3,obj] = solve_nonlinear(optim_space)
381 fprintf(
'Fitting MAMAP(2,2) F+S: running approximate fitting (nonlinear)\n');
383 if strcmp(optim_space,
'param')
384 [q1,q2,q3,obj] = solve_nonlinear_param();
386 if strcmp(optim_space,
'hybrid')
387 solve_nonlinear_func = @solve_nonlinear_hybrid;
388 elseif strcmp(optim_space, 'hybrid-z')
389 solve_nonlinear_func = @solve_nonlinear_hybrid_z;
390 elseif strcmp(optim_space, '
char')
391 solve_nonlinear_func = @solve_nonlinear_char;
393 error('Fitting MAMAP(2,2) F+S: invalid value for option "optim_space"');
396 eobj = make_objective(M1, p(1)^2);
397 fprintf('Fitting MAMAP(2,2) F+S: F1 == M1, objective = %e\n', eobj);
399 [lfeas,lobj,lF1,lS11] = solve_nonlinear_func('left');
401 fprintf('Fitting MAMAP(2,2) F+S: F1 < M1, objective = %e\n', lobj);
403 fprintf('Fitting MAMAP(2,2) F+S: F1 < M1 infeasible\n');
406 [rfeas,robj,rF1,rS11] = solve_nonlinear_func('right');
408 fprintf('Fitting MAMAP(2,2) F+S: F1 > M1, objective = %e\n', robj);
410 fprintf('Fitting MAMAP(2,2) F+S: F1 > M1 infeasible\n');
413 if (~lfeas && ~rfeas) || (eobj < lobj && eobj < robj)
418 elseif ~rfeas || lobj < robj
420 [q1,q2,q3] = fit(lF1, lS11);
423 [q1,q2,q3] = fit(rF1, rS11);
429% used for non-degenerate cases: parmeter space
430 function [q1,q2,q3,obj] = solve_nonlinear_param()
431 % find initial feasible solution
435 [pexp,pFexp,Sexp] = get_characteristics(vq(1),vq(2),vq(3));
437 cstr_exact_p = pexp == p(1);
438 cstr_tighten_F = -z(1) <= (pFexp - p(1)*F(1))/(p(1)*F(1)) <= z(1);
439 cstr_tighten_S = -z(2) <= (Sexp - S(1,1))/S(1,1) <= z(2);
440 cstr = [0 <= vq(1) <= 1, ...
446 z(1) >= 0, z(2) >= 0];
448 zobj = fsWeights(1) * z(1)^2 + fsWeights(2) * z(2)^2;
450 zsol = solvesdp(cstr, zobj, yalmip_nonlinear_opt);
457 fprintf('Fitting MAMAP(2,2) F+S: solver (parameter space) objective = %e\n', obj);
460 save(fname,'
map','p','F','S');
461 error('Fitting MAMAP(2,2) F+S: solver (parameter space) error: %s, input saved to %s\n', zsol.info, fname);
465% used for non-degenerate cases: hybrid space
466 function [feas,bobj,bF1,bS11] = solve_nonlinear_hybrid(side)
472 q1exp = -(G(15)*p(1) - vF1*G(3)*p(1) + vq2*(G(14)*G(3)-G(15)*G(2)))/Y(2);
473 q2num = U(1)*vF1^2*p(1)^2 + U(2)*vF1*p(1)^2 + U(3)*vS11 + U(4)*p(1)^2;
474 q2den = p(1)*(U(5)*vF1 + U(6));
475 q3exp = +(G(13)*p(1) - vF1*G(1)*p(1) + vq2*(G(14)*G(1)-G(13)*G(2)))/Y(2);
476 hcstr = [0 <= q1exp <= 1, 0 <= vq2 <= 1, vq2*q2den/scale == q2num/scale, 0 <= q3exp <= 1, 0 <= vS11 <= 1, vF1 >= 0];
480 q1exp = -(E(13)*p(1) - vF1*E(2)*p(1) + vq3*(E(14)*E(2)-E(13)*E(3)))/Z(2);
481 q2exp = +(E(12)*p(1) - vF1*E(1)*p(1) + vq3*(E(14)*E(1)-E(12)*E(3)))/Z(2);
482 q3num = V(1)*vF1^2*p(1)^2 + V(2)*vF1*p(1)^2 + V(3)*p(1)^2 + V(4)*vS11;
483 q3den = p(1)*(V(5)*vF1 + V(6));
484 hcstr = [0 <= q1exp <= 1, 0 <= q2exp <= 1, vq3*q3den/scale == q3num/scale, 0 <= vq3 <= 1, 0 <= vS11 <= 1, vF1 >= 0];
486 if strcmp(side,'left')
487 hcstr = [hcstr, vF1 <= M1-tol];
489 hcstr = [hcstr, vF1 >= M1+tol];
491 hobj = make_objective(vF1,vS11);
492 hsol = solvesdp(hcstr, hobj, yalmip_nonlinear_opt);
494 fprintf('Fitting MAMAP(2,2) F+S: solver (hybrid space) objective = %f\n',
double(hobj));
499 elseif hsol.problem == 1 || hsol.problem == 12
500 fprintf('Fitting MAMAP(2,2) F+S: program
is infeasible\n');
507 save(fname,'
map','p','F','S');
508 error('Fitting MAMAP(2,2) F+S: solver (hybrid space) error: %s, input saved to %s\n', hsol.info, fname);
512% used for non-degenerate cases: hybrid space with z variable and implicit vS11
513 function [feas,bobj,bF1,bS11] = solve_nonlinear_hybrid_z(side)
518 q1exp = -(G(15)*p(1) - vF1*G(3)*p(1) + vq2*(G(14)*G(3)-G(15)*G(2)))/Y(2);
519 q2den = p(1)*(U(5)*vF1 + U(6));
520 q3exp = +(G(13)*p(1) - vF1*G(1)*p(1) + vq2*(G(14)*G(1)-G(13)*G(2)))/Y(2);
521 S11exp = (vq2*q2den - p(1)^2*(U(1)*vF1^2 + U(2)*vF1 + U(4)))/U(3);
522 tighten = -z <= S11exp - S(1,1) <= +z;
523 hcstr = [0 <= q1exp <= 1, 0 <= vq2 <= 1, 0 <= q3exp <= 1, vF1 >= 0, tighten];
526 q1exp = -(E(13)*p(1) - vF1*E(2)*p(1) + vq3*(E(14)*E(2)-E(13)*E(3)))/Z(2);
527 q2exp = +(E(12)*p(1) - vF1*E(1)*p(1) + vq3*(E(14)*E(1)-E(12)*E(3)))/Z(2);
528 q3den = p(1)*(V(5)*vF1 + V(6));
529 S11exp = (vq3*q3den - p(1)^2*(V(1)*vF1^2 + V(2)*vF1 + V(3)))/V(4);
530 tighten = -z <= S11exp - S(1,1) <= +z;
531 hcstr = [0 <= q1exp <= 1, 0 <= q2exp <= 1, 0 <= vq3 <= 1, vF1 >= 0, tighten];
533 if strcmp(side,'left')
534 hcstr = [hcstr, vF1 <= M1-tol];
536 hcstr = [hcstr, vF1 >= M1+tol];
538 hobj = fsWeights(1)*(vF1/F(1)-1)^2 + fsWeights(2)*(z/S(1,1))^2;
539 hsol = solvesdp(hcstr, hobj, yalmip_nonlinear_opt);
541 fprintf('Fitting MAMAP(2,2) F+S: solver (hybrid-z space) objective = %f\n',
double(hobj));
545 bS11 =
double(S11exp);
546 elseif hsol.problem == 1 || hsol.problem == 12
547 fprintf('Fitting MAMAP(2,2) F+S: program
is infeasible\n');
554 save(fname,'
map','p','F','S');
555 error('Fitting MAMAP(2,2) F+S: solver (hybrid-z space) error: %s, input saved to %s\n', hsol.info, fname);
559% used for non-degenerate cases: characteristic space
560 function [feas,bobj,bF1,bS11] = solve_nonlinear_char(side)
562 if strcmp(side,'left')
563 fprintf('Fitting MAMAP(2,2) F+S: optimizing for F11 < M1\n');
566 fprintf('Fitting MAMAP(2,2) F+S: optimizing for F11 > M1\n');
568 % find initial feasible solution
569 if use_linprog_prepass
570 % parameter variables vq and auxiliary variables
574 [pexp,pFexp,Sexp] = get_characteristics(vq(1),vq(2),vq(3));
577 cstr_side = pFexp <= pexp*(M1-tol);
579 cstr_side = pFexp >= pexp*(M1+tol);
581 cstr_exact_p = pexp == p(1);
582 cstr_tighten = -z <= pFexp-p(1)*F(1) <=z;
583 fcstr = [0 <= vq(1) <= 1, ...
590 % run linear programming solver
591 lsol = solvesdp(fcstr,z, get_yalmip_linear_options());
595 iF1 =
double(pFexp / pexp);
597 elseif lsol.problem == 1 || lsol.problem == 12
598 fprintf('Fitting MAMAP(2,2) F+S: linear program
is infeasible\n');
602 save(fname,'
map','p','F','S');
603 error('Fitting MAMAP(2,2) F+S: linear program error: %s, input saved to %s\n', lsol.info, fname);
609 % if feasible, solve nonlinear program
611 % declare variables for optimization in characteristic space
614 % initialize variables
615 if use_linprog_prepass
619 % define objective function
620 cobj = make_objective(vF1, vS11);
624 [cstr,~] = make_constraints_can1(p(1), vF1, vS11);
626 [cstr,~] = make_constraints_can2(p(1), vF1, vS11);
630 [~,cstr] = make_constraints_can1(p(1), vF1, vS11);
632 [~,cstr] = make_constraints_can2(p(1), vF1, vS11);
635 % solve nonlinear problem
636 csol = solvesdp(cstr, cobj, yalmip_nonlinear_opt);
640 save(fname,'
map','p','F','S');
641 error('Fitting MAMAP(2,2) F+S: solver (characteristic space) error: %s, input saved to %s\n', csol.info, fname);
646 fprintf('Fitting MAMAP(2,2) F+S: solver (characteristic space) objective = %e\n',
double(cobj));
649 % infeasible subproblem
656 function obj = make_objective(vF1, vS11)
657 obj = classWeights(1) * fsWeights(1) * (vF1/F(1) - 1)^2 + ...
658 classWeights(1) * fsWeights(2) * (vS11/S(1,1) - 1)^2;
661 function [q1n,q1d,q2n,q2d,q3] = make_q_can1(p, vF1, vS11)
662 % define coefficients of polynomials
663 q1n_F = p^2*(r1 - 1)*(r1*r2 - r2 + 1);
664 q1n_s = -r1*(h1 - h2 + h2*r1);
665 q1n_1 = h1*p^2*(r1*r2 - r2 + 1);
666 q1d_F = p*(r1 - 1)*(r1*r2 - r2 + 1);
667 q1d_1 = -p*(r1 - 1)*(h1 - h1*r2 + h2*r1);
668 q2n_Fsq = -p^2*(r1*r2 - r2 + 1)^2;
669 q2n_F = p^2*(r1*r2 - r2 + 1)*(2*h1 - h1*r1 - 2*h1*r2 + 3*h2*r1 - h2*r1^2 + h2*r1^2*r2 + h1*r1*r2 - h2*r1*r2);
670 q2n_s = -r1*(r2 - 1)*(h1 - h2 + h2*r1)^2;
671 q2n_1 = -p^2*(r1*r2 - r2 + 1)*(h2^2*r1 - h1^2*r2 + h1^2 + h1*h2*r1 - h1*h2*r1*r2);
672 q2d_F = p*r1*(r2 - 1)*(r1*r2 - r2 + 1)*(h1 - h2 + h2*r1);
673 q2d_1 = -p*r1*(r2 - 1)*(h1 - h1*r2 + h2*r1)*(h1 - h2 + h2*r1);
674 q3_F = -(p*(r1*r2 - r2 + 1))/(r1*r2*(h1 + h2*(r1 - 1)));
675 q3_1 = (p*(h1 + h2*r1)*(r1*r2 - r2 + 1))/(r1*r2*(h1 - h2 + h2*r1));
677 q1n = q1n_F * vF1 + q1n_s * vS11 + q1n_1;
678 q1d = q1d_F * vF1 + q1d_1;
679 q2n = q2n_Fsq * vF1^2 + q2n_F * vF1 + q2n_s * vS11 + q2n_1;
680 q2d = q2d_F * vF1 + q2d_1;
681 q3 = q3_F * vF1 + q3_1;
684 function [lcstr,rcstr] = make_constraints_can1(p, vF1, vS11)
686 % get fitting expressions
687 [q1n,q1d,q2n,q2d,q3] = make_q_can1(p, vF1, vS11);
689 % these are in common for the two subproblems
694 %scale = 1/abs(q2d{M1-tol});
696 % left constraints: F(1) < M1
700 %
do not change direction of inequalities
for q2
701 q2lb = scale*(q2n) >= 0;
702 q2ub = scale*(q2n) <= scale*(q2d);
704 % change direction of inequalities
for q2
705 q2lb = scale*(q2n) <= 0;
706 q2ub = scale*(q2n) >= scale*(q2d);
708 F1bound = vF1 <= M1-tol;
709 lcstr = [q1lb,q1ub,q2lb,q2ub,q3lb,q3ub,F1bound,vS11 >= 0, vS11 <= 1];
711 % right constraints: F(1) > M1
715 %
do not change direction of inequalities
for q2
716 q2lb = scale*(q2n) >= 0;
717 q2ub = scale*(q2n) <= scale*(q2d);
719 % change direction of inequalities
for q2
720 q2lb = scale*(q2n) <= 0;
721 q2ub = scale*(q2n) >= scale*(q2d);
723 F1bound = vF1 >= M1+tol;
724 rcstr = [q1lb,q1ub,q2lb,q2ub,q3lb,q3ub,F1bound,vS11 >= 0, vS11 <= 1];
727 function [q1n,q1d,q2,q3n,q3d] = make_q_can2(p, vF1, vS11)
728 % define coefficients of polynomials
729 q1n_F = p^2*(r1 - 1)*(r1 + r2 - r1*r2 - 2);
730 q1n_s = h1 - h2 + h2*r1;
731 q1n_1 = h1*p^2*(r1 + r2 - r1*r2 - 2);
732 q1d_F = p*(r1 - 1)*(r1 + r2 - r1*r2 - 2);
733 q1d_1 = p*(r1 - 1)*(h1 + h2 - h1*r2);
734 q2_F = p*(r1 + r2 - r1*r2 - 2)/(h2 - h1 + h1*r2 - h2*r1 - h2*r2 + h2*r1*r2);
735 q2_1 = -h2*p*(r1 + r2 - r1*r2 - 2)/(h2 - h1 + h1*r2 - h2*r1 - h2*r2 + h2*r1*r2);
736 q3n_Fsq = p^2*(r1 + r2 - r1*r2 - 2)^2;
737 q3n_F = p^2*(r1 + r2 - r1*r2 - 2)*(2*h1 + 2*h2 - h1*r2 - h2*r2 + h2*r1*r2);
738 q3n_s = -(r2 - 1)*(h1 - h2 + h2*r1)^2;
739 q3n_1 = -h2*p^2*(2*h1 - h1*r2 + h2*r1)*(r1 + r2 - r1*r2 - 2);
740 q3d_F = p*r2*(h1 - h2 + h2*r1)*(r1 + r2 - r1*r2 - 2);
741 q3d_1 = p*r2*(h1 + h2 - h1*r2)*(h1 - h2 + h2*r1);
743 q1n = q1n_F * vF1 + q1n_s * vS11 + q1n_1;
744 q1d = q1d_F * vF1 + q1d_1;
745 q2 = q2_F * vF1 + q2_1;
746 q3n = q3n_Fsq * vF1^2 + q3n_F * vF1 + q3n_s * vS11 + q3n_1;
747 q3d = q3d_F * vF1 + q3d_1;
750 function [lcstr,rcstr] = make_constraints_can2(p, vF1, vS11)
752 % get fitting expressions
753 [q1n,q1d,q2,q3n,q3d] = make_q_can2(p, vF1, vS11);
755 % these are in common
for the two subproblems
760 %scale = 1/abs(q3d{M1-tol});
762 % left constraints: F1 < M1
765 if (h1 - h2 + h2*r1) < 0
766 q3lb = scale*(q3n) <= 0;
767 q3ub = scale*(q3n) >= scale*(q3d);
769 q3lb = scale*(q3n) >= 0;
770 q3ub = scale*(q3n) <= scale*(q3d);
772 F1bound = vF1 <= M1-tol;
773 lcstr = [q1lb,q1ub,q2lb,q2ub,q3lb,q3ub,F1bound,vS11 >= 0, vS11 <= 1];
775 % rigt costraints: F1 > M1
778 if (h1 - h2 + h2*r1) < 0
779 q3lb = scale*(q3n) >= 0;
780 q3ub = scale*(q3n) <= scale*(q3d);
782 q3lb = scale*(q3n) <= 0;
783 q3ub = scale*(q3n) >= scale*(q3d);
785 F1bound = vF1 >= M1+tol;
786 rcstr = [q1lb,q1ub,q2lb,q2ub,q3lb,q3ub,F1bound,vS11 >= 0, vS11 <= 1];
789% used
for degenerate
case
790 function x = solve_quadprog()
791 fprintf('Fitting MAMAP(2,2) F+S: running quadratic programming solver...\n');
792 options = optimset('Algorithm','interior-point-convex','Display','none');
793 %[x,fx,xflag] = quadprog(H, h, A, b, [], [], [], [], [], options);
794 lb = 1e-6*ones( size(A,2),1);
795 ub = 1e6*ones( size(A,2),1);
796 [x,fx,xflag]=QP(H, h, A, b, Aeq, beq, lb, ub, options);
799 error('Quadratic programming solver failed: %d\n', exit);
801 fit_error = fx + length(x);
802 fprintf('Fitting MAMAP(2,2) F+S: error = %f\n', fit_error);