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