1function PH = kpcfit_ph_manual(E,varargin)
4% PH = kpcfit_ph_manual(E,
'option1',
'val1',
'option2',
'val2',...)
7% Fit phase-type (PH) process
using Kronecker Product Composition (KPC)
12% E - vector of moments of consecutive order to be fitted
18%
for k=1:6 E(k)=mean(S.^k); end
19% PH = kpcfit_ph_manual(E);
22%
'WantHyper' - boolean,
if true returns hyper-exponential distribution
23%
'NumStates' - integer, number of states of the PH distribution - **must be multiple of 2**,
default: 4
24%
'NumPHs' - integer, number of PHs to be composed,
default: 2 (i.e., PH(4))
25%
'NumMoms' - integer, moments considered in the moment matching problem,
default: 6
26%
'MaxIterMM' - integer, maximum number of iterations for a single moment-matching fitting run
45for i = 1:size(OptionNames,1)
46 options.(deblank(OptionNames(i,:)))=[];
53options.MaxIterMM = 100;
55% Parse optional parameters
56options=ParseOptPara(options,OptionNames,OptionTypes,OptionValues,varargin);
57if mod(options.NumStates,2) ~= 0
58 error('kpcfit_ph: number of states must be multiple of 2');
64optimoptions = optimset('Algorithm','active-set', ...
65 'LargeScale','off', ...
66 'MaxIter',options.MaxIterMM, ...
67 'MaxFunEvals',1e10, ...
71 'OutputFcn',@kpcfit_ph_manual_outfun);
75x0=zeros(3*options.NumPHs,1); % each PH brings 3 degrees of freedomg
76lgkx = x0; % last good known x
77n=length(E); % number of moments
84 PH=map_feasblock(rand,1000*rand,-1,0); % hyperexponential
87 x0((i-1)*options.NumPHs+j)=map_moment(PH,i);
91fmincon(@objfun,x0,[],[],[],[],x0*0+EPSTOL,[],@nnlcon,optimoptions);
92xtopar(lgkx); % this recomputes PH
93PH=map_normalize(map_scale(PH,E(1)));
95if map_isfeasible(PH)<10
96 warning('PH distribution may not be valid, check for negative rates in D1 or in off-diagonal of D0')
101 function [Eest]=xtopar(x)
105 E1j=x(1:options.NumPHs)';
106 SCVj=x((options.NumPHs+1):2*options.NumPHs)';
107 E2j=(1+SCVj).*(E1j.^2);
108 E3j=x((2*options.NumPHs+1):3*options.NumPHs);
112 PH = map_feasblock(E1j(1),E2j(1),E3j(1),rand);
114 PH = mmpp2_fit3(E1j(1),E2j(1),E3j(1),rand);
116 PH = map_scale(PH,E1j(1));
118 for j=2:options.NumPHs-1
119 [PHk]=map_feasblock(E1j(1),E2j(j),E3j(j),rand);
122 E1j(options.NumPHs)=E(1)/map_moment(PH,1);
123 E2j(options.NumPHs)=E(2)*2/map_moment(PH,2);
125 E3j(options.NumPHs)=E(3)*6/map_moment(PH,3);
127 x(2)=E1j(options.NumPHs);
128 x(4)=E2j(options.NumPHs);
129 x(6)=E3j(options.NumPHs);
132 [PH]=map_kpc(PH,map_feasblock(E1j(options.NumPHs),E2j(options.NumPHs),E3j(options.NumPHs),0));
133% F=map_feasblock(E1j(options.NumPHs),E2j(options.NumPHs),E3j(options.NumPHs),0);
141 PH{1}=diag(diag(PH{1}));
143 Eest(k)=map_moment(PH,k);
147 function [c,ceq]=nnlcon(x)
152 ceq(end+1)=norm((E(k))-(Eest(k)),1);
159 for k=(nexact+1):length(E)
160 f=f+norm(log10(E(k))-log10(Eest(k)),1);
166function [MAP]=map_rand(K)
176MAP=map_normalize(MAP);