src/glpscl.c
author Alpar Juttner <alpar@cs.elte.hu>
Sun, 05 Dec 2010 17:35:23 +0100
changeset 2 4c8956a7bdf4
permissions -rw-r--r--
Set up CMAKE build environment
alpar@1
     1
/* glpscl.c */
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 "glpapi.h"
alpar@1
    26
alpar@1
    27
/***********************************************************************
alpar@1
    28
*  min_row_aij - determine minimal |a[i,j]| in i-th row
alpar@1
    29
*
alpar@1
    30
*  This routine returns minimal magnitude of (non-zero) constraint
alpar@1
    31
*  coefficients in i-th row of the constraint matrix.
alpar@1
    32
*
alpar@1
    33
*  If the parameter scaled is zero, the original constraint matrix A is
alpar@1
    34
*  assumed. Otherwise, the scaled constraint matrix R*A*S is assumed.
alpar@1
    35
*
alpar@1
    36
*  If i-th row of the matrix is empty, the routine returns 1. */
alpar@1
    37
alpar@1
    38
static double min_row_aij(glp_prob *lp, int i, int scaled)
alpar@1
    39
{     GLPAIJ *aij;
alpar@1
    40
      double min_aij, temp;
alpar@1
    41
      xassert(1 <= i && i <= lp->m);
alpar@1
    42
      min_aij = 1.0;
alpar@1
    43
      for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next)
alpar@1
    44
      {  temp = fabs(aij->val);
alpar@1
    45
         if (scaled) temp *= (aij->row->rii * aij->col->sjj);
alpar@1
    46
         if (aij->r_prev == NULL || min_aij > temp)
alpar@1
    47
            min_aij = temp;
alpar@1
    48
      }
alpar@1
    49
      return min_aij;
alpar@1
    50
}
alpar@1
    51
alpar@1
    52
/***********************************************************************
alpar@1
    53
*  max_row_aij - determine maximal |a[i,j]| in i-th row
alpar@1
    54
*
alpar@1
    55
*  This routine returns maximal magnitude of (non-zero) constraint
alpar@1
    56
*  coefficients in i-th row of the constraint matrix.
alpar@1
    57
*
alpar@1
    58
*  If the parameter scaled is zero, the original constraint matrix A is
alpar@1
    59
*  assumed. Otherwise, the scaled constraint matrix R*A*S is assumed.
alpar@1
    60
*
alpar@1
    61
*  If i-th row of the matrix is empty, the routine returns 1. */
alpar@1
    62
alpar@1
    63
static double max_row_aij(glp_prob *lp, int i, int scaled)
alpar@1
    64
{     GLPAIJ *aij;
alpar@1
    65
      double max_aij, temp;
alpar@1
    66
      xassert(1 <= i && i <= lp->m);
alpar@1
    67
      max_aij = 1.0;
alpar@1
    68
      for (aij = lp->row[i]->ptr; aij != NULL; aij = aij->r_next)
alpar@1
    69
      {  temp = fabs(aij->val);
alpar@1
    70
         if (scaled) temp *= (aij->row->rii * aij->col->sjj);
alpar@1
    71
         if (aij->r_prev == NULL || max_aij < temp)
alpar@1
    72
            max_aij = temp;
alpar@1
    73
      }
alpar@1
    74
      return max_aij;
alpar@1
    75
}
alpar@1
    76
alpar@1
    77
/***********************************************************************
alpar@1
    78
*  min_col_aij - determine minimal |a[i,j]| in j-th column
alpar@1
    79
*
alpar@1
    80
*  This routine returns minimal magnitude of (non-zero) constraint
alpar@1
    81
*  coefficients in j-th column of the constraint matrix.
alpar@1
    82
*
alpar@1
    83
*  If the parameter scaled is zero, the original constraint matrix A is
alpar@1
    84
*  assumed. Otherwise, the scaled constraint matrix R*A*S is assumed.
alpar@1
    85
*
alpar@1
    86
*  If j-th column of the matrix is empty, the routine returns 1. */
alpar@1
    87
alpar@1
    88
