Beispiel #1
0
    public static void lsfitcreatefgh(double[,] x, double[] y, double[] c, out lsfitstate state)
    {
        int n;
        int m;
        int k;
        if( (ap.rows(x)!=ap.len(y)))
            throw new alglibexception("Error while calling 'lsfitcreatefgh': looks like one of arguments has wrong size");
        state = new lsfitstate();
        n = ap.rows(x);
        m = ap.cols(x);
        k = ap.len(c);
        lsfit.lsfitcreatefgh(x, y, c, n, m, k, state.innerobj);

        return;
    }
        /*************************************************************************
        Nonlinear least squares fitting using gradient/Hessian without  individual
        weights. See LSFitNonlinearWFGH() for more information.


          -- ALGLIB --
             Copyright 17.08.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void lsfitnonlinearfgh(ref double[,] x,
            ref double[] y,
            ref double[] c,
            int n,
            int m,
            int k,
            ref lsfitstate state)
        {
            int i = 0;
            int i_ = 0;

            state.n = n;
            state.m = m;
            state.k = k;
            lsfitnonlinearsetcond(ref state, 0.0, 0.0, 0);
            lsfitnonlinearsetstpmax(ref state, 0.0);
            state.cheapfg = true;
            state.havehess = true;
            if( n>=1 & m>=1 & k>=1 )
            {
                state.taskx = new double[n, m];
                state.tasky = new double[n];
                state.w = new double[n];
                state.c = new double[k];
                for(i_=0; i_<=k-1;i_++)
                {
                    state.c[i_] = c[i_];
                }
                for(i=0; i<=n-1; i++)
                {
                    for(i_=0; i_<=m-1;i_++)
                    {
                        state.taskx[i,i_] = x[i,i_];
                    }
                    state.tasky[i] = y[i];
                    state.w[i] = 1;
                }
            }
            state.rstate.ia = new int[4+1];
            state.rstate.ra = new double[1+1];
            state.rstate.stage = -1;
        }
        /*************************************************************************
        This function sets maximum step length

        INPUT PARAMETERS:
            State   -   structure which stores algorithm state between calls and
                        which is used for reverse communication. Must be
                        initialized with LSFitNonLinearCreate???()
            StpMax  -   maximum step length, >=0. Set StpMax to 0.0,  if you don't
                        want to limit step length.

        Use this subroutine when you optimize target function which contains exp()
        or  other  fast  growing  functions,  and optimization algorithm makes too
        large  steps  which  leads  to overflow. This function allows us to reject
        steps  that  are  too  large  (and  therefore  expose  us  to the possible
        overflow) without actually calculating function value at the x+stp*d.

        NOTE: non-zero StpMax leads to moderate  performance  degradation  because
        intermediate  step  of  preconditioned L-BFGS optimization is incompatible
        with limits on step size.

          -- ALGLIB --
             Copyright 02.04.2010 by Bochkanov Sergey
        *************************************************************************/
        public static void lsfitnonlinearsetstpmax(ref lsfitstate state,
            double stpmax)
        {
            System.Diagnostics.Debug.Assert((double)(stpmax)>=(double)(0), "LSFitNonlinearSetStpMax: StpMax<0!");
            state.stpmax = stpmax;
        }
Beispiel #4
0
        /*************************************************************************
        Nonlinear least squares fitting results.

        Called after return from LSFitFit().

        INPUT PARAMETERS:
            State   -   algorithm state

        OUTPUT PARAMETERS:
            Info    -   completion code:
                            * -7    gradient verification failed.
                                    See LSFitSetGradientCheck() for more information.
                            *  1    relative function improvement is no more than
                                    EpsF.
                            *  2    relative step is no more than EpsX.
                            *  4    gradient norm is no more than EpsG
                            *  5    MaxIts steps was taken
                            *  7    stopping conditions are too stringent,
                                    further improvement is impossible
            C       -   array[0..K-1], solution
            Rep     -   optimization report. On success following fields are set:
                        * R2                non-adjusted coefficient of determination
                                            (non-weighted)
                        * RMSError          rms error on the (X,Y).
                        * AvgError          average error on the (X,Y).
                        * AvgRelError       average relative error on the non-zero Y
                        * MaxError          maximum error
                                            NON-WEIGHTED ERRORS ARE CALCULATED
                        * WRMSError         weighted rms error on the (X,Y).
                        
        ERRORS IN PARAMETERS                
                        
        This  solver  also  calculates different kinds of errors in parameters and
        fills corresponding fields of report:
        * Rep.CovPar        covariance matrix for parameters, array[K,K].
        * Rep.ErrPar        errors in parameters, array[K],
                            errpar = sqrt(diag(CovPar))
        * Rep.ErrCurve      vector of fit errors - standard deviations of empirical
                            best-fit curve from "ideal" best-fit curve built  with
                            infinite number of samples, array[N].
                            errcurve = sqrt(diag(J*CovPar*J')),
                            where J is Jacobian matrix.
        * Rep.Noise         vector of per-point estimates of noise, array[N]

        IMPORTANT:  errors  in  parameters  are  calculated  without  taking  into
                    account boundary/linear constraints! Presence  of  constraints
                    changes distribution of errors, but there is no  easy  way  to
                    account for constraints when you calculate covariance matrix.
                    
        NOTE:       noise in the data is estimated as follows:
                    * for fitting without user-supplied  weights  all  points  are
                      assumed to have same level of noise, which is estimated from
                      the data
                    * for fitting with user-supplied weights we assume that  noise
                      level in I-th point is inversely proportional to Ith weight.
                      Coefficient of proportionality is estimated from the data.
                    
        NOTE:       we apply small amount of regularization when we invert squared
                    Jacobian and calculate covariance matrix. It  guarantees  that
                    algorithm won't divide by zero  during  inversion,  but  skews
                    error estimates a bit (fractional error is about 10^-9).
                    
                    However, we believe that this difference is insignificant  for
                    all practical purposes except for the situation when you  want
                    to compare ALGLIB results with "reference"  implementation  up
                    to the last significant digit.
                    
        NOTE:       covariance matrix is estimated using  correction  for  degrees
                    of freedom (covariances are divided by N-M instead of dividing
                    by N).

          -- ALGLIB --
             Copyright 17.08.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void lsfitresults(lsfitstate state,
            ref int info,
            ref double[] c,
            lsfitreport rep)
        {
            int i = 0;
            int j = 0;
            int i_ = 0;

            info = 0;
            c = new double[0];

            clearreport(rep);
            info = state.repterminationtype;
            rep.varidx = state.repvaridx;
            if( info>0 )
            {
                c = new double[state.k];
                for(i_=0; i_<=state.k-1;i_++)
                {
                    c[i_] = state.c[i_];
                }
                rep.rmserror = state.reprmserror;
                rep.wrmserror = state.repwrmserror;
                rep.avgerror = state.repavgerror;
                rep.avgrelerror = state.repavgrelerror;
                rep.maxerror = state.repmaxerror;
                rep.iterationscount = state.repiterationscount;
                rep.covpar = new double[state.k, state.k];
                rep.errpar = new double[state.k];
                rep.errcurve = new double[state.npoints];
                rep.noise = new double[state.npoints];
                rep.r2 = state.rep.r2;
                for(i=0; i<=state.k-1; i++)
                {
                    for(j=0; j<=state.k-1; j++)
                    {
                        rep.covpar[i,j] = state.rep.covpar[i,j];
                    }
                    rep.errpar[i] = state.rep.errpar[i];
                }
                for(i=0; i<=state.npoints-1; i++)
                {
                    rep.errcurve[i] = state.rep.errcurve[i];
                    rep.noise[i] = state.rep.noise[i];
                }
            }
        }
        /*************************************************************************
        Nonlinear least squares fitting results.

        Called after LSFitNonlinearIteration() returned False.

        INPUT PARAMETERS:
            State   -   algorithm state (used by LSFitNonlinearIteration).

        OUTPUT PARAMETERS:
            Info    -   completetion code:
                            * -1    incorrect parameters were specified
                            *  1    relative function improvement is no more than
                                    EpsF.
                            *  2    relative step is no more than EpsX.
                            *  4    gradient norm is no more than EpsG
                            *  5    MaxIts steps was taken
            C       -   array[0..K-1], solution
            Rep     -   optimization report. Following fields are set:
                        * Rep.TerminationType completetion code:
                        * RMSError          rms error on the (X,Y).
                        * AvgError          average error on the (X,Y).
                        * AvgRelError       average relative error on the non-zero Y
                        * MaxError          maximum error
                                            NON-WEIGHTED ERRORS ARE CALCULATED


          -- ALGLIB --
             Copyright 17.08.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void lsfitnonlinearresults(ref lsfitstate state,
            ref int info,
            ref double[] c,
            ref lsfitreport rep)
        {
            int i_ = 0;

            info = state.repterminationtype;
            if( info>0 )
            {
                c = new double[state.k];
                for(i_=0; i_<=state.k-1;i_++)
                {
                    c[i_] = state.c[i_];
                }
                rep.rmserror = state.reprmserror;
                rep.avgerror = state.repavgerror;
                rep.avgrelerror = state.repavgrelerror;
                rep.maxerror = state.repmaxerror;
            }
        }
Beispiel #6
0
        /*************************************************************************
        This function turns on/off reporting.

        INPUT PARAMETERS:
            State   -   structure which stores algorithm state
            NeedXRep-   whether iteration reports are needed or not
            
        When reports are needed, State.C (current parameters) and State.F (current
        value of fitting function) are reported.


          -- ALGLIB --
             Copyright 15.08.2010 by Bochkanov Sergey
        *************************************************************************/
        public static void lsfitsetxrep(lsfitstate state,
            bool needxrep)
        {
            state.xrep = needxrep;
        }
Beispiel #7
0
        /*************************************************************************
        This function sets boundary constraints for underlying optimizer

        Boundary constraints are inactive by default (after initial creation).
        They are preserved until explicitly turned off with another SetBC() call.

        INPUT PARAMETERS:
            State   -   structure stores algorithm state
            BndL    -   lower bounds, array[K].
                        If some (all) variables are unbounded, you may specify
                        very small number or -INF (latter is recommended because
                        it will allow solver to use better algorithm).
            BndU    -   upper bounds, array[K].
                        If some (all) variables are unbounded, you may specify
                        very large number or +INF (latter is recommended because
                        it will allow solver to use better algorithm).

        NOTE 1: it is possible to specify BndL[i]=BndU[i]. In this case I-th
        variable will be "frozen" at X[i]=BndL[i]=BndU[i].

        NOTE 2: unlike other constrained optimization algorithms, this solver  has
        following useful properties:
        * bound constraints are always satisfied exactly
        * function is evaluated only INSIDE area specified by bound constraints

          -- ALGLIB --
             Copyright 14.01.2011 by Bochkanov Sergey
        *************************************************************************/
        public static void lsfitsetbc(lsfitstate state,
            double[] bndl,
            double[] bndu)
        {
            int i = 0;
            int k = 0;

            k = state.k;
            alglib.ap.assert(alglib.ap.len(bndl)>=k, "LSFitSetBC: Length(BndL)<K");
            alglib.ap.assert(alglib.ap.len(bndu)>=k, "LSFitSetBC: Length(BndU)<K");
            for(i=0; i<=k-1; i++)
            {
                alglib.ap.assert(math.isfinite(bndl[i]) || Double.IsNegativeInfinity(bndl[i]), "LSFitSetBC: BndL contains NAN or +INF");
                alglib.ap.assert(math.isfinite(bndu[i]) || Double.IsPositiveInfinity(bndu[i]), "LSFitSetBC: BndU contains NAN or -INF");
                if( math.isfinite(bndl[i]) && math.isfinite(bndu[i]) )
                {
                    alglib.ap.assert((double)(bndl[i])<=(double)(bndu[i]), "LSFitSetBC: BndL[i]>BndU[i]");
                }
                state.bndl[i] = bndl[i];
                state.bndu[i] = bndu[i];
            }
        }
Beispiel #8
0
    /*************************************************************************
    Nonlinear least squares fitting results.

    Called after return from LSFitFit().

    INPUT PARAMETERS:
        State   -   algorithm state

    OUTPUT PARAMETERS:
        Info    -   completetion code:
                        *  1    relative function improvement is no more than
                                EpsF.
                        *  2    relative step is no more than EpsX.
                        *  4    gradient norm is no more than EpsG
                        *  5    MaxIts steps was taken
                        *  7    stopping conditions are too stringent,
                                further improvement is impossible
        C       -   array[0..K-1], solution
        Rep     -   optimization report. Following fields are set:
                    * Rep.TerminationType completetion code:
                    * RMSError          rms error on the (X,Y).
                    * AvgError          average error on the (X,Y).
                    * AvgRelError       average relative error on the non-zero Y
                    * MaxError          maximum error
                                        NON-WEIGHTED ERRORS ARE CALCULATED


      -- ALGLIB --
         Copyright 17.08.2009 by Bochkanov Sergey
    *************************************************************************/
    public static void lsfitresults(lsfitstate state, out int info, out double[] c, out lsfitreport rep)
    {
        info = 0;
        c = new double[0];
        rep = new lsfitreport();
        lsfit.lsfitresults(state.innerobj, ref info, ref c, rep.innerobj);
        return;
    }
