@@ -2195,6 +2195,57 @@ dual::status_t dual_phase2(i_t phase,
21952195 std::vector<i_t > nonbasic_list;
21962196 std::vector<i_t > superbasic_list;
21972197
2198+ phase2::bound_info (lp, settings);
2199+ get_basis_from_vstatus (m, vstatus, basic_list, nonbasic_list, superbasic_list);
2200+ assert (superbasic_list.size () == 0 );
2201+ assert (nonbasic_list.size () == n - m);
2202+
2203+ basis_update_mpf_t <i_t , f_t > ft (m, settings.refactor_frequency );
2204+
2205+ if (ft.factorize_basis (lp.A , settings, basic_list, nonbasic_list, vstatus) > 0 ) {
2206+ return dual::status_t ::NUMERICAL;
2207+ }
2208+
2209+ if (toc (start_time) > settings.time_limit ) { return dual::status_t ::TIME_LIMIT; }
2210+ return dual_phase2_with_basis_update (phase,
2211+ slack_basis,
2212+ start_time,
2213+ lp,
2214+ settings,
2215+ vstatus,
2216+ ft,
2217+ basic_list,
2218+ nonbasic_list,
2219+ sol,
2220+ iter,
2221+ delta_y_steepest_edge);
2222+ }
2223+
2224+ template <typename i_t , typename f_t >
2225+ dual::status_t dual_phase2_with_basis_update (i_t phase,
2226+ i_t slack_basis,
2227+ f_t start_time,
2228+ const lp_problem_t <i_t , f_t >& lp,
2229+ const simplex_solver_settings_t <i_t , f_t >& settings,
2230+ std::vector<variable_status_t >& vstatus,
2231+ basis_update_mpf_t <i_t , f_t >& ft,
2232+ std::vector<i_t >& basic_list,
2233+ std::vector<i_t >& nonbasic_list,
2234+ lp_solution_t <i_t , f_t >& sol,
2235+ i_t & iter,
2236+ std::vector<f_t >& delta_y_steepest_edge)
2237+ {
2238+ const i_t m = lp.num_rows ;
2239+ const i_t n = lp.num_cols ;
2240+ assert (m <= n);
2241+ assert (vstatus.size () == n);
2242+ assert (lp.A .m == m);
2243+ assert (lp.A .n == n);
2244+ assert (lp.objective .size () == n);
2245+ assert (lp.lower .size () == n);
2246+ assert (lp.upper .size () == n);
2247+ assert (lp.rhs .size () == m);
2248+
21982249 std::vector<f_t >& x = sol.x ;
21992250 std::vector<f_t >& y = sol.y ;
22002251 std::vector<f_t >& z = sol.z ;
@@ -2208,35 +2259,6 @@ dual::status_t dual_phase2(i_t phase,
22082259 std::vector<variable_status_t > vstatus_old = vstatus;
22092260 std::vector<f_t > z_old = z;
22102261
2211- phase2::bound_info (lp, settings);
2212- get_basis_from_vstatus (m, vstatus, basic_list, nonbasic_list, superbasic_list);
2213- assert (superbasic_list.size () == 0 );
2214- assert (nonbasic_list.size () == n - m);
2215-
2216- // Compute L*U = A(p, basic_list)
2217- csc_matrix_t <i_t , f_t > L (m, m, 1 );
2218- csc_matrix_t <i_t , f_t > U (m, m, 1 );
2219- std::vector<i_t > pinv (m);
2220- std::vector<i_t > p;
2221- std::vector<i_t > q;
2222- std::vector<i_t > deficient;
2223- std::vector<i_t > slacks_needed;
2224-
2225- if (factorize_basis (lp.A , settings, basic_list, L, U, p, pinv, q, deficient, slacks_needed) ==
2226- -1 ) {
2227- settings.log .debug (" Initial factorization failed\n " );
2228- basis_repair (lp.A , settings, deficient, slacks_needed, basic_list, nonbasic_list, vstatus);
2229- if (factorize_basis (lp.A , settings, basic_list, L, U, p, pinv, q, deficient, slacks_needed) ==
2230- -1 ) {
2231- return dual::status_t ::NUMERICAL;
2232- }
2233- settings.log .printf (" Basis repaired\n " );
2234- }
2235- if (toc (start_time) > settings.time_limit ) { return dual::status_t ::TIME_LIMIT; }
2236- assert (q.size () == m);
2237- reorder_basic_list (q, basic_list);
2238- basis_update_mpf_t <i_t , f_t > ft (L, U, p, settings.refactor_frequency );
2239-
22402262 std::vector<f_t > c_basic (m);
22412263 for (i_t k = 0 ; k < m; ++k) {
22422264 const i_t j = basic_list[k];
@@ -2872,48 +2894,27 @@ dual::status_t dual_phase2(i_t phase,
28722894#endif
28732895 if (should_refactor) {
28742896 bool should_recompute_x = false ;
2875- if (factorize_basis (lp.A , settings, basic_list, L, U, p, pinv, q, deficient, slacks_needed) ==
2876- -1 ) {
2897+ if (ft.factorize_basis (lp.A , settings, basic_list, nonbasic_list, vstatus) > 0 ) {
28772898 should_recompute_x = true ;
28782899 settings.log .printf (" Failed to factorize basis. Iteration %d\n " , iter);
28792900 if (toc (start_time) > settings.time_limit ) { return dual::status_t ::TIME_LIMIT; }
2880- basis_repair (lp.A , settings, deficient, slacks_needed, basic_list, nonbasic_list, vstatus);
28812901 i_t count = 0 ;
2882- while (factorize_basis (
2883- lp.A , settings, basic_list, L, U, p, pinv, q, deficient, slacks_needed) == -1 ) {
2902+ i_t deficient_size;
2903+ while ((deficient_size =
2904+ ft.factorize_basis (lp.A , settings, basic_list, nonbasic_list, vstatus)) > 0 ) {
28842905 settings.log .printf (" Failed to repair basis. Iteration %d. %d deficient columns.\n " ,
28852906 iter,
2886- static_cast <int >(deficient. size () ));
2907+ static_cast <int >(deficient_size ));
28872908 if (toc (start_time) > settings.time_limit ) { return dual::status_t ::TIME_LIMIT; }
28882909 settings.threshold_partial_pivoting_tol = 1.0 ;
2910+
28892911 count++;
28902912 if (count > 10 ) { return dual::status_t ::NUMERICAL; }
2891- basis_repair (
2892- lp.A , settings, deficient, slacks_needed, basic_list, nonbasic_list, vstatus);
2893-
2894- #ifdef CHECK_BASIS_REPAIR
2895- csc_matrix_t <i_t , f_t > B (m, m, 0 );
2896- form_b (lp.A , basic_list, B);
2897- for (i_t k = 0 ; k < deficient.size (); ++k) {
2898- const i_t j = deficient[k];
2899- const i_t col_start = B.col_start [j];
2900- const i_t col_end = B.col_start [j + 1 ];
2901- const i_t col_nz = col_end - col_start;
2902- if (col_nz != 1 ) {
2903- settings.log .printf (" Deficient column %d has %d nonzeros\n " , j, col_nz);
2904- }
2905- const i_t i = B.i [col_start];
2906- if (i != slacks_needed[k]) {
2907- settings.log .printf (" Slack %d needed but found %d instead\n " , slacks_needed[k], i);
2908- }
2909- }
2910- #endif
29112913 }
29122914
29132915 settings.log .printf (" Successfully repaired basis. Iteration %d\n " , iter);
29142916 }
2915- reorder_basic_list (q, basic_list);
2916- ft.reset (L, U, p);
2917+
29172918 phase2::reset_basis_mark (basic_list, nonbasic_list, basic_mark, nonbasic_mark);
29182919 if (should_recompute_x) {
29192920 std::vector<f_t > unperturbed_x (n);
0 commit comments