src/glpbfd.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
/* glpbfd.c (LP basis factorization driver) */
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
typedef struct BFD BFD;
alpar@1
    26
alpar@1
    27
#define GLPBFD_PRIVATE
alpar@1
    28
#include "glpapi.h"
alpar@1
    29
#include "glpfhv.h"
alpar@1
    30
#include "glplpf.h"
alpar@1
    31
alpar@1
    32
/* CAUTION: DO NOT CHANGE THE LIMIT BELOW */
alpar@1
    33
alpar@1
    34
#define M_MAX 100000000 /* = 100*10^6 */
alpar@1
    35
/* maximal order of the basis matrix */
alpar@1
    36
alpar@1
    37
struct BFD
alpar@1
    38
{     /* LP basis factorization */
alpar@1
    39
      int valid;
alpar@1
    40
      /* factorization is valid only if this flag is set */
alpar@1
    41
      int type;
alpar@1
    42
      /* factorization type:
alpar@1
    43
         GLP_BF_FT - LUF + Forrest-Tomlin
alpar@1
    44
         GLP_BF_BG - LUF + Schur compl. + Bartels-Golub
alpar@1
    45
         GLP_BF_GR - LUF + Schur compl. + Givens rotation */
alpar@1
    46
      FHV *fhv;
alpar@1
    47
      /* LP basis factorization (GLP_BF_FT) */
alpar@1
    48
      LPF *lpf;
alpar@1
    49
      /* LP basis factorization (GLP_BF_BG, GLP_BF_GR) */
alpar@1
    50
      int lu_size;      /* luf.sv_size */
alpar@1
    51
      double piv_tol;   /* luf.piv_tol */
alpar@1
    52
      int piv_lim;      /* luf.piv_lim */
alpar@1
    53
      int suhl;         /* luf.suhl */
alpar@1
    54
      double eps_tol;   /* luf.eps_tol */
alpar@1
    55
      double max_gro;   /* luf.max_gro */
alpar@1
    56
      int nfs_max;      /* fhv.hh_max */
alpar@1
    57
      double upd_tol;   /* fhv.upd_tol */
alpar@1
    58
      int nrs_max;      /* lpf.n_max */
alpar@1
    59
      int rs_size;      /* lpf.v_size */
alpar@1
    60
      /* internal control parameters */
alpar@1
    61
      int upd_lim;
alpar@1
    62
      /* the factorization update limit */
alpar@1
    63
      int upd_cnt;
alpar@1
    64
      /* the factorization update count */
alpar@1
    65
};
alpar@1
    66
alpar@1
    67
/***********************************************************************
alpar@1
    68
*  NAME
alpar@1
    69
*
alpar@1
    70
*  bfd_create_it - create LP basis factorization
alpar@1
    71
*
alpar@1
    72
*  SYNOPSIS
alpar@1
    73
*
alpar@1
    74
*  #include "glpbfd.h"
alpar@1
    75
*  BFD *bfd_create_it(void);
alpar@1
    76
*
alpar@1
    77
*  DESCRIPTION
alpar@1
    78
*
alpar@1
    79
*  The routine bfd_create_it creates a program object, which represents
alpar@1
    80
*  a factorization of LP basis.
alpar@1
    81
*
alpar@1
    82
*  RETURNS
alpar@1
    83
*
alpar@1
    84
*  The routine bfd_create_it returns a pointer to the object created. */
alpar@1
    85
alpar@1
    86
BFD *bfd_create_it(void)
alpar@1
    87
{     BFD *bfd;
alpar@1
    88
      bfd = xmalloc(sizeof(BFD));
alpar@1
    89
      bfd->valid = 0;
alpar@1
    90
      bfd->type = GLP_BF_FT;
alpar@1
    91
      bfd->fhv = NULL;
alpar@1
    92
      bfd->lpf = NULL;
alpar@1
    93
      bfd->lu_size = 0;
alpar@1
    94
      bfd->piv_tol = 0.10;
alpar@1
    95
      bfd->piv_lim = 4;
alpar@1
    96
      bfd->suhl = 1;
alpar@1
    97
      bfd->eps_tol = 1e-15;
alpar@1
    98
      bfd->max_gro = 1e+10;
alpar@1
    99
      bfd->nfs_max = 100;
alpar@1
   100
      bfd->upd_tol = 1e-6;
alpar@1
   101
      bfd->nrs_max = 100;
alpar@1
   102
      bfd->rs_size = 1000;
alpar@1
   103
      bfd->upd_lim = -1;
alpar@1
   104
      bfd->upd_cnt = 0;
alpar@1
   105
      return bfd;
alpar@1
   106
}
alpar@1
   107
