Skip to content

Commit

Permalink
Merge pull request #1993 from ERGO-Code/qp-format
Browse files Browse the repository at this point in the history
QP solver formatting
  • Loading branch information
galabovaa authored Oct 23, 2024
2 parents 78a273c + 229f0cd commit 2fc565a
Show file tree
Hide file tree
Showing 27 changed files with 525 additions and 478 deletions.
5 changes: 3 additions & 2 deletions .github/workflows/clang-format.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@ jobs:
- uses: actions/checkout@v4
- uses: DoozyX/[email protected]
with:
source: 'app/ src/Highs.h ./src/lp_data ./src/mip ./src/model ./src/simplex ./src/presolve ./src/simplex ./src/util ./src/test'
#./src/test ./interfaces'
source:
'app/ src/Highs.h ./src/lp_data ./src/mip ./src/model ./src/simplex ./src/presolve ./src/simplex ./src/util ./src/test ./src/qpsolver'
# ./src/test ./interfaces'
extensions: 'h,cpp,c'
clangFormatVersion: 18
100 changes: 53 additions & 47 deletions src/qpsolver/a_asm.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
#include "qpsolver/a_asm.hpp"

#include "qpsolver/quass.hpp"
#include "util/HighsCDouble.h"

QpAsmStatus solveqp_actual(Instance& instance, Settings& settings, QpHotstartInformation& startinfo, Statistics& stats, QpModelStatus& status, QpSolution& solution, HighsTimer& qp_timer) {
QpAsmStatus solveqp_actual(Instance& instance, Settings& settings,
QpHotstartInformation& startinfo, Statistics& stats,
QpModelStatus& status, QpSolution& solution,
HighsTimer& qp_timer) {
Runtime rt(instance, stats);
rt.settings = settings;
Quass quass(rt);
Expand All @@ -21,54 +25,55 @@ QpAsmStatus solveqp_actual(Instance& instance, Settings& settings, QpHotstartInf
solution.dualcon = rt.dualcon;

return QpAsmStatus::kOk;

}

std::string qpBasisStatusToString(const BasisStatus qp_basis_status) {
switch (qp_basis_status) {
case BasisStatus::kInactive:
return "Inactive";
case BasisStatus::kActiveAtLower:
return "Active at lower bound";
case BasisStatus::kActiveAtUpper:
return "Active at upper bound";
case BasisStatus::kInactiveInBasis:
return "Inactive in basis";
default:
return "Unidentified QP basis status";
case BasisStatus::kInactive:
return "Inactive";
case BasisStatus::kActiveAtLower:
return "Active at lower bound";
case BasisStatus::kActiveAtUpper:
return "Active at upper bound";
case BasisStatus::kInactiveInBasis:
return "Inactive in basis";
default:
return "Unidentified QP basis status";
}
}

std::string qpModelStatusToString(const QpModelStatus qp_model_status) {
switch (qp_model_status) {
case QpModelStatus::kNotset:
return "Not set";
case QpModelStatus::kUndetermined:
return "Undertermined";
case QpModelStatus::kOptimal:
return "Optimal";
case QpModelStatus::kUnbounded:
return "Unbounded";
case QpModelStatus::kInfeasible:
return "Infeasible";
case QpModelStatus::kIterationLimit:
return "Iteration limit";
case QpModelStatus::kTimeLimit:
return "Time ;limit";
case QpModelStatus::kLargeNullspace:
return "Large nullspace";
case QpModelStatus::kError:
return "Error";
default:
return "Unidentified QP model status";
case QpModelStatus::kNotset:
return "Not set";
case QpModelStatus::kUndetermined:
return "Undertermined";
case QpModelStatus::kOptimal:
return "Optimal";
case QpModelStatus::kUnbounded:
return "Unbounded";
case QpModelStatus::kInfeasible:
return "Infeasible";
case QpModelStatus::kIterationLimit:
return "Iteration limit";
case QpModelStatus::kTimeLimit:
return "Time ;limit";
case QpModelStatus::kLargeNullspace:
return "Large nullspace";
case QpModelStatus::kError:
return "Error";
default:
return "Unidentified QP model status";
}
}

void assessQpPrimalFeasibility(const Instance& instance, const double primal_feasibility_tolerance,
const std::vector<double>& var_value, const std::vector<double>& con_value,
HighsInt& num_var_infeasibilities, double& max_var_infeasibility, double& sum_var_infeasibilities,
HighsInt& num_con_infeasibilities, double& max_con_infeasibility, double& sum_con_infeasibilities,
double& max_con_residual, double& sum_con_residuals) {
void assessQpPrimalFeasibility(
const Instance& instance, const double primal_feasibility_tolerance,
const std::vector<double>& var_value, const std::vector<double>& con_value,
HighsInt& num_var_infeasibilities, double& max_var_infeasibility,
double& sum_var_infeasibilities, HighsInt& num_con_infeasibilities,
double& max_con_infeasibility, double& sum_con_infeasibilities,
double& max_con_residual, double& sum_con_residuals) {
num_var_infeasibilities = 0;
max_var_infeasibility = 0;
sum_var_infeasibilities = 0;
Expand All @@ -91,14 +96,16 @@ void assessQpPrimalFeasibility(const Instance& instance, const double primal_fea
var_infeasibility = primal - upper;
}
if (var_infeasibility > 0) {
if (var_infeasibility > primal_feasibility_tolerance)
num_var_infeasibilities++;
if (var_infeasibility > primal_feasibility_tolerance)
num_var_infeasibilities++;
max_var_infeasibility =
std::max(var_infeasibility, max_var_infeasibility);
std::max(var_infeasibility, max_var_infeasibility);
sum_var_infeasibilities += var_infeasibility;
}
for (HighsInt iEl = instance.A.mat.start[iVar]; iEl < instance.A.mat.start[iVar+1]; iEl++) {
con_value_quad[instance.A.mat.index[iEl]] += primal * instance.A.mat.value[iEl];
for (HighsInt iEl = instance.A.mat.start[iVar];
iEl < instance.A.mat.start[iVar + 1]; iEl++) {
con_value_quad[instance.A.mat.index[iEl]] +=
primal * instance.A.mat.value[iEl];
}
}
for (HighsInt iCon = 0; iCon < instance.num_con; iCon++) {
Expand All @@ -112,15 +119,14 @@ void assessQpPrimalFeasibility(const Instance& instance, const double primal_fea
con_infeasibility = primal - upper;
}
if (con_infeasibility > 0) {
if (con_infeasibility > primal_feasibility_tolerance)
num_con_infeasibilities++;
if (con_infeasibility > primal_feasibility_tolerance)
num_con_infeasibilities++;
max_con_infeasibility =
std::max(con_infeasibility, max_con_infeasibility);
std::max(con_infeasibility, max_con_infeasibility);
sum_con_infeasibilities += con_infeasibility;
}
double con_residual = std::fabs(primal-double(con_value_quad[iCon]));
double con_residual = std::fabs(primal - double(con_value_quad[iCon]));
max_con_residual = std::max(con_residual, max_con_residual);
sum_con_residuals += con_residual;
}
}

37 changes: 20 additions & 17 deletions src/qpsolver/a_asm.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
#define __SRC_LIB_QPSOLVER_ASM_HPP__

#include "qpsolver/instance.hpp"
#include "qpsolver/statistics.hpp"
#include "qpsolver/qpconst.hpp"
#include "qpsolver/settings.hpp"
#include "qpsolver/statistics.hpp"
#include "util/HighsTimer.h"

enum class QpAsmStatus {
Expand All @@ -24,15 +24,15 @@ struct QpSolution {
std::vector<BasisStatus> status_var;
std::vector<BasisStatus> status_con;

QpSolution(Instance& instance) : primal(QpVector(instance.num_var)),
QpSolution(Instance& instance)
: primal(QpVector(instance.num_var)),
rowactivity(QpVector(instance.num_con)),
dualvar(instance.num_var),
dualcon(instance.num_con),
status_var(instance.num_var),
status_con(instance.num_con) {}
};


struct QpHotstartInformation {
std::vector<HighsInt> active;
std::vector<HighsInt> inactive;
Expand All @@ -44,24 +44,27 @@ struct QpHotstartInformation {
: primal(QpVector(num_var)), rowact(QpVector(num_row)) {}
};

// the purpose of this is the pure algorithmic solution of a QP instance with given hotstart information.
// scenarios:
// 1) start from a given phase1 solution
// the purpose of this is the pure algorithmic solution of a QP instance with
// given hotstart information. scenarios: 1) start from a given phase1 solution
// 2) start from a user-given hotstart solution
// 3) start from a qp solution that was attained from a scaled instance and cleanup
// 4) start from a qp solution that was attained from a perturbed instance and cleanup
// 5) start from a qp solution and cleanup after recomputing basis and reduced hessian factorization
// 3) start from a qp solution that was attained from a scaled instance and
// cleanup 4) start from a qp solution that was attained from a perturbed
// instance and cleanup 5) start from a qp solution and cleanup after
// recomputing basis and reduced hessian factorization

std::string qpBasisStatusToString(const BasisStatus qp_basis_status);
std::string qpModelStatusToString(const QpModelStatus qp_model_status);
void assessQpPrimalFeasibility(const Instance& instance, const double primal_feasibility_tolerance,
const std::vector<double>& var_value, const std::vector<double>& con_value,
HighsInt& num_var_infeasibilities, double& max_var_infeasibility, double& sum_var_infeasibilities,
HighsInt& num_con_infeasibilities, double& max_con_infeasibility, double& sum_con_infeasibilities,
double& max_con_residual, double& sum_con_residuals);

QpAsmStatus solveqp_actual(Instance& instance, Settings& settings, QpHotstartInformation& startinfo, Statistics& stats, QpModelStatus& status, QpSolution& solution, HighsTimer& qp_timer);

void assessQpPrimalFeasibility(
const Instance& instance, const double primal_feasibility_tolerance,
const std::vector<double>& var_value, const std::vector<double>& con_value,
HighsInt& num_var_infeasibilities, double& max_var_infeasibility,
double& sum_var_infeasibilities, HighsInt& num_con_infeasibilities,
double& max_con_infeasibility, double& sum_con_infeasibilities,
double& max_con_residual, double& sum_con_residuals);

QpAsmStatus solveqp_actual(Instance& instance, Settings& settings,
QpHotstartInformation& startinfo, Statistics& stats,
QpModelStatus& status, QpSolution& solution,
HighsTimer& qp_timer);

#endif
Loading

0 comments on commit 2fc565a

Please sign in to comment.