Beispiel #9
0
        /*************************************************************************
        Nonlinear least squares fitting using gradient/Hessian, without individial
        weights.

        Nonlinear task min(F(c)) is solved, where

            F(c) = ((f(c,x[0])-y[0]))^2 + ... + ((f(c,x[n-1])-y[n-1]))^2,

            * N is a number of points,
            * M is a dimension of a space points belong to,
            * K is a dimension of a space of parameters being fitted,
            * x is a set of N points, each of them is an M-dimensional vector,
            * c is a K-dimensional vector of parameters being fitted

        This subroutine uses f(c,x[i]), its gradient and its Hessian.

        INPUT PARAMETERS:
            X       -   array[0..N-1,0..M-1], points (one row = one point)
            Y       -   array[0..N-1], function values.
            C       -   array[0..K-1], initial approximation to the solution,
            N       -   number of points, N>1
            M       -   dimension of space
            K       -   number of parameters being fitted

        OUTPUT PARAMETERS:
            State   -   structure which stores algorithm state


          -- ALGLIB --
             Copyright 17.08.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void lsfitcreatefgh(double[,] x,
            double[] y,
            double[] c,
            int n,
            int m,
            int k,
            lsfitstate state)
        {
            int i = 0;
            int i_ = 0;

            ap.assert(n>=1, "LSFitCreateFGH: N<1!");
            ap.assert(m>=1, "LSFitCreateFGH: M<1!");
            ap.assert(k>=1, "LSFitCreateFGH: K<1!");
            ap.assert(ap.len(c)>=k, "LSFitCreateFGH: length(C)<K!");
            ap.assert(apserv.isfinitevector(c, k), "LSFitCreateFGH: C contains infinite or NaN values!");
            ap.assert(ap.len(y)>=n, "LSFitCreateFGH: length(Y)<N!");
            ap.assert(apserv.isfinitevector(y, n), "LSFitCreateFGH: Y contains infinite or NaN values!");
            ap.assert(ap.rows(x)>=n, "LSFitCreateFGH: rows(X)<N!");
            ap.assert(ap.cols(x)>=m, "LSFitCreateFGH: cols(X)<M!");
            ap.assert(apserv.apservisfinitematrix(x, n, m), "LSFitCreateFGH: X contains infinite or NaN values!");
            state.n = n;
            state.m = m;
            state.k = k;
            lsfitsetcond(state, 0.0, 0.0, 0);
            lsfitsetstpmax(state, 0.0);
            lsfitsetxrep(state, false);
            state.taskx = new double[n, m];
            state.tasky = new double[n];
            state.w = new double[n];
            state.c = new double[k];
            state.h = new double[k, k];
            state.x = new double[m];
            state.g = new double[k];
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = c[i_];
            }
            for(i=0; i<=n-1; i++)
            {
                for(i_=0; i_<=m-1;i_++)
                {
                    state.taskx[i,i_] = x[i,i_];
                }
                state.tasky[i] = y[i];
                state.w[i] = 1;
            }
            minlm.minlmcreatefgh(k, state.c, state.optstate);
            lsfitclearrequestfields(state);
            state.rstate.ia = new int[4+1];
            state.rstate.ra = new double[1+1];
            state.rstate.stage = -1;
        }
Beispiel #10
0
    /*************************************************************************
    This function provides reverse communication interface
    Reverse communication interface is not documented or recommended to use.
    See below for functions which provide better documented API
    *************************************************************************/
    public static bool lsfititeration(lsfitstate state)
    {

        bool result = lsfit.lsfititeration(state.innerobj);
        return result;
    }
Beispiel #11
0
 public static void lsfitfit(lsfitstate state, ndimensional_pfunc func, ndimensional_pgrad grad, ndimensional_phess hess, ndimensional_rep rep, object obj)
 {
     if( func==null )
         throw new alglibexception("ALGLIB: error in 'lsfitfit()' (func is null)");
     if( grad==null )
         throw new alglibexception("ALGLIB: error in 'lsfitfit()' (grad is null)");
     if( hess==null )
         throw new alglibexception("ALGLIB: error in 'lsfitfit()' (hess is null)");
     while( alglib.lsfititeration(state) )
     {
         if( state.needf )
         {
             func(state.c, state.x, ref state.innerobj.f, obj);
             continue;
         }
         if( state.needfg )
         {
             grad(state.c, state.x, ref state.innerobj.f, state.innerobj.g, obj);
             continue;
         }
         if( state.needfgh )
         {
             hess(state.c, state.x, ref state.innerobj.f, state.innerobj.g, state.innerobj.h, obj);
             continue;
         }
         if( state.innerobj.xupdated )
         {
             if( rep!=null )
                 rep(state.innerobj.x, state.innerobj.f, obj);
             continue;
         }
         throw new alglibexception("ALGLIB: error in 'lsfitfit' (some derivatives were not provided?)");
     }
 }
Beispiel #12
0
    /*************************************************************************
    This function turns on/off reporting.

    INPUT PARAMETERS:
        State   -   structure which stores algorithm state
        NeedXRep-   whether iteration reports are needed or not

    When reports are needed, State.C (current parameters) and State.F (current
    value of fitting function) are reported.


      -- ALGLIB --
         Copyright 15.08.2010 by Bochkanov Sergey
    *************************************************************************/
    public static void lsfitsetxrep(lsfitstate state, bool needxrep)
    {

        lsfit.lsfitsetxrep(state.innerobj, needxrep);
        return;
    }
Beispiel #13
0
    /*************************************************************************
    This function sets maximum step length

    INPUT PARAMETERS:
        State   -   structure which stores algorithm state
        StpMax  -   maximum step length, >=0. Set StpMax to 0.0,  if you don't
                    want to limit step length.

    Use this subroutine when you optimize target function which contains exp()
    or  other  fast  growing  functions,  and optimization algorithm makes too
    large  steps  which  leads  to overflow. This function allows us to reject
    steps  that  are  too  large  (and  therefore  expose  us  to the possible
    overflow) without actually calculating function value at the x+stp*d.

    NOTE: non-zero StpMax leads to moderate  performance  degradation  because
    intermediate  step  of  preconditioned L-BFGS optimization is incompatible
    with limits on step size.

      -- ALGLIB --
         Copyright 02.04.2010 by Bochkanov Sergey
    *************************************************************************/
    public static void lsfitsetstpmax(lsfitstate state, double stpmax)
    {

        lsfit.lsfitsetstpmax(state.innerobj, stpmax);
        return;
    }
Beispiel #14
0
    /*************************************************************************
    Stopping conditions for nonlinear least squares fitting.

    INPUT PARAMETERS:
        State   -   structure which stores algorithm state
        EpsF    -   stopping criterion. Algorithm stops if
                    |F(k+1)-F(k)| <= EpsF*max{|F(k)|, |F(k+1)|, 1}
        EpsX    -   stopping criterion. Algorithm stops if
                    |X(k+1)-X(k)| <= EpsX*(1+|X(k)|)
        MaxIts  -   stopping criterion. Algorithm stops after MaxIts iterations.
                    MaxIts=0 means no stopping criterion.

    NOTE

    Passing EpsF=0, EpsX=0 and MaxIts=0 (simultaneously) will lead to automatic
    stopping criterion selection (according to the scheme used by MINLM unit).


      -- ALGLIB --
         Copyright 17.08.2009 by Bochkanov Sergey
    *************************************************************************/
    public static void lsfitsetcond(lsfitstate state, double epsf, double epsx, int maxits)
    {

        lsfit.lsfitsetcond(state.innerobj, epsf, epsx, maxits);
        return;
    }
Beispiel #15
0
        /*************************************************************************
        Stopping conditions for nonlinear least squares fitting.

        INPUT PARAMETERS:
            State   -   structure which stores algorithm state
            EpsF    -   stopping criterion. Algorithm stops if
                        |F(k+1)-F(k)| <= EpsF*max{|F(k)|, |F(k+1)|, 1}
            EpsX    -   >=0
                        The subroutine finishes its work if  on  k+1-th  iteration
                        the condition |v|<=EpsX is fulfilled, where:
                        * |.| means Euclidian norm
                        * v - scaled step vector, v[i]=dx[i]/s[i]
                        * dx - ste pvector, dx=X(k+1)-X(k)
                        * s - scaling coefficients set by LSFitSetScale()
            MaxIts  -   maximum number of iterations. If MaxIts=0, the  number  of
                        iterations   is    unlimited.   Only   Levenberg-Marquardt
                        iterations  are  counted  (L-BFGS/CG  iterations  are  NOT
                        counted because their cost is very low compared to that of
                        LM).

        NOTE

        Passing EpsF=0, EpsX=0 and MaxIts=0 (simultaneously) will lead to automatic
        stopping criterion selection (according to the scheme used by MINLM unit).


          -- ALGLIB --
             Copyright 17.08.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void lsfitsetcond(lsfitstate state,
            double epsf,
            double epsx,
            int maxits)
        {
            alglib.ap.assert(math.isfinite(epsf), "LSFitSetCond: EpsF is not finite!");
            alglib.ap.assert((double)(epsf)>=(double)(0), "LSFitSetCond: negative EpsF!");
            alglib.ap.assert(math.isfinite(epsx), "LSFitSetCond: EpsX is not finite!");
            alglib.ap.assert((double)(epsx)>=(double)(0), "LSFitSetCond: negative EpsX!");
            alglib.ap.assert(maxits>=0, "LSFitSetCond: negative MaxIts!");
            state.epsf = epsf;
            state.epsx = epsx;
            state.maxits = maxits;
        }
Beispiel #16
0
            /*************************************************************************
            Weighted nonlinear least squares fitting using gradient only.

            Nonlinear task min(F(c)) is solved, where

                F(c) = (w[0]*(f(c,x[0])-y[0]))^2 + ... + (w[n-1]*(f(c,x[n-1])-y[n-1]))^2,
            
                * N is a number of points,
                * M is a dimension of a space points belong to,
                * K is a dimension of a space of parameters being fitted,
                * w is an N-dimensional vector of weight coefficients,
                * x is a set of N points, each of them is an M-dimensional vector,
                * c is a K-dimensional vector of parameters being fitted
            
            This subroutine uses only f(c,x[i]) and its gradient.
            
            INPUT PARAMETERS:
                X       -   array[0..N-1,0..M-1], points (one row = one point)
                Y       -   array[0..N-1], function values.
                W       -   weights, array[0..N-1]
                C       -   array[0..K-1], initial approximation to the solution,
                N       -   number of points, N>1
                M       -   dimension of space
                K       -   number of parameters being fitted
                CheapFG -   boolean flag, which is:
                            * True  if both function and gradient calculation complexity
                                    are less than O(M^2).  An improved  algorithm  can
                                    be  used  which corresponds  to  FGJ  scheme  from
                                    MINLM unit.
                            * False otherwise.
                                    Standard Jacibian-bases  Levenberg-Marquardt  algo
                                    will be used (FJ scheme).

            OUTPUT PARAMETERS:
                State   -   structure which stores algorithm state

            See also:
                LSFitResults
                LSFitCreateFG (fitting without weights)
                LSFitCreateWFGH (fitting using Hessian)
                LSFitCreateFGH (fitting using Hessian, without weights)

              -- ALGLIB --
                 Copyright 17.08.2009 by Bochkanov Sergey
            *************************************************************************/
            public static void lsfitcreatewfg(double[,] x,
                double[] y,
                double[] w,
                double[] c,
                int n,
                int m,
                int k,
                bool cheapfg,
                lsfitstate state) {
                int i = 0;
                int i_ = 0;

                ap.assert(n >= 1, "LSFitCreateWFG: N<1!");
                ap.assert(m >= 1, "LSFitCreateWFG: M<1!");
                ap.assert(k >= 1, "LSFitCreateWFG: K<1!");
                ap.assert(ap.len(c) >= k, "LSFitCreateWFG: length(C)<K!");
                ap.assert(apserv.isfinitevector(c, k), "LSFitCreateWFG: C contains infinite or NaN values!");
                ap.assert(ap.len(y) >= n, "LSFitCreateWFG: length(Y)<N!");
                ap.assert(apserv.isfinitevector(y, n), "LSFitCreateWFG: Y contains infinite or NaN values!");
                ap.assert(ap.len(w) >= n, "LSFitCreateWFG: length(W)<N!");
                ap.assert(apserv.isfinitevector(w, n), "LSFitCreateWFG: W contains infinite or NaN values!");
                ap.assert(ap.rows(x) >= n, "LSFitCreateWFG: rows(X)<N!");
                ap.assert(ap.cols(x) >= m, "LSFitCreateWFG: cols(X)<M!");
                ap.assert(apserv.apservisfinitematrix(x, n, m), "LSFitCreateWFG: X contains infinite or NaN values!");
                state.npoints = n;
                state.nweights = n;
                state.wkind = 1;
                state.m = m;
                state.k = k;
                lsfitsetcond(state, 0.0, 0.0, 0);
                lsfitsetstpmax(state, 0.0);
                lsfitsetxrep(state, false);
                state.taskx = new double[n, m];
                state.tasky = new double[n];
                state.w = new double[n];
                state.c = new double[k];
                state.x = new double[m];
                state.g = new double[k];
                for(i_ = 0; i_ <= k - 1; i_++) {
                    state.c[i_] = c[i_];
                }
                for(i_ = 0; i_ <= n - 1; i_++) {
                    state.w[i_] = w[i_];
                }
                for(i = 0; i <= n - 1; i++) {
                    for(i_ = 0; i_ <= m - 1; i_++) {
                        state.taskx[i, i_] = x[i, i_];
                    }
                    state.tasky[i] = y[i];
                }
                state.s = new double[k];
                state.bndl = new double[k];
                state.bndu = new double[k];
                for(i = 0; i <= k - 1; i++) {
                    state.s[i] = 1.0;
                    state.bndl[i] = Double.NegativeInfinity;
                    state.bndu[i] = Double.PositiveInfinity;
                }
                state.optalgo = 1;
                state.prevnpt = -1;
                state.prevalgo = -1;
                if(cheapfg) {
                    minlm.minlmcreatevgj(k, n, state.c, state.optstate);
                } else {
                    minlm.minlmcreatevj(k, n, state.c, state.optstate);
                }
                lsfitclearrequestfields(state);
                state.rstate.ia = new int[4 + 1];
                state.rstate.ra = new double[2 + 1];
                state.rstate.stage = -1;
            }