static double min_col_aij(glp_prob *lp, int j, int scaled)
alpar@1
    89
{     GLPAIJ *aij;
alpar@1
    90
      double min_aij, temp;
alpar@1
    91
      xassert(1 <= j && j <= lp->n);
alpar@1
    92
      min_aij = 1.0;
alpar@1
    93
      for (aij = lp->col[j]->ptr; aij != NULL; aij = aij->c_next)
alpar@1
    94
      {  temp = fabs(aij->val);
alpar@1
    95
         if (scaled) temp *= (aij->row->rii * aij->col->sjj);
alpar@1
    96
         if (aij->c_prev == NULL || min_aij > temp)
alpar@1
    97
            min_aij = temp;
alpar@1
    98
      }
alpar@1
    99
      return min_aij;
alpar@1
   100
}
alpar@1
   101
alpar@1
   102
/***********************************************************************
alpar@1
   103
*  max_col_aij - determine maximal |a[i,j]| in j-th column
alpar@1
   104
*
alpar@1
   105
*  This routine returns maximal magnitude of (non-zero) constraint
alpar@1
   106
*  coefficients in j-th column of the constraint matrix.
alpar@1
   107
*
alpar@1
   108
*  If the parameter scaled is zero, the original constraint matrix A is
alpar@1
   109
*  assumed. Otherwise, the scaled constraint matrix R*A*S is assumed.
alpar@1
   110
*
alpar@1
   111
*  If j-th column of the matrix is empty, the routine returns 1. */
alpar@1
   112
alpar@1
   113
static double max_col_aij(glp_prob *lp, int j, int scaled)
alpar@1
   114
{     GLPAIJ *aij;
alpar@1
   115
      double max_aij, temp;
alpar@1
   116
      xassert(1 <= j && j <= lp->n);
alpar@1
   117
      max_aij = 1.0;
alpar@1
   118
      for (aij = lp->col[j]->ptr; aij != NULL; aij = aij->c_next)
alpar@1
   119
      {  temp = fabs(aij->val);
alpar@1
   120
         if (scaled) temp *= (aij->row->rii * aij->col->sjj);
alpar@1
   121
         if (aij->c_prev == NULL || max_aij < temp)
alpar@1
   122
            max_aij = temp;
alpar@1
   123
      }
alpar@1
   124
      return max_aij;
alpar@1
   125
}
alpar@1
   126
alpar@1
   127
/***********************************************************************
alpar@1
   128
*  min_mat_aij - determine minimal |a[i,j]| in constraint matrix
alpar@1
   129
*
alpar@1
   130
*  This routine returns minimal magnitude of (non-zero) constraint
alpar@1
   131
*  coefficients in the constraint matrix.
alpar@1
   132
*
alpar@1
   133
*  If the parameter scaled is zero, the original constraint matrix A is
alpar@1
   134
*  assumed. Otherwise, the scaled constraint matrix R*A*S is assumed.
alpar@1
   135
*
alpar@1
   136
*  If the matrix is empty, the routine returns 1. */
alpar@1
   137
alpar@1
   138
static double min_mat_aij(glp_prob *lp, int scaled)
alpar@1
   139
{     int i;
alpar@1
   140
      double min_aij, temp;
alpar@1
   141
      min_aij = 1.0;
alpar@1
   142
      for (i = 1; i <= lp->m; i++)
alpar@1
   143
      {  temp = min_row_aij(lp, i, scaled);
alpar@1
   144
         if (i == 1 || min_aij > temp)
alpar@1
   145
            min_aij = temp;
alpar@1
   146
      }
alpar@1
   147
      return min_aij;
alpar@1
   148
}
alpar@1
   149
alpar@1
   150
/***********************************************************************
alpar@1
   151
*  max_mat_aij - determine maximal |a[i,j]| in constraint matrix
alpar@1
   152
*
alpar@1
   153
*  This routine returns maximal magnitude of (non-zero) constraint
alpar@1
   154
*  coefficients in the constraint matrix.
alpar@1
   155
*
alpar@1
   156
*  If the parameter scaled is zero, the original constraint matrix A is
alpar@1
   157
*  assumed. Otherwise, the scaled constraint matrix R*A*S is assumed.
alpar@1
   158
*
alpar@1
   159
*  If the matrix is empty, the routine returns 1. */
alpar@1
   160
alpar@1
   161
static double max_mat_aij(glp_prob *lp, int scaled)
alpar@1
   162
{     int i;
alpar@1
   163
      double max_aij, temp;
alpar@1
   164
      max_aij = 1.0;
alpar@1
   165
      for (i = 1; i <= lp->m; i++)
alpar@1
   166
      {  temp = max_row_aij(lp, i, scaled);
alpar@1
   167
         if (i == 1 || max_aij < temp)
alpar@1
   168
            max_aij = temp;
alpar@1
   169
      }
alpar@1
   170
      return max_aij;
alpar@1
   171
}
alpar@1
   172
