@@ -52,6 +52,7 @@ void Solver::setOptions(const HighsOptions& highs_options) {
5252 options_.parallel_type = highs_options.hipo_parallel_type ;
5353 options_.nla = highs_options.hipo_system ;
5454 options_.ordering = highs_options.hipo_ordering ;
55+ options_.factor = highs_options.hipo_factor ;
5556 options_.block_size = highs_options.hipo_block_size ;
5657
5758 options_orig_ = options_;
@@ -156,22 +157,7 @@ bool Solver::initialise() {
156157 }
157158 LS_ ->clear ();
158159
159- // Use uplooking factorisation instead of multifrontal if
160- // - very few operations needed or
161- // - very few nz per column in L or
162- // - multifrontal is dominated by assembly operations
163- bool switch_to_uplooking =
164- LS_ ->flops () < kUplookFlopsThresh ||
165- LS_ ->nz () < kUplookNzPerColLower * kkt_->n () ||
166- LS_ ->flops () < kUplookSpopsRatioLower * LS_ ->spops () ||
167- (LS_ ->nz () < kUplookNzPerColUpper * kkt_->n () &&
168- LS_ ->flops () < kUplookSpopsRatioUpper * LS_ ->spops ());
169-
170- if (switch_to_uplooking) {
171- LS_ .reset (new UpLookingSolver (*kkt_, info_, it_->data , regul_, model_));
172- LS_ ->setup ();
173- LS_ ->clear ();
174- }
160+ chooseFactorisation ();
175161
176162 it_->data .append ();
177163 it_->data .back ().factorisation_used = LS_ ->type ();
@@ -356,22 +342,14 @@ bool Solver::solveNewtonSystem(NewtonDir& delta) {
356342 }
357343
358344 if (terminate) {
359- if (LS_ -> type () == kUpLookingType ) {
345+ if (switchToMultifrontal () ) {
360346 // try FactorHighs factorisation before giving up
361- LS_ .reset (new FactorHighsSolver (*kkt_, options_, model_, regul_, info_,
362- it_->data , logger_));
363- if (!LS_ ) {
364- info_.status = kStatusError ;
365- return true ;
366- }
367- LS_ ->clear ();
368347 it_->data .back ().factorisation_used = LS_ ->type ();
369- it_->bad_iter_ = 0 ;
370348 logger_.printInfo (" Switching to FactorHighs because of bad direction\n " );
371349 resetToBestIter (iter_ - 1 );
372350
373- // Solve again. This does not create an infinite loop, as the if statement
374- // cannot trigger in the second solve.
351+ // Solve again. This does not create an infinite loop, as
352+ // switchToMultifrontal() is false in the second solve.
375353 delta.clear ();
376354 it_->data .back ().omega = 0.0 ;
377355 terminate = solveNewtonSystem (delta);
@@ -1106,16 +1084,7 @@ bool Solver::checkBadIter() {
11061084 info_.status = kStatusPrimalInfeasible ;
11071085 terminate = true ;
11081086 } else if (stagnation) {
1109- if (LS_ ->type () == kUpLookingType ) {
1110- // try FactorHighs factorisation before giving up
1111- LS_ .reset (new FactorHighsSolver (*kkt_, options_, model_, regul_, info_,
1112- it_->data , logger_));
1113- if (!LS_ ) {
1114- info_.status = kStatusError ;
1115- return true ;
1116- }
1117- LS_ ->clear ();
1118- it_->bad_iter_ = 0 ;
1087+ if (switchToMultifrontal ()) {
11191088 logger_.printInfo (" Switching to FactorHighs because of no progress\n " );
11201089 resetToBestIter (iter_);
11211090 } else {
@@ -1222,6 +1191,49 @@ void Solver::resetToBestIter(Int iter, bool print) {
12221191 if (did_reset && print) printOutput (true );
12231192}
12241193
1194+ void Solver::chooseFactorisation () {
1195+ // Use uplooking factorisation instead of multifrontal if
1196+ // - very few operations needed or
1197+ // - very few nz per column in L or
1198+ // - multifrontal is dominated by assembly operations
1199+ const bool should_switch_to_uplooking =
1200+ LS_ ->flops () < kUplookFlopsThresh ||
1201+ LS_ ->nz () < kUplookNzPerColLower * kkt_->n () ||
1202+ LS_ ->flops () < kUplookSpopsRatioLower * LS_ ->spops () ||
1203+ (LS_ ->nz () < kUplookNzPerColUpper * kkt_->n () &&
1204+ LS_ ->flops () < kUplookSpopsRatioUpper * LS_ ->spops ());
1205+
1206+ bool do_switch;
1207+ if (options_.factor == kHipoFactorMultifrontal )
1208+ do_switch = false ;
1209+ else if (options_.factor == kHipoFactorUplooking )
1210+ do_switch = true ;
1211+ else
1212+ do_switch = should_switch_to_uplooking;
1213+
1214+ if (do_switch) {
1215+ LS_ .reset (new UpLookingSolver (*kkt_, info_, it_->data , regul_, model_));
1216+ LS_ ->setup ();
1217+ LS_ ->clear ();
1218+ }
1219+ }
1220+
1221+ bool Solver::switchToMultifrontal () {
1222+ // return true if switch successfull
1223+ if (LS_ ->type () == kUpLookingType && options_.factor == kHighsChooseString ) {
1224+ LS_ .reset (new FactorHighsSolver (*kkt_, options_, model_, regul_, info_,
1225+ it_->data , logger_));
1226+ if (!LS_ ) {
1227+ info_.status = kStatusError ;
1228+ return false ;
1229+ }
1230+ LS_ ->clear ();
1231+ it_->bad_iter_ = 0 ;
1232+ return true ;
1233+ }
1234+ return false ;
1235+ }
1236+
12251237void Solver::printHeader () const {
12261238 if (iter_ % 20 == 0 ) {
12271239 logger_.print (
0 commit comments