Beispiel #17
0
        /*************************************************************************
        This function sets maximum step length

        INPUT PARAMETERS:
            State   -   structure which stores algorithm state
            StpMax  -   maximum step length, >=0. Set StpMax to 0.0,  if you don't
                        want to limit step length.

        Use this subroutine when you optimize target function which contains exp()
        or  other  fast  growing  functions,  and optimization algorithm makes too
        large  steps  which  leads  to overflow. This function allows us to reject
        steps  that  are  too  large  (and  therefore  expose  us  to the possible
        overflow) without actually calculating function value at the x+stp*d.

        NOTE: non-zero StpMax leads to moderate  performance  degradation  because
        intermediate  step  of  preconditioned L-BFGS optimization is incompatible
        with limits on step size.

          -- ALGLIB --
             Copyright 02.04.2010 by Bochkanov Sergey
        *************************************************************************/
        public static void lsfitsetstpmax(lsfitstate state,
            double stpmax)
        {
            alglib.ap.assert((double)(stpmax)>=(double)(0), "LSFitSetStpMax: StpMax<0!");
            state.stpmax = stpmax;
        }
Beispiel #18
0
            /*************************************************************************
            NOTES:

            1. this algorithm is somewhat unusual because it works with  parameterized
               function f(C,X), where X is a function argument (we  have  many  points
               which are characterized by different  argument  values),  and  C  is  a
               parameter to fit.

               For example, if we want to do linear fit by f(c0,c1,x) = c0*x+c1,  then
               x will be argument, and {c0,c1} will be parameters.
           
               It is important to understand that this algorithm finds minimum in  the
               space of function PARAMETERS (not arguments), so it  needs  derivatives
               of f() with respect to C, not X.
           
               In the example above it will need f=c0*x+c1 and {df/dc0,df/dc1} = {x,1}
               instead of {df/dx} = {c0}.

            2. Callback functions accept C as the first parameter, and X as the second

            3. If  state  was  created  with  LSFitCreateFG(),  algorithm  needs  just
               function   and   its   gradient,   but   if   state   was  created with
               LSFitCreateFGH(), algorithm will need function, gradient and Hessian.
           
               According  to  the  said  above,  there  ase  several  versions of this
               function, which accept different sets of callbacks.
           
               This flexibility opens way to subtle errors - you may create state with
               LSFitCreateFGH() (optimization using Hessian), but call function  which
               does not accept Hessian. So when algorithm will request Hessian,  there
               will be no callback to call. In this case exception will be thrown.
           
               Be careful to avoid such errors because there is no way to find them at
               compile time - you can see them at runtime only.

              -- ALGLIB --
                 Copyright 17.08.2009 by Bochkanov Sergey
            *************************************************************************/
            public static bool lsfititeration(lsfitstate state) {
                bool result = new bool();
                int n = 0;
                int m = 0;
                int k = 0;
                int i = 0;
                int j = 0;
                double v = 0;
                double vv = 0;
                double relcnt = 0;
                int i_ = 0;


                //
                // Reverse communication preparations
                // I know it looks ugly, but it works the same way
                // anywhere from C++ to Python.
                //
                // This code initializes locals by:
                // * random values determined during code
                //   generation - on first subroutine call
                // * values from previous call - on subsequent calls
                //
                if(state.rstate.stage >= 0) {
                    n = state.rstate.ia[0];
                    m = state.rstate.ia[1];
                    k = state.rstate.ia[2];
                    i = state.rstate.ia[3];
                    j = state.rstate.ia[4];
                    v = state.rstate.ra[0];
                    vv = state.rstate.ra[1];
                    relcnt = state.rstate.ra[2];
                } else {
                    n = -983;
                    m = -989;
                    k = -834;
                    i = 900;
                    j = -287;
                    v = 364;
                    vv = 214;
                    relcnt = -338;
                }
                if(state.rstate.stage == 0) {
                    goto lbl_0;
                }
                if(state.rstate.stage == 1) {
                    goto lbl_1;
                }
                if(state.rstate.stage == 2) {
                    goto lbl_2;
                }
                if(state.rstate.stage == 3) {
                    goto lbl_3;
                }
                if(state.rstate.stage == 4) {
                    goto lbl_4;
                }
                if(state.rstate.stage == 5) {
                    goto lbl_5;
                }
                if(state.rstate.stage == 6) {
                    goto lbl_6;
                }

                //
                // Routine body
                //

                //
                // init
                //
                if(state.wkind == 1) {
                    ap.assert(state.npoints == state.nweights, "LSFitFit: number of points is not equal to the number of weights");
                }
                n = state.npoints;
                m = state.m;
                k = state.k;
                minlm.minlmsetcond(state.optstate, 0.0, state.epsf, state.epsx, state.maxits);
                minlm.minlmsetstpmax(state.optstate, state.stpmax);
                minlm.minlmsetxrep(state.optstate, state.xrep);
                minlm.minlmsetscale(state.optstate, state.s);
                minlm.minlmsetbc(state.optstate, state.bndl, state.bndu);

                //
            // Optimize
            //
            lbl_7:
                if(!minlm.minlmiteration(state.optstate)) {
                    goto lbl_8;
                }
                if(!state.optstate.needfi) {
                    goto lbl_9;
                }

                //
                // calculate f[] = wi*(f(xi,c)-yi)
                //
                i = 0;
            lbl_11:
                if(i > n - 1) {
                    goto lbl_13;
                }
                for(i_ = 0; i_ <= k - 1; i_++) {
                    state.c[i_] = state.optstate.x[i_];
                }
                for(i_ = 0; i_ <= m - 1; i_++) {
                    state.x[i_] = state.taskx[i, i_];
                }
                state.pointindex = i;
                lsfitclearrequestfields(state);
                state.needf = true;
                state.rstate.stage = 0;
                goto lbl_rcomm;
            lbl_0:
                state.needf = false;
                if(state.wkind == 1) {
                    vv = state.w[i];
                } else {
                    vv = 1.0;
                }
                state.optstate.fi[i] = vv * (state.f - state.tasky[i]);
                i = i + 1;
                goto lbl_11;
            lbl_13:
                goto lbl_7;
            lbl_9:
                if(!state.optstate.needf) {
                    goto lbl_14;
                }

                //
                // calculate F = sum (wi*(f(xi,c)-yi))^2
                //
                state.optstate.f = 0;
                i = 0;
            lbl_16:
                if(i > n - 1) {
                    goto lbl_18;
                }
                for(i_ = 0; i_ <= k - 1; i_++) {
                    state.c[i_] = state.optstate.x[i_];
                }
                for(i_ = 0; i_ <= m - 1; i_++) {
                    state.x[i_] = state.taskx[i, i_];
                }
                state.pointindex = i;
                lsfitclearrequestfields(state);
                state.needf = true;
                state.rstate.stage = 1;
                goto lbl_rcomm;
            lbl_1:
                state.needf = false;
                if(state.wkind == 1) {
                    vv = state.w[i];
                } else {
                    vv = 1.0;
                }
                state.optstate.f = state.optstate.f + math.sqr(vv * (state.f - state.tasky[i]));
                i = i + 1;
                goto lbl_16;
            lbl_18:
                goto lbl_7;
            lbl_14:
                if(!state.optstate.needfg) {
                    goto lbl_19;
                }

                //
                // calculate F/gradF
                //
                state.optstate.f = 0;
                for(i = 0; i <= k - 1; i++) {
                    state.optstate.g[i] = 0;
                }
                i = 0;
            lbl_21:
                if(i > n - 1) {
                    goto lbl_23;
                }
                for(i_ = 0; i_ <= k - 1; i_++) {
                    state.c[i_] = state.optstate.x[i_];
                }
                for(i_ = 0; i_ <= m - 1; i_++) {
                    state.x[i_] = state.taskx[i, i_];
                }
                state.pointindex = i;
                lsfitclearrequestfields(state);
                state.needfg = true;
                state.rstate.stage = 2;
                goto lbl_rcomm;
            lbl_2:
                state.needfg = false;
                if(state.wkind == 1) {
                    vv = state.w[i];
                } else {
                    vv = 1.0;
                }
                state.optstate.f = state.optstate.f + math.sqr(vv * (state.f - state.tasky[i]));
                v = math.sqr(vv) * 2 * (state.f - state.tasky[i]);
                for(i_ = 0; i_ <= k - 1; i_++) {
                    state.optstate.g[i_] = state.optstate.g[i_] + v * state.g[i_];
                }
                i = i + 1;
                goto lbl_21;
            lbl_23:
                goto lbl_7;
            lbl_19:
                if(!state.optstate.needfij) {
                    goto lbl_24;
                }

                //
                // calculate Fi/jac(Fi)
                //
                i = 0;
            lbl_26:
                if(i > n - 1) {
                    goto lbl_28;
                }
                for(i_ = 0; i_ <= k - 1; i_++) {
                    state.c[i_] = state.optstate.x[i_];
                }
                for(i_ = 0; i_ <= m - 1; i_++) {
                    state.x[i_] = state.taskx[i, i_];
                }
                state.pointindex = i;
                lsfitclearrequestfields(state);
                state.needfg = true;
                state.rstate.stage = 3;
                goto lbl_rcomm;
            lbl_3:
                state.needfg = false;
                if(state.wkind == 1) {
                    vv = state.w[i];
                } else {
                    vv = 1.0;
                }
                state.optstate.fi[i] = vv * (state.f - state.tasky[i]);
                for(i_ = 0; i_ <= k - 1; i_++) {
                    state.optstate.j[i, i_] = vv * state.g[i_];
                }
                i = i + 1;
                goto lbl_26;
            lbl_28:
                goto lbl_7;
            lbl_24:
                if(!state.optstate.needfgh) {
                    goto lbl_29;
                }

                //
                // calculate F/grad(F)/hess(F)
                //
                state.optstate.f = 0;
                for(i = 0; i <= k - 1; i++) {
                    state.optstate.g[i] = 0;
                }
                for(i = 0; i <= k - 1; i++) {
                    for(j = 0; j <= k - 1; j++) {
                        state.optstate.h[i, j] = 0;
                    }
                }
                i = 0;
            lbl_31:
                if(i > n - 1) {
                    goto lbl_33;
                }
                for(i_ = 0; i_ <= k - 1; i_++) {
                    state.c[i_] = state.optstate.x[i_];
                }
                for(i_ = 0; i_ <= m - 1; i_++) {
                    state.x[i_] = state.taskx[i, i_];
                }
                state.pointindex = i;
                lsfitclearrequestfields(state);
                state.needfgh = true;
                state.rstate.stage = 4;
                goto lbl_rcomm;
            lbl_4:
                state.needfgh = false;
                if(state.wkind == 1) {
                    vv = state.w[i];
                } else {
                    vv = 1.0;
                }
                state.optstate.f = state.optstate.f + math.sqr(vv * (state.f - state.tasky[i]));
                v = math.sqr(vv) * 2 * (state.f - state.tasky[i]);
                for(i_ = 0; i_ <= k - 1; i_++) {
                    state.optstate.g[i_] = state.optstate.g[i_] + v * state.g[i_];
                }
                for(j = 0; j <= k - 1; j++) {
                    v = 2 * math.sqr(vv) * state.g[j];
                    for(i_ = 0; i_ <= k - 1; i_++) {
                        state.optstate.h[j, i_] = state.optstate.h[j, i_] + v * state.g[i_];
                    }
                    v = 2 * math.sqr(vv) * (state.f - state.tasky[i]);
                    for(i_ = 0; i_ <= k - 1; i_++) {
                        state.optstate.h[j, i_] = state.optstate.h[j, i_] + v * state.h[j, i_];
                    }
                }
                i = i + 1;
                goto lbl_31;
            lbl_33:
                goto lbl_7;
            lbl_29:
                if(!state.optstate.xupdated) {
                    goto lbl_34;
                }

                //
                // Report new iteration
                //
                for(i_ = 0; i_ <= k - 1; i_++) {
                    state.c[i_] = state.optstate.x[i_];
                }
                state.f = state.optstate.f;
                lsfitclearrequestfields(state);
                state.xupdated = true;
                state.rstate.stage = 5;
                goto lbl_rcomm;
            lbl_5:
                state.xupdated = false;
                goto lbl_7;
            lbl_34:
                goto lbl_7;
            lbl_8:
                minlm.minlmresults(state.optstate, ref state.c, state.optrep);
                state.repterminationtype = state.optrep.terminationtype;
                state.repiterationscount = state.optrep.iterationscount;

                //
                // calculate errors
                //
                if(state.repterminationtype <= 0) {
                    goto lbl_36;
                }
                state.reprmserror = 0;
                state.repwrmserror = 0;
                state.repavgerror = 0;
                state.repavgrelerror = 0;
                state.repmaxerror = 0;
                relcnt = 0;
                i = 0;
            lbl_38:
                if(i > n - 1) {
                    goto lbl_40;
                }
                for(i_ = 0; i_ <= k - 1; i_++) {
                    state.c[i_] = state.c[i_];
                }
                for(i_ = 0; i_ <= m - 1; i_++) {
                    state.x[i_] = state.taskx[i, i_];
                }
                state.pointindex = i;
                lsfitclearrequestfields(state);
                state.needf = true;
                state.rstate.stage = 6;
                goto lbl_rcomm;
            lbl_6:
                state.needf = false;
                v = state.f;
                if(state.wkind == 1) {
                    vv = state.w[i];
                } else {
                    vv = 1.0;
                }
                state.reprmserror = state.reprmserror + math.sqr(v - state.tasky[i]);
                state.repwrmserror = state.repwrmserror + math.sqr(vv * (v - state.tasky[i]));
                state.repavgerror = state.repavgerror + Math.Abs(v - state.tasky[i]);
                if((double)(state.tasky[i]) != (double)(0)) {
                    state.repavgrelerror = state.repavgrelerror + Math.Abs(v - state.tasky[i]) / Math.Abs(state.tasky[i]);
                    relcnt = relcnt + 1;
                }
                state.repmaxerror = Math.Max(state.repmaxerror, Math.Abs(v - state.tasky[i]));
                i = i + 1;
                goto lbl_38;
            lbl_40:
                state.reprmserror = Math.Sqrt(state.reprmserror / n);
                state.repwrmserror = Math.Sqrt(state.repwrmserror / n);
                state.repavgerror = state.repavgerror / n;
                if((double)(relcnt) != (double)(0)) {
                    state.repavgrelerror = state.repavgrelerror / relcnt;
                }
            lbl_36:
                result = false;
                return result;

                //
            // Saving state
            //
            lbl_rcomm:
                result = true;
                state.rstate.ia[0] = n;
                state.rstate.ia[1] = m;
                state.rstate.ia[2] = k;
                state.rstate.ia[3] = i;
                state.rstate.ia[4] = j;
                state.rstate.ra[0] = v;
                state.rstate.ra[1] = vv;
                state.rstate.ra[2] = relcnt;
                return result;
            }