alpar@1
   173
/***********************************************************************
alpar@1
   174
*  eq_scaling - perform equilibration scaling
alpar@1
   175
*
alpar@1
   176
*  This routine performs equilibration scaling of rows and columns of
alpar@1
   177
*  the constraint matrix.
alpar@1
   178
*
alpar@1
   179
*  If the parameter flag is zero, the routine scales rows at first and
alpar@1
   180
*  then columns. Otherwise, the routine scales columns and then rows.
alpar@1
   181
*
alpar@1
   182
*  Rows are scaled as follows:
alpar@1
   183
*
alpar@1
   184
*                         n
alpar@1
   185
*     a'[i,j] = a[i,j] / max |a[i,j]|,  i = 1,...,m.
alpar@1
   186
*                        j=1
alpar@1
   187
*
alpar@1
   188
*  This makes the infinity (maximum) norm of each row of the matrix
alpar@1
   189
*  equal to 1.
alpar@1
   190
*
alpar@1
   191
*  Columns are scaled as follows:
alpar@1
   192
*
alpar@1
   193
*                         n
alpar@1
   194
*     a'[i,j] = a[i,j] / max |a[i,j]|,  j = 1,...,n.
alpar@1
   195
*                        i=1
alpar@1
   196
*
alpar@1
   197
*  This makes the infinity (maximum) norm of each column of the matrix
alpar@1
   198
*  equal to 1. */
alpar@1
   199
alpar@1
   200
static void eq_scaling(glp_prob *lp, int flag)
alpar@1
   201
{     int i, j, pass;
alpar@1
   202
      double temp;
alpar@1
   203
      xassert(flag == 0 || flag == 1);
alpar@1
   204
      for (pass = 0; pass <= 1; pass++)
alpar@1
   205
      {  if (pass == flag)
alpar@1
   206
         {  /* scale rows */
alpar@1
   207
            for (i = 1; i <= lp->m; i++)
alpar@1
   208
            {  temp = max_row_aij(lp, i, 1);
alpar@1
   209
               glp_set_rii(lp, i, glp_get_rii(lp, i) / temp);
alpar@1
   210
            }
alpar@1
   211
         }
alpar@1
   212
         else
alpar@1
   213
         {  /* scale columns */
alpar@1
   214
            for (j = 1; j <= lp->n; j++)
alpar@1
   215
            {  temp = max_col_aij(lp, j, 1);
alpar@1
   216
               glp_set_sjj(lp, j, glp_get_sjj(lp, j) / temp);
alpar@1
   217
            }
alpar@1
   218
         }
alpar@1
   219
      }
alpar@1
   220
      return;
alpar@1
   221
}
alpar@1
   222
alpar@1
   223
/***********************************************************************
alpar@1
   224
*  gm_scaling - perform geometric mean scaling
alpar@1
   225
*
alpar@1
   226
*  This routine performs geometric mean scaling of rows and columns of
alpar@1
   227
*  the constraint matrix.
alpar@1
   228
*
alpar@1
   229
*  If the parameter flag is zero, the routine scales rows at first and
alpar@1
   230
*  then columns. Otherwise, the routine scales columns and then rows.
alpar@1
   231
*
alpar@1
   232
*  Rows are scaled as follows:
alpar@1
   233
*
alpar@1
   234
*     a'[i,j] = a[i,j] / sqrt(alfa[i] * beta[i]),  i = 1,...,m,
alpar@1
   235
*
alpar@1
   236
*  where:
alpar@1
   237
*                n                        n
alpar@1
   238
*     alfa[i] = min |a[i,j]|,  beta[i] = max |a[i,j]|.
alpar@1
   239
*               j=1                      j=1
alpar@1
   240
*
alpar@1
   241
*  This allows decreasing the ratio beta[i] / alfa[i] for each row of
alpar@1
   242
*  the matrix.
alpar@1
   243
*
alpar@1
   244
*  Columns are scaled as follows:
alpar@1
   245
*
alpar@1
   246
*     a'[i,j] = a[i,j] / sqrt(alfa[j] * beta[j]),  j = 1,...,n,
alpar@1
   247
*
alpar@1
   248
*  where:
alpar@1
   249
*                m                        m
alpar@1
   250
*     alfa[j] = min |a[i,j]|,  beta[j] = max |a[i,j]|.
alpar@1
   251
*               i=1                      i=1
alpar@1
   252
*
alpar@1
   253
*  This allows decreasing the ratio beta[j] / alfa[j] for each column
alpar@1
   254
*  of the matrix. */
alpar@1
   255
alpar@1
   256
static void gm_scaling(glp_prob *lp, int flag)
alpar@1
   257
{     int i, j, pass;
alpar@1
   258
      double temp;
alpar@1
   259
      xassert(flag == 0 || flag == 1);
alpar@1
   260
      for (pass = 0; pass <= 1; pass++)
alpar@1
   261
      {  if (pass == flag)
alpar@1
   262
         {  /* scale rows */
alpar@1
   263
            for (i = 1; i <= lp->m; i++)
alpar@1
   264
            {  temp = min_row_aij(lp, i, 1) * max_row_aij(lp, i, 1);
alpar@1
   265
               glp_set_rii(lp, i, glp_get_rii(lp, i) / sqrt(temp));
alpar@1
   266
            }
alpar@1
   267
         }
alpar@1
   268
         else
alpar@1
   269
         {  /* scale columns */
alpar@1
   270
            for (j = 1; j <= lp->n; j++)
alpar@1
   271
            {  temp = min_col_aij(lp, j, 1) * max_col_aij(lp, j, 1);
alpar@1
   272
               glp_set_sjj(lp, j, glp_get_sjj(lp, j) / sqrt(temp));
alpar@1
   273
            }
alpar@1
   274
         }
alpar@1
   275
      }
alpar@1
   276
      return;
alpar@1
   277
}
alpar@1
   278
alpar@1
   279
/***********************************************************************
alpar@1
   280
*  max_row_ratio - determine worst scaling "quality" for rows
alpar@1
   281
*
alpar@1
   282
*  This routine returns the worst scaling "quality" for rows of the
alpar@1
   283
*  currently scaled constraint matrix:
alpar@1
   284
*
alpar@1
   285
*              m
alpar@1
   286
*     ratio = max ratio[i],
alpar@1
   287
*             i=1
alpar@1
   288
*  where:
alpar@1
   289
*                 n              n
alpar@1
   290
*     ratio[i] = max |a[i,j]| / min |a[i,j]|,  1 <= i <= m,
alpar@1
   291
*                j=1            j=1
alpar@1
   292
*
alpar@1
   293
*  is the scaling "quality" of i-th row. */
alpar@1
   294
alpar@1
   295
static double max_row_ratio(glp_prob *lp)
alpar@1
   296
{     int i;
alpar@1
   297
      double ratio, temp;
alpar@1
   298
      ratio = 1.0;
alpar@1
   299
      for (i = 1; i <= lp->m; i++)
alpar@1
   300
      {  temp = max_row_aij(lp, i, 1) / min_row_aij(lp, i, 1);
alpar@1
   301
         if (i == 1 || ratio < temp) ratio = temp;
alpar@1
   302
      }
alpar@1
   303
      return ratio;
alpar@1
   304
}
alpar@1
   305
alpar@1
   306
/***********************************************************************
alpar@1
   307
*  max_col_ratio - determine worst scaling "quality" for columns
alpar@1
   308
*
alpar@1
   309
*  This routine returns the worst scaling "quality" for columns of the
alpar@1
   310
*  currently scaled constraint matrix:
alpar@1
   311
*
alpar@1
   312
*              n
alpar@1
   313
*     ratio = max ratio[j],
alpar@1
   314
*             j=1
alpar@1
   315
*  where:
alpar@1
   316
*                 m              m
alpar@1
   317
*     ratio[j] = max |a[i,j]| / min |a[i,j]|,  1 <= j <= n,
alpar@1
   318
*                i=1            i=1
alpar@1
   319
*
alpar@1
   320
*  is the scaling "quality" of j-th column. */
alpar@1
   321
alpar@1
   322
static double max_col_ratio(glp_prob *lp)
alpar@1
   323
{     int j;
alpar@1
   324
      double ratio, temp;
alpar@1
   325
      ratio = 1.0;
alpar@1
   326
      for (j = 1; j <= lp->n; j++)
alpar@1
   327
      {  temp = max_col_aij(lp, j, 1) / min_col_aij(lp, j, 1);
alpar@1
   328
         if (j == 1 || ratio < temp) ratio = temp;
alpar@1
   329
      }
alpar@1
   330
      return ratio;
alpar@1
   331
}
alpar@1
   332
