0001 function [x_dir,ueq_dir,nFlag,pert]=solvekkt_ldl(obj,H,A,rhs1,rhs2)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018 start_time = cputime;
0019 [n m] = size(A);
0020
0021 LMUPDATE = obj.allopts.pert_update;
0022 LMLOW = obj.allopts.pert_min;
0023 PERT_TRY_MAX = obj.allopts.pert_try_max;
0024 pivot = obj.allopts.ldl_pivot;
0025
0026
0027 block22=sparse(m,m);
0028
0029 [L,D,perm] = ldl([H,A;A',block22],pivot,'vector');
0030 [e_pos, e_neg, e_zero] = inertia(D);
0031
0032 pert_try=0;
0033 lambda=max(obj.chol_lmlast/LMUPDATE, LMLOW);
0034 lambda_last=0.;
0035
0036 while ((e_zero>0 || e_neg>m) && pert_try<PERT_TRY_MAX)
0037 obj.print(4,Inf,'Wrong inertia: %d,%d,%d, new pert: %e',e_pos,e_neg,e_zero,lambda);
0038 H = H + (lambda-lambda_last)*speye(n,n);
0039 [L,D,perm] = ldl([H,A;A',block22],pivot,'vector');
0040 [e_pos, e_neg, e_zero] = inertia(D);
0041
0042 pert_try = pert_try+1;
0043 lambda_last=lambda;
0044 lambda=lambda*LMUPDATE;
0045 end
0046
0047 if (pert_try>0)
0048 obj.chol_lmlast=lambda_last;
0049 end
0050
0051
0052 time_factor = cputime-start_time;
0053 obj.stats_time_fact_last=obj.stats_time_fact_last+time_factor;
0054 obj.initer_last = obj.initer_last+pert_try+1;
0055 if (nargout>=4)
0056 pert=lambda_last;
0057 end
0058
0059 if (e_zero~=0 || e_neg~=m)
0060 obj.print(3,Inf,'Inertia control failure, wrong inertia: %d,%d,%d, last pert: %e',e_pos,e_neg,e_zero,lambda_last);
0061 nFlag = 1;
0062 x_dir=zeros(n,1);
0063 ueq_dir=zeros(m,1);
0064 return;
0065 end
0066
0067 rhs=[rhs1;rhs2];
0068
0069
0070 dir=L' \ (D \ (L \ rhs(perm)));
0071 dir(perm)=dir;
0072 x_dir=dir(1:n);
0073 ueq_dir=dir(n+1:n+m);
0074 time_total=cputime - start_time;
0075 nFlag=0;
0076
0077 obj.print(4,Inf,'LDL KKT OK, factor in %fs, total %fs, no pert=%i, pert=%.4e',time_factor, time_total, pert_try, lambda_last);
0078 if (lambda_last>0)
0079 obj.print(3,4,'LDL KKT solve: OK, pert=%.4e',lambda_last);
0080 end
0081
0082 end
0083
0084
0085 function [e_pos, e_neg, e_zero] = inertia(D)
0086
0087
0088
0089
0090 [dim dim2] = size(D);
0091 e=eig(D);
0092 e_pos=sum(e>0);
0093 e_neg=sum(e<0);
0094 e_zero=dim-e_pos-e_neg;
0095
0096 return;
0097
0098
0099 e_pos=0;
0100 e_neg=0;
0101
0102 i=1;
0103 while (i<=dim)
0104 if (i<dim && D(i,i+1))
0105 e=eig(D(i:i+1,i:i+1));
0106 e_pos = e_pos + sum(e>0);
0107 e_neg = e_neg + sum(e<0);
0108 i=i+2;
0109 else
0110 e_pos = e_pos + D(i,i)>0;
0111 e_neg = e_neg + D(i,i)<0;
0112 i=i+1;
0113 end
0114 end
0115 e_zero=dim-e_pos-e_neg;
0116
0117 end
0118