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

ClpQuadraticObjective.cpp

00001 // Copyright (C) 2003, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 
00004 #include "CoinPragma.hpp"
00005 #include "ClpModel.hpp"
00006 #include "ClpQuadraticObjective.hpp"
00007 
00008 //#############################################################################
00009 // Constructors / Destructor / Assignment
00010 //#############################################################################
00011 
00012 //-------------------------------------------------------------------
00013 // Default Constructor 
00014 //-------------------------------------------------------------------
00015 ClpQuadraticObjective::ClpQuadraticObjective () 
00016 : ClpObjective()
00017 {
00018   type_=2;
00019   objective_=NULL;
00020   quadraticObjective_=NULL;
00021   gradient_ = NULL;
00022   numberColumns_=0;
00023   numberExtendedColumns_=0;
00024 }
00025 
00026 //-------------------------------------------------------------------
00027 // Useful Constructor 
00028 //-------------------------------------------------------------------
00029 ClpQuadraticObjective::ClpQuadraticObjective (const double * objective , 
00030                                               int numberColumns,
00031                                               const CoinBigIndex * start,
00032                                               const int * column, const double * element,
00033                                               int numberExtendedColumns)
00034   : ClpObjective()
00035 {
00036   type_=2;
00037   numberColumns_ = numberColumns;
00038   if (numberExtendedColumns>=0)
00039     numberExtendedColumns_= max(numberColumns_,numberExtendedColumns);
00040   else
00041     numberExtendedColumns_= numberColumns_;
00042   if (objective) {
00043     objective_ = new double [numberExtendedColumns_];
00044     memcpy(objective_,objective,numberColumns_*sizeof(double));
00045     memset(objective_+numberColumns_,0,(numberExtendedColumns_-numberColumns_)*sizeof(double));
00046   } else {
00047     objective_ = new double [numberExtendedColumns_];
00048     memset(objective_,0,numberExtendedColumns_*sizeof(double));
00049   }
00050   if (start) 
00051     quadraticObjective_ = new CoinPackedMatrix(true,numberColumns,numberColumns,
00052                                              start[numberColumns],element,column,start,NULL);
00053   else
00054   quadraticObjective_=NULL;
00055   gradient_ = NULL;
00056 }
00057 
00058 //-------------------------------------------------------------------
00059 // Copy constructor 
00060 //-------------------------------------------------------------------
00061 ClpQuadraticObjective::ClpQuadraticObjective (const ClpQuadraticObjective & rhs) 
00062 : ClpObjective(rhs)
00063 {  
00064   numberColumns_=rhs.numberColumns_;
00065   numberExtendedColumns_=rhs.numberExtendedColumns_;
00066   if (rhs.objective_) {
00067     objective_ = new double [numberExtendedColumns_];
00068     memcpy(objective_,rhs.objective_,numberExtendedColumns_*sizeof(double));
00069   } else {
00070     objective_=NULL;
00071   }
00072   if (rhs.gradient_) {
00073     gradient_ = new double [numberExtendedColumns_];
00074     memcpy(gradient_,rhs.gradient_,numberExtendedColumns_*sizeof(double));
00075   } else {
00076     gradient_=NULL;
00077   }
00078   if (rhs.quadraticObjective_) 
00079     quadraticObjective_ = new CoinPackedMatrix(*rhs.quadraticObjective_);
00080   else 
00081     quadraticObjective_=NULL;
00082 }
00083 /* Subset constructor.  Duplicates are allowed
00084    and order is as given.
00085 */
00086 ClpQuadraticObjective::ClpQuadraticObjective (const ClpQuadraticObjective &rhs,
00087                                         int numberColumns, 
00088                                         const int * whichColumn) 
00089 : ClpObjective(rhs)
00090 {
00091   objective_=NULL;
00092   int extra = rhs.numberExtendedColumns_-rhs.numberColumns_;
00093   numberColumns_=0;
00094   if (numberColumns>0) {
00095     // check valid lists
00096     int numberBad=0;
00097     int i;
00098     for (i=0;i<numberColumns;i++)
00099       if (whichColumn[i]<0||whichColumn[i]>=rhs.numberColumns_)
00100         numberBad++;
00101     if (numberBad)
00102       throw CoinError("bad column list", "subset constructor", 
00103                       "ClpQuadraticObjective");
00104     numberColumns_ = numberColumns;
00105     numberExtendedColumns_ = numberColumns+extra;
00106     objective_ = new double[numberExtendedColumns_];
00107     for (i=0;i<numberColumns_;i++) 
00108       objective_[i]=rhs.objective_[whichColumn[i]];
00109     memcpy(objective_+numberColumns_,rhs.objective_+rhs.numberColumns_,
00110            (numberExtendedColumns_-numberColumns_)*sizeof(double));
00111     if (rhs.gradient_) {
00112       gradient_ = new double[numberExtendedColumns_];
00113       for (i=0;i<numberColumns_;i++) 
00114         gradient_[i]=rhs.gradient_[whichColumn[i]];
00115       memcpy(gradient_+numberColumns_,rhs.gradient_+rhs.numberColumns_,
00116              (numberExtendedColumns_-numberColumns_)*sizeof(double));
00117     }
00118   }
00119   if (rhs.quadraticObjective_) {
00120     quadraticObjective_ = new CoinPackedMatrix(*rhs.quadraticObjective_,
00121                                                numberColumns,whichColumn,
00122                                                numberColumns,whichColumn);
00123   } else {
00124     quadraticObjective_=NULL;
00125   }
00126 }
00127   
00128 
00129 //-------------------------------------------------------------------
00130 // Destructor 
00131 //-------------------------------------------------------------------
00132 ClpQuadraticObjective::~ClpQuadraticObjective ()
00133 {
00134   delete [] objective_;
00135   delete [] gradient_;
00136   delete quadraticObjective_;
00137 }
00138 
00139 //----------------------------------------------------------------
00140 // Assignment operator 
00141 //-------------------------------------------------------------------
00142 ClpQuadraticObjective &
00143 ClpQuadraticObjective::operator=(const ClpQuadraticObjective& rhs)
00144 {
00145   if (this != &rhs) {
00146     delete quadraticObjective_;
00147     quadraticObjective_ = NULL;
00148     ClpObjective::operator=(rhs);
00149     numberColumns_=rhs.numberColumns_;
00150     numberExtendedColumns_=rhs.numberExtendedColumns_;
00151     if (rhs.objective_) {
00152       objective_ = new double [numberExtendedColumns_];
00153       memcpy(objective_,rhs.objective_,numberExtendedColumns_*sizeof(double));
00154     } else {
00155       objective_=NULL;
00156     }
00157     if (rhs.gradient_) {
00158       gradient_ = new double [numberExtendedColumns_];
00159       memcpy(gradient_,rhs.gradient_,numberExtendedColumns_*sizeof(double));
00160     } else {
00161       gradient_=NULL;
00162     }
00163     if (rhs.quadraticObjective_) {
00164       quadraticObjective_ = new CoinPackedMatrix(*rhs.quadraticObjective_);
00165     } else {
00166       quadraticObjective_=NULL;
00167     }
00168   }
00169   return *this;
00170 }
00171 
00172 // Returns gradient
00173 double *  
00174 ClpQuadraticObjective::gradient(const double * solution, double & offset,bool refresh)
00175 {
00176   offset=0.0;
00177   if (!quadraticObjective_||!solution) {
00178     return objective_;
00179   } else {
00180     if (refresh||!gradient_) {
00181       if (!gradient_) 
00182         gradient_ = new double[numberExtendedColumns_];
00183       const int * columnQuadratic = quadraticObjective_->getIndices();
00184       const int * columnQuadraticStart = quadraticObjective_->getVectorStarts();
00185       const int * columnQuadraticLength = quadraticObjective_->getVectorLengths();
00186       const double * quadraticElement = quadraticObjective_->getElements();
00187       double offset=0.0;
00188       memcpy(gradient_,objective_,numberExtendedColumns_*sizeof(double));
00189       int iColumn;
00190       for (iColumn=0;iColumn<numberColumns_;iColumn++) {
00191         double valueI = solution[iColumn];
00192         int j;
00193         for (j=columnQuadraticStart[iColumn];
00194              j<columnQuadraticStart[iColumn]+columnQuadraticLength[iColumn];j++) {
00195           int jColumn = columnQuadratic[j];
00196           double valueJ = solution[jColumn];
00197           double elementValue = quadraticElement[j];
00198           elementValue *= 0.5;
00199           offset += valueI*valueJ*elementValue;
00200           double gradientI = valueJ*elementValue;
00201           double gradientJ = valueI*elementValue;
00202           offset -= gradientI*valueI;
00203           gradient_[iColumn] += gradientI;
00204           offset -= gradientJ*valueJ;
00205           gradient_[jColumn] += gradientJ;
00206         }
00207       }
00208     }
00209     return gradient_;
00210   }
00211 }
00212   
00213 //-------------------------------------------------------------------
00214 // Clone
00215 //-------------------------------------------------------------------
00216 ClpObjective * ClpQuadraticObjective::clone() const
00217 {
00218   return new ClpQuadraticObjective(*this);
00219 }
00220 /* Subset clone.  Duplicates are allowed
00221    and order is as given.
00222 */
00223 ClpObjective * 
00224 ClpQuadraticObjective::subsetClone (int numberColumns, 
00225                            const int * whichColumns) const
00226 {
00227   return new ClpQuadraticObjective(*this, numberColumns, whichColumns);
00228 }
00229 // Resize objective
00230 void 
00231 ClpQuadraticObjective::resize(int newNumberColumns)
00232 {
00233   if (numberColumns_!=newNumberColumns) {
00234     int newExtended = newNumberColumns + (numberExtendedColumns_-numberColumns_);
00235     int i;
00236     double * newArray = new double[newExtended];
00237     if (objective_)
00238       memcpy(newArray,objective_,
00239              min(newExtended,numberExtendedColumns_)*sizeof(double));
00240     delete [] objective_;
00241     objective_ = newArray;
00242     for (i=numberColumns_;i<newNumberColumns;i++) 
00243       objective_[i]=0.0;
00244     if (gradient_) {
00245       newArray = new double[newExtended];
00246       if (gradient_)
00247         memcpy(newArray,gradient_,
00248                min(newExtended,numberExtendedColumns_)*sizeof(double));
00249       delete [] gradient_;
00250       gradient_ = newArray;
00251       for (i=numberColumns_;i<newNumberColumns;i++) 
00252         gradient_[i]=0.0;
00253     }
00254     if (quadraticObjective_) {
00255       if (newNumberColumns<numberColumns_) {
00256         int * which = new int[numberColumns_-newNumberColumns];
00257         int i;
00258         for (i=newNumberColumns;i<numberColumns_;i++) 
00259           which[i-newNumberColumns]=i;
00260         quadraticObjective_->deleteRows(numberColumns_-newNumberColumns,which);
00261         quadraticObjective_->deleteCols(numberColumns_-newNumberColumns,which);
00262         delete [] which;
00263       } else {
00264         quadraticObjective_->setDimensions(newNumberColumns,newNumberColumns);
00265       }
00266     }
00267     numberColumns_ = newNumberColumns;
00268     numberExtendedColumns_ = newExtended;
00269   } 
00270   
00271 }
00272 // Delete columns in  objective
00273 void 
00274 ClpQuadraticObjective::deleteSome(int numberToDelete, const int * which) 
00275 {
00276   int newNumberColumns = numberColumns_-numberToDelete;
00277   int newExtended = numberExtendedColumns_ - numberToDelete;
00278   if (objective_) {
00279     int i ;
00280     char * deleted = new char[numberColumns_];
00281     int numberDeleted=0;
00282     memset(deleted,0,numberColumns_*sizeof(char));
00283     for (i=0;i<numberToDelete;i++) {
00284       int j = which[i];
00285       if (j>=0&&j<numberColumns_&&!deleted[j]) {
00286         numberDeleted++;
00287         deleted[j]=1;
00288       }
00289     }
00290     newNumberColumns = numberColumns_-numberDeleted;
00291     newExtended = numberExtendedColumns_ - numberDeleted;
00292     double * newArray = new double[newExtended];
00293     int put=0;
00294     for (i=0;i<numberColumns_;i++) {
00295       if (!deleted[i]) {
00296         newArray[put++]=objective_[i];
00297       }
00298     }
00299     delete [] objective_;
00300     objective_ = newArray;
00301     delete [] deleted;
00302     memcpy(objective_+newNumberColumns,objective_+numberColumns_,
00303            (numberExtendedColumns_-numberColumns_)*sizeof(double));
00304   }
00305   if (gradient_) {
00306     int i ;
00307     char * deleted = new char[numberColumns_];
00308     int numberDeleted=0;
00309     memset(deleted,0,numberColumns_*sizeof(char));
00310     for (i=0;i<numberToDelete;i++) {
00311       int j = which[i];
00312       if (j>=0&&j<numberColumns_&&!deleted[j]) {
00313         numberDeleted++;
00314         deleted[j]=1;
00315       }
00316     }
00317     newNumberColumns = numberColumns_-numberDeleted;
00318     newExtended = numberExtendedColumns_ - numberDeleted;
00319     double * newArray = new double[newExtended];
00320     int put=0;
00321     for (i=0;i<numberColumns_;i++) {
00322       if (!deleted[i]) {
00323         newArray[put++]=gradient_[i];
00324       }
00325     }
00326     delete [] gradient_;
00327     gradient_ = newArray;
00328     delete [] deleted;
00329     memcpy(gradient_+newNumberColumns,gradient_+numberColumns_,
00330            (numberExtendedColumns_-numberColumns_)*sizeof(double));
00331   }
00332   numberColumns_ = newNumberColumns;
00333   numberExtendedColumns_ = newExtended;
00334   if (quadraticObjective_) {
00335     quadraticObjective_->deleteCols(numberToDelete,which);
00336     quadraticObjective_->deleteRows(numberToDelete,which);
00337   }
00338 }
00339 
00340 // Load up quadratic objective 
00341 void 
00342 ClpQuadraticObjective::loadQuadraticObjective(const int numberColumns, const CoinBigIndex * start,
00343                               const int * column, const double * element,int numberExtended)
00344 {
00345   delete quadraticObjective_;
00346   quadraticObjective_ = new CoinPackedMatrix(true,numberColumns,numberColumns,
00347                                              start[numberColumns],element,column,start,NULL);
00348   numberColumns_=numberColumns;
00349   if (numberExtended>numberExtendedColumns_) {
00350     if (objective_) {
00351       // make correct size
00352       double * newArray = new double[numberExtended];
00353       memcpy(newArray,objective_,numberColumns_*sizeof(double));
00354       delete [] objective_;
00355       objective_ = newArray;
00356       memset(objective_+numberColumns_,0,(numberExtended-numberColumns_)*sizeof(double));
00357     }
00358     if (gradient_) {
00359       // make correct size
00360       double * newArray = new double[numberExtended];
00361       memcpy(newArray,gradient_,numberColumns_*sizeof(double));
00362       delete [] gradient_;
00363       gradient_ = newArray;
00364       memset(gradient_+numberColumns_,0,(numberExtended-numberColumns_)*sizeof(double));
00365     }
00366     numberExtendedColumns_ = numberExtended;
00367   } else {
00368     numberExtendedColumns_ = numberColumns_;
00369   }
00370 }
00371 void 
00372 ClpQuadraticObjective::loadQuadraticObjective (  const CoinPackedMatrix& matrix)
00373 {
00374   delete quadraticObjective_;
00375   quadraticObjective_ = new CoinPackedMatrix(matrix);
00376 }
00377 // Get rid of quadratic objective
00378 void 
00379 ClpQuadraticObjective::deleteQuadraticObjective()
00380 {
00381   delete quadraticObjective_;
00382   quadraticObjective_ = NULL;
00383 }

Generated on Wed Dec 3 14:37:31 2003 for CLP by doxygen 1.3.5