alpar@1
   108
/**********************************************************************/
alpar@1
   109
alpar@1
   110
void bfd_set_parm(BFD *bfd, const void *_parm)
alpar@1
   111
{     /* change LP basis factorization control parameters */
alpar@1
   112
      const glp_bfcp *parm = _parm;
alpar@1
   113
      xassert(bfd != NULL);
alpar@1
   114
      bfd->type = parm->type;
alpar@1
   115
      bfd->lu_size = parm->lu_size;
alpar@1
   116
      bfd->piv_tol = parm->piv_tol;
alpar@1
   117
      bfd->piv_lim = parm->piv_lim;
alpar@1
   118
      bfd->suhl = parm->suhl;
alpar@1
   119
      bfd->eps_tol = parm->eps_tol;
alpar@1
   120
      bfd->max_gro = parm->max_gro;
alpar@1
   121
      bfd->nfs_max = parm->nfs_max;
alpar@1
   122
      bfd->upd_tol = parm->upd_tol;
alpar@1
   123
      bfd->nrs_max = parm->nrs_max;
alpar@1
   124
      bfd->rs_size = parm->rs_size;
alpar@1
   125
      return;
alpar@1
   126
}
alpar@1
   127
alpar@1
   128
/***********************************************************************
alpar@1
   129
*  NAME
alpar@1
   130
*
alpar@1
   131
*  bfd_factorize - compute LP basis factorization
alpar@1
   132
*
alpar@1
   133
*  SYNOPSIS
alpar@1
   134
*
alpar@1
   135
*  #include "glpbfd.h"
alpar@1
   136
*  int bfd_factorize(BFD *bfd, int m, int bh[], int (*col)(void *info,
alpar@1
   137
*     int j, int ind[], double val[]), void *info);
alpar@1
   138
*
alpar@1
   139
*  DESCRIPTION
alpar@1
   140
*
alpar@1
   141
*  The routine bfd_factorize computes the factorization of the basis
alpar@1
   142
*  matrix B specified by the routine col.
alpar@1
   143
*
alpar@1
   144
*  The parameter bfd specified the basis factorization data structure
alpar@1
   145
*  created with the routine bfd_create_it.
alpar@1
   146
*
alpar@1
   147
*  The parameter m specifies the order of B, m > 0.
alpar@1
   148
*
alpar@1
   149
*  The array bh specifies the basis header: bh[j], 1 <= j <= m, is the
alpar@1
   150
*  number of j-th column of B in some original matrix. The array bh is
alpar@1
   151
*  optional and can be specified as NULL.
alpar@1
   152
*
alpar@1
   153
*  The formal routine col specifies the matrix B to be factorized. To
alpar@1
   154
*  obtain j-th column of A the routine bfd_factorize calls the routine
alpar@1
   155
*  col with the parameter j (1 <= j <= n). In response the routine col
alpar@1
   156
*  should store row indices and numerical values of non-zero elements
alpar@1
   157
*  of j-th column of B to locations ind[1,...,len] and val[1,...,len],
alpar@1
   158
*  respectively, where len is the number of non-zeros in j-th column
alpar@1
   159
*  returned on exit. Neither zero nor duplicate elements are allowed.
alpar@1
   160
*
alpar@1
   161
*  The parameter info is a transit pointer passed to the routine col.
alpar@1
   162
*
alpar@1
   163
*  RETURNS
alpar@1
   164
*
alpar@1
   165
*  0  The factorization has been successfully computed.
alpar@1
   166
*
alpar@1
   167
*  BFD_ESING
alpar@1
   168
*     The specified matrix is singular within the working precision.
alpar@1
   169
*
alpar@1
   170
*  BFD_ECOND
alpar@1
   171
*     The specified matrix is ill-conditioned.
alpar@1
   172
*
alpar@1
   173
*  For more details see comments to the routine luf_factorize. */
alpar@1
   174