Beispiel #19
0
        /*************************************************************************
        This function sets scaling coefficients for underlying optimizer.

        ALGLIB optimizers use scaling matrices to test stopping  conditions  (step
        size and gradient are scaled before comparison with tolerances).  Scale of
        the I-th variable is a translation invariant measure of:
        a) "how large" the variable is
        b) how large the step should be to make significant changes in the function

        Generally, scale is NOT considered to be a form of preconditioner.  But LM
        optimizer is unique in that it uses scaling matrix both  in  the  stopping
        condition tests and as Marquardt damping factor.

        Proper scaling is very important for the algorithm performance. It is less
        important for the quality of results, but still has some influence (it  is
        easier  to  converge  when  variables  are  properly  scaled, so premature
        stopping is possible when very badly scalled variables are  combined  with
        relaxed stopping conditions).

        INPUT PARAMETERS:
            State   -   structure stores algorithm state
            S       -   array[N], non-zero scaling coefficients
                        S[i] may be negative, sign doesn't matter.

          -- ALGLIB --
             Copyright 14.01.2011 by Bochkanov Sergey
        *************************************************************************/
        public static void lsfitsetscale(lsfitstate state,
            double[] s)
        {
            int i = 0;

            alglib.ap.assert(alglib.ap.len(s)>=state.k, "LSFitSetScale: Length(S)<K");
            for(i=0; i<=state.k-1; i++)
            {
                alglib.ap.assert(math.isfinite(s[i]), "LSFitSetScale: S contains infinite or NAN elements");
                alglib.ap.assert((double)(s[i])!=(double)(0), "LSFitSetScale: S contains infinite or NAN elements");
                state.s[i] = Math.Abs(s[i]);
            }
        }
        /*************************************************************************
        NOTES:

        1. this algorithm is somewhat unusual because it works with  parameterized
           function f(C,X), where X is a function argument (we  have  many  points
           which are characterized by different  argument  values),  and  C  is  a
           parameter to fit.

           For example, if we want to do linear fit by f(c0,c1,x) = c0*x+c1,  then
           x will be argument, and {c0,c1} will be parameters.
           
           It is important to understand that this algorithm finds minimum in  the
           space of function PARAMETERS (not arguments), so it  needs  derivatives
           of f() with respect to C, not X.
           
           In the example above it will need f=c0*x+c1 and {df/dc0,df/dc1} = {x,1}
           instead of {df/dx} = {c0}.

        2. Callback functions accept C as the first parameter, and X as the second

        3. If  state  was  created  with  LSFitCreateFG(),  algorithm  needs  just
           function   and   its   gradient,   but   if   state   was  created with
           LSFitCreateFGH(), algorithm will need function, gradient and Hessian.
           
           According  to  the  said  above,  there  ase  several  versions of this
           function, which accept different sets of callbacks.
           
           This flexibility opens way to subtle errors - you may create state with
           LSFitCreateFGH() (optimization using Hessian), but call function  which
           does not accept Hessian. So when algorithm will request Hessian,  there
           will be no callback to call. In this case exception will be thrown.
           
           Be careful to avoid such errors because there is no way to find them at
           compile time - you can see them at runtime only.

          -- ALGLIB --
             Copyright 17.08.2009 by Bochkanov Sergey
        *************************************************************************/
        public static bool lsfititeration(lsfitstate state)
        {
            bool result = new bool();
            double lx = 0;
            double lf = 0;
            double ld = 0;
            double rx = 0;
            double rf = 0;
            double rd = 0;
            int n = 0;
            int m = 0;
            int k = 0;
            double v = 0;
            double vv = 0;
            double relcnt = 0;
            int i = 0;
            int j = 0;
            int i_ = 0;

            
            //
            // Reverse communication preparations
            // I know it looks ugly, but it works the same way
            // anywhere from C++ to Python.
            //
            // This code initializes locals by:
            // * random values determined during code
            //   generation - on first subroutine call
            // * values from previous call - on subsequent calls
            //
            if( state.rstate.stage>=0 )
            {
                n = state.rstate.ia[0];
                m = state.rstate.ia[1];
                k = state.rstate.ia[2];
                i = state.rstate.ia[3];
                j = state.rstate.ia[4];
                lx = state.rstate.ra[0];
                lf = state.rstate.ra[1];
                ld = state.rstate.ra[2];
                rx = state.rstate.ra[3];
                rf = state.rstate.ra[4];
                rd = state.rstate.ra[5];
                v = state.rstate.ra[6];
                vv = state.rstate.ra[7];
                relcnt = state.rstate.ra[8];
            }
            else
            {
                n = -983;
                m = -989;
                k = -834;
                i = 900;
                j = -287;
                lx = 364;
                lf = 214;
                ld = -338;
                rx = -686;
                rf = 912;
                rd = 585;
                v = 497;
                vv = -271;
                relcnt = -581;
            }
            if( state.rstate.stage==0 )
            {
                goto lbl_0;
            }
            if( state.rstate.stage==1 )
            {
                goto lbl_1;
            }
            if( state.rstate.stage==2 )
            {
                goto lbl_2;
            }
            if( state.rstate.stage==3 )
            {
                goto lbl_3;
            }
            if( state.rstate.stage==4 )
            {
                goto lbl_4;
            }
            if( state.rstate.stage==5 )
            {
                goto lbl_5;
            }
            if( state.rstate.stage==6 )
            {
                goto lbl_6;
            }
            if( state.rstate.stage==7 )
            {
                goto lbl_7;
            }
            if( state.rstate.stage==8 )
            {
                goto lbl_8;
            }
            if( state.rstate.stage==9 )
            {
                goto lbl_9;
            }
            
            //
            // Routine body
            //
            
            //
            // Init
            //
            if( state.wkind==1 )
            {
                alglib.ap.assert(state.npoints==state.nweights, "LSFitFit: number of points is not equal to the number of weights");
            }
            state.repvaridx = -1;
            n = state.npoints;
            m = state.m;
            k = state.k;
            minlm.minlmsetcond(state.optstate, 0.0, state.epsf, state.epsx, state.maxits);
            minlm.minlmsetstpmax(state.optstate, state.stpmax);
            minlm.minlmsetxrep(state.optstate, state.xrep);
            minlm.minlmsetscale(state.optstate, state.s);
            minlm.minlmsetbc(state.optstate, state.bndl, state.bndu);
            
            //
            //  Check, that transferred derivative value is right
            //
            lsfitclearrequestfields(state);
            if( !((double)(state.teststep)>(double)(0) && state.optalgo==1) )
            {
                goto lbl_10;
            }
            for(i=0; i<=k-1; i++)
            {
                if( math.isfinite(state.bndl[i]) )
                {
                    state.c[i] = Math.Max(state.c[i], state.bndl[i]);
                }
                if( math.isfinite(state.bndu[i]) )
                {
                    state.c[i] = Math.Min(state.c[i], state.bndu[i]);
                }
            }
            state.needfg = true;
            i = 0;
        lbl_12:
            if( i>k-1 )
            {
                goto lbl_14;
            }
            alglib.ap.assert((double)(state.bndl[i])<=(double)(state.c[i]) && (double)(state.c[i])<=(double)(state.bndu[i]), "LSFitIteration: internal error(State.C is out of bounds)");
            v = state.c[i];
            j = 0;
        lbl_15:
            if( j>n-1 )
            {
                goto lbl_17;
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[j,i_];
            }
            state.c[i] = v-state.teststep*state.s[i];
            if( math.isfinite(state.bndl[i]) )
            {
                state.c[i] = Math.Max(state.c[i], state.bndl[i]);
            }
            lx = state.c[i];
            state.rstate.stage = 0;
            goto lbl_rcomm;
        lbl_0:
            lf = state.f;
            ld = state.g[i];
            state.c[i] = v+state.teststep*state.s[i];
            if( math.isfinite(state.bndu[i]) )
            {
                state.c[i] = Math.Min(state.c[i], state.bndu[i]);
            }
            rx = state.c[i];
            state.rstate.stage = 1;
            goto lbl_rcomm;
        lbl_1:
            rf = state.f;
            rd = state.g[i];
            state.c[i] = (lx+rx)/2;
            if( math.isfinite(state.bndl[i]) )
            {
                state.c[i] = Math.Max(state.c[i], state.bndl[i]);
            }
            if( math.isfinite(state.bndu[i]) )
            {
                state.c[i] = Math.Min(state.c[i], state.bndu[i]);
            }
            state.rstate.stage = 2;
            goto lbl_rcomm;
        lbl_2:
            state.c[i] = v;
            if( !optserv.derivativecheck(lf, ld, rf, rd, state.f, state.g[i], rx-lx) )
            {
                state.repvaridx = i;
                state.repterminationtype = -7;
                result = false;
                return result;
            }
            j = j+1;
            goto lbl_15;
        lbl_17:
            i = i+1;
            goto lbl_12;
        lbl_14:
            state.needfg = false;
        lbl_10:
            
            //
            // Optimize
            //
        lbl_18:
            if( !minlm.minlmiteration(state.optstate) )
            {
                goto lbl_19;
            }
            if( !state.optstate.needfi )
            {
                goto lbl_20;
            }
            
            //
            // calculate f[] = wi*(f(xi,c)-yi)
            //
            i = 0;
        lbl_22:
            if( i>n-1 )
            {
                goto lbl_24;
            }
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = state.optstate.x[i_];
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[i,i_];
            }
            state.pointindex = i;
            lsfitclearrequestfields(state);
            state.needf = true;
            state.rstate.stage = 3;
            goto lbl_rcomm;
        lbl_3:
            state.needf = false;
            if( state.wkind==1 )
            {
                vv = state.w[i];
            }
            else
            {
                vv = 1.0;
            }
            state.optstate.fi[i] = vv*(state.f-state.tasky[i]);
            i = i+1;
            goto lbl_22;
        lbl_24:
            goto lbl_18;
        lbl_20:
            if( !state.optstate.needf )
            {
                goto lbl_25;
            }
            
            //
            // calculate F = sum (wi*(f(xi,c)-yi))^2
            //
            state.optstate.f = 0;
            i = 0;
        lbl_27:
            if( i>n-1 )
            {
                goto lbl_29;
            }
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = state.optstate.x[i_];
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[i,i_];
            }
            state.pointindex = i;
            lsfitclearrequestfields(state);
            state.needf = true;
            state.rstate.stage = 4;
            goto lbl_rcomm;
        lbl_4:
            state.needf = false;
            if( state.wkind==1 )
            {
                vv = state.w[i];
            }
            else
            {
                vv = 1.0;
            }
            state.optstate.f = state.optstate.f+math.sqr(vv*(state.f-state.tasky[i]));
            i = i+1;
            goto lbl_27;
        lbl_29:
            goto lbl_18;
        lbl_25:
            if( !state.optstate.needfg )
            {
                goto lbl_30;
            }
            
            //
            // calculate F/gradF
            //
            state.optstate.f = 0;
            for(i=0; i<=k-1; i++)
            {
                state.optstate.g[i] = 0;
            }
            i = 0;
        lbl_32:
            if( i>n-1 )
            {
                goto lbl_34;
            }
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = state.optstate.x[i_];
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[i,i_];
            }
            state.pointindex = i;
            lsfitclearrequestfields(state);
            state.needfg = true;
            state.rstate.stage = 5;
            goto lbl_rcomm;
        lbl_5:
            state.needfg = false;
            if( state.wkind==1 )
            {
                vv = state.w[i];
            }
            else
            {
                vv = 1.0;
            }
            state.optstate.f = state.optstate.f+math.sqr(vv*(state.f-state.tasky[i]));
            v = math.sqr(vv)*2*(state.f-state.tasky[i]);
            for(i_=0; i_<=k-1;i_++)
            {
                state.optstate.g[i_] = state.optstate.g[i_] + v*state.g[i_];
            }
            i = i+1;
            goto lbl_32;
        lbl_34:
            goto lbl_18;
        lbl_30:
            if( !state.optstate.needfij )
            {
                goto lbl_35;
            }
            
            //
            // calculate Fi/jac(Fi)
            //
            i = 0;
        lbl_37:
            if( i>n-1 )
            {
                goto lbl_39;
            }
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = state.optstate.x[i_];
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[i,i_];
            }
            state.pointindex = i;
            lsfitclearrequestfields(state);
            state.needfg = true;
            state.rstate.stage = 6;
            goto lbl_rcomm;
        lbl_6:
            state.needfg = false;
            if( state.wkind==1 )
            {
                vv = state.w[i];
            }
            else
            {
                vv = 1.0;
            }
            state.optstate.fi[i] = vv*(state.f-state.tasky[i]);
            for(i_=0; i_<=k-1;i_++)
            {
                state.optstate.j[i,i_] = vv*state.g[i_];
            }
            i = i+1;
            goto lbl_37;
        lbl_39:
            goto lbl_18;
        lbl_35:
            if( !state.optstate.needfgh )
            {
                goto lbl_40;
            }
            
            //
            // calculate F/grad(F)/hess(F)
            //
            state.optstate.f = 0;
            for(i=0; i<=k-1; i++)
            {
                state.optstate.g[i] = 0;
            }
            for(i=0; i<=k-1; i++)
            {
                for(j=0; j<=k-1; j++)
                {
                    state.optstate.h[i,j] = 0;
                }
            }
            i = 0;
        lbl_42:
            if( i>n-1 )
            {
                goto lbl_44;
            }
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = state.optstate.x[i_];
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[i,i_];
            }
            state.pointindex = i;
            lsfitclearrequestfields(state);
            state.needfgh = true;
            state.rstate.stage = 7;
            goto lbl_rcomm;
        lbl_7:
            state.needfgh = false;
            if( state.wkind==1 )
            {
                vv = state.w[i];
            }
            else
            {
                vv = 1.0;
            }
            state.optstate.f = state.optstate.f+math.sqr(vv*(state.f-state.tasky[i]));
            v = math.sqr(vv)*2*(state.f-state.tasky[i]);
            for(i_=0; i_<=k-1;i_++)
            {
                state.optstate.g[i_] = state.optstate.g[i_] + v*state.g[i_];
            }
            for(j=0; j<=k-1; j++)
            {
                v = 2*math.sqr(vv)*state.g[j];
                for(i_=0; i_<=k-1;i_++)
                {
                    state.optstate.h[j,i_] = state.optstate.h[j,i_] + v*state.g[i_];
                }
                v = 2*math.sqr(vv)*(state.f-state.tasky[i]);
                for(i_=0; i_<=k-1;i_++)
                {
                    state.optstate.h[j,i_] = state.optstate.h[j,i_] + v*state.h[j,i_];
                }
            }
            i = i+1;
            goto lbl_42;
        lbl_44:
            goto lbl_18;
        lbl_40:
            if( !state.optstate.xupdated )
            {
                goto lbl_45;
            }
            
            //
            // Report new iteration
            //
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = state.optstate.x[i_];
            }
            state.f = state.optstate.f;
            lsfitclearrequestfields(state);
            state.xupdated = true;
            state.rstate.stage = 8;
            goto lbl_rcomm;
        lbl_8:
            state.xupdated = false;
            goto lbl_18;
        lbl_45:
            goto lbl_18;
        lbl_19:
            minlm.minlmresults(state.optstate, ref state.c, state.optrep);
            state.repterminationtype = state.optrep.terminationtype;
            state.repiterationscount = state.optrep.iterationscount;
            
            //
            // calculate errors
            //
            if( state.repterminationtype<=0 )
            {
                goto lbl_47;
            }
            state.reprmserror = 0;
            state.repwrmserror = 0;
            state.repavgerror = 0;
            state.repavgrelerror = 0;
            state.repmaxerror = 0;
            relcnt = 0;
            i = 0;
        lbl_49:
            if( i>n-1 )
            {
                goto lbl_51;
            }
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = state.c[i_];
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[i,i_];
            }
            state.pointindex = i;
            lsfitclearrequestfields(state);
            state.needf = true;
            state.rstate.stage = 9;
            goto lbl_rcomm;
        lbl_9:
            state.needf = false;
            v = state.f;
            if( state.wkind==1 )
            {
                vv = state.w[i];
            }
            else
            {
                vv = 1.0;
            }
            state.reprmserror = state.reprmserror+math.sqr(v-state.tasky[i]);
            state.repwrmserror = state.repwrmserror+math.sqr(vv*(v-state.tasky[i]));
            state.repavgerror = state.repavgerror+Math.Abs(v-state.tasky[i]);
            if( (double)(state.tasky[i])!=(double)(0) )
            {
                state.repavgrelerror = state.repavgrelerror+Math.Abs(v-state.tasky[i])/Math.Abs(state.tasky[i]);
                relcnt = relcnt+1;
            }
            state.repmaxerror = Math.Max(state.repmaxerror, Math.Abs(v-state.tasky[i]));
            i = i+1;
            goto lbl_49;
        lbl_51:
            state.reprmserror = Math.Sqrt(state.reprmserror/n);
            state.repwrmserror = Math.Sqrt(state.repwrmserror/n);
            state.repavgerror = state.repavgerror/n;
            if( (double)(relcnt)!=(double)(0) )
            {
                state.repavgrelerror = state.repavgrelerror/relcnt;
            }
        lbl_47:
            result = false;
            return result;
            
            //
            // Saving state
            //
        lbl_rcomm:
            result = true;
            state.rstate.ia[0] = n;
            state.rstate.ia[1] = m;
            state.rstate.ia[2] = k;
            state.rstate.ia[3] = i;
            state.rstate.ia[4] = j;
            state.rstate.ra[0] = lx;
            state.rstate.ra[1] = lf;
            state.rstate.ra[2] = ld;
            state.rstate.ra[3] = rx;
            state.rstate.ra[4] = rf;
            state.rstate.ra[5] = rd;
            state.rstate.ra[6] = v;
            state.rstate.ra[7] = vv;
            state.rstate.ra[8] = relcnt;
            return result;
        }
