From a817a342d065225be34b9f00d2ba4adca7b0fea1 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Tue, 4 Aug 2026 14:34:37 +0200 Subject: [PATCH 01/11] Remove boolean vectors --- check/TestCheckSolution.cpp | 2 +- highs/Highs.h | 2 +- highs/io/HMpsFF.cpp | 4 +- highs/io/HMpsFF.h | 4 +- highs/ipm/hipo/factorhighs/Analyse.cpp | 2 +- highs/ipm/hipo/ipm/Model.cpp | 2 +- highs/ipm/hipo/ipm/UpLookingSolver.cpp | 2 +- highs/ipm/ipx/lu_factorization.cc | 117 +++-- highs/ipm/ipx/maxvolume.cc | 564 ++++++++++++------------- highs/lp_data/Highs.cpp | 2 +- highs/lp_data/HighsCallback.cpp | 2 +- highs/lp_data/HighsCallback.h | 2 +- highs/lp_data/HighsInterface.cpp | 18 +- highs/mip/HighsCutPool.h | 4 +- highs/pdlp/hipdlp/pdhg.hpp | 2 +- highs/presolve/HPresolveAnalysis.h | 2 +- 16 files changed, 363 insertions(+), 368 deletions(-) diff --git a/check/TestCheckSolution.cpp b/check/TestCheckSolution.cpp index 9cd858646c6..dbca4cdfa9e 100644 --- a/check/TestCheckSolution.cpp +++ b/check/TestCheckSolution.cpp @@ -289,7 +289,7 @@ TEST_CASE("check-set-mip-solution", "[highs_check_solution]") { index.clear(); value.clear(); - std::vector is_set; + std::vector is_set; is_set.assign(lp.num_col_, false); HighsInt num_to_set = 2; assert(num_to_set > 0); diff --git a/highs/Highs.h b/highs/Highs.h index 83beb8c0669..bbaf16951d3 100644 --- a/highs/Highs.h +++ b/highs/Highs.h @@ -1842,7 +1842,7 @@ class Highs { HighsStatus getIisInterface(); HighsStatus getIisInterfaceReturn( const HighsStatus return_status, const HighsOptions& original_options, - const std::vector& original_callbacks); + const std::vector& original_callbacks); HighsStatus elasticityFilterReturn( const HighsStatus return_status, const std::string& original_model_name, diff --git a/highs/io/HMpsFF.cpp b/highs/io/HMpsFF.cpp index 643434cbfb5..0f044cbcfa9 100644 --- a/highs/io/HMpsFF.cpp +++ b/highs/io/HMpsFF.cpp @@ -1269,8 +1269,8 @@ HMpsFF::Parsekey HMpsFF::parseBounds(const HighsLogOptions& log_options, HighsInt num_si = 0; HighsInt num_sc = 0; - std::vector has_lower; - std::vector has_upper; + std::vector has_lower; + std::vector has_upper; has_lower.assign(num_col, false); has_upper.assign(num_col, false); diff --git a/highs/io/HMpsFF.h b/highs/io/HMpsFF.h index ebd5c3707fe..42fb8ec8dcc 100644 --- a/highs/io/HMpsFF.h +++ b/highs/io/HMpsFF.h @@ -97,7 +97,7 @@ class HMpsFF { // that are defined as integer by markers in the column section, or // as binary by having a BV flag in the BOUNDS section, and without // any LI or UI flags in the BOUNDS section - std::vector col_binary; + std::vector col_binary; // Record where the cost row is encountered HighsInt cost_row_location; @@ -117,7 +117,7 @@ class HMpsFF { // file for the objective or a row. Have to be class data members so // that they can be used by parseName and addRhs in HMpsFF::parseRhs bool has_obj_entry_; - std::vector has_row_entry_; + std::vector has_row_entry_; /// load LP from MPS file as transposed triplet matrix HighsInt parseFile(std::string filename); diff --git a/highs/ipm/hipo/factorhighs/Analyse.cpp b/highs/ipm/hipo/factorhighs/Analyse.cpp index 2a7905a835d..3d9606b785b 100644 --- a/highs/ipm/hipo/factorhighs/Analyse.cpp +++ b/highs/ipm/hipo/factorhighs/Analyse.cpp @@ -210,7 +210,7 @@ void Analyse::fundamentalSupernodes() { // Find fundamental supernodes. // isSN[i] is true if node i is the start of a fundamental supernode - std::vector is_sn(n_, false); + std::vector is_sn(n_, false); std::vector prev_nonz(n_, -1); diff --git a/highs/ipm/hipo/ipm/Model.cpp b/highs/ipm/hipo/ipm/Model.cpp index 258ed462e62..9f1a5f15421 100644 --- a/highs/ipm/hipo/ipm/Model.cpp +++ b/highs/ipm/hipo/ipm/Model.cpp @@ -44,7 +44,7 @@ Int Model::init(const HighsLp& lp, const HighsHessian& Q) { void Model::nzBounds() { // compute lower and upper bounds for the number of nonzeros in normal // equations. - std::vector mark(m_, false); + std::vector mark(m_, false); NE_nz_lb_ = A_.num_row_; NE_nz_ub_ = A_.num_row_; for (Int col = 0; col < A_.num_col_; ++col) { diff --git a/highs/ipm/hipo/ipm/UpLookingSolver.cpp b/highs/ipm/hipo/ipm/UpLookingSolver.cpp index 6a5ba38299f..46085ea0766 100644 --- a/highs/ipm/hipo/ipm/UpLookingSolver.cpp +++ b/highs/ipm/hipo/ipm/UpLookingSolver.cpp @@ -92,7 +92,7 @@ void UpLookingSolver::factor(const std::vector& ptr, // A must be upper triangular. // L is computed as lower triangular. The diagonal of L is used to store D^-1. - std::vector mark(n_, false); + std::vector mark(n_, false); std::vector stack(n_); Int top = 0; std::vector revpattern(n_); diff --git a/highs/ipm/ipx/lu_factorization.cc b/highs/ipm/ipx/lu_factorization.cc index 71408501b98..4834eab0a16 100644 --- a/highs/ipm/ipx/lu_factorization.cc +++ b/highs/ipm/ipx/lu_factorization.cc @@ -1,6 +1,8 @@ #include "ipm/ipx/lu_factorization.h" + #include #include + #include "ipm/ipx/utils.h" namespace ipx { @@ -13,24 +15,23 @@ static SparseMatrix PermutedMatrix(const Int* Bbegin, const Int* Bend, const std::vector& rowperm, const std::vector& colperm, const std::vector& dependent_cols) { - Int dim = rowperm.size(); - std::vector permuted_row = InversePerm(rowperm); - std::vector dependent(dim, false); - for (Int k : dependent_cols) - dependent[k] = true; + Int dim = rowperm.size(); + std::vector permuted_row = InversePerm(rowperm); + std::vector dependent(dim, false); + for (Int k : dependent_cols) dependent[k] = true; - SparseMatrix B(dim, 0); - for (Int k = 0; k < dim; k++) { - if (dependent[k]) { - B.push_back(k, 1.0); - } else { - Int j = colperm[k]; - for (Int p = Bbegin[j]; p < Bend[j]; p++) - B.push_back(permuted_row[Bi[p]], Bx[p]); - } - B.add_column(); + SparseMatrix B(dim, 0); + for (Int k = 0; k < dim; k++) { + if (dependent[k]) { + B.push_back(k, 1.0); + } else { + Int j = colperm[k]; + for (Int p = Bbegin[j]; p < Bend[j]; p++) + B.push_back(permuted_row[Bi[p]], Bx[p]); } - return B; + B.add_column(); + } + return B; } // Given a strict lower triangular matrix L and an upper triangular matrix U, @@ -38,14 +39,14 @@ static SparseMatrix PermutedMatrix(const Int* Bbegin, const Int* Bend, // lhs = U\(L+I)\rhs. static void SolveForward(const SparseMatrix& L, const SparseMatrix& U, Vector& rhs, Vector& lhs) { - Int dim = rhs.size(); - lhs = 0.0; - for (Int i = 0; i < dim; i++) { - rhs[i] = lhs[i] >= 0.0 ? 1.0 : -1.0; - lhs[i] += rhs[i]; - ScatterColumn(L, i, -lhs[i], lhs); - } - TriangularSolve(U, lhs, 'n', "upper", 0); + Int dim = rhs.size(); + lhs = 0.0; + for (Int i = 0; i < dim; i++) { + rhs[i] = lhs[i] >= 0.0 ? 1.0 : -1.0; + lhs[i] += rhs[i]; + ScatterColumn(L, i, -lhs[i], lhs); + } + TriangularSolve(U, lhs, 'n', "upper", 0); } // Given a strict lower triangular matrix L and an upper triangular matrix U, @@ -53,17 +54,17 @@ static void SolveForward(const SparseMatrix& L, const SparseMatrix& U, // lhs = (L+I)'\U'\rhs. static void SolveBackward(const SparseMatrix& L, const SparseMatrix& U, Vector& rhs, Vector& lhs) { - Int dim = rhs.size(); - lhs = 0.0; - for (Int j = 0; j < dim; j++) { - lhs[j] -= DotColumn(U, j, lhs); - rhs[j] = lhs[j] >= 0.0 ? 1.0 : -1.0; - lhs[j] += rhs[j]; - Int p = U.end(j)-1; - assert(U.index(p) == j); - lhs[j] /= U.value(p); - } - TriangularSolve(L, lhs, 't', "lower", 1); + Int dim = rhs.size(); + lhs = 0.0; + for (Int j = 0; j < dim; j++) { + lhs[j] -= DotColumn(U, j, lhs); + rhs[j] = lhs[j] >= 0.0 ? 1.0 : -1.0; + lhs[j] += rhs[j]; + Int p = U.end(j) - 1; + assert(U.index(p) == j); + lhs[j] /= U.value(p); + } + TriangularSolve(L, lhs, 't', "lower", 1); } // Returns a stability measure for the factorization L*U=B. Considering a linear @@ -88,27 +89,27 @@ static double StabilityEstimate(const Int* Bbegin, const Int* Bend, const std::vector& rowperm, const std::vector& colperm, const std::vector& dependent_cols) { - Int dim = rowperm.size(); - Vector rhs(dim), lhs(dim); + Int dim = rowperm.size(); + Vector rhs(dim), lhs(dim); - // Compute 1-norm and infinity-norm of B. - SparseMatrix B = PermutedMatrix(Bbegin, Bend, Bi, Bx, rowperm, colperm, - dependent_cols); - double onenorm = Onenorm(B); - double infnorm = Infnorm(B); + // Compute 1-norm and infinity-norm of B. + SparseMatrix B = + PermutedMatrix(Bbegin, Bend, Bi, Bx, rowperm, colperm, dependent_cols); + double onenorm = Onenorm(B); + double infnorm = Infnorm(B); - SolveForward(L, U, rhs, lhs); // builds some rhs and computes lhs = B\rhs - double norm_ftran = Onenorm(lhs); - MultiplyAdd(B, lhs, -1.0, rhs, 'N'); // overwrites rhs by residual - double norm_ftran_res = Onenorm(rhs); + SolveForward(L, U, rhs, lhs); // builds some rhs and computes lhs = B\rhs + double norm_ftran = Onenorm(lhs); + MultiplyAdd(B, lhs, -1.0, rhs, 'N'); // overwrites rhs by residual + double norm_ftran_res = Onenorm(rhs); - SolveBackward(L, U, rhs, lhs); // builds some rhs and computes lhs = B'\rhs - double norm_btran = Onenorm(lhs); - MultiplyAdd(B, lhs, -1.0, rhs, 'T'); // overwrites rhs by residual - double norm_btran_res = Onenorm(rhs); + SolveBackward(L, U, rhs, lhs); // builds some rhs and computes lhs = B'\rhs + double norm_btran = Onenorm(lhs); + MultiplyAdd(B, lhs, -1.0, rhs, 'T'); // overwrites rhs by residual + double norm_btran_res = Onenorm(rhs); - return std::max(norm_ftran_res / (dim + onenorm*norm_ftran), - norm_btran_res / (dim + infnorm*norm_btran)); + return std::max(norm_ftran_res / (dim + onenorm * norm_ftran), + norm_btran_res / (dim + infnorm * norm_btran)); } void LuFactorization::Factorize(Int dim, const Int* Bbegin, const Int* Bend, @@ -118,14 +119,12 @@ void LuFactorization::Factorize(Int dim, const Int* Bbegin, const Int* Bend, std::vector* rowperm, std::vector* colperm, std::vector* dependent_cols) { - _Factorize(dim, Bbegin, Bend, Bi, Bx, pivottol, strict_abs_pivottol, - L, U, rowperm, colperm, dependent_cols); - stability_ = StabilityEstimate(Bbegin, Bend, Bi, Bx, *L, *U, *rowperm, - *colperm, *dependent_cols); + _Factorize(dim, Bbegin, Bend, Bi, Bx, pivottol, strict_abs_pivottol, L, U, + rowperm, colperm, dependent_cols); + stability_ = StabilityEstimate(Bbegin, Bend, Bi, Bx, *L, *U, *rowperm, + *colperm, *dependent_cols); } -double LuFactorization::stability() const { - return stability_; -} +double LuFactorization::stability() const { return stability_; } } // namespace ipx diff --git a/highs/ipm/ipx/maxvolume.cc b/highs/ipm/ipx/maxvolume.cc index 0bfed80e5a0..08a32155afa 100644 --- a/highs/ipm/ipx/maxvolume.cc +++ b/highs/ipm/ipx/maxvolume.cc @@ -1,7 +1,9 @@ #include "ipm/ipx/maxvolume.h" + #include #include #include + #include "ipm/ipx/timer.h" #include "ipm/ipx/utils.h" @@ -10,144 +12,145 @@ namespace ipx { Maxvolume::Maxvolume(const Control& control) : control_(control) {} Int Maxvolume::RunSequential(const double* colscale, Basis& basis) { - const Model& model = basis.model(); - const Int m = model.rows(); - const Int n = model.cols(); - IndexedVector ftran(m); - Timer timer; - Int errflag = 0; - - const Int maxpasses = control_.maxpasses(); - const double volumetol = std::max(control_.volume_tol(), 1.0); - - // Maintain a copy of the inverse scaling factors of basic variables. - // If a variable has status BASIC_FREE, its inverse scaling factor is - // assumed zero, regardless of the entry in colscale. This ensures that - // BASIC_FREE variables are never pivoted out of the basis. - Vector invscale_basic(m); - for (Int p = 0; p < m; p++) { - Int j = basis[p]; - if (basis.StatusOf(j) == Basis::BASIC) - invscale_basic[p] = colscale ? 1.0/colscale[j] : 1.0; - } - - Reset(); - while (passes_ < maxpasses || maxpasses < 0) { - tblnnz_ = 0; - tblmax_ = 0.0; - frobnorm_squared_ = 0.0; - Int updates_last = 0; // # basis updates in this pass - std::vector candidates = Sortperm(n+m, colscale, false); - while(!candidates.empty()) { - Int j = candidates.back(); - const double dj = colscale ? colscale[j] : 1.0; - if (dj == 0.0) // all remaining columns have scaling factor 0 - break; - if (basis.StatusOf(j) != Basis::NONBASIC) { - candidates.pop_back(); - continue; - } - if ((errflag = control_.InterruptCheck()) != 0) - break; - basis.SolveForUpdate(j, ftran); - Int pmax = -1; - double vmax = 0.0; - auto search_pivot = [&](Int p, double x) { - double v = std::abs(x) * invscale_basic[p] * dj; - if (v > vmax) { - vmax = v; - pmax = p; - } - tblnnz_ += v != 0; - frobnorm_squared_ += v*v; - }; - for_each_nonzero(ftran, search_pivot); - tblmax_ = std::max(tblmax_, vmax); - if (vmax <= volumetol) { - skipped_++; - candidates.pop_back(); - continue; - } - - const Int jb = basis[pmax]; - assert(basis.StatusOf(jb) == Basis::BASIC); - bool exchanged; - errflag = basis.ExchangeIfStable(jb, j, ftran[pmax], -1, &exchanged); - if (errflag) - break; - if (!exchanged) // factorization was unstable, try again - continue; - invscale_basic[pmax] = 1.0 / dj; - updates_last++; - volinc_ += std::log2(vmax); - candidates.pop_back(); + const Model& model = basis.model(); + const Int m = model.rows(); + const Int n = model.cols(); + IndexedVector ftran(m); + Timer timer; + Int errflag = 0; + + const Int maxpasses = control_.maxpasses(); + const double volumetol = std::max(control_.volume_tol(), 1.0); + + // Maintain a copy of the inverse scaling factors of basic variables. + // If a variable has status BASIC_FREE, its inverse scaling factor is + // assumed zero, regardless of the entry in colscale. This ensures that + // BASIC_FREE variables are never pivoted out of the basis. + Vector invscale_basic(m); + for (Int p = 0; p < m; p++) { + Int j = basis[p]; + if (basis.StatusOf(j) == Basis::BASIC) + invscale_basic[p] = colscale ? 1.0 / colscale[j] : 1.0; + } + + Reset(); + while (passes_ < maxpasses || maxpasses < 0) { + tblnnz_ = 0; + tblmax_ = 0.0; + frobnorm_squared_ = 0.0; + Int updates_last = 0; // # basis updates in this pass + std::vector candidates = Sortperm(n + m, colscale, false); + while (!candidates.empty()) { + Int j = candidates.back(); + const double dj = colscale ? colscale[j] : 1.0; + if (dj == 0.0) // all remaining columns have scaling factor 0 + break; + if (basis.StatusOf(j) != Basis::NONBASIC) { + candidates.pop_back(); + continue; + } + if ((errflag = control_.InterruptCheck()) != 0) break; + basis.SolveForUpdate(j, ftran); + Int pmax = -1; + double vmax = 0.0; + auto search_pivot = [&](Int p, double x) { + double v = std::abs(x) * invscale_basic[p] * dj; + if (v > vmax) { + vmax = v; + pmax = p; } - updates_ += updates_last; - passes_++; - if (updates_last == 0 || errflag != 0) - break; + tblnnz_ += v != 0; + frobnorm_squared_ += v * v; + }; + for_each_nonzero(ftran, search_pivot); + tblmax_ = std::max(tblmax_, vmax); + if (vmax <= volumetol) { + skipped_++; + candidates.pop_back(); + continue; + } + + const Int jb = basis[pmax]; + assert(basis.StatusOf(jb) == Basis::BASIC); + bool exchanged; + errflag = basis.ExchangeIfStable(jb, j, ftran[pmax], -1, &exchanged); + if (errflag) break; + if (!exchanged) // factorization was unstable, try again + continue; + invscale_basic[pmax] = 1.0 / dj; + updates_last++; + volinc_ += std::log2(vmax); + candidates.pop_back(); } - time_ = timer.Elapsed(); - return errflag; + updates_ += updates_last; + passes_++; + if (updates_last == 0 || errflag != 0) break; + } + time_ = timer.Elapsed(); + return errflag; } struct Maxvolume::Slice { - Slice(Int m, Int n) : - colscale(n+m), invscale_basic(m), tblrow_used(m), colweights(n+m), - lhs(m), row(n+m), work(m) {} - Vector colscale; - Vector invscale_basic; - std::vector tblrow_used; - Vector colweights; - IndexedVector lhs, row; - Vector work; + Slice(Int m, Int n) + : colscale(n + m), + invscale_basic(m), + tblrow_used(m), + colweights(n + m), + lhs(m), + row(n + m), + work(m) {} + Vector colscale; + Vector invscale_basic; + std::vector tblrow_used; + Vector colweights; + IndexedVector lhs, row; + Vector work; }; Int Maxvolume::RunHeuristic(const double* colscale, Basis& basis) { - const Model& model = basis.model(); - const Int m = model.rows(); - const Int n = model.cols(); - Slice slice(m, n); - Int errflag = 0; - Timer timer; - - Reset(); - Int num_slices = 5 + std::max((long)(m/control_.rows_per_slice()), 0l); - num_slices = std::min(num_slices, m); - - // Maintain a copy of the inverse scaling factors of basic variables. - for (Int p = 0; p < m; p++) { - Int j = basis[p]; - if (basis.StatusOf(j) == Basis::BASIC) { - slice.invscale_basic[p] = colscale ? 1.0/colscale[j] : 1.0; - assert(std::isfinite(slice.invscale_basic[p])); - } + const Model& model = basis.model(); + const Int m = model.rows(); + const Int n = model.cols(); + Slice slice(m, n); + Int errflag = 0; + Timer timer; + + Reset(); + Int num_slices = 5 + std::max((long)(m / control_.rows_per_slice()), 0l); + num_slices = std::min(num_slices, m); + + // Maintain a copy of the inverse scaling factors of basic variables. + for (Int p = 0; p < m; p++) { + Int j = basis[p]; + if (basis.StatusOf(j) == Basis::BASIC) { + slice.invscale_basic[p] = colscale ? 1.0 / colscale[j] : 1.0; + assert(std::isfinite(slice.invscale_basic[p])); } - - // We need to work with a copy of the column scaling factors, in which - // skipped columns are set to zero (and not scanned again). - for (Int j = 0; j < n+m; j++) { - if (basis.StatusOf(j) == Basis::NONBASIC) - slice.colscale[j] = colscale ? colscale[j] : 1.0; - } - - // Split tableau matrix into num_slices row slices. In each call to - // Driver() there is exactly one row from each slice that has - // tblrow_used[p] == 1, while the other rows in the slice have - // tblrow_used[p] == 0. - std::vector perm = Sortperm(m, &slice.invscale_basic[0], false); - for (Int s = 0; s < num_slices; s++) { - for (Int i = 0; i < m; i++) - slice.tblrow_used[perm[i]] = i%num_slices == s; - errflag = Driver(basis, slice); - if (errflag) - break; - } - - time_ = timer.Elapsed(); - passes_ = -1; - slices_ = num_slices; - return errflag; + } + + // We need to work with a copy of the column scaling factors, in which + // skipped columns are set to zero (and not scanned again). + for (Int j = 0; j < n + m; j++) { + if (basis.StatusOf(j) == Basis::NONBASIC) + slice.colscale[j] = colscale ? colscale[j] : 1.0; + } + + // Split tableau matrix into num_slices row slices. In each call to + // Driver() there is exactly one row from each slice that has + // tblrow_used[p] == 1, while the other rows in the slice have + // tblrow_used[p] == 0. + std::vector perm = Sortperm(m, &slice.invscale_basic[0], false); + for (Int s = 0; s < num_slices; s++) { + for (Int i = 0; i < m; i++) + slice.tblrow_used[perm[i]] = i % num_slices == s; + errflag = Driver(basis, slice); + if (errflag) break; + } + + time_ = timer.Elapsed(); + passes_ = -1; + slices_ = num_slices; + return errflag; } Int Maxvolume::updates() const { return updates_; } @@ -161,177 +164,170 @@ double Maxvolume::tblmax() const { return tblmax_; } double Maxvolume::frobnorm_squared() const { return frobnorm_squared_; } void Maxvolume::Reset() { - updates_ = 0; - skipped_ = 0; - passes_ = 0; - slices_ = 0; - volinc_ = 0.0;; - time_ = 0.0; - tblnnz_ = 0; - tblmax_ = 0.0; - frobnorm_squared_ = 0.0; + updates_ = 0; + skipped_ = 0; + passes_ = 0; + slices_ = 0; + volinc_ = 0.0; + ; + time_ = 0.0; + tblnnz_ = 0; + tblmax_ = 0.0; + frobnorm_squared_ = 0.0; } // Returns a vector holding the indices of the largest and second largest // entry in @weights. The index of the largest entry is at the back. static std::vector FindLargest(const Vector& weights) { - const Int n = weights.size(); - Int jmax = 0; // index of largest element - Int jmax2 = 0; // index of second largest element - double wmax = 0.0; - double wmax2 = 0.0; - - for (Int j = 0; j < n; j++) { - double w = std::abs(weights[j]); - if (w > wmax) { - wmax2 = wmax; - wmax = w; - jmax2 = jmax; - jmax = j; - } - else if (w > wmax2) { - wmax2 = w; - jmax2 = j; - } + const Int n = weights.size(); + Int jmax = 0; // index of largest element + Int jmax2 = 0; // index of second largest element + double wmax = 0.0; + double wmax2 = 0.0; + + for (Int j = 0; j < n; j++) { + double w = std::abs(weights[j]); + if (w > wmax) { + wmax2 = wmax; + wmax = w; + jmax2 = jmax; + jmax = j; + } else if (w > wmax2) { + wmax2 = w; + jmax2 = j; } - return {jmax2, jmax}; + } + return {jmax2, jmax}; } Int Maxvolume::Driver(Basis& basis, Slice& slice) { - const Model& model = basis.model(); - const Int m = model.rows(); - const Int n = model.cols(); - const SparseMatrix& AI = model.AI(); - Int errflag = 0; - - const double volumetol = std::max(control_.volume_tol(), 1.0); - const Int maxskip = control_.maxskip_updates(); - - Vector& colscale = slice.colscale; - Vector& invscale_basic = slice.invscale_basic; - const std::vector& tblrow_used = slice.tblrow_used; - Vector& colweights = slice.colweights; - IndexedVector& lhs = slice.lhs; - IndexedVector& row = slice.row; - Vector& work = slice.work; - - // Compute column weights. - for (Int p = 0; p < m; p++) - work[p] = tblrow_used[p] ? invscale_basic[p] : 0.0; - basis.SolveDense(work, work, 'T'); - for (Int j = 0; j < n+m; j++) { - if (colscale[j]) { - assert(basis.StatusOf(j) == Basis::NONBASIC); - double sum = DotColumn(AI, j, work); - colweights[j] = sum * colscale[j]; - } - else - colweights[j] = 0.0; + const Model& model = basis.model(); + const Int m = model.rows(); + const Int n = model.cols(); + const SparseMatrix& AI = model.AI(); + Int errflag = 0; + + const double volumetol = std::max(control_.volume_tol(), 1.0); + const Int maxskip = control_.maxskip_updates(); + + Vector& colscale = slice.colscale; + Vector& invscale_basic = slice.invscale_basic; + const std::vector& tblrow_used = slice.tblrow_used; + Vector& colweights = slice.colweights; + IndexedVector& lhs = slice.lhs; + IndexedVector& row = slice.row; + Vector& work = slice.work; + + // Compute column weights. + for (Int p = 0; p < m; p++) + work[p] = tblrow_used[p] ? invscale_basic[p] : 0.0; + basis.SolveDense(work, work, 'T'); + for (Int j = 0; j < n + m; j++) { + if (colscale[j]) { + assert(basis.StatusOf(j) == Basis::NONBASIC); + double sum = DotColumn(AI, j, work); + colweights[j] = sum * colscale[j]; + } else + colweights[j] = 0.0; + } + + std::vector candidates; + Int skipped = 0; + while (true) { + // Pick column with maximum weight. + if (candidates.empty()) { + candidates = FindLargest(colweights); + assert(!candidates.empty()); } - - std::vector candidates; - Int skipped = 0; - while (true) { - // Pick column with maximum weight. - if (candidates.empty()) { - candidates = FindLargest(colweights); - assert(!candidates.empty()); - } - Int jn = candidates.back(); - assert(jn >= 0 && jn < n+m); - const double weight = colweights[jn]; - if (weight == 0.0) - break; - assert(basis.StatusOf(jn) == Basis::NONBASIC); - assert(colscale[jn] > 0.0); - - if ((errflag = control_.InterruptCheck()) != 0) - break; - - // Find maximum scaled FTRAN entry. - basis.SolveForUpdate(jn, lhs); - const Int pmax = ScaleFtran(colscale[jn], invscale_basic, lhs); - const double scaled_pivot = lhs[pmax]; - const double vmax = std::abs(scaled_pivot); - - // Skip the column if exchange does not increase volume enough. - if (vmax <= volumetol) { - colweights[jn] = 0.0; - colscale[jn] = 0.0; - candidates.pop_back(); - if (++skipped > maxskip && maxskip >= 0) - break; - continue; - } - - // Recompute column weight from FTRAN. - double weight_recomp = 0.0; - auto sum_used = [&](Int p, double x) { - if (tblrow_used[p]) - weight_recomp += x; - }; - for_each_nonzero(lhs, sum_used); - assert(std::isfinite(weight_recomp)); - - // Update basis. - const Int jb = basis[pmax]; - basis.TableauRow(jb, lhs, row, true); - const double pivot = row[jn]; - if (std::abs(pivot) < 1e-3) { - control_.Debug(3) - << " |pivot| " << sci2(std::abs(pivot)) - << "(maxvolume)\n"; - } - bool exchanged; - errflag = basis.ExchangeIfStable(jb, jn, pivot, 0, &exchanged); - if (errflag) - break; - if (!exchanged) // factorization was unstable, try again - continue; - updates_++; - volinc_ += std::log2(vmax); - - // Update colscale and invscale_basic. - const double dn = colscale[jn]; - const double dbinv = invscale_basic[pmax]; - assert(colscale[jb] == 0.0); - colscale[jb] = 1.0 / invscale_basic[pmax]; - invscale_basic[pmax] = 1.0 / colscale[jn]; - colscale[jn] = 0.0; - assert(std::isfinite(colscale[jb])); - assert(std::isfinite(invscale_basic[pmax])); - - // Update column weights. - const double alpha = (tblrow_used[pmax] - weight_recomp) / (dn*pivot); - assert(std::isfinite(alpha)); - auto add = [&](Int j, double x) { - colweights[j] += alpha * x * colscale[j]; - }; - for_each_nonzero(row, add); - colweights[jb] = tblrow_used[pmax] + alpha/dbinv; - colweights[jn] = 0.0; - candidates.clear(); + Int jn = candidates.back(); + assert(jn >= 0 && jn < n + m); + const double weight = colweights[jn]; + if (weight == 0.0) break; + assert(basis.StatusOf(jn) == Basis::NONBASIC); + assert(colscale[jn] > 0.0); + + if ((errflag = control_.InterruptCheck()) != 0) break; + + // Find maximum scaled FTRAN entry. + basis.SolveForUpdate(jn, lhs); + const Int pmax = ScaleFtran(colscale[jn], invscale_basic, lhs); + const double scaled_pivot = lhs[pmax]; + const double vmax = std::abs(scaled_pivot); + + // Skip the column if exchange does not increase volume enough. + if (vmax <= volumetol) { + colweights[jn] = 0.0; + colscale[jn] = 0.0; + candidates.pop_back(); + if (++skipped > maxskip && maxskip >= 0) break; + continue; } - skipped_ += skipped; - return errflag; + // Recompute column weight from FTRAN. + double weight_recomp = 0.0; + auto sum_used = [&](Int p, double x) { + if (tblrow_used[p]) weight_recomp += x; + }; + for_each_nonzero(lhs, sum_used); + assert(std::isfinite(weight_recomp)); + + // Update basis. + const Int jb = basis[pmax]; + basis.TableauRow(jb, lhs, row, true); + const double pivot = row[jn]; + if (std::abs(pivot) < 1e-3) { + control_.Debug(3) << " |pivot| " << sci2(std::abs(pivot)) + << "(maxvolume)\n"; + } + bool exchanged; + errflag = basis.ExchangeIfStable(jb, jn, pivot, 0, &exchanged); + if (errflag) break; + if (!exchanged) // factorization was unstable, try again + continue; + updates_++; + volinc_ += std::log2(vmax); + + // Update colscale and invscale_basic. + const double dn = colscale[jn]; + const double dbinv = invscale_basic[pmax]; + assert(colscale[jb] == 0.0); + colscale[jb] = 1.0 / invscale_basic[pmax]; + invscale_basic[pmax] = 1.0 / colscale[jn]; + colscale[jn] = 0.0; + assert(std::isfinite(colscale[jb])); + assert(std::isfinite(invscale_basic[pmax])); + + // Update column weights. + const double alpha = (tblrow_used[pmax] - weight_recomp) / (dn * pivot); + assert(std::isfinite(alpha)); + auto add = [&](Int j, double x) { + colweights[j] += alpha * x * colscale[j]; + }; + for_each_nonzero(row, add); + colweights[jb] = tblrow_used[pmax] + alpha / dbinv; + colweights[jn] = 0.0; + candidates.clear(); + } + + skipped_ += skipped; + return errflag; } Int Maxvolume::ScaleFtran(double colscale_jn, const Vector& invscale_basic, IndexedVector& ftran) { - double vmax = 0.0; - Int pmax = 0; - auto fcn = [&](Int p, double& pivot) { - double scaled_pivot = pivot * colscale_jn * invscale_basic[p]; - double v = std::abs(scaled_pivot); - if (v > vmax && std::abs(pivot) > kPivotZeroTol) { - vmax = v; - pmax = p; - } - pivot = scaled_pivot; - }; - for_each_nonzero(ftran, fcn); - return pmax; + double vmax = 0.0; + Int pmax = 0; + auto fcn = [&](Int p, double& pivot) { + double scaled_pivot = pivot * colscale_jn * invscale_basic[p]; + double v = std::abs(scaled_pivot); + if (v > vmax && std::abs(pivot) > kPivotZeroTol) { + vmax = v; + pmax = p; + } + pivot = scaled_pivot; + }; + for_each_nonzero(ftran, fcn); + return pmax; } } // namespace ipx diff --git a/highs/lp_data/Highs.cpp b/highs/lp_data/Highs.cpp index dc29a7f8f75..e6407a3a01f 100644 --- a/highs/lp_data/Highs.cpp +++ b/highs/lp_data/Highs.cpp @@ -2651,7 +2651,7 @@ HighsStatus Highs::setSolution(const HighsInt num_entries, if (model_.lp_.num_col_ == 0) return return_status; // Warn about duplicates in index HighsInt num_duplicates = 0; - std::vector is_set; + std::vector is_set; is_set.assign(model_.lp_.num_col_, false); const HighsInt to_ix = packed ? num_entries : model_.lp_.num_col_; for (HighsInt iX = 0; iX < to_ix; iX++) { diff --git a/highs/lp_data/HighsCallback.cpp b/highs/lp_data/HighsCallback.cpp index 4d7965a49e0..c4a73a7c0c8 100644 --- a/highs/lp_data/HighsCallback.cpp +++ b/highs/lp_data/HighsCallback.cpp @@ -196,7 +196,7 @@ HighsStatus HighsCallbackInput::setSolution(HighsInt num_entries, HighsStatus return_status = HighsStatus::kOk; HighsInt num_duplicates = 0; - std::vector is_set(lp.num_col_, false); + std::vector is_set(lp.num_col_, false); for (HighsInt iX = 0; iX < num_entries; iX++) { HighsInt iCol = index[iX]; diff --git a/highs/lp_data/HighsCallback.h b/highs/lp_data/HighsCallback.h index 6b350dbea9d..7bfdd888774 100644 --- a/highs/lp_data/HighsCallback.h +++ b/highs/lp_data/HighsCallback.h @@ -92,7 +92,7 @@ struct HighsCallback { HighsCCallbackType c_callback = nullptr; void* user_callback_data = nullptr; Highs* highs = nullptr; - std::vector active; + std::vector active; HighsCallbackOutput data_out; HighsCallbackInput data_in; bool callbackActive(const int callback_type); diff --git a/highs/lp_data/HighsInterface.cpp b/highs/lp_data/HighsInterface.cpp index b534634da42..b8c904c5ba3 100644 --- a/highs/lp_data/HighsInterface.cpp +++ b/highs/lp_data/HighsInterface.cpp @@ -1837,7 +1837,7 @@ HighsStatus Highs::getRangingInterface() { HighsStatus Highs::getIisInterfaceReturn( const HighsStatus return_status, const HighsOptions& original_options, - const std::vector& original_callback_active) { + const std::vector& original_callback_active) { // Restore options and callbacks this->options_ = original_options; for (int i = kCallbackMin; i <= kCallbackMax; i++) { @@ -1980,7 +1980,7 @@ HighsStatus Highs::getIisInterface() { HighsOptions original_options = this->options_; // Save original active callbacks and disable all except for // kCallbackLogging and kCallbackSimplexInterrupt - std::vector original_callback_active = callback_.active; + std::vector original_callback_active = callback_.active; for (int i = kCallbackMin; i <= kCallbackMax; i++) { if (i != kCallbackLogging && i != kCallbackSimplexInterrupt && callback_.active[i]) @@ -2266,8 +2266,8 @@ HighsStatus Highs::elasticityFilter(const double global_lower_penalty, // bound_of_row_of_ecol_is_lower so that the results can be interpreted std::vector col_of_ecol; std::vector row_of_ecol; - std::vector bound_of_row_of_ecol_is_lower; - std::vector bound_of_col_of_ecol_is_lower; + std::vector bound_of_row_of_ecol_is_lower; + std::vector bound_of_col_of_ecol_is_lower; std::vector erow_lower; std::vector erow_upper; std::vector erow_start; @@ -2775,7 +2775,7 @@ HighsStatus Highs::elasticityFilter(const double global_lower_penalty, in_row_index[iis.row_index_[iX]] = iX; // Determine the columns with nonzeros in the row subset - std::vector nonzero_in_row_index(original_num_col, false); + std::vector nonzero_in_row_index(original_num_col, false); if (lp.a_matrix_.isColwise()) { for (HighsInt iCol = 0; iCol < original_num_col; iCol++) { for (HighsInt iEl = lp.a_matrix_.start_[iCol]; @@ -4533,8 +4533,8 @@ void Highs::reportProfiling() const { } const double num_threads_used = used_thread.size(); std::stringstream ss; - std::vector mip_used_sub_solver(kToSubSolver, false); - std::vector submip_used_sub_solver(kToSubSolver, false); + std::vector mip_used_sub_solver(kToSubSolver, false); + std::vector submip_used_sub_solver(kToSubSolver, false); const HighsInt to_k = max_sumip_time > 0 ? 2 : 1; const std::vector& name = this->profiling_->name; double sum_sum_mip_sub_solve_time = 0; @@ -4557,7 +4557,7 @@ void Highs::reportProfiling() const { if (ideal_time <= 0) continue; const std::vector& record = k == 0 ? this->profiling_->record : this->profiling_->submip_record; - std::vector& used_sub_solver = + std::vector& used_sub_solver = k == 0 ? mip_used_sub_solver : submip_used_sub_solver; const std::vector& num_call = record[thread_num].num_call; const std::vector& run_time = record[thread_num].run_time; @@ -4627,7 +4627,7 @@ void Highs::reportProfiling() const { } highsLogUser(options_.log_options, HighsLogType::kInfo, "%s\n", ss.str().c_str()); - std::vector& used_sub_solver = + std::vector& used_sub_solver = k == 0 ? mip_used_sub_solver : submip_used_sub_solver; const std::vector& record = k == 0 ? this->profiling_->record : this->profiling_->submip_record; diff --git a/highs/mip/HighsCutPool.h b/highs/mip/HighsCutPool.h index 72068cc1f21..e0fd717699b 100644 --- a/highs/mip/HighsCutPool.h +++ b/highs/mip/HighsCutPool.h @@ -58,8 +58,8 @@ class HighsCutPool { std::vector ages_; std::deque> numLps_; std::deque> - ageResetWhileLocked_; // Was the cut propagated? - std::vector hasSynced_; // Has the cut been globally synced? + ageResetWhileLocked_; // Was the cut propagated? + std::vector hasSynced_; // Has the cut been globally synced? std::vector rownormalization_; std::vector maxabscoef_; std::vector rowintegral; diff --git a/highs/pdlp/hipdlp/pdhg.hpp b/highs/pdlp/hipdlp/pdhg.hpp index aa3fb4a38f6..baa57505693 100644 --- a/highs/pdlp/hipdlp/pdhg.hpp +++ b/highs/pdlp/hipdlp/pdhg.hpp @@ -211,7 +211,7 @@ class PDLPSolver { HighsInt sense_origin_ = 1; double unscaled_rhs_norm_ = 0.0; double unscaled_c_norm_ = 0.0; - std::vector is_equality_row_; + std::vector is_equality_row_; std::vector constraint_new_idx_; std::vector constraint_types_; diff --git a/highs/presolve/HPresolveAnalysis.h b/highs/presolve/HPresolveAnalysis.h index 9fa48f32d26..d0d8770cc4d 100644 --- a/highs/presolve/HPresolveAnalysis.h +++ b/highs/presolve/HPresolveAnalysis.h @@ -23,7 +23,7 @@ class HPresolveAnalysis { HighsInt original_num_row_; public: - std::vector allow_rule_; + std::vector allow_rule_; bool allow_logging_; bool logging_on_; From ec0882b10755726d1d4ba3c2d42975b1f36ff5b3 Mon Sep 17 00:00:00 2001 From: Ivet Galabova Date: Tue, 4 Aug 2026 16:43:49 +0300 Subject: [PATCH 02/11] upload logs on failure --- .github/workflows/action-sanitizers-bazel.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/action-sanitizers-bazel.yml b/.github/workflows/action-sanitizers-bazel.yml index 90ffee65529..8874ae67752 100644 --- a/.github/workflows/action-sanitizers-bazel.yml +++ b/.github/workflows/action-sanitizers-bazel.yml @@ -58,6 +58,7 @@ jobs: run: bazel test -c dbg --config=tsan --runs_per_test 5 //... - name: Upload bazel-testlogs + if: failure() uses: actions/upload-artifact@v7 with: name: bazel-testlogs-tsan From 3b1083aef4550ed4b92770633a9f65b4ca47e096 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Tue, 4 Aug 2026 15:57:26 +0200 Subject: [PATCH 03/11] Revert format changes --- highs/ipm/ipx/lu_factorization.cc | 117 ++++--- highs/ipm/ipx/maxvolume.cc | 564 +++++++++++++++--------------- 2 files changed, 343 insertions(+), 338 deletions(-) diff --git a/highs/ipm/ipx/lu_factorization.cc b/highs/ipm/ipx/lu_factorization.cc index 4834eab0a16..5e8ddd4f961 100644 --- a/highs/ipm/ipx/lu_factorization.cc +++ b/highs/ipm/ipx/lu_factorization.cc @@ -1,8 +1,6 @@ #include "ipm/ipx/lu_factorization.h" - #include #include - #include "ipm/ipx/utils.h" namespace ipx { @@ -15,23 +13,24 @@ static SparseMatrix PermutedMatrix(const Int* Bbegin, const Int* Bend, const std::vector& rowperm, const std::vector& colperm, const std::vector& dependent_cols) { - Int dim = rowperm.size(); - std::vector permuted_row = InversePerm(rowperm); - std::vector dependent(dim, false); - for (Int k : dependent_cols) dependent[k] = true; + Int dim = rowperm.size(); + std::vector permuted_row = InversePerm(rowperm); + std::vector dependent(dim, false); + for (Int k : dependent_cols) + dependent[k] = true; - SparseMatrix B(dim, 0); - for (Int k = 0; k < dim; k++) { - if (dependent[k]) { - B.push_back(k, 1.0); - } else { - Int j = colperm[k]; - for (Int p = Bbegin[j]; p < Bend[j]; p++) - B.push_back(permuted_row[Bi[p]], Bx[p]); + SparseMatrix B(dim, 0); + for (Int k = 0; k < dim; k++) { + if (dependent[k]) { + B.push_back(k, 1.0); + } else { + Int j = colperm[k]; + for (Int p = Bbegin[j]; p < Bend[j]; p++) + B.push_back(permuted_row[Bi[p]], Bx[p]); + } + B.add_column(); } - B.add_column(); - } - return B; + return B; } // Given a strict lower triangular matrix L and an upper triangular matrix U, @@ -39,14 +38,14 @@ static SparseMatrix PermutedMatrix(const Int* Bbegin, const Int* Bend, // lhs = U\(L+I)\rhs. static void SolveForward(const SparseMatrix& L, const SparseMatrix& U, Vector& rhs, Vector& lhs) { - Int dim = rhs.size(); - lhs = 0.0; - for (Int i = 0; i < dim; i++) { - rhs[i] = lhs[i] >= 0.0 ? 1.0 : -1.0; - lhs[i] += rhs[i]; - ScatterColumn(L, i, -lhs[i], lhs); - } - TriangularSolve(U, lhs, 'n', "upper", 0); + Int dim = rhs.size(); + lhs = 0.0; + for (Int i = 0; i < dim; i++) { + rhs[i] = lhs[i] >= 0.0 ? 1.0 : -1.0; + lhs[i] += rhs[i]; + ScatterColumn(L, i, -lhs[i], lhs); + } + TriangularSolve(U, lhs, 'n', "upper", 0); } // Given a strict lower triangular matrix L and an upper triangular matrix U, @@ -54,17 +53,17 @@ static void SolveForward(const SparseMatrix& L, const SparseMatrix& U, // lhs = (L+I)'\U'\rhs. static void SolveBackward(const SparseMatrix& L, const SparseMatrix& U, Vector& rhs, Vector& lhs) { - Int dim = rhs.size(); - lhs = 0.0; - for (Int j = 0; j < dim; j++) { - lhs[j] -= DotColumn(U, j, lhs); - rhs[j] = lhs[j] >= 0.0 ? 1.0 : -1.0; - lhs[j] += rhs[j]; - Int p = U.end(j) - 1; - assert(U.index(p) == j); - lhs[j] /= U.value(p); - } - TriangularSolve(L, lhs, 't', "lower", 1); + Int dim = rhs.size(); + lhs = 0.0; + for (Int j = 0; j < dim; j++) { + lhs[j] -= DotColumn(U, j, lhs); + rhs[j] = lhs[j] >= 0.0 ? 1.0 : -1.0; + lhs[j] += rhs[j]; + Int p = U.end(j)-1; + assert(U.index(p) == j); + lhs[j] /= U.value(p); + } + TriangularSolve(L, lhs, 't', "lower", 1); } // Returns a stability measure for the factorization L*U=B. Considering a linear @@ -89,27 +88,27 @@ static double StabilityEstimate(const Int* Bbegin, const Int* Bend, const std::vector& rowperm, const std::vector& colperm, const std::vector& dependent_cols) { - Int dim = rowperm.size(); - Vector rhs(dim), lhs(dim); + Int dim = rowperm.size(); + Vector rhs(dim), lhs(dim); - // Compute 1-norm and infinity-norm of B. - SparseMatrix B = - PermutedMatrix(Bbegin, Bend, Bi, Bx, rowperm, colperm, dependent_cols); - double onenorm = Onenorm(B); - double infnorm = Infnorm(B); + // Compute 1-norm and infinity-norm of B. + SparseMatrix B = PermutedMatrix(Bbegin, Bend, Bi, Bx, rowperm, colperm, + dependent_cols); + double onenorm = Onenorm(B); + double infnorm = Infnorm(B); - SolveForward(L, U, rhs, lhs); // builds some rhs and computes lhs = B\rhs - double norm_ftran = Onenorm(lhs); - MultiplyAdd(B, lhs, -1.0, rhs, 'N'); // overwrites rhs by residual - double norm_ftran_res = Onenorm(rhs); + SolveForward(L, U, rhs, lhs); // builds some rhs and computes lhs = B\rhs + double norm_ftran = Onenorm(lhs); + MultiplyAdd(B, lhs, -1.0, rhs, 'N'); // overwrites rhs by residual + double norm_ftran_res = Onenorm(rhs); - SolveBackward(L, U, rhs, lhs); // builds some rhs and computes lhs = B'\rhs - double norm_btran = Onenorm(lhs); - MultiplyAdd(B, lhs, -1.0, rhs, 'T'); // overwrites rhs by residual - double norm_btran_res = Onenorm(rhs); + SolveBackward(L, U, rhs, lhs); // builds some rhs and computes lhs = B'\rhs + double norm_btran = Onenorm(lhs); + MultiplyAdd(B, lhs, -1.0, rhs, 'T'); // overwrites rhs by residual + double norm_btran_res = Onenorm(rhs); - return std::max(norm_ftran_res / (dim + onenorm * norm_ftran), - norm_btran_res / (dim + infnorm * norm_btran)); + return std::max(norm_ftran_res / (dim + onenorm*norm_ftran), + norm_btran_res / (dim + infnorm*norm_btran)); } void LuFactorization::Factorize(Int dim, const Int* Bbegin, const Int* Bend, @@ -119,12 +118,14 @@ void LuFactorization::Factorize(Int dim, const Int* Bbegin, const Int* Bend, std::vector* rowperm, std::vector* colperm, std::vector* dependent_cols) { - _Factorize(dim, Bbegin, Bend, Bi, Bx, pivottol, strict_abs_pivottol, L, U, - rowperm, colperm, dependent_cols); - stability_ = StabilityEstimate(Bbegin, Bend, Bi, Bx, *L, *U, *rowperm, - *colperm, *dependent_cols); + _Factorize(dim, Bbegin, Bend, Bi, Bx, pivottol, strict_abs_pivottol, + L, U, rowperm, colperm, dependent_cols); + stability_ = StabilityEstimate(Bbegin, Bend, Bi, Bx, *L, *U, *rowperm, + *colperm, *dependent_cols); } -double LuFactorization::stability() const { return stability_; } +double LuFactorization::stability() const { + return stability_; +} } // namespace ipx diff --git a/highs/ipm/ipx/maxvolume.cc b/highs/ipm/ipx/maxvolume.cc index 08a32155afa..88bb84c7ff1 100644 --- a/highs/ipm/ipx/maxvolume.cc +++ b/highs/ipm/ipx/maxvolume.cc @@ -1,9 +1,7 @@ #include "ipm/ipx/maxvolume.h" - #include #include #include - #include "ipm/ipx/timer.h" #include "ipm/ipx/utils.h" @@ -12,145 +10,144 @@ namespace ipx { Maxvolume::Maxvolume(const Control& control) : control_(control) {} Int Maxvolume::RunSequential(const double* colscale, Basis& basis) { - const Model& model = basis.model(); - const Int m = model.rows(); - const Int n = model.cols(); - IndexedVector ftran(m); - Timer timer; - Int errflag = 0; - - const Int maxpasses = control_.maxpasses(); - const double volumetol = std::max(control_.volume_tol(), 1.0); - - // Maintain a copy of the inverse scaling factors of basic variables. - // If a variable has status BASIC_FREE, its inverse scaling factor is - // assumed zero, regardless of the entry in colscale. This ensures that - // BASIC_FREE variables are never pivoted out of the basis. - Vector invscale_basic(m); - for (Int p = 0; p < m; p++) { - Int j = basis[p]; - if (basis.StatusOf(j) == Basis::BASIC) - invscale_basic[p] = colscale ? 1.0 / colscale[j] : 1.0; - } - - Reset(); - while (passes_ < maxpasses || maxpasses < 0) { - tblnnz_ = 0; - tblmax_ = 0.0; - frobnorm_squared_ = 0.0; - Int updates_last = 0; // # basis updates in this pass - std::vector candidates = Sortperm(n + m, colscale, false); - while (!candidates.empty()) { - Int j = candidates.back(); - const double dj = colscale ? colscale[j] : 1.0; - if (dj == 0.0) // all remaining columns have scaling factor 0 - break; - if (basis.StatusOf(j) != Basis::NONBASIC) { - candidates.pop_back(); - continue; - } - if ((errflag = control_.InterruptCheck()) != 0) break; - basis.SolveForUpdate(j, ftran); - Int pmax = -1; - double vmax = 0.0; - auto search_pivot = [&](Int p, double x) { - double v = std::abs(x) * invscale_basic[p] * dj; - if (v > vmax) { - vmax = v; - pmax = p; + const Model& model = basis.model(); + const Int m = model.rows(); + const Int n = model.cols(); + IndexedVector ftran(m); + Timer timer; + Int errflag = 0; + + const Int maxpasses = control_.maxpasses(); + const double volumetol = std::max(control_.volume_tol(), 1.0); + + // Maintain a copy of the inverse scaling factors of basic variables. + // If a variable has status BASIC_FREE, its inverse scaling factor is + // assumed zero, regardless of the entry in colscale. This ensures that + // BASIC_FREE variables are never pivoted out of the basis. + Vector invscale_basic(m); + for (Int p = 0; p < m; p++) { + Int j = basis[p]; + if (basis.StatusOf(j) == Basis::BASIC) + invscale_basic[p] = colscale ? 1.0/colscale[j] : 1.0; + } + + Reset(); + while (passes_ < maxpasses || maxpasses < 0) { + tblnnz_ = 0; + tblmax_ = 0.0; + frobnorm_squared_ = 0.0; + Int updates_last = 0; // # basis updates in this pass + std::vector candidates = Sortperm(n+m, colscale, false); + while(!candidates.empty()) { + Int j = candidates.back(); + const double dj = colscale ? colscale[j] : 1.0; + if (dj == 0.0) // all remaining columns have scaling factor 0 + break; + if (basis.StatusOf(j) != Basis::NONBASIC) { + candidates.pop_back(); + continue; + } + if ((errflag = control_.InterruptCheck()) != 0) + break; + basis.SolveForUpdate(j, ftran); + Int pmax = -1; + double vmax = 0.0; + auto search_pivot = [&](Int p, double x) { + double v = std::abs(x) * invscale_basic[p] * dj; + if (v > vmax) { + vmax = v; + pmax = p; + } + tblnnz_ += v != 0; + frobnorm_squared_ += v*v; + }; + for_each_nonzero(ftran, search_pivot); + tblmax_ = std::max(tblmax_, vmax); + if (vmax <= volumetol) { + skipped_++; + candidates.pop_back(); + continue; + } + + const Int jb = basis[pmax]; + assert(basis.StatusOf(jb) == Basis::BASIC); + bool exchanged; + errflag = basis.ExchangeIfStable(jb, j, ftran[pmax], -1, &exchanged); + if (errflag) + break; + if (!exchanged) // factorization was unstable, try again + continue; + invscale_basic[pmax] = 1.0 / dj; + updates_last++; + volinc_ += std::log2(vmax); + candidates.pop_back(); } - tblnnz_ += v != 0; - frobnorm_squared_ += v * v; - }; - for_each_nonzero(ftran, search_pivot); - tblmax_ = std::max(tblmax_, vmax); - if (vmax <= volumetol) { - skipped_++; - candidates.pop_back(); - continue; - } - - const Int jb = basis[pmax]; - assert(basis.StatusOf(jb) == Basis::BASIC); - bool exchanged; - errflag = basis.ExchangeIfStable(jb, j, ftran[pmax], -1, &exchanged); - if (errflag) break; - if (!exchanged) // factorization was unstable, try again - continue; - invscale_basic[pmax] = 1.0 / dj; - updates_last++; - volinc_ += std::log2(vmax); - candidates.pop_back(); + updates_ += updates_last; + passes_++; + if (updates_last == 0 || errflag != 0) + break; } - updates_ += updates_last; - passes_++; - if (updates_last == 0 || errflag != 0) break; - } - time_ = timer.Elapsed(); - return errflag; + time_ = timer.Elapsed(); + return errflag; } struct Maxvolume::Slice { - Slice(Int m, Int n) - : colscale(n + m), - invscale_basic(m), - tblrow_used(m), - colweights(n + m), - lhs(m), - row(n + m), - work(m) {} - Vector colscale; - Vector invscale_basic; - std::vector tblrow_used; - Vector colweights; - IndexedVector lhs, row; - Vector work; + Slice(Int m, Int n) : + colscale(n+m), invscale_basic(m), tblrow_used(m), colweights(n+m), + lhs(m), row(n+m), work(m) {} + Vector colscale; + Vector invscale_basic; + std::vector tblrow_used; + Vector colweights; + IndexedVector lhs, row; + Vector work; }; Int Maxvolume::RunHeuristic(const double* colscale, Basis& basis) { - const Model& model = basis.model(); - const Int m = model.rows(); - const Int n = model.cols(); - Slice slice(m, n); - Int errflag = 0; - Timer timer; - - Reset(); - Int num_slices = 5 + std::max((long)(m / control_.rows_per_slice()), 0l); - num_slices = std::min(num_slices, m); - - // Maintain a copy of the inverse scaling factors of basic variables. - for (Int p = 0; p < m; p++) { - Int j = basis[p]; - if (basis.StatusOf(j) == Basis::BASIC) { - slice.invscale_basic[p] = colscale ? 1.0 / colscale[j] : 1.0; - assert(std::isfinite(slice.invscale_basic[p])); + const Model& model = basis.model(); + const Int m = model.rows(); + const Int n = model.cols(); + Slice slice(m, n); + Int errflag = 0; + Timer timer; + + Reset(); + Int num_slices = 5 + std::max((long)(m/control_.rows_per_slice()), 0l); + num_slices = std::min(num_slices, m); + + // Maintain a copy of the inverse scaling factors of basic variables. + for (Int p = 0; p < m; p++) { + Int j = basis[p]; + if (basis.StatusOf(j) == Basis::BASIC) { + slice.invscale_basic[p] = colscale ? 1.0/colscale[j] : 1.0; + assert(std::isfinite(slice.invscale_basic[p])); + } } - } - - // We need to work with a copy of the column scaling factors, in which - // skipped columns are set to zero (and not scanned again). - for (Int j = 0; j < n + m; j++) { - if (basis.StatusOf(j) == Basis::NONBASIC) - slice.colscale[j] = colscale ? colscale[j] : 1.0; - } - - // Split tableau matrix into num_slices row slices. In each call to - // Driver() there is exactly one row from each slice that has - // tblrow_used[p] == 1, while the other rows in the slice have - // tblrow_used[p] == 0. - std::vector perm = Sortperm(m, &slice.invscale_basic[0], false); - for (Int s = 0; s < num_slices; s++) { - for (Int i = 0; i < m; i++) - slice.tblrow_used[perm[i]] = i % num_slices == s; - errflag = Driver(basis, slice); - if (errflag) break; - } - - time_ = timer.Elapsed(); - passes_ = -1; - slices_ = num_slices; - return errflag; + + // We need to work with a copy of the column scaling factors, in which + // skipped columns are set to zero (and not scanned again). + for (Int j = 0; j < n+m; j++) { + if (basis.StatusOf(j) == Basis::NONBASIC) + slice.colscale[j] = colscale ? colscale[j] : 1.0; + } + + // Split tableau matrix into num_slices row slices. In each call to + // Driver() there is exactly one row from each slice that has + // tblrow_used[p] == 1, while the other rows in the slice have + // tblrow_used[p] == 0. + std::vector perm = Sortperm(m, &slice.invscale_basic[0], false); + for (Int s = 0; s < num_slices; s++) { + for (Int i = 0; i < m; i++) + slice.tblrow_used[perm[i]] = i%num_slices == s; + errflag = Driver(basis, slice); + if (errflag) + break; + } + + time_ = timer.Elapsed(); + passes_ = -1; + slices_ = num_slices; + return errflag; } Int Maxvolume::updates() const { return updates_; } @@ -164,170 +161,177 @@ double Maxvolume::tblmax() const { return tblmax_; } double Maxvolume::frobnorm_squared() const { return frobnorm_squared_; } void Maxvolume::Reset() { - updates_ = 0; - skipped_ = 0; - passes_ = 0; - slices_ = 0; - volinc_ = 0.0; - ; - time_ = 0.0; - tblnnz_ = 0; - tblmax_ = 0.0; - frobnorm_squared_ = 0.0; + updates_ = 0; + skipped_ = 0; + passes_ = 0; + slices_ = 0; + volinc_ = 0.0;; + time_ = 0.0; + tblnnz_ = 0; + tblmax_ = 0.0; + frobnorm_squared_ = 0.0; } // Returns a vector holding the indices of the largest and second largest // entry in @weights. The index of the largest entry is at the back. static std::vector FindLargest(const Vector& weights) { - const Int n = weights.size(); - Int jmax = 0; // index of largest element - Int jmax2 = 0; // index of second largest element - double wmax = 0.0; - double wmax2 = 0.0; - - for (Int j = 0; j < n; j++) { - double w = std::abs(weights[j]); - if (w > wmax) { - wmax2 = wmax; - wmax = w; - jmax2 = jmax; - jmax = j; - } else if (w > wmax2) { - wmax2 = w; - jmax2 = j; + const Int n = weights.size(); + Int jmax = 0; // index of largest element + Int jmax2 = 0; // index of second largest element + double wmax = 0.0; + double wmax2 = 0.0; + + for (Int j = 0; j < n; j++) { + double w = std::abs(weights[j]); + if (w > wmax) { + wmax2 = wmax; + wmax = w; + jmax2 = jmax; + jmax = j; + } + else if (w > wmax2) { + wmax2 = w; + jmax2 = j; + } } - } - return {jmax2, jmax}; + return {jmax2, jmax}; } Int Maxvolume::Driver(Basis& basis, Slice& slice) { - const Model& model = basis.model(); - const Int m = model.rows(); - const Int n = model.cols(); - const SparseMatrix& AI = model.AI(); - Int errflag = 0; - - const double volumetol = std::max(control_.volume_tol(), 1.0); - const Int maxskip = control_.maxskip_updates(); - - Vector& colscale = slice.colscale; - Vector& invscale_basic = slice.invscale_basic; - const std::vector& tblrow_used = slice.tblrow_used; - Vector& colweights = slice.colweights; - IndexedVector& lhs = slice.lhs; - IndexedVector& row = slice.row; - Vector& work = slice.work; - - // Compute column weights. - for (Int p = 0; p < m; p++) - work[p] = tblrow_used[p] ? invscale_basic[p] : 0.0; - basis.SolveDense(work, work, 'T'); - for (Int j = 0; j < n + m; j++) { - if (colscale[j]) { - assert(basis.StatusOf(j) == Basis::NONBASIC); - double sum = DotColumn(AI, j, work); - colweights[j] = sum * colscale[j]; - } else - colweights[j] = 0.0; - } - - std::vector candidates; - Int skipped = 0; - while (true) { - // Pick column with maximum weight. - if (candidates.empty()) { - candidates = FindLargest(colweights); - assert(!candidates.empty()); - } - Int jn = candidates.back(); - assert(jn >= 0 && jn < n + m); - const double weight = colweights[jn]; - if (weight == 0.0) break; - assert(basis.StatusOf(jn) == Basis::NONBASIC); - assert(colscale[jn] > 0.0); - - if ((errflag = control_.InterruptCheck()) != 0) break; - - // Find maximum scaled FTRAN entry. - basis.SolveForUpdate(jn, lhs); - const Int pmax = ScaleFtran(colscale[jn], invscale_basic, lhs); - const double scaled_pivot = lhs[pmax]; - const double vmax = std::abs(scaled_pivot); - - // Skip the column if exchange does not increase volume enough. - if (vmax <= volumetol) { - colweights[jn] = 0.0; - colscale[jn] = 0.0; - candidates.pop_back(); - if (++skipped > maxskip && maxskip >= 0) break; - continue; + const Model& model = basis.model(); + const Int m = model.rows(); + const Int n = model.cols(); + const SparseMatrix& AI = model.AI(); + Int errflag = 0; + + const double volumetol = std::max(control_.volume_tol(), 1.0); + const Int maxskip = control_.maxskip_updates(); + + Vector& colscale = slice.colscale; + Vector& invscale_basic = slice.invscale_basic; + const std::vector& tblrow_used = slice.tblrow_used; + Vector& colweights = slice.colweights; + IndexedVector& lhs = slice.lhs; + IndexedVector& row = slice.row; + Vector& work = slice.work; + + // Compute column weights. + for (Int p = 0; p < m; p++) + work[p] = tblrow_used[p] ? invscale_basic[p] : 0.0; + basis.SolveDense(work, work, 'T'); + for (Int j = 0; j < n+m; j++) { + if (colscale[j]) { + assert(basis.StatusOf(j) == Basis::NONBASIC); + double sum = DotColumn(AI, j, work); + colweights[j] = sum * colscale[j]; + } + else + colweights[j] = 0.0; } - // Recompute column weight from FTRAN. - double weight_recomp = 0.0; - auto sum_used = [&](Int p, double x) { - if (tblrow_used[p]) weight_recomp += x; - }; - for_each_nonzero(lhs, sum_used); - assert(std::isfinite(weight_recomp)); - - // Update basis. - const Int jb = basis[pmax]; - basis.TableauRow(jb, lhs, row, true); - const double pivot = row[jn]; - if (std::abs(pivot) < 1e-3) { - control_.Debug(3) << " |pivot| " << sci2(std::abs(pivot)) - << "(maxvolume)\n"; + std::vector candidates; + Int skipped = 0; + while (true) { + // Pick column with maximum weight. + if (candidates.empty()) { + candidates = FindLargest(colweights); + assert(!candidates.empty()); + } + Int jn = candidates.back(); + assert(jn >= 0 && jn < n+m); + const double weight = colweights[jn]; + if (weight == 0.0) + break; + assert(basis.StatusOf(jn) == Basis::NONBASIC); + assert(colscale[jn] > 0.0); + + if ((errflag = control_.InterruptCheck()) != 0) + break; + + // Find maximum scaled FTRAN entry. + basis.SolveForUpdate(jn, lhs); + const Int pmax = ScaleFtran(colscale[jn], invscale_basic, lhs); + const double scaled_pivot = lhs[pmax]; + const double vmax = std::abs(scaled_pivot); + + // Skip the column if exchange does not increase volume enough. + if (vmax <= volumetol) { + colweights[jn] = 0.0; + colscale[jn] = 0.0; + candidates.pop_back(); + if (++skipped > maxskip && maxskip >= 0) + break; + continue; + } + + // Recompute column weight from FTRAN. + double weight_recomp = 0.0; + auto sum_used = [&](Int p, double x) { + if (tblrow_used[p]) + weight_recomp += x; + }; + for_each_nonzero(lhs, sum_used); + assert(std::isfinite(weight_recomp)); + + // Update basis. + const Int jb = basis[pmax]; + basis.TableauRow(jb, lhs, row, true); + const double pivot = row[jn]; + if (std::abs(pivot) < 1e-3) { + control_.Debug(3) + << " |pivot| " << sci2(std::abs(pivot)) + << "(maxvolume)\n"; + } + bool exchanged; + errflag = basis.ExchangeIfStable(jb, jn, pivot, 0, &exchanged); + if (errflag) + break; + if (!exchanged) // factorization was unstable, try again + continue; + updates_++; + volinc_ += std::log2(vmax); + + // Update colscale and invscale_basic. + const double dn = colscale[jn]; + const double dbinv = invscale_basic[pmax]; + assert(colscale[jb] == 0.0); + colscale[jb] = 1.0 / invscale_basic[pmax]; + invscale_basic[pmax] = 1.0 / colscale[jn]; + colscale[jn] = 0.0; + assert(std::isfinite(colscale[jb])); + assert(std::isfinite(invscale_basic[pmax])); + + // Update column weights. + const double alpha = (tblrow_used[pmax] - weight_recomp) / (dn*pivot); + assert(std::isfinite(alpha)); + auto add = [&](Int j, double x) { + colweights[j] += alpha * x * colscale[j]; + }; + for_each_nonzero(row, add); + colweights[jb] = tblrow_used[pmax] + alpha/dbinv; + colweights[jn] = 0.0; + candidates.clear(); } - bool exchanged; - errflag = basis.ExchangeIfStable(jb, jn, pivot, 0, &exchanged); - if (errflag) break; - if (!exchanged) // factorization was unstable, try again - continue; - updates_++; - volinc_ += std::log2(vmax); - - // Update colscale and invscale_basic. - const double dn = colscale[jn]; - const double dbinv = invscale_basic[pmax]; - assert(colscale[jb] == 0.0); - colscale[jb] = 1.0 / invscale_basic[pmax]; - invscale_basic[pmax] = 1.0 / colscale[jn]; - colscale[jn] = 0.0; - assert(std::isfinite(colscale[jb])); - assert(std::isfinite(invscale_basic[pmax])); - - // Update column weights. - const double alpha = (tblrow_used[pmax] - weight_recomp) / (dn * pivot); - assert(std::isfinite(alpha)); - auto add = [&](Int j, double x) { - colweights[j] += alpha * x * colscale[j]; - }; - for_each_nonzero(row, add); - colweights[jb] = tblrow_used[pmax] + alpha / dbinv; - colweights[jn] = 0.0; - candidates.clear(); - } - - skipped_ += skipped; - return errflag; + + skipped_ += skipped; + return errflag; } Int Maxvolume::ScaleFtran(double colscale_jn, const Vector& invscale_basic, IndexedVector& ftran) { - double vmax = 0.0; - Int pmax = 0; - auto fcn = [&](Int p, double& pivot) { - double scaled_pivot = pivot * colscale_jn * invscale_basic[p]; - double v = std::abs(scaled_pivot); - if (v > vmax && std::abs(pivot) > kPivotZeroTol) { - vmax = v; - pmax = p; - } - pivot = scaled_pivot; - }; - for_each_nonzero(ftran, fcn); - return pmax; + double vmax = 0.0; + Int pmax = 0; + auto fcn = [&](Int p, double& pivot) { + double scaled_pivot = pivot * colscale_jn * invscale_basic[p]; + double v = std::abs(scaled_pivot); + if (v > vmax && std::abs(pivot) > kPivotZeroTol) { + vmax = v; + pmax = p; + } + pivot = scaled_pivot; + }; + for_each_nonzero(ftran, fcn); + return pmax; } } // namespace ipx From 0e435760f4fbad2af06c0680cf5852e1c0e814c2 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Tue, 4 Aug 2026 20:09:24 +0200 Subject: [PATCH 04/11] Change requested by Julian --- highs/util/HFactorRefactor.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/highs/util/HFactorRefactor.cpp b/highs/util/HFactorRefactor.cpp index e404747b315..9b3d8c8e5df 100644 --- a/highs/util/HFactorRefactor.cpp +++ b/highs/util/HFactorRefactor.cpp @@ -40,7 +40,7 @@ HighsInt HFactor::rebuild(HighsTimerClock* factor_timer_clock_pointer) { basis_matrix_num_el = 0; HighsInt stage = num_row; HighsInt rank_deficiency = 0; - vector has_pivot; + std::vector has_pivot; has_pivot.assign(num_row, false); const bool report_unit = false; const bool report_singletons = false; @@ -209,7 +209,7 @@ HighsInt HFactor::rebuild(HighsTimerClock* factor_timer_clock_pointer) { // Need to know whether to consider matrix entries for FtranL // operation. Initially these correspond to all the rows without // pivots - vector not_in_bump = has_pivot; + std::vector not_in_bump = has_pivot; // Monitor density of FtranL result to possibly switch from exploiting // hyper-sparsity double expected_density = 0.0; From 51619ec5093077ca9ff40977cdf0423a99b3763b Mon Sep 17 00:00:00 2001 From: fwesselm Date: Wed, 5 Aug 2026 13:44:59 +0200 Subject: [PATCH 05/11] Add HighsBool --- check/TestCheckSolution.cpp | 2 +- highs/Highs.h | 2 +- highs/io/HMpsFF.cpp | 4 ++-- highs/io/HMpsFF.h | 4 ++-- highs/ipm/hipo/factorhighs/Analyse.cpp | 2 +- highs/ipm/hipo/ipm/Model.cpp | 2 +- highs/ipm/hipo/ipm/UpLookingSolver.cpp | 2 +- highs/ipm/ipx/lu_factorization.cc | 2 +- highs/ipm/ipx/maxvolume.cc | 4 ++-- highs/lp_data/HStruct.h | 2 +- highs/lp_data/Highs.cpp | 2 +- highs/lp_data/HighsCallback.cpp | 2 +- highs/lp_data/HighsCallback.h | 2 +- highs/lp_data/HighsInterface.cpp | 18 +++++++++--------- highs/mip/HighsCliqueTable.h | 4 ++-- highs/mip/HighsCutGeneration.cpp | 14 +++++++------- highs/mip/HighsCutGeneration.h | 6 +++--- highs/mip/HighsCutPool.h | 6 +++--- highs/mip/HighsDomain.cpp | 8 ++++---- highs/mip/HighsDomain.h | 12 ++++++------ highs/mip/HighsDynamicRowMatrix.h | 2 +- highs/mip/HighsImplications.h | 2 +- highs/mip/HighsMipSolverData.h | 2 +- highs/mip/HighsModkSeparator.cpp | 2 +- highs/mip/HighsPathSeparator.cpp | 2 +- highs/mip/HighsSearch.cpp | 8 ++++---- highs/pdlp/hipdlp/pdhg.hpp | 2 +- highs/presolve/HPresolve.cpp | 6 ++---- highs/presolve/HPresolve.h | 10 +++++----- highs/presolve/HPresolveAnalysis.h | 2 +- highs/presolve/HighsPostsolveStack.h | 2 +- highs/presolve/HighsSymmetry.cpp | 2 +- highs/presolve/HighsSymmetry.h | 2 +- highs/util/HFactorRefactor.cpp | 4 ++-- highs/util/HighsInt.h | 2 ++ 35 files changed, 75 insertions(+), 75 deletions(-) diff --git a/check/TestCheckSolution.cpp b/check/TestCheckSolution.cpp index dbca4cdfa9e..c87b4400505 100644 --- a/check/TestCheckSolution.cpp +++ b/check/TestCheckSolution.cpp @@ -289,7 +289,7 @@ TEST_CASE("check-set-mip-solution", "[highs_check_solution]") { index.clear(); value.clear(); - std::vector is_set; + std::vector is_set; is_set.assign(lp.num_col_, false); HighsInt num_to_set = 2; assert(num_to_set > 0); diff --git a/highs/Highs.h b/highs/Highs.h index bbaf16951d3..a271803aac7 100644 --- a/highs/Highs.h +++ b/highs/Highs.h @@ -1842,7 +1842,7 @@ class Highs { HighsStatus getIisInterface(); HighsStatus getIisInterfaceReturn( const HighsStatus return_status, const HighsOptions& original_options, - const std::vector& original_callbacks); + const std::vector& original_callbacks); HighsStatus elasticityFilterReturn( const HighsStatus return_status, const std::string& original_model_name, diff --git a/highs/io/HMpsFF.cpp b/highs/io/HMpsFF.cpp index 0f044cbcfa9..df29fe7088b 100644 --- a/highs/io/HMpsFF.cpp +++ b/highs/io/HMpsFF.cpp @@ -1269,8 +1269,8 @@ HMpsFF::Parsekey HMpsFF::parseBounds(const HighsLogOptions& log_options, HighsInt num_si = 0; HighsInt num_sc = 0; - std::vector has_lower; - std::vector has_upper; + std::vector has_lower; + std::vector has_upper; has_lower.assign(num_col, false); has_upper.assign(num_col, false); diff --git a/highs/io/HMpsFF.h b/highs/io/HMpsFF.h index 42fb8ec8dcc..6c561966a02 100644 --- a/highs/io/HMpsFF.h +++ b/highs/io/HMpsFF.h @@ -97,7 +97,7 @@ class HMpsFF { // that are defined as integer by markers in the column section, or // as binary by having a BV flag in the BOUNDS section, and without // any LI or UI flags in the BOUNDS section - std::vector col_binary; + std::vector col_binary; // Record where the cost row is encountered HighsInt cost_row_location; @@ -117,7 +117,7 @@ class HMpsFF { // file for the objective or a row. Have to be class data members so // that they can be used by parseName and addRhs in HMpsFF::parseRhs bool has_obj_entry_; - std::vector has_row_entry_; + std::vector has_row_entry_; /// load LP from MPS file as transposed triplet matrix HighsInt parseFile(std::string filename); diff --git a/highs/ipm/hipo/factorhighs/Analyse.cpp b/highs/ipm/hipo/factorhighs/Analyse.cpp index 3d9606b785b..17bf39c1ec1 100644 --- a/highs/ipm/hipo/factorhighs/Analyse.cpp +++ b/highs/ipm/hipo/factorhighs/Analyse.cpp @@ -210,7 +210,7 @@ void Analyse::fundamentalSupernodes() { // Find fundamental supernodes. // isSN[i] is true if node i is the start of a fundamental supernode - std::vector is_sn(n_, false); + std::vector is_sn(n_, false); std::vector prev_nonz(n_, -1); diff --git a/highs/ipm/hipo/ipm/Model.cpp b/highs/ipm/hipo/ipm/Model.cpp index 9f1a5f15421..f5979fbe0e7 100644 --- a/highs/ipm/hipo/ipm/Model.cpp +++ b/highs/ipm/hipo/ipm/Model.cpp @@ -44,7 +44,7 @@ Int Model::init(const HighsLp& lp, const HighsHessian& Q) { void Model::nzBounds() { // compute lower and upper bounds for the number of nonzeros in normal // equations. - std::vector mark(m_, false); + std::vector mark(m_, false); NE_nz_lb_ = A_.num_row_; NE_nz_ub_ = A_.num_row_; for (Int col = 0; col < A_.num_col_; ++col) { diff --git a/highs/ipm/hipo/ipm/UpLookingSolver.cpp b/highs/ipm/hipo/ipm/UpLookingSolver.cpp index 46085ea0766..b31b4df9402 100644 --- a/highs/ipm/hipo/ipm/UpLookingSolver.cpp +++ b/highs/ipm/hipo/ipm/UpLookingSolver.cpp @@ -92,7 +92,7 @@ void UpLookingSolver::factor(const std::vector& ptr, // A must be upper triangular. // L is computed as lower triangular. The diagonal of L is used to store D^-1. - std::vector mark(n_, false); + std::vector mark(n_, false); std::vector stack(n_); Int top = 0; std::vector revpattern(n_); diff --git a/highs/ipm/ipx/lu_factorization.cc b/highs/ipm/ipx/lu_factorization.cc index 5e8ddd4f961..7958f8156d7 100644 --- a/highs/ipm/ipx/lu_factorization.cc +++ b/highs/ipm/ipx/lu_factorization.cc @@ -15,7 +15,7 @@ static SparseMatrix PermutedMatrix(const Int* Bbegin, const Int* Bend, const std::vector& dependent_cols) { Int dim = rowperm.size(); std::vector permuted_row = InversePerm(rowperm); - std::vector dependent(dim, false); + std::vector dependent(dim, false); for (Int k : dependent_cols) dependent[k] = true; diff --git a/highs/ipm/ipx/maxvolume.cc b/highs/ipm/ipx/maxvolume.cc index 88bb84c7ff1..0735545e119 100644 --- a/highs/ipm/ipx/maxvolume.cc +++ b/highs/ipm/ipx/maxvolume.cc @@ -97,7 +97,7 @@ struct Maxvolume::Slice { lhs(m), row(n+m), work(m) {} Vector colscale; Vector invscale_basic; - std::vector tblrow_used; + std::vector tblrow_used; Vector colweights; IndexedVector lhs, row; Vector work; @@ -209,7 +209,7 @@ Int Maxvolume::Driver(Basis& basis, Slice& slice) { Vector& colscale = slice.colscale; Vector& invscale_basic = slice.invscale_basic; - const std::vector& tblrow_used = slice.tblrow_used; + const std::vector& tblrow_used = slice.tblrow_used; Vector& colweights = slice.colweights; IndexedVector& lhs = slice.lhs; IndexedVector& row = slice.row; diff --git a/highs/lp_data/HStruct.h b/highs/lp_data/HStruct.h index b3599e84631..0f0081c5a0e 100644 --- a/highs/lp_data/HStruct.h +++ b/highs/lp_data/HStruct.h @@ -182,7 +182,7 @@ struct HighsProfiling { HighsInt num_profiling_clock_ = -1; std::vector name; // These vectors are over threads - std::vector submip; + std::vector submip; std::vector record; std::vector submip_record; bool initialized = false; diff --git a/highs/lp_data/Highs.cpp b/highs/lp_data/Highs.cpp index e6407a3a01f..98c37561cc1 100644 --- a/highs/lp_data/Highs.cpp +++ b/highs/lp_data/Highs.cpp @@ -2651,7 +2651,7 @@ HighsStatus Highs::setSolution(const HighsInt num_entries, if (model_.lp_.num_col_ == 0) return return_status; // Warn about duplicates in index HighsInt num_duplicates = 0; - std::vector is_set; + std::vector is_set; is_set.assign(model_.lp_.num_col_, false); const HighsInt to_ix = packed ? num_entries : model_.lp_.num_col_; for (HighsInt iX = 0; iX < to_ix; iX++) { diff --git a/highs/lp_data/HighsCallback.cpp b/highs/lp_data/HighsCallback.cpp index c4a73a7c0c8..2b3b202e693 100644 --- a/highs/lp_data/HighsCallback.cpp +++ b/highs/lp_data/HighsCallback.cpp @@ -196,7 +196,7 @@ HighsStatus HighsCallbackInput::setSolution(HighsInt num_entries, HighsStatus return_status = HighsStatus::kOk; HighsInt num_duplicates = 0; - std::vector is_set(lp.num_col_, false); + std::vector is_set(lp.num_col_, false); for (HighsInt iX = 0; iX < num_entries; iX++) { HighsInt iCol = index[iX]; diff --git a/highs/lp_data/HighsCallback.h b/highs/lp_data/HighsCallback.h index 7bfdd888774..15b3f6f46a7 100644 --- a/highs/lp_data/HighsCallback.h +++ b/highs/lp_data/HighsCallback.h @@ -92,7 +92,7 @@ struct HighsCallback { HighsCCallbackType c_callback = nullptr; void* user_callback_data = nullptr; Highs* highs = nullptr; - std::vector active; + std::vector active; HighsCallbackOutput data_out; HighsCallbackInput data_in; bool callbackActive(const int callback_type); diff --git a/highs/lp_data/HighsInterface.cpp b/highs/lp_data/HighsInterface.cpp index b8c904c5ba3..1a2fafe604c 100644 --- a/highs/lp_data/HighsInterface.cpp +++ b/highs/lp_data/HighsInterface.cpp @@ -1837,7 +1837,7 @@ HighsStatus Highs::getRangingInterface() { HighsStatus Highs::getIisInterfaceReturn( const HighsStatus return_status, const HighsOptions& original_options, - const std::vector& original_callback_active) { + const std::vector& original_callback_active) { // Restore options and callbacks this->options_ = original_options; for (int i = kCallbackMin; i <= kCallbackMax; i++) { @@ -1980,7 +1980,7 @@ HighsStatus Highs::getIisInterface() { HighsOptions original_options = this->options_; // Save original active callbacks and disable all except for // kCallbackLogging and kCallbackSimplexInterrupt - std::vector original_callback_active = callback_.active; + std::vector original_callback_active = callback_.active; for (int i = kCallbackMin; i <= kCallbackMax; i++) { if (i != kCallbackLogging && i != kCallbackSimplexInterrupt && callback_.active[i]) @@ -2266,8 +2266,8 @@ HighsStatus Highs::elasticityFilter(const double global_lower_penalty, // bound_of_row_of_ecol_is_lower so that the results can be interpreted std::vector col_of_ecol; std::vector row_of_ecol; - std::vector bound_of_row_of_ecol_is_lower; - std::vector bound_of_col_of_ecol_is_lower; + std::vector bound_of_row_of_ecol_is_lower; + std::vector bound_of_col_of_ecol_is_lower; std::vector erow_lower; std::vector erow_upper; std::vector erow_start; @@ -2775,7 +2775,7 @@ HighsStatus Highs::elasticityFilter(const double global_lower_penalty, in_row_index[iis.row_index_[iX]] = iX; // Determine the columns with nonzeros in the row subset - std::vector nonzero_in_row_index(original_num_col, false); + std::vector nonzero_in_row_index(original_num_col, false); if (lp.a_matrix_.isColwise()) { for (HighsInt iCol = 0; iCol < original_num_col; iCol++) { for (HighsInt iEl = lp.a_matrix_.start_[iCol]; @@ -4533,8 +4533,8 @@ void Highs::reportProfiling() const { } const double num_threads_used = used_thread.size(); std::stringstream ss; - std::vector mip_used_sub_solver(kToSubSolver, false); - std::vector submip_used_sub_solver(kToSubSolver, false); + std::vector mip_used_sub_solver(kToSubSolver, false); + std::vector submip_used_sub_solver(kToSubSolver, false); const HighsInt to_k = max_sumip_time > 0 ? 2 : 1; const std::vector& name = this->profiling_->name; double sum_sum_mip_sub_solve_time = 0; @@ -4557,7 +4557,7 @@ void Highs::reportProfiling() const { if (ideal_time <= 0) continue; const std::vector& record = k == 0 ? this->profiling_->record : this->profiling_->submip_record; - std::vector& used_sub_solver = + std::vector& used_sub_solver = k == 0 ? mip_used_sub_solver : submip_used_sub_solver; const std::vector& num_call = record[thread_num].num_call; const std::vector& run_time = record[thread_num].run_time; @@ -4627,7 +4627,7 @@ void Highs::reportProfiling() const { } highsLogUser(options_.log_options, HighsLogType::kInfo, "%s\n", ss.str().c_str()); - std::vector& used_sub_solver = + std::vector& used_sub_solver = k == 0 ? mip_used_sub_solver : submip_used_sub_solver; const std::vector& record = k == 0 ? this->profiling_->record : this->profiling_->submip_record; diff --git a/highs/mip/HighsCliqueTable.h b/highs/mip/HighsCliqueTable.h index 3bfca902a5f..afaaedaae06 100644 --- a/highs/mip/HighsCliqueTable.h +++ b/highs/mip/HighsCliqueTable.h @@ -83,8 +83,8 @@ class HighsCliqueTable { std::vector substitutions; std::vector deletedrows; std::vector> cliqueextensions; - std::vector iscandidate; - std::vector colDeleted; + std::vector iscandidate; + std::vector colDeleted; std::vector cliquehits; std::vector cliquehitinds; diff --git a/highs/mip/HighsCutGeneration.cpp b/highs/mip/HighsCutGeneration.cpp index 40139253a89..567465e3125 100644 --- a/highs/mip/HighsCutGeneration.cpp +++ b/highs/mip/HighsCutGeneration.cpp @@ -221,12 +221,12 @@ bool HighsCutGeneration::separateLiftedMixedBinaryCover() { HighsInt coversize = cover.size(); std::vector S; S.resize(coversize); - std::vector coverflag; + std::vector coverflag; coverflag.resize(rowlen); if (coversize == 0) return false; - for (HighsInt i = 0; i != coversize; ++i) coverflag[cover[i]] = 1; + for (HighsInt i = 0; i != coversize; ++i) coverflag[cover[i]] = true; pdqsort_branchless(cover.begin(), cover.end(), [&](HighsInt a, HighsInt b) { return vals[a] > vals[b]; }); @@ -286,9 +286,9 @@ bool HighsCutGeneration::separateLiftedMixedIntegerCover() { HighsInt l = -1; - std::vector coverflag; + std::vector coverflag; coverflag.resize(rowlen); - for (HighsInt i : cover) coverflag[i] = 1; + for (HighsInt i : cover) coverflag[i] = true; auto comp = [&](HighsInt a, HighsInt b) { return vals[a] > vals[b]; }; pdqsort_branchless(cover.begin(), cover.end(), comp); @@ -1227,12 +1227,12 @@ bool HighsCutGeneration::generateConflict(const HighsDomain& localdomain, if (vals[i] < 0 && globaldom.col_upper_[col] != kHighsInf) { rhs -= globaldom.col_upper_[col] * vals[i]; vals[i] = -vals[i]; - complementation[i] = 1; + complementation[i] = true; solval[i] = globaldom.col_upper_[col] - solval[i]; } else { rhs -= globaldom.col_lower_[col] * vals[i]; - complementation[i] = 0; + complementation[i] = false; solval[i] = solval[i] - globaldom.col_lower_[col]; } @@ -1353,7 +1353,7 @@ void HighsCutGeneration::flipComplementation(HighsInt index) { assert(upper[index] != kHighsInf); // flip complementation - complementation[index] = 1 - complementation[index]; + complementation[index] = !complementation[index]; solval[index] = upper[index] - solval[index]; rhs -= upper[index] * vals[index]; vals[index] = -vals[index]; diff --git a/highs/mip/HighsCutGeneration.h b/highs/mip/HighsCutGeneration.h index 39e728db6cc..91e2d792c77 100644 --- a/highs/mip/HighsCutGeneration.h +++ b/highs/mip/HighsCutGeneration.h @@ -38,8 +38,8 @@ class HighsCutGeneration { HighsCDouble lambda; std::vector upper; std::vector solval; - std::vector complementation; - std::vector isintegral; + std::vector complementation; + std::vector isintegral; const double feastol; const double epsilon; @@ -56,7 +56,7 @@ class HighsCutGeneration { std::vector tmpVals; std::vector tmpInds; - std::vector tmpComplementation; + std::vector tmpComplementation; std::vector tmpSolval; bool determineCover(bool lpSol = true); diff --git a/highs/mip/HighsCutPool.h b/highs/mip/HighsCutPool.h index e0fd717699b..115befdbb8e 100644 --- a/highs/mip/HighsCutPool.h +++ b/highs/mip/HighsCutPool.h @@ -58,11 +58,11 @@ class HighsCutPool { std::vector ages_; std::deque> numLps_; std::deque> - ageResetWhileLocked_; // Was the cut propagated? - std::vector hasSynced_; // Has the cut been globally synced? + ageResetWhileLocked_; // Was the cut propagated? + std::vector hasSynced_; // Has the cut been globally synced? std::vector rownormalization_; std::vector maxabscoef_; - std::vector rowintegral; + std::vector rowintegral; std::unordered_multimap hashToCutMap; std::vector propagationDomains; std::set> propRows; diff --git a/highs/mip/HighsDomain.cpp b/highs/mip/HighsDomain.cpp index a7c0b5f9b2b..7bbcc3ef174 100644 --- a/highs/mip/HighsDomain.cpp +++ b/highs/mip/HighsDomain.cpp @@ -1946,7 +1946,7 @@ void HighsDomain::markPropagate(HighsInt row) { if (proplower || propupper) { propagateinds_.push_back(row); - propagateflags_[row] = 1; + propagateflags_[row] = true; } } } @@ -1993,7 +1993,7 @@ double HighsDomain::doChangeBound(const HighsDomainChange& boundchg) { updateActivityLbChange(boundchg.column, oldbound, boundchg.boundval); if (!isChangedCol(boundchg.column)) { - changedcolsflags_[boundchg.column] = 1; + changedcolsflags_[boundchg.column] = true; changedcols_.push_back(boundchg.column); } } @@ -2005,7 +2005,7 @@ double HighsDomain::doChangeBound(const HighsDomainChange& boundchg) { updateActivityUbChange(boundchg.column, oldbound, boundchg.boundval); if (!isChangedCol(boundchg.column)) { - changedcolsflags_[boundchg.column] = 1; + changedcolsflags_[boundchg.column] = true; changedcols_.push_back(boundchg.column); } } @@ -2410,7 +2410,7 @@ bool HighsDomain::propagate() { HighsInt numproprows = static_cast(propagateinds.size()); for (HighsInt i = 0; i != numproprows; ++i) { HighsInt row = propagateinds[i]; - propagateflags_[row] = 0; + propagateflags_[row] = false; } if (!infeasible_) { diff --git a/highs/mip/HighsDomain.h b/highs/mip/HighsDomain.h index 02981bc2218..2b1e48c489d 100644 --- a/highs/mip/HighsDomain.h +++ b/highs/mip/HighsDomain.h @@ -162,7 +162,7 @@ class HighsDomain { HighsCutPool* cutpool; std::vector activitycuts_; std::vector activitycutsinf_; - std::vector propagatecutflags_; + std::vector propagatecutflags_; std::vector propagatecutinds_; std::vector capacityThreshold_; @@ -198,7 +198,7 @@ class HighsDomain { HighsConflictPool* conflictpool_; std::vector colLowerWatched_; std::vector colUpperWatched_; - std::vector conflictFlag_; + std::vector conflictFlag_; std::vector propagateConflictInds_; struct WatchedLiteral { @@ -297,7 +297,7 @@ class HighsDomain { void recomputeCapacityThreshold(); }; - std::vector changedcolsflags_; + std::vector changedcolsflags_; std::vector changedcols_; std::vector> propRowNumChangedBounds_; @@ -311,7 +311,7 @@ class HighsDomain { std::vector activitymininf_; std::vector activitymaxinf_; std::vector capacityThreshold_; - std::vector propagateflags_; + std::vector propagateflags_; std::vector propagateinds_; ObjectivePropagation objProp_; @@ -446,7 +446,7 @@ class HighsDomain { void addConflictPool(HighsConflictPool& conflictPool); void clearChangedCols() { - for (HighsInt i : changedcols_) changedcolsflags_[i] = 0; + for (HighsInt i : changedcols_) changedcolsflags_[i] = false; changedcols_.clear(); } @@ -462,7 +462,7 @@ class HighsDomain { void clearChangedCols(size_t start) { for (size_t i = start; i != changedcols_.size(); ++i) - changedcolsflags_[changedcols_[i]] = 0; + changedcolsflags_[changedcols_[i]] = false; changedcols_.resize(start); } diff --git a/highs/mip/HighsDynamicRowMatrix.h b/highs/mip/HighsDynamicRowMatrix.h index aa3bb7b2550..1e71de84295 100644 --- a/highs/mip/HighsDynamicRowMatrix.h +++ b/highs/mip/HighsDynamicRowMatrix.h @@ -35,7 +35,7 @@ class HighsDynamicRowMatrix { std::vector AheadPos_; std::vector AheadNeg_; - std::vector colsLinked; + std::vector colsLinked; /// vector of column sizes diff --git a/highs/mip/HighsImplications.h b/highs/mip/HighsImplications.h index a82cc1d1a9b..50fa737395e 100644 --- a/highs/mip/HighsImplications.h +++ b/highs/mip/HighsImplications.h @@ -56,7 +56,7 @@ class HighsImplications { public: const HighsMipSolver& mipsolver; std::vector substitutions; - std::vector colsubstituted; + std::vector colsubstituted; HighsImplications(const HighsMipSolver& mipsolver) : mipsolver(mipsolver) { HighsInt numcol = mipsolver.numCol(); implications.resize(2 * static_cast(numcol)); diff --git a/highs/mip/HighsMipSolverData.h b/highs/mip/HighsMipSolverData.h index 12041d116f7..070d90ef0d1 100644 --- a/highs/mip/HighsMipSolverData.h +++ b/highs/mip/HighsMipSolverData.h @@ -102,7 +102,7 @@ struct HighsMipSolverData { std::vector ARindex_; std::vector ARvalue_; std::vector maxAbsRowCoef; - std::vector rowintegral; + std::vector rowintegral; std::vector uplocks; std::vector downlocks; std::vector integer_cols; diff --git a/highs/mip/HighsModkSeparator.cpp b/highs/mip/HighsModkSeparator.cpp index 19727670bda..b1de06cab74 100644 --- a/highs/mip/HighsModkSeparator.cpp +++ b/highs/mip/HighsModkSeparator.cpp @@ -47,7 +47,7 @@ void HighsModkSeparator::separateLpSolution(HighsLpRelaxation& lpRelaxation, const HighsMipSolver& mipsolver = lpRelaxation.getMipSolver(); const HighsLp& lp = lpRelaxation.getLp(); - std::vector skipRow(lp.num_row_); + std::vector skipRow(lp.num_row_); // mark all rows that have continuous variables with a nonzero solution value // in the transformed LP to be skipped diff --git a/highs/mip/HighsPathSeparator.cpp b/highs/mip/HighsPathSeparator.cpp index d4fa7ad8e14..d67bab084f9 100644 --- a/highs/mip/HighsPathSeparator.cpp +++ b/highs/mip/HighsPathSeparator.cpp @@ -400,7 +400,7 @@ void HighsPathSeparator::separateLpSolution(HighsLpRelaxation& lpRelaxation, std::vector inds; std::vector solval; std::vector upper; - std::vector isIntegral; + std::vector isIntegral; inds.reserve(lp.num_col_ + lp.num_row_); solval.reserve(lp.num_col_ + lp.num_row_); upper.reserve(lp.num_col_ + lp.num_row_); diff --git a/highs/mip/HighsSearch.cpp b/highs/mip/HighsSearch.cpp index 2ab00508239..2472401eba6 100644 --- a/highs/mip/HighsSearch.cpp +++ b/highs/mip/HighsSearch.cpp @@ -251,8 +251,8 @@ HighsInt HighsSearch::selectBranchingCandidate(int64_t maxSbIters, std::vector upscore; std::vector downscore; - std::vector upscorereliable; - std::vector downscorereliable; + std::vector upscorereliable; + std::vector downscorereliable; std::vector upbound; std::vector downbound; @@ -680,8 +680,8 @@ HighsInt HighsSearch::selectBranchingCandidate(int64_t maxSbIters, // avoid choosing it as branching candidate if possible downscore[candidate] = 0.0; upscore[candidate] = 0.0; - downscorereliable[candidate] = 1; - upscorereliable[candidate] = 1; + downscorereliable[candidate] = true; + upscorereliable[candidate] = true; markBranchingVarUpReliableAtNode(col); markBranchingVarDownReliableAtNode(col); } diff --git a/highs/pdlp/hipdlp/pdhg.hpp b/highs/pdlp/hipdlp/pdhg.hpp index baa57505693..cc04f0e6d74 100644 --- a/highs/pdlp/hipdlp/pdhg.hpp +++ b/highs/pdlp/hipdlp/pdhg.hpp @@ -211,7 +211,7 @@ class PDLPSolver { HighsInt sense_origin_ = 1; double unscaled_rhs_norm_ = 0.0; double unscaled_c_norm_ = 0.0; - std::vector is_equality_row_; + std::vector is_equality_row_; std::vector constraint_new_idx_; std::vector constraint_types_; diff --git a/highs/presolve/HPresolve.cpp b/highs/presolve/HPresolve.cpp index 940d68b51f2..c8aa0600254 100644 --- a/highs/presolve/HPresolve.cpp +++ b/highs/presolve/HPresolve.cpp @@ -6469,10 +6469,8 @@ void HPresolve::computeIntermediateMatrix(std::vector& flagRow, toCSC(model->a_matrix_.value_, model->a_matrix_.index_, model->a_matrix_.start_); - for (HighsInt i = 0; i != model->num_row_; ++i) - flagRow[i] = 1 - rowDeleted[i]; - for (HighsInt i = 0; i != model->num_col_; ++i) - flagCol[i] = 1 - colDeleted[i]; + for (HighsInt i = 0; i != model->num_row_; ++i) flagRow[i] = !rowDeleted[i]; + for (HighsInt i = 0; i != model->num_col_; ++i) flagCol[i] = !colDeleted[i]; } HPresolve::Result HPresolve::removeDependentEquations( diff --git a/highs/presolve/HPresolve.h b/highs/presolve/HPresolve.h index a3d04928e63..780b84c33a7 100644 --- a/highs/presolve/HPresolve.h +++ b/highs/presolve/HPresolve.h @@ -90,9 +90,9 @@ class HPresolve { HighsLinearSumBounds impliedDualRowBounds; std::vector changedRowIndices; - std::vector changedRowFlag; + std::vector changedRowFlag; std::vector changedColIndices; - std::vector changedColFlag; + std::vector changedColFlag; std::vector> substitutionOpportunities; @@ -114,12 +114,12 @@ class HPresolve { std::vector singletonColumns; // flags to mark rows/columns as deleted - std::vector rowDeleted; - std::vector colDeleted; + std::vector rowDeleted; + std::vector colDeleted; // flags to skip repeated single-equation handling (dual fixing) on unchanged // rows - std::vector singleEquationChecked; + std::vector singleEquationChecked; std::vector numProbes; diff --git a/highs/presolve/HPresolveAnalysis.h b/highs/presolve/HPresolveAnalysis.h index d0d8770cc4d..9a22712d0a2 100644 --- a/highs/presolve/HPresolveAnalysis.h +++ b/highs/presolve/HPresolveAnalysis.h @@ -23,7 +23,7 @@ class HPresolveAnalysis { HighsInt original_num_row_; public: - std::vector allow_rule_; + std::vector allow_rule_; bool allow_logging_; bool logging_on_; diff --git a/highs/presolve/HighsPostsolveStack.h b/highs/presolve/HighsPostsolveStack.h index 009cf282b21..e207f041b30 100644 --- a/highs/presolve/HighsPostsolveStack.h +++ b/highs/presolve/HighsPostsolveStack.h @@ -249,7 +249,7 @@ class HighsPostsolveStack { std::vector> reductions; std::vector origColIndex; std::vector origRowIndex; - std::vector linearlyTransformable; + std::vector linearlyTransformable; std::vector rowValues; std::vector colValues; diff --git a/highs/presolve/HighsSymmetry.cpp b/highs/presolve/HighsSymmetry.cpp index 2820fd6002f..5c52b6f0bb2 100644 --- a/highs/presolve/HighsSymmetry.cpp +++ b/highs/presolve/HighsSymmetry.cpp @@ -729,7 +729,7 @@ HighsInt HighsOrbitopeMatrix::orbitalFixingForFullOrbitope( HighsInt HighsOrbitopeMatrix::orbitalFixing(HighsDomain& domain) const { std::vector rows; - std::vector rowUsed(numRows); + std::vector rowUsed(numRows); rows.reserve(numRows); diff --git a/highs/presolve/HighsSymmetry.h b/highs/presolve/HighsSymmetry.h index 3aac69b57b1..b3ed0d0a63f 100644 --- a/highs/presolve/HighsSymmetry.h +++ b/highs/presolve/HighsSymmetry.h @@ -182,7 +182,7 @@ class HighsSymmetryDetection { std::vector orbitSize; std::vector cellCreationStack; - std::vector cellInRefinementQueue; + std::vector cellInRefinementQueue; std::vector refinementQueue; std::vector distinguishCands; std::vector automorphisms; diff --git a/highs/util/HFactorRefactor.cpp b/highs/util/HFactorRefactor.cpp index 9b3d8c8e5df..6817fd5f9cf 100644 --- a/highs/util/HFactorRefactor.cpp +++ b/highs/util/HFactorRefactor.cpp @@ -40,7 +40,7 @@ HighsInt HFactor::rebuild(HighsTimerClock* factor_timer_clock_pointer) { basis_matrix_num_el = 0; HighsInt stage = num_row; HighsInt rank_deficiency = 0; - std::vector has_pivot; + std::vector has_pivot; has_pivot.assign(num_row, false); const bool report_unit = false; const bool report_singletons = false; @@ -209,7 +209,7 @@ HighsInt HFactor::rebuild(HighsTimerClock* factor_timer_clock_pointer) { // Need to know whether to consider matrix entries for FtranL // operation. Initially these correspond to all the rows without // pivots - std::vector not_in_bump = has_pivot; + std::vector not_in_bump = has_pivot; // Monitor density of FtranL result to possibly switch from exploiting // hyper-sparsity double expected_density = 0.0; diff --git a/highs/util/HighsInt.h b/highs/util/HighsInt.h index 95a610f55bb..fbdec1e9149 100644 --- a/highs/util/HighsInt.h +++ b/highs/util/HighsInt.h @@ -33,4 +33,6 @@ typedef unsigned int HighsUInt; #define HIGHSINT_FORMAT "d" #endif +typedef uint8_t HighsBool; + #endif From cf9f40f4940883cacbf24d4476ded81f15f12fe7 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Wed, 5 Aug 2026 14:18:38 +0200 Subject: [PATCH 06/11] Rename --- check/Avgas.h | 2 +- cmake/sources.cmake | 2 +- docs/c_api_gen/build.jl | 2 +- highs/HighsExternalApi.h | 2 +- highs/io/HMPSIO.h | 2 +- highs/io/HMpsFF.h | 2 +- highs/ipm/IpxSolution.h | 2 +- highs/ipm/hipo/auxiliary/IntConfig.h | 2 +- highs/ipm/hipo/factorhighs/FactorHighs_c_api.h | 2 +- highs/ipm/ipx/ipx_config.h | 2 +- highs/lp_data/HConst.h | 2 +- highs/lp_data/HighsCallbackStruct.h | 2 +- highs/mip/HighsConflictPool.h | 2 +- highs/mip/HighsCutGeneration.h | 2 +- highs/mip/HighsDomainChange.h | 2 +- highs/mip/HighsDynamicRowMatrix.h | 2 +- highs/mip/HighsObjectiveFunction.h | 2 +- highs/mip/HighsPseudocost.h | 2 +- highs/mip/HighsSeparator.h | 2 +- highs/mip/HighsTransformedLp.h | 2 +- highs/parallel/HighsSplitDeque.h | 2 +- highs/parallel/HighsTaskExecutor.h | 2 +- highs/presolve/HighsSymmetry.h | 2 +- highs/qpsolver/qpvector.hpp | 2 +- highs/simplex/SimplexConst.h | 2 +- highs/test_kkt/KktCh2.h | 2 +- highs/util/HFactorConst.h | 2 +- highs/util/HSet.h | 2 +- highs/util/HVectorBase.h | 2 +- highs/util/HighsDataStack.h | 2 +- highs/util/HighsDisjointSets.h | 2 +- highs/util/HighsHash.h | 2 +- highs/util/HighsIntegers.h | 2 +- highs/util/HighsMatrixSlice.h | 2 +- highs/util/HighsMemoryAllocation.h | 2 +- highs/util/HighsRbTree.h | 2 +- highs/util/HighsSparseVectorSum.h | 2 +- highs/util/HighsSplay.h | 2 +- highs/util/HighsTimer.h | 2 +- highs/util/{HighsInt.h => HighsType.h} | 8 ++++---- 40 files changed, 43 insertions(+), 43 deletions(-) rename highs/util/{HighsInt.h => HighsType.h} (88%) diff --git a/check/Avgas.h b/check/Avgas.h index 6e7154cfc2f..d3f79fb15c1 100644 --- a/check/Avgas.h +++ b/check/Avgas.h @@ -15,7 +15,7 @@ #include -#include "util/HighsInt.h" +#include "util/HighsType.h" const HighsInt avgas_num_col = 8; const HighsInt avgas_num_row = 10; diff --git a/cmake/sources.cmake b/cmake/sources.cmake index aa21420e9d9..a0406ac5465 100644 --- a/cmake/sources.cmake +++ b/cmake/sources.cmake @@ -617,7 +617,7 @@ set(highs_headers util/HighsDynamicLibrary.h util/HighsHash.h util/HighsHashTree.h - util/HighsInt.h + util/HighsType.h util/HighsIntegers.h util/HighsLinearSumBounds.h util/HighsMatrixPic.h diff --git a/docs/c_api_gen/build.jl b/docs/c_api_gen/build.jl index 29ca8fb006f..3417d09bfa1 100644 --- a/docs/c_api_gen/build.jl +++ b/docs/c_api_gen/build.jl @@ -16,7 +16,7 @@ libhighs_filename = joinpath(@__DIR__, "libhighs.jl") Generators.build!( Generators.create_context( - [c_api, joinpath(highs_src, "util", "HighsInt.h")], + [c_api, joinpath(highs_src, "util", "HighsType.h")], [Generators.get_default_args(); "-I$highs_src"; "-I$(@__DIR__)"], Dict{String,Any}( "general" => Dict{String,Any}( diff --git a/highs/HighsExternalApi.h b/highs/HighsExternalApi.h index 92a832a7f5b..50ace471c39 100644 --- a/highs/HighsExternalApi.h +++ b/highs/HighsExternalApi.h @@ -20,7 +20,7 @@ #include "HighsExtrasApi.h" #include "io/HighsIO.h" #include "util/HighsDynamicLibrary.h" -#include "util/HighsInt.h" +#include "util/HighsType.h" #include "util/stringutil.h" // diff --git a/highs/io/HMPSIO.h b/highs/io/HMPSIO.h index 58acffe6e81..4e09cbd2549 100644 --- a/highs/io/HMPSIO.h +++ b/highs/io/HMPSIO.h @@ -19,7 +19,7 @@ #include #include "io/Filereader.h" -#include "util/HighsInt.h" +#include "util/HighsType.h" using std::string; using std::vector; diff --git a/highs/io/HMpsFF.h b/highs/io/HMpsFF.h index 6c561966a02..c5d3e66a33e 100644 --- a/highs/io/HMpsFF.h +++ b/highs/io/HMpsFF.h @@ -30,7 +30,7 @@ #include "io/HighsIO.h" #include "model/HighsModel.h" -// #include "util/HighsInt.h" +// #include "util/HighsType.h" #include "util/stringutil.h" using Triplet = std::tuple; diff --git a/highs/ipm/IpxSolution.h b/highs/ipm/IpxSolution.h index 3a5eb919a8d..7ad4dd0e64e 100644 --- a/highs/ipm/IpxSolution.h +++ b/highs/ipm/IpxSolution.h @@ -15,7 +15,7 @@ #include -#include "util/HighsInt.h" +#include "util/HighsType.h" typedef HighsInt ipxint; struct IpxSolution { diff --git a/highs/ipm/hipo/auxiliary/IntConfig.h b/highs/ipm/hipo/auxiliary/IntConfig.h index f103a1e5b83..cf647e35126 100644 --- a/highs/ipm/hipo/auxiliary/IntConfig.h +++ b/highs/ipm/hipo/auxiliary/IntConfig.h @@ -2,7 +2,7 @@ #define HIPO_INT_CONFIG_H #include "lp_data/HConst.h" -#include "util/HighsInt.h" +#include "util/HighsType.h" namespace hipo { diff --git a/highs/ipm/hipo/factorhighs/FactorHighs_c_api.h b/highs/ipm/hipo/factorhighs/FactorHighs_c_api.h index 10c060b8de0..56771f92ce7 100644 --- a/highs/ipm/hipo/factorhighs/FactorHighs_c_api.h +++ b/highs/ipm/hipo/factorhighs/FactorHighs_c_api.h @@ -1,7 +1,7 @@ #ifndef FACTOR_HIGHS_C_API_H #define FACTOR_HIGHS_C_API_H -#include "util/HighsInt.h" +#include "util/HighsType.h" /* C API to HiPO linear solver It is meant to be used outside of HiGHS as a standalone linear solver. diff --git a/highs/ipm/ipx/ipx_config.h b/highs/ipm/ipx/ipx_config.h index af19dfd0780..8e08a115be3 100644 --- a/highs/ipm/ipx/ipx_config.h +++ b/highs/ipm/ipx/ipx_config.h @@ -3,7 +3,7 @@ #include -#include "util/HighsInt.h" +#include "util/HighsType.h" typedef HighsInt ipxint; #endif /* IPX_CONFIG_H_ */ diff --git a/highs/lp_data/HConst.h b/highs/lp_data/HConst.h index e7e14fadd53..b7aa7e77ed3 100644 --- a/highs/lp_data/HConst.h +++ b/highs/lp_data/HConst.h @@ -15,7 +15,7 @@ #include #include -#include "util/HighsInt.h" +#include "util/HighsType.h" const std::string kHighsCopyrightStatement = "Copyright (c) 2026 under MIT licence terms"; diff --git a/highs/lp_data/HighsCallbackStruct.h b/highs/lp_data/HighsCallbackStruct.h index f30c8be2867..92954214b55 100644 --- a/highs/lp_data/HighsCallbackStruct.h +++ b/highs/lp_data/HighsCallbackStruct.h @@ -11,7 +11,7 @@ #ifndef LP_DATA_HIGHSCALLBACKSTRUCT_H_ #define LP_DATA_HIGHSCALLBACKSTRUCT_H_ -#include "util/HighsInt.h" +#include "util/HighsType.h" #ifdef __cplusplus extern "C" { diff --git a/highs/mip/HighsConflictPool.h b/highs/mip/HighsConflictPool.h index c13ac077314..8767420d94d 100644 --- a/highs/mip/HighsConflictPool.h +++ b/highs/mip/HighsConflictPool.h @@ -13,7 +13,7 @@ #include #include "mip/HighsDomain.h" -#include "util/HighsInt.h" +#include "util/HighsType.h" class HighsConflictPool { private: diff --git a/highs/mip/HighsCutGeneration.h b/highs/mip/HighsCutGeneration.h index 91e2d792c77..b249958a952 100644 --- a/highs/mip/HighsCutGeneration.h +++ b/highs/mip/HighsCutGeneration.h @@ -18,8 +18,8 @@ #include #include "util/HighsCDouble.h" -#include "util/HighsInt.h" #include "util/HighsRandom.h" +#include "util/HighsType.h" class HighsLpRelaxation; class HighsTransformedLp; diff --git a/highs/mip/HighsDomainChange.h b/highs/mip/HighsDomainChange.h index 6e84708b30c..39282302be0 100644 --- a/highs/mip/HighsDomainChange.h +++ b/highs/mip/HighsDomainChange.h @@ -9,7 +9,7 @@ #ifndef HIGHS_DOMAIN_CHANGE_H_ #define HIGHS_DOMAIN_CHANGE_H_ -#include "util/HighsInt.h" +#include "util/HighsType.h" enum class HighsBoundType { kLower, kUpper }; diff --git a/highs/mip/HighsDynamicRowMatrix.h b/highs/mip/HighsDynamicRowMatrix.h index 1e71de84295..47773e1d7ee 100644 --- a/highs/mip/HighsDynamicRowMatrix.h +++ b/highs/mip/HighsDynamicRowMatrix.h @@ -12,7 +12,7 @@ #include #include -#include "util/HighsInt.h" +#include "util/HighsType.h" class HighsDynamicRowMatrix { private: diff --git a/highs/mip/HighsObjectiveFunction.h b/highs/mip/HighsObjectiveFunction.h index 0598146e327..317142b8328 100644 --- a/highs/mip/HighsObjectiveFunction.h +++ b/highs/mip/HighsObjectiveFunction.h @@ -12,7 +12,7 @@ #include #include -#include "util/HighsInt.h" +#include "util/HighsType.h" class HighsCliqueTable; class HighsDomain; diff --git a/highs/mip/HighsPseudocost.h b/highs/mip/HighsPseudocost.h index 52591c4dea3..4abf2884daf 100644 --- a/highs/mip/HighsPseudocost.h +++ b/highs/mip/HighsPseudocost.h @@ -15,7 +15,7 @@ #include #include -#include "util/HighsInt.h" +#include "util/HighsType.h" class HighsMipSolver; namespace presolve { diff --git a/highs/mip/HighsSeparator.h b/highs/mip/HighsSeparator.h index 2eb5d60cdcd..89367f51d15 100644 --- a/highs/mip/HighsSeparator.h +++ b/highs/mip/HighsSeparator.h @@ -15,7 +15,7 @@ #include -#include "util/HighsInt.h" +#include "util/HighsType.h" const std::string kImplboundSepaString = "Separation: Implied bounds"; const std::string kCliqueSepaString = "Separation: Clique"; diff --git a/highs/mip/HighsTransformedLp.h b/highs/mip/HighsTransformedLp.h index bb7e929224c..3b26e1eaf0c 100644 --- a/highs/mip/HighsTransformedLp.h +++ b/highs/mip/HighsTransformedLp.h @@ -19,8 +19,8 @@ #include "lp_data/HConst.h" #include "mip/HighsImplications.h" #include "util/HighsCDouble.h" -#include "util/HighsInt.h" #include "util/HighsSparseVectorSum.h" +#include "util/HighsType.h" class HighsLpRelaxation; diff --git a/highs/parallel/HighsSplitDeque.h b/highs/parallel/HighsSplitDeque.h index 5811b8bfeda..7dd4e71c616 100644 --- a/highs/parallel/HighsSplitDeque.h +++ b/highs/parallel/HighsSplitDeque.h @@ -21,8 +21,8 @@ #include "parallel/HighsCacheAlign.h" #include "parallel/HighsSpinMutex.h" #include "parallel/HighsTask.h" -#include "util/HighsInt.h" #include "util/HighsRandom.h" +#include "util/HighsType.h" #ifdef __has_feature #if __has_feature(thread_sanitizer) diff --git a/highs/parallel/HighsTaskExecutor.h b/highs/parallel/HighsTaskExecutor.h index f960085770a..96a394fcb78 100644 --- a/highs/parallel/HighsTaskExecutor.h +++ b/highs/parallel/HighsTaskExecutor.h @@ -18,8 +18,8 @@ #include "parallel/HighsCacheAlign.h" #include "parallel/HighsSchedulerConstants.h" #include "parallel/HighsSplitDeque.h" -#include "util/HighsInt.h" #include "util/HighsRandom.h" +#include "util/HighsType.h" class HighsTaskExecutor { public: diff --git a/highs/presolve/HighsSymmetry.h b/highs/presolve/HighsSymmetry.h index b3ed0d0a63f..53c96a644dc 100644 --- a/highs/presolve/HighsSymmetry.h +++ b/highs/presolve/HighsSymmetry.h @@ -20,7 +20,7 @@ #include "lp_data/HighsLp.h" #include "util/HighsDisjointSets.h" #include "util/HighsHash.h" -#include "util/HighsInt.h" +#include "util/HighsType.h" /// class that is responsible for assigning distinct colors for each distinct /// double value diff --git a/highs/qpsolver/qpvector.hpp b/highs/qpsolver/qpvector.hpp index 1d5a85b6ed9..34d6d7ff6fc 100644 --- a/highs/qpsolver/qpvector.hpp +++ b/highs/qpsolver/qpvector.hpp @@ -8,7 +8,7 @@ #ifndef __SRC_LIB_VECTOR_HPP__ #define __SRC_LIB_VECTOR_HPP__ -#include +#include #include #include diff --git a/highs/simplex/SimplexConst.h b/highs/simplex/SimplexConst.h index cc69fcb2ace..dd54beb661b 100644 --- a/highs/simplex/SimplexConst.h +++ b/highs/simplex/SimplexConst.h @@ -11,7 +11,7 @@ #ifndef SIMPLEX_SIMPLEXCONST_H_ #define SIMPLEX_SIMPLEXCONST_H_ -#include "util/HighsInt.h" +#include "util/HighsType.h" enum class SimplexAlgorithm { kNone = 0, kPrimal, kDual }; diff --git a/highs/test_kkt/KktCh2.h b/highs/test_kkt/KktCh2.h index c4be01bc4a2..34435dd1dd2 100644 --- a/highs/test_kkt/KktCh2.h +++ b/highs/test_kkt/KktCh2.h @@ -21,7 +21,7 @@ #include "lp_data/HConst.h" #include "test_kkt/DevKkt.h" -#include "util/HighsInt.h" +#include "util/HighsType.h" namespace presolve { diff --git a/highs/util/HFactorConst.h b/highs/util/HFactorConst.h index 7b6b2b2df02..90be1f50f28 100644 --- a/highs/util/HFactorConst.h +++ b/highs/util/HFactorConst.h @@ -11,7 +11,7 @@ #ifndef HFACTORCONST_H_ #define HFACTORCONST_H_ -#include "util/HighsInt.h" +#include "util/HighsType.h" enum UPDATE_METHOD { kUpdateMethodFt = 1, diff --git a/highs/util/HSet.h b/highs/util/HSet.h index 4eab605d154..7ec5d615fc9 100644 --- a/highs/util/HSet.h +++ b/highs/util/HSet.h @@ -17,7 +17,7 @@ #include #include -#include "util/HighsInt.h" +#include "util/HighsType.h" // #include diff --git a/highs/util/HVectorBase.h b/highs/util/HVectorBase.h index a9a9ec0cfa7..8fb01255c27 100644 --- a/highs/util/HVectorBase.h +++ b/highs/util/HVectorBase.h @@ -13,7 +13,7 @@ #include -#include "util/HighsInt.h" +#include "util/HighsType.h" // using std::map; using std::vector; diff --git a/highs/util/HighsDataStack.h b/highs/util/HighsDataStack.h index e459267a5a2..7fc1d0fee0a 100644 --- a/highs/util/HighsDataStack.h +++ b/highs/util/HighsDataStack.h @@ -16,7 +16,7 @@ #include #include -#include "util/HighsInt.h" +#include "util/HighsType.h" #if __GNUG__ && __GNUC__ < 5 && !defined(__clang__) #define IS_TRIVIALLY_COPYABLE(T) __has_trivial_copy(T) diff --git a/highs/util/HighsDisjointSets.h b/highs/util/HighsDisjointSets.h index d7f216d4ae3..ef8a6090645 100644 --- a/highs/util/HighsDisjointSets.h +++ b/highs/util/HighsDisjointSets.h @@ -22,7 +22,7 @@ #include #include -#include "util/HighsInt.h" +#include "util/HighsType.h" template class HighsDisjointSets { diff --git a/highs/util/HighsHash.h b/highs/util/HighsHash.h index f74034d823e..c387c31f7c2 100644 --- a/highs/util/HighsHash.h +++ b/highs/util/HighsHash.h @@ -21,7 +21,7 @@ #include #include -#include "util/HighsInt.h" +#include "util/HighsType.h" #ifdef HIGHS_HAVE_BITSCAN_REVERSE #include diff --git a/highs/util/HighsIntegers.h b/highs/util/HighsIntegers.h index 1b5f613a029..05bcd2271e1 100644 --- a/highs/util/HighsIntegers.h +++ b/highs/util/HighsIntegers.h @@ -16,7 +16,7 @@ #include #include "util/HighsCDouble.h" -#include "util/HighsInt.h" +#include "util/HighsType.h" class HighsIntegers { public: diff --git a/highs/util/HighsMatrixSlice.h b/highs/util/HighsMatrixSlice.h index 67d5e912219..c58c4442e65 100644 --- a/highs/util/HighsMatrixSlice.h +++ b/highs/util/HighsMatrixSlice.h @@ -17,7 +17,7 @@ #include #include -#include "util/HighsInt.h" +#include "util/HighsType.h" template class HighsMatrixSlice; diff --git a/highs/util/HighsMemoryAllocation.h b/highs/util/HighsMemoryAllocation.h index 3f372b727f0..f695a37fd88 100644 --- a/highs/util/HighsMemoryAllocation.h +++ b/highs/util/HighsMemoryAllocation.h @@ -14,7 +14,7 @@ #include -#include "util/HighsInt.h" +#include "util/HighsType.h" template bool okResize(std::vector& use_vector, HighsInt dimension, T value = T{}) { diff --git a/highs/util/HighsRbTree.h b/highs/util/HighsRbTree.h index bc7427ec936..720b4f1aabf 100644 --- a/highs/util/HighsRbTree.h +++ b/highs/util/HighsRbTree.h @@ -12,7 +12,7 @@ #include #include -#include "util/HighsInt.h" +#include "util/HighsType.h" namespace highs { diff --git a/highs/util/HighsSparseVectorSum.h b/highs/util/HighsSparseVectorSum.h index 61f527932a6..7db0263c94d 100644 --- a/highs/util/HighsSparseVectorSum.h +++ b/highs/util/HighsSparseVectorSum.h @@ -14,7 +14,7 @@ #include #include "util/HighsCDouble.h" -#include "util/HighsInt.h" +#include "util/HighsType.h" class HighsSparseVectorSum { public: diff --git a/highs/util/HighsSplay.h b/highs/util/HighsSplay.h index 18e44e2c920..61ddf73a84b 100644 --- a/highs/util/HighsSplay.h +++ b/highs/util/HighsSplay.h @@ -10,7 +10,7 @@ #include -#include "util/HighsInt.h" +#include "util/HighsType.h" /// top down splay operation to maintain a binary search tree. The search tree /// is assumed to be stored in an array/vector and therefore uses integers diff --git a/highs/util/HighsTimer.h b/highs/util/HighsTimer.h index 85bb50b7181..33a18b564f7 100644 --- a/highs/util/HighsTimer.h +++ b/highs/util/HighsTimer.h @@ -19,7 +19,7 @@ #include #include -#include "util/HighsInt.h" +#include "util/HighsType.h" const HighsInt check_clock = -46; const HighsInt simplex_no_basis_clock = 8; diff --git a/highs/util/HighsInt.h b/highs/util/HighsType.h similarity index 88% rename from highs/util/HighsInt.h rename to highs/util/HighsType.h index fbdec1e9149..3d98757a104 100644 --- a/highs/util/HighsInt.h +++ b/highs/util/HighsType.h @@ -5,12 +5,12 @@ /* Available as open-source under the MIT License */ /* */ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ -/**@file HighsInt.h - * @brief The definition for the integer type to use +/**@file HighsType.h + * @brief The definition for basic types to use */ -#ifndef UTIL_HIGHS_INT_H_ -#define UTIL_HIGHS_INT_H_ +#ifndef UTIL_HIGHS_TYPE_H_ +#define UTIL_HIGHS_TYPE_H_ #include From c84d81232d3597e0692d4267387dc7856e5a72de Mon Sep 17 00:00:00 2001 From: fwesselm Date: Wed, 5 Aug 2026 15:26:27 +0200 Subject: [PATCH 07/11] Revert move --- cmake/sources.cmake | 1 + highs/util/HighsInt.h | 36 ++++++++++++++++++++++++++++++++++++ highs/util/HighsType.h | 21 +-------------------- 3 files changed, 38 insertions(+), 20 deletions(-) create mode 100644 highs/util/HighsInt.h diff --git a/cmake/sources.cmake b/cmake/sources.cmake index a0406ac5465..6c370ee9290 100644 --- a/cmake/sources.cmake +++ b/cmake/sources.cmake @@ -617,6 +617,7 @@ set(highs_headers util/HighsDynamicLibrary.h util/HighsHash.h util/HighsHashTree.h + util/HighsInt.h util/HighsType.h util/HighsIntegers.h util/HighsLinearSumBounds.h diff --git a/highs/util/HighsInt.h b/highs/util/HighsInt.h new file mode 100644 index 00000000000..95a610f55bb --- /dev/null +++ b/highs/util/HighsInt.h @@ -0,0 +1,36 @@ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* */ +/* This file is part of the HiGHS linear optimization suite */ +/* */ +/* Available as open-source under the MIT License */ +/* */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/**@file HighsInt.h + * @brief The definition for the integer type to use + */ + +#ifndef UTIL_HIGHS_INT_H_ +#define UTIL_HIGHS_INT_H_ + +#include + +#ifdef __cplusplus +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS +#endif +#endif +#include + +#include "HConfig.h" + +#ifdef HIGHSINT64 +typedef int64_t HighsInt; +typedef uint64_t HighsUInt; +#define HIGHSINT_FORMAT PRId64 +#else +typedef int HighsInt; +typedef unsigned int HighsUInt; +#define HIGHSINT_FORMAT "d" +#endif + +#endif diff --git a/highs/util/HighsType.h b/highs/util/HighsType.h index 3d98757a104..80297027de3 100644 --- a/highs/util/HighsType.h +++ b/highs/util/HighsType.h @@ -12,26 +12,7 @@ #ifndef UTIL_HIGHS_TYPE_H_ #define UTIL_HIGHS_TYPE_H_ -#include - -#ifdef __cplusplus -#ifndef __STDC_FORMAT_MACROS -#define __STDC_FORMAT_MACROS -#endif -#endif -#include - -#include "HConfig.h" - -#ifdef HIGHSINT64 -typedef int64_t HighsInt; -typedef uint64_t HighsUInt; -#define HIGHSINT_FORMAT PRId64 -#else -typedef int HighsInt; -typedef unsigned int HighsUInt; -#define HIGHSINT_FORMAT "d" -#endif +#include "util/HighsInt.h" typedef uint8_t HighsBool; From ae0558694cddbaeb916681c541e6d64b87797485 Mon Sep 17 00:00:00 2001 From: JAJHall Date: Wed, 5 Aug 2026 15:07:56 +0100 Subject: [PATCH 08/11] Added comment to util/HighsType.h about the motivation for HighsBool, and changed std::vector failure(k, 0); to std::vector failure(k, false); in FactorHighsSolver.cpp --- highs/ipm/hipo/ipm/FactorHighsSolver.cpp | 5 ++--- highs/util/HighsType.h | 2 ++ 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/highs/ipm/hipo/ipm/FactorHighsSolver.cpp b/highs/ipm/hipo/ipm/FactorHighsSolver.cpp index a7805bf6ee6..6f897d90246 100644 --- a/highs/ipm/hipo/ipm/FactorHighsSolver.cpp +++ b/highs/ipm/hipo/ipm/FactorHighsSolver.cpp @@ -369,8 +369,7 @@ Int FactorHighsSolver::chooseOrdering(const std::vector& rows, const Int k = orderings_to_try.size(); - // vector is not thread-safe - std::vector failure(k, 0); + std::vector failure(k, false); if (nla == "NE") { if (ptr.back() >= kkt_.NE_nz_limit.load(std::memory_order_relaxed)) { @@ -647,4 +646,4 @@ void FactorHighsSolver::getReg(std::vector& reg) { FH_.getRegularisation(reg.data()); } -} // namespace hipo \ No newline at end of file +} // namespace hipo diff --git a/highs/util/HighsType.h b/highs/util/HighsType.h index 80297027de3..574487271d4 100644 --- a/highs/util/HighsType.h +++ b/highs/util/HighsType.h @@ -14,6 +14,8 @@ #include "util/HighsInt.h" +// vector is not thread-safe, so HiGHS uses vector + typedef uint8_t HighsBool; #endif From d3d32a3488bb1487a6b9955caf3617da350d5552 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Wed, 5 Aug 2026 16:40:42 +0200 Subject: [PATCH 09/11] Remove some occurrences of vector --- highs/mip/HighsCutGeneration.cpp | 2 +- highs/mip/HighsCutPool.h | 2 +- highs/mip/HighsDomain.h | 6 +++--- highs/mip/HighsDynamicRowMatrix.h | 4 +--- highs/mip/HighsLpRelaxation.cpp | 2 +- highs/mip/HighsSearch.cpp | 4 ++-- highs/presolve/HighsPostsolveStack.h | 2 +- highs/simplex/HEkkDualRHS.cpp | 18 +++++++++--------- highs/simplex/HEkkDualRHS.h | 4 ++-- highs/util/HFactor.cpp | 10 +++++----- highs/util/HFactor.h | 2 +- 11 files changed, 27 insertions(+), 29 deletions(-) diff --git a/highs/mip/HighsCutGeneration.cpp b/highs/mip/HighsCutGeneration.cpp index 567465e3125..5ae328155e5 100644 --- a/highs/mip/HighsCutGeneration.cpp +++ b/highs/mip/HighsCutGeneration.cpp @@ -1209,7 +1209,7 @@ bool HighsCutGeneration::generateConflict(const HighsDomain& localdomain, lpRelaxation.getMipSolver().mipdata_->debugSolution.checkCut( inds, vals, rowlen, proofrhs); - complementation.assign(rowlen, 0); + complementation.assign(rowlen, false); upper.resize(rowlen); solval.resize(rowlen); diff --git a/highs/mip/HighsCutPool.h b/highs/mip/HighsCutPool.h index 115befdbb8e..e9f988cf305 100644 --- a/highs/mip/HighsCutPool.h +++ b/highs/mip/HighsCutPool.h @@ -159,7 +159,7 @@ class HighsCutPool { void separateLpCutsAfterRestart(HighsCutSet& cutset); - bool cutIsIntegral(HighsInt cut) const { return (rowintegral[cut] != 0); } + bool cutIsIntegral(HighsInt cut) const { return rowintegral[cut]; } HighsInt getNumCuts() const { return matrix_.getNumRows() - matrix_.getNumDelRows(); diff --git a/highs/mip/HighsDomain.h b/highs/mip/HighsDomain.h index 2b1e48c489d..92747afd954 100644 --- a/highs/mip/HighsDomain.h +++ b/highs/mip/HighsDomain.h @@ -162,7 +162,7 @@ class HighsDomain { HighsCutPool* cutpool; std::vector activitycuts_; std::vector activitycutsinf_; - std::vector propagatecutflags_; + std::vector propagatecutflags_; std::vector propagatecutinds_; std::vector capacityThreshold_; @@ -198,7 +198,7 @@ class HighsDomain { HighsConflictPool* conflictpool_; std::vector colLowerWatched_; std::vector colUpperWatched_; - std::vector conflictFlag_; + std::vector conflictFlag_; std::vector propagateConflictInds_; struct WatchedLiteral { @@ -467,7 +467,7 @@ class HighsDomain { changedcols_.resize(start); } - bool isChangedCol(HighsInt col) const { return changedcolsflags_[col] != 0; } + bool isChangedCol(HighsInt col) const { return changedcolsflags_[col]; } void markPropagate(HighsInt row); diff --git a/highs/mip/HighsDynamicRowMatrix.h b/highs/mip/HighsDynamicRowMatrix.h index 47773e1d7ee..510b041edc7 100644 --- a/highs/mip/HighsDynamicRowMatrix.h +++ b/highs/mip/HighsDynamicRowMatrix.h @@ -49,9 +49,7 @@ class HighsDynamicRowMatrix { public: HighsDynamicRowMatrix(HighsInt ncols); - bool columnsLinked(HighsInt rowindex) const { - return (colsLinked[rowindex] != 0); - } + bool columnsLinked(HighsInt rowindex) const { return colsLinked[rowindex]; } void unlinkColumns(HighsInt rowindex); diff --git a/highs/mip/HighsLpRelaxation.cpp b/highs/mip/HighsLpRelaxation.cpp index 843b27849b8..c727e79a741 100644 --- a/highs/mip/HighsLpRelaxation.cpp +++ b/highs/mip/HighsLpRelaxation.cpp @@ -118,7 +118,7 @@ bool HighsLpRelaxation::LpRow::isIntegral( case kCutPool: return mipsolver.mipdata_->cutpools[cutpoolindex].cutIsIntegral(index); case kModel: - return (mipsolver.mipdata_->rowintegral[index] != 0); + return mipsolver.mipdata_->rowintegral[index]; }; assert(false); diff --git a/highs/mip/HighsSearch.cpp b/highs/mip/HighsSearch.cpp index 2472401eba6..bfb41fb2fd9 100644 --- a/highs/mip/HighsSearch.cpp +++ b/highs/mip/HighsSearch.cpp @@ -264,8 +264,8 @@ HighsInt HighsSearch::selectBranchingCandidate(int64_t maxSbIters, upbound.resize(numfrac, getCurrentLowerBound()); downbound.resize(numfrac, getCurrentLowerBound()); - upscorereliable.resize(numfrac, 0); - downscorereliable.resize(numfrac, 0); + upscorereliable.resize(numfrac, false); + downscorereliable.resize(numfrac, false); // initialize up and down scores of variables that have a // reliable pseudocost so that they do not get evaluated diff --git a/highs/presolve/HighsPostsolveStack.h b/highs/presolve/HighsPostsolveStack.h index e207f041b30..ccd96ed9388 100644 --- a/highs/presolve/HighsPostsolveStack.h +++ b/highs/presolve/HighsPostsolveStack.h @@ -575,7 +575,7 @@ class HighsPostsolveStack { bool isColLinearlyTransformable(HighsInt col) const { assert(col >= 0); assert(static_cast(col) < origColIndex.size()); - return (linearlyTransformable[origColIndex[col]] != 0); + return linearlyTransformable[origColIndex[col]]; } template diff --git a/highs/simplex/HEkkDualRHS.cpp b/highs/simplex/HEkkDualRHS.cpp index 622c6458a7c..982b592af19 100644 --- a/highs/simplex/HEkkDualRHS.cpp +++ b/highs/simplex/HEkkDualRHS.cpp @@ -386,10 +386,10 @@ void HEkkDualRHS::updateInfeasList(HVector* column) { // The regular sparse way for (HighsInt i = 0; i < columnCount; i++) { HighsInt iRow = variable_index[i]; - if (workMark[iRow] == 0) { + if (!workMark[iRow]) { if (work_infeasibility[iRow]) { workIndex[workCount++] = iRow; - workMark[iRow] = 1; + workMark[iRow] = true; } } } @@ -397,10 +397,10 @@ void HEkkDualRHS::updateInfeasList(HVector* column) { // The hyper sparse way for (HighsInt i = 0; i < columnCount; i++) { HighsInt iRow = variable_index[i]; - if (workMark[iRow] == 0) { + if (!workMark[iRow]) { if (work_infeasibility[iRow] > edge_weight[iRow] * workCutoff) { workIndex[workCount++] = iRow; - workMark[iRow] = 1; + workMark[iRow] = true; } } } @@ -438,12 +438,12 @@ void HEkkDualRHS::createInfeasList(double columnDensity) { double* dwork = ekk_instance_.scattered_dual_edge_weight_.data(); // 1. Build the full list - fill_n(workMark.data(), numRow, 0); + fill_n(workMark.data(), numRow, false); workCount = 0; workCutoff = 0; for (HighsInt iRow = 0; iRow < numRow; iRow++) { if (work_infeasibility[iRow]) { - workMark[iRow] = 1; + workMark[iRow] = true; workIndex[workCount++] = iRow; } } @@ -465,12 +465,12 @@ void HEkkDualRHS::createInfeasList(double columnDensity) { workCutoff = min(maxMerit * 0.99999, cutMerit * 1.00001); // Create again - fill_n(workMark.data(), numRow, 0); + fill_n(workMark.data(), numRow, false); workCount = 0; for (HighsInt iRow = 0; iRow < numRow; iRow++) { if (work_infeasibility[iRow] >= edge_weight[iRow] * workCutoff) { workIndex[workCount++] = iRow; - workMark[iRow] = 1; + workMark[iRow] = true; } } @@ -484,7 +484,7 @@ void HEkkDualRHS::createInfeasList(double columnDensity) { if (work_infeasibility[iRow] > edge_weight[iRow] * cutMerit) { workIndex[workCount++] = iRow; } else { - workMark[iRow] = 0; + workMark[iRow] = false; } } } diff --git a/highs/simplex/HEkkDualRHS.h b/highs/simplex/HEkkDualRHS.h index 8aadcfa9c76..f6b3f2989da 100644 --- a/highs/simplex/HEkkDualRHS.h +++ b/highs/simplex/HEkkDualRHS.h @@ -116,8 +116,8 @@ class HEkkDualRHS { //!< infeasibilities HighsInt workCount; //!< Number of rows in list with greatest primal //!< infeasibilities - std::vector workMark; //!< Flag set if row is in list of those with - //!< greatest primal infeasibilities + std::vector workMark; //!< Flag set if row is in list of those + //!< with greatest primal infeasibilities std::vector workIndex; //!< List of rows with greatest primal infeasibilities std::vector work_infeasibility; diff --git a/highs/util/HFactor.cpp b/highs/util/HFactor.cpp index 31a16af2540..59045fd5f31 100644 --- a/highs/util/HFactor.cpp +++ b/highs/util/HFactor.cpp @@ -281,7 +281,7 @@ void HFactor::setupGeneral( mr_count_before.resize(num_row); mr_index.resize(basis_matrix_limit_size * kMRExtraEntriesMultiplier); - mwz_column_mark.assign(num_row, 0); + mwz_column_mark.assign(num_row, false); mwz_column_index.resize(num_row); mwz_column_array.assign(num_row, 0); @@ -1117,7 +1117,7 @@ HighsInt HFactor::buildKernel() { const double value = mc_value[k] / pivot_multiplier; mwz_column_index[mwz_column_count++] = iRow; mwz_column_array[iRow] = value; - mwz_column_mark[iRow] = 1; + mwz_column_mark[iRow] = true; l_index.push_back(iRow); l_value.push_back(value); mr_count_before[iRow] = mr_count[iRow]; @@ -1157,7 +1157,7 @@ HighsInt HFactor::buildKernel() { HighsInt iRow = mc_index[my_k]; double value = mc_value[my_k]; if (mwz_column_mark[iRow]) { - mwz_column_mark[iRow] = 0; + mwz_column_mark[iRow] = false; nFillin--; value -= my_pivot * mwz_column_array[iRow]; if (fabs(value) < kHighsTiny) { @@ -1231,7 +1231,7 @@ HighsInt HFactor::buildKernel() { // 2.4.5. Reset pivot column mark for (HighsInt i = 0; i < mwz_column_count; i++) - mwz_column_mark[mwz_column_index[i]] = 1; + mwz_column_mark[mwz_column_index[i]] = true; // 2.4.6. Fix max value and link list colFixMax(iCol); @@ -1243,7 +1243,7 @@ HighsInt HFactor::buildKernel() { // 2.5. Clear pivot column buffer for (HighsInt i = 0; i < mwz_column_count; i++) - mwz_column_mark[mwz_column_index[i]] = 0; + mwz_column_mark[mwz_column_index[i]] = false; // 2.6. Correct row links for the remain active part for (HighsInt i = start_A; i < end_A; i++) { diff --git a/highs/util/HFactor.h b/highs/util/HFactor.h index 8e452846f89..b367dc4bf04 100644 --- a/highs/util/HFactor.h +++ b/highs/util/HFactor.h @@ -408,7 +408,7 @@ class HFactor { // Kernel column buffer vector mwz_column_index; - vector mwz_column_mark; + vector mwz_column_mark; vector mwz_column_array; // Count link list From 7bd94ce15704431c9d725b3f058c5e2545442968 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Wed, 5 Aug 2026 16:44:44 +0200 Subject: [PATCH 10/11] Fix format --- highs/simplex/HEkkDualRHS.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/highs/simplex/HEkkDualRHS.h b/highs/simplex/HEkkDualRHS.h index f6b3f2989da..bd7f8932b2f 100644 --- a/highs/simplex/HEkkDualRHS.h +++ b/highs/simplex/HEkkDualRHS.h @@ -117,7 +117,7 @@ class HEkkDualRHS { HighsInt workCount; //!< Number of rows in list with greatest primal //!< infeasibilities std::vector workMark; //!< Flag set if row is in list of those - //!< with greatest primal infeasibilities + //!< with greatest primal infeasibilities std::vector workIndex; //!< List of rows with greatest primal infeasibilities std::vector work_infeasibility; From 4a5b7797f154e7ac8408347f713591eb41084d14 Mon Sep 17 00:00:00 2001 From: fwesselm Date: Thu, 6 Aug 2026 09:32:31 +0200 Subject: [PATCH 11/11] Replace vector factorColPerm; std::vector factorRowPerm; std::vector colBasisStatus; - std::vector rowUsed; + std::vector rowUsed; // working memory std::vector iterstack; @@ -198,7 +198,7 @@ class HighsGFkSolve { factorColPerm.reserve(maxPivot); factorRowPerm.reserve(maxPivot); colBasisStatus.assign(numCol, 0); - rowUsed.assign(numRow, 0); + rowUsed.assign(numRow, false); HighsInt numPivot = 0; while (!pqueue.empty()) { @@ -285,7 +285,7 @@ class HighsGFkSolve { factorColPerm.push_back(pivotCol); factorRowPerm.push_back(pivotRow); colBasisStatus[pivotCol] = 1; - rowUsed[pivotRow] = 1; + rowUsed[pivotRow] = true; if (numPivot == maxPivot) break; for (HighsInt i = 0; i != pivotRowLen; ++i) { @@ -321,7 +321,7 @@ class HighsGFkSolve { hasSolution[rhsIndex] = true; for (HighsInt i = 0; i != numRow; ++i) { // if the row was used it is linearly independent - if (rowUsed[i] == 1) continue; + if (rowUsed[i]) continue; // if the row is linearly dependent, the right hand side must be zero, // otherwise no solution exists diff --git a/highs/simplex/HSimplexNlaProductForm.cpp b/highs/simplex/HSimplexNlaProductForm.cpp index ea2a4d04d2a..f282c92f55a 100644 --- a/highs/simplex/HSimplexNlaProductForm.cpp +++ b/highs/simplex/HSimplexNlaProductForm.cpp @@ -87,8 +87,8 @@ void ProductFormUpdate::ftran(HVector& rhs) const { // list. If RHS fill-in occurs in a row, then we have to add it to // the list. We're not tracking cancellation, so we don't need to // know where a row appears in the list - vector& in_index = rhs.cwork; - for (HighsInt iX = 0; iX < rhs.count; iX++) in_index[rhs.index[iX]] = 1; + vector& in_index = rhs.cwork; + for (HighsInt iX = 0; iX < rhs.count; iX++) in_index[rhs.index[iX]] = true; for (HighsInt iX = 0; iX < update_count_; iX++) { const HighsInt pivot_index = pivot_index_[iX]; @@ -101,13 +101,13 @@ void ProductFormUpdate::ftran(HVector& rhs) const { HighsInt iRow = index_[iEl]; rhs.array[iRow] -= pivot_value * value_[iEl]; if (in_index[iRow]) continue; - in_index[iRow] = 1; + in_index[iRow] = true; rhs.index[rhs.count++] = iRow; } } else { rhs.array[pivot_index] = 0; } } - // Zero the in_index entries used to point into the index list - for (HighsInt iX = 0; iX < rhs.count; iX++) in_index[rhs.index[iX]] = 0; + // Reset the in_index entries used to point into the index list + for (HighsInt iX = 0; iX < rhs.count; iX++) in_index[rhs.index[iX]] = false; } diff --git a/highs/util/HFactor.cpp b/highs/util/HFactor.cpp index 59045fd5f31..0abe78b4ca1 100644 --- a/highs/util/HFactor.cpp +++ b/highs/util/HFactor.cpp @@ -70,7 +70,7 @@ static void solveHyper(const HighsInt h_size, const HighsInt* h_lookup, // Take count // Build list - char* list_mark = rhs->cwork.data(); + HighsBool* list_mark = rhs->cwork.data(); HighsInt* list_index = rhs->iwork.data(); HighsInt* list_stack = &rhs->iwork[h_size]; HighsInt list_count = 0; @@ -89,13 +89,13 @@ static void solveHyper(const HighsInt h_size, const HighsInt* h_lookup, HighsInt Hk = h_start[Hi]; // H matrix non zero position HighsInt n_stack = -1; // Usage of the stack (-1 not used) - list_mark[Hi] = 1; // Mark this as touched + list_mark[Hi] = true; // Mark this as touched for (;;) { if (Hk < h_end[Hi]) { HighsInt Hi_sub = h_lookup[h_index[Hk++]]; - if (list_mark[Hi_sub] == 0) { // Go to a child - list_mark[Hi_sub] = 1; // Mark as touched + if (!list_mark[Hi_sub]) { // Go to a child + list_mark[Hi_sub] = true; // Mark as touched list_stack[++n_stack] = Hi; // Store current into stack list_stack[++n_stack] = Hk; Hi = Hi_sub; // Replace current with child @@ -122,7 +122,7 @@ static void solveHyper(const HighsInt h_size, const HighsInt* h_lookup, rhs_count = 0; for (HighsInt iList = list_count - 1; iList >= 0; iList--) { HighsInt i = list_index[iList]; - list_mark[i] = 0; + list_mark[i] = false; HighsInt pivotRow = h_pivot_index[i]; double pivot_multiplier = rhs_array[pivotRow]; if (fabs(pivot_multiplier) > kHighsTiny) { @@ -139,7 +139,7 @@ static void solveHyper(const HighsInt h_size, const HighsInt* h_lookup, rhs_count = 0; for (HighsInt iList = list_count - 1; iList >= 0; iList--) { HighsInt i = list_index[iList]; - list_mark[i] = 0; + list_mark[i] = false; HighsInt pivotRow = h_pivot_index[i]; double pivot_multiplier = rhs_array[pivotRow]; if (fabs(pivot_multiplier) > kHighsTiny) { diff --git a/highs/util/HVectorBase.cpp b/highs/util/HVectorBase.cpp index 332cb8f4769..0fe446f004b 100644 --- a/highs/util/HVectorBase.cpp +++ b/highs/util/HVectorBase.cpp @@ -27,7 +27,7 @@ void HVectorBase::setup(HighsInt size_) { count = 0; index.resize(size); array.assign(size, Real{0}); - cwork.assign(size + 6400, 0); // MAX invert + cwork.assign(size + 6400, false); // MAX invert iwork.assign(size * 4, 0); packCount = 0; diff --git a/highs/util/HVectorBase.h b/highs/util/HVectorBase.h index 8fb01255c27..5cc501924bb 100644 --- a/highs/util/HVectorBase.h +++ b/highs/util/HVectorBase.h @@ -45,7 +45,7 @@ class HVectorBase { double synthetic_tick; //!< Synthetic clock for operations with this vector // For update - vector cwork; //!< char working buffer for UPDATE + vector cwork; //!< Working buffer for UPDATE vector iwork; //!< integer working buffer for UPDATE HVectorBase* next; //!< Allows vectors to be linked for PAMI