📄 searchq.c
字号:
/*
* MATLAB Compiler: 2.0.1
* Date: Tue May 08 21:28:22 2001
* Arguments: "-B" "sgl" "-m" "-W" "mainhg" "-L" "C" "asufit.m" "absfun.m"
* "absfunfree.m" "absfunshift.m" "absfunwidth.m" "dispfit.m" "dispfitdisp.m"
* "dispfitfree.m" "dispfitwidth.m" "seqmodfree.m" "spcfun.m" "spcfun1.m"
* "atamult.m" "aprecon.m"
*/
#include "searchq.h"
#include "cubici2.h"
/*
* The function "Msearchq" is the implementation version of the "searchq"
* M-function from file "C:\MATLABR11\toolbox\optim\searchq.m" (lines 1-86). It
* contains the actual compiled code for that M-function. It is a static
* function and must only be called from one of the interface functions,
* appearing below.
*/
/*
* function [pcnt, matl,matx,stepsize,fnew,how]=searchq(pcnt,fnew,oldx,matl,matx,sd,gdold,stepsize,how)
*/
static mxArray * Msearchq(mxArray * * matl,
mxArray * * matx,
mxArray * * stepsize,
mxArray * * fnew,
mxArray * * how,
int nargout_,
mxArray * pcnt_,
mxArray * fnew_,
mxArray * oldx,
mxArray * matl_,
mxArray * matx_,
mxArray * sd,
mxArray * gdold,
mxArray * stepsize_,
mxArray * how_) {
mxArray * pcnt = mclGetUninitializedArray();
mxArray * newstep = mclGetUninitializedArray();
mclValidateInputs(
"searchq",
9,
&pcnt_,
&fnew_,
&oldx,
&matl_,
&matx_,
&sd,
&gdold,
&stepsize_,
&how_);
mclCopyInputArg(&pcnt, pcnt_);
mclCopyInputArg(matl, matl_);
mclCopyInputArg(matx, matx_);
mclCopyInputArg(stepsize, stepsize_);
mclCopyInputArg(fnew, fnew_);
mclCopyInputArg(how, how_);
/*
* %SEARCHQ Line search routine for FMINU and LEASTSQ functions.
* % Performs line search procedure for unconstrained and least squares
* % optimization. Uses Quadratic Interpolation.
* % When finished pcnt returns 0.
*
* % Copyright (c) 1990-98 by The MathWorks, Inc.
* % $Revision: 1.11 $ $Date: 1997/11/29 01:23:25 $
* % Andy Grace 7-9-90.
* if pcnt==1
*/
if (mlfTobool(mlfEq(pcnt, mlfScalar(1.0)))) {
/*
* % Case 1: Next point less than initial point.
* % Increase step-length based on last gradient evaluation
* if fnew<matl(1)
*/
if (mlfTobool(
mlfLt(*fnew, mlfIndexRef(*matl, "(?)", mlfScalar(1.0))))) {
/*
* % Quadratic Extrapolation using gradient of first point and
* % values of two other points.
* matl(2)=fnew;
*/
mlfIndexAssign(matl, "(?)", mlfScalar(2.0), *fnew);
/*
* matx(2)=stepsize;
*/
mlfIndexAssign(matx, "(?)", mlfScalar(2.0), *stepsize);
/*
* newstep=-0.5*gdold*stepsize*stepsize/(fnew-gdold*stepsize-matl(1)+eps);
*/
mlfAssign(
&newstep,
mlfMrdivide(
mlfMtimes(
mlfMtimes(mlfMtimes(mlfScalar(-0.5), gdold), *stepsize),
*stepsize),
mlfPlus(
mlfMinus(
mlfMinus(*fnew, mlfMtimes(gdold, *stepsize)),
mlfIndexRef(*matl, "(?)", mlfScalar(1.0))),
mlfEps())));
/*
* if newstep<stepsize,how=[how,'QEF ']; newstep=1.2*stepsize; end
*/
if (mlfTobool(mlfLt(newstep, *stepsize))) {
mlfAssign(how, mlfHorzcat(*how, mxCreateString("QEF "), NULL));
mlfAssign(&newstep, mlfMtimes(mlfScalar(1.2), *stepsize));
}
/*
* stepsize=1.2*newstep;
*/
mlfAssign(stepsize, mlfMtimes(mlfScalar(1.2), newstep));
/*
* pcnt=2;
*/
mlfAssign(&pcnt, mlfScalar(2.0));
/*
* else
*/
} else {
/*
* % Case 2: New point greater than initial point. Decrease step-length.
* matl(3)=fnew;
*/
mlfIndexAssign(matl, "(?)", mlfScalar(3.0), *fnew);
/*
* matx(3)=stepsize;
*/
mlfIndexAssign(matx, "(?)", mlfScalar(3.0), *stepsize);
/*
* %Interpolate to get stepsize
* stepsize=max([1e-8*stepsize,-gdold*0.5*stepsize^2/(fnew-gdold*stepsize-matl(1)+eps)]);
*/
mlfAssign(
stepsize,
mlfMax(
NULL,
mlfHorzcat(
mlfMtimes(mlfScalar(1e-8), *stepsize),
mlfMrdivide(
mlfMtimes(
mlfMtimes(mlfUminus(gdold), mlfScalar(0.5)),
mlfMpower(*stepsize, mlfScalar(2.0))),
mlfPlus(
mlfMinus(
mlfMinus(*fnew, mlfMtimes(gdold, *stepsize)),
mlfIndexRef(*matl, "(?)", mlfScalar(1.0))),
mlfEps())),
NULL),
NULL,
NULL));
/*
* how=[how,'r'];
*/
mlfAssign(how, mlfHorzcat(*how, mxCreateString("r"), NULL));
/*
* pcnt=3;
*/
mlfAssign(&pcnt, mlfScalar(3.0));
/*
* end
*/
}
/*
* % Case 3: Last run was Case 1 (pcnt=2) and new point less than
* % both of other 2. Replace.
* elseif pcnt==2 & fnew< matl(2)
*/
} else {
mxArray * a_ = mclInitialize(mlfEq(pcnt, mlfScalar(2.0)));
if (mlfTobool(a_)
&& mlfTobool(
mlfAnd(
a_,
mlfLt(*fnew, mlfIndexRef(*matl, "(?)", mlfScalar(2.0)))))) {
mxDestroyArray(a_);
/*
* newstep=cubici2(gdold,[matl(1);matl(2);fnew],[matx(1);matx(2);stepsize]);
*/
mlfAssign(
&newstep,
mlfCubici2(
gdold,
mlfVertcat(
mlfHorzcat(mlfIndexRef(*matl, "(?)", mlfScalar(1.0)), NULL),
mlfHorzcat(mlfIndexRef(*matl, "(?)", mlfScalar(2.0)), NULL),
mlfHorzcat(*fnew, NULL),
NULL),
mlfVertcat(
mlfHorzcat(mlfIndexRef(*matx, "(?)", mlfScalar(1.0)), NULL),
mlfHorzcat(mlfIndexRef(*matx, "(?)", mlfScalar(2.0)), NULL),
mlfHorzcat(*stepsize, NULL),
NULL)));
/*
* if newstep<stepsize,how=[how, 'CEF ']; end
*/
if (mlfTobool(mlfLt(newstep, *stepsize))) {
mlfAssign(how, mlfHorzcat(*how, mxCreateString("CEF "), NULL));
}
/*
* matl(1)=matl(2);
*/
mlfIndexAssign(
matl,
"(?)",
mlfScalar(1.0),
mlfIndexRef(*matl, "(?)", mlfScalar(2.0)));
/*
* matx(1)=matx(2);
*/
mlfIndexAssign(
matx,
"(?)",
mlfScalar(1.0),
mlfIndexRef(*matx, "(?)", mlfScalar(2.0)));
/*
* matl(2)=fnew;
*/
mlfIndexAssign(matl, "(?)", mlfScalar(2.0), *fnew);
/*
* matx(2)=stepsize;
*/
mlfIndexAssign(matx, "(?)", mlfScalar(2.0), *stepsize);
/*
* stepsize=min([newstep,1])+1.5*stepsize;
*/
mlfAssign(
stepsize,
mlfPlus(
mlfMin(
NULL, mlfHorzcat(newstep, mlfScalar(1.0), NULL), NULL, NULL),
mlfMtimes(mlfScalar(1.5), *stepsize)));
/*
* stepsize=max([1.2*newstep,1.2*stepsize]);
*/
mlfAssign(
stepsize,
mlfMax(
NULL,
mlfHorzcat(
mlfMtimes(mlfScalar(1.2), newstep),
mlfMtimes(mlfScalar(1.2), *stepsize),
NULL),
NULL,
NULL));
/*
* how=[how,'i'];
*/
mlfAssign(how, mlfHorzcat(*how, mxCreateString("i"), NULL));
/*
* % Case 4: Last run was Case 2: (pcnt=3) and new function still
* % greater than initial value.
* elseif pcnt==3 & fnew>=matl(1)
*/
} else {
mxDestroyArray(a_);
{
mxArray * a_ = mclInitialize(mlfEq(pcnt, mlfScalar(3.0)));
if (mlfTobool(a_)
&& mlfTobool(
mlfAnd(
a_,
mlfGe(
*fnew,
mlfIndexRef(*matl, "(?)", mlfScalar(1.0)))))) {
mxDestroyArray(a_);
/*
* matl(2)=fnew;
*/
mlfIndexAssign(matl, "(?)", mlfScalar(2.0), *fnew);
/*
* matx(2)=stepsize;
*/
mlfIndexAssign(matx, "(?)", mlfScalar(2.0), *stepsize);
/*
* if stepsize<1e-6
*/
if (mlfTobool(mlfLt(*stepsize, mlfScalar(1e-6)))) {
/*
* newstep=-stepsize/2;
*/
mlfAssign(
&newstep,
mlfMrdivide(mlfUminus(*stepsize), mlfScalar(2.0)));
/*
* % Give up if the step-size gets too small
* % Stops infinite loops if no improvement is possible.
* if abs(newstep) < (eps * eps), pcnt = 0; end
*/
if (mlfTobool(
mlfLt(
mlfAbs(newstep),
mlfMtimes(mlfEps(), mlfEps())))) {
mlfAssign(&pcnt, mlfScalar(0.0));
}
/*
* else
*/
} else {
/*
* newstep=cubici2(gdold,[matl(1);matl(3);fnew],[matx(1);matx(3);stepsize]);
*/
mlfAssign(
&newstep,
mlfCubici2(
gdold,
mlfVertcat(
mlfHorzcat(
mlfIndexRef(*matl, "(?)", mlfScalar(1.0)),
NULL),
mlfHorzcat(
mlfIndexRef(*matl, "(?)", mlfScalar(3.0)),
NULL),
mlfHorzcat(*fnew, NULL),
NULL),
mlfVertcat(
mlfHorzcat(
mlfIndexRef(*matx, "(?)", mlfScalar(1.0)),
NULL),
mlfHorzcat(
mlfIndexRef(*matx, "(?)", mlfScalar(3.0)),
NULL),
mlfHorzcat(*stepsize, NULL),
NULL)));
/*
* end
*/
}
/*
* matx(3)=stepsize;
*/
mlfIndexAssign(matx, "(?)", mlfScalar(3.0), *stepsize);
/*
* if isnan(newstep), stepsize=stepsize/2; else stepsize=newstep; end
*/
if (mlfTobool(mlfIsnan(newstep))) {
mlfAssign(
stepsize, mlfMrdivide(*stepsize, mlfScalar(2.0)));
} else {
mlfAssign(stepsize, newstep);
}
/*
* matl(3)=fnew;
*/
mlfIndexAssign(matl, "(?)", mlfScalar(3.0), *fnew);
/*
* how=[how,'R'];
*/
mlfAssign(how, mlfHorzcat(*how, mxCreateString("R"), NULL));
/*
* % Otherwise must have Bracketed Minimum so do quadratic interpolation.
* % ... having just increased step.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -