⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 searchq.c

📁 ASUFIT-Matlab-全局拟合程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*
 * 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 + -