Accord.Math.Optimization.BoundedBroydenFletcherGoldfarbShanno.cauchy C# (CSharp) Method

cauchy() private static method

private static cauchy ( int n, double x, int _x_offset, double l, int _l_offset, double u, int _u_offset, int nbd, int _nbd_offset, double g, int _g_offset, int iorder, int _iorder_offset, int iwhere, int _iwhere_offset, double t, int _t_offset, double d, int _d_offset, double xcp, int _xcp_offset, int m, double wy, int _wy_offset, double ws, int _ws_offset, double sy, int _sy_offset, double wt, int _wt_offset, double theta, int col, int head, double p, int _p_offset, double c, int _c_offset, double wbp, int _wbp_offset, double v, int _v_offset, int &nseg, int iprint, double sbgnrm, int &info, double epsmch ) : void
n int
x double
_x_offset int
l double
_l_offset int
u double
_u_offset int
nbd int
_nbd_offset int
g double
_g_offset int
iorder int
_iorder_offset int
iwhere int
_iwhere_offset int
t double
_t_offset int
d double
_d_offset int
xcp double
_xcp_offset int
m int
wy double
_wy_offset int
ws double
_ws_offset int
sy double
_sy_offset int
wt double
_wt_offset int
theta double
col int
head int
p double
_p_offset int
c double
_c_offset int
wbp double
_wbp_offset int
v double
_v_offset int
nseg int
iprint int
sbgnrm double
info int
epsmch double
return void
        private static void cauchy(int n, double[] x, int _x_offset, double[] l, int _l_offset,
            double[] u, int _u_offset, int[] nbd, int _nbd_offset, double[] g, int _g_offset,
            int[] iorder, int _iorder_offset, int[] iwhere, int _iwhere_offset, double[] t, int _t_offset,
            double[] d, int _d_offset, double[] xcp, int _xcp_offset, int m,
            double[] wy, int _wy_offset, double[] ws, int _ws_offset, double[] sy, int _sy_offset,
            double[] wt, int _wt_offset, double theta, int col,
            int head, double[] p, int _p_offset, double[] c, int _c_offset,
            double[] wbp, int _wbp_offset, double[] v, int _v_offset, ref int nseg,
            int iprint, double sbgnrm, ref int info, double epsmch)
        {

            bool xlower = false;
            bool xupper = false;
            bool bnded = false;
            int i = 0;
            int j = 0;
            int col2 = 0;
            int nfree = 0;
            int nbreak = 0;
            int pointr = 0;
            int ibp = 0;
            int nleft = 0;
            int ibkmin = 0;
            int iter = 0;
            double f1 = 0.0d;
            double f2 = 0.0d;
            double dt = 0.0d;
            double dtm = 0.0d;
            double tsum = 0.0d;
            double dibp = 0.0d;
            double zibp = 0.0d;
            double dibp2 = 0.0d;
            double bkmin = 0.0d;
            double tu = 0.0d;
            double tl = 0.0d;
            double wmc = 0.0d;
            double wmp = 0.0d;
            double wmw = 0.0d;
            double tj = 0.0d;
            double tj0 = 0.0d;
            double neggi = 0.0d;
            double f2_org = 0.0d;

            if ((sbgnrm <= 0.0))
            {
                if ((iprint >= 0))
                {
                    // DISPLAY: Subgnorm = 0.  GCP = X.
                }

                dcopy(n, x, _x_offset, 1, xcp, _xcp_offset, 1);
                return;
            }

            bnded = true;
            nfree = (n + 1);
            nbreak = 0;
            ibkmin = 0;
            bkmin = 0.0;
            col2 = (2 * col);
            f1 = 0.0;
            if ((iprint >= 99))
            {
                // DISPLAY: '---------------- CAUCHY entered-------------------'
            }
            // 
            // c     We set p to zero and build it up as we determine d.
            // 
            {
                for (i = 1; i <= col2; i++)
                {
                    p[(i - (1)) + _p_offset] = 0.0;
                }
            }
            // 
            // c     In the following loop we determine for each variable its bound
            // c        status and its breakpoint, and update p accordingly.
            // c        Smallest breakpoint is identified.
            // 
            {
                for (i = 1; i <= n; i++)
                {
                    neggi = (-(g[(i - (1)) + _g_offset]));

                    if (((iwhere[(i - (1)) + _iwhere_offset] != 3)
                        && (iwhere[(i - (1)) + _iwhere_offset] != -1)))
                    {
                        // c             if x(i) is not a constant and has bounds,
                        // c             compute the difference between x(i) and its bounds.
                        if ((nbd[(i - (1)) + _nbd_offset] <= 2))
                        {
                            tl = (x[(i - (1)) + _x_offset] - l[(i - (1)) + _l_offset]);
                        }
                        if ((nbd[(i - (1)) + _nbd_offset] >= 2))
                        {
                            tu = (u[(i - (1)) + _u_offset] - x[(i - (1)) + _x_offset]);
                        }
                        // 
                        // c           If a variable is close enough to a bound
                        // c             we treat it as at bound.
                        xlower = ((nbd[(i - (1)) + _nbd_offset] <= 2) && (tl <= 0.0));
                        xupper = ((nbd[(i - (1)) + _nbd_offset] >= 2) && (tu <= 0.0));
                        // 
                        // c              reset iwhere(i).
                        iwhere[(i - (1)) + _iwhere_offset] = 0;
                        if (xlower)
                        {
                            if ((neggi <= 0.0))
                            {
                                iwhere[(i - (1)) + _iwhere_offset] = 1;
                            }
                        }
                        else if (xupper)
                        {
                            if ((neggi >= 0.0))
                            {
                                iwhere[(i - (1)) + _iwhere_offset] = 2;
                            }
                        }
                        else
                        {
                            if ((System.Math.Abs(neggi) <= 0.0))
                            {
                                iwhere[(i - (1)) + _iwhere_offset] = -3;
                            }
                        }
                    }
                    pointr = head;
                    if (((iwhere[(i - (1)) + _iwhere_offset] != 0) && (iwhere[(i - (1)) + _iwhere_offset] != -1)))
                    {
                        d[(i - (1)) + _d_offset] = 0.0;
                    }
                    else
                    {
                        d[(i - (1)) + _d_offset] = neggi;
                        f1 = (f1 - (neggi * neggi));

                        // calculate p := p - W'e_i* (g_i).
                        {
                            for (j = 1; j <= col; j++)
                            {
                                p[(j - (1)) + _p_offset] = (p[(j - (1))
                                    + _p_offset] + (wy[(i - (1)) + (pointr - (1)) * (n) + _wy_offset] * neggi));
                                p[((col + j) - (1)) + _p_offset] = (p[((col + j) - (1))
                                    + _p_offset] + (ws[(i - (1)) + (pointr - (1)) * (n) + _ws_offset] * neggi));
                                pointr = ((pointr) % (m) + 1);
                            }
                        }
                        if ((((nbd[(i - (1)) + _nbd_offset] <= 2)
                            && (nbd[(i - (1)) + _nbd_offset] != 0)) && (neggi < 0.0)))
                        {
                            // x(i) + d(i) is bounded; compute t(i).

                            nbreak = (nbreak + 1);
                            iorder[(nbreak - (1)) + _iorder_offset] = i;
                            t[(nbreak - (1)) + _t_offset] = (tl / ((-(neggi))));
                            if (((nbreak == 1) || (t[(nbreak - (1)) + _t_offset] < bkmin)))
                            {
                                bkmin = t[(nbreak - (1)) + _t_offset];
                                ibkmin = nbreak;
                            }
                        }
                        else if (((nbd[(i - (1)) + _nbd_offset] >= 2) && (neggi > 0.0)))
                        {
                            // x(i) + d(i) is bounded; compute t(i).

                            nbreak = (nbreak + 1);
                            iorder[(nbreak - (1)) + _iorder_offset] = i;
                            t[(nbreak - (1)) + _t_offset] = (tu / neggi);
                            if (((nbreak == 1) || (t[(nbreak - (1)) + _t_offset] < bkmin)))
                            {
                                bkmin = t[(nbreak - (1)) + _t_offset];
                                ibkmin = nbreak;
                            }
                        }
                        else
                        {
                            // x(i) + d(i) is not bounded.
                            nfree = (nfree - 1);
                            iorder[(nfree - (1)) + _iorder_offset] = i;
                            if ((System.Math.Abs(neggi) > 0.0))
                            {
                                bnded = false;
                            }
                        }
                    }
                }
            }
            // 
            // The indices of the nonzero components of d are now stored
            // in iorder(1),...,iorder(nbreak) and iorder(nfree),...,iorder(n).
            // The smallest of the nbreak breakpoints is in t(ibkmin)=bkmin.
            // 
            if ((theta != 1.0))
            {
                // complete the initialization of p for theta not= one.
                dscal(col, theta, p, ((col + 1) - (1)) + _p_offset, 1);
            }

            // 
            // c     Initialize GCP xcp = x.
            // 
            dcopy(n, x, _x_offset, 1, xcp, _xcp_offset, 1);

            if (((nbreak == 0) && (nfree == (n + 1))))
            {
                // is a zero vector, return with the initial xcp as GCP.
                return;
            }

            // 
            // c     Initialize c = W'(xcp - x) = 0.
            // 
            {
                for (j = 1; j <= col2; j++)
                {
                    c[(j - (1)) + _c_offset] = 0.0;
                }
            }

            // 
            // c     Initialize derivative f2.
            // 
            f2 = (-((theta * f1)));
            f2_org = f2;
            if ((col > 0))
            {
                bmv(m, sy, _sy_offset, wt, _wt_offset,
                    col, p, _p_offset, v, _v_offset, ref info);

                if ((info != 0))
                {
                    return;
                }

                f2 = (f2 - BoundedBroydenFletcherGoldfarbShanno.ddot(col2, v, _v_offset, 1, p, _p_offset, 1));
            }

            dtm = (-((f1 / f2)));
            tsum = 0.0;
            nseg = 1;

            if ((iprint >= 99))
            {
                // DISPLAY: "There are " + nbreak + "  breakpoints "
            }

            // 
            // c     If there are no breakpoints, locate the GCP and return. 
            // 
            if ((nbreak == 0))
                goto L888;

            nleft = nbreak;
            iter = 1;
            tj = 0.0;

        // 
        // c------------------- the beginning of the loop -------------------------
        // 
        L777:
            // 
            //     Find the next smallest breakpoint;
            //      compute dt = t(nleft) - t(nleft + 1).
            // 
            tj0 = tj;

            if ((iter == 1))
            {
                // Since we already have the smallest breakpoint we need not do
                // heapsort yet. Often only one breakpoint is used and the
                // cost of heapsort is avoided.
                tj = bkmin;
                ibp = iorder[(ibkmin - (1)) + _iorder_offset];
            }
            else
            {
                if ((iter == 2))
                {
                    // Replace the already used smallest breakpoint with the
                    // breakpoint numbered nbreak > nlast, before heapsort call.

                    if ((ibkmin != nbreak))
                    {
                        t[(ibkmin - (1)) + _t_offset] = t[(nbreak - (1)) + _t_offset];
                        iorder[(ibkmin - (1)) + _iorder_offset] = iorder[(nbreak - (1)) + _iorder_offset];
                    }
                    // Update heap structure of breakpoints
                    //   (if iter=2, initialize heap).
                }
                hpsolb(nleft, t, _t_offset, iorder, _iorder_offset, (iter - 2));
                tj = t[(nleft - (1)) + _t_offset];
                ibp = iorder[(nleft - (1)) + _iorder_offset];
            }
            // 
            dt = (tj - tj0);
            // 
            if (((dt != 0.0) && (iprint >= 100)))
            {
                // DISPLAY: nseg, f1, f2
                //          "/,'Piece    ',i3,' --f1, f2 at start point ',1p,2(1x,d11.4)"
                // 
                // DISPLAY: dt,
                //          "'Distance to the next break point =  ',1p,d11.4"
                //
                // DISPLAY: dtm,
                //          "'Distance to the stationary point =  ',1p,d11.4"
            }

            // 
            // If a minimizer is within this interval, locate the GCP and return.
            // 
            if ((dtm < dt))
                goto L888;

            // 
            // Otherwise fix one variable and
            //   reset the corresponding component of d to zero.
            // 
            tsum = (tsum + dt);
            nleft = (nleft - 1);
            iter = (iter + 1);
            dibp = d[(ibp - (1)) + _d_offset];
            d[(ibp - (1)) + _d_offset] = 0.0;

            if ((dibp > 0.0))
            {
                zibp = (u[(ibp - (1)) + _u_offset] - x[(ibp - (1)) + _x_offset]);
                xcp[(ibp - (1)) + _xcp_offset] = u[(ibp - (1)) + _u_offset];
                iwhere[(ibp - (1)) + _iwhere_offset] = 2;
            }
            else
            {
                zibp = (l[(ibp - (1)) + _l_offset] - x[(ibp - (1)) + _x_offset]);
                xcp[(ibp - (1)) + _xcp_offset] = l[(ibp - (1)) + _l_offset];
                iwhere[(ibp - (1)) + _iwhere_offset] = 1;
            }

            if ((iprint >= 100))
            {
                // DISPLAY: "Variable  " + ibp + "  is fixed."
            }

            if (((nleft == 0) && (nbreak == n)))
            {
                // all n variables are fixed,
                // return with xcp as GCP.
                dtm = dt;
                goto L999;
            }

            // 
            // Update the derivative information.
            // 
            nseg = (nseg + 1);
            dibp2 = (System.Math.Pow(dibp, 2));

            // 
            // Update f1 and f2.
            // 
            // temporarily set f1 and f2 for col=0.
            //
            f1 = (((f1 + (dt * f2)) + dibp2) - ((theta * dibp) * zibp));
            f2 = (f2 - (theta * dibp2));
            // 
            if ((col > 0))
            {
                // update c = c + dt*p.
                daxpy(col2, dt, p, _p_offset, 1, c, _c_offset, 1);

                // choose wbp,
                // the row of W corresponding to the breakpoint encountered.
                pointr = head;
                {
                    for (j = 1; j <= col; j++)
                    {
                        wbp[(j - (1)) + _wbp_offset] = wy[(ibp - (1))
                            + (pointr - (1)) * (n) + _wy_offset];

                        wbp[((col + j) - (1)) + _wbp_offset] = (theta * ws[(ibp
                            - (1)) + (pointr - (1)) * (n) + _ws_offset]);

                        pointr = ((pointr) % (m) + 1);
                    }
                }

                // compute (wbp)Mc, (wbp)Mp, and (wbp)M(wbp)'.
                bmv(m, sy, _sy_offset, wt, _wt_offset, col, wbp,
                    _wbp_offset, v, _v_offset, ref info);

                if ((info != 0))
                {
                    return;
                }

                wmc = ddot(col2, c, _c_offset, 1, v, _v_offset, 1);
                wmp = ddot(col2, p, _p_offset, 1, v, _v_offset, 1);
                wmw = ddot(col2, wbp, _wbp_offset, 1, v, _v_offset, 1);

                // update p = p - dibp*wbp. 
                daxpy(col2, (-(dibp)), wbp, _wbp_offset, 1, p, _p_offset, 1);

                // complete updating f1 and f2 while col > 0.
                f1 = (f1 + (dibp * wmc));
                f2 = ((f2 + ((2.0e0 * dibp) * wmp)) - (dibp2 * wmw));
            }


            f2 = System.Math.Max((epsmch * f2_org), f2);

            if ((nleft > 0))
            {
                dtm = (-((f1 / f2)));
                goto L777;
                // to repeat the loop for unsearched intervals. 
            }
            else if (bnded)
            {
                f1 = 0.0;
                f2 = 0.0;
                dtm = 0.0;
            }
            else
            {
                dtm = (-((f1 / f2)));
            }

        // 
        // c------------------- the end of the loop -------------------------------
        // 
        L888:

            if ((iprint >= 99))
            {
                // DISPLAY: "GCP found in this segment", 
                //
                // DISPLAY: nseg, f1, f2
                //          'Piece    ',i3,' --f1, f2 at start point ',1p,2(1x,d11.4)"
                //          dtm
                //          "'Distance to the stationary point =  ',1p,d11.4"
            }
            if ((dtm <= 0.0))
            {
                dtm = 0.0;
            }
            tsum = (tsum + dtm);

            // 
            // Move free variables (i.e., the ones w/o breakpoints) and 
            //   the variables whose breakpoints haven't been reached.
            // 
            daxpy(n, tsum, d, _d_offset, 1, xcp, _xcp_offset, 1);
        // 
        L999:
            // 
            // Update c = c + dtm*p = W'(x^c - x) 
            //   which will be used in computing r = Z'(B(x^c - x) + g).
            // 
            if ((col > 0))
            {
                daxpy(col2, dtm, p, _p_offset, 1, c, _c_offset, 1);
            }

            
            if ((iprint > 100))
            {
                for (i = 1; i <= n; i++)
                {
                    // DISPLAY: xcp[(i - (1)) + _xcp_offset];
                }
                // DISPLAY: "'Cauchy X =  ',/,(4x,1p,6(1x,d11.4))"
            }

            if ((iprint >= 99))
            {
                // DISPLAY: '---------------- exit CAUCHY----------------------'
            }

        }