diff --git a/src/ipm/ipx/ipm.cc b/src/ipm/ipx/ipm.cc index 4a21364951..d8860f19fc 100644 --- a/src/ipm/ipx/ipm.cc +++ b/src/ipm/ipx/ipm.cc @@ -856,7 +856,7 @@ void IPM::PrintOutput() { control_.Debug() << " " << Fixed(step_primal_, 4, 2) << " " << Fixed(step_dual_, 4, 2) << " " << Format(kkt_->basis_changes(), 7) - << " " << Format(kkt_->iter(), 7); + << " " << Format(kkt_->iterSum(), 7); control_.Debug() << " " << Format(info_->dual_dropped, 7) << " " << Format(info_->primal_dropped, 7); diff --git a/src/ipm/ipx/kkt_solver.cc b/src/ipm/ipx/kkt_solver.cc index dde0967e52..1aaee27133 100644 --- a/src/ipm/ipx/kkt_solver.cc +++ b/src/ipm/ipx/kkt_solver.cc @@ -16,7 +16,8 @@ void KKTSolver::Solve(const Vector& a, const Vector& b, double tol, info->time_kkt_solve += timer.Elapsed(); } -Int KKTSolver::iter() const { return _iter(); } +Int KKTSolver::iterSum() const { return _iterSum(); } + //Int KKTSolver::iterMax() const { return _iterMax(); } Int KKTSolver::basis_changes() const { return _basis_changes(); } const Basis* KKTSolver::basis() const { return _basis(); } diff --git a/src/ipm/ipx/kkt_solver.h b/src/ipm/ipx/kkt_solver.h index 3889f1b97c..5de82440db 100644 --- a/src/ipm/ipx/kkt_solver.h +++ b/src/ipm/ipx/kkt_solver.h @@ -46,7 +46,12 @@ class KKTSolver { // If an iterative method is used, returns the # iterations in all Solve() // calls since the last call to Factorize(). A direct solver returns the # // iterative refinement steps. - Int iter() const; + Int iterSum() const; + + // If an iterative method is used, returns the max # iterations in + // all Solve() calls since the last call to Factorize(). A direct + // solver returns the max # iterative refinement steps. + // Int iterMax() const; // If a basis matrix is maintained, returns the # basis changes in the last // call to Factorize(). Otherwise returns 0. @@ -60,7 +65,7 @@ class KKTSolver { virtual void _Factorize(Iterate* iterate, Info* info) = 0; virtual void _Solve(const Vector& a, const Vector& b, double tol, Vector& x, Vector& y, Info* info) = 0; - virtual Int _iter() const = 0; + virtual Int _iterSum() const = 0; virtual Int _basis_changes() const { return 0; } virtual const Basis* _basis() const { return nullptr; } }; diff --git a/src/ipm/ipx/kkt_solver_basis.cc b/src/ipm/ipx/kkt_solver_basis.cc index dddb35ec8b..e335ec9dba 100644 --- a/src/ipm/ipx/kkt_solver_basis.cc +++ b/src/ipm/ipx/kkt_solver_basis.cc @@ -20,7 +20,8 @@ void KKTSolverBasis::_Factorize(Iterate* iterate, Info* info) { const Int n = model_.cols(); info->errflag = 0; factorized_ = false; - iter_ = 0; + iter_sum_ = 0; + iter_max_ = 0; basis_changes_ = 0; for (Int j = 0; j < n+m; j++) @@ -152,7 +153,8 @@ void KKTSolverBasis::_Solve(const Vector& a, const Vector& b, double tol, info->time_cr2_NNt += splitted_normal_matrix_.time_NNt(); info->time_cr2_B += splitted_normal_matrix_.time_B(); info->time_cr2_Bt += splitted_normal_matrix_.time_Bt(); - iter_ += cr.iter(); + iter_sum_ += cr.iter(); + iter_max_ = std::max(cr.iter(), iter_max_); // Permute back solution to normal equations. for (Int k = 0; k < m; k++) diff --git a/src/ipm/ipx/kkt_solver_basis.h b/src/ipm/ipx/kkt_solver_basis.h index db7e1af131..da637324bd 100644 --- a/src/ipm/ipx/kkt_solver_basis.h +++ b/src/ipm/ipx/kkt_solver_basis.h @@ -33,7 +33,8 @@ class KKTSolverBasis : public KKTSolver { void _Factorize(Iterate* iterate, Info* info) override; void _Solve(const Vector& a, const Vector& b, double tol, Vector& x, Vector& y, Info* info) override; - Int _iter() const override { return iter_; } + Int _iterSum() const override { return iter_sum_; } + // Int _iterMax() const override { return iter_max_; } Int _basis_changes() const override { return basis_changes_; } const Basis* _basis() const override { return &basis_; } @@ -57,7 +58,8 @@ class KKTSolverBasis : public KKTSolver { Vector colscale_; // interior point column scaling factors bool factorized_{false}; // preconditioner prepared? Int maxiter_{-1}; - Int iter_{0}; + Int iter_sum_{0}; + Int iter_max_{0}; Int basis_changes_{0}; }; diff --git a/src/ipm/ipx/kkt_solver_diag.cc b/src/ipm/ipx/kkt_solver_diag.cc index 382c9d06cc..4ff530cb37 100644 --- a/src/ipm/ipx/kkt_solver_diag.cc +++ b/src/ipm/ipx/kkt_solver_diag.cc @@ -18,7 +18,8 @@ KKTSolverDiag::KKTSolverDiag(const Control& control, const Model& model) : void KKTSolverDiag::_Factorize(Iterate* pt, Info* info) { const Int m = model_.rows(); const Int n = model_.cols(); - iter_ = 0; + iter_sum_ = 0; + iter_max_ = 0; factorized_ = false; if (pt) { @@ -102,7 +103,8 @@ void KKTSolverDiag::_Solve(const Vector& a, const Vector& b, double tol, info->time_cr1 += cr.time(); info->time_cr1_AAt += normal_matrix_.time(); info->time_cr1_pre += precond_.time(); - iter_ += cr.iter(); + iter_sum_ += cr.iter(); + iter_max_ = std::max(cr.iter(), iter_max_); // Recover solution to KKT system. for (Int i = 0; i < m; i++) diff --git a/src/ipm/ipx/kkt_solver_diag.h b/src/ipm/ipx/kkt_solver_diag.h index 31a2b708ba..66029e0a6a 100644 --- a/src/ipm/ipx/kkt_solver_diag.h +++ b/src/ipm/ipx/kkt_solver_diag.h @@ -29,7 +29,8 @@ class KKTSolverDiag : public KKTSolver { void _Factorize(Iterate* iterate, Info* info) override; void _Solve(const Vector& a, const Vector& b, double tol, Vector& x, Vector& y, Info* info) override; - Int _iter() const override { return iter_; }; + Int _iterSum() const override { return iter_sum_; }; + // Int _iterMax() const override { return iter_max_; }; const Control& control_; const Model& model_; @@ -40,7 +41,8 @@ class KKTSolverDiag : public KKTSolver { Vector resscale_; // residual scaling factors for CR termination test bool factorized_{false}; // KKT matrix factorized? Int maxiter_{-1}; - Int iter_{0}; // # CR iterations since last Factorize() + Int iter_sum_{0}; + Int iter_max_{0}; }; } // namespace ipx diff --git a/src/lp_data/HighsInfo.cpp b/src/lp_data/HighsInfo.cpp index 2792f64550..987c18cc70 100644 --- a/src/lp_data/HighsInfo.cpp +++ b/src/lp_data/HighsInfo.cpp @@ -41,6 +41,7 @@ void HighsInfo::invalidate() { max_complementarity_violation = kHighsIllegalComplementarityViolation; sum_complementarity_violations = kHighsIllegalComplementarityViolation; primal_dual_integral = -kHighsInf; + max_cr_iteration_count = -1; } static std::string infoEntryTypeToString(const HighsInfoType type) { diff --git a/src/lp_data/HighsInfo.h b/src/lp_data/HighsInfo.h index 3292b8281e..294b4350ed 100644 --- a/src/lp_data/HighsInfo.h +++ b/src/lp_data/HighsInfo.h @@ -116,6 +116,7 @@ struct HighsInfoStruct { double max_complementarity_violation; double sum_complementarity_violations; double primal_dual_integral; + HighsInt max_cr_iteration_count; }; class HighsInfo : public HighsInfoStruct { @@ -279,6 +280,11 @@ class HighsInfo : public HighsInfoStruct { new InfoRecordDouble("primal_dual_integral", "Primal-dual integral", advanced, &primal_dual_integral, 0); records.push_back(record_double); + + record_int = new InfoRecordInt("max_cr_iteration_count", + "Maximum number of CG iterations in IPX", advanced, + &max_cr_iteration_count, -1); + records.push_back(record_int); } public: