1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 2 /* */ 3 /* This file is part of the class library */ 4 /* SoPlex --- the Sequential object-oriented simPlex. */ 5 /* */ 6 /* Copyright (c) 1996-2023 Zuse Institute Berlin (ZIB) */ 7 /* */ 8 /* Licensed under the Apache License, Version 2.0 (the "License"); */ 9 /* you may not use this file except in compliance with the License. */ 10 /* You may obtain a copy of the License at */ 11 /* */ 12 /* http://www.apache.org/licenses/LICENSE-2.0 */ 13 /* */ 14 /* Unless required by applicable law or agreed to in writing, software */ 15 /* distributed under the License is distributed on an "AS IS" BASIS, */ 16 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */ 17 /* See the License for the specific language governing permissions and */ 18 /* limitations under the License. */ 19 /* */ 20 /* You should have received a copy of the Apache-2.0 license */ 21 /* along with SoPlex; see the file LICENSE. If not email to soplex@zib.de. */ 22 /* */ 23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 24 25 #include <iostream> 26 #include <assert.h> 27 28 #include "soplex/timerfactory.h" 29 30 namespace soplex 31 { 32 /// default constructor 33 template <class R> 34 SoPlexBase<R>::Statistics::Statistics(Timer::TYPE ttype) 35 { 36 timerType = ttype; 37 readingTime = TimerFactory::createTimer(timerType); 38 solvingTime = TimerFactory::createTimer(timerType); 39 preprocessingTime = TimerFactory::createTimer(timerType); 40 simplexTime = TimerFactory::createTimer(timerType); 41 syncTime = TimerFactory::createTimer(timerType); 42 transformTime = TimerFactory::createTimer(timerType); 43 rationalTime = TimerFactory::createTimer(timerType); 44 initialPrecisionTime = TimerFactory::createTimer(timerType); 45 extendedPrecisionTime = TimerFactory::createTimer(timerType); 46 reconstructionTime = TimerFactory::createTimer(timerType); 47 boostingStepTime = TimerFactory::createTimer(timerType); 48 clearAllData(); 49 } 50 51 /// copy constructor 52 template <class R> 53 SoPlexBase<R>::Statistics::Statistics(const Statistics& base) 54 { 55 timerType = base.timerType; 56 readingTime = TimerFactory::createTimer(timerType); 57 solvingTime = TimerFactory::createTimer(timerType); 58 preprocessingTime = TimerFactory::createTimer(timerType); 59 simplexTime = TimerFactory::createTimer(timerType); 60 syncTime = TimerFactory::createTimer(timerType); 61 transformTime = TimerFactory::createTimer(timerType); 62 rationalTime = TimerFactory::createTimer(timerType); 63 initialPrecisionTime = TimerFactory::createTimer(timerType); 64 extendedPrecisionTime = TimerFactory::createTimer(timerType); 65 reconstructionTime = TimerFactory::createTimer(timerType); 66 boostingStepTime = TimerFactory::createTimer(timerType); 67 clearAllData(); 68 } 69 70 /// assignment operator 71 template <class R> 72 typename SoPlexBase<R>::Statistics& SoPlexBase<R>::Statistics::operator=(const Statistics& rhs) 73 { 74 *readingTime = *(rhs.readingTime); 75 *solvingTime = *(rhs.solvingTime); 76 *preprocessingTime = *(rhs.preprocessingTime); 77 *simplexTime = *(rhs.simplexTime); 78 *syncTime = *(rhs.syncTime); 79 *transformTime = *(rhs.transformTime); 80 *rationalTime = *(rhs.rationalTime); 81 *initialPrecisionTime = *(rhs.initialPrecisionTime); 82 *extendedPrecisionTime = *(rhs.extendedPrecisionTime); 83 *reconstructionTime = *(rhs.reconstructionTime); 84 *boostingStepTime = *(rhs.boostingStepTime); 85 timerType = rhs.timerType; 86 multTimeSparse = rhs.multTimeSparse; 87 multTimeFull = rhs.multTimeFull; 88 multTimeColwise = rhs.multTimeColwise; 89 multTimeUnsetup = rhs.multTimeUnsetup; 90 multSparseCalls = rhs.multSparseCalls; 91 multFullCalls = rhs.multFullCalls; 92 multColwiseCalls = rhs.multColwiseCalls; 93 multUnsetupCalls = rhs.multUnsetupCalls; 94 luFactorizationTimeReal = rhs.luFactorizationTimeReal; 95 luSolveTimeReal = rhs.luSolveTimeReal; 96 luFactorizationTimeRational = rhs.luFactorizationTimeRational; 97 luSolveTimeRational = rhs.luSolveTimeRational; 98 fpTime = rhs.fpTime; 99 iterations = rhs.iterations; 100 iterationsPrimal = rhs.iterationsPrimal; 101 iterationsFromBasis = rhs.iterationsFromBasis; 102 iterationsPolish = rhs.iterationsPolish; 103 iterationsFP = rhs.iterationsFP; 104 boundflips = rhs.boundflips; 105 boostedIterations = rhs.boostedIterations; 106 boostedIterationsPrimal = rhs.boostedIterationsPrimal; 107 boostedIterationsFromBasis = rhs.boostedIterationsFromBasis; 108 boostedIterationsPolish = rhs.boostedIterationsPolish; 109 boostedBoundflips = rhs.boostedBoundflips; 110 luFactorizationsReal = rhs.luFactorizationsReal; 111 luSolvesReal = rhs.luSolvesReal; 112 luFactorizationsRational = rhs.luFactorizationsRational; 113 rationalReconstructions = rhs.rationalReconstructions; 114 refinements = rhs.refinements; 115 stallRefinements = rhs.stallRefinements; 116 pivotRefinements = rhs.pivotRefinements; 117 feasRefinements = rhs.feasRefinements; 118 unbdRefinements = rhs.unbdRefinements; 119 precBoosts = rhs.precBoosts; 120 stallPrecBoosts = rhs.stallPrecBoosts; 121 pivotPrecBoosts = rhs.pivotPrecBoosts; 122 feasPrecBoosts = rhs.feasPrecBoosts; 123 unbdPrecBoosts = rhs.unbdPrecBoosts; 124 125 return *this; 126 } 127 128 /// clears all statistics 129 template <class R> 130 void SoPlexBase<R>::Statistics::clearAllData() 131 { 132 readingTime->reset(); 133 clearSolvingData(); 134 } 135 136 /// clears statistics on solving process 137 template <class R> 138 void SoPlexBase<R>::Statistics::clearSolvingData() 139 { 140 solvingTime->reset(); 141 preprocessingTime->reset(); 142 simplexTime->reset(); 143 syncTime->reset(); 144 transformTime->reset(); 145 rationalTime->reset(); 146 initialPrecisionTime->reset(); 147 extendedPrecisionTime->reset(); 148 reconstructionTime->reset(); 149 boostingStepTime->reset(); 150 multTimeSparse = 0.0; 151 multTimeFull = 0.0; 152 multTimeColwise = 0.0; 153 multTimeUnsetup = 0.0; 154 multSparseCalls = 0; 155 multFullCalls = 0; 156 multColwiseCalls = 0; 157 multUnsetupCalls = 0; 158 luFactorizationTimeReal = 0.0; 159 luSolveTimeReal = 0.0; 160 luFactorizationTimeRational = 0.0; 161 luSolveTimeRational = 0.0; 162 fpTime = 0.0; 163 iterations = 0; 164 iterationsPrimal = 0; 165 iterationsFromBasis = 0; 166 iterationsPolish = 0; 167 iterationsFP = 0; 168 boundflips = 0; 169 boostedIterations = 0; 170 boostedIterationsPrimal = 0; 171 boostedIterationsFromBasis = 0; 172 boostedIterationsPolish = 0; 173 boostedBoundflips = 0; 174 luFactorizationsReal = 0; 175 luSolvesReal = 0; 176 luFactorizationsRational = 0; 177 rationalReconstructions = 0; 178 refinements = 0; 179 stallRefinements = 0; 180 pivotRefinements = 0; 181 feasRefinements = 0; 182 unbdRefinements = 0; 183 precBoosts = 0; 184 stallPrecBoosts = 0; 185 pivotPrecBoosts = 0; 186 feasPrecBoosts = 0; 187 unbdPrecBoosts = 0; 188 189 callsReducedProb = 0; 190 iterationsInit = 0; 191 iterationsRedProb = 0; 192 iterationsCompProb = 0; 193 numRedProbRows = 0; 194 numRedProbCols = 0; 195 degenPivotsPrimal = 0; 196 degenPivotsDual = 0; 197 degenPivotCandPrimal = 0; 198 degenPivotCandDual = 0; 199 sumDualDegen = 0; 200 sumPrimalDegen = 0; 201 decompBasisCondNum = 0; 202 totalBoundViol = 0; 203 totalRowViol = 0; 204 maxBoundViol = 0; 205 maxRowViol = 0; 206 redProbStatus = 0; 207 compProbStatus = 0; 208 finalCompObj = 0; 209 finalBasisCondition = 0; 210 } 211 212 /// prints statistics 213 template <class R> 214 void SoPlexBase<R>::Statistics::print(std::ostream& os) 215 { 216 Real solTime = solvingTime->time(); 217 Real totTime = readingTime->time() + solTime; 218 Real otherTime = solTime - syncTime->time() - transformTime->time() - preprocessingTime->time() - 219 simplexTime->time() - rationalTime->time(); 220 221 R avgPrimalDegeneracy = iterationsPrimal > 0 ? sumPrimalDegen / iterationsPrimal : 0.0; 222 R avgDualDegeneracy = (iterations - iterationsPrimal) > 0 ? 223 (sumDualDegen / (iterations - iterationsPrimal)) : 0.0; 224 225 SPxOut::setFixed(os, 2); 226 227 os << "Total time : " << totTime << "\n" 228 << " Reading : " << readingTime->time() << "\n" 229 << " Solving : " << solTime << "\n" 230 << " Preprocessing : " << preprocessingTime->time(); 231 232 if(solTime > 0) 233 os << " (" << 100 * (preprocessingTime->time() / solTime) << "% of solving time)"; 234 235 os << "\n Simplex : " << simplexTime->time(); 236 237 if(solTime > 0) 238 os << " (" << 100 * (simplexTime->time() / solTime) << "% of solving time)"; 239 240 os << "\n Synchronization : " << syncTime->time(); 241 242 if(solTime > 0) 243 os << " (" << 100 * (syncTime->time() / solTime) << "% of solving time)"; 244 245 os << "\n Transformation : " << transformTime->time(); 246 247 if(solTime > 0) 248 os << " (" << 100 * transformTime->time() / solTime << "% of solving time)"; 249 250 os << "\n Rational : " << rationalTime->time(); 251 252 if(solTime > 0) 253 os << " (" << 100 * rationalTime->time() / solTime << "% of solving time)"; 254 255 os << "\n InitialPrecision : " << initialPrecisionTime->time(); 256 257 if(solTime > 0) 258 os << " (" << 100 * initialPrecisionTime->time() / solTime << "% of solving time)"; 259 260 os << "\n ExtendedPrecision : " << extendedPrecisionTime->time(); 261 262 if(solTime > 0) 263 os << " (" << 100 * extendedPrecisionTime->time() / solTime << "% of solving time)"; 264 265 os << "\n BoostingStep : " << boostingStepTime->time(); 266 267 if(solTime > 0) 268 os << " (" << 100 * boostingStepTime->time() / solTime << "% of solving time)"; 269 270 os << "\n FpTime : " << fpTime; 271 272 if(solTime > 0) 273 os << " (" << 100 * fpTime / solTime << "% of solving time)"; 274 275 os << "\n Other : " << otherTime; 276 277 if(solTime > 0) 278 os << " (" << 100 * otherTime / solTime << "% of solving time)"; 279 280 os << "\nRefinements : " << refinements << "\n" 281 << " Stalling : " << stallRefinements << "\n" 282 << " Pivoting : " << pivotRefinements << "\n" 283 << " Feasibility : " << feasRefinements << "\n" 284 << " Unboundedness : " << unbdRefinements << "\n"; 285 286 os << "Precision boosts : " << precBoosts << "\n" 287 << " Stalling : " << stallPrecBoosts << "\n" 288 << " Pivoting : " << pivotPrecBoosts << "\n" 289 << " Feasibility : " << feasPrecBoosts << "\n" 290 << " Unboundedness : " << unbdPrecBoosts << "\n"; 291 292 os << "Iterations : " << iterations << "\n" 293 << " From scratch : " << iterations - iterationsFromBasis; 294 295 if(iterations > 0) 296 os << " (" << 100 * double((iterations - iterationsFromBasis)) / double(iterations) << "%)"; 297 298 os << "\n From basis : " << iterationsFromBasis; 299 300 if(iterations > 0) 301 os << " (" << 100 * double(iterationsFromBasis) / double(iterations) << "%)"; 302 303 os << "\n Primal : " << iterationsPrimal; 304 305 if(iterations > 0) 306 os << " (" << 100 * double(iterationsPrimal) / double(iterations) << "%)"; 307 308 os << "\n Dual : " << iterations - iterationsPrimal - iterationsPolish; 309 310 if(iterations > 0) 311 os << " (" << 100 * double((iterations - iterationsPrimal)) / double(iterations) << "%)"; 312 313 os << "\n Bound flips : " << boundflips; 314 os << "\n Sol. polishing : " << iterationsPolish; 315 os << "\n First FP solve : " << iterationsFP; 316 317 os << "\nIterationsBoosted : " << boostedIterations << "\n" 318 << " From scratch : " << int(boostedIterations - boostedIterationsFromBasis); 319 320 if(boostedIterations > 0) 321 os << " (" << 100 * double((boostedIterations - boostedIterationsFromBasis)) / double( 322 boostedIterations) << "%)"; 323 324 os << "\n From basis : " << boostedIterationsFromBasis; 325 326 if(boostedIterations > 0) 327 os << " (" << 100 * double(boostedIterationsFromBasis) / double(boostedIterations) << "%)"; 328 329 os << "\n Primal : " << boostedIterationsPrimal; 330 331 if(boostedIterations > 0) 332 os << " (" << 100 * double(boostedIterationsPrimal) / double(boostedIterations) << "%)"; 333 334 os << "\n Dual : " << boostedIterations - boostedIterationsPrimal - 335 boostedIterationsPolish; 336 337 if(boostedIterations > 0) 338 os << " (" << 100 * double((boostedIterations - boostedIterationsPrimal)) / double( 339 boostedIterations) << "%)"; 340 341 os << "\n Bound flips : " << boostedBoundflips; 342 os << "\n Sol. polishing : " << boostedIterationsPolish; 343 344 os << "\nLU factorizations : " << luFactorizationsReal << "\n" 345 << " Factor. frequency : "; 346 347 if(luFactorizationsReal > 0) 348 os << double(iterations) / double(luFactorizationsReal) << " iterations per factorization\n"; 349 else 350 os << "-\n"; 351 352 os << " Factor. time : " << luFactorizationTimeReal << "\n"; 353 354 os << "LU solves : " << luSolvesReal << "\n" 355 << " Solve frequency : "; 356 357 if(iterations > 0) 358 os << double(luSolvesReal) / double(iterations) << " solves per iteration\n"; 359 else 360 os << "-\n"; 361 362 os << " Solve time : " << luSolveTimeReal << "\n"; 363 364 os << "Matrix-Vector ops : \n" 365 << " Sparse time : " << multTimeSparse; 366 367 if(solTime > 0) 368 os << " (" << 100 * (multTimeSparse / solTime) << "% of solving time)"; 369 370 os << "\n calls : " << multSparseCalls; 371 os << " (" << 100 * (multSparseCalls / (0.01 + iterations)) << "% of iterations)"; 372 os << "\n Full time : " << multTimeFull; 373 374 if(solTime > 0) 375 os << " (" << 100 * (multTimeFull / solTime) << "% of solving time)"; 376 377 os << "\n calls : " << multFullCalls; 378 os << " (" << 100 * (multFullCalls / (0.01 + iterations)) << "% of iterations)"; 379 os << "\n Colwise time : " << multTimeColwise; 380 381 if(solTime > 0) 382 os << " (" << 100 * (multTimeColwise / solTime) << "% of solving time)"; 383 384 os << "\n calls : " << multColwiseCalls; 385 os << " (" << 100 * (multColwiseCalls / (0.01 + iterations)) << "% of iterations)"; 386 os << "\n Unsetup time : " << multTimeUnsetup; 387 388 if(solTime > 0) 389 os << " (" << 100 * (multTimeUnsetup / solTime) << "% of solving time)"; 390 391 os << "\n calls : " << multUnsetupCalls; 392 os << " (" << 100 * (multUnsetupCalls / (0.01 + iterations)) << "% of iterations)"; 393 os << "\n"; 394 395 os << "Rat. factorizations : " << luFactorizationsRational << "\n" 396 << " Rat. factor. time : " << luFactorizationTimeRational << "\n" 397 << " Rat. solve time : " << luSolveTimeRational << "\n"; 398 399 os << "Rat. reconstructions: " << rationalReconstructions << "\n" 400 << " Rat. rec. time : " << reconstructionTime->time() << "\n"; 401 402 os << "Degeneracy : \n"; 403 os << " Primal Pivots : " << degenPivotsPrimal << "\n"; 404 os << " Dual Pivots : " << degenPivotsDual << "\n"; 405 os << " Primal Candidates : " << degenPivotCandPrimal << "\n"; 406 os << " Dual Candidates : " << degenPivotCandDual << "\n"; 407 os << " Average Primal : " << avgPrimalDegeneracy << "\n"; 408 os << " Average Dual : " << avgDualDegeneracy << "\n"; 409 410 if(iterationsInit > 0) 411 { 412 os << "Algorithm Iterations: " << callsReducedProb << "\n"; 413 os << "Decomp. Iterations : \n"; 414 os << " Total : " << iterationsInit + iterationsRedProb << "\n"; 415 os << " Initial : " << iterationsInit << "\n"; 416 os << " Reduced Problem : " << iterationsRedProb << "\n"; 417 os << " Comp. Problem : " << iterationsCompProb << "\n"; 418 os << "Red. Problem Size : \n"; 419 os << " Rows : " << numRedProbRows << "\n"; 420 os << " Columns : " << numRedProbCols << "\n"; 421 422 SPxOut::setScientific(os, 16); 423 424 os << "Decomp. Basis Cond. : " << decompBasisCondNum << "\n"; 425 os << "Decomp Violations : \n"; 426 os << " Sum Bound : " << totalBoundViol << "\n"; 427 os << " Sum Row : " << totalRowViol << "\n"; 428 os << " Max Bound : " << maxBoundViol << "\n"; 429 os << " Max Row : " << maxRowViol << "\n"; 430 431 SPxOut::setFixed(os, 2); 432 433 os << "Red. Problem Status : " << redProbStatus << "\n"; 434 os << "Comp. Problem Status: " << compProbStatus << "\n"; 435 436 SPxOut::setScientific(os, 16); 437 438 os << "Comp. Problem Obj. : " << finalCompObj << "\n"; 439 } 440 441 SPxOut::setScientific(os); 442 443 os << "Numerics :\n"; 444 os << " Condition Number : " << finalBasisCondition << "\n"; 445 446 } 447 } // namespace soplex 448