alpar@1
   333
/***********************************************************************
alpar@1
   334
*  gm_iterate - perform iterative geometric mean scaling
alpar@1
   335
*
alpar@1
   336
*  This routine performs iterative geometric mean scaling of rows and
alpar@1
   337
*  columns of the constraint matrix.
alpar@1
   338
*
alpar@1
   339
*  The parameter it_max specifies the maximal number of iterations.
alpar@1
   340
*  Recommended value of it_max is 15.
alpar@1
   341
*
alpar@1
   342
*  The parameter tau specifies a minimal improvement of the scaling
alpar@1
   343
*  "quality" on each iteration, 0 < tau < 1. It means than the scaling
alpar@1
   344
*  process continues while the following condition is satisfied:
alpar@1
   345
*
alpar@1
   346
*     ratio[k] <= tau * ratio[k-1],
alpar@1
   347
*
alpar@1
   348
*  where ratio = max |a[i,j]| / min |a[i,j]| is the scaling "quality"
alpar@1
   349
*  to be minimized, k is the iteration number. Recommended value of tau
alpar@1
   350
*  is 0.90. */
alpar@1
   351
alpar@1
   352
static void gm_iterate(glp_prob *lp, int it_max, double tau)
alpar@1
   353
{     int k, flag;
alpar@1
   354
      double ratio = 0.0, r_old;
alpar@1
   355
      /* if the scaling "quality" for rows is better than for columns,
alpar@1
   356
         the rows are scaled first; otherwise, the columns are scaled
alpar@1
   357
         first */
alpar@1
   358
      flag = (max_row_ratio(lp) > max_col_ratio(lp));
alpar@1
   359
      for (k = 1; k <= it_max; k++)
alpar@1
   360
      {  /* save the scaling "quality" from previous iteration */
alpar@1
   361
         r_old = ratio;
alpar@1
   362
         /* determine the current scaling "quality" */
alpar@1
   363
         ratio = max_mat_aij(lp, 1) / min_mat_aij(lp, 1);
alpar@1
   364
#if 0
alpar@1
   365
         xprintf("k = %d; ratio = %g\n", k, ratio);
alpar@1
   366
#endif
alpar@1
   367
         /* if improvement is not enough, terminate scaling */
alpar@1
   368
         if (k > 1 && ratio > tau * r_old) break;
alpar@1
   369
         /* otherwise, perform another iteration */
alpar@1
   370
         gm_scaling(lp, flag);
alpar@1
   371
      }
alpar@1
   372
      return;
alpar@1
   373
}
alpar@1
   374
alpar@1
   375
/***********************************************************************
alpar@1
   376
*  NAME
alpar@1
   377
*
alpar@1
   378
*  scale_prob - scale problem data
alpar@1
   379
*
alpar@1
   380
*  SYNOPSIS
alpar@1
   381
*
alpar@1
   382
*  #include "glpscl.h"
alpar@1
   383
*  void scale_prob(glp_prob *lp, int flags);
alpar@1
   384
*
alpar@1
   385
*  DESCRIPTION
alpar@1
   386
*
alpar@1
   387
*  The routine scale_prob performs automatic scaling of problem data
alpar@1
   388
*  for the specified problem object. */
alpar@1
   389
alpar@1
   390