Beispiel #21
0
        /*************************************************************************
        NOTES:

        1. this algorithm is somewhat unusual because it works with  parameterized
           function f(C,X), where X is a function argument (we  have  many  points
           which are characterized by different  argument  values),  and  C  is  a
           parameter to fit.

           For example, if we want to do linear fit by f(c0,c1,x) = c0*x+c1,  then
           x will be argument, and {c0,c1} will be parameters.
           
           It is important to understand that this algorithm finds minimum in  the
           space of function PARAMETERS (not arguments), so it  needs  derivatives
           of f() with respect to C, not X.
           
           In the example above it will need f=c0*x+c1 and {df/dc0,df/dc1} = {x,1}
           instead of {df/dx} = {c0}.

        2. Callback functions accept C as the first parameter, and X as the second

        3. If  state  was  created  with  LSFitCreateFG(),  algorithm  needs  just
           function   and   its   gradient,   but   if   state   was  created with
           LSFitCreateFGH(), algorithm will need function, gradient and Hessian.
           
           According  to  the  said  above,  there  ase  several  versions of this
           function, which accept different sets of callbacks.
           
           This flexibility opens way to subtle errors - you may create state with
           LSFitCreateFGH() (optimization using Hessian), but call function  which
           does not accept Hessian. So when algorithm will request Hessian,  there
           will be no callback to call. In this case exception will be thrown.
           
           Be careful to avoid such errors because there is no way to find them at
           compile time - you can see them at runtime only.

          -- ALGLIB --
             Copyright 17.08.2009 by Bochkanov Sergey
        *************************************************************************/
        public static bool lsfititeration(lsfitstate state)
        {
            bool result = new bool();
            double lx = 0;
            double lf = 0;
            double ld = 0;
            double rx = 0;
            double rf = 0;
            double rd = 0;
            int n = 0;
            int m = 0;
            int k = 0;
            double v = 0;
            double vv = 0;
            double relcnt = 0;
            int i = 0;
            int j = 0;
            int j1 = 0;
            int info = 0;
            int i_ = 0;

            
            //
            // Reverse communication preparations
            // I know it looks ugly, but it works the same way
            // anywhere from C++ to Python.
            //
            // This code initializes locals by:
            // * random values determined during code
            //   generation - on first subroutine call
            // * values from previous call - on subsequent calls
            //
            if( state.rstate.stage>=0 )
            {
                n = state.rstate.ia[0];
                m = state.rstate.ia[1];
                k = state.rstate.ia[2];
                i = state.rstate.ia[3];
                j = state.rstate.ia[4];
                j1 = state.rstate.ia[5];
                info = state.rstate.ia[6];
                lx = state.rstate.ra[0];
                lf = state.rstate.ra[1];
                ld = state.rstate.ra[2];
                rx = state.rstate.ra[3];
                rf = state.rstate.ra[4];
                rd = state.rstate.ra[5];
                v = state.rstate.ra[6];
                vv = state.rstate.ra[7];
                relcnt = state.rstate.ra[8];
            }
            else
            {
                n = -983;
                m = -989;
                k = -834;
                i = 900;
                j = -287;
                j1 = 364;
                info = 214;
                lx = -338;
                lf = -686;
                ld = 912;
                rx = 585;
                rf = 497;
                rd = -271;
                v = -581;
                vv = 745;
                relcnt = -533;
            }
            if( state.rstate.stage==0 )
            {
                goto lbl_0;
            }
            if( state.rstate.stage==1 )
            {
                goto lbl_1;
            }
            if( state.rstate.stage==2 )
            {
                goto lbl_2;
            }
            if( state.rstate.stage==3 )
            {
                goto lbl_3;
            }
            if( state.rstate.stage==4 )
            {
                goto lbl_4;
            }
            if( state.rstate.stage==5 )
            {
                goto lbl_5;
            }
            if( state.rstate.stage==6 )
            {
                goto lbl_6;
            }
            if( state.rstate.stage==7 )
            {
                goto lbl_7;
            }
            if( state.rstate.stage==8 )
            {
                goto lbl_8;
            }
            if( state.rstate.stage==9 )
            {
                goto lbl_9;
            }
            if( state.rstate.stage==10 )
            {
                goto lbl_10;
            }
            if( state.rstate.stage==11 )
            {
                goto lbl_11;
            }
            if( state.rstate.stage==12 )
            {
                goto lbl_12;
            }
            if( state.rstate.stage==13 )
            {
                goto lbl_13;
            }
            
            //
            // Routine body
            //
            
            //
            // Init
            //
            if( state.wkind==1 )
            {
                alglib.ap.assert(state.npoints==state.nweights, "LSFitFit: number of points is not equal to the number of weights");
            }
            state.repvaridx = -1;
            n = state.npoints;
            m = state.m;
            k = state.k;
            minlm.minlmsetcond(state.optstate, 0.0, state.epsf, state.epsx, state.maxits);
            minlm.minlmsetstpmax(state.optstate, state.stpmax);
            minlm.minlmsetxrep(state.optstate, state.xrep);
            minlm.minlmsetscale(state.optstate, state.s);
            minlm.minlmsetbc(state.optstate, state.bndl, state.bndu);
            
            //
            //  Check that user-supplied gradient is correct
            //
            lsfitclearrequestfields(state);
            if( !((double)(state.teststep)>(double)(0) && state.optalgo==1) )
            {
                goto lbl_14;
            }
            for(i=0; i<=k-1; i++)
            {
                if( math.isfinite(state.bndl[i]) )
                {
                    state.c[i] = Math.Max(state.c[i], state.bndl[i]);
                }
                if( math.isfinite(state.bndu[i]) )
                {
                    state.c[i] = Math.Min(state.c[i], state.bndu[i]);
                }
            }
            state.needfg = true;
            i = 0;
        lbl_16:
            if( i>k-1 )
            {
                goto lbl_18;
            }
            alglib.ap.assert((double)(state.bndl[i])<=(double)(state.c[i]) && (double)(state.c[i])<=(double)(state.bndu[i]), "LSFitIteration: internal error(State.C is out of bounds)");
            v = state.c[i];
            j = 0;
        lbl_19:
            if( j>n-1 )
            {
                goto lbl_21;
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[j,i_];
            }
            state.c[i] = v-state.teststep*state.s[i];
            if( math.isfinite(state.bndl[i]) )
            {
                state.c[i] = Math.Max(state.c[i], state.bndl[i]);
            }
            lx = state.c[i];
            state.rstate.stage = 0;
            goto lbl_rcomm;
        lbl_0:
            lf = state.f;
            ld = state.g[i];
            state.c[i] = v+state.teststep*state.s[i];
            if( math.isfinite(state.bndu[i]) )
            {
                state.c[i] = Math.Min(state.c[i], state.bndu[i]);
            }
            rx = state.c[i];
            state.rstate.stage = 1;
            goto lbl_rcomm;
        lbl_1:
            rf = state.f;
            rd = state.g[i];
            state.c[i] = (lx+rx)/2;
            if( math.isfinite(state.bndl[i]) )
            {
                state.c[i] = Math.Max(state.c[i], state.bndl[i]);
            }
            if( math.isfinite(state.bndu[i]) )
            {
                state.c[i] = Math.Min(state.c[i], state.bndu[i]);
            }
            state.rstate.stage = 2;
            goto lbl_rcomm;
        lbl_2:
            state.c[i] = v;
            if( !optserv.derivativecheck(lf, ld, rf, rd, state.f, state.g[i], rx-lx) )
            {
                state.repvaridx = i;
                state.repterminationtype = -7;
                result = false;
                return result;
            }
            j = j+1;
            goto lbl_19;
        lbl_21:
            i = i+1;
            goto lbl_16;
        lbl_18:
            state.needfg = false;
        lbl_14:
            
            //
            // Fill WCur by weights:
            // * for WKind=0 unit weights are chosen
            // * for WKind=1 we use user-supplied weights stored in State.TaskW
            //
            apserv.rvectorsetlengthatleast(ref state.wcur, n);
            for(i=0; i<=n-1; i++)
            {
                state.wcur[i] = 1.0;
                if( state.wkind==1 )
                {
                    state.wcur[i] = state.taskw[i];
                }
            }
            
            //
            // Optimize
            //
        lbl_22:
            if( !minlm.minlmiteration(state.optstate) )
            {
                goto lbl_23;
            }
            if( !state.optstate.needfi )
            {
                goto lbl_24;
            }
            
            //
            // calculate f[] = wi*(f(xi,c)-yi)
            //
            i = 0;
        lbl_26:
            if( i>n-1 )
            {
                goto lbl_28;
            }
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = state.optstate.x[i_];
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[i,i_];
            }
            state.pointindex = i;
            lsfitclearrequestfields(state);
            state.needf = true;
            state.rstate.stage = 3;
            goto lbl_rcomm;
        lbl_3:
            state.needf = false;
            vv = state.wcur[i];
            state.optstate.fi[i] = vv*(state.f-state.tasky[i]);
            i = i+1;
            goto lbl_26;
        lbl_28:
            goto lbl_22;
        lbl_24:
            if( !state.optstate.needf )
            {
                goto lbl_29;
            }
            
            //
            // calculate F = sum (wi*(f(xi,c)-yi))^2
            //
            state.optstate.f = 0;
            i = 0;
        lbl_31:
            if( i>n-1 )
            {
                goto lbl_33;
            }
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = state.optstate.x[i_];
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[i,i_];
            }
            state.pointindex = i;
            lsfitclearrequestfields(state);
            state.needf = true;
            state.rstate.stage = 4;
            goto lbl_rcomm;
        lbl_4:
            state.needf = false;
            vv = state.wcur[i];
            state.optstate.f = state.optstate.f+math.sqr(vv*(state.f-state.tasky[i]));
            i = i+1;
            goto lbl_31;
        lbl_33:
            goto lbl_22;
        lbl_29:
            if( !state.optstate.needfg )
            {
                goto lbl_34;
            }
            
            //
            // calculate F/gradF
            //
            state.optstate.f = 0;
            for(i=0; i<=k-1; i++)
            {
                state.optstate.g[i] = 0;
            }
            i = 0;
        lbl_36:
            if( i>n-1 )
            {
                goto lbl_38;
            }
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = state.optstate.x[i_];
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[i,i_];
            }
            state.pointindex = i;
            lsfitclearrequestfields(state);
            state.needfg = true;
            state.rstate.stage = 5;
            goto lbl_rcomm;
        lbl_5:
            state.needfg = false;
            vv = state.wcur[i];
            state.optstate.f = state.optstate.f+math.sqr(vv*(state.f-state.tasky[i]));
            v = math.sqr(vv)*2*(state.f-state.tasky[i]);
            for(i_=0; i_<=k-1;i_++)
            {
                state.optstate.g[i_] = state.optstate.g[i_] + v*state.g[i_];
            }
            i = i+1;
            goto lbl_36;
        lbl_38:
            goto lbl_22;
        lbl_34:
            if( !state.optstate.needfij )
            {
                goto lbl_39;
            }
            
            //
            // calculate Fi/jac(Fi)
            //
            i = 0;
        lbl_41:
            if( i>n-1 )
            {
                goto lbl_43;
            }
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = state.optstate.x[i_];
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[i,i_];
            }
            state.pointindex = i;
            lsfitclearrequestfields(state);
            state.needfg = true;
            state.rstate.stage = 6;
            goto lbl_rcomm;
        lbl_6:
            state.needfg = false;
            vv = state.wcur[i];
            state.optstate.fi[i] = vv*(state.f-state.tasky[i]);
            for(i_=0; i_<=k-1;i_++)
            {
                state.optstate.j[i,i_] = vv*state.g[i_];
            }
            i = i+1;
            goto lbl_41;
        lbl_43:
            goto lbl_22;
        lbl_39:
            if( !state.optstate.needfgh )
            {
                goto lbl_44;
            }
            
            //
            // calculate F/grad(F)/hess(F)
            //
            state.optstate.f = 0;
            for(i=0; i<=k-1; i++)
            {
                state.optstate.g[i] = 0;
            }
            for(i=0; i<=k-1; i++)
            {
                for(j=0; j<=k-1; j++)
                {
                    state.optstate.h[i,j] = 0;
                }
            }
            i = 0;
        lbl_46:
            if( i>n-1 )
            {
                goto lbl_48;
            }
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = state.optstate.x[i_];
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[i,i_];
            }
            state.pointindex = i;
            lsfitclearrequestfields(state);
            state.needfgh = true;
            state.rstate.stage = 7;
            goto lbl_rcomm;
        lbl_7:
            state.needfgh = false;
            vv = state.wcur[i];
            state.optstate.f = state.optstate.f+math.sqr(vv*(state.f-state.tasky[i]));
            v = math.sqr(vv)*2*(state.f-state.tasky[i]);
            for(i_=0; i_<=k-1;i_++)
            {
                state.optstate.g[i_] = state.optstate.g[i_] + v*state.g[i_];
            }
            for(j=0; j<=k-1; j++)
            {
                v = 2*math.sqr(vv)*state.g[j];
                for(i_=0; i_<=k-1;i_++)
                {
                    state.optstate.h[j,i_] = state.optstate.h[j,i_] + v*state.g[i_];
                }
                v = 2*math.sqr(vv)*(state.f-state.tasky[i]);
                for(i_=0; i_<=k-1;i_++)
                {
                    state.optstate.h[j,i_] = state.optstate.h[j,i_] + v*state.h[j,i_];
                }
            }
            i = i+1;
            goto lbl_46;
        lbl_48:
            goto lbl_22;
        lbl_44:
            if( !state.optstate.xupdated )
            {
                goto lbl_49;
            }
            
            //
            // Report new iteration
            //
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = state.optstate.x[i_];
            }
            state.f = state.optstate.f;
            lsfitclearrequestfields(state);
            state.xupdated = true;
            state.rstate.stage = 8;
            goto lbl_rcomm;
        lbl_8:
            state.xupdated = false;
            goto lbl_22;
        lbl_49:
            goto lbl_22;
        lbl_23:
            minlm.minlmresults(state.optstate, ref state.c, state.optrep);
            state.repterminationtype = state.optrep.terminationtype;
            state.repiterationscount = state.optrep.iterationscount;
            
            //
            // calculate errors
            //
            if( state.repterminationtype<=0 )
            {
                goto lbl_51;
            }
            
            //
            // Calculate RMS/Avg/Max/... errors
            //
            state.reprmserror = 0;
            state.repwrmserror = 0;
            state.repavgerror = 0;
            state.repavgrelerror = 0;
            state.repmaxerror = 0;
            relcnt = 0;
            i = 0;
        lbl_53:
            if( i>n-1 )
            {
                goto lbl_55;
            }
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = state.c[i_];
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[i,i_];
            }
            state.pointindex = i;
            lsfitclearrequestfields(state);
            state.needf = true;
            state.rstate.stage = 9;
            goto lbl_rcomm;
        lbl_9:
            state.needf = false;
            v = state.f;
            vv = state.wcur[i];
            state.reprmserror = state.reprmserror+math.sqr(v-state.tasky[i]);
            state.repwrmserror = state.repwrmserror+math.sqr(vv*(v-state.tasky[i]));
            state.repavgerror = state.repavgerror+Math.Abs(v-state.tasky[i]);
            if( (double)(state.tasky[i])!=(double)(0) )
            {
                state.repavgrelerror = state.repavgrelerror+Math.Abs(v-state.tasky[i])/Math.Abs(state.tasky[i]);
                relcnt = relcnt+1;
            }
            state.repmaxerror = Math.Max(state.repmaxerror, Math.Abs(v-state.tasky[i]));
            i = i+1;
            goto lbl_53;
        lbl_55:
            state.reprmserror = Math.Sqrt(state.reprmserror/n);
            state.repwrmserror = Math.Sqrt(state.repwrmserror/n);
            state.repavgerror = state.repavgerror/n;
            if( (double)(relcnt)!=(double)(0) )
            {
                state.repavgrelerror = state.repavgrelerror/relcnt;
            }
            
            //
            // Calculate covariance matrix
            //
            apserv.rmatrixsetlengthatleast(ref state.tmpjac, n, k);
            apserv.rvectorsetlengthatleast(ref state.tmpf, n);
            apserv.rvectorsetlengthatleast(ref state.tmp, k);
            if( (double)(state.diffstep)<=(double)(0) )
            {
                goto lbl_56;
            }
            
            //
            // Compute Jacobian by means of numerical differentiation
            //
            lsfitclearrequestfields(state);
            state.needf = true;
            i = 0;
        lbl_58:
            if( i>n-1 )
            {
                goto lbl_60;
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[i,i_];
            }
            state.pointindex = i;
            state.rstate.stage = 10;
            goto lbl_rcomm;
        lbl_10:
            state.tmpf[i] = state.f;
            j = 0;
        lbl_61:
            if( j>k-1 )
            {
                goto lbl_63;
            }
            v = state.c[j];
            lx = v-state.diffstep*state.s[j];
            state.c[j] = lx;
            if( math.isfinite(state.bndl[j]) )
            {
                state.c[j] = Math.Max(state.c[j], state.bndl[j]);
            }
            state.rstate.stage = 11;
            goto lbl_rcomm;
        lbl_11:
            lf = state.f;
            rx = v+state.diffstep*state.s[j];
            state.c[j] = rx;
            if( math.isfinite(state.bndu[j]) )
            {
                state.c[j] = Math.Min(state.c[j], state.bndu[j]);
            }
            state.rstate.stage = 12;
            goto lbl_rcomm;
        lbl_12:
            rf = state.f;
            state.c[j] = v;
            if( (double)(rx)!=(double)(lx) )
            {
                state.tmpjac[i,j] = (rf-lf)/(rx-lx);
            }
            else
            {
                state.tmpjac[i,j] = 0;
            }
            j = j+1;
            goto lbl_61;
        lbl_63:
            i = i+1;
            goto lbl_58;
        lbl_60:
            state.needf = false;
            goto lbl_57;
        lbl_56:
            
            //
            // Jacobian is calculated with user-provided analytic gradient
            //
            lsfitclearrequestfields(state);
            state.needfg = true;
            i = 0;
        lbl_64:
            if( i>n-1 )
            {
                goto lbl_66;
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[i,i_];
            }
            state.pointindex = i;
            state.rstate.stage = 13;
            goto lbl_rcomm;
        lbl_13:
            state.tmpf[i] = state.f;
            for(j=0; j<=k-1; j++)
            {
                state.tmpjac[i,j] = state.g[j];
            }
            i = i+1;
            goto lbl_64;
        lbl_66:
            state.needfg = false;
        lbl_57:
            for(i=0; i<=k-1; i++)
            {
                state.tmp[i] = 0.0;
            }
            estimateerrors(state.tmpjac, state.tmpf, state.tasky, state.wcur, state.tmp, state.s, n, k, state.rep, ref state.tmpjacw, 0);
        lbl_51:
            result = false;
            return result;
            
            //
            // Saving state
            //
        lbl_rcomm:
            result = true;
            state.rstate.ia[0] = n;
            state.rstate.ia[1] = m;
            state.rstate.ia[2] = k;
            state.rstate.ia[3] = i;
            state.rstate.ia[4] = j;
            state.rstate.ia[5] = j1;
            state.rstate.ia[6] = info;
            state.rstate.ra[0] = lx;
            state.rstate.ra[1] = lf;
            state.rstate.ra[2] = ld;
            state.rstate.ra[3] = rx;
            state.rstate.ra[4] = rf;
            state.rstate.ra[5] = rd;
            state.rstate.ra[6] = v;
            state.rstate.ra[7] = vv;
            state.rstate.ra[8] = relcnt;
            return result;
        }
        /*************************************************************************
        Nonlinear least squares fitting results.

        Called after return from LSFitFit().

        INPUT PARAMETERS:
            State   -   algorithm state

        OUTPUT PARAMETERS:
            Info    -   completetion code:
                            * -7    gradient verification failed.
                                    See LSFitSetGradientCheck() for more information.
                            *  1    relative function improvement is no more than
                                    EpsF.
                            *  2    relative step is no more than EpsX.
                            *  4    gradient norm is no more than EpsG
                            *  5    MaxIts steps was taken
                            *  7    stopping conditions are too stringent,
                                    further improvement is impossible
            C       -   array[0..K-1], solution
            Rep     -   optimization report. Following fields are set:
                        * Rep.TerminationType completetion code:
                        * RMSError          rms error on the (X,Y).
                        * AvgError          average error on the (X,Y).
                        * AvgRelError       average relative error on the non-zero Y
                        * MaxError          maximum error
                                            NON-WEIGHTED ERRORS ARE CALCULATED
                        * WRMSError         weighted rms error on the (X,Y).


          -- ALGLIB --
             Copyright 17.08.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void lsfitresults(lsfitstate state,
            ref int info,
            ref double[] c,
            lsfitreport rep)
        {
            int i_ = 0;

            info = 0;
            c = new double[0];

            info = state.repterminationtype;
            rep.varidx = state.repvaridx;
            if( info>0 )
            {
                c = new double[state.k];
                for(i_=0; i_<=state.k-1;i_++)
                {
                    c[i_] = state.c[i_];
                }
                rep.rmserror = state.reprmserror;
                rep.wrmserror = state.repwrmserror;
                rep.avgerror = state.repavgerror;
                rep.avgrelerror = state.repavgrelerror;
                rep.maxerror = state.repmaxerror;
                rep.iterationscount = state.repiterationscount;
            }
        }
Beispiel #23
0
        /*************************************************************************
        This  subroutine  turns  on  verification  of  the  user-supplied analytic
        gradient:
        * user calls this subroutine before fitting begins
        * LSFitFit() is called
        * prior to actual fitting, for  each  point  in  data  set  X_i  and  each
          component  of  parameters  being  fited C_j algorithm performs following
          steps:
          * two trial steps are made to C_j-TestStep*S[j] and C_j+TestStep*S[j],
            where C_j is j-th parameter and S[j] is a scale of j-th parameter
          * if needed, steps are bounded with respect to constraints on C[]
          * F(X_i|C) is evaluated at these trial points
          * we perform one more evaluation in the middle point of the interval
          * we  build  cubic  model using function values and derivatives at trial
            points and we compare its prediction with actual value in  the  middle
            point
          * in case difference between prediction and actual value is higher  than
            some predetermined threshold, algorithm stops with completion code -7;
            Rep.VarIdx is set to index of the parameter with incorrect derivative.
        * after verification is over, algorithm proceeds to the actual optimization.

        NOTE 1: verification needs N*K (points count * parameters count)  gradient
                evaluations. It is very costly and you should use it only for  low
                dimensional  problems,  when  you  want  to  be  sure  that you've
                correctly calculated analytic derivatives. You should not  use  it
                in the production code  (unless  you  want  to  check  derivatives
                provided by some third party).

        NOTE 2: you  should  carefully  choose  TestStep. Value which is too large
                (so large that function behaviour is significantly non-cubic) will
                lead to false alarms. You may use  different  step  for  different
                parameters by means of setting scale with LSFitSetScale().

        NOTE 3: this function may lead to false positives. In case it reports that
                I-th  derivative was calculated incorrectly, you may decrease test
                step  and  try  one  more  time  - maybe your function changes too
                sharply  and  your  step  is  too  large for such rapidly chanding
                function.

        NOTE 4: this function works only for optimizers created with LSFitCreateWFG()
                or LSFitCreateFG() constructors.
                
        INPUT PARAMETERS:
            State       -   structure used to store algorithm state
            TestStep    -   verification step:
                            * TestStep=0 turns verification off
                            * TestStep>0 activates verification

          -- ALGLIB --
             Copyright 15.06.2012 by Bochkanov Sergey
        *************************************************************************/
        public static void lsfitsetgradientcheck(lsfitstate state,
            double teststep)
        {
            alglib.ap.assert(math.isfinite(teststep), "LSFitSetGradientCheck: TestStep contains NaN or Infinite");
            alglib.ap.assert((double)(teststep)>=(double)(0), "LSFitSetGradientCheck: invalid argument TestStep(TestStep<0)");
            state.teststep = teststep;
        }
