public inbox for git-commits@fedoraproject.org
help / color / mirror / Atom feed
* [rpms/coin-or-HiGHS] rawhide: Version 1.15.1
@ 2026-07-14 16:55 Jerry James
0 siblings, 0 replies; only message in thread
From: Jerry James @ 2026-07-14 16:55 UTC (permalink / raw)
To: git-commits
A new commit has been pushed.
Repo : rpms/coin-or-HiGHS
Branch : rawhide
Commit : b9404b79ed484a64cfc07725dd431322453ef5d3
Author : Jerry James <loganjerry@gmail.com>
Date : 2026-07-14T10:55:31-06:00
Stats : +153/-1075 in 4 file(s)
URL : https://src.fedoraproject.org/rpms/coin-or-HiGHS/c/b9404b79ed484a64cfc07725dd431322453ef5d3?branch=rawhide
Log:
Version 1.15.1
- Bundle AMD and metis until they are updated in Rawhide
- Remove unused BuildRequires
---
diff --git a/coin-or-HiGHS-issue-2957.patch b/coin-or-HiGHS-issue-2957.patch
deleted file mode 100644
index c9616d3..0000000
--- a/coin-or-HiGHS-issue-2957.patch
+++ /dev/null
@@ -1,763 +0,0 @@
-From 0199f95a453eadba6aab5161bb4bb078b33cdfb9 Mon Sep 17 00:00:00 2001
-From: fwesselm <fwesselm@mathworks.com>
-Date: Wed, 8 Apr 2026 11:24:45 +0200
-Subject: [PATCH 1/9] WIP
-
----
- highs/presolve/HPresolve.cpp | 46 ++++++++++++++++++------------------
- 1 file changed, 23 insertions(+), 23 deletions(-)
-
-diff --git a/highs/presolve/HPresolve.cpp b/highs/presolve/HPresolve.cpp
-index 8f55b22be3..dad787aeb5 100644
---- a/highs/presolve/HPresolve.cpp
-+++ b/highs/presolve/HPresolve.cpp
-@@ -4982,7 +4982,11 @@ HPresolve::Result HPresolve::singletonColStuffing(
- // count number of fixed columns
- HighsInt numFixedCols = 0;
-
-- typedef std::tuple<HighsInt, double, HighsInt> candidate;
-+ struct candidate {
-+ HighsInt col;
-+ double val;
-+ HighsInt multiplier;
-+ };
-
- auto isSingleton = [&](HighsInt col) {
- return (!colDeleted[col] && colsize[col] == 1 &&
-@@ -4991,9 +4995,9 @@ HPresolve::Result HPresolve::singletonColStuffing(
-
- auto sortCols = [&](std::vector<candidate>& vec) {
- boost::sort::pdqsort(vec.begin(), vec.end(),
-- [&](const candidate& col1, const candidate& col2) {
-- return model->col_cost_[std::get<0>(col1)] / std::get<1>(col1) <
-- model->col_cost_[std::get<0>(col2)] / std::get<1>(col2);
-+ [&](const candidate& c1, const candidate& c2) {
-+ return model->col_cost_[c1.col] / c1.val <
-+ model->col_cost_[c2.col] / c2.val;
- });
- };
-
-@@ -5018,7 +5022,7 @@ HPresolve::Result HPresolve::singletonColStuffing(
- allInteger && model->integrality_[col] == HighsVarType::kInteger;
- minWeight = std::min(minWeight, direction * val);
- maxWeight = std::max(maxWeight, direction * val);
-- candidates.push_back(std::make_tuple(col, val, direction));
-+ candidates.push_back(candidate{col, val, direction});
- };
-
- // lambda for fixing a variable
-@@ -5083,40 +5087,36 @@ HPresolve::Result HPresolve::singletonColStuffing(
-
- // remove integer columns if there are also continuous ones
- if (!allInteger)
-- candidates.erase(
-- std::remove_if(candidates.begin(), candidates.end(),
-- [&](const candidate& p) {
-- return model->integrality_[std::get<0>(p)] ==
-- HighsVarType::kInteger;
-- }),
-- candidates.end());
-+ candidates.erase(std::remove_if(candidates.begin(), candidates.end(),
-+ [&](const candidate& p) {
-+ return model->integrality_[p.col] ==
-+ HighsVarType::kInteger;
-+ }),
-+ candidates.end());
-
- // sort candidates
- sortCols(candidates);
-
- // check candidates
- for (const auto& t : candidates) {
-- // get variable index, coefficient and multiplier (-1 if sign was flipped)
-- HighsInt j = std::get<0>(t);
-- double aj = std::get<1>(t);
-- HighsInt multiplier = std::get<2>(t);
- // both bounds have to be finite
-- if (model->col_lower_[j] == -kHighsInf ||
-- model->col_upper_[j] == kHighsInf)
-+ if (model->col_lower_[t.col] == -kHighsInf ||
-+ model->col_upper_[t.col] == kHighsInf)
- break;
- // compute delta (bound difference)
-- HighsCDouble delta = multiplier * aj *
-- (static_cast<HighsCDouble>(model->col_upper_[j]) -
-- static_cast<HighsCDouble>(model->col_lower_[j]));
-+ HighsCDouble delta =
-+ t.multiplier * t.val *
-+ (static_cast<HighsCDouble>(model->col_upper_[t.col]) -
-+ static_cast<HighsCDouble>(model->col_lower_[t.col]));
- // check if variable can be fixed
- if (sumUpperFinite &&
- delta <= direction * rhs - sumUpper + primal_feastol) {
- numFixedCols++;
-- HPRESOLVE_CHECKED_CALL(fixCol(j, multiplier));
-+ HPRESOLVE_CHECKED_CALL(fixCol(t.col, t.multiplier));
- } else if (sumLowerFinite &&
- direction * rhs <= sumLower + primal_feastol) {
- numFixedCols++;
-- HPRESOLVE_CHECKED_CALL(fixCol(j, -multiplier));
-+ HPRESOLVE_CHECKED_CALL(fixCol(t.col, -t.multiplier));
- }
- // update row activities
- if (sumLowerFinite) sumLower += delta;
-
-From 198a8c8dba4389ebca73dbaed04a70b33457a243 Mon Sep 17 00:00:00 2001
-From: fwesselm <fwesselm@mathworks.com>
-Date: Thu, 9 Apr 2026 08:40:47 +0200
-Subject: [PATCH 2/9] Fix candidate computation
-
----
- highs/presolve/HPresolve.cpp | 146 ++++++++++++++++++++++-------------
- 1 file changed, 93 insertions(+), 53 deletions(-)
-
-diff --git a/highs/presolve/HPresolve.cpp b/highs/presolve/HPresolve.cpp
-index dad787aeb5..faa5295574 100644
---- a/highs/presolve/HPresolve.cpp
-+++ b/highs/presolve/HPresolve.cpp
-@@ -5017,7 +5017,10 @@ HPresolve::Result HPresolve::singletonColStuffing(
- // lambda for storing a candidate
- auto addCandidate = [&](std::vector<candidate>& candidates, HighsInt col,
- double val, HighsInt direction, double& minWeight,
-- double& maxWeight, bool& allInteger) {
-+ double& maxWeight, bool& hasInteger,
-+ bool& allInteger) {
-+ hasInteger =
-+ hasInteger || model->integrality_[col] == HighsVarType::kInteger;
- allInteger =
- allInteger && model->integrality_[col] == HighsVarType::kInteger;
- minWeight = std::min(minWeight, direction * val);
-@@ -5034,6 +5037,68 @@ HPresolve::Result HPresolve::singletonColStuffing(
- return Result::kOk;
- };
-
-+ // lambda for computing candidates for stuffing
-+ auto computeCandidates =
-+ [&](HighsInt row, HighsInt direction, std::vector<candidate>& candidates,
-+ HighsCDouble& sumLower, HighsCDouble& sumUpper, bool& sumLowerFinite,
-+ bool& sumUpperFinite, bool& hasInteger, bool& allInteger,
-+ double& minWeight, double& maxWeight, bool allowIntegerCandidates) {
-+ // vectors for candidates and activity bounds
-+ candidates.clear();
-+ candidates.reserve(rowsize[row]);
-+ sumLower = 0.0;
-+ sumUpper = 0.0;
-+ sumLowerFinite = true;
-+ sumUpperFinite = true;
-+ hasInteger = false;
-+ allInteger = true;
-+ minWeight = kHighsInf;
-+ maxWeight = -kHighsInf;
-+
-+ for (auto& nz : getRowVector(row)) {
-+ // get column index, coefficient, cost and bounds
-+ HighsInt j = nz.index();
-+ double aj = direction * nz.value();
-+ double cj = model->col_cost_[j];
-+ double sumLowerBound = model->col_lower_[j];
-+ double sumUpperBound = model->col_upper_[j];
-+ bool isCandidate = allowIntegerCandidates ||
-+ model->integrality_[j] != HighsVarType::kInteger;
-+
-+ if (isSingleton(j)) {
-+ // check singleton
-+ if (aj > 0) {
-+ if (cj >= 0)
-+ // dual fixing: fix to lower bound
-+ sumUpperBound = sumLowerBound;
-+ else if (isCandidate) {
-+ // candidate for stuffing
-+ sumUpperBound = sumLowerBound;
-+ addCandidate(candidates, j, aj, HighsInt{1}, minWeight,
-+ maxWeight, hasInteger, allInteger);
-+ }
-+ } else {
-+ if (cj <= 0)
-+ // dual fixing: fix to upper bound
-+ sumLowerBound = sumUpperBound;
-+ else if (isCandidate) {
-+ // candidate for stuffing; multiply column with -1
-+ sumLowerBound = sumUpperBound;
-+ addCandidate(candidates, j, aj, HighsInt{-1}, minWeight,
-+ maxWeight, hasInteger, allInteger);
-+ }
-+ }
-+ }
-+ // update activities
-+ if (aj < 0) std::swap(sumLowerBound, sumUpperBound);
-+ updateActivityBounds(sumLower, sumUpper, sumLowerFinite,
-+ sumUpperFinite, aj, sumLowerBound,
-+ sumUpperBound);
-+ if (!sumLowerFinite && !sumUpperFinite) return false;
-+ }
-+ return true;
-+ };
-+
- // lambda for actual stuffing
- auto checkRow = [&](HighsInt row, double rhs, HighsInt direction) {
- // skip row if rhs is not finite
-@@ -5041,58 +5106,33 @@ HPresolve::Result HPresolve::singletonColStuffing(
-
- // vectors for candidates and activity bounds
- std::vector<candidate> candidates;
-- candidates.reserve(rowsize[row]);
-- HighsCDouble sumLower = 0.0;
-- HighsCDouble sumUpper = 0.0;
-- bool sumLowerFinite = true;
-- bool sumUpperFinite = true;
-- bool allInteger = true;
-- double minWeight = kHighsInf;
-- double maxWeight = -kHighsInf;
--
-- for (auto& nz : getRowVector(row)) {
-- // get column index, coefficient, cost and bounds
-- HighsInt j = nz.index();
-- double aj = direction * nz.value();
-- double cj = model->col_cost_[j];
-- double sumLowerBound = model->col_lower_[j];
-- double sumUpperBound = model->col_upper_[j];
-- if (isSingleton(j)) {
-- // check singleton
-- if (aj > 0) {
-- // use lower bound
-- sumUpperBound = sumLowerBound;
-- // candidate for stuffing?
-- if (cj < 0)
-- addCandidate(candidates, j, aj, HighsInt{1}, minWeight, maxWeight,
-- allInteger);
-- } else {
-- // use upper bound
-- sumLowerBound = sumUpperBound;
-- // candidate for stuffing? multiply column with -1
-- if (cj > 0)
-- addCandidate(candidates, j, aj, HighsInt{-1}, minWeight, maxWeight,
-- allInteger);
-- }
-- } else if (aj < 0)
-- std::swap(sumLowerBound, sumUpperBound);
-- // update activities
-- updateActivityBounds(sumLower, sumUpper, sumLowerFinite, sumUpperFinite,
-- aj, sumLowerBound, sumUpperBound);
-- if (!sumLowerFinite && !sumUpperFinite) return Result::kOk;
-- }
--
-- // all columns need to have same weights if we only have integer columns
-- if (allInteger && minWeight != maxWeight) return Result::kOk;
--
-- // remove integer columns if there are also continuous ones
-- if (!allInteger)
-- candidates.erase(std::remove_if(candidates.begin(), candidates.end(),
-- [&](const candidate& p) {
-- return model->integrality_[p.col] ==
-- HighsVarType::kInteger;
-- }),
-- candidates.end());
-+ HighsCDouble sumLower;
-+ HighsCDouble sumUpper;
-+ bool sumLowerFinite;
-+ bool sumUpperFinite;
-+ bool hasInteger;
-+ bool allInteger;
-+ double minWeight;
-+ double maxWeight;
-+
-+ // compute candidates
-+ while (true) {
-+ if (computeCandidates(row, direction, candidates, sumLower, sumUpper,
-+ sumLowerFinite, sumUpperFinite, hasInteger,
-+ allInteger, minWeight, maxWeight, true)) {
-+ // all columns need to have same weights if we only have integer columns
-+ if (!hasInteger || (allInteger && minWeight == maxWeight)) break;
-+ }
-+
-+ // recompute candidates without integer columns
-+ if (hasInteger &&
-+ computeCandidates(row, direction, candidates, sumLower, sumUpper,
-+ sumLowerFinite, sumUpperFinite, hasInteger,
-+ allInteger, minWeight, maxWeight, false))
-+ break;
-+
-+ return Result::kOk;
-+ }
-
- // sort candidates
- sortCols(candidates);
-
-From 491392b318e419157dbcff3693bba2dba16bd929 Mon Sep 17 00:00:00 2001
-From: fwesselm <fwesselm@mathworks.com>
-Date: Thu, 9 Apr 2026 08:51:57 +0200
-Subject: [PATCH 3/9] Add test
-
----
- check/TestMipSolver.cpp | 24 ++++++++++++++++++++++++
- 1 file changed, 24 insertions(+)
-
-diff --git a/check/TestMipSolver.cpp b/check/TestMipSolver.cpp
-index cf0b248c68..9d7df7fad6 100644
---- a/check/TestMipSolver.cpp
-+++ b/check/TestMipSolver.cpp
-@@ -1404,3 +1404,27 @@ TEST_CASE("issue-2173", "[highs_test_mip_solver]") {
- const double optimal_objective = -26770.8075489;
- solve(highs, kHighsOnString, require_model_status, optimal_objective);
- }
-+
-+TEST_CASE("issue-2957", "[highs_test_mip_solver]") {
-+ HighsLp lp;
-+ lp.num_col_ = 2;
-+ lp.num_row_ = 1;
-+ lp.col_cost_ = {1, 2};
-+ lp.col_lower_ = {0, 8};
-+ lp.col_upper_ = {20, 20};
-+ lp.integrality_ = {HighsVarType::kInteger, HighsVarType::kContinuous};
-+ lp.row_lower_ = {20.1};
-+ lp.row_upper_ = {kHighsInf};
-+ lp.a_matrix_.start_ = {0, 1, 2};
-+ lp.a_matrix_.index_ = {0, 1};
-+ lp.a_matrix_.value_ = {1, 1};
-+ Highs highs;
-+ highs.passModel(lp);
-+ highs.setOptionValue("output_flag", dev_run);
-+ highs.setOptionValue("mip_rel_gap", 0);
-+ highs.setOptionValue("mip_abs_gap", 0);
-+ highs.readModel(filename);
-+ const HighsModelStatus require_model_status = HighsModelStatus::kOptimal;
-+ const double optimal_objective = 28.2;
-+ solve(highs, kHighsOnString, require_model_status, optimal_objective);
-+}
-
-From c08e4e1087276161c031b1cdbfa40881521d649e Mon Sep 17 00:00:00 2001
-From: fwesselm <fwesselm@mathworks.com>
-Date: Thu, 9 Apr 2026 08:53:07 +0200
-Subject: [PATCH 4/9] Fix test
-
----
- check/TestMipSolver.cpp | 3 +--
- 1 file changed, 1 insertion(+), 2 deletions(-)
-
-diff --git a/check/TestMipSolver.cpp b/check/TestMipSolver.cpp
-index 9d7df7fad6..fbd52bdb5d 100644
---- a/check/TestMipSolver.cpp
-+++ b/check/TestMipSolver.cpp
-@@ -1419,11 +1419,10 @@ TEST_CASE("issue-2957", "[highs_test_mip_solver]") {
- lp.a_matrix_.index_ = {0, 1};
- lp.a_matrix_.value_ = {1, 1};
- Highs highs;
-- highs.passModel(lp);
- highs.setOptionValue("output_flag", dev_run);
- highs.setOptionValue("mip_rel_gap", 0);
- highs.setOptionValue("mip_abs_gap", 0);
-- highs.readModel(filename);
-+ highs.passModel(lp);
- const HighsModelStatus require_model_status = HighsModelStatus::kOptimal;
- const double optimal_objective = 28.2;
- solve(highs, kHighsOnString, require_model_status, optimal_objective);
-
-From 5891232dbf35609784162199f5b44718e605b218 Mon Sep 17 00:00:00 2001
-From: fwesselm <fwesselm@mathworks.com>
-Date: Thu, 9 Apr 2026 09:20:07 +0200
-Subject: [PATCH 5/9] Fix indexing
-
----
- check/TestMipSolver.cpp | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/check/TestMipSolver.cpp b/check/TestMipSolver.cpp
-index fbd52bdb5d..ea971f8a94 100644
---- a/check/TestMipSolver.cpp
-+++ b/check/TestMipSolver.cpp
-@@ -1416,7 +1416,7 @@ TEST_CASE("issue-2957", "[highs_test_mip_solver]") {
- lp.row_lower_ = {20.1};
- lp.row_upper_ = {kHighsInf};
- lp.a_matrix_.start_ = {0, 1, 2};
-- lp.a_matrix_.index_ = {0, 1};
-+ lp.a_matrix_.index_ = {0, 0};
- lp.a_matrix_.value_ = {1, 1};
- Highs highs;
- highs.setOptionValue("output_flag", dev_run);
-
-From eabdcc9f9f1a8a2b8e8b153242d1203e15ef4f11 Mon Sep 17 00:00:00 2001
-From: fwesselm <fwesselm@mathworks.com>
-Date: Thu, 9 Apr 2026 11:17:43 +0200
-Subject: [PATCH 6/9] Clean up
-
----
- highs/presolve/HPresolve.cpp | 46 +++++++++++++++++++++++-------------
- 1 file changed, 30 insertions(+), 16 deletions(-)
-
-diff --git a/highs/presolve/HPresolve.cpp b/highs/presolve/HPresolve.cpp
-index faa5295574..7a217e57d0 100644
---- a/highs/presolve/HPresolve.cpp
-+++ b/highs/presolve/HPresolve.cpp
-@@ -5099,6 +5099,33 @@ HPresolve::Result HPresolve::singletonColStuffing(
- return true;
- };
-
-+ // lambda for computing candidates for stuffing
-+ auto checkCandidates =
-+ [&](HighsInt row, HighsInt direction, std::vector<candidate>& candidates,
-+ HighsCDouble& sumLower, HighsCDouble& sumUpper, bool& sumLowerFinite,
-+ bool& sumUpperFinite, bool& hasInteger, bool& allInteger,
-+ double& minWeight, double& maxWeight) {
-+ // compute candidates
-+ if (computeCandidates(row, direction, candidates, sumLower, sumUpper,
-+ sumLowerFinite, sumUpperFinite, hasInteger,
-+ allInteger, minWeight, maxWeight, true)) {
-+ // all columns need to have same weights if we only have integer
-+ // columns
-+ if (!hasInteger || (allInteger && minWeight == maxWeight))
-+ return true;
-+ } else
-+ allInteger = false;
-+
-+ // recompute candidates without integer columns
-+ if (hasInteger && !allInteger &&
-+ computeCandidates(row, direction, candidates, sumLower, sumUpper,
-+ sumLowerFinite, sumUpperFinite, hasInteger,
-+ allInteger, minWeight, maxWeight, false))
-+ return true;
-+
-+ return false;
-+ };
-+
- // lambda for actual stuffing
- auto checkRow = [&](HighsInt row, double rhs, HighsInt direction) {
- // skip row if rhs is not finite
-@@ -5116,23 +5143,10 @@ HPresolve::Result HPresolve::singletonColStuffing(
- double maxWeight;
-
- // compute candidates
-- while (true) {
-- if (computeCandidates(row, direction, candidates, sumLower, sumUpper,
-- sumLowerFinite, sumUpperFinite, hasInteger,
-- allInteger, minWeight, maxWeight, true)) {
-- // all columns need to have same weights if we only have integer columns
-- if (!hasInteger || (allInteger && minWeight == maxWeight)) break;
-- }
--
-- // recompute candidates without integer columns
-- if (hasInteger &&
-- computeCandidates(row, direction, candidates, sumLower, sumUpper,
-- sumLowerFinite, sumUpperFinite, hasInteger,
-- allInteger, minWeight, maxWeight, false))
-- break;
--
-+ if (!checkCandidates(row, direction, candidates, sumLower, sumUpper,
-+ sumLowerFinite, sumUpperFinite, hasInteger, allInteger,
-+ minWeight, maxWeight))
- return Result::kOk;
-- }
-
- // sort candidates
- sortCols(candidates);
-
-From 65c83af54537bbda07f459110f47a9e5804a9002 Mon Sep 17 00:00:00 2001
-From: fwesselm <fwesselm@mathworks.com>
-Date: Thu, 9 Apr 2026 14:20:00 +0200
-Subject: [PATCH 7/9] Simplify
-
----
- highs/presolve/HPresolve.cpp | 63 +++++++++++++++++++-----------------
- 1 file changed, 33 insertions(+), 30 deletions(-)
-
-diff --git a/highs/presolve/HPresolve.cpp b/highs/presolve/HPresolve.cpp
-index 7a217e57d0..e7105f2823 100644
---- a/highs/presolve/HPresolve.cpp
-+++ b/highs/presolve/HPresolve.cpp
-@@ -5099,32 +5099,40 @@ HPresolve::Result HPresolve::singletonColStuffing(
- return true;
- };
-
-- // lambda for computing candidates for stuffing
-- auto checkCandidates =
-- [&](HighsInt row, HighsInt direction, std::vector<candidate>& candidates,
-- HighsCDouble& sumLower, HighsCDouble& sumUpper, bool& sumLowerFinite,
-- bool& sumUpperFinite, bool& hasInteger, bool& allInteger,
-- double& minWeight, double& maxWeight) {
-- // compute candidates
-- if (computeCandidates(row, direction, candidates, sumLower, sumUpper,
-- sumLowerFinite, sumUpperFinite, hasInteger,
-- allInteger, minWeight, maxWeight, true)) {
-- // all columns need to have same weights if we only have integer
-- // columns
-- if (!hasInteger || (allInteger && minWeight == maxWeight))
-- return true;
-- } else
-- allInteger = false;
-+ // lambda for computing and checking candidates for stuffing
-+ auto checkCandidates = [&](HighsInt row, HighsInt direction,
-+ std::vector<candidate>& candidates,
-+ HighsCDouble& sumLower, HighsCDouble& sumUpper,
-+ bool& sumLowerFinite, bool& sumUpperFinite) {
-+ // indicators for integer candidates and weights
-+ bool hasInteger;
-+ bool allInteger;
-+ double minWeight;
-+ double maxWeight;
-
-- // recompute candidates without integer columns
-- if (hasInteger && !allInteger &&
-- computeCandidates(row, direction, candidates, sumLower, sumUpper,
-- sumLowerFinite, sumUpperFinite, hasInteger,
-- allInteger, minWeight, maxWeight, false))
-- return true;
-+ // compute candidates
-+ if (computeCandidates(row, direction, candidates, sumLower, sumUpper,
-+ sumLowerFinite, sumUpperFinite, hasInteger,
-+ allInteger, minWeight, maxWeight, true)) {
-+ // return if there are no integer columns
-+ if (!hasInteger) return true;
-+ // all columns need to have same weights if we only have integer
-+ // columns
-+ if (allInteger) {
-+ if (minWeight != maxWeight) return false;
-+ return true;
-+ }
-+ }
-
-- return false;
-- };
-+ // recompute candidates without integer columns
-+ if (hasInteger &&
-+ computeCandidates(row, direction, candidates, sumLower, sumUpper,
-+ sumLowerFinite, sumUpperFinite, hasInteger,
-+ allInteger, minWeight, maxWeight, false))
-+ return true;
-+
-+ return false;
-+ };
-
- // lambda for actual stuffing
- auto checkRow = [&](HighsInt row, double rhs, HighsInt direction) {
-@@ -5137,15 +5145,10 @@ HPresolve::Result HPresolve::singletonColStuffing(
- HighsCDouble sumUpper;
- bool sumLowerFinite;
- bool sumUpperFinite;
-- bool hasInteger;
-- bool allInteger;
-- double minWeight;
-- double maxWeight;
-
- // compute candidates
- if (!checkCandidates(row, direction, candidates, sumLower, sumUpper,
-- sumLowerFinite, sumUpperFinite, hasInteger, allInteger,
-- minWeight, maxWeight))
-+ sumLowerFinite, sumUpperFinite))
- return Result::kOk;
-
- // sort candidates
-
-From 373bfc770707ccee76bd6e969644e9bde40d7b9f Mon Sep 17 00:00:00 2001
-From: fwesselm <fwesselm@mathworks.com>
-Date: Thu, 9 Apr 2026 14:34:13 +0200
-Subject: [PATCH 8/9] Use counter instead of boolean indicators
-
----
- highs/presolve/HPresolve.cpp | 141 +++++++++++++++++------------------
- 1 file changed, 68 insertions(+), 73 deletions(-)
-
-diff --git a/highs/presolve/HPresolve.cpp b/highs/presolve/HPresolve.cpp
-index e7105f2823..3e3ed588e9 100644
---- a/highs/presolve/HPresolve.cpp
-+++ b/highs/presolve/HPresolve.cpp
-@@ -5017,12 +5017,9 @@ HPresolve::Result HPresolve::singletonColStuffing(
- // lambda for storing a candidate
- auto addCandidate = [&](std::vector<candidate>& candidates, HighsInt col,
- double val, HighsInt direction, double& minWeight,
-- double& maxWeight, bool& hasInteger,
-- bool& allInteger) {
-- hasInteger =
-- hasInteger || model->integrality_[col] == HighsVarType::kInteger;
-- allInteger =
-- allInteger && model->integrality_[col] == HighsVarType::kInteger;
-+ double& maxWeight, size_t& numIntegerCandidates) {
-+ if (model->integrality_[col] == HighsVarType::kInteger)
-+ numIntegerCandidates++;
- minWeight = std::min(minWeight, direction * val);
- maxWeight = std::max(maxWeight, direction * val);
- candidates.push_back(candidate{col, val, direction});
-@@ -5038,66 +5035,65 @@ HPresolve::Result HPresolve::singletonColStuffing(
- };
-
- // lambda for computing candidates for stuffing
-- auto computeCandidates =
-- [&](HighsInt row, HighsInt direction, std::vector<candidate>& candidates,
-- HighsCDouble& sumLower, HighsCDouble& sumUpper, bool& sumLowerFinite,
-- bool& sumUpperFinite, bool& hasInteger, bool& allInteger,
-- double& minWeight, double& maxWeight, bool allowIntegerCandidates) {
-- // vectors for candidates and activity bounds
-- candidates.clear();
-- candidates.reserve(rowsize[row]);
-- sumLower = 0.0;
-- sumUpper = 0.0;
-- sumLowerFinite = true;
-- sumUpperFinite = true;
-- hasInteger = false;
-- allInteger = true;
-- minWeight = kHighsInf;
-- maxWeight = -kHighsInf;
--
-- for (auto& nz : getRowVector(row)) {
-- // get column index, coefficient, cost and bounds
-- HighsInt j = nz.index();
-- double aj = direction * nz.value();
-- double cj = model->col_cost_[j];
-- double sumLowerBound = model->col_lower_[j];
-- double sumUpperBound = model->col_upper_[j];
-- bool isCandidate = allowIntegerCandidates ||
-- model->integrality_[j] != HighsVarType::kInteger;
--
-- if (isSingleton(j)) {
-- // check singleton
-- if (aj > 0) {
-- if (cj >= 0)
-- // dual fixing: fix to lower bound
-- sumUpperBound = sumLowerBound;
-- else if (isCandidate) {
-- // candidate for stuffing
-- sumUpperBound = sumLowerBound;
-- addCandidate(candidates, j, aj, HighsInt{1}, minWeight,
-- maxWeight, hasInteger, allInteger);
-- }
-- } else {
-- if (cj <= 0)
-- // dual fixing: fix to upper bound
-- sumLowerBound = sumUpperBound;
-- else if (isCandidate) {
-- // candidate for stuffing; multiply column with -1
-- sumLowerBound = sumUpperBound;
-- addCandidate(candidates, j, aj, HighsInt{-1}, minWeight,
-- maxWeight, hasInteger, allInteger);
-- }
-- }
-+ auto computeCandidates = [&](HighsInt row, HighsInt direction,
-+ std::vector<candidate>& candidates,
-+ HighsCDouble& sumLower, HighsCDouble& sumUpper,
-+ bool& sumLowerFinite, bool& sumUpperFinite,
-+ size_t& numIntegerCandidates, double& minWeight,
-+ double& maxWeight, bool allowIntegerCandidates) {
-+ // vectors for candidates and activity bounds
-+ candidates.clear();
-+ candidates.reserve(rowsize[row]);
-+ sumLower = 0.0;
-+ sumUpper = 0.0;
-+ sumLowerFinite = true;
-+ sumUpperFinite = true;
-+ numIntegerCandidates = 0;
-+ minWeight = kHighsInf;
-+ maxWeight = -kHighsInf;
-+
-+ for (auto& nz : getRowVector(row)) {
-+ // get column index, coefficient, cost and bounds
-+ HighsInt j = nz.index();
-+ double aj = direction * nz.value();
-+ double cj = model->col_cost_[j];
-+ double sumLowerBound = model->col_lower_[j];
-+ double sumUpperBound = model->col_upper_[j];
-+ bool isCandidate = allowIntegerCandidates ||
-+ model->integrality_[j] != HighsVarType::kInteger;
-+
-+ if (isSingleton(j)) {
-+ // check singleton
-+ if (aj > 0) {
-+ if (cj >= 0)
-+ // dual fixing: fix to lower bound
-+ sumUpperBound = sumLowerBound;
-+ else if (isCandidate) {
-+ // candidate for stuffing
-+ sumUpperBound = sumLowerBound;
-+ addCandidate(candidates, j, aj, HighsInt{1}, minWeight, maxWeight,
-+ numIntegerCandidates);
-+ }
-+ } else {
-+ if (cj <= 0)
-+ // dual fixing: fix to upper bound
-+ sumLowerBound = sumUpperBound;
-+ else if (isCandidate) {
-+ // candidate for stuffing; multiply column with -1
-+ sumLowerBound = sumUpperBound;
-+ addCandidate(candidates, j, aj, HighsInt{-1}, minWeight, maxWeight,
-+ numIntegerCandidates);
- }
-- // update activities
-- if (aj < 0) std::swap(sumLowerBound, sumUpperBound);
-- updateActivityBounds(sumLower, sumUpper, sumLowerFinite,
-- sumUpperFinite, aj, sumLowerBound,
-- sumUpperBound);
-- if (!sumLowerFinite && !sumUpperFinite) return false;
- }
-- return true;
-- };
-+ }
-+ // update activities
-+ if (aj < 0) std::swap(sumLowerBound, sumUpperBound);
-+ updateActivityBounds(sumLower, sumUpper, sumLowerFinite, sumUpperFinite,
-+ aj, sumLowerBound, sumUpperBound);
-+ if (!sumLowerFinite && !sumUpperFinite) return false;
-+ }
-+ return true;
-+ };
-
- // lambda for computing and checking candidates for stuffing
- auto checkCandidates = [&](HighsInt row, HighsInt direction,
-@@ -5105,30 +5101,29 @@ HPresolve::Result HPresolve::singletonColStuffing(
- HighsCDouble& sumLower, HighsCDouble& sumUpper,
- bool& sumLowerFinite, bool& sumUpperFinite) {
- // indicators for integer candidates and weights
-- bool hasInteger;
-- bool allInteger;
-+ size_t numIntegerCandidates;
- double minWeight;
- double maxWeight;
-
- // compute candidates
- if (computeCandidates(row, direction, candidates, sumLower, sumUpper,
-- sumLowerFinite, sumUpperFinite, hasInteger,
-- allInteger, minWeight, maxWeight, true)) {
-+ sumLowerFinite, sumUpperFinite, numIntegerCandidates,
-+ minWeight, maxWeight, true)) {
- // return if there are no integer columns
-- if (!hasInteger) return true;
-+ if (numIntegerCandidates == 0) return true;
- // all columns need to have same weights if we only have integer
- // columns
-- if (allInteger) {
-+ if (numIntegerCandidates == candidates.size()) {
- if (minWeight != maxWeight) return false;
- return true;
- }
- }
-
- // recompute candidates without integer columns
-- if (hasInteger &&
-+ if (numIntegerCandidates > 0 &&
- computeCandidates(row, direction, candidates, sumLower, sumUpper,
-- sumLowerFinite, sumUpperFinite, hasInteger,
-- allInteger, minWeight, maxWeight, false))
-+ sumLowerFinite, sumUpperFinite, numIntegerCandidates,
-+ minWeight, maxWeight, false))
- return true;
-
- return false;
-
-From cc1df27728bb6f5a9c516868e46b7f43dcc156af Mon Sep 17 00:00:00 2001
-From: fwesselm <fwesselm@mathworks.com>
-Date: Thu, 9 Apr 2026 14:34:50 +0200
-Subject: [PATCH 9/9] Fix comment
-
----
- highs/presolve/HPresolve.cpp | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/highs/presolve/HPresolve.cpp b/highs/presolve/HPresolve.cpp
-index 3e3ed588e9..1ebf6d9ca5 100644
---- a/highs/presolve/HPresolve.cpp
-+++ b/highs/presolve/HPresolve.cpp
-@@ -5100,7 +5100,7 @@ HPresolve::Result HPresolve::singletonColStuffing(
- std::vector<candidate>& candidates,
- HighsCDouble& sumLower, HighsCDouble& sumUpper,
- bool& sumLowerFinite, bool& sumUpperFinite) {
-- // indicators for integer candidates and weights
-+ // number of integer candidates and weights
- size_t numIntegerCandidates;
- double minWeight;
- double maxWeight;
diff --git a/coin-or-HiGHS-unbundle.patch b/coin-or-HiGHS-unbundle.patch
index 5c21190..10420d8 100644
--- a/coin-or-HiGHS-unbundle.patch
+++ b/coin-or-HiGHS-unbundle.patch
@@ -1,17 +1,28 @@
---- HiGHS-1.14.0/app/HighsRuntimeOptions.h.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/app/HighsRuntimeOptions.h 2026-04-06 13:50:14.751516416 -0600
-@@ -14,7 +14,7 @@
+--- HiGHS-1.15.1/app/HighsAppExternalDeps.h.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/app/HighsAppExternalDeps.h 2026-07-04 12:00:19.480938223 -0600
+@@ -13,7 +13,7 @@
+ #define HIGHS_APP_EXTERNAL_DEPS_H_
+
+ #include "HighsExternalApi.h"
+-#include "cli11/CLI11.hpp"
++#include <CLI/CLI.hpp>
+ namespace HighsExtras {
+ struct app_family {};
+--- HiGHS-1.15.1/app/HighsRuntimeOptions.h.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/app/HighsRuntimeOptions.h 2026-07-04 11:59:29.528548797 -0600
+@@ -15,7 +15,7 @@
#include <cassert>
+ #include <tuple>
--#include "../extern/CLI11.hpp"
+-#include "../extern/cli11/CLI11.hpp"
+#include <CLI/CLI.hpp>
#include "HConfig.h"
+ #include "HighsAppExternalDeps.h"
#include "io/HighsIO.h"
- #include "io/LoadOptions.h"
---- HiGHS-1.14.0/CMakeLists.txt.orig 2026-05-27 16:51:14.869693032 -0600
-+++ HiGHS-1.14.0/CMakeLists.txt 2026-05-27 16:51:32.269938087 -0600
-@@ -547,8 +547,9 @@ if(NOT FAST_BUILD OR CSHARP)
+--- HiGHS-1.15.1/CMakeLists.txt.orig 2026-07-13 09:54:10.447453642 -0600
++++ HiGHS-1.15.1/CMakeLists.txt 2026-07-13 09:54:26.080125164 -0600
+@@ -558,8 +558,9 @@ if(NOT FAST_BUILD OR CSHARP)
endif()
# if zlib is found, then we can enable reading zlib-compressed input
@@ -22,90 +33,10 @@
+ set(ZLIB_FOUND ON)
endif()
- if (PYTHON_BUILD_SETUP OR CMAKE_INSTALL_DOCDIR STREQUAL "" OR NOT BUILD_CXX)
---- HiGHS-1.14.0/cmake/sources.cmake.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/cmake/sources.cmake 2026-04-06 13:50:14.751990479 -0600
-@@ -1,7 +1,5 @@
- set(include_dirs
- $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/extern>
-- $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/extern/pdqsort>
-- $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/extern/zstr>
- $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/highs>
- $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/highs/interfaces>
- $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/highs/io>
-@@ -259,71 +257,9 @@ set(hipo_util_headers
- ipm/hipo/auxiliary/VectorOperations.h)
-
- set(hipo_orderings_sources
-- ../extern/amd/amd_1.c
-- ../extern/amd/amd_2.c
-- ../extern/amd/amd_aat.c
-- ../extern/amd/amd_control.c
-- ../extern/amd/amd_defaults.c
-- ../extern/amd/amd_info.c
-- ../extern/amd/amd_order.c
-- ../extern/amd/amd_post_tree.c
-- ../extern/amd/amd_postorder.c
-- ../extern/amd/amd_preprocess.c
-- ../extern/amd/amd_valid.c
-- ../extern/amd/SuiteSparse_config.c
-- ../extern/metis/GKlib/error.c
-- ../extern/metis/GKlib/mcore.c
-- ../extern/metis/GKlib/memory.c
-- ../extern/metis/GKlib/random.c
-- ../extern/metis/libmetis/auxapi.c
-- ../extern/metis/libmetis/balance.c
-- ../extern/metis/libmetis/bucketsort.c
-- ../extern/metis/libmetis/coarsen.c
-- ../extern/metis/libmetis/compress.c
-- ../extern/metis/libmetis/contig.c
-- ../extern/metis/libmetis/fm.c
-- ../extern/metis/libmetis/gklib.c
-- ../extern/metis/libmetis/graph.c
-- ../extern/metis/libmetis/initpart.c
-- ../extern/metis/libmetis/mcutil.c
-- ../extern/metis/libmetis/mmd.c
-- ../extern/metis/libmetis/ometis.c
-- ../extern/metis/libmetis/options.c
-- ../extern/metis/libmetis/refine.c
-- ../extern/metis/libmetis/separator.c
-- ../extern/metis/libmetis/sfm.c
-- ../extern/metis/libmetis/srefine.c
-- ../extern/metis/libmetis/util.c
-- ../extern/metis/libmetis/wspace.c
- ../extern/rcm/rcm.cpp)
-
- set(hipo_orderings_headers
-- ../extern/amd/amd_internal.h
-- ../extern/amd/amd.h
-- ../extern/amd/SuiteSparse_config.h
-- ../extern/metis/GKlib/gk_arch.h
-- ../extern/metis/GKlib/gk_defs.h
-- ../extern/metis/GKlib/gk_macros.h
-- ../extern/metis/GKlib/gk_mkblas.h
-- ../extern/metis/GKlib/gk_mkmemory.h
-- ../extern/metis/GKlib/gk_mkpqueue.h
-- ../extern/metis/GKlib/gk_mkrandom.h
-- ../extern/metis/GKlib/gk_mksort.h
-- ../extern/metis/GKlib/gk_ms_inttypes.h
-- ../extern/metis/GKlib/gk_ms_stat.h
-- ../extern/metis/GKlib/gk_ms_stdint.h
-- ../extern/metis/GKlib/gk_proto.h
-- ../extern/metis/GKlib/gk_struct.h
-- ../extern/metis/GKlib/gk_types.h
-- ../extern/metis/GKlib/GKlib.h
-- ../extern/metis/libmetis/defs.h
-- ../extern/metis/libmetis/gklib_defs.h
-- ../extern/metis/libmetis/macros.h
-- ../extern/metis/libmetis/metislib.h
-- ../extern/metis/libmetis/proto.h
-- ../extern/metis/libmetis/stdheaders.h
-- ../extern/metis/libmetis/struct.h
-- ../extern/metis/metis.h
- ../extern/rcm/rcm.h)
-
- # redefinition of 'kHighsInf'
-@@ -447,9 +383,6 @@ set(highs_sources
+ if (NOT CMAKE_INSTALL_DOCDIR STREQUAL "" AND BUILD_CXX)
+--- HiGHS-1.15.1/cmake/sources.cmake.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/cmake/sources.cmake 2026-07-13 09:55:16.533539008 -0600
+@@ -463,9 +393,6 @@ set(highs_sources
# add catch header?
set(highs_headers
@@ -115,27 +46,9 @@
interfaces/highs_c_api.h
io/Filereader.h
io/FilereaderLp.h
---- HiGHS-1.14.0/cmake/sources-python.cmake.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/cmake/sources-python.cmake 2026-04-06 13:50:14.752167118 -0600
-@@ -1,7 +1,5 @@
- set(include_dirs_python
- $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/extern>
-- $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/extern/pdqsort>
-- $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/extern/zstr>
- $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/highs>
- $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/highs/interfaces>
- $<BUILD_INTERFACE:${PROJECT_SOURCE_DIR}/highs/io>
-@@ -292,7 +290,6 @@ set(highs_sources_python
- highs/util/stringutil.cpp)
-
- set(highs_headers_python
-- extern/pdqsort/pdqsort.h
- highs/interfaces/highs_c_api.h
- highs/io/Filereader.h
- highs/io/FilereaderLp.h
---- HiGHS-1.14.0/highs/CMakeLists.txt.orig 2026-05-27 16:51:09.999028876 -0600
-+++ HiGHS-1.14.0/highs/CMakeLists.txt 2026-05-27 16:51:32.270775528 -0600
-@@ -51,8 +51,8 @@ if(NOT FAST_BUILD)
+--- HiGHS-1.15.1/highs/CMakeLists.txt.orig 2026-07-13 09:54:07.872817310 -0600
++++ HiGHS-1.15.1/highs/CMakeLists.txt 2026-07-13 10:33:45.276614239 -0600
+@@ -57,8 +57,8 @@ if(NOT FAST_BUILD)
)
if(ZLIB AND ZLIB_FOUND)
@@ -146,24 +59,7 @@
endif()
# set the install rpath to the installed destination
-@@ -156,6 +156,7 @@ else()
-
-
- target_sources(highs PRIVATE ${sources} ${headers} ${win_version_file})
-+ target_link_libraries(highs PRIVATE metis amd)
-
- # Optional Cuda
- if (CUPDLP_GPU)
-@@ -257,7 +258,7 @@ else()
- else()
- # LINUX
- if(BLAS_LIB)
-- target_link_libraries(highs PRIVATE "${BLAS_LIB}" cblas)
-+ target_link_libraries(highs PRIVATE "${BLAS_LIB}")
- elseif(OPENBLAS_LIB)
- target_link_libraries(highs PRIVATE "${OPENBLAS_LIB}")
- target_compile_definitions(highs PRIVATE HIPO_USES_OPENBLAS)
-@@ -342,10 +343,7 @@ else()
+@@ -314,10 +315,7 @@ else()
if(ZLIB AND ZLIB_FOUND)
@@ -174,9 +70,29 @@
+ target_link_libraries(highs PRIVATE zlib-ng::zlib)
endif()
- # install the header files of highs
---- HiGHS-1.14.0/highs/io/filereaderlp/reader.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/io/filereaderlp/reader.cpp 2026-05-27 16:54:25.423097121 -0600
+ # allow consumers of highs to be aware of potential external dependencies
+--- HiGHS-1.15.1/highs/HighsExternalDeps.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/HighsExternalDeps.cpp 2026-07-04 11:56:41.546978695 -0600
+@@ -15,7 +15,7 @@ namespace HighsExtras {
+
+ #ifdef ZLIB_FOUND
+ constexpr bool __zlib_enabled = true;
+-#include "zlib.h" // defines ZLIB_VERSION
++#include <zlib-ng.h> // defines ZLIB_VERSION
+ #else
+ constexpr bool __zlib_enabled = false;
+ #define ZLIB_VERSION "unknown"
+@@ -30,7 +30,7 @@ constexpr bool __cuda_enabled = false;
+ const HighsExtrasFeatureInfo highs_family_info_[] = {
+ {"pdqsort", "git:b1ef26a", "Zlib", true},
+ {"zstr", "1.0.6", "MIT", __zlib_enabled},
+- {"ZLIB", ZLIB_VERSION, "Zlib", __zlib_enabled},
++ {"ZLIB-NG", ZLIBNG_VERSION, "Zlib", __zlib_enabled},
+ {"NVIDIA Driver API", "runtime", "N/A (not redistributed)",
+ __cuda_enabled}};
+
+--- HiGHS-1.15.1/highs/io/filereaderlp/reader.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/io/filereaderlp/reader.cpp 2026-07-04 10:06:20.514832612 -0600
@@ -17,7 +17,7 @@
#include "builder.hpp"
#include "def.hpp"
@@ -186,8 +102,8 @@
#endif
// Cygwin doesn't come with an implementation for strdup if compiled with
---- HiGHS-1.14.0/highs/io/HMpsFF.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/io/HMpsFF.cpp 2026-05-27 16:54:25.425604826 -0600
+--- HiGHS-1.15.1/highs/io/HMpsFF.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/io/HMpsFF.cpp 2026-07-04 10:06:20.515144022 -0600
@@ -11,7 +11,7 @@
#include "lp_data/HighsModelUtils.h"
@@ -197,8 +113,8 @@
#endif
namespace free_format_parser {
---- HiGHS-1.14.0/highs/io/HMPSIO.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/io/HMPSIO.cpp 2026-05-27 16:54:25.426027211 -0600
+--- HiGHS-1.15.1/highs/io/HMPSIO.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/io/HMPSIO.cpp 2026-07-04 10:06:20.515451596 -0600
@@ -21,7 +21,7 @@
#include "util/stringutil.h"
@@ -208,70 +124,8 @@
#endif
using std::map;
---- HiGHS-1.14.0/highs/ipm/hipo/factorhighs/Analyse.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/ipm/hipo/factorhighs/Analyse.cpp 2026-05-27 16:54:25.432757511 -0600
-@@ -10,10 +10,10 @@
- #include "DataCollector.h"
- #include "FactorHiGHSSettings.h"
- #include "ReturnValues.h"
--#include "amd/amd.h"
-+#include <suitesparse/amd.h>
- #include "ipm/hipo/auxiliary/Auxiliary.h"
- #include "ipm/hipo/auxiliary/Log.h"
--#include "metis/metis.h"
-+#include <metis.h>
- #include "rcm/rcm.h"
-
- namespace hipo {
---- HiGHS-1.14.0/highs/ipm/hipo/ipm/FactorHiGHSSolver.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/ipm/hipo/ipm/FactorHiGHSSolver.cpp 2026-05-27 16:54:25.436186183 -0600
-@@ -3,10 +3,10 @@
- #include <limits>
-
- #include "Status.h"
--#include "amd/amd.h"
-+#include <suitesparse/amd.h>
- #include "ipm/hipo/auxiliary/Auxiliary.h"
- #include "ipm/hipo/auxiliary/Log.h"
--#include "metis/metis.h"
-+#include <metis.h>
- #include "parallel/HighsParallel.h"
- #include "rcm/rcm.h"
-
-@@ -591,7 +591,7 @@ Int FactorHiGHSSolver::chooseOrdering(co
- // compute ordering
- if (orderings_to_try[i] == kHipoMetisString) {
- idx_t options[METIS_NOPTIONS];
-- Highs_METIS_SetDefaultOptions(options);
-+ METIS_SetDefaultOptions(options);
- options[METIS_OPTION_SEED] = kMetisSeed;
-
- // set logging of Metis depending on debug level
-@@ -606,7 +606,7 @@ Int FactorHiGHSSolver::chooseOrdering(co
- std::vector<Int> iperm(n);
-
- Int status =
-- Highs_METIS_NodeND(&n, full_ptr.data(), full_rows.data(), NULL,
-+ METIS_NodeND(&n, full_ptr.data(), full_rows.data(), NULL,
- options, permutations[i].data(), iperm.data());
-
- log_.printDevInfo("Metis done\n");
-@@ -616,11 +616,11 @@ Int FactorHiGHSSolver::chooseOrdering(co
- }
- } else if (orderings_to_try[i] == kHipoAmdString) {
- double control[AMD_CONTROL];
-- Highs_amd_defaults(control);
-+ amd_defaults(control);
- double info[AMD_INFO];
-
- log_.printDevInfo("Running AMD\n");
-- Int status = Highs_amd_order(n, full_ptr.data(), full_rows.data(),
-+ Int status = amd_order(n, full_ptr.data(), full_rows.data(),
- permutations[i].data(), control, info);
- log_.printDevInfo("AMD done\n");
-
---- HiGHS-1.14.0/highs/ipm/ipx/model.cc.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/ipm/ipx/model.cc 2026-05-27 16:54:25.442792098 -0600
+--- HiGHS-1.15.1/highs/ipm/ipx/model.cc.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/ipm/ipx/model.cc 2026-07-04 10:06:20.516406035 -0600
@@ -3,7 +3,7 @@
#include <cassert>
#include <cmath>
@@ -290,8 +144,8 @@
for (Int j = 1; j < num_cols_; j++) {
if (colcount[j] >
---- HiGHS-1.14.0/highs/ipm/ipx/sparse_matrix.cc.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/ipm/ipx/sparse_matrix.cc 2026-05-27 16:54:25.443027015 -0600
+--- HiGHS-1.15.1/highs/ipm/ipx/sparse_matrix.cc.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/ipm/ipx/sparse_matrix.cc 2026-07-04 10:06:20.516665388 -0600
@@ -4,7 +4,7 @@
#include <cmath>
#include <utility>
@@ -310,8 +164,8 @@
for (Int k = 0, p = begin(j); p < end(j); k++, p++) {
index(p) = work[k].first;
value(p) = work[k].second;
---- HiGHS-1.14.0/highs/ipm/ipx/utils.cc.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/ipm/ipx/utils.cc 2026-05-27 16:54:25.443537017 -0600
+--- HiGHS-1.15.1/highs/ipm/ipx/utils.cc.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/ipm/ipx/utils.cc 2026-07-04 10:06:20.516815548 -0600
@@ -3,7 +3,7 @@
#include <cassert>
#include <cmath>
@@ -335,8 +189,8 @@
return std::make_pair(values[i], i) < std::make_pair(values[j], j);
});
---- HiGHS-1.14.0/highs/mip/HighsCliqueTable.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/mip/HighsCliqueTable.cpp 2026-05-27 16:54:25.461049916 -0600
+--- HiGHS-1.15.1/highs/mip/HighsCliqueTable.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/mip/HighsCliqueTable.cpp 2026-07-04 10:06:20.517038293 -0600
@@ -12,7 +12,7 @@
#include <cstdio>
#include <numeric>
@@ -355,7 +209,7 @@
return std::make_pair(a.weight(data.sol), a.index()) >
std::make_pair(b.weight(data.sol), b.index());
});
-@@ -513,7 +513,7 @@ void HighsCliqueTable::queryNeighbourhoo
+@@ -514,7 +514,7 @@ void HighsCliqueTable::queryNeighbourhoo
d.neighbourhoodInds.end());
numQueries += d.numQueries;
});
@@ -364,7 +218,7 @@
}
}
-@@ -901,7 +901,7 @@ void HighsCliqueTable::extractCliques(
+@@ -902,7 +902,7 @@ void HighsCliqueTable::extractCliques(
// only one binary means we do have no cliques
if (nbin <= 1) return;
@@ -373,7 +227,7 @@
return std::make_pair(vals[p1], p1) > std::make_pair(vals[p2], p2);
});
// check if any cliques exists
-@@ -1009,7 +1009,7 @@ void HighsCliqueTable::cliquePartition(c
+@@ -1010,7 +1010,7 @@ void HighsCliqueTable::cliquePartition(c
std::vector<HighsInt>& partitionStart) {
randgen.shuffle(clqVars.data(), clqVars.size());
@@ -382,7 +236,7 @@
[&](CliqueVar v1, CliqueVar v2) {
return (2 * v1.val - 1) * objective[v1.col] >
(2 * v2.val - 1) * objective[v2.col];
-@@ -1029,7 +1029,7 @@ void HighsCliqueTable::cliquePartition(c
+@@ -1030,7 +1030,7 @@ void HighsCliqueTable::cliquePartition(c
partitionStart.push_back(i);
extensionEnd = numClqVars;
if (lastSwappedIndex >= i)
@@ -391,7 +245,7 @@
clqVars.begin() + lastSwappedIndex + 1,
[&](CliqueVar v1, CliqueVar v2) {
return (2 * v1.val - 1) * objective[v1.col] >
-@@ -1210,7 +1210,7 @@ void HighsCliqueTable::extractCliquesFro
+@@ -1211,7 +1211,7 @@ void HighsCliqueTable::extractCliquesFro
std::vector<CliqueVar> clique;
clique.reserve(nbin);
@@ -400,7 +254,7 @@
return std::make_pair(std::abs(vals[p1]), p1) >
std::make_pair(std::abs(vals[p2]), p2);
});
-@@ -1405,7 +1405,7 @@ void HighsCliqueTable::extractObjCliques
+@@ -1406,7 +1406,7 @@ void HighsCliqueTable::extractObjCliques
std::vector<CliqueVar> clique;
clique.reserve(nbin);
@@ -409,18 +263,18 @@
return std::make_pair(std::fabs(vals[p1]), p1) >
std::make_pair(std::fabs(vals[p2]), p2);
});
---- HiGHS-1.14.0/highs/mip/HighsCutGeneration.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/mip/HighsCutGeneration.cpp 2026-05-27 16:54:25.461831754 -0600
+--- HiGHS-1.15.1/highs/mip/HighsCutGeneration.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/mip/HighsCutGeneration.cpp 2026-07-04 10:19:20.617855675 -0600
@@ -7,7 +7,7 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "mip/HighsCutGeneration.h"
-#include "../extern/pdqsort/pdqsort.h"
+#include <boost/sort/pdqsort/pdqsort.hpp>
+ #include "mip/HighsDomain.h"
#include "mip/HighsMipSolverData.h"
#include "mip/HighsTransformedLp.h"
- #include "util/HighsIntegers.h"
-@@ -57,7 +57,7 @@ bool HighsCutGeneration::determineCover(
+@@ -58,7 +58,7 @@ bool HighsCutGeneration::determineCover(
// sort the remaining variables by the contribution to the rows activity in
// the current solution
@@ -429,7 +283,7 @@
[&](HighsInt i, HighsInt j) {
if (upper[i] < 1.5 && upper[j] > 1.5) return true;
if (upper[i] > 1.5 && upper[j] < 1.5) return false;
-@@ -82,7 +82,7 @@ bool HighsCutGeneration::determineCover(
+@@ -83,7 +83,7 @@ bool HighsCutGeneration::determineCover(
// the current solution
const auto& nodequeue = lpRelaxation.getMipSolver().mipdata_->nodequeue;
@@ -438,7 +292,7 @@
[&](HighsInt i, HighsInt j) {
if (solval[i] > feastol && solval[j] <= feastol) return true;
if (solval[i] <= feastol && solval[j] > feastol) return false;
-@@ -136,7 +136,7 @@ void HighsCutGeneration::separateLiftedK
+@@ -135,7 +135,7 @@ void HighsCutGeneration::separateLiftedK
S.resize(coversize);
std::vector<int8_t> coverflag;
coverflag.resize(rowlen);
@@ -447,7 +301,7 @@
[&](HighsInt a, HighsInt b) { return vals[a] > vals[b]; });
HighsCDouble abartmp = vals[cover[0]];
-@@ -229,7 +229,7 @@ bool HighsCutGeneration::separateLiftedM
+@@ -228,7 +228,7 @@ bool HighsCutGeneration::separateLiftedM
for (HighsInt i = 0; i != coversize; ++i) coverflag[cover[i]] = 1;
@@ -456,7 +310,7 @@
[&](HighsInt a, HighsInt b) { return vals[a] > vals[b]; });
HighsCDouble sum = 0;
-@@ -292,7 +292,7 @@ bool HighsCutGeneration::separateLiftedM
+@@ -291,7 +291,7 @@ bool HighsCutGeneration::separateLiftedM
for (HighsInt i : cover) coverflag[i] = 1;
auto comp = [&](HighsInt a, HighsInt b) { return vals[a] > vals[b]; };
@@ -465,7 +319,7 @@
std::vector<HighsCDouble> a;
std::vector<HighsCDouble> u;
-@@ -566,7 +566,7 @@ bool HighsCutGeneration::cmirCutGenerati
+@@ -565,7 +565,7 @@ bool HighsCutGeneration::cmirCutGenerati
if (deltas.empty()) return false;
@@ -474,8 +328,8 @@
double curdelta = deltas[0];
for (size_t i = 1; i < deltas.size(); ++i) {
if (deltas[i] - curdelta <= 10 * feastol)
---- HiGHS-1.14.0/highs/mip/HighsCutPool.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/mip/HighsCutPool.cpp 2026-05-27 16:54:25.462342526 -0600
+--- HiGHS-1.15.1/highs/mip/HighsCutPool.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/mip/HighsCutPool.cpp 2026-07-04 10:06:20.517726165 -0600
@@ -11,7 +11,7 @@
#include <cassert>
#include <numeric>
@@ -485,7 +339,7 @@
#include "mip/HighsDomain.h"
#include "mip/HighsLpRelaxation.h"
#include "mip/HighsMipSolverData.h"
-@@ -272,7 +272,7 @@ void HighsCutPool::separate(const std::v
+@@ -346,7 +346,7 @@ void HighsCutPool::separate(const std::v
assert((HighsInt)propRows.size() == numPropRows);
if (efficacious_cuts.empty()) return;
@@ -494,7 +348,7 @@
[&efficacious_cuts](const std::pair<double, HighsInt>& a,
const std::pair<double, HighsInt>& b) {
if (a.first > b.first) return true;
-@@ -420,7 +420,7 @@ HighsInt HighsCutPool::addCut(const High
+@@ -518,7 +518,7 @@ HighsInt HighsCutPool::addCut(const High
sortBuffer[i].first = Rindex[i];
sortBuffer[i].second = Rvalue[i];
}
@@ -503,8 +357,8 @@
sortBuffer.begin(), sortBuffer.end(),
[](const std::pair<HighsInt, double>& a,
const std::pair<HighsInt, double>& b) { return a.first < b.first; });
---- HiGHS-1.14.0/highs/mip/HighsDomain.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/mip/HighsDomain.cpp 2026-05-27 16:54:25.462641974 -0600
+--- HiGHS-1.15.1/highs/mip/HighsDomain.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/mip/HighsDomain.cpp 2026-07-04 10:06:20.518071969 -0600
@@ -12,7 +12,7 @@
#include <numeric>
#include <queue>
@@ -514,7 +368,7 @@
#include "mip/HighsConflictPool.h"
#include "mip/HighsCutPool.h"
#include "mip/HighsMipSolverData.h"
-@@ -2731,7 +2731,7 @@ bool HighsDomain::ConflictSet::explainBo
+@@ -2832,7 +2832,7 @@ bool HighsDomain::ConflictSet::explainBo
if (domchgVal == 0) return false;
@@ -523,7 +377,7 @@
// to explain the bound change we start from the bound constraint,
// multiply it by the columns coefficient in the constraint. Then the
-@@ -2838,7 +2838,7 @@ bool HighsDomain::ConflictSet::explainBo
+@@ -2939,7 +2939,7 @@ bool HighsDomain::ConflictSet::explainBo
if (domchgVal == 0) return false;
@@ -532,7 +386,7 @@
assert(domchgVal != 0);
-@@ -3309,7 +3309,7 @@ bool HighsDomain::ConflictSet::explainIn
+@@ -3410,7 +3410,7 @@ bool HighsDomain::ConflictSet::explainIn
resolveBuffer.push_back(cand);
}
@@ -541,7 +395,7 @@
// compute the lower bound of M that is necessary
double Mupper = rhs - std::max(10.0, std::fabs(rhs)) *
-@@ -3356,7 +3356,7 @@ bool HighsDomain::ConflictSet::explainIn
+@@ -3457,7 +3457,7 @@ bool HighsDomain::ConflictSet::explainIn
resolveBuffer.push_back(cand);
}
@@ -550,8 +404,8 @@
// compute the lower bound of M that is necessary
double Mlower = rhs + std::max(10.0, std::fabs(rhs)) *
---- HiGHS-1.14.0/highs/mip/HighsImplications.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/mip/HighsImplications.cpp 2026-05-27 16:54:25.463698383 -0600
+--- HiGHS-1.15.1/highs/mip/HighsImplications.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/mip/HighsImplications.cpp 2026-07-04 10:06:20.518461686 -0600
@@ -7,7 +7,7 @@
/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
#include "mip/HighsImplications.h"
@@ -570,8 +424,8 @@
std::array<HighsCliqueTable::CliqueVar, 2> clique;
clique[0] = HighsCliqueTable::CliqueVar(col, val);
---- HiGHS-1.14.0/highs/mip/HighsMipSolverData.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/mip/HighsMipSolverData.cpp 2026-05-27 16:54:25.464066069 -0600
+--- HiGHS-1.15.1/highs/mip/HighsMipSolverData.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/mip/HighsMipSolverData.cpp 2026-07-04 10:06:20.518709448 -0600
@@ -10,7 +10,7 @@
#include <random>
#include <sstream>
@@ -581,8 +435,8 @@
#include "lp_data/HighsModelUtils.h"
#include "mip/HighsPseudocost.h"
#include "mip/HighsRedcostFixing.h"
---- HiGHS-1.14.0/highs/mip/HighsModkSeparator.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/mip/HighsModkSeparator.cpp 2026-05-27 16:54:25.465010960 -0600
+--- HiGHS-1.15.1/highs/mip/HighsModkSeparator.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/mip/HighsModkSeparator.cpp 2026-07-04 10:06:20.518981605 -0600
@@ -12,7 +12,7 @@
#include <unordered_set>
@@ -601,8 +455,8 @@
if (!usedWeights.insert(weights)) return;
assert(lpAggregator.isEmpty());
---- HiGHS-1.14.0/highs/mip/HighsObjectiveFunction.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/mip/HighsObjectiveFunction.cpp 2026-05-27 16:54:25.465224809 -0600
+--- HiGHS-1.15.1/highs/mip/HighsObjectiveFunction.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/mip/HighsObjectiveFunction.cpp 2026-07-04 10:06:20.519194452 -0600
@@ -10,7 +10,7 @@
#include <numeric>
@@ -621,8 +475,8 @@
[&](HighsInt i, HighsInt j) {
return std::make_pair((HighsUInt)colToPartition[i],
HighsHashHelpers::hash(i)) <
---- HiGHS-1.14.0/highs/mip/HighsPrimalHeuristics.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/mip/HighsPrimalHeuristics.cpp 2026-05-27 16:54:25.465473883 -0600
+--- HiGHS-1.15.1/highs/mip/HighsPrimalHeuristics.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/mip/HighsPrimalHeuristics.cpp 2026-07-04 10:06:20.519429409 -0600
@@ -10,7 +10,7 @@
#include <numeric>
#include <unordered_set>
@@ -632,7 +486,7 @@
#include "io/HighsIO.h"
#include "lp_data/HConst.h"
#include "lp_data/HighsLpUtils.h"
-@@ -48,7 +48,7 @@ HighsPrimalHeuristics::HighsPrimalHeuris
+@@ -43,7 +43,7 @@ HighsPrimalHeuristics::HighsPrimalHeuris
void HighsPrimalHeuristics::setupIntCols() {
intcols = mipsolver.mipdata_->integer_cols;
@@ -641,8 +495,8 @@
const FP_32BIT_VOLATILE double lockScore1 =
(mipsolver.mipdata_->feastol + mipsolver.mipdata_->uplocks[c1]) *
(mipsolver.mipdata_->feastol + mipsolver.mipdata_->downlocks[c1]);
-@@ -286,7 +286,7 @@ void HighsPrimalHeuristics::rootReducedC
- mipsolver.mipdata_->redcostfixing.getLurkingBounds(mipsolver);
+@@ -317,7 +317,7 @@ void HighsPrimalHeuristics::rootReducedC
+ mipsolver, worker.getGlobalDomain());
if (10 * lurkingBounds.size() < mipsolver.mipdata_->integral_cols.size())
return;
- pdqsort(lurkingBounds.begin(), lurkingBounds.end(),
@@ -650,7 +504,7 @@
[](const std::pair<double, HighsDomainChange>& a,
const std::pair<double, HighsDomainChange>& b) {
return a.first > b.first;
-@@ -485,7 +485,7 @@ retry:
+@@ -533,7 +533,7 @@ retry:
return fixval;
};
@@ -659,7 +513,7 @@
heurlp.getFractionalIntegers().end(),
[&](const std::pair<HighsInt, double>& a,
const std::pair<HighsInt, double>& b) {
-@@ -769,7 +769,7 @@ retry:
+@@ -844,7 +844,7 @@ retry:
// now sort the variables by their distance towards the value they will be
// fixed to
@@ -668,8 +522,8 @@
[&](const std::pair<HighsInt, double>& a,
const std::pair<HighsInt, double>& b) {
return std::make_pair(
---- HiGHS-1.14.0/highs/mip/HighsTableauSeparator.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/mip/HighsTableauSeparator.cpp 2026-05-27 16:54:25.466148812 -0600
+--- HiGHS-1.15.1/highs/mip/HighsTableauSeparator.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/mip/HighsTableauSeparator.cpp 2026-07-04 10:06:20.519669838 -0600
@@ -12,7 +12,7 @@
#include <algorithm>
@@ -706,8 +560,8 @@
double bestScore = -1.0;
HighsInt numCuts = cutpool.getNumCuts();
---- HiGHS-1.14.0/highs/presolve/HighsSymmetry.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/presolve/HighsSymmetry.cpp 2026-05-27 16:54:25.477032141 -0600
+--- HiGHS-1.15.1/highs/presolve/HighsSymmetry.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/presolve/HighsSymmetry.cpp 2026-07-04 10:06:20.519881823 -0600
@@ -15,7 +15,7 @@
#include <algorithm>
#include <numeric>
@@ -717,7 +571,7 @@
#include "mip/HighsCliqueTable.h"
#include "mip/HighsDomain.h"
#include "parallel/HighsParallel.h"
-@@ -231,10 +231,10 @@ HighsSymmetries::computeStabilizerOrbits
+@@ -240,10 +240,10 @@ HighsSymmetries::computeStabilizerOrbits
stabilizerOrbits.orbitCols.push_back(permutationColumns[i]);
}
stabilizerOrbits.symmetries = this;
@@ -729,8 +583,8 @@
+ boost::sort::pdqsort(stabilizerOrbits.orbitCols.begin(),
stabilizerOrbits.orbitCols.end(),
[&](HighsInt col1, HighsInt col2) {
- return getOrbit(col1) < getOrbit(col2);
-@@ -740,7 +740,7 @@ HighsInt HighsOrbitopeMatrix::orbitalFix
+ return getOrbit(col1, workspace.orbitPartition,
+@@ -755,7 +755,7 @@ HighsInt HighsOrbitopeMatrix::orbitalFix
void HighsSymmetryDetection::initializeGroundSet() {
vertexGroundSet = currentPartition;
@@ -739,7 +593,7 @@
vertexPosition.resize(vertexToCell.size(), -1);
for (HighsInt i = 0; i < numVertices; ++i)
vertexPosition[vertexGroundSet[i]] = i;
-@@ -911,7 +911,7 @@ bool HighsSymmetryDetection::partitionRe
+@@ -926,7 +926,7 @@ bool HighsSymmetryDetection::partitionRe
if (refineStart == cellEnd) continue;
// sort the vertices that have updated hash values by their hash values
@@ -748,7 +602,7 @@
currentPartition.begin() + cellEnd, [&](HighsInt v1, HighsInt v2) {
return vertexHash[v1] < vertexHash[v2];
});
-@@ -1267,7 +1267,7 @@ void HighsSymmetryDetection::loadModelAs
+@@ -1282,7 +1282,7 @@ void HighsSymmetryDetection::loadModelAs
// assigned above
currentPartition.resize(numVertices);
std::iota(currentPartition.begin(), currentPartition.end(), 0);
@@ -757,7 +611,7 @@
[&](HighsInt v1, HighsInt v2) {
return vertexToCell[v1] < vertexToCell[v2];
});
-@@ -1428,7 +1428,7 @@ HighsSymmetryDetection::computeComponent
+@@ -1443,7 +1443,7 @@ HighsSymmetryDetection::computeComponent
componentData.componentSets.assign(vertexGroundSet.begin(),
vertexGroundSet.begin() + numActiveCols);
@@ -766,7 +620,7 @@
componentData.componentSets.end(), [&](HighsInt u, HighsInt v) {
HighsInt uComp = componentData.components.getSet(vertexPosition[u]);
HighsInt vComp = componentData.components.getSet(vertexPosition[v]);
-@@ -1466,7 +1466,7 @@ HighsSymmetryDetection::computeComponent
+@@ -1481,7 +1481,7 @@ HighsSymmetryDetection::computeComponent
componentData.permComponents.push_back(i);
}
@@ -775,8 +629,8 @@
componentData.permComponents.end(), [&](HighsInt i, HighsInt j) {
HighsInt seti =
componentData.components.getSet(componentData.firstUnfixed[i]);
---- HiGHS-1.14.0/highs/presolve/HPresolve.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/presolve/HPresolve.cpp 2026-05-27 16:54:25.478026611 -0600
+--- HiGHS-1.15.1/highs/presolve/HPresolve.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/presolve/HPresolve.cpp 2026-07-04 10:20:50.713026544 -0600
@@ -12,7 +12,7 @@
#include <cmath>
#include <limits>
@@ -786,7 +640,7 @@
#include "Highs.h"
#include "io/HighsIO.h"
#include "lp_data/HConst.h"
-@@ -1623,7 +1623,7 @@ HPresolve::Result HPresolve::runProbing(
+@@ -1633,7 +1633,7 @@ HPresolve::Result HPresolve::runProbing(
}
if (!binaries.empty()) {
// sort variables with many implications on other binaries first
@@ -795,7 +649,7 @@
size_t numChangedCols = 0;
while (domain.getChangedCols().size() != numChangedCols) {
-@@ -1996,7 +1996,7 @@ HPresolve::Result HPresolve::liftingForP
+@@ -2006,7 +2006,7 @@ HPresolve::Result HPresolve::liftingForP
};
// sort according to score
@@ -804,16 +658,16 @@
liftingtable.begin(), liftingtable.end(),
[&](const liftingdata& opp1, const liftingdata& opp2) {
double score1 = computeOverallScore(
-@@ -4990,7 +4990,7 @@ HPresolve::Result HPresolve::singletonCo
+@@ -5005,7 +5005,7 @@ HPresolve::Result HPresolve::singletonCo
};
auto sortCols = [&](std::vector<candidate>& vec) {
- pdqsort(vec.begin(), vec.end(),
+ boost::sort::pdqsort(vec.begin(), vec.end(),
- [&](const candidate& col1, const candidate& col2) {
- return model->col_cost_[std::get<0>(col1)] / std::get<1>(col1) <
- model->col_cost_[std::get<0>(col2)] / std::get<1>(col2);
-@@ -5192,7 +5192,7 @@ HPresolve::Result HPresolve::enumerateSo
+ [&](const candidate& c1, const candidate& c2) {
+ return model->col_cost_[c1.col] / c1.val <
+ model->col_cost_[c2.col] / c2.val;
+@@ -5265,7 +5265,7 @@ HPresolve::Result HPresolve::enumerateSo
binvars[numnzs++] = col;
}
if (numnzs == 0) return false;
@@ -822,7 +676,7 @@
return true;
};
-@@ -5321,7 +5321,7 @@ HPresolve::Result HPresolve::enumerateSo
+@@ -5394,7 +5394,7 @@ HPresolve::Result HPresolve::enumerateSo
// compile rows and sort them
compileRows(rows);
@@ -831,7 +685,7 @@
// remove similar rows
removeSimilarRows(rows);
-@@ -6618,7 +6618,7 @@ HPresolve::Result HPresolve::aggregator(
+@@ -6700,7 +6700,7 @@ HPresolve::Result HPresolve::aggregator(
}),
substitutionOpportunities.end());
@@ -840,7 +694,7 @@
substitutionOpportunities.begin(), substitutionOpportunities.end(),
[&](const std::pair<HighsInt, HighsInt>& nz1,
const std::pair<HighsInt, HighsInt>& nz2) {
-@@ -7068,7 +7068,7 @@ HPresolve::Result HPresolve::strengthenI
+@@ -7150,7 +7150,7 @@ HPresolve::Result HPresolve::strengthenI
if (maxviolation - continuouscontribution <= smallVal || indices.empty())
break;
@@ -849,8 +703,8 @@
return std::make_pair(reducedcost[i1], i1) >
std::make_pair(reducedcost[i2], i2);
});
---- HiGHS-1.14.0/highs/simplex/HEkkDualRHS.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/simplex/HEkkDualRHS.cpp 2026-05-27 16:54:25.489819431 -0600
+--- HiGHS-1.15.1/highs/simplex/HEkkDualRHS.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/simplex/HEkkDualRHS.cpp 2026-07-04 10:06:20.521268326 -0600
@@ -15,7 +15,7 @@
#include <iostream>
#include <set>
@@ -887,8 +741,8 @@
if ((HighsInt)(setP.size()) > chLimit) setP.resize(chLimit);
*chCount = static_cast<HighsInt>(setP.size());
for (size_t i = 0; i < setP.size(); i++) chIndex[i] = setP[i].second;
---- HiGHS-1.14.0/highs/simplex/HEkkDualRow.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/simplex/HEkkDualRow.cpp 2026-05-27 16:54:25.490114932 -0600
+--- HiGHS-1.15.1/highs/simplex/HEkkDualRow.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/simplex/HEkkDualRow.cpp 2026-07-04 10:06:20.521452269 -0600
@@ -13,7 +13,7 @@
#include <cassert>
#include <iostream>
@@ -907,8 +761,8 @@
analysis->simplexTimerStop(Chuzc4eClock);
analysis->simplexTimerStop(Chuzc4Clock);
---- HiGHS-1.14.0/highs/simplex/HEkkPrimal.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/simplex/HEkkPrimal.cpp 2026-05-27 16:54:25.490437944 -0600
+--- HiGHS-1.15.1/highs/simplex/HEkkPrimal.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/simplex/HEkkPrimal.cpp 2026-07-04 10:06:20.521699580 -0600
@@ -10,7 +10,7 @@
*/
#include "simplex/HEkkPrimal.h"
@@ -936,8 +790,8 @@
double dMaxAlpha = 0.0;
size_t iLast = ph1SorterT.size();
for (size_t i = 0; i < ph1SorterT.size(); i++) {
---- HiGHS-1.14.0/highs/simplex/HSimplexNla.cpp.orig 2026-04-06 08:36:31.000000000 -0600
-+++ HiGHS-1.14.0/highs/simplex/HSimplexNla.cpp 2026-05-27 16:54:25.491394868 -0600
+--- HiGHS-1.15.1/highs/simplex/HSimplexNla.cpp.orig 2026-07-02 00:42:37.000000000 -0600
++++ HiGHS-1.15.1/highs/simplex/HSimplexNla.cpp 2026-07-04 10:06:20.521969643 -0600
@@ -14,7 +14,7 @@
#include <stdio.h>
@@ -965,8 +819,8 @@
for (HighsInt en = 0; en < vector->packCount; en++) {
HighsInt iRow = sorted_index[en];
if (en % 5 == 0) printf("\n");
---- HiGHS-1.14.0/highs/util/HFactor.cpp.orig 2026-05-27 16:51:17.165196338 -0600
-+++ HiGHS-1.14.0/highs/util/HFactor.cpp 2026-05-27 16:54:25.498108254 -0600
+--- HiGHS-1.15.1/highs/util/HFactor.cpp.orig 2026-07-13 09:54:15.646690768 -0600
++++ HiGHS-1.15.1/highs/util/HFactor.cpp 2026-07-13 09:54:26.088203673 -0600
@@ -13,7 +13,7 @@
#include <cassert>
#include <iostream>
diff --git a/coin-or-HiGHS.spec b/coin-or-HiGHS.spec
index 1727628..ea9d4b1 100644
--- a/coin-or-HiGHS.spec
+++ b/coin-or-HiGHS.spec
@@ -5,12 +5,12 @@
%bcond ctest 1
# The build runs git to get a commit, but we don't have a git checkout
-%global commit 7df0786de
+%global commit 04024d701
%global giturl https://github.com/ERGO-Code/HiGHS
Name: coin-or-HiGHS
-Version: 1.14.0
+Version: 1.15.1
Release: %autorelease
Summary: Linear optimization software
@@ -24,23 +24,8 @@ Patch: %{name}-rpath.patch
Patch: %{name}-popcount.patch
# Fix out-of-bounds vector accesses
Patch: %{name}-vector.patch
-# Unbundle amd, cli11, metis, pdqsort, and zstr
+# Unbundle cli11, pdqsort, and zstr
Patch: %{name}-unbundle.patch
-# Fix 2957
-# https://github.com/ERGO-Code/HiGHS/pull/2961
-#
-# Fixes:
-#
-# - MIP incorrect solution in HiGHS 1.14:
-# https://github.com/ERGO-Code/HiGHS/issues/2957
-# - highspy v1.14 regression: presolve in toy example is reaching non-optimal
-# solution: https://github.com/ERGO-Code/HiGHS/issues/3002
-# - Test regressions in 3.3.0 with HiGHS 1.14:
-# https://github.com/coin-or/pulp/issues/904
-# - python-pulp: FTBFS in Fedora Rawhide: pulp.constants.PulpError: Tests
-# failed for solver <pulp.apis.highs_api.HiGHS_CMD object at 0x7f39f283cb00>:
-# var x == 2.0 != 3: https://bugzilla.redhat.com/show_bug.cgi?id=2466661
-Patch: %{name}-issue-2957.patch
# Patch courtesy of Gentoo to fix the tests on some arches
Patch: %{name}-ignore-test-iterations.patch
@@ -60,15 +45,10 @@ BuildRequires: boost-devel
BuildRequires: catch2-devel
BuildRequires: cli11-static
BuildRequires: cmake
-BuildRequires: cmake(AMD)
-BuildRequires: doctest-static
BuildRequires: gcc-c++
BuildRequires: help2man
BuildRequires: libatomic
-BuildRequires: metis-devel
BuildRequires: ninja-build
-BuildRequires: pkgconfig(coindatanetlib)
-BuildRequires: pkgconfig(coindatasample)
BuildRequires: pkgconfig(flexiblas)
BuildRequires: python3-devel
BuildRequires: zstr-static
@@ -83,6 +63,13 @@ Provides: bundled(FilereaderLP)
# https://people.sc.fsu.edu/~jburkardt/f77_src/sparsepak/sparsepak.html
Provides: bundled(rcm)
+# In the past, we unbundled both AMD (part of suitesparse) and metis. However,
+# with version 1.15.1, we see multiple test failures when unbundling either.
+# The bundled versions are newer than those available in Rawhide. If either
+# package is updated in Rawhide, see if we can unbundle again.
+Provides: bundled(metis) = 5.2.1
+Provides: bundled(suitesparse) = 7.12.1
+
%description
HiGHS is a high performance serial and parallel solver for large scale sparse
linear optimization problems of the form
@@ -127,11 +114,11 @@ This package contains a Python 3 interface to coin-or-HiGHS.
sed -i 's,n/a,%{commit},' CMakeLists.txt
# Unbundle catch
-rm extern/catch.hpp
-ln -s %{_includedir}/catch2/catch.hpp extern/catch.hpp
+rm extern/catch/catch.hpp
+ln -s %{_includedir}/catch2/catch.hpp extern/catch/catch.hpp
-# Ensure the bundled amd, cli11, metis, pdqsort, and zstr are not used
-rm -fr extern/{CLI11.hpp,amd,metis,pdqsort,zstr}
+# Ensure the bundled cli11, pdqsort, and zstr are not used
+rm -fr extern/{cli11,pdqsort,zstr}
%generate_buildrequires
%pyproject_buildrequires -x test
@@ -157,9 +144,9 @@ rm -fr %{buildroot}%{_docdir}
# Instead of linking with and installing a private copy of the library,
# fix up the installed python tree to use the installed library
-cd highs
-g++ %{build_cxxflags} -fPIC -shared -I . -I ../%{_vpath_builddir} \
- -I %{_includedir}/python%{python3_version} highs_bindings.cpp \
+cd highspy
+g++ %{build_cxxflags} -fPIC -shared -I ../highs -I ../%{_vpath_builddir} \
+ -I ../extern -I %{_includedir}/python%{python3_version} highs_bindings.cpp \
-o %{buildroot}%{python3_sitearch}/highspy/_core%{python3_ext_suffix} \
%{build_ldflags} -L %{buildroot}%{_libdir} -lhighs
cd -
diff --git a/sources b/sources
index febb87b..e2895aa 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-SHA512 (HiGHS-1.14.0.tar.gz) = d4c2d09bf41384a58a04528ffaac223eee40dea4a1cadaea369791f6e8d1aa61ff3fce57e7c97cb5f4bef0f1305681066e8ef7483f4471770295f95b9ec337f7
+SHA512 (HiGHS-1.15.1.tar.gz) = 0ea407784bc6c8e31c72fbcdcab201e8a7cc7debbca57504e74177658208151e90637e5fb1e0cdf1b1ae6b677e7865e77771ec025b17f8223f74d00fc6420546
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2026-07-14 16:55 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-07-14 16:55 [rpms/coin-or-HiGHS] rawhide: Version 1.15.1 Jerry James
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox