Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members | Related Pages

CoinWarmStartDual.cpp

00001 // Copyright (C) 2003, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 #if defined(_MSC_VER)
00004 // Turn off compiler warning about long names
00005 #  pragma warning(disable:4786)
00006 #endif
00007 
00008 #include <cassert>
00009 
00010 #include "CoinWarmStartDual.hpp"
00011 #include <cmath>
00012 
00013 //#############################################################################
00014 
00015 /*
00016   Generate a `diff' that can convert the warm start passed as a parameter to
00017   the warm start specified by this.
00018 
00019   The capabilities are limited: the basis passed as a parameter can be no
00020   larger than the basis pointed to by this.
00021 */
00022 
00023 CoinWarmStartDiff*
00024 CoinWarmStartDual::generateDiff (const CoinWarmStart *const oldCWS) const
00025 { 
00026 /*
00027   Make sure the parameter is CoinWarmStartDual or derived class.
00028 */
00029   const CoinWarmStartDual *oldDual =
00030       dynamic_cast<const CoinWarmStartDual *>(oldCWS) ;
00031   if (!oldDual)
00032   { throw CoinError("Old warm start not derived from CoinWarmStartDual.",
00033                     "generateDiff","CoinWarmStartDual") ; }
00034   const CoinWarmStartDual *newDual = this ;
00035 /*
00036   Make sure newDual is equal or bigger than oldDual. Calculate the worst
00037   case number of diffs and allocate vectors to hold them.
00038 */
00039   const int oldCnt = oldDual->size() ;
00040   const int newCnt = newDual->size() ;
00041 
00042   assert(newCnt >= oldCnt) ;
00043 
00044   unsigned int *diffNdx = new unsigned int [newCnt]; 
00045   double *diffVal = new double [newCnt]; 
00046 /*
00047   Scan the dual vectors.  For the portion of the vectors which overlap,
00048   create diffs. Then add any additional entries from newDual.
00049 */
00050   const double *oldVal = oldDual->dual() ;
00051   const double *newVal = newDual->dual() ;
00052   int numberChanged = 0 ;
00053   int i ;
00054   for (i = 0 ; i < oldCnt ; i++)
00055   { if (oldVal[i] != newVal[i])
00056     { diffNdx[numberChanged] = i ;
00057       diffVal[numberChanged++] = newVal[i] ; } }
00058   for ( ; i < newCnt ; i++)
00059   { diffNdx[numberChanged] = i ;
00060     diffVal[numberChanged++] = newVal[i] ; }
00061 /*
00062   Create the object of our desire.
00063 */
00064   CoinWarmStartDualDiff *diff =
00065     new CoinWarmStartDualDiff(numberChanged,diffNdx,diffVal) ;
00066 /*
00067   Clean up and return.
00068 */
00069   delete[] diffNdx ;
00070   delete[] diffVal ;
00071 
00072   return (dynamic_cast<CoinWarmStartDiff *>(diff)) ; }
00073 
00074 
00075 /*
00076   Apply diff to this warm start.
00077 
00078   Update this warm start by applying diff. It's assumed that the
00079   allocated capacity of the warm start is sufficiently large.
00080 */
00081 
00082 void CoinWarmStartDual::applyDiff (const CoinWarmStartDiff *const cwsdDiff)
00083 {
00084 /*
00085   Make sure we have a CoinWarmStartDualDiff
00086 */
00087   const CoinWarmStartDualDiff *diff =
00088     dynamic_cast<const CoinWarmStartDualDiff *>(cwsdDiff) ;
00089   if (!diff)
00090   { throw CoinError("Diff not derived from CoinWarmStartDualDiff.",
00091                     "applyDiff","CoinWarmStartDual") ; }
00092 /*
00093   Application is by straighforward replacement of words in the dual vector.
00094 */
00095   const int numberChanges = diff->sze_ ;
00096   const unsigned int *diffNdxs = diff->diffNdxs_ ;
00097   const double *diffVals = diff->diffVals_ ;
00098   double *vals = this->dualVector_ ;
00099 
00100   for (int i = 0 ; i < numberChanges ; i++)
00101   { unsigned int diffNdx = diffNdxs[i] ;
00102     double diffVal = diffVals[i] ;
00103     vals[diffNdx] = diffVal ; }
00104 
00105   return ; }
00106 
00107 
00108 //#############################################################################
00109 
00110 
00111 // Assignment
00112 
00113 CoinWarmStartDualDiff&
00114 CoinWarmStartDualDiff::operator= (const CoinWarmStartDualDiff &rhs)
00115 
00116 { if (this != &rhs)
00117   { if (sze_ > 0)
00118     { delete[] diffNdxs_ ;
00119       delete[] diffVals_ ; }
00120     sze_ = rhs.sze_ ;
00121     if (sze_ > 0)
00122     { diffNdxs_ = new unsigned int[sze_] ;
00123       memcpy(diffNdxs_,rhs.diffNdxs_,sze_*sizeof(unsigned int)) ;
00124       diffVals_ = new double[sze_] ;
00125       memcpy(diffVals_,rhs.diffVals_,sze_*sizeof(double)) ; }
00126     else
00127     { diffNdxs_ = 0 ;
00128       diffVals_ = 0 ; } }
00129 
00130   return (*this) ; }
00131 
00132 
00133 // Copy constructor
00134 
00135 CoinWarmStartDualDiff::CoinWarmStartDualDiff (const CoinWarmStartDualDiff &rhs)
00136   : sze_(rhs.sze_),
00137     diffNdxs_(0),
00138     diffVals_(0)
00139 { if (sze_ > 0)
00140   { diffNdxs_ = new unsigned int[sze_] ;
00141     memcpy(diffNdxs_,rhs.diffNdxs_,sze_*sizeof(unsigned int)) ;
00142     diffVals_ = new double[sze_] ;
00143     memcpy(diffVals_,rhs.diffVals_,sze_*sizeof(double)) ; }
00144   
00145   return ; }
00146 
00147 
00149 
00150 CoinWarmStartDualDiff::CoinWarmStartDualDiff
00151   (int sze, const unsigned int *const diffNdxs, const double *const diffVals)
00152   : sze_(sze),
00153     diffNdxs_(0),
00154     diffVals_(0)
00155 { if (sze > 0)
00156   { diffNdxs_ = new unsigned int[sze] ;
00157     memcpy(diffNdxs_,diffNdxs,sze*sizeof(unsigned int)) ;
00158     diffVals_ = new double[sze] ;
00159     memcpy(diffVals_,diffVals,sze*sizeof(double)) ; }
00160   
00161   return ; }
00162 

Generated on Wed Dec 3 14:34:24 2003 for Coin by doxygen 1.3.5