Beispiel #24
0
 public override alglib.apobject make_copy()
 {
     lsfitstate _result = new lsfitstate();
     _result.optalgo = optalgo;
     _result.m = m;
     _result.k = k;
     _result.epsf = epsf;
     _result.epsx = epsx;
     _result.maxits = maxits;
     _result.stpmax = stpmax;
     _result.xrep = xrep;
     _result.s = (double[])s.Clone();
     _result.bndl = (double[])bndl.Clone();
     _result.bndu = (double[])bndu.Clone();
     _result.taskx = (double[,])taskx.Clone();
     _result.tasky = (double[])tasky.Clone();
     _result.npoints = npoints;
     _result.taskw = (double[])taskw.Clone();
     _result.nweights = nweights;
     _result.wkind = wkind;
     _result.wits = wits;
     _result.diffstep = diffstep;
     _result.teststep = teststep;
     _result.xupdated = xupdated;
     _result.needf = needf;
     _result.needfg = needfg;
     _result.needfgh = needfgh;
     _result.pointindex = pointindex;
     _result.x = (double[])x.Clone();
     _result.c = (double[])c.Clone();
     _result.f = f;
     _result.g = (double[])g.Clone();
     _result.h = (double[,])h.Clone();
     _result.wcur = (double[])wcur.Clone();
     _result.tmp = (double[])tmp.Clone();
     _result.tmpf = (double[])tmpf.Clone();
     _result.tmpjac = (double[,])tmpjac.Clone();
     _result.tmpjacw = (double[,])tmpjacw.Clone();
     _result.tmpnoise = tmpnoise;
     _result.invrep = (matinv.matinvreport)invrep.make_copy();
     _result.repiterationscount = repiterationscount;
     _result.repterminationtype = repterminationtype;
     _result.repvaridx = repvaridx;
     _result.reprmserror = reprmserror;
     _result.repavgerror = repavgerror;
     _result.repavgrelerror = repavgrelerror;
     _result.repmaxerror = repmaxerror;
     _result.repwrmserror = repwrmserror;
     _result.rep = (lsfitreport)rep.make_copy();
     _result.optstate = (minlm.minlmstate)optstate.make_copy();
     _result.optrep = (minlm.minlmreport)optrep.make_copy();
     _result.prevnpt = prevnpt;
     _result.prevalgo = prevalgo;
     _result.rstate = (rcommstate)rstate.make_copy();
     return _result;
 }
