00001
00002
00003
00004 #include "CoinPragma.hpp"
00005 #include "ClpModel.hpp"
00006 #include "ClpQuadraticObjective.hpp"
00007
00008
00009
00010
00011
00012
00013
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
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
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
00084
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
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
00131
00132 ClpQuadraticObjective::~ClpQuadraticObjective ()
00133 {
00134 delete [] objective_;
00135 delete [] gradient_;
00136 delete quadraticObjective_;
00137 }
00138
00139
00140
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
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
00215
00216 ClpObjective * ClpQuadraticObjective::clone() const
00217 {
00218 return new ClpQuadraticObjective(*this);
00219 }
00220
00221
00222
00223 ClpObjective *
00224 ClpQuadraticObjective::subsetClone (int numberColumns,
00225 const int * whichColumns) const
00226 {
00227 return new ClpQuadraticObjective(*this, numberColumns, whichColumns);
00228 }
00229
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
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
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
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
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
00378 void
00379 ClpQuadraticObjective::deleteQuadraticObjective()
00380 {
00381 delete quadraticObjective_;
00382 quadraticObjective_ = NULL;
00383 }