src/glpspx02.c
author Alpar Juttner <alpar@cs.elte.hu>
Mon, 06 Dec 2010 13:09:21 +0100
changeset 1 c445c931472f
permissions -rw-r--r--
Import glpk-4.45

- Generated files and doc/notes are removed
     1 /* glpspx02.c (dual simplex method) */
     2 
     3 /***********************************************************************
     4 *  This code is part of GLPK (GNU Linear Programming Kit).
     5 *
     6 *  Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008,
     7 *  2009, 2010 Andrew Makhorin, Department for Applied Informatics,
     8 *  Moscow Aviation Institute, Moscow, Russia. All rights reserved.
     9 *  E-mail: <mao@gnu.org>.
    10 *
    11 *  GLPK is free software: you can redistribute it and/or modify it
    12 *  under the terms of the GNU General Public License as published by
    13 *  the Free Software Foundation, either version 3 of the License, or
    14 *  (at your option) any later version.
    15 *
    16 *  GLPK is distributed in the hope that it will be useful, but WITHOUT
    17 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
    18 *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
    19 *  License for more details.
    20 *
    21 *  You should have received a copy of the GNU General Public License
    22 *  along with GLPK. If not, see <http://www.gnu.org/licenses/>.
    23 ***********************************************************************/
    24 
    25 #include "glpspx.h"
    26 
    27 #define GLP_DEBUG 1
    28 
    29 #if 0
    30 #define GLP_LONG_STEP 1
    31 #endif
    32 
    33 struct csa
    34 {     /* common storage area */
    35       /*--------------------------------------------------------------*/
    36       /* LP data */
    37       int m;
    38       /* number of rows (auxiliary variables), m > 0 */
    39       int n;
    40       /* number of columns (structural variables), n > 0 */
    41       char *type; /* char type[1+m+n]; */
    42       /* type[0] is not used;
    43          type[k], 1 <= k <= m+n, is the type of variable x[k]:
    44          GLP_FR - free variable
    45          GLP_LO - variable with lower bound
    46          GLP_UP - variable with upper bound
    47          GLP_DB - double-bounded variable
    48          GLP_FX - fixed variable */
    49       double *lb; /* double lb[1+m+n]; */
    50       /* lb[0] is not used;
    51          lb[k], 1 <= k <= m+n, is an lower bound of variable x[k];
    52          if x[k] has no lower bound, lb[k] is zero */
    53       double *ub; /* double ub[1+m+n]; */
    54       /* ub[0] is not used;
    55          ub[k], 1 <= k <= m+n, is an upper bound of variable x[k];
    56          if x[k] has no upper bound, ub[k] is zero;
    57          if x[k] is of fixed type, ub[k] is the same as lb[k] */
    58       double *coef; /* double coef[1+m+n]; */
    59       /* coef[0] is not used;
    60          coef[k], 1 <= k <= m+n, is an objective coefficient at
    61          variable x[k] */
    62       /*--------------------------------------------------------------*/
    63       /* original bounds of variables */
    64       char *orig_type; /* char orig_type[1+m+n]; */
    65       double *orig_lb; /* double orig_lb[1+m+n]; */
    66       double *orig_ub; /* double orig_ub[1+m+n]; */
    67       /*--------------------------------------------------------------*/
    68       /* original objective function */
    69       double *obj; /* double obj[1+n]; */
    70       /* obj[0] is a constant term of the original objective function;
    71          obj[j], 1 <= j <= n, is an original objective coefficient at
    72          structural variable x[m+j] */
    73       double zeta;
    74       /* factor used to scale original objective coefficients; its
    75          sign defines original optimization direction: zeta > 0 means
    76          minimization, zeta < 0 means maximization */
    77       /*--------------------------------------------------------------*/
    78       /* constraint matrix A; it has m rows and n columns and is stored
    79          by columns */
    80       int *A_ptr; /* int A_ptr[1+n+1]; */
    81       /* A_ptr[0] is not used;
    82          A_ptr[j], 1 <= j <= n, is starting position of j-th column in
    83          arrays A_ind and A_val; note that A_ptr[1] is always 1;
    84          A_ptr[n+1] indicates the position after the last element in
    85          arrays A_ind and A_val */
    86       int *A_ind; /* int A_ind[A_ptr[n+1]]; */
    87       /* row indices */
    88       double *A_val; /* double A_val[A_ptr[n+1]]; */
    89       /* non-zero element values */
    90 #if 1 /* 06/IV-2009 */
    91       /* constraint matrix A stored by rows */
    92       int *AT_ptr; /* int AT_ptr[1+m+1];
    93       /* AT_ptr[0] is not used;
    94          AT_ptr[i], 1 <= i <= m, is starting position of i-th row in
    95          arrays AT_ind and AT_val; note that AT_ptr[1] is always 1;
    96          AT_ptr[m+1] indicates the position after the last element in
    97          arrays AT_ind and AT_val */
    98       int *AT_ind; /* int AT_ind[AT_ptr[m+1]]; */
    99       /* column indices */
   100       double *AT_val; /* double AT_val[AT_ptr[m+1]]; */
   101       /* non-zero element values */
   102 #endif
   103       /*--------------------------------------------------------------*/
   104       /* basis header */
   105       int *head; /* int head[1+m+n]; */
   106       /* head[0] is not used;
   107          head[i], 1 <= i <= m, is the ordinal number of basic variable
   108          xB[i]; head[i] = k means that xB[i] = x[k] and i-th column of
   109          matrix B is k-th column of matrix (I|-A);
   110          head[m+j], 1 <= j <= n, is the ordinal number of non-basic
   111          variable xN[j]; head[m+j] = k means that xN[j] = x[k] and j-th
   112          column of matrix N is k-th column of matrix (I|-A) */
   113 #if 1 /* 06/IV-2009 */
   114       int *bind; /* int bind[1+m+n]; */
   115       /* bind[0] is not used;
   116          bind[k], 1 <= k <= m+n, is the position of k-th column of the
   117          matrix (I|-A) in the matrix (B|N); that is, bind[k] = k' means
   118          that head[k'] = k */
   119 #endif
   120       char *stat; /* char stat[1+n]; */
   121       /* stat[0] is not used;
   122          stat[j], 1 <= j <= n, is the status of non-basic variable
   123          xN[j], which defines its active bound:
   124          GLP_NL - lower bound is active
   125          GLP_NU - upper bound is active
   126          GLP_NF - free variable
   127          GLP_NS - fixed variable */
   128       /*--------------------------------------------------------------*/
   129       /* matrix B is the basis matrix; it is composed from columns of
   130          the augmented constraint matrix (I|-A) corresponding to basic
   131          variables and stored in a factorized (invertable) form */
   132       int valid;
   133       /* factorization is valid only if this flag is set */
   134       BFD *bfd; /* BFD bfd[1:m,1:m]; */
   135       /* factorized (invertable) form of the basis matrix */
   136 #if 0 /* 06/IV-2009 */
   137       /*--------------------------------------------------------------*/
   138       /* matrix N is a matrix composed from columns of the augmented
   139          constraint matrix (I|-A) corresponding to non-basic variables
   140          except fixed ones; it is stored by rows and changes every time
   141          the basis changes */
   142       int *N_ptr; /* int N_ptr[1+m+1]; */
   143       /* N_ptr[0] is not used;
   144          N_ptr[i], 1 <= i <= m, is starting position of i-th row in
   145          arrays N_ind and N_val; note that N_ptr[1] is always 1;
   146          N_ptr[m+1] indicates the position after the last element in
   147          arrays N_ind and N_val */
   148       int *N_len; /* int N_len[1+m]; */
   149       /* N_len[0] is not used;
   150          N_len[i], 1 <= i <= m, is length of i-th row (0 to n) */
   151       int *N_ind; /* int N_ind[N_ptr[m+1]]; */
   152       /* column indices */
   153       double *N_val; /* double N_val[N_ptr[m+1]]; */
   154       /* non-zero element values */
   155 #endif
   156       /*--------------------------------------------------------------*/
   157       /* working parameters */
   158       int phase;
   159       /* search phase:
   160          0 - not determined yet
   161          1 - search for dual feasible solution
   162          2 - search for optimal solution */
   163       glp_long tm_beg;
   164       /* time value at the beginning of the search */
   165       int it_beg;
   166       /* simplex iteration count at the beginning of the search */
   167       int it_cnt;
   168       /* simplex iteration count; it increases by one every time the
   169          basis changes */
   170       int it_dpy;
   171       /* simplex iteration count at the most recent display output */
   172       /*--------------------------------------------------------------*/
   173       /* basic solution components */
   174       double *bbar; /* double bbar[1+m]; */
   175       /* bbar[0] is not used on phase I; on phase II it is the current
   176          value of the original objective function;
   177          bbar[i], 1 <= i <= m, is primal value of basic variable xB[i]
   178          (if xB[i] is free, its primal value is not updated) */
   179       double *cbar; /* double cbar[1+n]; */
   180       /* cbar[0] is not used;
   181          cbar[j], 1 <= j <= n, is reduced cost of non-basic variable
   182          xN[j] (if xN[j] is fixed, its reduced cost is not updated) */
   183       /*--------------------------------------------------------------*/
   184       /* the following pricing technique options may be used:
   185          GLP_PT_STD - standard ("textbook") pricing;
   186          GLP_PT_PSE - projected steepest edge;
   187          GLP_PT_DVX - Devex pricing (not implemented yet);
   188          in case of GLP_PT_STD the reference space is not used, and all
   189          steepest edge coefficients are set to 1 */
   190       int refct;
   191       /* this count is set to an initial value when the reference space
   192          is defined and decreases by one every time the basis changes;
   193          once this count reaches zero, the reference space is redefined
   194          again */
   195       char *refsp; /* char refsp[1+m+n]; */
   196       /* refsp[0] is not used;
   197          refsp[k], 1 <= k <= m+n, is the flag which means that variable
   198          x[k] belongs to the current reference space */
   199       double *gamma; /* double gamma[1+m]; */
   200       /* gamma[0] is not used;
   201          gamma[i], 1 <= i <= n, is the steepest edge coefficient for
   202          basic variable xB[i]; if xB[i] is free, gamma[i] is not used
   203          and just set to 1 */
   204       /*--------------------------------------------------------------*/
   205       /* basic variable xB[p] chosen to leave the basis */
   206       int p;
   207       /* index of the basic variable xB[p] chosen, 1 <= p <= m;
   208          if the set of eligible basic variables is empty (i.e. if the
   209          current basic solution is primal feasible within a tolerance)
   210          and thus no variable has been chosen, p is set to 0 */
   211       double delta;
   212       /* change of xB[p] in the adjacent basis;
   213          delta > 0 means that xB[p] violates its lower bound and will
   214          increase to achieve it in the adjacent basis;
   215          delta < 0 means that xB[p] violates its upper bound and will
   216          decrease to achieve it in the adjacent basis */
   217       /*--------------------------------------------------------------*/
   218       /* pivot row of the simplex table corresponding to basic variable
   219          xB[p] chosen is the following vector:
   220             T' * e[p] = - N' * inv(B') * e[p] = - N' * rho,
   221          where B' is a matrix transposed to the current basis matrix,
   222          N' is a matrix, whose rows are columns of the matrix (I|-A)
   223          corresponding to non-basic non-fixed variables */
   224       int trow_nnz;
   225       /* number of non-zero components, 0 <= nnz <= n */
   226       int *trow_ind; /* int trow_ind[1+n]; */
   227       /* trow_ind[0] is not used;
   228          trow_ind[t], 1 <= t <= nnz, is an index of non-zero component,
   229          i.e. trow_ind[t] = j means that trow_vec[j] != 0 */
   230       double *trow_vec; /* int trow_vec[1+n]; */
   231       /* trow_vec[0] is not used;
   232          trow_vec[j], 1 <= j <= n, is a numeric value of j-th component
   233          of the row */
   234       double trow_max;
   235       /* infinity (maximum) norm of the row (max |trow_vec[j]|) */
   236       int trow_num;
   237       /* number of significant non-zero components, which means that:
   238          |trow_vec[j]| >= eps for j in trow_ind[1,...,num],
   239          |tcol_vec[j]| <  eps for j in trow_ind[num+1,...,nnz],
   240          where eps is a pivot tolerance */
   241       /*--------------------------------------------------------------*/
   242 #ifdef GLP_LONG_STEP /* 07/IV-2009 */
   243       int nbps;
   244       /* number of breakpoints, 0 <= nbps <= n */
   245       struct bkpt
   246       {     int j;
   247             /* index of non-basic variable xN[j], 1 <= j <= n */
   248             double t;
   249             /* value of dual ray parameter at breakpoint, t >= 0 */
   250             double dz;
   251             /* dz = zeta(t = t[k]) - zeta(t = 0) */
   252       } *bkpt; /* struct bkpt bkpt[1+n]; */
   253       /* bkpt[0] is not used;
   254          bkpt[k], 1 <= k <= nbps, is k-th breakpoint of the dual
   255          objective */
   256 #endif
   257       /*--------------------------------------------------------------*/
   258       /* non-basic variable xN[q] chosen to enter the basis */
   259       int q;
   260       /* index of the non-basic variable xN[q] chosen, 1 <= q <= n;
   261          if no variable has been chosen, q is set to 0 */
   262       double new_dq;
   263       /* reduced cost of xN[q] in the adjacent basis (it is the change
   264          of lambdaB[p]) */
   265       /*--------------------------------------------------------------*/
   266       /* pivot column of the simplex table corresponding to non-basic
   267          variable xN[q] chosen is the following vector:
   268             T * e[q] = - inv(B) * N * e[q] = - inv(B) * N[q],
   269          where B is the current basis matrix, N[q] is a column of the
   270          matrix (I|-A) corresponding to xN[q] */
   271       int tcol_nnz;
   272       /* number of non-zero components, 0 <= nnz <= m */
   273       int *tcol_ind; /* int tcol_ind[1+m]; */
   274       /* tcol_ind[0] is not used;
   275          tcol_ind[t], 1 <= t <= nnz, is an index of non-zero component,
   276          i.e. tcol_ind[t] = i means that tcol_vec[i] != 0 */
   277       double *tcol_vec; /* double tcol_vec[1+m]; */
   278       /* tcol_vec[0] is not used;
   279          tcol_vec[i], 1 <= i <= m, is a numeric value of i-th component
   280          of the column */
   281       /*--------------------------------------------------------------*/
   282       /* working arrays */
   283       double *work1; /* double work1[1+m]; */
   284       double *work2; /* double work2[1+m]; */
   285       double *work3; /* double work3[1+m]; */
   286       double *work4; /* double work4[1+m]; */
   287 };
   288 
   289 static const double kappa = 0.10;
   290 
   291 /***********************************************************************
   292 *  alloc_csa - allocate common storage area
   293 *
   294 *  This routine allocates all arrays in the common storage area (CSA)
   295 *  and returns a pointer to the CSA. */
   296 
   297 static struct csa *alloc_csa(glp_prob *lp)
   298 {     struct csa *csa;
   299       int m = lp->m;
   300       int n = lp->n;
   301       int nnz = lp->nnz;
   302       csa = xmalloc(sizeof(struct csa));
   303       xassert(m > 0 && n > 0);
   304       csa->m = m;
   305       csa->n = n;
   306       csa->type = xcalloc(1+m+n, sizeof(char));
   307       csa->lb = xcalloc(1+m+n, sizeof(double));
   308       csa->ub = xcalloc(1+m+n, sizeof(double));
   309       csa->coef = xcalloc(1+m+n, sizeof(double));
   310       csa->orig_type = xcalloc(1+m+n, sizeof(char));
   311       csa->orig_lb = xcalloc(1+m+n, sizeof(double));
   312       csa->orig_ub = xcalloc(1+m+n, sizeof(double));
   313       csa->obj = xcalloc(1+n, sizeof(double));
   314       csa->A_ptr = xcalloc(1+n+1, sizeof(int));
   315       csa->A_ind = xcalloc(1+nnz, sizeof(int));
   316       csa->A_val = xcalloc(1+nnz, sizeof(double));
   317 #if 1 /* 06/IV-2009 */
   318       csa->AT_ptr = xcalloc(1+m+1, sizeof(int));
   319       csa->AT_ind = xcalloc(1+nnz, sizeof(int));
   320       csa->AT_val = xcalloc(1+nnz, sizeof(double));
   321 #endif
   322       csa->head = xcalloc(1+m+n, sizeof(int));
   323 #if 1 /* 06/IV-2009 */
   324       csa->bind = xcalloc(1+m+n, sizeof(int));
   325 #endif
   326       csa->stat = xcalloc(1+n, sizeof(char));
   327 #if 0 /* 06/IV-2009 */
   328       csa->N_ptr = xcalloc(1+m+1, sizeof(int));
   329       csa->N_len = xcalloc(1+m, sizeof(int));
   330       csa->N_ind = NULL; /* will be allocated later */
   331       csa->N_val = NULL; /* will be allocated later */
   332 #endif
   333       csa->bbar = xcalloc(1+m, sizeof(double));
   334       csa->cbar = xcalloc(1+n, sizeof(double));
   335       csa->refsp = xcalloc(1+m+n, sizeof(char));
   336       csa->gamma = xcalloc(1+m, sizeof(double));
   337       csa->trow_ind = xcalloc(1+n, sizeof(int));
   338       csa->trow_vec = xcalloc(1+n, sizeof(double));
   339 #ifdef GLP_LONG_STEP /* 07/IV-2009 */
   340       csa->bkpt = xcalloc(1+n, sizeof(struct bkpt));
   341 #endif
   342       csa->tcol_ind = xcalloc(1+m, sizeof(int));
   343       csa->tcol_vec = xcalloc(1+m, sizeof(double));
   344       csa->work1 = xcalloc(1+m, sizeof(double));
   345       csa->work2 = xcalloc(1+m, sizeof(double));
   346       csa->work3 = xcalloc(1+m, sizeof(double));
   347       csa->work4 = xcalloc(1+m, sizeof(double));
   348       return csa;
   349 }
   350 
   351 /***********************************************************************
   352 *  init_csa - initialize common storage area
   353 *
   354 *  This routine initializes all data structures in the common storage
   355 *  area (CSA). */
   356 
   357 static void init_csa(struct csa *csa, glp_prob *lp)
   358 {     int m = csa->m;
   359       int n = csa->n;
   360       char *type = csa->type;
   361       double *lb = csa->lb;
   362       double *ub = csa->ub;
   363       double *coef = csa->coef;
   364       char *orig_type = csa->orig_type;
   365       double *orig_lb = csa->orig_lb;
   366       double *orig_ub = csa->orig_ub;
   367       double *obj = csa->obj;
   368       int *A_ptr = csa->A_ptr;
   369       int *A_ind = csa->A_ind;
   370       double *A_val = csa->A_val;
   371 #if 1 /* 06/IV-2009 */
   372       int *AT_ptr = csa->AT_ptr;
   373       int *AT_ind = csa->AT_ind;
   374       double *AT_val = csa->AT_val;
   375 #endif
   376       int *head = csa->head;
   377 #if 1 /* 06/IV-2009 */
   378       int *bind = csa->bind;
   379 #endif
   380       char *stat = csa->stat;
   381       char *refsp = csa->refsp;
   382       double *gamma = csa->gamma;
   383       int i, j, k, loc;
   384       double cmax;
   385       /* auxiliary variables */
   386       for (i = 1; i <= m; i++)
   387       {  GLPROW *row = lp->row[i];
   388          type[i] = (char)row->type;
   389          lb[i] = row->lb * row->rii;
   390          ub[i] = row->ub * row->rii;
   391          coef[i] = 0.0;
   392       }
   393       /* structural variables */
   394       for (j = 1; j <= n; j++)
   395       {  GLPCOL *col = lp->col[j];
   396          type[m+j] = (char)col->type;
   397          lb[m+j] = col->lb / col->sjj;
   398          ub[m+j] = col->ub / col->sjj;
   399          coef[m+j] = col->coef * col->sjj;
   400       }
   401       /* original bounds of variables */
   402       memcpy(&orig_type[1], &type[1], (m+n) * sizeof(char));
   403       memcpy(&orig_lb[1], &lb[1], (m+n) * sizeof(double));
   404       memcpy(&orig_ub[1], &ub[1], (m+n) * sizeof(double));
   405       /* original objective function */
   406       obj[0] = lp->c0;
   407       memcpy(&obj[1], &coef[m+1], n * sizeof(double));
   408       /* factor used to scale original objective coefficients */
   409       cmax = 0.0;
   410       for (j = 1; j <= n; j++)
   411          if (cmax < fabs(obj[j])) cmax = fabs(obj[j]);
   412       if (cmax == 0.0) cmax = 1.0;
   413       switch (lp->dir)
   414       {  case GLP_MIN:
   415             csa->zeta = + 1.0 / cmax;
   416             break;
   417          case GLP_MAX:
   418             csa->zeta = - 1.0 / cmax;
   419             break;
   420          default:
   421             xassert(lp != lp);
   422       }
   423 #if 1
   424       if (fabs(csa->zeta) < 1.0) csa->zeta *= 1000.0;
   425 #endif
   426       /* scale working objective coefficients */
   427       for (j = 1; j <= n; j++) coef[m+j] *= csa->zeta;
   428       /* matrix A (by columns) */
   429       loc = 1;
   430       for (j = 1; j <= n; j++)
   431       {  GLPAIJ *aij;
   432          A_ptr[j] = loc;
   433          for (aij = lp->col[j]->ptr; aij != NULL; aij = aij->c_next)
   434          {  A_ind[loc] = aij->row->i;
   435             A_val[loc] = aij->row->rii * aij->val * aij->col->sjj;
   436             loc++;
   437          }
   438       }
   439       A_ptr[n+1] = loc;
   440       xassert(loc-1 == lp->nnz);
   441 #if 1 /* 06/IV-2009 */
   442       /* matrix A (by rows) */
   443       loc = 1;
   444       for (i = 1; i <= m; i++)
   445       {  GLPAIJ *aij;
   446          AT_ptr[i] = loc;
   447          for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next)
   448          {  AT_ind[loc] = aij->col->j;
   449             AT_val[loc] = aij->row->rii * aij->val * aij->col->sjj;
   450             loc++;
   451          }
   452       }
   453       AT_ptr[m+1] = loc;
   454       xassert(loc-1 == lp->nnz);
   455 #endif
   456       /* basis header */
   457       xassert(lp->valid);
   458       memcpy(&head[1], &lp->head[1], m * sizeof(int));
   459       k = 0;
   460       for (i = 1; i <= m; i++)
   461       {  GLPROW *row = lp->row[i];
   462          if (row->stat != GLP_BS)
   463          {  k++;
   464             xassert(k <= n);
   465             head[m+k] = i;
   466             stat[k] = (char)row->stat;
   467          }
   468       }
   469       for (j = 1; j <= n; j++)
   470       {  GLPCOL *col = lp->col[j];
   471          if (col->stat != GLP_BS)
   472          {  k++;
   473             xassert(k <= n);
   474             head[m+k] = m + j;
   475             stat[k] = (char)col->stat;
   476          }
   477       }
   478       xassert(k == n);
   479 #if 1 /* 06/IV-2009 */
   480       for (k = 1; k <= m+n; k++)
   481          bind[head[k]] = k;
   482 #endif
   483       /* factorization of matrix B */
   484       csa->valid = 1, lp->valid = 0;
   485       csa->bfd = lp->bfd, lp->bfd = NULL;
   486 #if 0 /* 06/IV-2009 */
   487       /* matrix N (by rows) */
   488       alloc_N(csa);
   489       build_N(csa);
   490 #endif
   491       /* working parameters */
   492       csa->phase = 0;
   493       csa->tm_beg = xtime();
   494       csa->it_beg = csa->it_cnt = lp->it_cnt;
   495       csa->it_dpy = -1;
   496       /* reference space and steepest edge coefficients */
   497       csa->refct = 0;
   498       memset(&refsp[1], 0, (m+n) * sizeof(char));
   499       for (i = 1; i <= m; i++) gamma[i] = 1.0;
   500       return;
   501 }
   502 
   503 #if 1 /* copied from primal */
   504 /***********************************************************************
   505 *  invert_B - compute factorization of the basis matrix
   506 *
   507 *  This routine computes factorization of the current basis matrix B.
   508 *
   509 *  If the operation is successful, the routine returns zero, otherwise
   510 *  non-zero. */
   511 
   512 static int inv_col(void *info, int i, int ind[], double val[])
   513 {     /* this auxiliary routine returns row indices and numeric values
   514          of non-zero elements of i-th column of the basis matrix */
   515       struct csa *csa = info;
   516       int m = csa->m;
   517 #ifdef GLP_DEBUG
   518       int n = csa->n;
   519 #endif
   520       int *A_ptr = csa->A_ptr;
   521       int *A_ind = csa->A_ind;
   522       double *A_val = csa->A_val;
   523       int *head = csa->head;
   524       int k, len, ptr, t;
   525 #ifdef GLP_DEBUG
   526       xassert(1 <= i && i <= m);
   527 #endif
   528       k = head[i]; /* B[i] is k-th column of (I|-A) */
   529 #ifdef GLP_DEBUG
   530       xassert(1 <= k && k <= m+n);
   531 #endif
   532       if (k <= m)
   533       {  /* B[i] is k-th column of submatrix I */
   534          len = 1;
   535          ind[1] = k;
   536          val[1] = 1.0;
   537       }
   538       else
   539       {  /* B[i] is (k-m)-th column of submatrix (-A) */
   540          ptr = A_ptr[k-m];
   541          len = A_ptr[k-m+1] - ptr;
   542          memcpy(&ind[1], &A_ind[ptr], len * sizeof(int));
   543          memcpy(&val[1], &A_val[ptr], len * sizeof(double));
   544          for (t = 1; t <= len; t++) val[t] = - val[t];
   545       }
   546       return len;
   547 }
   548 
   549 static int invert_B(struct csa *csa)
   550 {     int ret;
   551       ret = bfd_factorize(csa->bfd, csa->m, NULL, inv_col, csa);
   552       csa->valid = (ret == 0);
   553       return ret;
   554 }
   555 #endif
   556 
   557 #if 1 /* copied from primal */
   558 /***********************************************************************
   559 *  update_B - update factorization of the basis matrix
   560 *
   561 *  This routine replaces i-th column of the basis matrix B by k-th
   562 *  column of the augmented constraint matrix (I|-A) and then updates
   563 *  the factorization of B.
   564 *
   565 *  If the factorization has been successfully updated, the routine
   566 *  returns zero, otherwise non-zero. */
   567 
   568 static int update_B(struct csa *csa, int i, int k)
   569 {     int m = csa->m;
   570 #ifdef GLP_DEBUG
   571       int n = csa->n;
   572 #endif
   573       int ret;
   574 #ifdef GLP_DEBUG
   575       xassert(1 <= i && i <= m);
   576       xassert(1 <= k && k <= m+n);
   577 #endif
   578       if (k <= m)
   579       {  /* new i-th column of B is k-th column of I */
   580          int ind[1+1];
   581          double val[1+1];
   582          ind[1] = k;
   583          val[1] = 1.0;
   584          xassert(csa->valid);
   585          ret = bfd_update_it(csa->bfd, i, 0, 1, ind, val);
   586       }
   587       else
   588       {  /* new i-th column of B is (k-m)-th column of (-A) */
   589          int *A_ptr = csa->A_ptr;
   590          int *A_ind = csa->A_ind;
   591          double *A_val = csa->A_val;
   592          double *val = csa->work1;
   593          int beg, end, ptr, len;
   594          beg = A_ptr[k-m];
   595          end = A_ptr[k-m+1];
   596          len = 0;
   597          for (ptr = beg; ptr < end; ptr++)
   598             val[++len] = - A_val[ptr];
   599          xassert(csa->valid);
   600          ret = bfd_update_it(csa->bfd, i, 0, len, &A_ind[beg-1], val);
   601       }
   602       csa->valid = (ret == 0);
   603       return ret;
   604 }
   605 #endif
   606 
   607 #if 1 /* copied from primal */
   608 /***********************************************************************
   609 *  error_ftran - compute residual vector r = h - B * x
   610 *
   611 *  This routine computes the residual vector r = h - B * x, where B is
   612 *  the current basis matrix, h is the vector of right-hand sides, x is
   613 *  the solution vector. */
   614 
   615 static void error_ftran(struct csa *csa, double h[], double x[],
   616       double r[])
   617 {     int m = csa->m;
   618 #ifdef GLP_DEBUG
   619       int n = csa->n;
   620 #endif
   621       int *A_ptr = csa->A_ptr;
   622       int *A_ind = csa->A_ind;
   623       double *A_val = csa->A_val;
   624       int *head = csa->head;
   625       int i, k, beg, end, ptr;
   626       double temp;
   627       /* compute the residual vector:
   628          r = h - B * x = h - B[1] * x[1] - ... - B[m] * x[m],
   629          where B[1], ..., B[m] are columns of matrix B */
   630       memcpy(&r[1], &h[1], m * sizeof(double));
   631       for (i = 1; i <= m; i++)
   632       {  temp = x[i];
   633          if (temp == 0.0) continue;
   634          k = head[i]; /* B[i] is k-th column of (I|-A) */
   635 #ifdef GLP_DEBUG
   636          xassert(1 <= k && k <= m+n);
   637 #endif
   638          if (k <= m)
   639          {  /* B[i] is k-th column of submatrix I */
   640             r[k] -= temp;
   641          }
   642          else
   643          {  /* B[i] is (k-m)-th column of submatrix (-A) */
   644             beg = A_ptr[k-m];
   645             end = A_ptr[k-m+1];
   646             for (ptr = beg; ptr < end; ptr++)
   647                r[A_ind[ptr]] += A_val[ptr] * temp;
   648          }
   649       }
   650       return;
   651 }
   652 #endif
   653 
   654 #if 1 /* copied from primal */
   655 /***********************************************************************
   656 *  refine_ftran - refine solution of B * x = h
   657 *
   658 *  This routine performs one iteration to refine the solution of
   659 *  the system B * x = h, where B is the current basis matrix, h is the
   660 *  vector of right-hand sides, x is the solution vector. */
   661 
   662 static void refine_ftran(struct csa *csa, double h[], double x[])
   663 {     int m = csa->m;
   664       double *r = csa->work1;
   665       double *d = csa->work1;
   666       int i;
   667       /* compute the residual vector r = h - B * x */
   668       error_ftran(csa, h, x, r);
   669       /* compute the correction vector d = inv(B) * r */
   670       xassert(csa->valid);
   671       bfd_ftran(csa->bfd, d);
   672       /* refine the solution vector (new x) = (old x) + d */
   673       for (i = 1; i <= m; i++) x[i] += d[i];
   674       return;
   675 }
   676 #endif
   677 
   678 #if 1 /* copied from primal */
   679 /***********************************************************************
   680 *  error_btran - compute residual vector r = h - B'* x
   681 *
   682 *  This routine computes the residual vector r = h - B'* x, where B'
   683 *  is a matrix transposed to the current basis matrix, h is the vector
   684 *  of right-hand sides, x is the solution vector. */
   685 
   686 static void error_btran(struct csa *csa, double h[], double x[],
   687       double r[])
   688 {     int m = csa->m;
   689 #ifdef GLP_DEBUG
   690       int n = csa->n;
   691 #endif
   692       int *A_ptr = csa->A_ptr;
   693       int *A_ind = csa->A_ind;
   694       double *A_val = csa->A_val;
   695       int *head = csa->head;
   696       int i, k, beg, end, ptr;
   697       double temp;
   698       /* compute the residual vector r = b - B'* x */
   699       for (i = 1; i <= m; i++)
   700       {  /* r[i] := b[i] - (i-th column of B)'* x */
   701          k = head[i]; /* B[i] is k-th column of (I|-A) */
   702 #ifdef GLP_DEBUG
   703          xassert(1 <= k && k <= m+n);
   704 #endif
   705          temp = h[i];
   706          if (k <= m)
   707          {  /* B[i] is k-th column of submatrix I */
   708             temp -= x[k];
   709          }
   710          else
   711          {  /* B[i] is (k-m)-th column of submatrix (-A) */
   712             beg = A_ptr[k-m];
   713             end = A_ptr[k-m+1];
   714             for (ptr = beg; ptr < end; ptr++)
   715                temp += A_val[ptr] * x[A_ind[ptr]];
   716          }
   717          r[i] = temp;
   718       }
   719       return;
   720 }
   721 #endif
   722 
   723 #if 1 /* copied from primal */
   724 /***********************************************************************
   725 *  refine_btran - refine solution of B'* x = h
   726 *
   727 *  This routine performs one iteration to refine the solution of the
   728 *  system B'* x = h, where B' is a matrix transposed to the current
   729 *  basis matrix, h is the vector of right-hand sides, x is the solution
   730 *  vector. */
   731 
   732 static void refine_btran(struct csa *csa, double h[], double x[])
   733 {     int m = csa->m;
   734       double *r = csa->work1;
   735       double *d = csa->work1;
   736       int i;
   737       /* compute the residual vector r = h - B'* x */
   738       error_btran(csa, h, x, r);
   739       /* compute the correction vector d = inv(B') * r */
   740       xassert(csa->valid);
   741       bfd_btran(csa->bfd, d);
   742       /* refine the solution vector (new x) = (old x) + d */
   743       for (i = 1; i <= m; i++) x[i] += d[i];
   744       return;
   745 }
   746 #endif
   747 
   748 #if 1 /* copied from primal */
   749 /***********************************************************************
   750 *  get_xN - determine current value of non-basic variable xN[j]
   751 *
   752 *  This routine returns the current value of non-basic variable xN[j],
   753 *  which is a value of its active bound. */
   754 
   755 static double get_xN(struct csa *csa, int j)
   756 {     int m = csa->m;
   757 #ifdef GLP_DEBUG
   758       int n = csa->n;
   759 #endif
   760       double *lb = csa->lb;
   761       double *ub = csa->ub;
   762       int *head = csa->head;
   763       char *stat = csa->stat;
   764       int k;
   765       double xN;
   766 #ifdef GLP_DEBUG
   767       xassert(1 <= j && j <= n);
   768 #endif
   769       k = head[m+j]; /* x[k] = xN[j] */
   770 #ifdef GLP_DEBUG
   771       xassert(1 <= k && k <= m+n);
   772 #endif
   773       switch (stat[j])
   774       {  case GLP_NL:
   775             /* x[k] is on its lower bound */
   776             xN = lb[k]; break;
   777          case GLP_NU:
   778             /* x[k] is on its upper bound */
   779             xN = ub[k]; break;
   780          case GLP_NF:
   781             /* x[k] is free non-basic variable */
   782             xN = 0.0; break;
   783          case GLP_NS:
   784             /* x[k] is fixed non-basic variable */
   785             xN = lb[k]; break;
   786          default:
   787             xassert(stat != stat);
   788       }
   789       return xN;
   790 }
   791 #endif
   792 
   793 #if 1 /* copied from primal */
   794 /***********************************************************************
   795 *  eval_beta - compute primal values of basic variables
   796 *
   797 *  This routine computes current primal values of all basic variables:
   798 *
   799 *     beta = - inv(B) * N * xN,
   800 *
   801 *  where B is the current basis matrix, N is a matrix built of columns
   802 *  of matrix (I|-A) corresponding to non-basic variables, and xN is the
   803 *  vector of current values of non-basic variables. */
   804 
   805 static void eval_beta(struct csa *csa, double beta[])
   806 {     int m = csa->m;
   807       int n = csa->n;
   808       int *A_ptr = csa->A_ptr;
   809       int *A_ind = csa->A_ind;
   810       double *A_val = csa->A_val;
   811       int *head = csa->head;
   812       double *h = csa->work2;
   813       int i, j, k, beg, end, ptr;
   814       double xN;
   815       /* compute the right-hand side vector:
   816          h := - N * xN = - N[1] * xN[1] - ... - N[n] * xN[n],
   817          where N[1], ..., N[n] are columns of matrix N */
   818       for (i = 1; i <= m; i++)
   819          h[i] = 0.0;
   820       for (j = 1; j <= n; j++)
   821       {  k = head[m+j]; /* x[k] = xN[j] */
   822 #ifdef GLP_DEBUG
   823          xassert(1 <= k && k <= m+n);
   824 #endif
   825          /* determine current value of xN[j] */
   826          xN = get_xN(csa, j);
   827          if (xN == 0.0) continue;
   828          if (k <= m)
   829          {  /* N[j] is k-th column of submatrix I */
   830             h[k] -= xN;
   831          }
   832          else
   833          {  /* N[j] is (k-m)-th column of submatrix (-A) */
   834             beg = A_ptr[k-m];
   835             end = A_ptr[k-m+1];
   836             for (ptr = beg; ptr < end; ptr++)
   837                h[A_ind[ptr]] += xN * A_val[ptr];
   838          }
   839       }
   840       /* solve system B * beta = h */
   841       memcpy(&beta[1], &h[1], m * sizeof(double));
   842       xassert(csa->valid);
   843       bfd_ftran(csa->bfd, beta);
   844       /* and refine the solution */
   845       refine_ftran(csa, h, beta);
   846       return;
   847 }
   848 #endif
   849 
   850 #if 1 /* copied from primal */
   851 /***********************************************************************
   852 *  eval_pi - compute vector of simplex multipliers
   853 *
   854 *  This routine computes the vector of current simplex multipliers:
   855 *
   856 *     pi = inv(B') * cB,
   857 *
   858 *  where B' is a matrix transposed to the current basis matrix, cB is
   859 *  a subvector of objective coefficients at basic variables. */
   860 
   861 static void eval_pi(struct csa *csa, double pi[])
   862 {     int m = csa->m;
   863       double *c = csa->coef;
   864       int *head = csa->head;
   865       double *cB = csa->work2;
   866       int i;
   867       /* construct the right-hand side vector cB */
   868       for (i = 1; i <= m; i++)
   869          cB[i] = c[head[i]];
   870       /* solve system B'* pi = cB */
   871       memcpy(&pi[1], &cB[1], m * sizeof(double));
   872       xassert(csa->valid);
   873       bfd_btran(csa->bfd, pi);
   874       /* and refine the solution */
   875       refine_btran(csa, cB, pi);
   876       return;
   877 }
   878 #endif
   879 
   880 #if 1 /* copied from primal */
   881 /***********************************************************************
   882 *  eval_cost - compute reduced cost of non-basic variable xN[j]
   883 *
   884 *  This routine computes the current reduced cost of non-basic variable
   885 *  xN[j]:
   886 *
   887 *     d[j] = cN[j] - N'[j] * pi,
   888 *
   889 *  where cN[j] is the objective coefficient at variable xN[j], N[j] is
   890 *  a column of the augmented constraint matrix (I|-A) corresponding to
   891 *  xN[j], pi is the vector of simplex multipliers. */
   892 
   893 static double eval_cost(struct csa *csa, double pi[], int j)
   894 {     int m = csa->m;
   895 #ifdef GLP_DEBUG
   896       int n = csa->n;
   897 #endif
   898       double *coef = csa->coef;
   899       int *head = csa->head;
   900       int k;
   901       double dj;
   902 #ifdef GLP_DEBUG
   903       xassert(1 <= j && j <= n);
   904 #endif
   905       k = head[m+j]; /* x[k] = xN[j] */
   906 #ifdef GLP_DEBUG
   907       xassert(1 <= k && k <= m+n);
   908 #endif
   909       dj = coef[k];
   910       if (k <= m)
   911       {  /* N[j] is k-th column of submatrix I */
   912          dj -= pi[k];
   913       }
   914       else
   915       {  /* N[j] is (k-m)-th column of submatrix (-A) */
   916          int *A_ptr = csa->A_ptr;
   917          int *A_ind = csa->A_ind;
   918          double *A_val = csa->A_val;
   919          int beg, end, ptr;
   920          beg = A_ptr[k-m];
   921          end = A_ptr[k-m+1];
   922          for (ptr = beg; ptr < end; ptr++)
   923             dj += A_val[ptr] * pi[A_ind[ptr]];
   924       }
   925       return dj;
   926 }
   927 #endif
   928 
   929 #if 1 /* copied from primal */
   930 /***********************************************************************
   931 *  eval_bbar - compute and store primal values of basic variables
   932 *
   933 *  This routine computes primal values of all basic variables and then
   934 *  stores them in the solution array. */
   935 
   936 static void eval_bbar(struct csa *csa)
   937 {     eval_beta(csa, csa->bbar);
   938       return;
   939 }
   940 #endif
   941 
   942 #if 1 /* copied from primal */
   943 /***********************************************************************
   944 *  eval_cbar - compute and store reduced costs of non-basic variables
   945 *
   946 *  This routine computes reduced costs of all non-basic variables and
   947 *  then stores them in the solution array. */
   948 
   949 static void eval_cbar(struct csa *csa)
   950 {
   951 #ifdef GLP_DEBUG
   952       int m = csa->m;
   953 #endif
   954       int n = csa->n;
   955 #ifdef GLP_DEBUG
   956       int *head = csa->head;
   957 #endif
   958       double *cbar = csa->cbar;
   959       double *pi = csa->work3;
   960       int j;
   961 #ifdef GLP_DEBUG
   962       int k;
   963 #endif
   964       /* compute simplex multipliers */
   965       eval_pi(csa, pi);
   966       /* compute and store reduced costs */
   967       for (j = 1; j <= n; j++)
   968       {
   969 #ifdef GLP_DEBUG
   970          k = head[m+j]; /* x[k] = xN[j] */
   971          xassert(1 <= k && k <= m+n);
   972 #endif
   973          cbar[j] = eval_cost(csa, pi, j);
   974       }
   975       return;
   976 }
   977 #endif
   978 
   979 /***********************************************************************
   980 *  reset_refsp - reset the reference space
   981 *
   982 *  This routine resets (redefines) the reference space used in the
   983 *  projected steepest edge pricing algorithm. */
   984 
   985 static void reset_refsp(struct csa *csa)
   986 {     int m = csa->m;
   987       int n = csa->n;
   988       int *head = csa->head;
   989       char *refsp = csa->refsp;
   990       double *gamma = csa->gamma;
   991       int i, k;
   992       xassert(csa->refct == 0);
   993       csa->refct = 1000;
   994       memset(&refsp[1], 0, (m+n) * sizeof(char));
   995       for (i = 1; i <= m; i++)
   996       {  k = head[i]; /* x[k] = xB[i] */
   997          refsp[k] = 1;
   998          gamma[i] = 1.0;
   999       }
  1000       return;
  1001 }
  1002 
  1003 /***********************************************************************
  1004 *  eval_gamma - compute steepest edge coefficients
  1005 *
  1006 *  This routine computes the vector of steepest edge coefficients for
  1007 *  all basic variables (except free ones) using its direct definition:
  1008 *
  1009 *     gamma[i] = eta[i] +  sum   alfa[i,j]^2,  i = 1,...,m,
  1010 *                         j in C
  1011 *
  1012 *  where eta[i] = 1 means that xB[i] is in the current reference space,
  1013 *  and 0 otherwise; C is a set of non-basic non-fixed variables xN[j],
  1014 *  which are in the current reference space; alfa[i,j] are elements of
  1015 *  the current simplex table.
  1016 *
  1017 *  NOTE: The routine is intended only for debugginig purposes. */
  1018 
  1019 static void eval_gamma(struct csa *csa, double gamma[])
  1020 {     int m = csa->m;
  1021       int n = csa->n;
  1022       char *type = csa->type;
  1023       int *head = csa->head;
  1024       char *refsp = csa->refsp;
  1025       double *alfa = csa->work3;
  1026       double *h = csa->work3;
  1027       int i, j, k;
  1028       /* gamma[i] := eta[i] (or 1, if xB[i] is free) */
  1029       for (i = 1; i <= m; i++)
  1030       {  k = head[i]; /* x[k] = xB[i] */
  1031 #ifdef GLP_DEBUG
  1032          xassert(1 <= k && k <= m+n);
  1033 #endif
  1034          if (type[k] == GLP_FR)
  1035             gamma[i] = 1.0;
  1036          else
  1037             gamma[i] = (refsp[k] ? 1.0 : 0.0);
  1038       }
  1039       /* compute columns of the current simplex table */
  1040       for (j = 1; j <= n; j++)
  1041       {  k = head[m+j]; /* x[k] = xN[j] */
  1042 #ifdef GLP_DEBUG
  1043          xassert(1 <= k && k <= m+n);
  1044 #endif
  1045          /* skip column, if xN[j] is not in C */
  1046          if (!refsp[k]) continue;
  1047 #ifdef GLP_DEBUG
  1048          /* set C must not contain fixed variables */
  1049          xassert(type[k] != GLP_FX);
  1050 #endif
  1051          /* construct the right-hand side vector h = - N[j] */
  1052          for (i = 1; i <= m; i++)
  1053             h[i] = 0.0;
  1054          if (k <= m)
  1055          {  /* N[j] is k-th column of submatrix I */
  1056             h[k] = -1.0;
  1057          }
  1058          else
  1059          {  /* N[j] is (k-m)-th column of submatrix (-A) */
  1060             int *A_ptr = csa->A_ptr;
  1061             int *A_ind = csa->A_ind;
  1062             double *A_val = csa->A_val;
  1063             int beg, end, ptr;
  1064             beg = A_ptr[k-m];
  1065             end = A_ptr[k-m+1];
  1066             for (ptr = beg; ptr < end; ptr++)
  1067                h[A_ind[ptr]] = A_val[ptr];
  1068          }
  1069          /* solve system B * alfa = h */
  1070          xassert(csa->valid);
  1071          bfd_ftran(csa->bfd, alfa);
  1072          /* gamma[i] := gamma[i] + alfa[i,j]^2 */
  1073          for (i = 1; i <= m; i++)
  1074          {  k = head[i]; /* x[k] = xB[i] */
  1075             if (type[k] != GLP_FR)
  1076                gamma[i] += alfa[i] * alfa[i];
  1077          }
  1078       }
  1079       return;
  1080 }
  1081 
  1082 /***********************************************************************
  1083 *  chuzr - choose basic variable (row of the simplex table)
  1084 *
  1085 *  This routine chooses basic variable xB[p] having largest weighted
  1086 *  bound violation:
  1087 *
  1088 *     |r[p]| / sqrt(gamma[p]) = max  |r[i]| / sqrt(gamma[i]),
  1089 *                              i in I
  1090 *
  1091 *            / lB[i] - beta[i], if beta[i] < lB[i]
  1092 *            |
  1093 *     r[i] = < 0,               if lB[i] <= beta[i] <= uB[i]
  1094 *            |
  1095 *            \ uB[i] - beta[i], if beta[i] > uB[i]
  1096 *
  1097 *  where beta[i] is primal value of xB[i] in the current basis, lB[i]
  1098 *  and uB[i] are lower and upper bounds of xB[i], I is a subset of
  1099 *  eligible basic variables, which significantly violates their bounds,
  1100 *  gamma[i] is the steepest edge coefficient.
  1101 *
  1102 *  If |r[i]| is less than a specified tolerance, xB[i] is not included
  1103 *  in I and therefore ignored.
  1104 *
  1105 *  If I is empty and no variable has been chosen, p is set to 0. */
  1106 
  1107 static void chuzr(struct csa *csa, double tol_bnd)
  1108 {     int m = csa->m;
  1109 #ifdef GLP_DEBUG
  1110       int n = csa->n;
  1111 #endif
  1112       char *type = csa->type;
  1113       double *lb = csa->lb;
  1114       double *ub = csa->ub;
  1115       int *head = csa->head;
  1116       double *bbar = csa->bbar;
  1117       double *gamma = csa->gamma;
  1118       int i, k, p;
  1119       double delta, best, eps, ri, temp;
  1120       /* nothing is chosen so far */
  1121       p = 0, delta = 0.0, best = 0.0;
  1122       /* look through the list of basic variables */
  1123       for (i = 1; i <= m; i++)
  1124       {  k = head[i]; /* x[k] = xB[i] */
  1125 #ifdef GLP_DEBUG
  1126          xassert(1 <= k && k <= m+n);
  1127 #endif
  1128          /* determine bound violation ri[i] */
  1129          ri = 0.0;
  1130          if (type[k] == GLP_LO || type[k] == GLP_DB ||
  1131              type[k] == GLP_FX)
  1132          {  /* xB[i] has lower bound */
  1133             eps = tol_bnd * (1.0 + kappa * fabs(lb[k]));
  1134             if (bbar[i] < lb[k] - eps)
  1135             {  /* and significantly violates it */
  1136                ri = lb[k] - bbar[i];
  1137             }
  1138          }
  1139          if (type[k] == GLP_UP || type[k] == GLP_DB ||
  1140              type[k] == GLP_FX)
  1141          {  /* xB[i] has upper bound */
  1142             eps = tol_bnd * (1.0 + kappa * fabs(ub[k]));
  1143             if (bbar[i] > ub[k] + eps)
  1144             {  /* and significantly violates it */
  1145                ri = ub[k] - bbar[i];
  1146             }
  1147          }
  1148          /* if xB[i] is not eligible, skip it */
  1149          if (ri == 0.0) continue;
  1150          /* xB[i] is eligible basic variable; choose one with largest
  1151             weighted bound violation */
  1152 #ifdef GLP_DEBUG
  1153          xassert(gamma[i] >= 0.0);
  1154 #endif
  1155          temp = gamma[i];
  1156          if (temp < DBL_EPSILON) temp = DBL_EPSILON;
  1157          temp = (ri * ri) / temp;
  1158          if (best < temp)
  1159             p = i, delta = ri, best = temp;
  1160       }
  1161       /* store the index of basic variable xB[p] chosen and its change
  1162          in the adjacent basis */
  1163       csa->p = p;
  1164       csa->delta = delta;
  1165       return;
  1166 }
  1167 
  1168 #if 1 /* copied from primal */
  1169 /***********************************************************************
  1170 *  eval_rho - compute pivot row of the inverse
  1171 *
  1172 *  This routine computes the pivot (p-th) row of the inverse inv(B),
  1173 *  which corresponds to basic variable xB[p] chosen:
  1174 *
  1175 *     rho = inv(B') * e[p],
  1176 *
  1177 *  where B' is a matrix transposed to the current basis matrix, e[p]
  1178 *  is unity vector. */
  1179 
  1180 static void eval_rho(struct csa *csa, double rho[])
  1181 {     int m = csa->m;
  1182       int p = csa->p;
  1183       double *e = rho;
  1184       int i;
  1185 #ifdef GLP_DEBUG
  1186       xassert(1 <= p && p <= m);
  1187 #endif
  1188       /* construct the right-hand side vector e[p] */
  1189       for (i = 1; i <= m; i++)
  1190          e[i] = 0.0;
  1191       e[p] = 1.0;
  1192       /* solve system B'* rho = e[p] */
  1193       xassert(csa->valid);
  1194       bfd_btran(csa->bfd, rho);
  1195       return;
  1196 }
  1197 #endif
  1198 
  1199 #if 1 /* copied from primal */
  1200 /***********************************************************************
  1201 *  refine_rho - refine pivot row of the inverse
  1202 *
  1203 *  This routine refines the pivot row of the inverse inv(B) assuming
  1204 *  that it was previously computed by the routine eval_rho. */
  1205 
  1206 static void refine_rho(struct csa *csa, double rho[])
  1207 {     int m = csa->m;
  1208       int p = csa->p;
  1209       double *e = csa->work3;
  1210       int i;
  1211 #ifdef GLP_DEBUG
  1212       xassert(1 <= p && p <= m);
  1213 #endif
  1214       /* construct the right-hand side vector e[p] */
  1215       for (i = 1; i <= m; i++)
  1216          e[i] = 0.0;
  1217       e[p] = 1.0;
  1218       /* refine solution of B'* rho = e[p] */
  1219       refine_btran(csa, e, rho);
  1220       return;
  1221 }
  1222 #endif
  1223 
  1224 #if 1 /* 06/IV-2009 */
  1225 /***********************************************************************
  1226 *  eval_trow - compute pivot row of the simplex table
  1227 *
  1228 *  This routine computes the pivot row of the simplex table, which
  1229 *  corresponds to basic variable xB[p] chosen.
  1230 *
  1231 *  The pivot row is the following vector:
  1232 *
  1233 *     trow = T'* e[p] = - N'* inv(B') * e[p] = - N' * rho,
  1234 *
  1235 *  where rho is the pivot row of the inverse inv(B) previously computed
  1236 *  by the routine eval_rho.
  1237 *
  1238 *  Note that elements of the pivot row corresponding to fixed non-basic
  1239 *  variables are not computed.
  1240 *
  1241 *  NOTES
  1242 *
  1243 *  Computing pivot row of the simplex table is one of the most time
  1244 *  consuming operations, and for some instances it may take more than
  1245 *  50% of the total solution time.
  1246 *
  1247 *  In the current implementation there are two routines to compute the
  1248 *  pivot row. The routine eval_trow1 computes elements of the pivot row
  1249 *  as inner products of columns of the matrix N and the vector rho; it
  1250 *  is used when the vector rho is relatively dense. The routine
  1251 *  eval_trow2 computes the pivot row as a linear combination of rows of
  1252 *  the matrix N; it is used when the vector rho is relatively sparse. */
  1253 
  1254 static void eval_trow1(struct csa *csa, double rho[])
  1255 {     int m = csa->m;
  1256       int n = csa->n;
  1257       int *A_ptr = csa->A_ptr;
  1258       int *A_ind = csa->A_ind;
  1259       double *A_val = csa->A_val;
  1260       int *head = csa->head;
  1261       char *stat = csa->stat;
  1262       int *trow_ind = csa->trow_ind;
  1263       double *trow_vec = csa->trow_vec;
  1264       int j, k, beg, end, ptr, nnz;
  1265       double temp;
  1266       /* compute the pivot row as inner products of columns of the
  1267          matrix N and vector rho: trow[j] = - rho * N[j] */
  1268       nnz = 0;
  1269       for (j = 1; j <= n; j++)
  1270       {  if (stat[j] == GLP_NS)
  1271          {  /* xN[j] is fixed */
  1272             trow_vec[j] = 0.0;
  1273             continue;
  1274          }
  1275          k = head[m+j]; /* x[k] = xN[j] */
  1276          if (k <= m)
  1277          {  /* N[j] is k-th column of submatrix I */
  1278             temp = - rho[k];
  1279          }
  1280          else
  1281          {  /* N[j] is (k-m)-th column of submatrix (-A) */
  1282             beg = A_ptr[k-m], end = A_ptr[k-m+1];
  1283             temp = 0.0;
  1284             for (ptr = beg; ptr < end; ptr++)
  1285                temp += rho[A_ind[ptr]] * A_val[ptr];
  1286          }
  1287          if (temp != 0.0)
  1288             trow_ind[++nnz] = j;
  1289          trow_vec[j] = temp;
  1290       }
  1291       csa->trow_nnz = nnz;
  1292       return;
  1293 }
  1294 
  1295 static void eval_trow2(struct csa *csa, double rho[])
  1296 {     int m = csa->m;
  1297       int n = csa->n;
  1298       int *AT_ptr = csa->AT_ptr;
  1299       int *AT_ind = csa->AT_ind;
  1300       double *AT_val = csa->AT_val;
  1301       int *bind = csa->bind;
  1302       char *stat = csa->stat;
  1303       int *trow_ind = csa->trow_ind;
  1304       double *trow_vec = csa->trow_vec;
  1305       int i, j, beg, end, ptr, nnz;
  1306       double temp;
  1307       /* clear the pivot row */
  1308       for (j = 1; j <= n; j++)
  1309          trow_vec[j] = 0.0;
  1310       /* compute the pivot row as a linear combination of rows of the
  1311          matrix N: trow = - rho[1] * N'[1] - ... - rho[m] * N'[m] */
  1312       for (i = 1; i <= m; i++)
  1313       {  temp = rho[i];
  1314          if (temp == 0.0) continue;
  1315          /* trow := trow - rho[i] * N'[i] */
  1316          j = bind[i] - m; /* x[i] = xN[j] */
  1317          if (j >= 1 && stat[j] != GLP_NS)
  1318             trow_vec[j] -= temp;
  1319          beg = AT_ptr[i], end = AT_ptr[i+1];
  1320          for (ptr = beg; ptr < end; ptr++)
  1321          {  j = bind[m + AT_ind[ptr]] - m; /* x[k] = xN[j] */
  1322             if (j >= 1 && stat[j] != GLP_NS)
  1323                trow_vec[j] += temp * AT_val[ptr];
  1324          }
  1325       }
  1326       /* construct sparse pattern of the pivot row */
  1327       nnz = 0;
  1328       for (j = 1; j <= n; j++)
  1329       {  if (trow_vec[j] != 0.0)
  1330             trow_ind[++nnz] = j;
  1331       }
  1332       csa->trow_nnz = nnz;
  1333       return;
  1334 }
  1335 
  1336 static void eval_trow(struct csa *csa, double rho[])
  1337 {     int m = csa->m;
  1338       int i, nnz;
  1339       double dens;
  1340       /* determine the density of the vector rho */
  1341       nnz = 0;
  1342       for (i = 1; i <= m; i++)
  1343          if (rho[i] != 0.0) nnz++;
  1344       dens = (double)nnz / (double)m;
  1345       if (dens >= 0.20)
  1346       {  /* rho is relatively dense */
  1347          eval_trow1(csa, rho);
  1348       }
  1349       else
  1350       {  /* rho is relatively sparse */
  1351          eval_trow2(csa, rho);
  1352       }
  1353       return;
  1354 }
  1355 #endif
  1356 
  1357 /***********************************************************************
  1358 *  sort_trow - sort pivot row of the simplex table
  1359 *
  1360 *  This routine reorders the list of non-zero elements of the pivot
  1361 *  row to put significant elements, whose magnitude is not less than
  1362 *  a specified tolerance, in front of the list, and stores the number
  1363 *  of significant elements in trow_num. */
  1364 
  1365 static void sort_trow(struct csa *csa, double tol_piv)
  1366 {
  1367 #ifdef GLP_DEBUG
  1368       int n = csa->n;
  1369       char *stat = csa->stat;
  1370 #endif
  1371       int nnz = csa->trow_nnz;
  1372       int *trow_ind = csa->trow_ind;
  1373       double *trow_vec = csa->trow_vec;
  1374       int j, num, pos;
  1375       double big, eps, temp;
  1376       /* compute infinity (maximum) norm of the row */
  1377       big = 0.0;
  1378       for (pos = 1; pos <= nnz; pos++)
  1379       {
  1380 #ifdef GLP_DEBUG
  1381          j = trow_ind[pos];
  1382          xassert(1 <= j && j <= n);
  1383          xassert(stat[j] != GLP_NS);
  1384 #endif
  1385          temp = fabs(trow_vec[trow_ind[pos]]);
  1386          if (big < temp) big = temp;
  1387       }
  1388       csa->trow_max = big;
  1389       /* determine absolute pivot tolerance */
  1390       eps = tol_piv * (1.0 + 0.01 * big);
  1391       /* move significant row components to the front of the list */
  1392       for (num = 0; num < nnz; )
  1393       {  j = trow_ind[nnz];
  1394          if (fabs(trow_vec[j]) < eps)
  1395             nnz--;
  1396          else
  1397          {  num++;
  1398             trow_ind[nnz] = trow_ind[num];
  1399             trow_ind[num] = j;
  1400          }
  1401       }
  1402       csa->trow_num = num;
  1403       return;
  1404 }
  1405 
  1406 #ifdef GLP_LONG_STEP /* 07/IV-2009 */
  1407 static int ls_func(const void *p1_, const void *p2_)
  1408 {     const struct bkpt *p1 = p1_, *p2 = p2_;
  1409       if (p1->t < p2->t) return -1;
  1410       if (p1->t > p2->t) return +1;
  1411       return 0;
  1412 }
  1413 
  1414 static int ls_func1(const void *p1_, const void *p2_)
  1415 {     const struct bkpt *p1 = p1_, *p2 = p2_;
  1416       if (p1->dz < p2->dz) return -1;
  1417       if (p1->dz > p2->dz) return +1;
  1418       return 0;
  1419 }
  1420 
  1421 static void long_step(struct csa *csa)
  1422 {     int m = csa->m;
  1423 #ifdef GLP_DEBUG
  1424       int n = csa->n;
  1425 #endif
  1426       char *type = csa->type;
  1427       double *lb = csa->lb;
  1428       double *ub = csa->ub;
  1429       int *head = csa->head;
  1430       char *stat = csa->stat;
  1431       double *cbar = csa->cbar;
  1432       double delta = csa->delta;
  1433       int *trow_ind = csa->trow_ind;
  1434       double *trow_vec = csa->trow_vec;
  1435       int trow_num = csa->trow_num;
  1436       struct bkpt *bkpt = csa->bkpt;
  1437       int j, k, kk, nbps, pos;
  1438       double alfa, s, slope, dzmax;
  1439       /* delta > 0 means that xB[p] violates its lower bound, so to
  1440          increase the dual objective lambdaB[p] must increase;
  1441          delta < 0 means that xB[p] violates its upper bound, so to
  1442          increase the dual objective lambdaB[p] must decrease */
  1443       /* s := sign(delta) */
  1444       s = (delta > 0.0 ? +1.0 : -1.0);
  1445       /* determine breakpoints of the dual objective */
  1446       nbps = 0;
  1447       for (pos = 1; pos <= trow_num; pos++)
  1448       {  j = trow_ind[pos];
  1449 #ifdef GLP_DEBUG
  1450          xassert(1 <= j && j <= n);
  1451          xassert(stat[j] != GLP_NS);
  1452 #endif
  1453          /* if there is free non-basic variable, switch to the standard
  1454             ratio test */
  1455          if (stat[j] == GLP_NF)
  1456          {  nbps = 0;
  1457             goto done;
  1458          }
  1459          /* lambdaN[j] = ... - alfa * t - ..., where t = s * lambdaB[i]
  1460             is the dual ray parameter, t >= 0 */
  1461          alfa = s * trow_vec[j];
  1462 #ifdef GLP_DEBUG
  1463          xassert(alfa != 0.0);
  1464          xassert(stat[j] == GLP_NL || stat[j] == GLP_NU);
  1465 #endif
  1466          if (alfa > 0.0 && stat[j] == GLP_NL ||
  1467              alfa < 0.0 && stat[j] == GLP_NU)
  1468          {  /* either lambdaN[j] >= 0 (if stat = GLP_NL) and decreases
  1469                or lambdaN[j] <= 0 (if stat = GLP_NU) and increases; in
  1470                both cases we have a breakpoint */
  1471             nbps++;
  1472 #ifdef GLP_DEBUG
  1473             xassert(nbps <= n);
  1474 #endif
  1475             bkpt[nbps].j = j;
  1476             bkpt[nbps].t = cbar[j] / alfa;
  1477 /*
  1478 if (stat[j] == GLP_NL && cbar[j] < 0.0 ||
  1479     stat[j] == GLP_NU && cbar[j] > 0.0)
  1480 xprintf("%d %g\n", stat[j], cbar[j]);
  1481 */
  1482             /* if t is negative, replace it by exact zero (see comments
  1483                in the routine chuzc) */
  1484             if (bkpt[nbps].t < 0.0) bkpt[nbps].t = 0.0;
  1485          }
  1486       }
  1487       /* if there are less than two breakpoints, switch to the standard
  1488          ratio test */
  1489       if (nbps < 2)
  1490       {  nbps = 0;
  1491          goto done;
  1492       }
  1493       /* sort breakpoints by ascending the dual ray parameter, t */
  1494       qsort(&bkpt[1], nbps, sizeof(struct bkpt), ls_func);
  1495       /* determine last breakpoint, at which the dual objective still
  1496          greater than at t = 0 */
  1497       dzmax = 0.0;
  1498       slope = fabs(delta); /* initial slope */
  1499       for (kk = 1; kk <= nbps; kk++)
  1500       {  if (kk == 1)
  1501             bkpt[kk].dz =
  1502                0.0 + slope * (bkpt[kk].t - 0.0);
  1503          else
  1504             bkpt[kk].dz =
  1505                bkpt[kk-1].dz + slope * (bkpt[kk].t - bkpt[kk-1].t);
  1506          if (dzmax < bkpt[kk].dz)
  1507             dzmax = bkpt[kk].dz;
  1508          else if (bkpt[kk].dz < 0.05 * (1.0 + dzmax))
  1509          {  nbps = kk - 1;
  1510             break;
  1511          }
  1512          j = bkpt[kk].j;
  1513          k = head[m+j]; /* x[k] = xN[j] */
  1514          if (type[k] == GLP_DB)
  1515             slope -= fabs(trow_vec[j]) * (ub[k] - lb[k]);
  1516          else
  1517          {  nbps = kk;
  1518             break;
  1519          }
  1520       }
  1521       /* if there are less than two breakpoints, switch to the standard
  1522          ratio test */
  1523       if (nbps < 2)
  1524       {  nbps = 0;
  1525          goto done;
  1526       }
  1527       /* sort breakpoints by ascending the dual change, dz */
  1528       qsort(&bkpt[1], nbps, sizeof(struct bkpt), ls_func1);
  1529 /*
  1530 for (kk = 1; kk <= nbps; kk++)
  1531 xprintf("%d; t = %g; dz = %g\n", kk, bkpt[kk].t, bkpt[kk].dz);
  1532 */
  1533 done: csa->nbps = nbps;
  1534       return;
  1535 }
  1536 #endif
  1537 
  1538 /***********************************************************************
  1539 *  chuzc - choose non-basic variable (column of the simplex table)
  1540 *
  1541 *  This routine chooses non-basic variable xN[q], which being entered
  1542 *  in the basis keeps dual feasibility of the basic solution.
  1543 *
  1544 *  The parameter rtol is a relative tolerance used to relax zero bounds
  1545 *  of reduced costs of non-basic variables. If rtol = 0, the routine
  1546 *  implements the standard ratio test. Otherwise, if rtol > 0, the
  1547 *  routine implements Harris' two-pass ratio test. In the latter case
  1548 *  rtol should be about three times less than a tolerance used to check
  1549 *  dual feasibility. */
  1550 
  1551 static void chuzc(struct csa *csa, double rtol)
  1552 {
  1553 #ifdef GLP_DEBUG
  1554       int m = csa->m;
  1555       int n = csa->n;
  1556 #endif
  1557       char *stat = csa->stat;
  1558       double *cbar = csa->cbar;
  1559 #ifdef GLP_DEBUG
  1560       int p = csa->p;
  1561 #endif
  1562       double delta = csa->delta;
  1563       int *trow_ind = csa->trow_ind;
  1564       double *trow_vec = csa->trow_vec;
  1565       int trow_num = csa->trow_num;
  1566       int j, pos, q;
  1567       double alfa, big, s, t, teta, tmax;
  1568 #ifdef GLP_DEBUG
  1569       xassert(1 <= p && p <= m);
  1570 #endif
  1571       /* delta > 0 means that xB[p] violates its lower bound and goes
  1572          to it in the adjacent basis, so lambdaB[p] is increasing from
  1573          its lower zero bound;
  1574          delta < 0 means that xB[p] violates its upper bound and goes
  1575          to it in the adjacent basis, so lambdaB[p] is decreasing from
  1576          its upper zero bound */
  1577 #ifdef GLP_DEBUG
  1578       xassert(delta != 0.0);
  1579 #endif
  1580       /* s := sign(delta) */
  1581       s = (delta > 0.0 ? +1.0 : -1.0);
  1582       /*** FIRST PASS ***/
  1583       /* nothing is chosen so far */
  1584       q = 0, teta = DBL_MAX, big = 0.0;
  1585       /* walk through significant elements of the pivot row */
  1586       for (pos = 1; pos <= trow_num; pos++)
  1587       {  j = trow_ind[pos];
  1588 #ifdef GLP_DEBUG
  1589          xassert(1 <= j && j <= n);
  1590 #endif
  1591          alfa = s * trow_vec[j];
  1592 #ifdef GLP_DEBUG
  1593          xassert(alfa != 0.0);
  1594 #endif
  1595          /* lambdaN[j] = ... - alfa * lambdaB[p] - ..., and due to s we
  1596             need to consider only increasing lambdaB[p] */
  1597          if (alfa > 0.0)
  1598          {  /* lambdaN[j] is decreasing */
  1599             if (stat[j] == GLP_NL || stat[j] == GLP_NF)
  1600             {  /* lambdaN[j] has zero lower bound */
  1601                t = (cbar[j] + rtol) / alfa;
  1602             }
  1603             else
  1604             {  /* lambdaN[j] has no lower bound */
  1605                continue;
  1606             }
  1607          }
  1608          else
  1609          {  /* lambdaN[j] is increasing */
  1610             if (stat[j] == GLP_NU || stat[j] == GLP_NF)
  1611             {  /* lambdaN[j] has zero upper bound */
  1612                t = (cbar[j] - rtol) / alfa;
  1613             }
  1614             else
  1615             {  /* lambdaN[j] has no upper bound */
  1616                continue;
  1617             }
  1618          }
  1619          /* t is a change of lambdaB[p], on which lambdaN[j] reaches
  1620             its zero bound (possibly relaxed); since the basic solution
  1621             is assumed to be dual feasible, t has to be non-negative by
  1622             definition; however, it may happen that lambdaN[j] slightly
  1623             (i.e. within a tolerance) violates its zero bound, that
  1624             leads to negative t; in the latter case, if xN[j] is chosen,
  1625             negative t means that lambdaB[p] changes in wrong direction
  1626             that may cause wrong results on updating reduced costs;
  1627             thus, if t is negative, we should replace it by exact zero
  1628             assuming that lambdaN[j] is exactly on its zero bound, and
  1629             violation appears due to round-off errors */
  1630          if (t < 0.0) t = 0.0;
  1631          /* apply minimal ratio test */
  1632          if (teta > t || teta == t && big < fabs(alfa))
  1633             q = j, teta = t, big = fabs(alfa);
  1634       }
  1635       /* the second pass is skipped in the following cases: */
  1636       /* if the standard ratio test is used */
  1637       if (rtol == 0.0) goto done;
  1638       /* if no non-basic variable has been chosen on the first pass */
  1639       if (q == 0) goto done;
  1640       /* if lambdaN[q] prevents lambdaB[p] from any change */
  1641       if (teta == 0.0) goto done;
  1642       /*** SECOND PASS ***/
  1643       /* here tmax is a maximal change of lambdaB[p], on which the
  1644          solution remains dual feasible within a tolerance */
  1645 #if 0
  1646       tmax = (1.0 + 10.0 * DBL_EPSILON) * teta;
  1647 #else
  1648       tmax = teta;
  1649 #endif
  1650       /* nothing is chosen so far */
  1651       q = 0, teta = DBL_MAX, big = 0.0;
  1652       /* walk through significant elements of the pivot row */
  1653       for (pos = 1; pos <= trow_num; pos++)
  1654       {  j = trow_ind[pos];
  1655 #ifdef GLP_DEBUG
  1656          xassert(1 <= j && j <= n);
  1657 #endif
  1658          alfa = s * trow_vec[j];
  1659 #ifdef GLP_DEBUG
  1660          xassert(alfa != 0.0);
  1661 #endif
  1662          /* lambdaN[j] = ... - alfa * lambdaB[p] - ..., and due to s we
  1663             need to consider only increasing lambdaB[p] */
  1664          if (alfa > 0.0)
  1665          {  /* lambdaN[j] is decreasing */
  1666             if (stat[j] == GLP_NL || stat[j] == GLP_NF)
  1667             {  /* lambdaN[j] has zero lower bound */
  1668                t = cbar[j] / alfa;
  1669             }
  1670             else
  1671             {  /* lambdaN[j] has no lower bound */
  1672                continue;
  1673             }
  1674          }
  1675          else
  1676          {  /* lambdaN[j] is increasing */
  1677             if (stat[j] == GLP_NU || stat[j] == GLP_NF)
  1678             {  /* lambdaN[j] has zero upper bound */
  1679                t = cbar[j] / alfa;
  1680             }
  1681             else
  1682             {  /* lambdaN[j] has no upper bound */
  1683                continue;
  1684             }
  1685          }
  1686          /* (see comments for the first pass) */
  1687          if (t < 0.0) t = 0.0;
  1688          /* t is a change of lambdaB[p], on which lambdaN[j] reaches
  1689             its zero (lower or upper) bound; if t <= tmax, all reduced
  1690             costs can violate their zero bounds only within relaxation
  1691             tolerance rtol, so we can choose non-basic variable having
  1692             largest influence coefficient to avoid possible numerical
  1693             instability */
  1694          if (t <= tmax && big < fabs(alfa))
  1695             q = j, teta = t, big = fabs(alfa);
  1696       }
  1697       /* something must be chosen on the second pass */
  1698       xassert(q != 0);
  1699 done: /* store the index of non-basic variable xN[q] chosen */
  1700       csa->q = q;
  1701       /* store reduced cost of xN[q] in the adjacent basis */
  1702       csa->new_dq = s * teta;
  1703       return;
  1704 }
  1705 
  1706 #if 1 /* copied from primal */
  1707 /***********************************************************************
  1708 *  eval_tcol - compute pivot column of the simplex table
  1709 *
  1710 *  This routine computes the pivot column of the simplex table, which
  1711 *  corresponds to non-basic variable xN[q] chosen.
  1712 *
  1713 *  The pivot column is the following vector:
  1714 *
  1715 *     tcol = T * e[q] = - inv(B) * N * e[q] = - inv(B) * N[q],
  1716 *
  1717 *  where B is the current basis matrix, N[q] is a column of the matrix
  1718 *  (I|-A) corresponding to variable xN[q]. */
  1719 
  1720 static void eval_tcol(struct csa *csa)
  1721 {     int m = csa->m;
  1722 #ifdef GLP_DEBUG
  1723       int n = csa->n;
  1724 #endif
  1725       int *head = csa->head;
  1726       int q = csa->q;
  1727       int *tcol_ind = csa->tcol_ind;
  1728       double *tcol_vec = csa->tcol_vec;
  1729       double *h = csa->tcol_vec;
  1730       int i, k, nnz;
  1731 #ifdef GLP_DEBUG
  1732       xassert(1 <= q && q <= n);
  1733 #endif
  1734       k = head[m+q]; /* x[k] = xN[q] */
  1735 #ifdef GLP_DEBUG
  1736       xassert(1 <= k && k <= m+n);
  1737 #endif
  1738       /* construct the right-hand side vector h = - N[q] */
  1739       for (i = 1; i <= m; i++)
  1740          h[i] = 0.0;
  1741       if (k <= m)
  1742       {  /* N[q] is k-th column of submatrix I */
  1743          h[k] = -1.0;
  1744       }
  1745       else
  1746       {  /* N[q] is (k-m)-th column of submatrix (-A) */
  1747          int *A_ptr = csa->A_ptr;
  1748          int *A_ind = csa->A_ind;
  1749          double *A_val = csa->A_val;
  1750          int beg, end, ptr;
  1751          beg = A_ptr[k-m];
  1752          end = A_ptr[k-m+1];
  1753          for (ptr = beg; ptr < end; ptr++)
  1754             h[A_ind[ptr]] = A_val[ptr];
  1755       }
  1756       /* solve system B * tcol = h */
  1757       xassert(csa->valid);
  1758       bfd_ftran(csa->bfd, tcol_vec);
  1759       /* construct sparse pattern of the pivot column */
  1760       nnz = 0;
  1761       for (i = 1; i <= m; i++)
  1762       {  if (tcol_vec[i] != 0.0)
  1763             tcol_ind[++nnz] = i;
  1764       }
  1765       csa->tcol_nnz = nnz;
  1766       return;
  1767 }
  1768 #endif
  1769 
  1770 #if 1 /* copied from primal */
  1771 /***********************************************************************
  1772 *  refine_tcol - refine pivot column of the simplex table
  1773 *
  1774 *  This routine refines the pivot column of the simplex table assuming
  1775 *  that it was previously computed by the routine eval_tcol. */
  1776 
  1777 static void refine_tcol(struct csa *csa)
  1778 {     int m = csa->m;
  1779 #ifdef GLP_DEBUG
  1780       int n = csa->n;
  1781 #endif
  1782       int *head = csa->head;
  1783       int q = csa->q;
  1784       int *tcol_ind = csa->tcol_ind;
  1785       double *tcol_vec = csa->tcol_vec;
  1786       double *h = csa->work3;
  1787       int i, k, nnz;
  1788 #ifdef GLP_DEBUG
  1789       xassert(1 <= q && q <= n);
  1790 #endif
  1791       k = head[m+q]; /* x[k] = xN[q] */
  1792 #ifdef GLP_DEBUG
  1793       xassert(1 <= k && k <= m+n);
  1794 #endif
  1795       /* construct the right-hand side vector h = - N[q] */
  1796       for (i = 1; i <= m; i++)
  1797          h[i] = 0.0;
  1798       if (k <= m)
  1799       {  /* N[q] is k-th column of submatrix I */
  1800          h[k] = -1.0;
  1801       }
  1802       else
  1803       {  /* N[q] is (k-m)-th column of submatrix (-A) */
  1804          int *A_ptr = csa->A_ptr;
  1805          int *A_ind = csa->A_ind;
  1806          double *A_val = csa->A_val;
  1807          int beg, end, ptr;
  1808          beg = A_ptr[k-m];
  1809          end = A_ptr[k-m+1];
  1810          for (ptr = beg; ptr < end; ptr++)
  1811             h[A_ind[ptr]] = A_val[ptr];
  1812       }
  1813       /* refine solution of B * tcol = h */
  1814       refine_ftran(csa, h, tcol_vec);
  1815       /* construct sparse pattern of the pivot column */
  1816       nnz = 0;
  1817       for (i = 1; i <= m; i++)
  1818       {  if (tcol_vec[i] != 0.0)
  1819             tcol_ind[++nnz] = i;
  1820       }
  1821       csa->tcol_nnz = nnz;
  1822       return;
  1823 }
  1824 #endif
  1825 
  1826 /***********************************************************************
  1827 *  update_cbar - update reduced costs of non-basic variables
  1828 *
  1829 *  This routine updates reduced costs of all (except fixed) non-basic
  1830 *  variables for the adjacent basis. */
  1831 
  1832 static void update_cbar(struct csa *csa)
  1833 {
  1834 #ifdef GLP_DEBUG
  1835       int n = csa->n;
  1836 #endif
  1837       double *cbar = csa->cbar;
  1838       int trow_nnz = csa->trow_nnz;
  1839       int *trow_ind = csa->trow_ind;
  1840       double *trow_vec = csa->trow_vec;
  1841       int q = csa->q;
  1842       double new_dq = csa->new_dq;
  1843       int j, pos;
  1844 #ifdef GLP_DEBUG
  1845       xassert(1 <= q && q <= n);
  1846 #endif
  1847       /* set new reduced cost of xN[q] */
  1848       cbar[q] = new_dq;
  1849       /* update reduced costs of other non-basic variables */
  1850       if (new_dq == 0.0) goto done;
  1851       for (pos = 1; pos <= trow_nnz; pos++)
  1852       {  j = trow_ind[pos];
  1853 #ifdef GLP_DEBUG
  1854          xassert(1 <= j && j <= n);
  1855 #endif
  1856          if (j != q)
  1857             cbar[j] -= trow_vec[j] * new_dq;
  1858       }
  1859 done: return;
  1860 }
  1861 
  1862 /***********************************************************************
  1863 *  update_bbar - update values of basic variables
  1864 *
  1865 *  This routine updates values of all basic variables for the adjacent
  1866 *  basis. */
  1867 
  1868 static void update_bbar(struct csa *csa)
  1869 {
  1870 #ifdef GLP_DEBUG
  1871       int m = csa->m;
  1872       int n = csa->n;
  1873 #endif
  1874       double *bbar = csa->bbar;
  1875       int p = csa->p;
  1876       double delta = csa->delta;
  1877       int q = csa->q;
  1878       int tcol_nnz = csa->tcol_nnz;
  1879       int *tcol_ind = csa->tcol_ind;
  1880       double *tcol_vec = csa->tcol_vec;
  1881       int i, pos;
  1882       double teta;
  1883 #ifdef GLP_DEBUG
  1884       xassert(1 <= p && p <= m);
  1885       xassert(1 <= q && q <= n);
  1886 #endif
  1887       /* determine the change of xN[q] in the adjacent basis */
  1888 #ifdef GLP_DEBUG
  1889       xassert(tcol_vec[p] != 0.0);
  1890 #endif
  1891       teta = delta / tcol_vec[p];
  1892       /* set new primal value of xN[q] */
  1893       bbar[p] = get_xN(csa, q) + teta;
  1894       /* update primal values of other basic variables */
  1895       if (teta == 0.0) goto done;
  1896       for (pos = 1; pos <= tcol_nnz; pos++)
  1897       {  i = tcol_ind[pos];
  1898 #ifdef GLP_DEBUG
  1899          xassert(1 <= i && i <= m);
  1900 #endif
  1901          if (i != p)
  1902             bbar[i] += tcol_vec[i] * teta;
  1903       }
  1904 done: return;
  1905 }
  1906 
  1907 /***********************************************************************
  1908 *  update_gamma - update steepest edge coefficients
  1909 *
  1910 *  This routine updates steepest-edge coefficients for the adjacent
  1911 *  basis. */
  1912 
  1913 static void update_gamma(struct csa *csa)
  1914 {     int m = csa->m;
  1915 #ifdef GLP_DEBUG
  1916       int n = csa->n;
  1917 #endif
  1918       char *type = csa->type;
  1919       int *head = csa->head;
  1920       char *refsp = csa->refsp;
  1921       double *gamma = csa->gamma;
  1922       int p = csa->p;
  1923       int trow_nnz = csa->trow_nnz;
  1924       int *trow_ind = csa->trow_ind;
  1925       double *trow_vec = csa->trow_vec;
  1926       int q = csa->q;
  1927       int tcol_nnz = csa->tcol_nnz;
  1928       int *tcol_ind = csa->tcol_ind;
  1929       double *tcol_vec = csa->tcol_vec;
  1930       double *u = csa->work3;
  1931       int i, j, k,pos;
  1932       double gamma_p, eta_p, pivot, t, t1, t2;
  1933 #ifdef GLP_DEBUG
  1934       xassert(1 <= p && p <= m);
  1935       xassert(1 <= q && q <= n);
  1936 #endif
  1937       /* the basis changes, so decrease the count */
  1938       xassert(csa->refct > 0);
  1939       csa->refct--;
  1940       /* recompute gamma[p] for the current basis more accurately and
  1941          compute auxiliary vector u */
  1942 #ifdef GLP_DEBUG
  1943       xassert(type[head[p]] != GLP_FR);
  1944 #endif
  1945       gamma_p = eta_p = (refsp[head[p]] ? 1.0 : 0.0);
  1946       for (i = 1; i <= m; i++) u[i] = 0.0;
  1947       for (pos = 1; pos <= trow_nnz; pos++)
  1948       {  j = trow_ind[pos];
  1949 #ifdef GLP_DEBUG
  1950          xassert(1 <= j && j <= n);
  1951 #endif
  1952          k = head[m+j]; /* x[k] = xN[j] */
  1953 #ifdef GLP_DEBUG
  1954          xassert(1 <= k && k <= m+n);
  1955          xassert(type[k] != GLP_FX);
  1956 #endif
  1957          if (!refsp[k]) continue;
  1958          t = trow_vec[j];
  1959          gamma_p += t * t;
  1960          /* u := u + N[j] * delta[j] * trow[j] */
  1961          if (k <= m)
  1962          {  /* N[k] = k-j stolbec submatrix I */
  1963             u[k] += t;
  1964          }
  1965          else
  1966          {  /* N[k] = k-m-k stolbec (-A) */
  1967             int *A_ptr = csa->A_ptr;
  1968             int *A_ind = csa->A_ind;
  1969             double *A_val = csa->A_val;
  1970             int beg, end, ptr;
  1971             beg = A_ptr[k-m];
  1972             end = A_ptr[k-m+1];
  1973             for (ptr = beg; ptr < end; ptr++)
  1974                u[A_ind[ptr]] -= t * A_val[ptr];
  1975          }
  1976       }
  1977       xassert(csa->valid);
  1978       bfd_ftran(csa->bfd, u);
  1979       /* update gamma[i] for other basic variables (except xB[p] and
  1980          free variables) */
  1981       pivot = tcol_vec[p];
  1982 #ifdef GLP_DEBUG
  1983       xassert(pivot != 0.0);
  1984 #endif
  1985       for (pos = 1; pos <= tcol_nnz; pos++)
  1986       {  i = tcol_ind[pos];
  1987 #ifdef GLP_DEBUG
  1988          xassert(1 <= i && i <= m);
  1989 #endif
  1990          k = head[i];
  1991 #ifdef GLP_DEBUG
  1992          xassert(1 <= k && k <= m+n);
  1993 #endif
  1994          /* skip xB[p] */
  1995          if (i == p) continue;
  1996          /* skip free basic variable */
  1997          if (type[head[i]] == GLP_FR)
  1998          {
  1999 #ifdef GLP_DEBUG
  2000             xassert(gamma[i] == 1.0);
  2001 #endif
  2002             continue;
  2003          }
  2004          /* compute gamma[i] for the adjacent basis */
  2005          t = tcol_vec[i] / pivot;
  2006          t1 = gamma[i] + t * t * gamma_p + 2.0 * t * u[i];
  2007          t2 = (refsp[k] ? 1.0 : 0.0) + eta_p * t * t;
  2008          gamma[i] = (t1 >= t2 ? t1 : t2);
  2009          /* (though gamma[i] can be exact zero, because the reference
  2010             space does not include non-basic fixed variables) */
  2011          if (gamma[i] < DBL_EPSILON) gamma[i] = DBL_EPSILON;
  2012       }
  2013       /* compute gamma[p] for the adjacent basis */
  2014       if (type[head[m+q]] == GLP_FR)
  2015          gamma[p] = 1.0;
  2016       else
  2017       {  gamma[p] = gamma_p / (pivot * pivot);
  2018          if (gamma[p] < DBL_EPSILON) gamma[p] = DBL_EPSILON;
  2019       }
  2020       /* if xB[p], which becomes xN[q] in the adjacent basis, is fixed
  2021          and belongs to the reference space, remove it from there, and
  2022          change all gamma's appropriately */
  2023       k = head[p];
  2024       if (type[k] == GLP_FX && refsp[k])
  2025       {  refsp[k] = 0;
  2026          for (pos = 1; pos <= tcol_nnz; pos++)
  2027          {  i = tcol_ind[pos];
  2028             if (i == p)
  2029             {  if (type[head[m+q]] == GLP_FR) continue;
  2030                t = 1.0 / tcol_vec[p];
  2031             }
  2032             else
  2033             {  if (type[head[i]] == GLP_FR) continue;
  2034                t = tcol_vec[i] / tcol_vec[p];
  2035             }
  2036             gamma[i] -= t * t;
  2037             if (gamma[i] < DBL_EPSILON) gamma[i] = DBL_EPSILON;
  2038          }
  2039       }
  2040       return;
  2041 }
  2042 
  2043 #if 1 /* copied from primal */
  2044 /***********************************************************************
  2045 *  err_in_bbar - compute maximal relative error in primal solution
  2046 *
  2047 *  This routine returns maximal relative error:
  2048 *
  2049 *     max |beta[i] - bbar[i]| / (1 + |beta[i]|),
  2050 *
  2051 *  where beta and bbar are, respectively, directly computed and the
  2052 *  current (updated) values of basic variables.
  2053 *
  2054 *  NOTE: The routine is intended only for debugginig purposes. */
  2055 
  2056 static double err_in_bbar(struct csa *csa)
  2057 {     int m = csa->m;
  2058       double *bbar = csa->bbar;
  2059       int i;
  2060       double e, emax, *beta;
  2061       beta = xcalloc(1+m, sizeof(double));
  2062       eval_beta(csa, beta);
  2063       emax = 0.0;
  2064       for (i = 1; i <= m; i++)
  2065       {  e = fabs(beta[i] - bbar[i]) / (1.0 + fabs(beta[i]));
  2066          if (emax < e) emax = e;
  2067       }
  2068       xfree(beta);
  2069       return emax;
  2070 }
  2071 #endif
  2072 
  2073 #if 1 /* copied from primal */
  2074 /***********************************************************************
  2075 *  err_in_cbar - compute maximal relative error in dual solution
  2076 *
  2077 *  This routine returns maximal relative error:
  2078 *
  2079 *     max |cost[j] - cbar[j]| / (1 + |cost[j]|),
  2080 *
  2081 *  where cost and cbar are, respectively, directly computed and the
  2082 *  current (updated) reduced costs of non-basic non-fixed variables.
  2083 *
  2084 *  NOTE: The routine is intended only for debugginig purposes. */
  2085 
  2086 static double err_in_cbar(struct csa *csa)
  2087 {     int m = csa->m;
  2088       int n = csa->n;
  2089       char *stat = csa->stat;
  2090       double *cbar = csa->cbar;
  2091       int j;
  2092       double e, emax, cost, *pi;
  2093       pi = xcalloc(1+m, sizeof(double));
  2094       eval_pi(csa, pi);
  2095       emax = 0.0;
  2096       for (j = 1; j <= n; j++)
  2097       {  if (stat[j] == GLP_NS) continue;
  2098          cost = eval_cost(csa, pi, j);
  2099          e = fabs(cost - cbar[j]) / (1.0 + fabs(cost));
  2100          if (emax < e) emax = e;
  2101       }
  2102       xfree(pi);
  2103       return emax;
  2104 }
  2105 #endif
  2106 
  2107 /***********************************************************************
  2108 *  err_in_gamma - compute maximal relative error in steepest edge cff.
  2109 *
  2110 *  This routine returns maximal relative error:
  2111 *
  2112 *     max |gamma'[j] - gamma[j]| / (1 + |gamma'[j]),
  2113 *
  2114 *  where gamma'[j] and gamma[j] are, respectively, directly computed
  2115 *  and the current (updated) steepest edge coefficients for non-basic
  2116 *  non-fixed variable x[j].
  2117 *
  2118 *  NOTE: The routine is intended only for debugginig purposes. */
  2119 
  2120 static double err_in_gamma(struct csa *csa)
  2121 {     int m = csa->m;
  2122       char *type = csa->type;
  2123       int *head = csa->head;
  2124       double *gamma = csa->gamma;
  2125       double *exact = csa->work4;
  2126       int i;
  2127       double e, emax, temp;
  2128       eval_gamma(csa, exact);
  2129       emax = 0.0;
  2130       for (i = 1; i <= m; i++)
  2131       {  if (type[head[i]] == GLP_FR)
  2132          {  xassert(gamma[i] == 1.0);
  2133             xassert(exact[i] == 1.0);
  2134             continue;
  2135          }
  2136          temp = exact[i];
  2137          e = fabs(temp - gamma[i]) / (1.0 + fabs(temp));
  2138          if (emax < e) emax = e;
  2139       }
  2140       return emax;
  2141 }
  2142 
  2143 /***********************************************************************
  2144 *  change_basis - change basis header
  2145 *
  2146 *  This routine changes the basis header to make it corresponding to
  2147 *  the adjacent basis. */
  2148 
  2149 static void change_basis(struct csa *csa)
  2150 {     int m = csa->m;
  2151 #ifdef GLP_DEBUG
  2152       int n = csa->n;
  2153 #endif
  2154       char *type = csa->type;
  2155       int *head = csa->head;
  2156 #if 1 /* 06/IV-2009 */
  2157       int *bind = csa->bind;
  2158 #endif
  2159       char *stat = csa->stat;
  2160       int p = csa->p;
  2161       double delta = csa->delta;
  2162       int q = csa->q;
  2163       int k;
  2164       /* xB[p] leaves the basis, xN[q] enters the basis */
  2165 #ifdef GLP_DEBUG
  2166       xassert(1 <= p && p <= m);
  2167       xassert(1 <= q && q <= n);
  2168 #endif
  2169       /* xB[p] <-> xN[q] */
  2170       k = head[p], head[p] = head[m+q], head[m+q] = k;
  2171 #if 1 /* 06/IV-2009 */
  2172       bind[head[p]] = p, bind[head[m+q]] = m + q;
  2173 #endif
  2174       if (type[k] == GLP_FX)
  2175          stat[q] = GLP_NS;
  2176       else if (delta > 0.0)
  2177       {
  2178 #ifdef GLP_DEBUG
  2179          xassert(type[k] == GLP_LO || type[k] == GLP_DB);
  2180 #endif
  2181          stat[q] = GLP_NL;
  2182       }
  2183       else /* delta < 0.0 */
  2184       {
  2185 #ifdef GLP_DEBUG
  2186          xassert(type[k] == GLP_UP || type[k] == GLP_DB);
  2187 #endif
  2188          stat[q] = GLP_NU;
  2189       }
  2190       return;
  2191 }
  2192 
  2193 /***********************************************************************
  2194 *  check_feas - check dual feasibility of basic solution
  2195 *
  2196 *  If the current basic solution is dual feasible within a tolerance,
  2197 *  this routine returns zero, otherwise it returns non-zero. */
  2198 
  2199 static int check_feas(struct csa *csa, double tol_dj)
  2200 {     int m = csa->m;
  2201       int n = csa->n;
  2202       char *orig_type = csa->orig_type;
  2203       int *head = csa->head;
  2204       double *cbar = csa->cbar;
  2205       int j, k;
  2206       for (j = 1; j <= n; j++)
  2207       {  k = head[m+j]; /* x[k] = xN[j] */
  2208 #ifdef GLP_DEBUG
  2209          xassert(1 <= k && k <= m+n);
  2210 #endif
  2211          if (cbar[j] < - tol_dj)
  2212             if (orig_type[k] == GLP_LO || orig_type[k] == GLP_FR)
  2213                return 1;
  2214          if (cbar[j] > + tol_dj)
  2215             if (orig_type[k] == GLP_UP || orig_type[k] == GLP_FR)
  2216                return 1;
  2217       }
  2218       return 0;
  2219 }
  2220 
  2221 /***********************************************************************
  2222 *  set_aux_bnds - assign auxiliary bounds to variables
  2223 *
  2224 *  This routine assigns auxiliary bounds to variables to construct an
  2225 *  LP problem solved on phase I. */
  2226 
  2227 static void set_aux_bnds(struct csa *csa)
  2228 {     int m = csa->m;
  2229       int n = csa->n;
  2230       char *type = csa->type;
  2231       double *lb = csa->lb;
  2232       double *ub = csa->ub;
  2233       char *orig_type = csa->orig_type;
  2234       int *head = csa->head;
  2235       char *stat = csa->stat;
  2236       double *cbar = csa->cbar;
  2237       int j, k;
  2238       for (k = 1; k <= m+n; k++)
  2239       {  switch (orig_type[k])
  2240          {  case GLP_FR:
  2241 #if 0
  2242                type[k] = GLP_DB, lb[k] = -1.0, ub[k] = +1.0;
  2243 #else
  2244                /* to force free variables to enter the basis */
  2245                type[k] = GLP_DB, lb[k] = -1e3, ub[k] = +1e3;
  2246 #endif
  2247                break;
  2248             case GLP_LO:
  2249                type[k] = GLP_DB, lb[k] = 0.0, ub[k] = +1.0;
  2250                break;
  2251             case GLP_UP:
  2252                type[k] = GLP_DB, lb[k] = -1.0, ub[k] = 0.0;
  2253                break;
  2254             case GLP_DB:
  2255             case GLP_FX:
  2256                type[k] = GLP_FX, lb[k] = ub[k] = 0.0;
  2257                break;
  2258             default:
  2259                xassert(orig_type != orig_type);
  2260          }
  2261       }
  2262       for (j = 1; j <= n; j++)
  2263       {  k = head[m+j]; /* x[k] = xN[j] */
  2264 #ifdef GLP_DEBUG
  2265          xassert(1 <= k && k <= m+n);
  2266 #endif
  2267          if (type[k] == GLP_FX)
  2268             stat[j] = GLP_NS;
  2269          else if (cbar[j] >= 0.0)
  2270             stat[j] = GLP_NL;
  2271          else
  2272             stat[j] = GLP_NU;
  2273       }
  2274       return;
  2275 }
  2276 
  2277 /***********************************************************************
  2278 *  set_orig_bnds - restore original bounds of variables
  2279 *
  2280 *  This routine restores original types and bounds of variables and
  2281 *  determines statuses of non-basic variables assuming that the current
  2282 *  basis is dual feasible. */
  2283 
  2284 static void set_orig_bnds(struct csa *csa)
  2285 {     int m = csa->m;
  2286       int n = csa->n;
  2287       char *type = csa->type;
  2288       double *lb = csa->lb;
  2289       double *ub = csa->ub;
  2290       char *orig_type = csa->orig_type;
  2291       double *orig_lb = csa->orig_lb;
  2292       double *orig_ub = csa->orig_ub;
  2293       int *head = csa->head;
  2294       char *stat = csa->stat;
  2295       double *cbar = csa->cbar;
  2296       int j, k;
  2297       memcpy(&type[1], &orig_type[1], (m+n) * sizeof(char));
  2298       memcpy(&lb[1], &orig_lb[1], (m+n) * sizeof(double));
  2299       memcpy(&ub[1], &orig_ub[1], (m+n) * sizeof(double));
  2300       for (j = 1; j <= n; j++)
  2301       {  k = head[m+j]; /* x[k] = xN[j] */
  2302 #ifdef GLP_DEBUG
  2303          xassert(1 <= k && k <= m+n);
  2304 #endif
  2305          switch (type[k])
  2306          {  case GLP_FR:
  2307                stat[j] = GLP_NF;
  2308                break;
  2309             case GLP_LO:
  2310                stat[j] = GLP_NL;
  2311                break;
  2312             case GLP_UP:
  2313                stat[j] = GLP_NU;
  2314                break;
  2315             case GLP_DB:
  2316                if (cbar[j] >= +DBL_EPSILON)
  2317                   stat[j] = GLP_NL;
  2318                else if (cbar[j] <= -DBL_EPSILON)
  2319                   stat[j] = GLP_NU;
  2320                else if (fabs(lb[k]) <= fabs(ub[k]))
  2321                   stat[j] = GLP_NL;
  2322                else
  2323                   stat[j] = GLP_NU;
  2324                break;
  2325             case GLP_FX:
  2326                stat[j] = GLP_NS;
  2327                break;
  2328             default:
  2329                xassert(type != type);
  2330          }
  2331       }
  2332       return;
  2333 }
  2334 
  2335 /***********************************************************************
  2336 *  check_stab - check numerical stability of basic solution
  2337 *
  2338 *  If the current basic solution is dual feasible within a tolerance,
  2339 *  this routine returns zero, otherwise it returns non-zero. */
  2340 
  2341 static int check_stab(struct csa *csa, double tol_dj)
  2342 {     int n = csa->n;
  2343       char *stat = csa->stat;
  2344       double *cbar = csa->cbar;
  2345       int j;
  2346       for (j = 1; j <= n; j++)
  2347       {  if (cbar[j] < - tol_dj)
  2348             if (stat[j] == GLP_NL || stat[j] == GLP_NF) return 1;
  2349          if (cbar[j] > + tol_dj)
  2350             if (stat[j] == GLP_NU || stat[j] == GLP_NF) return 1;
  2351       }
  2352       return 0;
  2353 }
  2354 
  2355 #if 1 /* copied from primal */
  2356 /***********************************************************************
  2357 *  eval_obj - compute original objective function
  2358 *
  2359 *  This routine computes the current value of the original objective
  2360 *  function. */
  2361 
  2362 static double eval_obj(struct csa *csa)
  2363 {     int m = csa->m;
  2364       int n = csa->n;
  2365       double *obj = csa->obj;
  2366       int *head = csa->head;
  2367       double *bbar = csa->bbar;
  2368       int i, j, k;
  2369       double sum;
  2370       sum = obj[0];
  2371       /* walk through the list of basic variables */
  2372       for (i = 1; i <= m; i++)
  2373       {  k = head[i]; /* x[k] = xB[i] */
  2374 #ifdef GLP_DEBUG
  2375          xassert(1 <= k && k <= m+n);
  2376 #endif
  2377          if (k > m)
  2378             sum += obj[k-m] * bbar[i];
  2379       }
  2380       /* walk through the list of non-basic variables */
  2381       for (j = 1; j <= n; j++)
  2382       {  k = head[m+j]; /* x[k] = xN[j] */
  2383 #ifdef GLP_DEBUG
  2384          xassert(1 <= k && k <= m+n);
  2385 #endif
  2386          if (k > m)
  2387             sum += obj[k-m] * get_xN(csa, j);
  2388       }
  2389       return sum;
  2390 }
  2391 #endif
  2392 
  2393 /***********************************************************************
  2394 *  display - display the search progress
  2395 *
  2396 *  This routine displays some information about the search progress. */
  2397 
  2398 static void display(struct csa *csa, const glp_smcp *parm, int spec)
  2399 {     int m = csa->m;
  2400       int n = csa->n;
  2401       double *coef = csa->coef;
  2402       char *orig_type = csa->orig_type;
  2403       int *head = csa->head;
  2404       char *stat = csa->stat;
  2405       int phase = csa->phase;
  2406       double *bbar = csa->bbar;
  2407       double *cbar = csa->cbar;
  2408       int i, j, cnt;
  2409       double sum;
  2410       if (parm->msg_lev < GLP_MSG_ON) goto skip;
  2411       if (parm->out_dly > 0 &&
  2412          1000.0 * xdifftime(xtime(), csa->tm_beg) < parm->out_dly)
  2413          goto skip;
  2414       if (csa->it_cnt == csa->it_dpy) goto skip;
  2415       if (!spec && csa->it_cnt % parm->out_frq != 0) goto skip;
  2416       /* compute the sum of dual infeasibilities */
  2417       sum = 0.0;
  2418       if (phase == 1)
  2419       {  for (i = 1; i <= m; i++)
  2420             sum -= coef[head[i]] * bbar[i];
  2421          for (j = 1; j <= n; j++)
  2422             sum -= coef[head[m+j]] * get_xN(csa, j);
  2423       }
  2424       else
  2425       {  for (j = 1; j <= n; j++)
  2426          {  if (cbar[j] < 0.0)
  2427                if (stat[j] == GLP_NL || stat[j] == GLP_NF)
  2428                   sum -= cbar[j];
  2429             if (cbar[j] > 0.0)
  2430                if (stat[j] == GLP_NU || stat[j] == GLP_NF)
  2431                   sum += cbar[j];
  2432          }
  2433       }
  2434       /* determine the number of basic fixed variables */
  2435       cnt = 0;
  2436       for (i = 1; i <= m; i++)
  2437          if (orig_type[head[i]] == GLP_FX) cnt++;
  2438       if (csa->phase == 1)
  2439          xprintf(" %6d: %24s infeas = %10.3e (%d)\n",
  2440             csa->it_cnt, "", sum, cnt);
  2441       else
  2442          xprintf("|%6d: obj = %17.9e  infeas = %10.3e (%d)\n",
  2443             csa->it_cnt, eval_obj(csa), sum, cnt);
  2444       csa->it_dpy = csa->it_cnt;
  2445 skip: return;
  2446 }
  2447 
  2448 #if 1 /* copied from primal */
  2449 /***********************************************************************
  2450 *  store_sol - store basic solution back to the problem object
  2451 *
  2452 *  This routine stores basic solution components back to the problem
  2453 *  object. */
  2454 
  2455 static void store_sol(struct csa *csa, glp_prob *lp, int p_stat,
  2456       int d_stat, int ray)
  2457 {     int m = csa->m;
  2458       int n = csa->n;
  2459       double zeta = csa->zeta;
  2460       int *head = csa->head;
  2461       char *stat = csa->stat;
  2462       double *bbar = csa->bbar;
  2463       double *cbar = csa->cbar;
  2464       int i, j, k;
  2465 #ifdef GLP_DEBUG
  2466       xassert(lp->m == m);
  2467       xassert(lp->n == n);
  2468 #endif
  2469       /* basis factorization */
  2470 #ifdef GLP_DEBUG
  2471       xassert(!lp->valid && lp->bfd == NULL);
  2472       xassert(csa->valid && csa->bfd != NULL);
  2473 #endif
  2474       lp->valid = 1, csa->valid = 0;
  2475       lp->bfd = csa->bfd, csa->bfd = NULL;
  2476       memcpy(&lp->head[1], &head[1], m * sizeof(int));
  2477       /* basic solution status */
  2478       lp->pbs_stat = p_stat;
  2479       lp->dbs_stat = d_stat;
  2480       /* objective function value */
  2481       lp->obj_val = eval_obj(csa);
  2482       /* simplex iteration count */
  2483       lp->it_cnt = csa->it_cnt;
  2484       /* unbounded ray */
  2485       lp->some = ray;
  2486       /* basic variables */
  2487       for (i = 1; i <= m; i++)
  2488       {  k = head[i]; /* x[k] = xB[i] */
  2489 #ifdef GLP_DEBUG
  2490          xassert(1 <= k && k <= m+n);
  2491 #endif
  2492          if (k <= m)
  2493          {  GLPROW *row = lp->row[k];
  2494             row->stat = GLP_BS;
  2495             row->bind = i;
  2496             row->prim = bbar[i] / row->rii;
  2497             row->dual = 0.0;
  2498          }
  2499          else
  2500          {  GLPCOL *col = lp->col[k-m];
  2501             col->stat = GLP_BS;
  2502             col->bind = i;
  2503             col->prim = bbar[i] * col->sjj;
  2504             col->dual = 0.0;
  2505          }
  2506       }
  2507       /* non-basic variables */
  2508       for (j = 1; j <= n; j++)
  2509       {  k = head[m+j]; /* x[k] = xN[j] */
  2510 #ifdef GLP_DEBUG
  2511          xassert(1 <= k && k <= m+n);
  2512 #endif
  2513          if (k <= m)
  2514          {  GLPROW *row = lp->row[k];
  2515             row->stat = stat[j];
  2516             row->bind = 0;
  2517 #if 0
  2518             row->prim = get_xN(csa, j) / row->rii;
  2519 #else
  2520             switch (stat[j])
  2521             {  case GLP_NL:
  2522                   row->prim = row->lb; break;
  2523                case GLP_NU:
  2524                   row->prim = row->ub; break;
  2525                case GLP_NF:
  2526                   row->prim = 0.0; break;
  2527                case GLP_NS:
  2528                   row->prim = row->lb; break;
  2529                default:
  2530                   xassert(stat != stat);
  2531             }
  2532 #endif
  2533             row->dual = (cbar[j] * row->rii) / zeta;
  2534          }
  2535          else
  2536          {  GLPCOL *col = lp->col[k-m];
  2537             col->stat = stat[j];
  2538             col->bind = 0;
  2539 #if 0
  2540             col->prim = get_xN(csa, j) * col->sjj;
  2541 #else
  2542             switch (stat[j])
  2543             {  case GLP_NL:
  2544                   col->prim = col->lb; break;
  2545                case GLP_NU:
  2546                   col->prim = col->ub; break;
  2547                case GLP_NF:
  2548                   col->prim = 0.0; break;
  2549                case GLP_NS:
  2550                   col->prim = col->lb; break;
  2551                default:
  2552                   xassert(stat != stat);
  2553             }
  2554 #endif
  2555             col->dual = (cbar[j] / col->sjj) / zeta;
  2556          }
  2557       }
  2558       return;
  2559 }
  2560 #endif
  2561 
  2562 /***********************************************************************
  2563 *  free_csa - deallocate common storage area
  2564 *
  2565 *  This routine frees all the memory allocated to arrays in the common
  2566 *  storage area (CSA). */
  2567 
  2568 static void free_csa(struct csa *csa)
  2569 {     xfree(csa->type);
  2570       xfree(csa->lb);
  2571       xfree(csa->ub);
  2572       xfree(csa->coef);
  2573       xfree(csa->orig_type);
  2574       xfree(csa->orig_lb);
  2575       xfree(csa->orig_ub);
  2576       xfree(csa->obj);
  2577       xfree(csa->A_ptr);
  2578       xfree(csa->A_ind);
  2579       xfree(csa->A_val);
  2580 #if 1 /* 06/IV-2009 */
  2581       xfree(csa->AT_ptr);
  2582       xfree(csa->AT_ind);
  2583       xfree(csa->AT_val);
  2584 #endif
  2585       xfree(csa->head);
  2586 #if 1 /* 06/IV-2009 */
  2587       xfree(csa->bind);
  2588 #endif
  2589       xfree(csa->stat);
  2590 #if 0 /* 06/IV-2009 */
  2591       xfree(csa->N_ptr);
  2592       xfree(csa->N_len);
  2593       xfree(csa->N_ind);
  2594       xfree(csa->N_val);
  2595 #endif
  2596       xfree(csa->bbar);
  2597       xfree(csa->cbar);
  2598       xfree(csa->refsp);
  2599       xfree(csa->gamma);
  2600       xfree(csa->trow_ind);
  2601       xfree(csa->trow_vec);
  2602 #ifdef GLP_LONG_STEP /* 07/IV-2009 */
  2603       xfree(csa->bkpt);
  2604 #endif
  2605       xfree(csa->tcol_ind);
  2606       xfree(csa->tcol_vec);
  2607       xfree(csa->work1);
  2608       xfree(csa->work2);
  2609       xfree(csa->work3);
  2610       xfree(csa->work4);
  2611       xfree(csa);
  2612       return;
  2613 }
  2614 
  2615 /***********************************************************************
  2616 *  spx_dual - core LP solver based on the dual simplex method
  2617 *
  2618 *  SYNOPSIS
  2619 *
  2620 *  #include "glpspx.h"
  2621 *  int spx_dual(glp_prob *lp, const glp_smcp *parm);
  2622 *
  2623 *  DESCRIPTION
  2624 *
  2625 *  The routine spx_dual is a core LP solver based on the two-phase dual
  2626 *  simplex method.
  2627 *
  2628 *  RETURNS
  2629 *
  2630 *  0  LP instance has been successfully solved.
  2631 *
  2632 *  GLP_EOBJLL
  2633 *     Objective lower limit has been reached (maximization).
  2634 *
  2635 *  GLP_EOBJUL
  2636 *     Objective upper limit has been reached (minimization).
  2637 *
  2638 *  GLP_EITLIM
  2639 *     Iteration limit has been exhausted.
  2640 *
  2641 *  GLP_ETMLIM
  2642 *     Time limit has been exhausted.
  2643 *
  2644 *  GLP_EFAIL
  2645 *     The solver failed to solve LP instance. */
  2646 
  2647 int spx_dual(glp_prob *lp, const glp_smcp *parm)
  2648 {     struct csa *csa;
  2649       int binv_st = 2;
  2650       /* status of basis matrix factorization:
  2651          0 - invalid; 1 - just computed; 2 - updated */
  2652       int bbar_st = 0;
  2653       /* status of primal values of basic variables:
  2654          0 - invalid; 1 - just computed; 2 - updated */
  2655       int cbar_st = 0;
  2656       /* status of reduced costs of non-basic variables:
  2657          0 - invalid; 1 - just computed; 2 - updated */
  2658       int rigorous = 0;
  2659       /* rigorous mode flag; this flag is used to enable iterative
  2660          refinement on computing pivot rows and columns of the simplex
  2661          table */
  2662       int check = 0;
  2663       int p_stat, d_stat, ret;
  2664       /* allocate and initialize the common storage area */
  2665       csa = alloc_csa(lp);
  2666       init_csa(csa, lp);
  2667       if (parm->msg_lev >= GLP_MSG_DBG)
  2668          xprintf("Objective scale factor = %g\n", csa->zeta);
  2669 loop: /* main loop starts here */
  2670       /* compute factorization of the basis matrix */
  2671       if (binv_st == 0)
  2672       {  ret = invert_B(csa);
  2673          if (ret != 0)
  2674          {  if (parm->msg_lev >= GLP_MSG_ERR)
  2675             {  xprintf("Error: unable to factorize the basis matrix (%d"
  2676                   ")\n", ret);
  2677                xprintf("Sorry, basis recovery procedure not implemented"
  2678                   " yet\n");
  2679             }
  2680             xassert(!lp->valid && lp->bfd == NULL);
  2681             lp->bfd = csa->bfd, csa->bfd = NULL;
  2682             lp->pbs_stat = lp->dbs_stat = GLP_UNDEF;
  2683             lp->obj_val = 0.0;
  2684             lp->it_cnt = csa->it_cnt;
  2685             lp->some = 0;
  2686             ret = GLP_EFAIL;
  2687             goto done;
  2688          }
  2689          csa->valid = 1;
  2690          binv_st = 1; /* just computed */
  2691          /* invalidate basic solution components */
  2692          bbar_st = cbar_st = 0;
  2693       }
  2694       /* compute reduced costs of non-basic variables */
  2695       if (cbar_st == 0)
  2696       {  eval_cbar(csa);
  2697          cbar_st = 1; /* just computed */
  2698          /* determine the search phase, if not determined yet */
  2699          if (csa->phase == 0)
  2700          {  if (check_feas(csa, 0.90 * parm->tol_dj) != 0)
  2701             {  /* current basic solution is dual infeasible */
  2702                /* start searching for dual feasible solution */
  2703                csa->phase = 1;
  2704                set_aux_bnds(csa);
  2705             }
  2706             else
  2707             {  /* current basic solution is dual feasible */
  2708                /* start searching for optimal solution */
  2709                csa->phase = 2;
  2710                set_orig_bnds(csa);
  2711             }
  2712             xassert(check_stab(csa, parm->tol_dj) == 0);
  2713             /* some non-basic double-bounded variables might become
  2714                fixed (on phase I) or vice versa (on phase II) */
  2715 #if 0 /* 06/IV-2009 */
  2716             build_N(csa);
  2717 #endif
  2718             csa->refct = 0;
  2719             /* bounds of non-basic variables have been changed, so
  2720                invalidate primal values */
  2721             bbar_st = 0;
  2722          }
  2723          /* make sure that the current basic solution remains dual
  2724             feasible */
  2725          if (check_stab(csa, parm->tol_dj) != 0)
  2726          {  if (parm->msg_lev >= GLP_MSG_ERR)
  2727                xprintf("Warning: numerical instability (dual simplex, p"
  2728                   "hase %s)\n", csa->phase == 1 ? "I" : "II");
  2729 #if 1
  2730             if (parm->meth == GLP_DUALP)
  2731             {  store_sol(csa, lp, GLP_UNDEF, GLP_UNDEF, 0);
  2732                ret = GLP_EFAIL;
  2733                goto done;
  2734             }
  2735 #endif
  2736             /* restart the search */
  2737             csa->phase = 0;
  2738             binv_st = 0;
  2739             rigorous = 5;
  2740             goto loop;
  2741          }
  2742       }
  2743       xassert(csa->phase == 1 || csa->phase == 2);
  2744       /* on phase I we do not need to wait until the current basic
  2745          solution becomes primal feasible; it is sufficient to make
  2746          sure that all reduced costs have correct signs */
  2747       if (csa->phase == 1 && check_feas(csa, parm->tol_dj) == 0)
  2748       {  /* the current basis is dual feasible; switch to phase II */
  2749          display(csa, parm, 1);
  2750          csa->phase = 2;
  2751          if (cbar_st != 1)
  2752          {  eval_cbar(csa);
  2753             cbar_st = 1;
  2754          }
  2755          set_orig_bnds(csa);
  2756 #if 0 /* 06/IV-2009 */
  2757          build_N(csa);
  2758 #endif
  2759          csa->refct = 0;
  2760          bbar_st = 0;
  2761       }
  2762       /* compute primal values of basic variables */
  2763       if (bbar_st == 0)
  2764       {  eval_bbar(csa);
  2765          if (csa->phase == 2)
  2766             csa->bbar[0] = eval_obj(csa);
  2767          bbar_st = 1; /* just computed */
  2768       }
  2769       /* redefine the reference space, if required */
  2770       switch (parm->pricing)
  2771       {  case GLP_PT_STD:
  2772             break;
  2773          case GLP_PT_PSE:
  2774             if (csa->refct == 0) reset_refsp(csa);
  2775             break;
  2776          default:
  2777             xassert(parm != parm);
  2778       }
  2779       /* at this point the basis factorization and all basic solution
  2780          components are valid */
  2781       xassert(binv_st && bbar_st && cbar_st);
  2782       /* check accuracy of current basic solution components (only for
  2783          debugging) */
  2784       if (check)
  2785       {  double e_bbar = err_in_bbar(csa);
  2786          double e_cbar = err_in_cbar(csa);
  2787          double e_gamma =
  2788             (parm->pricing == GLP_PT_PSE ? err_in_gamma(csa) : 0.0);
  2789          xprintf("e_bbar = %10.3e; e_cbar = %10.3e; e_gamma = %10.3e\n",
  2790             e_bbar, e_cbar, e_gamma);
  2791          xassert(e_bbar <= 1e-5 && e_cbar <= 1e-5 && e_gamma <= 1e-3);
  2792       }
  2793       /* if the objective has to be maximized, check if it has reached
  2794          its lower limit */
  2795       if (csa->phase == 2 && csa->zeta < 0.0 &&
  2796           parm->obj_ll > -DBL_MAX && csa->bbar[0] <= parm->obj_ll)
  2797       {  if (bbar_st != 1 || cbar_st != 1)
  2798          {  if (bbar_st != 1) bbar_st = 0;
  2799             if (cbar_st != 1) cbar_st = 0;
  2800             goto loop;
  2801          }
  2802          display(csa, parm, 1);
  2803          if (parm->msg_lev >= GLP_MSG_ALL)
  2804             xprintf("OBJECTIVE LOWER LIMIT REACHED; SEARCH TERMINATED\n"
  2805                );
  2806          store_sol(csa, lp, GLP_INFEAS, GLP_FEAS, 0);
  2807          ret = GLP_EOBJLL;
  2808          goto done;
  2809       }
  2810       /* if the objective has to be minimized, check if it has reached
  2811          its upper limit */
  2812       if (csa->phase == 2 && csa->zeta > 0.0 &&
  2813           parm->obj_ul < +DBL_MAX && csa->bbar[0] >= parm->obj_ul)
  2814       {  if (bbar_st != 1 || cbar_st != 1)
  2815          {  if (bbar_st != 1) bbar_st = 0;
  2816             if (cbar_st != 1) cbar_st = 0;
  2817             goto loop;
  2818          }
  2819          display(csa, parm, 1);
  2820          if (parm->msg_lev >= GLP_MSG_ALL)
  2821             xprintf("OBJECTIVE UPPER LIMIT REACHED; SEARCH TERMINATED\n"
  2822                );
  2823          store_sol(csa, lp, GLP_INFEAS, GLP_FEAS, 0);
  2824          ret = GLP_EOBJUL;
  2825          goto done;
  2826       }
  2827       /* check if the iteration limit has been exhausted */
  2828       if (parm->it_lim < INT_MAX &&
  2829           csa->it_cnt - csa->it_beg >= parm->it_lim)
  2830       {  if (csa->phase == 2 && bbar_st != 1 || cbar_st != 1)
  2831          {  if (csa->phase == 2 && bbar_st != 1) bbar_st = 0;
  2832             if (cbar_st != 1) cbar_st = 0;
  2833             goto loop;
  2834          }
  2835          display(csa, parm, 1);
  2836          if (parm->msg_lev >= GLP_MSG_ALL)
  2837             xprintf("ITERATION LIMIT EXCEEDED; SEARCH TERMINATED\n");
  2838          switch (csa->phase)
  2839          {  case 1:
  2840                d_stat = GLP_INFEAS;
  2841                set_orig_bnds(csa);
  2842                eval_bbar(csa);
  2843                break;
  2844             case 2:
  2845                d_stat = GLP_FEAS;
  2846                break;
  2847             default:
  2848                xassert(csa != csa);
  2849          }
  2850          store_sol(csa, lp, GLP_INFEAS, d_stat, 0);
  2851          ret = GLP_EITLIM;
  2852          goto done;
  2853       }
  2854       /* check if the time limit has been exhausted */
  2855       if (parm->tm_lim < INT_MAX &&
  2856           1000.0 * xdifftime(xtime(), csa->tm_beg) >= parm->tm_lim)
  2857       {  if (csa->phase == 2 && bbar_st != 1 || cbar_st != 1)
  2858          {  if (csa->phase == 2 && bbar_st != 1) bbar_st = 0;
  2859             if (cbar_st != 1) cbar_st = 0;
  2860             goto loop;
  2861          }
  2862          display(csa, parm, 1);
  2863          if (parm->msg_lev >= GLP_MSG_ALL)
  2864             xprintf("TIME LIMIT EXCEEDED; SEARCH TERMINATED\n");
  2865          switch (csa->phase)
  2866          {  case 1:
  2867                d_stat = GLP_INFEAS;
  2868                set_orig_bnds(csa);
  2869                eval_bbar(csa);
  2870                break;
  2871             case 2:
  2872                d_stat = GLP_FEAS;
  2873                break;
  2874             default:
  2875                xassert(csa != csa);
  2876          }
  2877          store_sol(csa, lp, GLP_INFEAS, d_stat, 0);
  2878          ret = GLP_ETMLIM;
  2879          goto done;
  2880       }
  2881       /* display the search progress */
  2882       display(csa, parm, 0);
  2883       /* choose basic variable xB[p] */
  2884       chuzr(csa, parm->tol_bnd);
  2885       if (csa->p == 0)
  2886       {  if (bbar_st != 1 || cbar_st != 1)
  2887          {  if (bbar_st != 1) bbar_st = 0;
  2888             if (cbar_st != 1) cbar_st = 0;
  2889             goto loop;
  2890          }
  2891          display(csa, parm, 1);
  2892          switch (csa->phase)
  2893          {  case 1:
  2894                if (parm->msg_lev >= GLP_MSG_ALL)
  2895                   xprintf("PROBLEM HAS NO DUAL FEASIBLE SOLUTION\n");
  2896                set_orig_bnds(csa);
  2897                eval_bbar(csa);
  2898                p_stat = GLP_INFEAS, d_stat = GLP_NOFEAS;
  2899                break;
  2900             case 2:
  2901                if (parm->msg_lev >= GLP_MSG_ALL)
  2902                   xprintf("OPTIMAL SOLUTION FOUND\n");
  2903                p_stat = d_stat = GLP_FEAS;
  2904                break;
  2905             default:
  2906                xassert(csa != csa);
  2907          }
  2908          store_sol(csa, lp, p_stat, d_stat, 0);
  2909          ret = 0;
  2910          goto done;
  2911       }
  2912       /* compute pivot row of the simplex table */
  2913       {  double *rho = csa->work4;
  2914          eval_rho(csa, rho);
  2915          if (rigorous) refine_rho(csa, rho);
  2916          eval_trow(csa, rho);
  2917          sort_trow(csa, parm->tol_bnd);
  2918       }
  2919       /* unlike primal simplex there is no need to check accuracy of
  2920          the primal value of xB[p] (which might be computed using the
  2921          pivot row), since bbar is a result of FTRAN */
  2922 #ifdef GLP_LONG_STEP /* 07/IV-2009 */
  2923       long_step(csa);
  2924       if (csa->nbps > 0)
  2925       {  csa->q = csa->bkpt[csa->nbps].j;
  2926          if (csa->delta > 0.0)
  2927             csa->new_dq = + csa->bkpt[csa->nbps].t;
  2928          else
  2929             csa->new_dq = - csa->bkpt[csa->nbps].t;
  2930       }
  2931       else
  2932 #endif
  2933       /* choose non-basic variable xN[q] */
  2934       switch (parm->r_test)
  2935       {  case GLP_RT_STD:
  2936             chuzc(csa, 0.0);
  2937             break;
  2938          case GLP_RT_HAR:
  2939             chuzc(csa, 0.30 * parm->tol_dj);
  2940             break;
  2941          default:
  2942             xassert(parm != parm);
  2943       }
  2944       if (csa->q == 0)
  2945       {  if (bbar_st != 1 || cbar_st != 1 || !rigorous)
  2946          {  if (bbar_st != 1) bbar_st = 0;
  2947             if (cbar_st != 1) cbar_st = 0;
  2948             rigorous = 1;
  2949             goto loop;
  2950          }
  2951          display(csa, parm, 1);
  2952          switch (csa->phase)
  2953          {  case 1:
  2954                if (parm->msg_lev >= GLP_MSG_ERR)
  2955                   xprintf("Error: unable to choose basic variable on ph"
  2956                      "ase I\n");
  2957                xassert(!lp->valid && lp->bfd == NULL);
  2958                lp->bfd = csa->bfd, csa->bfd = NULL;
  2959                lp->pbs_stat = lp->dbs_stat = GLP_UNDEF;
  2960                lp->obj_val = 0.0;
  2961                lp->it_cnt = csa->it_cnt;
  2962                lp->some = 0;
  2963                ret = GLP_EFAIL;
  2964                break;
  2965             case 2:
  2966                if (parm->msg_lev >= GLP_MSG_ALL)
  2967                   xprintf("PROBLEM HAS NO FEASIBLE SOLUTION\n");
  2968                store_sol(csa, lp, GLP_NOFEAS, GLP_FEAS,
  2969                   csa->head[csa->p]);
  2970                ret = 0;
  2971                break;
  2972             default:
  2973                xassert(csa != csa);
  2974          }
  2975          goto done;
  2976       }
  2977       /* check if the pivot element is acceptable */
  2978       {  double piv = csa->trow_vec[csa->q];
  2979          double eps = 1e-5 * (1.0 + 0.01 * csa->trow_max);
  2980          if (fabs(piv) < eps)
  2981          {  if (parm->msg_lev >= GLP_MSG_DBG)
  2982                xprintf("piv = %.12g; eps = %g\n", piv, eps);
  2983             if (!rigorous)
  2984             {  rigorous = 5;
  2985                goto loop;
  2986             }
  2987          }
  2988       }
  2989       /* now xN[q] and xB[p] have been chosen anyhow */
  2990       /* compute pivot column of the simplex table */
  2991       eval_tcol(csa);
  2992       if (rigorous) refine_tcol(csa);
  2993       /* accuracy check based on the pivot element */
  2994       {  double piv1 = csa->tcol_vec[csa->p]; /* more accurate */
  2995          double piv2 = csa->trow_vec[csa->q]; /* less accurate */
  2996          xassert(piv1 != 0.0);
  2997          if (fabs(piv1 - piv2) > 1e-8 * (1.0 + fabs(piv1)) ||
  2998              !(piv1 > 0.0 && piv2 > 0.0 || piv1 < 0.0 && piv2 < 0.0))
  2999          {  if (parm->msg_lev >= GLP_MSG_DBG)
  3000                xprintf("piv1 = %.12g; piv2 = %.12g\n", piv1, piv2);
  3001             if (binv_st != 1 || !rigorous)
  3002             {  if (binv_st != 1) binv_st = 0;
  3003                rigorous = 5;
  3004                goto loop;
  3005             }
  3006             /* (not a good idea; should be revised later) */
  3007             if (csa->tcol_vec[csa->p] == 0.0)
  3008             {  csa->tcol_nnz++;
  3009                xassert(csa->tcol_nnz <= csa->m);
  3010                csa->tcol_ind[csa->tcol_nnz] = csa->p;
  3011             }
  3012             csa->tcol_vec[csa->p] = piv2;
  3013          }
  3014       }
  3015       /* update primal values of basic variables */
  3016 #ifdef GLP_LONG_STEP /* 07/IV-2009 */
  3017       if (csa->nbps > 0)
  3018       {  int kk, j, k;
  3019          for (kk = 1; kk < csa->nbps; kk++)
  3020          {  if (csa->bkpt[kk].t >= csa->bkpt[csa->nbps].t) continue;
  3021             j = csa->bkpt[kk].j;
  3022             k = csa->head[csa->m + j];
  3023             xassert(csa->type[k] == GLP_DB);
  3024             if (csa->stat[j] == GLP_NL)
  3025                csa->stat[j] = GLP_NU;
  3026             else
  3027                csa->stat[j] = GLP_NL;
  3028          }
  3029       }
  3030       bbar_st = 0;
  3031 #else
  3032       update_bbar(csa);
  3033       if (csa->phase == 2)
  3034          csa->bbar[0] += (csa->cbar[csa->q] / csa->zeta) *
  3035             (csa->delta / csa->tcol_vec[csa->p]);
  3036       bbar_st = 2; /* updated */
  3037 #endif
  3038       /* update reduced costs of non-basic variables */
  3039       update_cbar(csa);
  3040       cbar_st = 2; /* updated */
  3041       /* update steepest edge coefficients */
  3042       switch (parm->pricing)
  3043       {  case GLP_PT_STD:
  3044             break;
  3045          case GLP_PT_PSE:
  3046             if (csa->refct > 0) update_gamma(csa);
  3047             break;
  3048          default:
  3049             xassert(parm != parm);
  3050       }
  3051       /* update factorization of the basis matrix */
  3052       ret = update_B(csa, csa->p, csa->head[csa->m+csa->q]);
  3053       if (ret == 0)
  3054          binv_st = 2; /* updated */
  3055       else
  3056       {  csa->valid = 0;
  3057          binv_st = 0; /* invalid */
  3058       }
  3059 #if 0 /* 06/IV-2009 */
  3060       /* update matrix N */
  3061       del_N_col(csa, csa->q, csa->head[csa->m+csa->q]);
  3062       if (csa->type[csa->head[csa->p]] != GLP_FX)
  3063          add_N_col(csa, csa->q, csa->head[csa->p]);
  3064 #endif
  3065       /* change the basis header */
  3066       change_basis(csa);
  3067       /* iteration complete */
  3068       csa->it_cnt++;
  3069       if (rigorous > 0) rigorous--;
  3070       goto loop;
  3071 done: /* deallocate the common storage area */
  3072       free_csa(csa);
  3073       /* return to the calling program */
  3074       return ret;
  3075 }
  3076 
  3077 /* eof */