Beispiel #25
0
 /*************************************************************************
 Internal subroutine
 *************************************************************************/
 private static void lsfitclearrequestfields(ref lsfitstate state)
 {
     state.needf = false;
     state.needfg = false;
     state.needfgh = false;
 }
Beispiel #26
0
        /*************************************************************************
        Weighted nonlinear least squares fitting using function values only.

        Combination of numerical differentiation and secant updates is used to
        obtain function Jacobian.

        Nonlinear task min(F(c)) is solved, where

            F(c) = (w[0]*(f(c,x[0])-y[0]))^2 + ... + (w[n-1]*(f(c,x[n-1])-y[n-1]))^2,

            * N is a number of points,
            * M is a dimension of a space points belong to,
            * K is a dimension of a space of parameters being fitted,
            * w is an N-dimensional vector of weight coefficients,
            * x is a set of N points, each of them is an M-dimensional vector,
            * c is a K-dimensional vector of parameters being fitted

        This subroutine uses only f(c,x[i]).

        INPUT PARAMETERS:
            X       -   array[0..N-1,0..M-1], points (one row = one point)
            Y       -   array[0..N-1], function values.
            W       -   weights, array[0..N-1]
            C       -   array[0..K-1], initial approximation to the solution,
            N       -   number of points, N>1
            M       -   dimension of space
            K       -   number of parameters being fitted
            DiffStep-   numerical differentiation step;
                        should not be very small or large;
                        large = loss of accuracy
                        small = growth of round-off errors

        OUTPUT PARAMETERS:
            State   -   structure which stores algorithm state

          -- ALGLIB --
             Copyright 18.10.2008 by Bochkanov Sergey
        *************************************************************************/
        public static void lsfitcreatewf(double[,] x,
            double[] y,
            double[] w,
            double[] c,
            int n,
            int m,
            int k,
            double diffstep,
            lsfitstate state)
        {
            int i = 0;
            int i_ = 0;

            alglib.ap.assert(n>=1, "LSFitCreateWF: N<1!");
            alglib.ap.assert(m>=1, "LSFitCreateWF: M<1!");
            alglib.ap.assert(k>=1, "LSFitCreateWF: K<1!");
            alglib.ap.assert(alglib.ap.len(c)>=k, "LSFitCreateWF: length(C)<K!");
            alglib.ap.assert(apserv.isfinitevector(c, k), "LSFitCreateWF: C contains infinite or NaN values!");
            alglib.ap.assert(alglib.ap.len(y)>=n, "LSFitCreateWF: length(Y)<N!");
            alglib.ap.assert(apserv.isfinitevector(y, n), "LSFitCreateWF: Y contains infinite or NaN values!");
            alglib.ap.assert(alglib.ap.len(w)>=n, "LSFitCreateWF: length(W)<N!");
            alglib.ap.assert(apserv.isfinitevector(w, n), "LSFitCreateWF: W contains infinite or NaN values!");
            alglib.ap.assert(alglib.ap.rows(x)>=n, "LSFitCreateWF: rows(X)<N!");
            alglib.ap.assert(alglib.ap.cols(x)>=m, "LSFitCreateWF: cols(X)<M!");
            alglib.ap.assert(apserv.apservisfinitematrix(x, n, m), "LSFitCreateWF: X contains infinite or NaN values!");
            alglib.ap.assert(math.isfinite(diffstep), "LSFitCreateWF: DiffStep is not finite!");
            alglib.ap.assert((double)(diffstep)>(double)(0), "LSFitCreateWF: DiffStep<=0!");
            state.teststep = 0;
            state.diffstep = diffstep;
            state.npoints = n;
            state.nweights = n;
            state.wkind = 1;
            state.m = m;
            state.k = k;
            lsfitsetcond(state, 0.0, 0.0, 0);
            lsfitsetstpmax(state, 0.0);
            lsfitsetxrep(state, false);
            state.taskx = new double[n, m];
            state.tasky = new double[n];
            state.taskw = new double[n];
            state.c = new double[k];
            state.x = new double[m];
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = c[i_];
            }
            for(i_=0; i_<=n-1;i_++)
            {
                state.taskw[i_] = w[i_];
            }
            for(i=0; i<=n-1; i++)
            {
                for(i_=0; i_<=m-1;i_++)
                {
                    state.taskx[i,i_] = x[i,i_];
                }
                state.tasky[i] = y[i];
            }
            state.s = new double[k];
            state.bndl = new double[k];
            state.bndu = new double[k];
            for(i=0; i<=k-1; i++)
            {
                state.s[i] = 1.0;
                state.bndl[i] = Double.NegativeInfinity;
                state.bndu[i] = Double.PositiveInfinity;
            }
            state.optalgo = 0;
            state.prevnpt = -1;
            state.prevalgo = -1;
            minlm.minlmcreatev(k, n, state.c, diffstep, state.optstate);
            lsfitclearrequestfields(state);
            state.rstate.ia = new int[6+1];
            state.rstate.ra = new double[8+1];
            state.rstate.stage = -1;
        }
Beispiel #27
0
        /*************************************************************************
        Stopping conditions for nonlinear least squares fitting.

        INPUT PARAMETERS:
            State   -   structure which stores algorithm state between calls and
                        which is used for reverse communication. Must be initialized
                        with LSFitNonLinearCreate???()
            EpsF    -   stopping criterion. Algorithm stops if
                        |F(k+1)-F(k)| <= EpsF*max{|F(k)|, |F(k+1)|, 1}
            EpsX    -   stopping criterion. Algorithm stops if
                        |X(k+1)-X(k)| <= EpsX*(1+|X(k)|)
            MaxIts  -   stopping criterion. Algorithm stops after MaxIts iterations.
                        MaxIts=0 means no stopping criterion.

        NOTE

        Passing EpsF=0, EpsX=0 and MaxIts=0 (simultaneously) will lead to automatic
        stopping criterion selection (according to the scheme used by MINLM unit).


          -- ALGLIB --
             Copyright 17.08.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void lsfitnonlinearsetcond(ref lsfitstate state,
            double epsf,
            double epsx,
            int maxits)
        {
            System.Diagnostics.Debug.Assert((double)(epsf)>=(double)(0), "LSFitNonlinearSetCond: negative EpsF!");
            System.Diagnostics.Debug.Assert((double)(epsx)>=(double)(0), "LSFitNonlinearSetCond: negative EpsX!");
            System.Diagnostics.Debug.Assert(maxits>=0, "LSFitNonlinearSetCond: negative MaxIts!");
            state.epsf = epsf;
            state.epsx = epsx;
            state.maxits = maxits;
        }
Beispiel #28
0
        /*************************************************************************
        Nonlinear least squares fitting using gradient/Hessian, without individial
        weights.

        Nonlinear task min(F(c)) is solved, where

            F(c) = ((f(c,x[0])-y[0]))^2 + ... + ((f(c,x[n-1])-y[n-1]))^2,

            * N is a number of points,
            * M is a dimension of a space points belong to,
            * K is a dimension of a space of parameters being fitted,
            * x is a set of N points, each of them is an M-dimensional vector,
            * c is a K-dimensional vector of parameters being fitted

        This subroutine uses f(c,x[i]), its gradient and its Hessian.

        INPUT PARAMETERS:
            X       -   array[0..N-1,0..M-1], points (one row = one point)
            Y       -   array[0..N-1], function values.
            C       -   array[0..K-1], initial approximation to the solution,
            N       -   number of points, N>1
            M       -   dimension of space
            K       -   number of parameters being fitted

        OUTPUT PARAMETERS:
            State   -   structure which stores algorithm state


          -- ALGLIB --
             Copyright 17.08.2009 by Bochkanov Sergey
        *************************************************************************/
        public static void lsfitcreatefgh(double[,] x,
            double[] y,
            double[] c,
            int n,
            int m,
            int k,
            lsfitstate state)
        {
            int i = 0;
            int i_ = 0;

            alglib.ap.assert(n>=1, "LSFitCreateFGH: N<1!");
            alglib.ap.assert(m>=1, "LSFitCreateFGH: M<1!");
            alglib.ap.assert(k>=1, "LSFitCreateFGH: K<1!");
            alglib.ap.assert(alglib.ap.len(c)>=k, "LSFitCreateFGH: length(C)<K!");
            alglib.ap.assert(apserv.isfinitevector(c, k), "LSFitCreateFGH: C contains infinite or NaN values!");
            alglib.ap.assert(alglib.ap.len(y)>=n, "LSFitCreateFGH: length(Y)<N!");
            alglib.ap.assert(apserv.isfinitevector(y, n), "LSFitCreateFGH: Y contains infinite or NaN values!");
            alglib.ap.assert(alglib.ap.rows(x)>=n, "LSFitCreateFGH: rows(X)<N!");
            alglib.ap.assert(alglib.ap.cols(x)>=m, "LSFitCreateFGH: cols(X)<M!");
            alglib.ap.assert(apserv.apservisfinitematrix(x, n, m), "LSFitCreateFGH: X contains infinite or NaN values!");
            state.teststep = 0;
            state.diffstep = 0;
            state.npoints = n;
            state.wkind = 0;
            state.m = m;
            state.k = k;
            lsfitsetcond(state, 0.0, 0.0, 0);
            lsfitsetstpmax(state, 0.0);
            lsfitsetxrep(state, false);
            state.taskx = new double[n, m];
            state.tasky = new double[n];
            state.c = new double[k];
            state.h = new double[k, k];
            state.x = new double[m];
            state.g = new double[k];
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = c[i_];
            }
            for(i=0; i<=n-1; i++)
            {
                for(i_=0; i_<=m-1;i_++)
                {
                    state.taskx[i,i_] = x[i,i_];
                }
                state.tasky[i] = y[i];
            }
            state.s = new double[k];
            state.bndl = new double[k];
            state.bndu = new double[k];
            for(i=0; i<=k-1; i++)
            {
                state.s[i] = 1.0;
                state.bndl[i] = Double.NegativeInfinity;
                state.bndu[i] = Double.PositiveInfinity;
            }
            state.optalgo = 2;
            state.prevnpt = -1;
            state.prevalgo = -1;
            minlm.minlmcreatefgh(k, state.c, state.optstate);
            lsfitclearrequestfields(state);
            state.rstate.ia = new int[6+1];
            state.rstate.ra = new double[8+1];
            state.rstate.stage = -1;
        }
