eqsolve.src
来自「没有说明」· SRC 代码 · 共 549 行 · 第 1/2 页
SRC
549 行
end;
endif;
/*
** Initialize defaults.
**
*/
retcode = 0;
eta = sqrt(__macheps);
eqmtol = __macheps^(2/3);
if eqstol == 0;
eqstol = __macheps^(2/3);
endif;
if eqtol == 0;
eqtol = __macheps^(1/3);
endif;
if eqtypx == 0;
sx = ones(n,1);
typx = sx;
elseif rows(sx) == n;
typx = missrv(miss(eqtypx,0),1);
sx = 1/typx;
endif;
if eqtypf == 0;
sf = ones(n,1);
typf = sf;
elseif rows(sf) == n;
typf = missrv(miss(eqtypf,0),1);
sf = 1/typf;
endif;
sfsq = sf^2;
maxstep = (10^3)*maxc(sqrt(moment(sx.*x0,0))'|sqrt(moment(sx,0))');
if eqaltnam $== 0;
varlist = zeros(n,1) $+ "X" $+ ftocv(seqa(1,1,n), eqvpad*(floor(log(n)
)+1),0);
else;
if rows(eqaltnam) == n;
varlist = eqaltnam;
elseif cols(eqaltnam) == n;
varlist = eqaltnam';
else;
errorlog "\nERROR: Wrong number of rows in __altnam.\n";
end;
endif;
endif;
eqlist = 0 $+ "F" $+ ftocv(seqa(1,1,n), eqvpad*(floor(log(n))+1),0) $+
"(X)";
fmtstr = { "-*.*lf" 15 8, "*.*lf" 18 8, "*.*lf" 22 8, "*.*lf" 22 8 };
if eqjac;
jacob = eqjac; /* Assign pointer to jacob */
local jacob:proc; /* Assume jacob is procedure pointer */
jc = jacob(x0);
else;
jc = _eqs_jacob(&f,x0,fvc,0,typx,eta);
endif;
gc = jc'fvc;
xp = x0;
fc = 0.5*moment(sf.*fvc,0);
retcode = 0;
consecmx = 0;
itncount = 0;
if eqiterinfo;
print chrs(45*ones(80,1));
print " ROOTS";;
print chrs(32*ones(32,1)) " F(ROOTS)";
print chrs(45*ones(80,1));
print;
endif;
do while retcode == 0;
p = -fvc/jc;
gc = jc'fvc;
xc = xp;
local alpha,newtlen,rlength,minlam,lambda,ab,inslope,
ltemp, one,two,three,fpprev,a,b,disc,lprev, notdone,
tcode;
/* Initialize Parameters */
maxtaken = 0;
alpha = 1e-4;
newtlen = sqrt(moment(sx.*p,0));
if newtlen > maxstep;
p = p*(maxstep/newtlen);
newtlen = maxstep;
endif;
inslope = gc'p;
rlength = maxc(abs(p) ./ (maxc(xc'|(typx')) ));
if rlength == 0;
xp = xc;
fp = fc;
else;
minlam = eqstol/rlength;
lambda = 1;
notdone = 1;
do while notdone;
xp = xc + lambda*p;
fp = 0.5*moment(sf.*f(xp),0); /* objective function */
if fp <= fc + alpha*lambda*inslope;
if lambda == 1 and newtlen > .99*maxstep;
maxtaken = 1;
endif;
notdone = 0;
elseif lambda < minlam;
xp = xc;
notdone = 0;
else;
if lambda == 1;
/* Quadratic step */
ltemp = -inslope/(2*(fp-fc-inslope));
else;
one = 1/(lambda - lprev);
two = ((1/lambda^2 ~ -1/lprev^2) |
(-lprev/lambda^2 ~ lambda/lprev^2));
three = fp - fc - lambda *inslope | fpprev - fc
-lprev*inslope;
ab = one*two*three;
a = ab[1,1];
b = ab[2,1];
disc = b^2 - 3*a*inslope;
if ndpchk(8);
break;
elseif a == 0;
ltemp = -inslope/(2*b);
elseif disc <= 0 or ndpchk(8);
break;
else;
ltemp = (-b+sqrt(disc))/(3*a);
endif;
if ltemp > 0.5*lambda;
ltemp = 0.5*lambda;
endif;
endif;
lprev = lambda;
fpprev = fp;
if ltemp <= 0.1*lambda;
lambda = 0.1*lambda;
else;
lambda = ltemp;
endif;
endif;
endo;
endif;
fvp = f(xp);
if eqjac;
jc = jacob(xp);
else;
jc = _eqs_jacob(&f,xp,fvp,0,typx,eta);
endif;
/*
** Check to see if any stopping criteria have been met.
*/
if _eqs_norm2(fvp.*sf) <= eqtol;
retcode = 1; /* A proper termination */
elseif abs(xp-xc)./maxc(abs(xp)'|typx') <= eqstol;
retcode = 2; /* Algorithm may have bogged down */
elseif retcode == 1;
retcode = 3;
elseif itncount >= eqmaxit;
retcode = 4;
elseif maxtaken == 1;
consecmx = consecmx+1;
if consecmx == 20;
retcode = 5;
endif;
else;
consecmx = 0;
gp = jc'.*sfsq*fvp;
if maxc(abs((gp.* maxc(xp'|typx'))/maxc(fp|1/sf))) <= eqmtol;
retcode = 6;
endif;
endif;
itncount = itncount + 1;
if eqiterinfo > 0;
print "Iteration #" ftos(itncount,"%*.*lf",1,0);
call printfm(varlist~xp~eqlist~fvp,0~1~0~1,fmtstr);
print;
print;
endif;
fc = fp;
fvc = fvp;
endo;
retp(xp,retcode);
endp;
proc _eqs_norm2(x);
retp(0.5*sqrt(x'x));
endp;
proc _eqs_jacob(f,x,f0,dh,typx,eta);
local rows_f,rows_x,jacobian,i,xc,xp;
local f:proc;
rows_f = rows(f0);
rows_x = rows(x);
jacobian = zeros(rows_f,rows_x);
/* Computation of stepsize (dh) for gradient if dh == 0 */
if dh == 0;
dh = eta*maxc(abs(x')|typx');
dh = dh + (dh == 0);
endif;
xc = x + dh;
dh = xc - x; /* This increases precision slightly */
xp = x + eye(rows_x).*dh;
/* Calculate forward difference */
i = 1;
do until i > rows_x;
jacobian[.,i] = (f(xp[.,i]) - f0);
i = i + 1;
endo;
retp(jacobian./(dh'));
endp;
proc (0) = eqSolveSet;
gausset;
_eqs_typicalX = 0;
_eqs_typicalF = 0;
_eqs_IterInfo = 0;
_eqs_JacobianProc = 0;
_eqs_MaxIters = 100;
_eqs_StepTol = __macheps^(2/3);
endp;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?