alpar@1
   175
int bfd_factorize(BFD *bfd, int m, const int bh[], int (*col)
alpar@1
   176
      (void *info, int j, int ind[], double val[]), void *info)
alpar@1
   177
{     LUF *luf;
alpar@1
   178
      int nov, ret;
alpar@1
   179
      xassert(bfd != NULL);
alpar@1
   180
      xassert(1 <= m && m <= M_MAX);
alpar@1
   181
      /* invalidate the factorization */
alpar@1
   182
      bfd->valid = 0;
alpar@1
   183
      /* create the factorization, if necessary */
alpar@1
   184
      nov = 0;
alpar@1
   185
      switch (bfd->type)
alpar@1
   186
      {  case GLP_BF_FT:
alpar@1
   187
            if (bfd->lpf != NULL)
alpar@1
   188
               lpf_delete_it(bfd->lpf), bfd->lpf = NULL;
alpar@1
   189
            if (bfd->fhv == NULL)
alpar@1
   190
               bfd->fhv = fhv_create_it(), nov = 1;
alpar@1
   191
            break;
alpar@1
   192
         case GLP_BF_BG:
alpar@1
   193
         case GLP_BF_GR:
alpar@1
   194
            if (bfd->fhv != NULL)
alpar@1
   195
               fhv_delete_it(bfd->fhv), bfd->fhv = NULL;
alpar@1
   196
            if (bfd->lpf == NULL)
alpar@1
   197
               bfd->lpf = lpf_create_it(), nov = 1;
alpar@1
   198
            break;
alpar@1
   199
         default:
alpar@1
   200
            xassert(bfd != bfd);
alpar@1
   201
      }
alpar@1
   202
      /* set control parameters specific to LUF */
alpar@1
   203
      if (bfd->fhv != NULL)
alpar@1
   204
         luf = bfd->fhv->luf;
alpar@1
   205
      else if (bfd->lpf != NULL)
alpar@1
   206
         luf = bfd->lpf->luf;
alpar@1
   207
      else
alpar@1
   208
         xassert(bfd != bfd);
alpar@1
   209
      if (nov) luf->new_sva = bfd->lu_size;
alpar@1
   210
      luf->piv_tol = bfd->piv_tol;
alpar@1
   211
      luf->piv_lim = bfd->piv_lim;
alpar@1
   212
      luf->suhl = bfd->suhl;
alpar@1
   213
      luf->eps_tol = bfd->eps_tol;
alpar@1
   214
      luf->max_gro = bfd->max_gro;
alpar@1
   215
      /* set control parameters specific to FHV */
alpar@1
   216
      if (bfd->fhv != NULL)
alpar@1
   217
      {  if (nov) bfd->fhv->hh_max = bfd->nfs_max;
alpar@1
   218
         bfd->fhv->upd_tol = bfd->upd_tol;
alpar@1
   219
      }
alpar@1
   220
      /* set control parameters specific to LPF */
alpar@1
   221
      if (bfd->lpf != NULL)
alpar@1
   222
      {  if (nov) bfd->lpf->n_max = bfd->nrs_max;
alpar@1
   223
         if (nov) bfd->lpf->v_size = bfd->rs_size;
alpar@1
   224
      }
alpar@1
   225
      /* try to factorize the basis matrix */
alpar@1
   226
      if (bfd->fhv != NULL)
alpar@1
   227
      {  switch (fhv_factorize(bfd->fhv, m, col, info))
alpar@1
   228
         {  case 0:
alpar@1
   229
               break;
alpar@1
   230
            case FHV_ESING:
alpar@1
   231
               ret = BFD_ESING;
alpar@1
   232
               goto done;
alpar@1
   233
            case FHV_ECOND:
alpar@1
   234
               ret = BFD_ECOND;
alpar@1
   235
               goto done;
alpar@1
   236
            default:
alpar@1
   237
               xassert(bfd != bfd);
alpar@1
   238
         }
alpar@1
   239
      }
alpar@1
   240
      else if (bfd->lpf != NULL)
alpar@1
   241
      {  switch (lpf_factorize(bfd->lpf, m, bh, col, info))
alpar@1
   242
         {  case 0:
alpar@1
   243
               /* set the Schur complement update type */
alpar@1
   244
               switch (bfd->type)
alpar@1
   245
               {  case GLP_BF_BG:
alpar@1
   246
                     /* Bartels-Golub update */
alpar@1
   247
                     bfd->lpf->scf->t_opt = SCF_TBG;
alpar@1
   248
                     break;
alpar@1
   249
                  case GLP_BF_GR:
alpar@1
   250
                     /* Givens rotation update */
alpar@1
   251
                     bfd->lpf->scf->t_opt = SCF_TGR;
alpar@1
   252
                     break;
alpar@1
   253
                  default:
alpar@1
   254
                     xassert(bfd != bfd);
alpar@1
   255
               }
alpar@1
   256
               break;
alpar@1
   257
            case LPF_ESING:
alpar@1
   258
               ret = BFD_ESING;
alpar@1
   259
               goto done;
alpar@1
   260
            case LPF_ECOND:
alpar@1
   261
               ret = BFD_ECOND;
alpar@1
   262
               goto done;
alpar@1
   263
            default:
alpar@1
   264
               xassert(bfd != bfd);
alpar@1
   265
         }
alpar@1
   266
      }
alpar@1
   267
      else
alpar@1
   268
         xassert(bfd != bfd);
alpar@1
   269
      /* the basis matrix has been successfully factorized */
alpar@1
   270
      bfd->valid = 1;
alpar@1
   271
      bfd->upd_cnt = 0;
alpar@1
   272
      ret = 0;
alpar@1
   273
done: /* return to the calling program */
alpar@1
   274
      return ret;
alpar@1
   275
}
alpar@1
   276