Beispiel #29
0
        /*************************************************************************
        Nonlinear least squares fitting. Algorithm iteration.

        Called after inialization of the State structure with  LSFitNonlinearXXX()
        subroutine. See HTML docs for examples.

        INPUT PARAMETERS:
            State   -   structure which stores algorithm state between  subsequent
                        calls and which is used for reverse communication. Must be
                        initialized with LSFitNonlinearXXX() call first.

        RESULT
        1. If subroutine returned False, iterative algorithm has converged.
        2. If subroutine returned True, then if:
        * if State.NeedF=True,      function value F(X,C) is required
        * if State.NeedFG=True,     function value F(X,C) and gradient  dF/dC(X,C)
                                    are required
        * if State.NeedFGH=True     function value F(X,C), gradient dF/dC(X,C) and
                                    Hessian are required

        One and only one of this fields can be set at time.

        Function, its gradient and Hessian are calculated at  (X,C),  where  X  is
        stored in State.X[0..M-1] and C is stored in State.C[0..K-1].

        Results are stored:
        * function value            -   in State.F
        * gradient                  -   in State.G[0..K-1]
        * Hessian                   -   in State.H[0..K-1,0..K-1]

          -- ALGLIB --
             Copyright 17.08.2009 by Bochkanov Sergey
        *************************************************************************/
        public static bool lsfitnonlineariteration(ref lsfitstate state)
        {
            bool result = new bool();
            int n = 0;
            int m = 0;
            int k = 0;
            int i = 0;
            int j = 0;
            double v = 0;
            double relcnt = 0;
            int i_ = 0;

            
            //
            // Reverse communication preparations
            // I know it looks ugly, but it works the same way
            // anywhere from C++ to Python.
            //
            // This code initializes locals by:
            // * random values determined during code
            //   generation - on first subroutine call
            // * values from previous call - on subsequent calls
            //
            if( state.rstate.stage>=0 )
            {
                n = state.rstate.ia[0];
                m = state.rstate.ia[1];
                k = state.rstate.ia[2];
                i = state.rstate.ia[3];
                j = state.rstate.ia[4];
                v = state.rstate.ra[0];
                relcnt = state.rstate.ra[1];
            }
            else
            {
                n = -983;
                m = -989;
                k = -834;
                i = 900;
                j = -287;
                v = 364;
                relcnt = 214;
            }
            if( state.rstate.stage==0 )
            {
                goto lbl_0;
            }
            if( state.rstate.stage==1 )
            {
                goto lbl_1;
            }
            if( state.rstate.stage==2 )
            {
                goto lbl_2;
            }
            if( state.rstate.stage==3 )
            {
                goto lbl_3;
            }
            if( state.rstate.stage==4 )
            {
                goto lbl_4;
            }
            
            //
            // Routine body
            //
            
            //
            // check params
            //
            if( state.n<1 | state.m<1 | state.k<1 | (double)(state.epsf)<(double)(0) | (double)(state.epsx)<(double)(0) | state.maxits<0 )
            {
                state.repterminationtype = -1;
                result = false;
                return result;
            }
            
            //
            // init
            //
            n = state.n;
            m = state.m;
            k = state.k;
            state.x = new double[m];
            state.g = new double[k];
            if( state.havehess )
            {
                state.h = new double[k, k];
            }
            
            //
            // initialize LM optimizer
            //
            if( state.havehess )
            {
                
                //
                // use Hessian.
                // transform stopping conditions.
                //
                minlm.minlmcreatefgh(k, ref state.c, ref state.optstate);
            }
            else
            {
                
                //
                // use one of gradient-based schemes (depending on gradient cost).
                // transform stopping conditions.
                //
                if( state.cheapfg )
                {
                    minlm.minlmcreatefgj(k, n, ref state.c, ref state.optstate);
                }
                else
                {
                    minlm.minlmcreatefj(k, n, ref state.c, ref state.optstate);
                }
            }
            minlm.minlmsetcond(ref state.optstate, 0.0, state.epsf, state.epsx, state.maxits);
            minlm.minlmsetstpmax(ref state.optstate, state.stpmax);
            
            //
            // Optimize
            //
        lbl_5:
            if( ! minlm.minlmiteration(ref state.optstate) )
            {
                goto lbl_6;
            }
            if( ! state.optstate.needf )
            {
                goto lbl_7;
            }
            
            //
            // calculate F = sum (wi*(f(xi,c)-yi))^2
            //
            state.optstate.f = 0;
            i = 0;
        lbl_9:
            if( i>n-1 )
            {
                goto lbl_11;
            }
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = state.optstate.x[i_];
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[i,i_];
            }
            state.pointindex = i;
            lsfitclearrequestfields(ref state);
            state.needf = true;
            state.rstate.stage = 0;
            goto lbl_rcomm;
        lbl_0:
            state.optstate.f = state.optstate.f+AP.Math.Sqr(state.w[i]*(state.f-state.tasky[i]));
            i = i+1;
            goto lbl_9;
        lbl_11:
            goto lbl_5;
        lbl_7:
            if( ! state.optstate.needfg )
            {
                goto lbl_12;
            }
            
            //
            // calculate F/gradF
            //
            state.optstate.f = 0;
            for(i=0; i<=k-1; i++)
            {
                state.optstate.g[i] = 0;
            }
            i = 0;
        lbl_14:
            if( i>n-1 )
            {
                goto lbl_16;
            }
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = state.optstate.x[i_];
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[i,i_];
            }
            state.pointindex = i;
            lsfitclearrequestfields(ref state);
            state.needfg = true;
            state.rstate.stage = 1;
            goto lbl_rcomm;
        lbl_1:
            state.optstate.f = state.optstate.f+AP.Math.Sqr(state.w[i]*(state.f-state.tasky[i]));
            v = AP.Math.Sqr(state.w[i])*2*(state.f-state.tasky[i]);
            for(i_=0; i_<=k-1;i_++)
            {
                state.optstate.g[i_] = state.optstate.g[i_] + v*state.g[i_];
            }
            i = i+1;
            goto lbl_14;
        lbl_16:
            goto lbl_5;
        lbl_12:
            if( ! state.optstate.needfij )
            {
                goto lbl_17;
            }
            
            //
            // calculate Fi/jac(Fi)
            //
            i = 0;
        lbl_19:
            if( i>n-1 )
            {
                goto lbl_21;
            }
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = state.optstate.x[i_];
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[i,i_];
            }
            state.pointindex = i;
            lsfitclearrequestfields(ref state);
            state.needfg = true;
            state.rstate.stage = 2;
            goto lbl_rcomm;
        lbl_2:
            state.optstate.fi[i] = state.w[i]*(state.f-state.tasky[i]);
            v = state.w[i];
            for(i_=0; i_<=k-1;i_++)
            {
                state.optstate.j[i,i_] = v*state.g[i_];
            }
            i = i+1;
            goto lbl_19;
        lbl_21:
            goto lbl_5;
        lbl_17:
            if( ! state.optstate.needfgh )
            {
                goto lbl_22;
            }
            
            //
            // calculate F/grad(F)/hess(F)
            //
            state.optstate.f = 0;
            for(i=0; i<=k-1; i++)
            {
                state.optstate.g[i] = 0;
            }
            for(i=0; i<=k-1; i++)
            {
                for(j=0; j<=k-1; j++)
                {
                    state.optstate.h[i,j] = 0;
                }
            }
            i = 0;
        lbl_24:
            if( i>n-1 )
            {
                goto lbl_26;
            }
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = state.optstate.x[i_];
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[i,i_];
            }
            state.pointindex = i;
            lsfitclearrequestfields(ref state);
            state.needfgh = true;
            state.rstate.stage = 3;
            goto lbl_rcomm;
        lbl_3:
            state.optstate.f = state.optstate.f+AP.Math.Sqr(state.w[i]*(state.f-state.tasky[i]));
            v = AP.Math.Sqr(state.w[i])*2*(state.f-state.tasky[i]);
            for(i_=0; i_<=k-1;i_++)
            {
                state.optstate.g[i_] = state.optstate.g[i_] + v*state.g[i_];
            }
            for(j=0; j<=k-1; j++)
            {
                v = 2*AP.Math.Sqr(state.w[i])*state.g[j];
                for(i_=0; i_<=k-1;i_++)
                {
                    state.optstate.h[j,i_] = state.optstate.h[j,i_] + v*state.g[i_];
                }
                v = 2*AP.Math.Sqr(state.w[i])*(state.f-state.tasky[i]);
                for(i_=0; i_<=k-1;i_++)
                {
                    state.optstate.h[j,i_] = state.optstate.h[j,i_] + v*state.h[j,i_];
                }
            }
            i = i+1;
            goto lbl_24;
        lbl_26:
            goto lbl_5;
        lbl_22:
            goto lbl_5;
        lbl_6:
            minlm.minlmresults(ref state.optstate, ref state.c, ref state.optrep);
            state.repterminationtype = state.optrep.terminationtype;
            
            //
            // calculate errors
            //
            if( state.repterminationtype<=0 )
            {
                goto lbl_27;
            }
            state.reprmserror = 0;
            state.repavgerror = 0;
            state.repavgrelerror = 0;
            state.repmaxerror = 0;
            relcnt = 0;
            i = 0;
        lbl_29:
            if( i>n-1 )
            {
                goto lbl_31;
            }
            for(i_=0; i_<=k-1;i_++)
            {
                state.c[i_] = state.c[i_];
            }
            for(i_=0; i_<=m-1;i_++)
            {
                state.x[i_] = state.taskx[i,i_];
            }
            state.pointindex = i;
            lsfitclearrequestfields(ref state);
            state.needf = true;
            state.rstate.stage = 4;
            goto lbl_rcomm;
        lbl_4:
            v = state.f;
            state.reprmserror = state.reprmserror+AP.Math.Sqr(v-state.tasky[i]);
            state.repavgerror = state.repavgerror+Math.Abs(v-state.tasky[i]);
            if( (double)(state.tasky[i])!=(double)(0) )
            {
                state.repavgrelerror = state.repavgrelerror+Math.Abs(v-state.tasky[i])/Math.Abs(state.tasky[i]);
                relcnt = relcnt+1;
            }
            state.repmaxerror = Math.Max(state.repmaxerror, Math.Abs(v-state.tasky[i]));
            i = i+1;
            goto lbl_29;
        lbl_31:
            state.reprmserror = Math.Sqrt(state.reprmserror/n);
            state.repavgerror = state.repavgerror/n;
            if( (double)(relcnt)!=(double)(0) )
            {
                state.repavgrelerror = state.repavgrelerror/relcnt;
            }
        lbl_27:
            result = false;
            return result;
            
            //
            // Saving state
            //
        lbl_rcomm:
            result = true;
            state.rstate.ia[0] = n;
            state.rstate.ia[1] = m;
            state.rstate.ia[2] = k;
            state.rstate.ia[3] = i;
            state.rstate.ia[4] = j;
            state.rstate.ra[0] = v;
            state.rstate.ra[1] = relcnt;
            return result;
        }
Beispiel #30
0
    /*************************************************************************
    Nonlinear least squares fitting using gradient/Hessian, without individial
    weights.

    Nonlinear task min(F(c)) is solved, where

        F(c) = ((f(c,x[0])-y[0]))^2 + ... + ((f(c,x[n-1])-y[n-1]))^2,

        * N is a number of points,
        * M is a dimension of a space points belong to,
        * K is a dimension of a space of parameters being fitted,
        * x is a set of N points, each of them is an M-dimensional vector,
        * c is a K-dimensional vector of parameters being fitted

    This subroutine uses f(c,x[i]), its gradient and its Hessian.

    INPUT PARAMETERS:
        X       -   array[0..N-1,0..M-1], points (one row = one point)
        Y       -   array[0..N-1], function values.
        C       -   array[0..K-1], initial approximation to the solution,
        N       -   number of points, N>1
        M       -   dimension of space
        K       -   number of parameters being fitted

    OUTPUT PARAMETERS:
        State   -   structure which stores algorithm state


      -- ALGLIB --
         Copyright 17.08.2009 by Bochkanov Sergey
    *************************************************************************/
    public static void lsfitcreatefgh(double[,] x, double[] y, double[] c, int n, int m, int k, out lsfitstate state)
    {
        state = new lsfitstate();
        lsfit.lsfitcreatefgh(x, y, c, n, m, k, state.innerobj);
        return;
    }