// Copyright (C) 2002, International Business Machines
// Corporation and others. All Rights Reserved.
#include <stdio.h>
#include <assert.h>
#include <iostream>
#include "CoinHelperFunctions.hpp"
#include "CoinPresolveMatrix.hpp"
#if PRESOLVE_DEBUG || PRESOLVE_CONSISTENCY
#include "CoinPresolvePsdebug.hpp"
#endif
/*! \file
This file contains methods for CoinPostsolveMatrix, the object used during
postsolve transformations.
*/
/*
Constructor and destructor for CoinPostsolveMatrix.
*/
/*
Default constructor
Postpone allocation of space until we actually load the object.
*/
CoinPostsolveMatrix::CoinPostsolveMatrix
(int ncols_alloc, int nrows_alloc, CoinBigIndex nelems_alloc)
: CoinPrePostsolveMatrix(ncols_alloc,nrows_alloc,nelems_alloc),
free_list_(0),
maxlink_(nelems_alloc),
link_(0),
cdone_(0),
rdone_(0)
{ /* nothing to do here */
return ; }
/*
Destructor
*/
CoinPostsolveMatrix::~CoinPostsolveMatrix()
{ delete[] link_ ;
delete[] cdone_ ;
delete[] rdone_ ;
return ; }
/*
This routine loads a CoinPostsolveMatrix object from a CoinPresolveMatrix
object. The CoinPresolveMatrix object will be stripped, its components
transferred to the CoinPostsolveMatrix object, and the empty shell of the
CoinPresolveObject will be destroyed.
The routine expects an empty CoinPostsolveMatrix object, and will leak
any memory already allocated.
*/
void
CoinPostsolveMatrix::assignPresolveToPostsolve (CoinPresolveMatrix *&preObj)
{
/*
Start with simple data --- allocated and current size.
*/
ncols0_ = preObj->ncols0_ ;
nrows0_ = preObj->nrows0_ ;
nelems0_ = preObj->nelems0_ ;
bulk0_ = preObj->bulk0_ ;
ncols_ = preObj->ncols_ ;
nrows_ = preObj->nrows_ ;
nelems_ = preObj->nelems_ ;
/*
Now bring over the column-major matrix and other problem data.
*/
mcstrt_ = preObj->mcstrt_ ;
preObj->mcstrt_ = 0 ;
hincol_ = preObj->hincol_ ;
preObj->hincol_ = 0 ;
hrow_ = preObj->hrow_ ;
preObj->hrow_ = 0 ;
colels_ = preObj->colels_ ;
preObj->colels_ = 0 ;
cost_ = preObj->cost_ ;
preObj->cost_ = 0 ;
originalOffset_ = preObj->originalOffset_ ;
clo_ = preObj->clo_ ;
preObj->clo_ = 0 ;
cup_ = preObj->cup_ ;
preObj->cup_ = 0 ;
rlo_ = preObj->rlo_ ;
preObj->rlo_ = 0 ;
rup_ = preObj->rup_ ;
preObj->rup_ = 0 ;
originalColumn_ = preObj->originalColumn_ ;
preObj->originalColumn_ = 0 ;
originalRow_ = preObj->originalRow_ ;
preObj->originalRow_ = 0 ;
ztolzb_ = preObj->ztolzb_ ;
ztoldj_ = preObj->ztoldj_ ;
maxmin_ = preObj->maxmin_ ;
/*
Now the problem solution. Often this will be empty, but that's not a problem.
*/
sol_ = preObj->sol_ ;
preObj->sol_ = 0 ;
rowduals_ = preObj->rowduals_ ;
preObj->rowduals_ = 0 ;
acts_ = preObj->acts_ ;
preObj->acts_ = 0 ;
rcosts_ = preObj->rcosts_ ;
preObj->rcosts_ = 0 ;
colstat_ = preObj->colstat_ ;
preObj->colstat_ = 0 ;
rowstat_ = preObj->rowstat_ ;
preObj->rowstat_ = 0 ;
/*
The CoinPostsolveMatrix comes with messages and a handler, but replace them
with the versions from the CoinPresolveObject, in case they've been
customized. Let preObj believe it's no longer responsible for the handler.
*/
if (defaultHandler_ == true)
delete handler_ ;
handler_ = preObj->handler_ ;
preObj->defaultHandler_ = false ;
messages_ = preObj->messages_ ;
/*
Initialise the postsolve portions of this object. Which amounts to setting
up the thread links to match the column-major matrix representation. This
would be trivial except that the presolve matrix is loosely packed. We can
either compress the matrix, or record the existing free space pattern. Bet
that the latter is more efficient. Remember that mcstrt_[ncols_] actually
points to the end of the bulk storage area, so when we process the last
column in the bulk storage area, we'll add the free space block at the end
of bulk storage to the free list.
We need to allow for a 0x0 matrix here --- a pathological case, but it slips
in when (for example) confirming a solution in an ILP code.
*/
free_list_ = NO_LINK ;
maxlink_ = bulk0_ ;
link_ = new CoinBigIndex [maxlink_] ;
if (ncols_ > 0)
{ CoinBigIndex minkcs = -1 ;
for (int j = 0 ; j < ncols_ ; j++)
{ CoinBigIndex kcs = mcstrt_[j] ;
int lenj = hincol_[j] ;
assert(lenj > 0) ;
CoinBigIndex kce = kcs+lenj-1 ;
CoinBigIndex k ;
for (k = kcs ; k < kce ; k++)
{ link_[k] = k+1 ; }
link_[k++] = NO_LINK ;
if (preObj->clink_[j].pre == NO_LINK)
{ minkcs = kcs ; }
int nxtj = preObj->clink_[j].suc ;
assert(nxtj >= 0 && nxtj <= ncols_) ;
CoinBigIndex nxtcs = mcstrt_[nxtj] ;
for ( ; k < nxtcs ; k++)
{ link_[k] = free_list_ ;
free_list_ = k ; } }
assert(minkcs >= 0) ;
if (minkcs > 0)
{ for (CoinBigIndex k = 0 ; k < minkcs ; k++)
{ link_[k] = free_list_ ;
free_list_ = k ; } } }
else
{ for (CoinBigIndex k = 0 ; k < maxlink_ ; k++)
{ link_[k] = free_list_ ;
free_list_ = k ; } }
/*
That's it, preObj can die now.
*/
delete preObj ;
preObj = 0 ;
# if PRESOLVE_DEBUG || PRESOLVE_CONSISTENCY
/*
These are used to track the action of postsolve transforms during debugging.
*/
cdone_ = new char [ncols0_] ;
CoinFillN(cdone_,ncols_,PRESENT_IN_REDUCED) ;
CoinZeroN(cdone_+ncols_,ncols0_-ncols_) ;
rdone_ = new char [nrows0_] ;
CoinFillN(rdone_,nrows_,PRESENT_IN_REDUCED) ;
CoinZeroN(rdone_+nrows_,nrows0_-nrows_) ;
# endif
# if PRESOLVE_CONSISTENCY
presolve_check_free_list(this,true) ;
presolve_check_threads(this) ;
# endif
return ; }
syntax highlighted by Code2HTML, v. 0.9.1