static void scale_prob(glp_prob *lp, int flags)
alpar@1
   391
{     static const char *fmt =
alpar@1
   392
         "%s: min|aij| = %10.3e  max|aij| = %10.3e  ratio = %10.3e\n";
alpar@1
   393
      double min_aij, max_aij, ratio;
alpar@1
   394
      xprintf("Scaling...\n");
alpar@1
   395
      /* cancel the current scaling effect */
alpar@1
   396
      glp_unscale_prob(lp);
alpar@1
   397
      /* report original scaling "quality" */
alpar@1
   398
      min_aij = min_mat_aij(lp, 1);
alpar@1
   399
      max_aij = max_mat_aij(lp, 1);
alpar@1
   400
      ratio = max_aij / min_aij;
alpar@1
   401
      xprintf(fmt, " A", min_aij, max_aij, ratio);
alpar@1
   402
      /* check if the problem is well scaled */
alpar@1
   403
      if (min_aij >= 0.10 && max_aij <= 10.0)
alpar@1
   404
      {  xprintf("Problem data seem to be well scaled\n");
alpar@1
   405
         /* skip scaling, if required */
alpar@1
   406
         if (flags & GLP_SF_SKIP) goto done;
alpar@1
   407
      }
alpar@1
   408
      /* perform iterative geometric mean scaling, if required */
alpar@1
   409
      if (flags & GLP_SF_GM)
alpar@1
   410
      {  gm_iterate(lp, 15, 0.90);
alpar@1
   411
         min_aij = min_mat_aij(lp, 1);
alpar@1
   412
         max_aij = max_mat_aij(lp, 1);
alpar@1
   413
         ratio = max_aij / min_aij;
alpar@1
   414
         xprintf(fmt, "GM", min_aij, max_aij, ratio);
alpar@1
   415
      }
alpar@1
   416
      /* perform equilibration scaling, if required */
alpar@1
   417
      if (flags & GLP_SF_EQ)
alpar@1
   418
      {  eq_scaling(lp, max_row_ratio(lp) > max_col_ratio(lp));
alpar@1
   419
         min_aij = min_mat_aij(lp, 1);
alpar@1
   420
         max_aij = max_mat_aij(lp, 1);
alpar@1
   421
         ratio = max_aij / min_aij;
alpar@1
   422
         xprintf(fmt, "EQ", min_aij, max_aij, ratio);
alpar@1
   423
      }
alpar@1
   424
      /* round scale factors to nearest power of two, if required */
alpar@1
   425
      if (flags & GLP_SF_2N)
alpar@1
   426
      {  int i, j;
alpar@1
   427
         for (i = 1; i <= lp->m; i++)
alpar@1
   428
            glp_set_rii(lp, i, round2n(glp_get_rii(lp, i)));
alpar@1
   429
         for (j = 1; j <= lp->n; j++)
alpar@1
   430
            glp_set_sjj(lp, j, round2n(glp_get_sjj(lp, j)));
alpar@1
   431
         min_aij = min_mat_aij(lp, 1);
alpar@1
   432
         max_aij = max_mat_aij(lp, 1);
alpar@1
   433
         ratio = max_aij / min_aij;
alpar@1
   434
         xprintf(fmt, "2N", min_aij, max_aij, ratio);
alpar@1
   435
      }
alpar@1
   436
done: return;
alpar@1
   437
}
alpar@1
   438
alpar@1
   439
/***********************************************************************
alpar@1
   440
*  NAME
alpar@1
   441
*
alpar@1
   442
*  glp_scale_prob - scale problem data
alpar@1
   443
*
alpar@1
   444
*  SYNOPSIS
alpar@1
   445
*
alpar@1
   446
*  void glp_scale_prob(glp_prob *lp, int flags);
alpar@1
   447
*
alpar@1
   448
*  DESCRIPTION
alpar@1
   449
*
alpar@1
   450
*  The routine glp_scale_prob performs automatic scaling of problem
alpar@1
   451
*  data for the specified problem object.
alpar@1
   452
*
alpar@1
   453
*  The parameter flags specifies scaling options used by the routine.
alpar@1
   454
*  Options can be combined with the bitwise OR operator and may be the
alpar@1
   455
*  following:
alpar@1
   456
*
alpar@1
   457
*  GLP_SF_GM      perform geometric mean scaling;
alpar@1
   458
*  GLP_SF_EQ      perform equilibration scaling;
alpar@1
   459
*  GLP_SF_2N      round scale factors to nearest power of two;
alpar@1
   460
*  GLP_SF_SKIP    skip scaling, if the problem is well scaled.
alpar@1
   461
*
alpar@1
   462
*  The parameter flags may be specified as GLP_SF_AUTO, in which case
alpar@1
   463
*  the routine chooses scaling options automatically. */
alpar@1
   464
alpar@1
   465
void glp_scale_prob(glp_prob *lp, int flags)
alpar@1
   466
{     if (flags & ~(GLP_SF_GM | GLP_SF_EQ | GLP_SF_2N | GLP_SF_SKIP |
alpar@1
   467
                    GLP_SF_AUTO))
alpar@1
   468
         xerror("glp_scale_prob: flags = 0x%02X; invalid scaling option"
alpar@1
   469
            "s\n", flags);
alpar@1
   470
      if (flags & GLP_SF_AUTO)
alpar@1
   471
         flags = (GLP_SF_GM | GLP_SF_EQ | GLP_SF_SKIP);
alpar@1
   472
      scale_prob(lp, flags);
alpar@1
   473
      return;
alpar@1
   474
}
alpar@1
   475
alpar@1
   476
/* eof */