alpar@1
   277
/***********************************************************************
alpar@1
   278
*  NAME
alpar@1
   279
*
alpar@1
   280
*  bfd_ftran - perform forward transformation (solve system B*x = b)
alpar@1
   281
*
alpar@1
   282
*  SYNOPSIS
alpar@1
   283
*
alpar@1
   284
*  #include "glpbfd.h"
alpar@1
   285
*  void bfd_ftran(BFD *bfd, double x[]);
alpar@1
   286
*
alpar@1
   287
*  DESCRIPTION
alpar@1
   288
*
alpar@1
   289
*  The routine bfd_ftran performs forward transformation, i.e. solves
alpar@1
   290
*  the system B*x = b, where B is the basis matrix, x is the vector of
alpar@1
   291
*  unknowns to be computed, b is the vector of right-hand sides.
alpar@1
   292
*
alpar@1
   293
*  On entry elements of the vector b should be stored in dense format
alpar@1
   294
*  in locations x[1], ..., x[m], where m is the number of rows. On exit
alpar@1
   295
*  the routine stores elements of the vector x in the same locations. */
alpar@1
   296
alpar@1
   297
void bfd_ftran(BFD *bfd, double x[])
alpar@1
   298
{     xassert(bfd != NULL);
alpar@1
   299
      xassert(bfd->valid);
alpar@1
   300
      if (bfd->fhv != NULL)
alpar@1
   301
         fhv_ftran(bfd->fhv, x);
alpar@1
   302
      else if (bfd->lpf != NULL)
alpar@1
   303
         lpf_ftran(bfd->lpf, x);
alpar@1
   304
      else
alpar@1
   305
         xassert(bfd != bfd);
alpar@1
   306
      return;
alpar@1
   307
}
alpar@1
   308
alpar@1
   309
