0001 function [rRelStep, nFlag]=lseq_pen(obj, dir, udir, miter)
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 rAlphaMin = 1.0e-14;
0016 rPrecfac=10.0;
0017 rMacheps=1.0e-16;
0018
0019
0020 bJustStarted=0;
0021 if (isempty(obj.ls_rnu) || miter==0)
0022 obj.ls_rnu=0;
0023 bJustStarted=1;
0024 end
0025
0026 LSEQ_MAX_ITER = obj.allopts.max_lseq_iter;
0027 xall0 = obj.xall;
0028 ueq0 = obj.ueq;
0029
0030
0031
0032
0033
0034 rStepMax = 1.;
0035
0036
0037 rPi = dir'*(obj.ALdx - obj.eqdx*obj.ueq);
0038 rEqNorm0 = obj.eqx'*obj.eqx;
0039 rU0C0 = obj.ueq'*obj.eqx;
0040 rUgVh0 = (obj.ueq+udir)'*obj.eqx - 2*rU0C0;
0041
0042
0043 rNu_old = obj.ls_rnu;
0044 if (rEqNorm0 > 1e-12)
0045 rEtadd = (rPi + rUgVh0) / rEqNorm0;
0046 else
0047 rEtadd = 0.;
0048 end
0049
0050 if (bJustStarted)
0051 obj.ls_rnu = abs(rEtadd) + 0.1;
0052 else
0053 obj.ls_rnu = max(0.,rEtadd) + 0.1;
0054 end
0055
0056
0057 obj.print(4,Inf,'LSEQ (pen): penalty par. NU=%f', obj.ls_rnu);
0058
0059
0060 fx = obj.ALx;
0061 fx0 = fx;
0062 meritx0 = fx0 + .5*obj.ls_rnu*rEqNorm0;
0063 rDelal0 = rUgVh0 - obj.ls_rnu * rEqNorm0 + rPi;
0064
0065 obj.print(4,Inf,'LSEQ (pen): NU: %e %e %f', rDelal0, rEqNorm0, rEtadd);
0066
0067 rAlphaStep = 2.0*rStepMax;
0068
0069 ok=0;
0070 for iter=1:LSEQ_MAX_ITER
0071 rAlphaStep = rAlphaStep / 2.0;
0072
0073
0074
0075 obj.xall = xall0 + rAlphaStep*dir;
0076 obj.ueq = ueq0 + rAlphaStep*udir;
0077
0078 obj.eval_alx();
0079 fx=obj.ALx;
0080
0081 rEqNorm=obj.eqx'*obj.eqx;
0082 meritx = fx + .5*obj.ls_rnu*rEqNorm;
0083
0084 if (iter==1 && abs((fx - fx0)/(.5*(fx + fx0))) + abs(rEqNorm0 - rEqNorm) < 1.0e-14)
0085 ok=2;
0086 break;
0087 end
0088
0089 rUC = obj.ueq'*obj.eqx;
0090 rUgVh = rUC - rU0C0;
0091
0092 rZlhs = fx - fx0 + rUgVh - 1.0e-4 * rAlphaStep * (rPi + rUgVh0);
0093 rZrhs = (rEqNorm0 - rEqNorm) * .5 - rAlphaStep * 1.0e-4 * rEqNorm0;
0094
0095 if (abs(rZrhs) <= 1.0e-15 && rZlhs <= 1.0e-15 && isfinite(fx))
0096 ok=1;
0097 break;
0098 end
0099 if (rZrhs >= 0. && isfinite(fx))
0100 ok=1;
0101 break;
0102 end
0103
0104 rNu_ls = rZlhs / rZrhs;
0105
0106 if (iter > 1 && rNu_ls > obj.ls_rnu && isfinite(fx))
0107 ok=1;
0108 break;
0109 end
0110
0111 rLhs = meritx - meritx0 - rPrecfac * rMacheps * abs(meritx0);
0112 rRhs = rAlphaStep * 1.0e-4 * rDelal0;
0113
0114 if (rLhs <= rRhs && isfinite(fx))
0115 ok=1;
0116 break;
0117 end
0118
0119 if (rAlphaStep <= rAlphaMin)
0120 ok=1;
0121 break;
0122 end
0123
0124 end
0125
0126
0127 if (ok>0)
0128 obj.print(3,Inf,'LSEQ (pen): %i steps, rel. width %f',iter,rAlphaStep);
0129
0130
0131 obj.eval_aldx();
0132
0133 rRelStep=rAlphaStep;
0134 nFlag=0;
0135 else
0136 obj.print(3,Inf,'LSEQ (pen): failed - step too short, max_ls_it (%i)',iter);
0137
0138 obj.xall=xall0;
0139 obj.ueq=ueq0;
0140 obj.eval_alx();
0141
0142 rRelStep=0;
0143 nFlag=3;
0144 end
0145
0146 obj.lsiter_last = obj.lsiter_last+iter;
0147
0148
0149
0150
0151
0152
0153
0154
0155
0156
0157
0158
0159 return;
0160
0161
0162 function [phi, constr] = add_penalty_to(objective, rNu, x, ueq)
0163
0164
0165
0166
0167
0168
0169
0170 error('this is not adapted for PenLab');
0171 [f, constr]=objective(x,ueq);
0172 phi = f + 0.5*rNu*(constr'*constr);
0173
0174 return;
0175