| 354 | } |
| 355 | |
| 356 | HighsInt HFactor::build(HighsTimerClock* factor_timer_clock_pointer) { |
| 357 | // Set up a timer to prevent build running longer than time_limit_, |
| 358 | // which is kHighsInf by default, and only set to a finite value in |
| 359 | // HPresolve::removeDependentEquations |
| 360 | HighsTimer build_timer; |
| 361 | build_timer_ = &build_timer; |
| 362 | build_timer.start(); |
| 363 | |
| 364 | const bool report_lu = false; |
| 365 | // Ensure that the A matrix is valid for factorization |
| 366 | assert(this->a_matrix_valid); |
| 367 | FactorTimer factor_timer; |
| 368 | // Possibly use the refactorization information! |
| 369 | if (refactor_info_.use) { |
| 370 | factor_timer.start(FactorReinvert, factor_timer_clock_pointer); |
| 371 | rank_deficiency = rebuild(factor_timer_clock_pointer); |
| 372 | factor_timer.stop(FactorReinvert, factor_timer_clock_pointer); |
| 373 | if (!rank_deficiency) return 0; |
| 374 | } |
| 375 | // Refactoring from just the list of basic variables. Initialise the |
| 376 | // refactorization information. |
| 377 | refactor_info_.clear(); |
| 378 | // Start the timer |
| 379 | factor_timer.start(FactorInvert, factor_timer_clock_pointer); |
| 380 | build_synthetic_tick = 0; |
| 381 | factor_timer.start(FactorInvertSimple, factor_timer_clock_pointer); |
| 382 | // Build the L, U factor |
| 383 | buildSimple(); |
| 384 | if (report_lu) { |
| 385 | printf("\nAfter units and singletons\n"); |
| 386 | reportLu(kReportLuBoth, false); |
| 387 | } |
| 388 | factor_timer.stop(FactorInvertSimple, factor_timer_clock_pointer); |
| 389 | factor_timer.start(FactorInvertKernel, factor_timer_clock_pointer); |
| 390 | const HighsInt build_kernel_return = buildKernel(); |
| 391 | factor_timer.stop(FactorInvertKernel, factor_timer_clock_pointer); |
| 392 | // |
| 393 | // build_kernel_return of kBuildKernelReturnTimeout (<0) indicates |
| 394 | // that time limit has been reached, otherwise it's the rank |
| 395 | // deficiency of the basic variables. If num_basic < num_row, then |
| 396 | // have to identify the logicals required to complete the basis by |
| 397 | // continuing as if a full-dimension set of basic variables was rank |
| 398 | // deficient. |
| 399 | if (build_kernel_return == kBuildKernelReturnTimeout) |
| 400 | return kBuildKernelReturnTimeout; |
| 401 | rank_deficiency = build_kernel_return; |
| 402 | const bool incomplete_basis = num_basic < num_row; |
| 403 | if (rank_deficiency || incomplete_basis) { |
| 404 | factor_timer.start(FactorInvertDeficient, factor_timer_clock_pointer); |
| 405 | if (num_basic == num_row) |
| 406 | highsLogDev(log_options, HighsLogType::kWarning, |
| 407 | "Rank deficiency of %" HIGHSINT_FORMAT |
| 408 | " identified in basis matrix\n", |
| 409 | rank_deficiency); |
| 410 | // Singular matrix B: reorder the basic variables so that the |
| 411 | // singular columns are in the position corresponding to the |
| 412 | // logical which replaces them |
| 413 | buildHandleRankDeficiency(); |