/***********************************************************************
alpar@1
   310
*  NAME
alpar@1
   311
*
alpar@1
   312
*  bfd_btran - perform backward transformation (solve system B'*x = b)
alpar@1
   313
*
alpar@1
   314
*  SYNOPSIS
alpar@1
   315
*
alpar@1
   316
*  #include "glpbfd.h"
alpar@1
   317
*  void bfd_btran(BFD *bfd, double x[]);
alpar@1
   318
*
alpar@1
   319
*  DESCRIPTION
alpar@1
   320
*
alpar@1
   321
*  The routine bfd_btran performs backward transformation, i.e. solves
alpar@1
   322
*  the system B'*x = b, where B' is a matrix transposed to the basis
alpar@1
   323
*  matrix B, x is the vector of unknowns to be computed, b is the vector
alpar@1
   324
*  of right-hand sides.
alpar@1
   325
*
alpar@1
   326
*  On entry elements of the vector b should be stored in dense format
alpar@1
   327
*  in locations x[1], ..., x[m], where m is the number of rows. On exit
alpar@1
   328
*  the routine stores elements of the vector x in the same locations. */
alpar@1
   329
alpar@1
   330
void bfd_btran(BFD *bfd, double x[])
alpar@1
   331
{     xassert(bfd != NULL);
alpar@1
   332
      xassert(bfd->valid);
alpar@1
   333
      if (bfd->fhv != NULL)
alpar@1
   334
         fhv_btran(bfd->fhv, x);
alpar@1
   335
      else if (bfd->lpf != NULL)
alpar@1
   336
         lpf_btran(bfd->lpf, x);
alpar@1
   337
      else
alpar@1
   338
         xassert(bfd != bfd);
alpar@1
   339
      return;
alpar@1
   340
}
alpar@1
   341
alpar@1
   342
/***********************************************************************
alpar@1
   343
*  NAME
alpar@1
   344
*
alpar@1
   345
*  bfd_update_it - update LP basis factorization
alpar@1
   346
*
alpar@1
   347
*  SYNOPSIS
alpar@1
   348
*
alpar@1
   349
*  #include "glpbfd.h"
alpar@1
   350
*  int bfd_update_it(BFD *bfd, int j, int bh, int len, const int ind[],
alpar@1
   351
*     const double val[]);
alpar@1
   352
*
alpar@1
   353
*  DESCRIPTION
alpar@1
   354
*
alpar@1
   355
*  The routine bfd_update_it updates the factorization of the basis
alpar@1
   356
*  matrix B after replacing its j-th column by a new vector.
alpar@1
   357
*
alpar@1
   358
*  The parameter j specifies the number of column of B, which has been
alpar@1
   359
*  replaced, 1 <= j <= m, where m is the order of B.
alpar@1
   360
*
alpar@1
   361
*  The parameter bh specifies the basis header entry for the new column
alpar@1
   362
*  of B, which is the number of the new column in some original matrix.
alpar@1
   363
*  This parameter is optional and can be specified as 0.
alpar@1
   364
*
alpar@1
   365
*  Row indices and numerical values of non-zero elements of the new
alpar@1
   366
*  column of B should be placed in locations ind[1], ..., ind[len] and
alpar@1
   367
*  val[1], ..., val[len], resp., where len is the number of non-zeros
alpar@1
   368
*  in the column. Neither zero nor duplicate elements are allowed.
alpar@1
   369
*
alpar@1
   370
*  RETURNS
alpar@1
   371
*
alpar@1
   372
*  0  The factorization has been successfully updated.
alpar@1
   373
*
alpar@1
   374
*  BFD_ESING
alpar@1
   375
*     New basis matrix is singular within the working precision.
alpar@1
   376
*
alpar@1
   377
*  BFD_ECHECK
alpar@1
   378
*     The factorization is inaccurate.
alpar@1
   379
*
alpar@1
   380
*  BFD_ELIMIT
alpar@1
   381
*     Factorization update limit has been reached.
alpar@1
   382
*
alpar@1
   383
*  BFD_EROOM
alpar@1
   384
*     Overflow of the sparse vector area.
alpar@1
   385
*
alpar@1
   386
*  In case of non-zero return code the factorization becomes invalid.
alpar@1
   387
*  It should not be used until it has been recomputed with the routine
alpar@1
   388
*  bfd_factorize. */
alpar@1
   389
alpar@1
   390
int bfd_update_it(BFD *bfd, int j, int bh, int len, const int ind[],
alpar@1
   391
      const double val[])
alpar@1
   392
{     int ret;
alpar@1
   393
      xassert(bfd != NULL);
alpar@1
   394
      xassert(bfd->valid);
alpar@1
   395
      /* try to update the factorization */
alpar@1
   396
      if (bfd->fhv != NULL)
alpar@1
   397
      {  switch (fhv_update_it(bfd->fhv, j, len, ind, val))
alpar@1
   398
         {  case 0:
alpar@1
   399
               break;
alpar@1
   400
            case FHV_ESING:
alpar@1
   401
               bfd->valid = 0;
alpar@1
   402
               ret = BFD_ESING;
alpar@1
   403
               goto done;
alpar@1
   404
            case FHV_ECHECK:
alpar@1
   405
               bfd->valid = 0;
alpar@1
   406
               ret = BFD_ECHECK;
alpar@1
   407
               goto done;
alpar@1
   408
            case FHV_ELIMIT:
alpar@1
   409
               bfd->valid = 0;
alpar@1
   410
               ret = BFD_ELIMIT;
alpar@1
   411
               goto done;
alpar@1
   412
            case FHV_EROOM:
alpar@1
   413
               bfd->valid = 0;
alpar@1
   414
               ret = BFD_EROOM;
alpar@1
   415
               goto done;
alpar@1
   416
            default:
alpar@1
   417
               xassert(bfd != bfd);
alpar@1
   418
         }
alpar@1
   419
      }
alpar@1
   420
      else if (bfd->lpf != NULL)
alpar@1
   421
      {  switch (lpf_update_it(bfd->lpf, j, bh, len, ind, val))
alpar@1
   422
         {  case 0:
alpar@1
   423
               break;
alpar@1
   424
            case LPF_ESING:
alpar@1
   425
               bfd->valid = 0;
alpar@1
   426
               ret = BFD_ESING;
alpar@1
   427
               goto done;
alpar@1
   428
            case LPF_ELIMIT:
alpar@1
   429
               bfd->valid = 0;
alpar@1
   430
               ret = BFD_ELIMIT;
alpar@1
   431
               goto done;
alpar@1
   432
            default:
alpar@1
   433
               xassert(bfd != bfd);
alpar@1
   434
         }
alpar@1
   435
      }
alpar@1
   436
      else
alpar@1
   437
         xassert(bfd != bfd);
alpar@1
   438
      /* the factorization has been successfully updated */
alpar@1
   439
      /* increase the update count */
alpar@1
   440
      bfd->upd_cnt++;
alpar@1
   441
      ret = 0;
alpar@1
   442
done: /* return to the calling program */
alpar@1
   443
      return ret;
alpar@1
   444
}
alpar@1
   445
alpar@1
   446
/**********************************************************************/
alpar@1
   447
alpar@1
   448
int bfd_get_count(BFD *bfd)
alpar@1
   449
{     /* determine factorization update count */
alpar@1
   450
      xassert(bfd != NULL);
alpar@1
   451
      xassert(bfd->valid);
alpar@1
   452
      return bfd->upd_cnt;
alpar@1
   453
}
alpar@1
   454
alpar@1
   455
/***********************************************************************
alpar@1
   456
*  NAME
alpar@1
   457
*
alpar@1
   458
*  bfd_delete_it - delete LP basis factorization
alpar@1
   459
*
alpar@1
   460
*  SYNOPSIS
alpar@1
   461
*
alpar@1
   462
*  #include "glpbfd.h"
alpar@1
   463
*  void bfd_delete_it(BFD *bfd);
alpar@1
   464
*
alpar@1
   465
*  DESCRIPTION
alpar@1
   466
*
alpar@1
   467
*  The routine bfd_delete_it deletes LP basis factorization specified
alpar@1
   468
*  by the parameter fhv and frees all memory allocated to this program
alpar@1
   469
*  object. */
alpar@1
   470
alpar@1
   471
void bfd_delete_it(BFD *bfd)
alpar@1
   472
{     xassert(bfd != NULL);
alpar@1
   473
      if (bfd->fhv != NULL)
alpar@1
   474
         fhv_delete_it(bfd->fhv);
alpar@1
   475
      if (bfd->lpf != NULL)
alpar@1
   476
         lpf_delete_it(bfd->lpf);
alpar@1
   477
      xfree(bfd);
alpar@1
   478
      return;
alpar@1
   479
}
alpar@1
   480
alpar@1
   481
/* eof */