lpsolver 0.1.0 → 0.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1165) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/README.md +70 -26
  4. data/ext/lpsolver/Makefile +273 -0
  5. data/ext/lpsolver/ext.c +353 -0
  6. data/ext/lpsolver/ext.o +0 -0
  7. data/ext/lpsolver/extconf.rb +79 -0
  8. data/ext/lpsolver/native.so +0 -0
  9. data/ext/lpsolver-highs/AUTHORS +7 -0
  10. data/ext/lpsolver-highs/BUILD.bazel +243 -0
  11. data/ext/lpsolver-highs/CITATION.cff +29 -0
  12. data/ext/lpsolver-highs/CMakeCache.txt +406 -0
  13. data/ext/lpsolver-highs/CMakeFiles/3.31.4/CMakeCCompiler.cmake +81 -0
  14. data/ext/lpsolver-highs/CMakeFiles/3.31.4/CMakeCXXCompiler.cmake +101 -0
  15. data/ext/lpsolver-highs/CMakeFiles/3.31.4/CMakeDetermineCompilerABI_C.bin +0 -0
  16. data/ext/lpsolver-highs/CMakeFiles/3.31.4/CMakeDetermineCompilerABI_CXX.bin +0 -0
  17. data/ext/lpsolver-highs/CMakeFiles/3.31.4/CMakeSystem.cmake +15 -0
  18. data/ext/lpsolver-highs/CMakeFiles/3.31.4/CompilerIdC/CMakeCCompilerId.c +904 -0
  19. data/ext/lpsolver-highs/CMakeFiles/3.31.4/CompilerIdC/a.out +0 -0
  20. data/ext/lpsolver-highs/CMakeFiles/3.31.4/CompilerIdCXX/CMakeCXXCompilerId.cpp +919 -0
  21. data/ext/lpsolver-highs/CMakeFiles/3.31.4/CompilerIdCXX/a.out +0 -0
  22. data/ext/lpsolver-highs/CMakeFiles/CMakeConfigureLog.yaml +576 -0
  23. data/ext/lpsolver-highs/CMakeFiles/cmake.check_cache +1 -0
  24. data/ext/lpsolver-highs/CMakeLists.txt +983 -0
  25. data/ext/lpsolver-highs/CODE_OF_CONDUCT.md +128 -0
  26. data/ext/lpsolver-highs/CONTRIBUTING.md +31 -0
  27. data/ext/lpsolver-highs/FEATURES.md +61 -0
  28. data/ext/lpsolver-highs/LICENSE.txt +21 -0
  29. data/ext/lpsolver-highs/MODULE.bazel +38 -0
  30. data/ext/lpsolver-highs/README.md +281 -0
  31. data/ext/lpsolver-highs/THIRD_PARTY_NOTICES.md +78 -0
  32. data/ext/lpsolver-highs/Version.txt +4 -0
  33. data/ext/lpsolver-highs/WORKSPACE +33 -0
  34. data/ext/lpsolver-highs/app/CMakeLists.txt +110 -0
  35. data/ext/lpsolver-highs/app/HighsRuntimeOptions.h +292 -0
  36. data/ext/lpsolver-highs/app/RunHighs.cpp +147 -0
  37. data/ext/lpsolver-highs/app/highs_webdemo_shell.html +73 -0
  38. data/ext/lpsolver-highs/build/bin/highs +0 -0
  39. data/ext/lpsolver-highs/build/include/highs/HConfig.h +22 -0
  40. data/ext/lpsolver-highs/build/include/highs/Highs.h +1812 -0
  41. data/ext/lpsolver-highs/build/include/highs/interfaces/highs_c_api.h +2651 -0
  42. data/ext/lpsolver-highs/build/include/highs/io/Filereader.h +45 -0
  43. data/ext/lpsolver-highs/build/include/highs/io/FilereaderLp.h +49 -0
  44. data/ext/lpsolver-highs/build/include/highs/io/FilereaderMps.h +27 -0
  45. data/ext/lpsolver-highs/build/include/highs/io/HMPSIO.h +78 -0
  46. data/ext/lpsolver-highs/build/include/highs/io/HMpsFF.h +245 -0
  47. data/ext/lpsolver-highs/build/include/highs/io/HighsIO.h +118 -0
  48. data/ext/lpsolver-highs/build/include/highs/io/LoadOptions.h +24 -0
  49. data/ext/lpsolver-highs/build/include/highs/io/filereaderlp/builder.hpp +25 -0
  50. data/ext/lpsolver-highs/build/include/highs/io/filereaderlp/def.hpp +19 -0
  51. data/ext/lpsolver-highs/build/include/highs/io/filereaderlp/model.hpp +68 -0
  52. data/ext/lpsolver-highs/build/include/highs/io/filereaderlp/reader.hpp +10 -0
  53. data/ext/lpsolver-highs/build/include/highs/ipm/IpxSolution.h +32 -0
  54. data/ext/lpsolver-highs/build/include/highs/ipm/IpxWrapper.h +106 -0
  55. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu.h +161 -0
  56. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_factorize.h +247 -0
  57. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_get_factors.h +108 -0
  58. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_initialize.h +119 -0
  59. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_factorize.h +34 -0
  60. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_free.h +19 -0
  61. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_get_factors.h +34 -0
  62. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_initialize.h +46 -0
  63. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_solve_dense.h +29 -0
  64. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_solve_for_update.h +42 -0
  65. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_solve_sparse.h +32 -0
  66. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_obj_update.h +31 -0
  67. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_object.h +30 -0
  68. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_solve_dense.h +75 -0
  69. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_solve_for_update.h +169 -0
  70. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_solve_sparse.h +112 -0
  71. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/basiclu_update.h +125 -0
  72. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/lu_def.h +39 -0
  73. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/lu_file.h +21 -0
  74. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/lu_internal.h +220 -0
  75. data/ext/lpsolver-highs/build/include/highs/ipm/basiclu/lu_list.h +173 -0
  76. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/basiclu_kernel.h +20 -0
  77. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/basiclu_wrapper.h +47 -0
  78. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/basis.h +350 -0
  79. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/conjugate_residuals.h +74 -0
  80. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/control.h +167 -0
  81. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/crossover.h +157 -0
  82. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/diagonal_precond.h +45 -0
  83. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/forrest_tomlin.h +102 -0
  84. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/guess_basis.h +21 -0
  85. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/indexed_vector.h +113 -0
  86. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/info.h +27 -0
  87. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipm.h +94 -0
  88. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipx_c.h +47 -0
  89. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipx_config.h +9 -0
  90. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipx_info.h +111 -0
  91. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipx_internal.h +89 -0
  92. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipx_parameters.h +76 -0
  93. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/ipx_status.h +57 -0
  94. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/iterate.h +331 -0
  95. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/kkt_solver.h +70 -0
  96. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/kkt_solver_basis.h +66 -0
  97. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/kkt_solver_diag.h +48 -0
  98. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/linear_operator.h +26 -0
  99. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/lp_solver.h +204 -0
  100. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/lu_factorization.h +79 -0
  101. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/lu_update.h +129 -0
  102. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/maxvolume.h +54 -0
  103. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/model.h +413 -0
  104. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/multistream.h +52 -0
  105. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/normal_matrix.h +44 -0
  106. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/power_method.h +44 -0
  107. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/sparse_matrix.h +195 -0
  108. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/sparse_utils.h +58 -0
  109. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/splitted_normal_matrix.h +63 -0
  110. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/starting_basis.h +39 -0
  111. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/symbolic_invert.h +29 -0
  112. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/timer.h +25 -0
  113. data/ext/lpsolver-highs/build/include/highs/ipm/ipx/utils.h +37 -0
  114. data/ext/lpsolver-highs/build/include/highs/lp_data/HConst.h +430 -0
  115. data/ext/lpsolver-highs/build/include/highs/lp_data/HStruct.h +213 -0
  116. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsAnalysis.h +23 -0
  117. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsCallback.h +104 -0
  118. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsCallbackStruct.h +70 -0
  119. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsDebug.h +34 -0
  120. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsIis.h +139 -0
  121. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsInfo.h +421 -0
  122. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsInfoDebug.h +27 -0
  123. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsLp.h +97 -0
  124. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsLpSolverObject.h +47 -0
  125. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsLpUtils.h +330 -0
  126. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsModelUtils.h +129 -0
  127. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsOptions.h +1715 -0
  128. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsRanging.h +43 -0
  129. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsSolution.h +179 -0
  130. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsSolutionDebug.h +87 -0
  131. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsSolve.h +29 -0
  132. data/ext/lpsolver-highs/build/include/highs/lp_data/HighsStatus.h +29 -0
  133. data/ext/lpsolver-highs/build/include/highs/mip/HighsCliqueTable.h +329 -0
  134. data/ext/lpsolver-highs/build/include/highs/mip/HighsConflictPool.h +109 -0
  135. data/ext/lpsolver-highs/build/include/highs/mip/HighsCutGeneration.h +108 -0
  136. data/ext/lpsolver-highs/build/include/highs/mip/HighsCutPool.h +168 -0
  137. data/ext/lpsolver-highs/build/include/highs/mip/HighsDebugSol.h +133 -0
  138. data/ext/lpsolver-highs/build/include/highs/mip/HighsDomain.h +657 -0
  139. data/ext/lpsolver-highs/build/include/highs/mip/HighsDomainChange.h +48 -0
  140. data/ext/lpsolver-highs/build/include/highs/mip/HighsDynamicRowMatrix.h +104 -0
  141. data/ext/lpsolver-highs/build/include/highs/mip/HighsGFkSolve.h +439 -0
  142. data/ext/lpsolver-highs/build/include/highs/mip/HighsImplications.h +194 -0
  143. data/ext/lpsolver-highs/build/include/highs/mip/HighsLpAggregator.h +50 -0
  144. data/ext/lpsolver-highs/build/include/highs/mip/HighsLpRelaxation.h +361 -0
  145. data/ext/lpsolver-highs/build/include/highs/mip/HighsMipAnalysis.h +71 -0
  146. data/ext/lpsolver-highs/build/include/highs/mip/HighsMipSolver.h +159 -0
  147. data/ext/lpsolver-highs/build/include/highs/mip/HighsMipSolverData.h +313 -0
  148. data/ext/lpsolver-highs/build/include/highs/mip/HighsModkSeparator.h +60 -0
  149. data/ext/lpsolver-highs/build/include/highs/mip/HighsNodeQueue.h +312 -0
  150. data/ext/lpsolver-highs/build/include/highs/mip/HighsObjectiveFunction.h +71 -0
  151. data/ext/lpsolver-highs/build/include/highs/mip/HighsPathSeparator.h +39 -0
  152. data/ext/lpsolver-highs/build/include/highs/mip/HighsPrimalHeuristics.h +75 -0
  153. data/ext/lpsolver-highs/build/include/highs/mip/HighsPseudocost.h +366 -0
  154. data/ext/lpsolver-highs/build/include/highs/mip/HighsRedcostFixing.h +42 -0
  155. data/ext/lpsolver-highs/build/include/highs/mip/HighsSearch.h +241 -0
  156. data/ext/lpsolver-highs/build/include/highs/mip/HighsSeparation.h +41 -0
  157. data/ext/lpsolver-highs/build/include/highs/mip/HighsSeparator.h +60 -0
  158. data/ext/lpsolver-highs/build/include/highs/mip/HighsTableauSeparator.h +34 -0
  159. data/ext/lpsolver-highs/build/include/highs/mip/HighsTransformedLp.h +63 -0
  160. data/ext/lpsolver-highs/build/include/highs/mip/MipTimer.h +544 -0
  161. data/ext/lpsolver-highs/build/include/highs/mip/feasibilityjump.hh +800 -0
  162. data/ext/lpsolver-highs/build/include/highs/model/HighsHessian.h +54 -0
  163. data/ext/lpsolver-highs/build/include/highs/model/HighsHessianUtils.h +47 -0
  164. data/ext/lpsolver-highs/build/include/highs/model/HighsModel.h +42 -0
  165. data/ext/lpsolver-highs/build/include/highs/parallel/HighsBinarySemaphore.h +108 -0
  166. data/ext/lpsolver-highs/build/include/highs/parallel/HighsCacheAlign.h +82 -0
  167. data/ext/lpsolver-highs/build/include/highs/parallel/HighsCombinable.h +116 -0
  168. data/ext/lpsolver-highs/build/include/highs/parallel/HighsMutex.h +124 -0
  169. data/ext/lpsolver-highs/build/include/highs/parallel/HighsParallel.h +128 -0
  170. data/ext/lpsolver-highs/build/include/highs/parallel/HighsRaceTimer.h +38 -0
  171. data/ext/lpsolver-highs/build/include/highs/parallel/HighsSchedulerConstants.h +19 -0
  172. data/ext/lpsolver-highs/build/include/highs/parallel/HighsSpinMutex.h +48 -0
  173. data/ext/lpsolver-highs/build/include/highs/parallel/HighsSplitDeque.h +606 -0
  174. data/ext/lpsolver-highs/build/include/highs/parallel/HighsTask.h +170 -0
  175. data/ext/lpsolver-highs/build/include/highs/parallel/HighsTaskExecutor.h +217 -0
  176. data/ext/lpsolver-highs/build/include/highs/pdlp/CupdlpWrapper.h +108 -0
  177. data/ext/lpsolver-highs/build/include/highs/pdlp/HiPdlpTimer.h +155 -0
  178. data/ext/lpsolver-highs/build/include/highs/pdlp/HiPdlpWrapper.h +26 -0
  179. data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_cs.h +40 -0
  180. data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_defs.h +447 -0
  181. data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_linalg.h +189 -0
  182. data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_proj.h +19 -0
  183. data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_restart.h +31 -0
  184. data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_scaling.h +26 -0
  185. data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_solver.h +105 -0
  186. data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_step.h +37 -0
  187. data/ext/lpsolver-highs/build/include/highs/pdlp/cupdlp/cupdlp_utils.c +1850 -0
  188. data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/defs.hpp +222 -0
  189. data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/linalg.hpp +61 -0
  190. data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/logger.hpp +80 -0
  191. data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/pdhg.hpp +358 -0
  192. data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/restart.hpp +96 -0
  193. data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/scaling.hpp +74 -0
  194. data/ext/lpsolver-highs/build/include/highs/pdlp/hipdlp/solver_results.hpp +65 -0
  195. data/ext/lpsolver-highs/build/include/highs/pdqsort/pdqsort.h +532 -0
  196. data/ext/lpsolver-highs/build/include/highs/presolve/HPresolve.h +505 -0
  197. data/ext/lpsolver-highs/build/include/highs/presolve/HPresolveAnalysis.h +52 -0
  198. data/ext/lpsolver-highs/build/include/highs/presolve/HighsPostsolveStack.h +943 -0
  199. data/ext/lpsolver-highs/build/include/highs/presolve/HighsSymmetry.h +284 -0
  200. data/ext/lpsolver-highs/build/include/highs/presolve/ICrash.h +124 -0
  201. data/ext/lpsolver-highs/build/include/highs/presolve/ICrashUtil.h +62 -0
  202. data/ext/lpsolver-highs/build/include/highs/presolve/ICrashX.h +23 -0
  203. data/ext/lpsolver-highs/build/include/highs/presolve/PresolveComponent.h +90 -0
  204. data/ext/lpsolver-highs/build/include/highs/qpsolver/a_asm.hpp +77 -0
  205. data/ext/lpsolver-highs/build/include/highs/qpsolver/a_quass.hpp +22 -0
  206. data/ext/lpsolver-highs/build/include/highs/qpsolver/basis.hpp +159 -0
  207. data/ext/lpsolver-highs/build/include/highs/qpsolver/crashsolution.hpp +20 -0
  208. data/ext/lpsolver-highs/build/include/highs/qpsolver/dantzigpricing.hpp +80 -0
  209. data/ext/lpsolver-highs/build/include/highs/qpsolver/devexpricing.hpp +108 -0
  210. data/ext/lpsolver-highs/build/include/highs/qpsolver/eventhandler.hpp +30 -0
  211. data/ext/lpsolver-highs/build/include/highs/qpsolver/factor.hpp +408 -0
  212. data/ext/lpsolver-highs/build/include/highs/qpsolver/feasibility_bounded.hpp +114 -0
  213. data/ext/lpsolver-highs/build/include/highs/qpsolver/feasibility_highs.hpp +301 -0
  214. data/ext/lpsolver-highs/build/include/highs/qpsolver/gradient.hpp +46 -0
  215. data/ext/lpsolver-highs/build/include/highs/qpsolver/instance.hpp +70 -0
  216. data/ext/lpsolver-highs/build/include/highs/qpsolver/matrix.hpp +342 -0
  217. data/ext/lpsolver-highs/build/include/highs/qpsolver/perturbation.hpp +15 -0
  218. data/ext/lpsolver-highs/build/include/highs/qpsolver/pricing.hpp +22 -0
  219. data/ext/lpsolver-highs/build/include/highs/qpsolver/qpconst.hpp +34 -0
  220. data/ext/lpsolver-highs/build/include/highs/qpsolver/qpvector.hpp +242 -0
  221. data/ext/lpsolver-highs/build/include/highs/qpsolver/quass.hpp +27 -0
  222. data/ext/lpsolver-highs/build/include/highs/qpsolver/ratiotest.hpp +26 -0
  223. data/ext/lpsolver-highs/build/include/highs/qpsolver/runtime.hpp +45 -0
  224. data/ext/lpsolver-highs/build/include/highs/qpsolver/scaling.hpp +15 -0
  225. data/ext/lpsolver-highs/build/include/highs/qpsolver/settings.hpp +84 -0
  226. data/ext/lpsolver-highs/build/include/highs/qpsolver/snippets.hpp +36 -0
  227. data/ext/lpsolver-highs/build/include/highs/qpsolver/statistics.hpp +30 -0
  228. data/ext/lpsolver-highs/build/include/highs/qpsolver/steepestedgepricing.hpp +173 -0
  229. data/ext/lpsolver-highs/build/include/highs/simplex/HApp.h +550 -0
  230. data/ext/lpsolver-highs/build/include/highs/simplex/HEkk.h +419 -0
  231. data/ext/lpsolver-highs/build/include/highs/simplex/HEkkDual.h +513 -0
  232. data/ext/lpsolver-highs/build/include/highs/simplex/HEkkDualRHS.h +134 -0
  233. data/ext/lpsolver-highs/build/include/highs/simplex/HEkkDualRow.h +201 -0
  234. data/ext/lpsolver-highs/build/include/highs/simplex/HEkkPrimal.h +191 -0
  235. data/ext/lpsolver-highs/build/include/highs/simplex/HSimplex.h +42 -0
  236. data/ext/lpsolver-highs/build/include/highs/simplex/HSimplexDebug.h +48 -0
  237. data/ext/lpsolver-highs/build/include/highs/simplex/HSimplexNla.h +158 -0
  238. data/ext/lpsolver-highs/build/include/highs/simplex/HSimplexReport.h +21 -0
  239. data/ext/lpsolver-highs/build/include/highs/simplex/HighsSimplexAnalysis.h +500 -0
  240. data/ext/lpsolver-highs/build/include/highs/simplex/SimplexConst.h +273 -0
  241. data/ext/lpsolver-highs/build/include/highs/simplex/SimplexStruct.h +263 -0
  242. data/ext/lpsolver-highs/build/include/highs/simplex/SimplexTimer.h +414 -0
  243. data/ext/lpsolver-highs/build/include/highs/test_kkt/DevKkt.h +143 -0
  244. data/ext/lpsolver-highs/build/include/highs/test_kkt/KktCh2.h +79 -0
  245. data/ext/lpsolver-highs/build/include/highs/util/FactorTimer.h +199 -0
  246. data/ext/lpsolver-highs/build/include/highs/util/HFactor.h +587 -0
  247. data/ext/lpsolver-highs/build/include/highs/util/HFactorConst.h +81 -0
  248. data/ext/lpsolver-highs/build/include/highs/util/HFactorDebug.h +55 -0
  249. data/ext/lpsolver-highs/build/include/highs/util/HSet.h +89 -0
  250. data/ext/lpsolver-highs/build/include/highs/util/HVector.h +22 -0
  251. data/ext/lpsolver-highs/build/include/highs/util/HVectorBase.h +102 -0
  252. data/ext/lpsolver-highs/build/include/highs/util/HighsCDouble.h +323 -0
  253. data/ext/lpsolver-highs/build/include/highs/util/HighsComponent.h +53 -0
  254. data/ext/lpsolver-highs/build/include/highs/util/HighsDataStack.h +83 -0
  255. data/ext/lpsolver-highs/build/include/highs/util/HighsDisjointSets.h +107 -0
  256. data/ext/lpsolver-highs/build/include/highs/util/HighsHash.h +1274 -0
  257. data/ext/lpsolver-highs/build/include/highs/util/HighsHashTree.h +1461 -0
  258. data/ext/lpsolver-highs/build/include/highs/util/HighsInt.h +36 -0
  259. data/ext/lpsolver-highs/build/include/highs/util/HighsIntegers.h +212 -0
  260. data/ext/lpsolver-highs/build/include/highs/util/HighsLinearSumBounds.h +203 -0
  261. data/ext/lpsolver-highs/build/include/highs/util/HighsMatrixPic.h +37 -0
  262. data/ext/lpsolver-highs/build/include/highs/util/HighsMatrixSlice.h +561 -0
  263. data/ext/lpsolver-highs/build/include/highs/util/HighsMatrixUtils.h +57 -0
  264. data/ext/lpsolver-highs/build/include/highs/util/HighsMemoryAllocation.h +63 -0
  265. data/ext/lpsolver-highs/build/include/highs/util/HighsRandom.h +242 -0
  266. data/ext/lpsolver-highs/build/include/highs/util/HighsRbTree.h +452 -0
  267. data/ext/lpsolver-highs/build/include/highs/util/HighsSort.h +131 -0
  268. data/ext/lpsolver-highs/build/include/highs/util/HighsSparseMatrix.h +151 -0
  269. data/ext/lpsolver-highs/build/include/highs/util/HighsSparseVectorSum.h +95 -0
  270. data/ext/lpsolver-highs/build/include/highs/util/HighsSplay.h +135 -0
  271. data/ext/lpsolver-highs/build/include/highs/util/HighsTimer.h +385 -0
  272. data/ext/lpsolver-highs/build/include/highs/util/HighsUtils.h +272 -0
  273. data/ext/lpsolver-highs/build/include/highs/util/stringutil.h +46 -0
  274. data/ext/lpsolver-highs/build/include/highs/zstr/strict_fstream.hpp +237 -0
  275. data/ext/lpsolver-highs/build/include/highs/zstr/zstr.hpp +473 -0
  276. data/ext/lpsolver-highs/build/include/highs_export.h +43 -0
  277. data/ext/lpsolver-highs/build/lib/cmake/highs/highs-config-version.cmake +65 -0
  278. data/ext/lpsolver-highs/build/lib/cmake/highs/highs-config.cmake +36 -0
  279. data/ext/lpsolver-highs/build/lib/cmake/highs/highs-targets-release.cmake +19 -0
  280. data/ext/lpsolver-highs/build/lib/cmake/highs/highs-targets.cmake +111 -0
  281. data/ext/lpsolver-highs/build/lib/libhighs.a +0 -0
  282. data/ext/lpsolver-highs/build/lib/pkgconfig/highs.pc +12 -0
  283. data/ext/lpsolver-highs/build/share/doc/HIGHS/AUTHORS +7 -0
  284. data/ext/lpsolver-highs/build/share/doc/HIGHS/CITATION.cff +29 -0
  285. data/ext/lpsolver-highs/build/share/doc/HIGHS/CODE_OF_CONDUCT.md +128 -0
  286. data/ext/lpsolver-highs/build/share/doc/HIGHS/CONTRIBUTING.md +31 -0
  287. data/ext/lpsolver-highs/build/share/doc/HIGHS/FEATURES.md +61 -0
  288. data/ext/lpsolver-highs/build/share/doc/HIGHS/LICENSE.txt +21 -0
  289. data/ext/lpsolver-highs/build/share/doc/HIGHS/README.md +281 -0
  290. data/ext/lpsolver-highs/build_webdemo.sh +46 -0
  291. data/ext/lpsolver-highs/check/Avgas.cpp +245 -0
  292. data/ext/lpsolver-highs/check/Avgas.h +44 -0
  293. data/ext/lpsolver-highs/check/CMakeLists.txt +573 -0
  294. data/ext/lpsolver-highs/check/HCheckConfig.h.bazel.in +6 -0
  295. data/ext/lpsolver-highs/check/HCheckConfig.h.in +12 -0
  296. data/ext/lpsolver-highs/check/HCheckConfig.h.meson.in +6 -0
  297. data/ext/lpsolver-highs/check/SpecialLps.h +405 -0
  298. data/ext/lpsolver-highs/check/TestAlienBasis.cpp +720 -0
  299. data/ext/lpsolver-highs/check/TestBasis.cpp +359 -0
  300. data/ext/lpsolver-highs/check/TestBasisSolves.cpp +669 -0
  301. data/ext/lpsolver-highs/check/TestCAPI.c +2513 -0
  302. data/ext/lpsolver-highs/check/TestCallbacks.cpp +608 -0
  303. data/ext/lpsolver-highs/check/TestCheckSolution.cpp +740 -0
  304. data/ext/lpsolver-highs/check/TestCrossover.cpp +111 -0
  305. data/ext/lpsolver-highs/check/TestDualize.cpp +172 -0
  306. data/ext/lpsolver-highs/check/TestEkk.cpp +100 -0
  307. data/ext/lpsolver-highs/check/TestFactor.cpp +389 -0
  308. data/ext/lpsolver-highs/check/TestFilereader.cpp +568 -0
  309. data/ext/lpsolver-highs/check/TestFortranAPI.f90 +65 -0
  310. data/ext/lpsolver-highs/check/TestHSet.cpp +80 -0
  311. data/ext/lpsolver-highs/check/TestHighsCDouble.cpp +109 -0
  312. data/ext/lpsolver-highs/check/TestHighsGFkSolve.cpp +102 -0
  313. data/ext/lpsolver-highs/check/TestHighsHash.cpp +126 -0
  314. data/ext/lpsolver-highs/check/TestHighsHessian.cpp +329 -0
  315. data/ext/lpsolver-highs/check/TestHighsIntegers.cpp +42 -0
  316. data/ext/lpsolver-highs/check/TestHighsModel.cpp +134 -0
  317. data/ext/lpsolver-highs/check/TestHighsParallel.cpp +277 -0
  318. data/ext/lpsolver-highs/check/TestHighsRbTree.cpp +109 -0
  319. data/ext/lpsolver-highs/check/TestHighsSparseMatrix.cpp +126 -0
  320. data/ext/lpsolver-highs/check/TestHighsVersion.cpp +61 -0
  321. data/ext/lpsolver-highs/check/TestHipo.cpp +122 -0
  322. data/ext/lpsolver-highs/check/TestICrash.cpp +46 -0
  323. data/ext/lpsolver-highs/check/TestIO.cpp +163 -0
  324. data/ext/lpsolver-highs/check/TestIis.cpp +1063 -0
  325. data/ext/lpsolver-highs/check/TestInfo.cpp +116 -0
  326. data/ext/lpsolver-highs/check/TestIpm.cpp +226 -0
  327. data/ext/lpsolver-highs/check/TestIpx.cpp +96 -0
  328. data/ext/lpsolver-highs/check/TestLPFileFormat.cpp +22 -0
  329. data/ext/lpsolver-highs/check/TestLogging.cpp +69 -0
  330. data/ext/lpsolver-highs/check/TestLpModification.cpp +2497 -0
  331. data/ext/lpsolver-highs/check/TestLpOrientation.cpp +121 -0
  332. data/ext/lpsolver-highs/check/TestLpSolvers.cpp +555 -0
  333. data/ext/lpsolver-highs/check/TestLpValidation.cpp +689 -0
  334. data/ext/lpsolver-highs/check/TestMain.cpp +6 -0
  335. data/ext/lpsolver-highs/check/TestMipSolver.cpp +1406 -0
  336. data/ext/lpsolver-highs/check/TestModelProperties.cpp +143 -0
  337. data/ext/lpsolver-highs/check/TestMultiObjective.cpp +198 -0
  338. data/ext/lpsolver-highs/check/TestNames.cpp +187 -0
  339. data/ext/lpsolver-highs/check/TestOptions.cpp +544 -0
  340. data/ext/lpsolver-highs/check/TestPdlp.cpp +327 -0
  341. data/ext/lpsolver-highs/check/TestPdlpHi.cpp +40 -0
  342. data/ext/lpsolver-highs/check/TestPresolve.cpp +912 -0
  343. data/ext/lpsolver-highs/check/TestQpSolver.cpp +1345 -0
  344. data/ext/lpsolver-highs/check/TestRanging.cpp +558 -0
  345. data/ext/lpsolver-highs/check/TestRays.cpp +1010 -0
  346. data/ext/lpsolver-highs/check/TestSemiVariables.cpp +329 -0
  347. data/ext/lpsolver-highs/check/TestSetup.cpp +12 -0
  348. data/ext/lpsolver-highs/check/TestSort.cpp +247 -0
  349. data/ext/lpsolver-highs/check/TestSpecialLps.cpp +775 -0
  350. data/ext/lpsolver-highs/check/TestThrow.cpp +83 -0
  351. data/ext/lpsolver-highs/check/TestTspSolver.cpp +19 -0
  352. data/ext/lpsolver-highs/check/TestUserScale.cpp +444 -0
  353. data/ext/lpsolver-highs/check/cublas_example.cpp +76 -0
  354. data/ext/lpsolver-highs/check/cublas_gpu_start.cpp +88 -0
  355. data/ext/lpsolver-highs/check/hipo_test_option_files/hipo_options_0 +1 -0
  356. data/ext/lpsolver-highs/check/instances/1448.lp +1 -0
  357. data/ext/lpsolver-highs/check/instances/1449a.lp +1 -0
  358. data/ext/lpsolver-highs/check/instances/1449b.lp +1 -0
  359. data/ext/lpsolver-highs/check/instances/1451.lp +8 -0
  360. data/ext/lpsolver-highs/check/instances/2122.lp +1822 -0
  361. data/ext/lpsolver-highs/check/instances/2171.mps +717 -0
  362. data/ext/lpsolver-highs/check/instances/25fv47.mps +6919 -0
  363. data/ext/lpsolver-highs/check/instances/2821-duplicate.mps +31 -0
  364. data/ext/lpsolver-highs/check/instances/2821-qmatrix.mps +31 -0
  365. data/ext/lpsolver-highs/check/instances/2821-quadobj.mps +29 -0
  366. data/ext/lpsolver-highs/check/instances/2821-summation.mps +30 -0
  367. data/ext/lpsolver-highs/check/instances/2821.mps +29 -0
  368. data/ext/lpsolver-highs/check/instances/2894.mps +89 -0
  369. data/ext/lpsolver-highs/check/instances/80bau3b.mps +23732 -0
  370. data/ext/lpsolver-highs/check/instances/WithInf.set +3 -0
  371. data/ext/lpsolver-highs/check/instances/adlittle.mps +335 -0
  372. data/ext/lpsolver-highs/check/instances/afiro.mps +83 -0
  373. data/ext/lpsolver-highs/check/instances/avgas.mps +51 -0
  374. data/ext/lpsolver-highs/check/instances/bell5.mps +384 -0
  375. data/ext/lpsolver-highs/check/instances/bgetam.mps +2112 -0
  376. data/ext/lpsolver-highs/check/instances/blending.mps +13 -0
  377. data/ext/lpsolver-highs/check/instances/box1.mps +1085 -0
  378. data/ext/lpsolver-highs/check/instances/chip.mps +13 -0
  379. data/ext/lpsolver-highs/check/instances/comment.mps +23 -0
  380. data/ext/lpsolver-highs/check/instances/cplex1.mps +9674 -0
  381. data/ext/lpsolver-highs/check/instances/dD2e.mps +10 -0
  382. data/ext/lpsolver-highs/check/instances/dcmulti.mps +2310 -0
  383. data/ext/lpsolver-highs/check/instances/e226.mps +1733 -0
  384. data/ext/lpsolver-highs/check/instances/egout-ac.mps +473 -0
  385. data/ext/lpsolver-highs/check/instances/egout.mps +403 -0
  386. data/ext/lpsolver-highs/check/instances/etamacro.mps +2084 -0
  387. data/ext/lpsolver-highs/check/instances/ex72a.mps +849 -0
  388. data/ext/lpsolver-highs/check/instances/fixed-binary.lp +11 -0
  389. data/ext/lpsolver-highs/check/instances/flugpl.mps +111 -0
  390. data/ext/lpsolver-highs/check/instances/flugpl_illegal_integer.sol +24 -0
  391. data/ext/lpsolver-highs/check/instances/flugpl_integer.sol +25 -0
  392. data/ext/lpsolver-highs/check/instances/forest6.mps +261 -0
  393. data/ext/lpsolver-highs/check/instances/galenet.mps +34 -0
  394. data/ext/lpsolver-highs/check/instances/gams10am.mps +478 -0
  395. data/ext/lpsolver-highs/check/instances/garbage.ems +3 -0
  396. data/ext/lpsolver-highs/check/instances/garbage.lp +3 -0
  397. data/ext/lpsolver-highs/check/instances/garbage.mps +3 -0
  398. data/ext/lpsolver-highs/check/instances/gas11.mps +2924 -0
  399. data/ext/lpsolver-highs/check/instances/gesa2.mps +5459 -0
  400. data/ext/lpsolver-highs/check/instances/greenbea.mps +19215 -0
  401. data/ext/lpsolver-highs/check/instances/gt2.mps +534 -0
  402. data/ext/lpsolver-highs/check/instances/infeasible-mip0.mps +140 -0
  403. data/ext/lpsolver-highs/check/instances/infeasible-mip1.mps +371 -0
  404. data/ext/lpsolver-highs/check/instances/israel.mps +1490 -0
  405. data/ext/lpsolver-highs/check/instances/issue-2095.mps +836 -0
  406. data/ext/lpsolver-highs/check/instances/issue-2173.mps +3331 -0
  407. data/ext/lpsolver-highs/check/instances/issue-2204.mps +143 -0
  408. data/ext/lpsolver-highs/check/instances/issue-2290.mps +158 -0
  409. data/ext/lpsolver-highs/check/instances/issue-2388.lp +76 -0
  410. data/ext/lpsolver-highs/check/instances/issue-2402.mps +435 -0
  411. data/ext/lpsolver-highs/check/instances/issue-2446.mps +9154 -0
  412. data/ext/lpsolver-highs/check/instances/issue-2585.lp +16 -0
  413. data/ext/lpsolver-highs/check/instances/issue-2874-3.mps +97 -0
  414. data/ext/lpsolver-highs/check/instances/klein1.mps +422 -0
  415. data/ext/lpsolver-highs/check/instances/lseu.mps +371 -0
  416. data/ext/lpsolver-highs/check/instances/model.xyz +1 -0
  417. data/ext/lpsolver-highs/check/instances/nan0.mps +13 -0
  418. data/ext/lpsolver-highs/check/instances/nan1.mps +13 -0
  419. data/ext/lpsolver-highs/check/instances/nan2.mps +13 -0
  420. data/ext/lpsolver-highs/check/instances/no-newline-eof.lp +5 -0
  421. data/ext/lpsolver-highs/check/instances/p01.mps +909 -0
  422. data/ext/lpsolver-highs/check/instances/p0548.mps +1992 -0
  423. data/ext/lpsolver-highs/check/instances/primal1.mps +3909 -0
  424. data/ext/lpsolver-highs/check/instances/qap04.mps +606 -0
  425. data/ext/lpsolver-highs/check/instances/qcqp.lp +8 -0
  426. data/ext/lpsolver-highs/check/instances/qjh.lp +9 -0
  427. data/ext/lpsolver-highs/check/instances/qjh.mps +18 -0
  428. data/ext/lpsolver-highs/check/instances/qjh_qmatrix.mps +19 -0
  429. data/ext/lpsolver-highs/check/instances/qjh_quadobj.mps +18 -0
  430. data/ext/lpsolver-highs/check/instances/qjh_quadobj_qmatrix.mps +25 -0
  431. data/ext/lpsolver-highs/check/instances/qjh_uncon.lp +10 -0
  432. data/ext/lpsolver-highs/check/instances/qjh_uncon.mps +17 -0
  433. data/ext/lpsolver-highs/check/instances/qpinfeasible.lp +8 -0
  434. data/ext/lpsolver-highs/check/instances/qptestnw.lp +7 -0
  435. data/ext/lpsolver-highs/check/instances/qpunbounded.lp +5 -0
  436. data/ext/lpsolver-highs/check/instances/refinery.mps +1882 -0
  437. data/ext/lpsolver-highs/check/instances/rgn.mps +559 -0
  438. data/ext/lpsolver-highs/check/instances/scrs8.mps +2717 -0
  439. data/ext/lpsolver-highs/check/instances/sctest.mps +66 -0
  440. data/ext/lpsolver-highs/check/instances/semi-continuous.lp +13 -0
  441. data/ext/lpsolver-highs/check/instances/semi-continuous.mps +24 -0
  442. data/ext/lpsolver-highs/check/instances/semi-integer.lp +15 -0
  443. data/ext/lpsolver-highs/check/instances/semi-integer.mps +22 -0
  444. data/ext/lpsolver-highs/check/instances/shell.mps +4039 -0
  445. data/ext/lpsolver-highs/check/instances/silly-names.mps +14 -0
  446. data/ext/lpsolver-highs/check/instances/small_mip.mps +87 -0
  447. data/ext/lpsolver-highs/check/instances/smalllp.mps +21 -0
  448. data/ext/lpsolver-highs/check/instances/sp150x300d.mps +1983 -0
  449. data/ext/lpsolver-highs/check/instances/stair.mps +2499 -0
  450. data/ext/lpsolver-highs/check/instances/standata.mps +2317 -0
  451. data/ext/lpsolver-highs/check/instances/standgub.mps +2428 -0
  452. data/ext/lpsolver-highs/check/instances/standmps.mps +2695 -0
  453. data/ext/lpsolver-highs/check/instances/test.mps +53 -0
  454. data/ext/lpsolver-highs/check/instances/vol1.mps +1895 -0
  455. data/ext/lpsolver-highs/check/instances/warnings.mps +68 -0
  456. data/ext/lpsolver-highs/check/instances/woodinfe.mps +216 -0
  457. data/ext/lpsolver-highs/check/matrix_multiplication.hpp +49 -0
  458. data/ext/lpsolver-highs/check/meson.build +92 -0
  459. data/ext/lpsolver-highs/check/pythontest.py +11 -0
  460. data/ext/lpsolver-highs/check/sample_options_file +8 -0
  461. data/ext/lpsolver-highs/cmake/CheckAtomic.cmake +74 -0
  462. data/ext/lpsolver-highs/cmake/FindCUDAConf.cmake +44 -0
  463. data/ext/lpsolver-highs/cmake/FindHipoDeps.cmake +351 -0
  464. data/ext/lpsolver-highs/cmake/README.md +243 -0
  465. data/ext/lpsolver-highs/cmake/cpp-highs.cmake +243 -0
  466. data/ext/lpsolver-highs/cmake/dotnet.cmake +94 -0
  467. data/ext/lpsolver-highs/cmake/highs-config.cmake.in +22 -0
  468. data/ext/lpsolver-highs/cmake/python-highs.cmake +74 -0
  469. data/ext/lpsolver-highs/cmake/set-version.cmake +26 -0
  470. data/ext/lpsolver-highs/cmake/sources-python.cmake +461 -0
  471. data/ext/lpsolver-highs/cmake/sources.cmake +618 -0
  472. data/ext/lpsolver-highs/docs/HiGHS_CopyrightHeader.pl +78 -0
  473. data/ext/lpsolver-highs/docs/HiGHS_CopyrightHeaderUpdateAll +32 -0
  474. data/ext/lpsolver-highs/docs/Project.toml +7 -0
  475. data/ext/lpsolver-highs/docs/README.md +27 -0
  476. data/ext/lpsolver-highs/docs/c_api_gen/HConfig.h +1 -0
  477. data/ext/lpsolver-highs/docs/c_api_gen/build.jl +48 -0
  478. data/ext/lpsolver-highs/docs/make.jl +115 -0
  479. data/ext/lpsolver-highs/docs/src/assets/logo.png +0 -0
  480. data/ext/lpsolver-highs/docs/src/callbacks.md +171 -0
  481. data/ext/lpsolver-highs/docs/src/executable.md +88 -0
  482. data/ext/lpsolver-highs/docs/src/guide/advanced.md +66 -0
  483. data/ext/lpsolver-highs/docs/src/guide/basic.md +116 -0
  484. data/ext/lpsolver-highs/docs/src/guide/further.md +193 -0
  485. data/ext/lpsolver-highs/docs/src/guide/gpu.md +58 -0
  486. data/ext/lpsolver-highs/docs/src/guide/index.md +18 -0
  487. data/ext/lpsolver-highs/docs/src/guide/kkt.md +219 -0
  488. data/ext/lpsolver-highs/docs/src/guide/numerics.md +55 -0
  489. data/ext/lpsolver-highs/docs/src/index.md +86 -0
  490. data/ext/lpsolver-highs/docs/src/installation.md +130 -0
  491. data/ext/lpsolver-highs/docs/src/interfaces/c_api.md +6 -0
  492. data/ext/lpsolver-highs/docs/src/interfaces/cpp/examples.md +1 -0
  493. data/ext/lpsolver-highs/docs/src/interfaces/cpp/index.md +29 -0
  494. data/ext/lpsolver-highs/docs/src/interfaces/cpp/library.md +107 -0
  495. data/ext/lpsolver-highs/docs/src/interfaces/csharp.md +55 -0
  496. data/ext/lpsolver-highs/docs/src/interfaces/fortran.md +11 -0
  497. data/ext/lpsolver-highs/docs/src/interfaces/julia/index.md +130 -0
  498. data/ext/lpsolver-highs/docs/src/interfaces/other.md +41 -0
  499. data/ext/lpsolver-highs/docs/src/interfaces/python/example-py.md +275 -0
  500. data/ext/lpsolver-highs/docs/src/interfaces/python/index.md +91 -0
  501. data/ext/lpsolver-highs/docs/src/interfaces/python/model-py.md +90 -0
  502. data/ext/lpsolver-highs/docs/src/options/definitions.md +529 -0
  503. data/ext/lpsolver-highs/docs/src/options/intro.md +46 -0
  504. data/ext/lpsolver-highs/docs/src/parallel.md +88 -0
  505. data/ext/lpsolver-highs/docs/src/solvers.md +168 -0
  506. data/ext/lpsolver-highs/docs/src/structures/classes/HighsHessian.md +9 -0
  507. data/ext/lpsolver-highs/docs/src/structures/classes/HighsIis.md +16 -0
  508. data/ext/lpsolver-highs/docs/src/structures/classes/HighsLp.md +19 -0
  509. data/ext/lpsolver-highs/docs/src/structures/classes/HighsModel.md +6 -0
  510. data/ext/lpsolver-highs/docs/src/structures/classes/HighsSparseMatrix.md +10 -0
  511. data/ext/lpsolver-highs/docs/src/structures/classes/index.md +11 -0
  512. data/ext/lpsolver-highs/docs/src/structures/enums.md +114 -0
  513. data/ext/lpsolver-highs/docs/src/structures/index.md +12 -0
  514. data/ext/lpsolver-highs/docs/src/structures/structs/HighsBasis.md +8 -0
  515. data/ext/lpsolver-highs/docs/src/structures/structs/HighsInfo.md +148 -0
  516. data/ext/lpsolver-highs/docs/src/structures/structs/HighsLinearObjective.md +11 -0
  517. data/ext/lpsolver-highs/docs/src/structures/structs/HighsSolution.md +10 -0
  518. data/ext/lpsolver-highs/docs/src/structures/structs/index.md +10 -0
  519. data/ext/lpsolver-highs/docs/src/terminology.md +163 -0
  520. data/ext/lpsolver-highs/examples/CMakeLists.txt +26 -0
  521. data/ext/lpsolver-highs/examples/Docs.py +104 -0
  522. data/ext/lpsolver-highs/examples/branch-and-price.py +465 -0
  523. data/ext/lpsolver-highs/examples/call_highs_from_c.c +685 -0
  524. data/ext/lpsolver-highs/examples/call_highs_from_c_minimal.c +659 -0
  525. data/ext/lpsolver-highs/examples/call_highs_from_cpp.cpp +178 -0
  526. data/ext/lpsolver-highs/examples/call_highs_from_csharp.cs +83 -0
  527. data/ext/lpsolver-highs/examples/call_highs_from_fortran.f90 +579 -0
  528. data/ext/lpsolver-highs/examples/call_highs_from_python.py +448 -0
  529. data/ext/lpsolver-highs/examples/call_highs_from_python_highspy.py +71 -0
  530. data/ext/lpsolver-highs/examples/call_highs_from_python_mps.py +59 -0
  531. data/ext/lpsolver-highs/examples/callback_gap.py +71 -0
  532. data/ext/lpsolver-highs/examples/chip.py +43 -0
  533. data/ext/lpsolver-highs/examples/chip0.py +29 -0
  534. data/ext/lpsolver-highs/examples/distillation.py +77 -0
  535. data/ext/lpsolver-highs/examples/knapsack.py +43 -0
  536. data/ext/lpsolver-highs/examples/minimal.py +11 -0
  537. data/ext/lpsolver-highs/examples/multi_objective.py +139 -0
  538. data/ext/lpsolver-highs/examples/multiple_objective.py +120 -0
  539. data/ext/lpsolver-highs/examples/network_flow.py +37 -0
  540. data/ext/lpsolver-highs/examples/nqueens.py +29 -0
  541. data/ext/lpsolver-highs/examples/plot_highs_log.py +134 -0
  542. data/ext/lpsolver-highs/extern/CLI11.hpp +11546 -0
  543. data/ext/lpsolver-highs/extern/LICENCE_1_0.txt +23 -0
  544. data/ext/lpsolver-highs/extern/amd/License.txt +35 -0
  545. data/ext/lpsolver-highs/extern/amd/SuiteSparse_config.c +54 -0
  546. data/ext/lpsolver-highs/extern/amd/SuiteSparse_config.h +56 -0
  547. data/ext/lpsolver-highs/extern/amd/amd.h +357 -0
  548. data/ext/lpsolver-highs/extern/amd/amd_1.c +172 -0
  549. data/ext/lpsolver-highs/extern/amd/amd_2.c +1761 -0
  550. data/ext/lpsolver-highs/extern/amd/amd_aat.c +179 -0
  551. data/ext/lpsolver-highs/extern/amd/amd_control.c +65 -0
  552. data/ext/lpsolver-highs/extern/amd/amd_defaults.c +37 -0
  553. data/ext/lpsolver-highs/extern/amd/amd_info.c +120 -0
  554. data/ext/lpsolver-highs/extern/amd/amd_internal.h +137 -0
  555. data/ext/lpsolver-highs/extern/amd/amd_order.c +195 -0
  556. data/ext/lpsolver-highs/extern/amd/amd_post_tree.c +105 -0
  557. data/ext/lpsolver-highs/extern/amd/amd_postorder.c +140 -0
  558. data/ext/lpsolver-highs/extern/amd/amd_preprocess.c +107 -0
  559. data/ext/lpsolver-highs/extern/amd/amd_valid.c +93 -0
  560. data/ext/lpsolver-highs/extern/amd/changes.txt +8 -0
  561. data/ext/lpsolver-highs/extern/catch.hpp +18861 -0
  562. data/ext/lpsolver-highs/extern/metis/Changes.txt +31 -0
  563. data/ext/lpsolver-highs/extern/metis/GKlib/GKlib.h +62 -0
  564. data/ext/lpsolver-highs/extern/metis/GKlib/error.c +21 -0
  565. data/ext/lpsolver-highs/extern/metis/GKlib/gk_arch.h +64 -0
  566. data/ext/lpsolver-highs/extern/metis/GKlib/gk_defs.h +19 -0
  567. data/ext/lpsolver-highs/extern/metis/GKlib/gk_macros.h +50 -0
  568. data/ext/lpsolver-highs/extern/metis/GKlib/gk_mkblas.h +51 -0
  569. data/ext/lpsolver-highs/extern/metis/GKlib/gk_mkmemory.h +80 -0
  570. data/ext/lpsolver-highs/extern/metis/GKlib/gk_mkpqueue.h +329 -0
  571. data/ext/lpsolver-highs/extern/metis/GKlib/gk_mkrandom.h +89 -0
  572. data/ext/lpsolver-highs/extern/metis/GKlib/gk_mksort.h +271 -0
  573. data/ext/lpsolver-highs/extern/metis/GKlib/gk_ms_inttypes.h +41 -0
  574. data/ext/lpsolver-highs/extern/metis/GKlib/gk_ms_stat.h +22 -0
  575. data/ext/lpsolver-highs/extern/metis/GKlib/gk_ms_stdint.h +41 -0
  576. data/ext/lpsolver-highs/extern/metis/GKlib/gk_proto.h +50 -0
  577. data/ext/lpsolver-highs/extern/metis/GKlib/gk_struct.h +66 -0
  578. data/ext/lpsolver-highs/extern/metis/GKlib/gk_types.h +15 -0
  579. data/ext/lpsolver-highs/extern/metis/GKlib/mcore.c +176 -0
  580. data/ext/lpsolver-highs/extern/metis/GKlib/memory.c +23 -0
  581. data/ext/lpsolver-highs/extern/metis/GKlib/random.c +37 -0
  582. data/ext/lpsolver-highs/extern/metis/LICENSE.txt +18 -0
  583. data/ext/lpsolver-highs/extern/metis/libmetis/auxapi.c +27 -0
  584. data/ext/lpsolver-highs/extern/metis/libmetis/balance.c +491 -0
  585. data/ext/lpsolver-highs/extern/metis/libmetis/bucketsort.c +44 -0
  586. data/ext/lpsolver-highs/extern/metis/libmetis/coarsen.c +895 -0
  587. data/ext/lpsolver-highs/extern/metis/libmetis/compress.c +231 -0
  588. data/ext/lpsolver-highs/extern/metis/libmetis/contig.c +83 -0
  589. data/ext/lpsolver-highs/extern/metis/libmetis/defs.h +39 -0
  590. data/ext/lpsolver-highs/extern/metis/libmetis/fm.c +527 -0
  591. data/ext/lpsolver-highs/extern/metis/libmetis/gklib.c +55 -0
  592. data/ext/lpsolver-highs/extern/metis/libmetis/gklib_defs.h +33 -0
  593. data/ext/lpsolver-highs/extern/metis/libmetis/graph.c +268 -0
  594. data/ext/lpsolver-highs/extern/metis/libmetis/initpart.c +385 -0
  595. data/ext/lpsolver-highs/extern/metis/libmetis/macros.h +59 -0
  596. data/ext/lpsolver-highs/extern/metis/libmetis/mcutil.c +162 -0
  597. data/ext/lpsolver-highs/extern/metis/libmetis/metislib.h +35 -0
  598. data/ext/lpsolver-highs/extern/metis/libmetis/mmd.c +598 -0
  599. data/ext/lpsolver-highs/extern/metis/libmetis/ometis.c +661 -0
  600. data/ext/lpsolver-highs/extern/metis/libmetis/options.c +260 -0
  601. data/ext/lpsolver-highs/extern/metis/libmetis/proto.h +172 -0
  602. data/ext/lpsolver-highs/extern/metis/libmetis/refine.c +99 -0
  603. data/ext/lpsolver-highs/extern/metis/libmetis/separator.c +57 -0
  604. data/ext/lpsolver-highs/extern/metis/libmetis/sfm.c +581 -0
  605. data/ext/lpsolver-highs/extern/metis/libmetis/srefine.c +152 -0
  606. data/ext/lpsolver-highs/extern/metis/libmetis/stdheaders.h +29 -0
  607. data/ext/lpsolver-highs/extern/metis/libmetis/struct.h +117 -0
  608. data/ext/lpsolver-highs/extern/metis/libmetis/util.c +59 -0
  609. data/ext/lpsolver-highs/extern/metis/libmetis/wspace.c +91 -0
  610. data/ext/lpsolver-highs/extern/metis/metis.h +271 -0
  611. data/ext/lpsolver-highs/extern/pdqsort/license.txt +16 -0
  612. data/ext/lpsolver-highs/extern/pdqsort/pdqsort.h +532 -0
  613. data/ext/lpsolver-highs/extern/rcm/LICENSE +19 -0
  614. data/ext/lpsolver-highs/extern/rcm/rcm.cpp +873 -0
  615. data/ext/lpsolver-highs/extern/rcm/rcm.h +22 -0
  616. data/ext/lpsolver-highs/extern/zstr/LICENSE +21 -0
  617. data/ext/lpsolver-highs/extern/zstr/strict_fstream.hpp +237 -0
  618. data/ext/lpsolver-highs/extern/zstr/zstr.hpp +473 -0
  619. data/ext/lpsolver-highs/flake.lock +61 -0
  620. data/ext/lpsolver-highs/flake.nix +73 -0
  621. data/ext/lpsolver-highs/highs/CMakeLists.txt +499 -0
  622. data/ext/lpsolver-highs/highs/HConfig.h.bazel.in +25 -0
  623. data/ext/lpsolver-highs/highs/HConfig.h.in +22 -0
  624. data/ext/lpsolver-highs/highs/HConfig.h.meson.in +17 -0
  625. data/ext/lpsolver-highs/highs/Highs.h +1812 -0
  626. data/ext/lpsolver-highs/highs/HighsRun.md +143 -0
  627. data/ext/lpsolver-highs/highs/highs_bindings.cpp +1826 -0
  628. data/ext/lpsolver-highs/highs/highspy/__init__.py +93 -0
  629. data/ext/lpsolver-highs/highs/highspy/__init__.pyi +91 -0
  630. data/ext/lpsolver-highs/highs/highspy/_core/__init__.pyi +1058 -0
  631. data/ext/lpsolver-highs/highs/highspy/_core/cb.pyi +118 -0
  632. data/ext/lpsolver-highs/highs/highspy/_core/simplex_constants.pyi +472 -0
  633. data/ext/lpsolver-highs/highs/highspy/highs.py +2430 -0
  634. data/ext/lpsolver-highs/highs/interfaces/highs_c_api.cpp +1812 -0
  635. data/ext/lpsolver-highs/highs/interfaces/highs_c_api.h +2651 -0
  636. data/ext/lpsolver-highs/highs/interfaces/highs_csharp_api.cs +1142 -0
  637. data/ext/lpsolver-highs/highs/interfaces/highs_fortran_api.f90 +873 -0
  638. data/ext/lpsolver-highs/highs/io/Filereader.cpp +87 -0
  639. data/ext/lpsolver-highs/highs/io/Filereader.h +45 -0
  640. data/ext/lpsolver-highs/highs/io/FilereaderLp.cpp +539 -0
  641. data/ext/lpsolver-highs/highs/io/FilereaderLp.h +49 -0
  642. data/ext/lpsolver-highs/highs/io/FilereaderMps.cpp +86 -0
  643. data/ext/lpsolver-highs/highs/io/FilereaderMps.h +27 -0
  644. data/ext/lpsolver-highs/highs/io/HMPSIO.cpp +1001 -0
  645. data/ext/lpsolver-highs/highs/io/HMPSIO.h +78 -0
  646. data/ext/lpsolver-highs/highs/io/HMpsFF.cpp +2113 -0
  647. data/ext/lpsolver-highs/highs/io/HMpsFF.h +245 -0
  648. data/ext/lpsolver-highs/highs/io/HighsIO.cpp +371 -0
  649. data/ext/lpsolver-highs/highs/io/HighsIO.h +118 -0
  650. data/ext/lpsolver-highs/highs/io/LoadOptions.cpp +60 -0
  651. data/ext/lpsolver-highs/highs/io/LoadOptions.h +24 -0
  652. data/ext/lpsolver-highs/highs/io/filereaderlp/LICENSE +19 -0
  653. data/ext/lpsolver-highs/highs/io/filereaderlp/builder.hpp +25 -0
  654. data/ext/lpsolver-highs/highs/io/filereaderlp/def.hpp +19 -0
  655. data/ext/lpsolver-highs/highs/io/filereaderlp/model.hpp +68 -0
  656. data/ext/lpsolver-highs/highs/io/filereaderlp/reader.cpp +1375 -0
  657. data/ext/lpsolver-highs/highs/io/filereaderlp/reader.hpp +10 -0
  658. data/ext/lpsolver-highs/highs/ipm/IpxSolution.h +32 -0
  659. data/ext/lpsolver-highs/highs/ipm/IpxWrapper.cpp +1526 -0
  660. data/ext/lpsolver-highs/highs/ipm/IpxWrapper.h +106 -0
  661. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu.h +161 -0
  662. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_factorize.c +132 -0
  663. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_factorize.h +247 -0
  664. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_get_factors.c +148 -0
  665. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_get_factors.h +108 -0
  666. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_initialize.c +24 -0
  667. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_initialize.h +119 -0
  668. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_factorize.h +34 -0
  669. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_free.h +19 -0
  670. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_get_factors.h +34 -0
  671. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_initialize.h +46 -0
  672. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_solve_dense.h +29 -0
  673. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_solve_for_update.h +42 -0
  674. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_solve_sparse.h +32 -0
  675. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_obj_update.h +31 -0
  676. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_object.c +325 -0
  677. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_object.h +30 -0
  678. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_solve_dense.c +46 -0
  679. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_solve_dense.h +75 -0
  680. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_solve_for_update.c +79 -0
  681. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_solve_for_update.h +169 -0
  682. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_solve_sparse.c +63 -0
  683. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_solve_sparse.h +112 -0
  684. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_update.c +44 -0
  685. data/ext/lpsolver-highs/highs/ipm/basiclu/basiclu_update.h +125 -0
  686. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_build_factors.c +441 -0
  687. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_condest.c +124 -0
  688. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_def.h +39 -0
  689. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_dfs.c +141 -0
  690. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_factorize_bump.c +56 -0
  691. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_file.c +184 -0
  692. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_file.h +21 -0
  693. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_garbage_perm.c +53 -0
  694. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_initialize.c +56 -0
  695. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_internal.c +352 -0
  696. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_internal.h +220 -0
  697. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_list.h +173 -0
  698. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_markowitz.c +188 -0
  699. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_matrix_norm.c +51 -0
  700. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_pivot.c +1247 -0
  701. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_residual_test.c +155 -0
  702. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_setup_bump.c +198 -0
  703. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_singletons.c +511 -0
  704. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_solve_dense.c +129 -0
  705. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_solve_for_update.c +360 -0
  706. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_solve_sparse.c +284 -0
  707. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_solve_symbolic.c +48 -0
  708. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_solve_triangular.c +140 -0
  709. data/ext/lpsolver-highs/highs/ipm/basiclu/lu_update.c +908 -0
  710. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/Auxiliary.cpp +301 -0
  711. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/Auxiliary.h +104 -0
  712. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/IntConfig.h +27 -0
  713. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/KrylovMethods.cpp +193 -0
  714. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/KrylovMethods.h +30 -0
  715. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/Log.cpp +60 -0
  716. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/Log.h +62 -0
  717. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/OrderingPrint.h +10 -0
  718. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/VectorOperations.cpp +117 -0
  719. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/VectorOperations.h +59 -0
  720. data/ext/lpsolver-highs/highs/ipm/hipo/auxiliary/mycblas.h +85 -0
  721. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Analyse.cpp +1367 -0
  722. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Analyse.h +122 -0
  723. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/CallAndTimeBlas.cpp +114 -0
  724. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/CallAndTimeBlas.h +46 -0
  725. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/CliqueStack.cpp +82 -0
  726. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/CliqueStack.h +83 -0
  727. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DataCollector.cpp +326 -0
  728. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DataCollector.h +86 -0
  729. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DenseFact.h +48 -0
  730. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DenseFactHybrid.cpp +279 -0
  731. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DenseFactKernel.cpp +284 -0
  732. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DgemmParallel.cpp +38 -0
  733. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/DgemmParallel.h +32 -0
  734. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/FactorHiGHS.cpp +57 -0
  735. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/FactorHiGHS.h +112 -0
  736. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/FactorHiGHSSettings.h +63 -0
  737. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Factorise.cpp +405 -0
  738. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Factorise.h +85 -0
  739. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/FormatHandler.cpp +46 -0
  740. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/FormatHandler.h +95 -0
  741. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/HybridHybridFormatHandler.cpp +238 -0
  742. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/HybridHybridFormatHandler.h +31 -0
  743. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/HybridSolveHandler.cpp +272 -0
  744. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/HybridSolveHandler.h +26 -0
  745. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/KrylovMethodsIpm.cpp +83 -0
  746. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/KrylovMethodsIpm.h +45 -0
  747. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Numeric.cpp +54 -0
  748. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Numeric.h +46 -0
  749. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/ReturnValues.h +19 -0
  750. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/SolveHandler.cpp +10 -0
  751. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/SolveHandler.h +48 -0
  752. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Swaps.cpp +70 -0
  753. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Swaps.h +19 -0
  754. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Symbolic.cpp +101 -0
  755. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Symbolic.h +220 -0
  756. data/ext/lpsolver-highs/highs/ipm/hipo/factorhighs/Timing.h +114 -0
  757. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Control.cpp +38 -0
  758. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Control.h +41 -0
  759. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/FactorHiGHSSolver.cpp +887 -0
  760. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/FactorHiGHSSolver.h +92 -0
  761. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Info.h +58 -0
  762. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/IpmData.cpp +8 -0
  763. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/IpmData.h +37 -0
  764. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Iterate.cpp +640 -0
  765. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Iterate.h +172 -0
  766. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/LinearSolver.h +81 -0
  767. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/LogHighs.cpp +71 -0
  768. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/LogHighs.h +33 -0
  769. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Model.cpp +403 -0
  770. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Model.h +136 -0
  771. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Options.h +35 -0
  772. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Parameters.h +63 -0
  773. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/PreProcess.cpp +646 -0
  774. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/PreProcess.h +94 -0
  775. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Refine.cpp +214 -0
  776. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Solver.cpp +1346 -0
  777. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Solver.h +338 -0
  778. data/ext/lpsolver-highs/highs/ipm/hipo/ipm/Status.h +88 -0
  779. data/ext/lpsolver-highs/highs/ipm/ipx/basiclu_kernel.cc +71 -0
  780. data/ext/lpsolver-highs/highs/ipm/ipx/basiclu_kernel.h +20 -0
  781. data/ext/lpsolver-highs/highs/ipm/ipx/basiclu_wrapper.cc +299 -0
  782. data/ext/lpsolver-highs/highs/ipm/ipx/basiclu_wrapper.h +47 -0
  783. data/ext/lpsolver-highs/highs/ipm/ipx/basis.cc +966 -0
  784. data/ext/lpsolver-highs/highs/ipm/ipx/basis.h +350 -0
  785. data/ext/lpsolver-highs/highs/ipm/ipx/conjugate_residuals.cc +217 -0
  786. data/ext/lpsolver-highs/highs/ipm/ipx/conjugate_residuals.h +74 -0
  787. data/ext/lpsolver-highs/highs/ipm/ipx/control.cc +151 -0
  788. data/ext/lpsolver-highs/highs/ipm/ipx/control.h +167 -0
  789. data/ext/lpsolver-highs/highs/ipm/ipx/crossover.cc +479 -0
  790. data/ext/lpsolver-highs/highs/ipm/ipx/crossover.h +157 -0
  791. data/ext/lpsolver-highs/highs/ipm/ipx/diagonal_precond.cc +70 -0
  792. data/ext/lpsolver-highs/highs/ipm/ipx/diagonal_precond.h +45 -0
  793. data/ext/lpsolver-highs/highs/ipm/ipx/forrest_tomlin.cc +360 -0
  794. data/ext/lpsolver-highs/highs/ipm/ipx/forrest_tomlin.h +102 -0
  795. data/ext/lpsolver-highs/highs/ipm/ipx/guess_basis.cc +233 -0
  796. data/ext/lpsolver-highs/highs/ipm/ipx/guess_basis.h +21 -0
  797. data/ext/lpsolver-highs/highs/ipm/ipx/indexed_vector.cc +30 -0
  798. data/ext/lpsolver-highs/highs/ipm/ipx/indexed_vector.h +113 -0
  799. data/ext/lpsolver-highs/highs/ipm/ipx/info.cc +124 -0
  800. data/ext/lpsolver-highs/highs/ipm/ipx/info.h +27 -0
  801. data/ext/lpsolver-highs/highs/ipm/ipx/ipm.cc +897 -0
  802. data/ext/lpsolver-highs/highs/ipm/ipx/ipm.h +94 -0
  803. data/ext/lpsolver-highs/highs/ipm/ipx/ipx_c.cc +83 -0
  804. data/ext/lpsolver-highs/highs/ipm/ipx/ipx_c.h +47 -0
  805. data/ext/lpsolver-highs/highs/ipm/ipx/ipx_config.h +9 -0
  806. data/ext/lpsolver-highs/highs/ipm/ipx/ipx_info.h +111 -0
  807. data/ext/lpsolver-highs/highs/ipm/ipx/ipx_internal.h +89 -0
  808. data/ext/lpsolver-highs/highs/ipm/ipx/ipx_parameters.h +76 -0
  809. data/ext/lpsolver-highs/highs/ipm/ipx/ipx_status.h +57 -0
  810. data/ext/lpsolver-highs/highs/ipm/ipx/iterate.cc +683 -0
  811. data/ext/lpsolver-highs/highs/ipm/ipx/iterate.h +331 -0
  812. data/ext/lpsolver-highs/highs/ipm/ipx/kkt_solver.cc +23 -0
  813. data/ext/lpsolver-highs/highs/ipm/ipx/kkt_solver.h +70 -0
  814. data/ext/lpsolver-highs/highs/ipm/ipx/kkt_solver_basis.cc +387 -0
  815. data/ext/lpsolver-highs/highs/ipm/ipx/kkt_solver_basis.h +66 -0
  816. data/ext/lpsolver-highs/highs/ipm/ipx/kkt_solver_diag.cc +120 -0
  817. data/ext/lpsolver-highs/highs/ipm/ipx/kkt_solver_diag.h +48 -0
  818. data/ext/lpsolver-highs/highs/ipm/ipx/linear_operator.cc +10 -0
  819. data/ext/lpsolver-highs/highs/ipm/ipx/linear_operator.h +26 -0
  820. data/ext/lpsolver-highs/highs/ipm/ipx/lp_solver.cc +686 -0
  821. data/ext/lpsolver-highs/highs/ipm/ipx/lp_solver.h +204 -0
  822. data/ext/lpsolver-highs/highs/ipm/ipx/lu_factorization.cc +131 -0
  823. data/ext/lpsolver-highs/highs/ipm/ipx/lu_factorization.h +79 -0
  824. data/ext/lpsolver-highs/highs/ipm/ipx/lu_update.cc +62 -0
  825. data/ext/lpsolver-highs/highs/ipm/ipx/lu_update.h +129 -0
  826. data/ext/lpsolver-highs/highs/ipm/ipx/maxvolume.cc +337 -0
  827. data/ext/lpsolver-highs/highs/ipm/ipx/maxvolume.h +54 -0
  828. data/ext/lpsolver-highs/highs/ipm/ipx/model.cc +1528 -0
  829. data/ext/lpsolver-highs/highs/ipm/ipx/model.h +413 -0
  830. data/ext/lpsolver-highs/highs/ipm/ipx/multistream.h +52 -0
  831. data/ext/lpsolver-highs/highs/ipm/ipx/normal_matrix.cc +126 -0
  832. data/ext/lpsolver-highs/highs/ipm/ipx/normal_matrix.h +44 -0
  833. data/ext/lpsolver-highs/highs/ipm/ipx/power_method.h +44 -0
  834. data/ext/lpsolver-highs/highs/ipm/ipx/sparse_matrix.cc +382 -0
  835. data/ext/lpsolver-highs/highs/ipm/ipx/sparse_matrix.h +195 -0
  836. data/ext/lpsolver-highs/highs/ipm/ipx/sparse_utils.cc +92 -0
  837. data/ext/lpsolver-highs/highs/ipm/ipx/sparse_utils.h +58 -0
  838. data/ext/lpsolver-highs/highs/ipm/ipx/splitted_normal_matrix.cc +117 -0
  839. data/ext/lpsolver-highs/highs/ipm/ipx/splitted_normal_matrix.h +63 -0
  840. data/ext/lpsolver-highs/highs/ipm/ipx/starting_basis.cc +182 -0
  841. data/ext/lpsolver-highs/highs/ipm/ipx/starting_basis.h +39 -0
  842. data/ext/lpsolver-highs/highs/ipm/ipx/symbolic_invert.cc +183 -0
  843. data/ext/lpsolver-highs/highs/ipm/ipx/symbolic_invert.h +29 -0
  844. data/ext/lpsolver-highs/highs/ipm/ipx/timer.cc +16 -0
  845. data/ext/lpsolver-highs/highs/ipm/ipx/timer.h +25 -0
  846. data/ext/lpsolver-highs/highs/ipm/ipx/utils.cc +95 -0
  847. data/ext/lpsolver-highs/highs/ipm/ipx/utils.h +37 -0
  848. data/ext/lpsolver-highs/highs/lp_data/HConst.h +430 -0
  849. data/ext/lpsolver-highs/highs/lp_data/HStruct.h +213 -0
  850. data/ext/lpsolver-highs/highs/lp_data/Highs.cpp +4949 -0
  851. data/ext/lpsolver-highs/highs/lp_data/HighsAnalysis.h +23 -0
  852. data/ext/lpsolver-highs/highs/lp_data/HighsCallback.cpp +323 -0
  853. data/ext/lpsolver-highs/highs/lp_data/HighsCallback.h +104 -0
  854. data/ext/lpsolver-highs/highs/lp_data/HighsCallbackStruct.h +70 -0
  855. data/ext/lpsolver-highs/highs/lp_data/HighsDebug.cpp +54 -0
  856. data/ext/lpsolver-highs/highs/lp_data/HighsDebug.h +34 -0
  857. data/ext/lpsolver-highs/highs/lp_data/HighsDeprecated.cpp +181 -0
  858. data/ext/lpsolver-highs/highs/lp_data/HighsIis.cpp +1290 -0
  859. data/ext/lpsolver-highs/highs/lp_data/HighsIis.h +139 -0
  860. data/ext/lpsolver-highs/highs/lp_data/HighsInfo.cpp +426 -0
  861. data/ext/lpsolver-highs/highs/lp_data/HighsInfo.h +421 -0
  862. data/ext/lpsolver-highs/highs/lp_data/HighsInfoDebug.cpp +175 -0
  863. data/ext/lpsolver-highs/highs/lp_data/HighsInfoDebug.h +27 -0
  864. data/ext/lpsolver-highs/highs/lp_data/HighsInterface.cpp +4344 -0
  865. data/ext/lpsolver-highs/highs/lp_data/HighsLp.cpp +564 -0
  866. data/ext/lpsolver-highs/highs/lp_data/HighsLp.h +97 -0
  867. data/ext/lpsolver-highs/highs/lp_data/HighsLpSolverObject.h +47 -0
  868. data/ext/lpsolver-highs/highs/lp_data/HighsLpUtils.cpp +3794 -0
  869. data/ext/lpsolver-highs/highs/lp_data/HighsLpUtils.h +330 -0
  870. data/ext/lpsolver-highs/highs/lp_data/HighsModelUtils.cpp +1650 -0
  871. data/ext/lpsolver-highs/highs/lp_data/HighsModelUtils.h +129 -0
  872. data/ext/lpsolver-highs/highs/lp_data/HighsOptions.cpp +1176 -0
  873. data/ext/lpsolver-highs/highs/lp_data/HighsOptions.h +1715 -0
  874. data/ext/lpsolver-highs/highs/lp_data/HighsRanging.cpp +733 -0
  875. data/ext/lpsolver-highs/highs/lp_data/HighsRanging.h +43 -0
  876. data/ext/lpsolver-highs/highs/lp_data/HighsSolution.cpp +2194 -0
  877. data/ext/lpsolver-highs/highs/lp_data/HighsSolution.h +179 -0
  878. data/ext/lpsolver-highs/highs/lp_data/HighsSolutionDebug.cpp +490 -0
  879. data/ext/lpsolver-highs/highs/lp_data/HighsSolutionDebug.h +87 -0
  880. data/ext/lpsolver-highs/highs/lp_data/HighsSolve.cpp +747 -0
  881. data/ext/lpsolver-highs/highs/lp_data/HighsSolve.h +29 -0
  882. data/ext/lpsolver-highs/highs/lp_data/HighsStatus.cpp +48 -0
  883. data/ext/lpsolver-highs/highs/lp_data/HighsStatus.h +29 -0
  884. data/ext/lpsolver-highs/highs/lp_data/Iis.md +113 -0
  885. data/ext/lpsolver-highs/highs/meson.build +433 -0
  886. data/ext/lpsolver-highs/highs/mip/HighsCliqueTable.cpp +2236 -0
  887. data/ext/lpsolver-highs/highs/mip/HighsCliqueTable.h +329 -0
  888. data/ext/lpsolver-highs/highs/mip/HighsConflictPool.cpp +201 -0
  889. data/ext/lpsolver-highs/highs/mip/HighsConflictPool.h +109 -0
  890. data/ext/lpsolver-highs/highs/mip/HighsCutGeneration.cpp +1491 -0
  891. data/ext/lpsolver-highs/highs/mip/HighsCutGeneration.h +108 -0
  892. data/ext/lpsolver-highs/highs/mip/HighsCutPool.cpp +526 -0
  893. data/ext/lpsolver-highs/highs/mip/HighsCutPool.h +168 -0
  894. data/ext/lpsolver-highs/highs/mip/HighsDebugSol.cpp +313 -0
  895. data/ext/lpsolver-highs/highs/mip/HighsDebugSol.h +133 -0
  896. data/ext/lpsolver-highs/highs/mip/HighsDomain.cpp +3861 -0
  897. data/ext/lpsolver-highs/highs/mip/HighsDomain.h +657 -0
  898. data/ext/lpsolver-highs/highs/mip/HighsDomainChange.h +48 -0
  899. data/ext/lpsolver-highs/highs/mip/HighsDynamicRowMatrix.cpp +199 -0
  900. data/ext/lpsolver-highs/highs/mip/HighsDynamicRowMatrix.h +104 -0
  901. data/ext/lpsolver-highs/highs/mip/HighsFeasibilityJump.cpp +139 -0
  902. data/ext/lpsolver-highs/highs/mip/HighsGFkSolve.cpp +106 -0
  903. data/ext/lpsolver-highs/highs/mip/HighsGFkSolve.h +439 -0
  904. data/ext/lpsolver-highs/highs/mip/HighsImplications.cpp +915 -0
  905. data/ext/lpsolver-highs/highs/mip/HighsImplications.h +194 -0
  906. data/ext/lpsolver-highs/highs/mip/HighsLpAggregator.cpp +56 -0
  907. data/ext/lpsolver-highs/highs/mip/HighsLpAggregator.h +50 -0
  908. data/ext/lpsolver-highs/highs/mip/HighsLpRelaxation.cpp +1609 -0
  909. data/ext/lpsolver-highs/highs/mip/HighsLpRelaxation.h +361 -0
  910. data/ext/lpsolver-highs/highs/mip/HighsMipAnalysis.cpp +313 -0
  911. data/ext/lpsolver-highs/highs/mip/HighsMipAnalysis.h +71 -0
  912. data/ext/lpsolver-highs/highs/mip/HighsMipSolver.cpp +1002 -0
  913. data/ext/lpsolver-highs/highs/mip/HighsMipSolver.h +159 -0
  914. data/ext/lpsolver-highs/highs/mip/HighsMipSolverData.cpp +2936 -0
  915. data/ext/lpsolver-highs/highs/mip/HighsMipSolverData.h +313 -0
  916. data/ext/lpsolver-highs/highs/mip/HighsModkSeparator.cpp +267 -0
  917. data/ext/lpsolver-highs/highs/mip/HighsModkSeparator.h +60 -0
  918. data/ext/lpsolver-highs/highs/mip/HighsNodeQueue.cpp +443 -0
  919. data/ext/lpsolver-highs/highs/mip/HighsNodeQueue.h +312 -0
  920. data/ext/lpsolver-highs/highs/mip/HighsObjectiveFunction.cpp +124 -0
  921. data/ext/lpsolver-highs/highs/mip/HighsObjectiveFunction.h +71 -0
  922. data/ext/lpsolver-highs/highs/mip/HighsPathSeparator.cpp +549 -0
  923. data/ext/lpsolver-highs/highs/mip/HighsPathSeparator.h +39 -0
  924. data/ext/lpsolver-highs/highs/mip/HighsPrimalHeuristics.cpp +1673 -0
  925. data/ext/lpsolver-highs/highs/mip/HighsPrimalHeuristics.h +75 -0
  926. data/ext/lpsolver-highs/highs/mip/HighsPseudocost.cpp +129 -0
  927. data/ext/lpsolver-highs/highs/mip/HighsPseudocost.h +366 -0
  928. data/ext/lpsolver-highs/highs/mip/HighsRedcostFixing.cpp +316 -0
  929. data/ext/lpsolver-highs/highs/mip/HighsRedcostFixing.h +42 -0
  930. data/ext/lpsolver-highs/highs/mip/HighsSearch.cpp +1881 -0
  931. data/ext/lpsolver-highs/highs/mip/HighsSearch.h +241 -0
  932. data/ext/lpsolver-highs/highs/mip/HighsSeparation.cpp +186 -0
  933. data/ext/lpsolver-highs/highs/mip/HighsSeparation.h +41 -0
  934. data/ext/lpsolver-highs/highs/mip/HighsSeparator.cpp +39 -0
  935. data/ext/lpsolver-highs/highs/mip/HighsSeparator.h +60 -0
  936. data/ext/lpsolver-highs/highs/mip/HighsTableauSeparator.cpp +244 -0
  937. data/ext/lpsolver-highs/highs/mip/HighsTableauSeparator.h +34 -0
  938. data/ext/lpsolver-highs/highs/mip/HighsTransformedLp.cpp +563 -0
  939. data/ext/lpsolver-highs/highs/mip/HighsTransformedLp.h +63 -0
  940. data/ext/lpsolver-highs/highs/mip/MipTimer.h +544 -0
  941. data/ext/lpsolver-highs/highs/mip/feasibilityjump.hh +800 -0
  942. data/ext/lpsolver-highs/highs/model/HighsHessian.cpp +263 -0
  943. data/ext/lpsolver-highs/highs/model/HighsHessian.h +54 -0
  944. data/ext/lpsolver-highs/highs/model/HighsHessianUtils.cpp +584 -0
  945. data/ext/lpsolver-highs/highs/model/HighsHessianUtils.h +47 -0
  946. data/ext/lpsolver-highs/highs/model/HighsModel.cpp +46 -0
  947. data/ext/lpsolver-highs/highs/model/HighsModel.h +42 -0
  948. data/ext/lpsolver-highs/highs/parallel/HighsBinarySemaphore.h +108 -0
  949. data/ext/lpsolver-highs/highs/parallel/HighsCacheAlign.h +82 -0
  950. data/ext/lpsolver-highs/highs/parallel/HighsCombinable.h +116 -0
  951. data/ext/lpsolver-highs/highs/parallel/HighsMutex.h +124 -0
  952. data/ext/lpsolver-highs/highs/parallel/HighsParallel.h +128 -0
  953. data/ext/lpsolver-highs/highs/parallel/HighsRaceTimer.h +38 -0
  954. data/ext/lpsolver-highs/highs/parallel/HighsSchedulerConstants.h +19 -0
  955. data/ext/lpsolver-highs/highs/parallel/HighsSpinMutex.h +48 -0
  956. data/ext/lpsolver-highs/highs/parallel/HighsSplitDeque.h +606 -0
  957. data/ext/lpsolver-highs/highs/parallel/HighsTask.h +170 -0
  958. data/ext/lpsolver-highs/highs/parallel/HighsTaskExecutor.cpp +43 -0
  959. data/ext/lpsolver-highs/highs/parallel/HighsTaskExecutor.h +217 -0
  960. data/ext/lpsolver-highs/highs/pdlp/CupdlpWrapper.cpp +848 -0
  961. data/ext/lpsolver-highs/highs/pdlp/CupdlpWrapper.h +108 -0
  962. data/ext/lpsolver-highs/highs/pdlp/HiPdlpTimer.h +155 -0
  963. data/ext/lpsolver-highs/highs/pdlp/HiPdlpWrapper.cpp +141 -0
  964. data/ext/lpsolver-highs/highs/pdlp/HiPdlpWrapper.h +26 -0
  965. data/ext/lpsolver-highs/highs/pdlp/cupdlp/Diff +12 -0
  966. data/ext/lpsolver-highs/highs/pdlp/cupdlp/Meld +7 -0
  967. data/ext/lpsolver-highs/highs/pdlp/cupdlp/Merge +2 -0
  968. data/ext/lpsolver-highs/highs/pdlp/cupdlp/README.md +95 -0
  969. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/CMakeLists.txt +58 -0
  970. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/cupdlp_cuda_kernels.cu +338 -0
  971. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/cupdlp_cuda_kernels.cuh +319 -0
  972. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/cupdlp_cudalinalg.cu +386 -0
  973. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/cupdlp_cudalinalg.cuh +149 -0
  974. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/test_cublas.c +154 -0
  975. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cuda/test_cuda_linalg.c +79 -0
  976. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp.h +16 -0
  977. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_cs.c +214 -0
  978. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_cs.h +40 -0
  979. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_defs.h +447 -0
  980. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_linalg.c +802 -0
  981. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_linalg.h +189 -0
  982. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_proj.c +148 -0
  983. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_proj.h +19 -0
  984. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_restart.c +124 -0
  985. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_restart.h +31 -0
  986. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_scaling.c +425 -0
  987. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_scaling.h +26 -0
  988. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_solver.c +1498 -0
  989. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_solver.h +105 -0
  990. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_step.c +478 -0
  991. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_step.h +37 -0
  992. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_utils.c +1850 -0
  993. data/ext/lpsolver-highs/highs/pdlp/cupdlp/cupdlp_utils.h +212 -0
  994. data/ext/lpsolver-highs/highs/pdlp/cupdlp/glbopts.h +342 -0
  995. data/ext/lpsolver-highs/highs/pdlp/hipdlp/defs.hpp +222 -0
  996. data/ext/lpsolver-highs/highs/pdlp/hipdlp/linalg.cc +231 -0
  997. data/ext/lpsolver-highs/highs/pdlp/hipdlp/linalg.hpp +61 -0
  998. data/ext/lpsolver-highs/highs/pdlp/hipdlp/logger.cc +225 -0
  999. data/ext/lpsolver-highs/highs/pdlp/hipdlp/logger.hpp +80 -0
  1000. data/ext/lpsolver-highs/highs/pdlp/hipdlp/pdhg.cc +2798 -0
  1001. data/ext/lpsolver-highs/highs/pdlp/hipdlp/pdhg.cu +497 -0
  1002. data/ext/lpsolver-highs/highs/pdlp/hipdlp/pdhg.hpp +358 -0
  1003. data/ext/lpsolver-highs/highs/pdlp/hipdlp/pdhg_kernels.hpp +77 -0
  1004. data/ext/lpsolver-highs/highs/pdlp/hipdlp/pdlp_gpu_debug.hpp +62 -0
  1005. data/ext/lpsolver-highs/highs/pdlp/hipdlp/restart.cc +132 -0
  1006. data/ext/lpsolver-highs/highs/pdlp/hipdlp/restart.hpp +96 -0
  1007. data/ext/lpsolver-highs/highs/pdlp/hipdlp/scaling.cc +307 -0
  1008. data/ext/lpsolver-highs/highs/pdlp/hipdlp/scaling.hpp +74 -0
  1009. data/ext/lpsolver-highs/highs/pdlp/hipdlp/solver_results.hpp +65 -0
  1010. data/ext/lpsolver-highs/highs/presolve/HPresolve.cpp +8511 -0
  1011. data/ext/lpsolver-highs/highs/presolve/HPresolve.h +505 -0
  1012. data/ext/lpsolver-highs/highs/presolve/HPresolveAnalysis.cpp +239 -0
  1013. data/ext/lpsolver-highs/highs/presolve/HPresolveAnalysis.h +52 -0
  1014. data/ext/lpsolver-highs/highs/presolve/HighsPostsolveStack.cpp +1368 -0
  1015. data/ext/lpsolver-highs/highs/presolve/HighsPostsolveStack.h +943 -0
  1016. data/ext/lpsolver-highs/highs/presolve/HighsSymmetry.cpp +1921 -0
  1017. data/ext/lpsolver-highs/highs/presolve/HighsSymmetry.h +284 -0
  1018. data/ext/lpsolver-highs/highs/presolve/ICrash.cpp +474 -0
  1019. data/ext/lpsolver-highs/highs/presolve/ICrash.h +124 -0
  1020. data/ext/lpsolver-highs/highs/presolve/ICrashUtil.cpp +267 -0
  1021. data/ext/lpsolver-highs/highs/presolve/ICrashUtil.h +62 -0
  1022. data/ext/lpsolver-highs/highs/presolve/ICrashX.cpp +173 -0
  1023. data/ext/lpsolver-highs/highs/presolve/ICrashX.h +23 -0
  1024. data/ext/lpsolver-highs/highs/presolve/PresolveComponent.cpp +45 -0
  1025. data/ext/lpsolver-highs/highs/presolve/PresolveComponent.h +90 -0
  1026. data/ext/lpsolver-highs/highs/qpsolver/README.md +185 -0
  1027. data/ext/lpsolver-highs/highs/qpsolver/a_asm.cpp +139 -0
  1028. data/ext/lpsolver-highs/highs/qpsolver/a_asm.hpp +77 -0
  1029. data/ext/lpsolver-highs/highs/qpsolver/a_quass.cpp +194 -0
  1030. data/ext/lpsolver-highs/highs/qpsolver/a_quass.hpp +22 -0
  1031. data/ext/lpsolver-highs/highs/qpsolver/basis.cpp +443 -0
  1032. data/ext/lpsolver-highs/highs/qpsolver/basis.hpp +159 -0
  1033. data/ext/lpsolver-highs/highs/qpsolver/crashsolution.hpp +20 -0
  1034. data/ext/lpsolver-highs/highs/qpsolver/dantzigpricing.hpp +80 -0
  1035. data/ext/lpsolver-highs/highs/qpsolver/devexharrispricing.hpp +98 -0
  1036. data/ext/lpsolver-highs/highs/qpsolver/devexpricing.hpp +108 -0
  1037. data/ext/lpsolver-highs/highs/qpsolver/eventhandler.hpp +30 -0
  1038. data/ext/lpsolver-highs/highs/qpsolver/factor.hpp +408 -0
  1039. data/ext/lpsolver-highs/highs/qpsolver/feasibility_bounded.hpp +114 -0
  1040. data/ext/lpsolver-highs/highs/qpsolver/feasibility_highs.hpp +301 -0
  1041. data/ext/lpsolver-highs/highs/qpsolver/gradient.hpp +46 -0
  1042. data/ext/lpsolver-highs/highs/qpsolver/instance.hpp +70 -0
  1043. data/ext/lpsolver-highs/highs/qpsolver/matrix.hpp +342 -0
  1044. data/ext/lpsolver-highs/highs/qpsolver/perturbation.cpp +41 -0
  1045. data/ext/lpsolver-highs/highs/qpsolver/perturbation.hpp +15 -0
  1046. data/ext/lpsolver-highs/highs/qpsolver/pricing.hpp +22 -0
  1047. data/ext/lpsolver-highs/highs/qpsolver/qpconst.hpp +34 -0
  1048. data/ext/lpsolver-highs/highs/qpsolver/qpvector.hpp +242 -0
  1049. data/ext/lpsolver-highs/highs/qpsolver/quass.cpp +551 -0
  1050. data/ext/lpsolver-highs/highs/qpsolver/quass.hpp +27 -0
  1051. data/ext/lpsolver-highs/highs/qpsolver/ratiotest.cpp +146 -0
  1052. data/ext/lpsolver-highs/highs/qpsolver/ratiotest.hpp +26 -0
  1053. data/ext/lpsolver-highs/highs/qpsolver/reducedcosts.hpp +46 -0
  1054. data/ext/lpsolver-highs/highs/qpsolver/reducedgradient.hpp +95 -0
  1055. data/ext/lpsolver-highs/highs/qpsolver/runtime.hpp +45 -0
  1056. data/ext/lpsolver-highs/highs/qpsolver/scaling.cpp +123 -0
  1057. data/ext/lpsolver-highs/highs/qpsolver/scaling.hpp +15 -0
  1058. data/ext/lpsolver-highs/highs/qpsolver/settings.hpp +84 -0
  1059. data/ext/lpsolver-highs/highs/qpsolver/snippets.hpp +36 -0
  1060. data/ext/lpsolver-highs/highs/qpsolver/statistics.hpp +30 -0
  1061. data/ext/lpsolver-highs/highs/qpsolver/steepestedgepricing.hpp +173 -0
  1062. data/ext/lpsolver-highs/highs/simplex/HApp.h +550 -0
  1063. data/ext/lpsolver-highs/highs/simplex/HEkk.cpp +4404 -0
  1064. data/ext/lpsolver-highs/highs/simplex/HEkk.h +419 -0
  1065. data/ext/lpsolver-highs/highs/simplex/HEkkControl.cpp +146 -0
  1066. data/ext/lpsolver-highs/highs/simplex/HEkkDebug.cpp +1722 -0
  1067. data/ext/lpsolver-highs/highs/simplex/HEkkDual.cpp +3003 -0
  1068. data/ext/lpsolver-highs/highs/simplex/HEkkDual.h +513 -0
  1069. data/ext/lpsolver-highs/highs/simplex/HEkkDualMulti.cpp +1020 -0
  1070. data/ext/lpsolver-highs/highs/simplex/HEkkDualRHS.cpp +535 -0
  1071. data/ext/lpsolver-highs/highs/simplex/HEkkDualRHS.h +134 -0
  1072. data/ext/lpsolver-highs/highs/simplex/HEkkDualRow.cpp +697 -0
  1073. data/ext/lpsolver-highs/highs/simplex/HEkkDualRow.h +201 -0
  1074. data/ext/lpsolver-highs/highs/simplex/HEkkInterface.cpp +26 -0
  1075. data/ext/lpsolver-highs/highs/simplex/HEkkPrimal.cpp +2984 -0
  1076. data/ext/lpsolver-highs/highs/simplex/HEkkPrimal.h +191 -0
  1077. data/ext/lpsolver-highs/highs/simplex/HSimplex.cpp +330 -0
  1078. data/ext/lpsolver-highs/highs/simplex/HSimplex.h +42 -0
  1079. data/ext/lpsolver-highs/highs/simplex/HSimplexDebug.cpp +145 -0
  1080. data/ext/lpsolver-highs/highs/simplex/HSimplexDebug.h +48 -0
  1081. data/ext/lpsolver-highs/highs/simplex/HSimplexNla.cpp +517 -0
  1082. data/ext/lpsolver-highs/highs/simplex/HSimplexNla.h +158 -0
  1083. data/ext/lpsolver-highs/highs/simplex/HSimplexNlaDebug.cpp +373 -0
  1084. data/ext/lpsolver-highs/highs/simplex/HSimplexNlaFreeze.cpp +28 -0
  1085. data/ext/lpsolver-highs/highs/simplex/HSimplexNlaProductForm.cpp +113 -0
  1086. data/ext/lpsolver-highs/highs/simplex/HSimplexReport.cpp +77 -0
  1087. data/ext/lpsolver-highs/highs/simplex/HSimplexReport.h +21 -0
  1088. data/ext/lpsolver-highs/highs/simplex/HighsSimplexAnalysis.cpp +1495 -0
  1089. data/ext/lpsolver-highs/highs/simplex/HighsSimplexAnalysis.h +500 -0
  1090. data/ext/lpsolver-highs/highs/simplex/SimplexConst.h +273 -0
  1091. data/ext/lpsolver-highs/highs/simplex/SimplexStruct.h +263 -0
  1092. data/ext/lpsolver-highs/highs/simplex/SimplexTimer.h +414 -0
  1093. data/ext/lpsolver-highs/highs/test_kkt/DevKkt.cpp +469 -0
  1094. data/ext/lpsolver-highs/highs/test_kkt/DevKkt.h +143 -0
  1095. data/ext/lpsolver-highs/highs/test_kkt/KktCh2.cpp +305 -0
  1096. data/ext/lpsolver-highs/highs/test_kkt/KktCh2.h +79 -0
  1097. data/ext/lpsolver-highs/highs/util/FactorTimer.h +199 -0
  1098. data/ext/lpsolver-highs/highs/util/HFactor.cpp +2597 -0
  1099. data/ext/lpsolver-highs/highs/util/HFactor.h +587 -0
  1100. data/ext/lpsolver-highs/highs/util/HFactorConst.h +81 -0
  1101. data/ext/lpsolver-highs/highs/util/HFactorDebug.cpp +231 -0
  1102. data/ext/lpsolver-highs/highs/util/HFactorDebug.h +55 -0
  1103. data/ext/lpsolver-highs/highs/util/HFactorExtend.cpp +229 -0
  1104. data/ext/lpsolver-highs/highs/util/HFactorRefactor.cpp +304 -0
  1105. data/ext/lpsolver-highs/highs/util/HFactorUtils.cpp +122 -0
  1106. data/ext/lpsolver-highs/highs/util/HSet.cpp +197 -0
  1107. data/ext/lpsolver-highs/highs/util/HSet.h +89 -0
  1108. data/ext/lpsolver-highs/highs/util/HVector.h +22 -0
  1109. data/ext/lpsolver-highs/highs/util/HVectorBase.cpp +271 -0
  1110. data/ext/lpsolver-highs/highs/util/HVectorBase.h +102 -0
  1111. data/ext/lpsolver-highs/highs/util/HighsCDouble.h +323 -0
  1112. data/ext/lpsolver-highs/highs/util/HighsComponent.h +53 -0
  1113. data/ext/lpsolver-highs/highs/util/HighsDataStack.h +83 -0
  1114. data/ext/lpsolver-highs/highs/util/HighsDisjointSets.h +107 -0
  1115. data/ext/lpsolver-highs/highs/util/HighsHash.cpp +10 -0
  1116. data/ext/lpsolver-highs/highs/util/HighsHash.h +1274 -0
  1117. data/ext/lpsolver-highs/highs/util/HighsHashTree.h +1461 -0
  1118. data/ext/lpsolver-highs/highs/util/HighsInt.h +36 -0
  1119. data/ext/lpsolver-highs/highs/util/HighsIntegers.h +212 -0
  1120. data/ext/lpsolver-highs/highs/util/HighsLinearSumBounds.cpp +267 -0
  1121. data/ext/lpsolver-highs/highs/util/HighsLinearSumBounds.h +203 -0
  1122. data/ext/lpsolver-highs/highs/util/HighsMatrixPic.cpp +146 -0
  1123. data/ext/lpsolver-highs/highs/util/HighsMatrixPic.h +37 -0
  1124. data/ext/lpsolver-highs/highs/util/HighsMatrixSlice.h +561 -0
  1125. data/ext/lpsolver-highs/highs/util/HighsMatrixUtils.cpp +407 -0
  1126. data/ext/lpsolver-highs/highs/util/HighsMatrixUtils.h +57 -0
  1127. data/ext/lpsolver-highs/highs/util/HighsMemoryAllocation.h +63 -0
  1128. data/ext/lpsolver-highs/highs/util/HighsRandom.h +242 -0
  1129. data/ext/lpsolver-highs/highs/util/HighsRbTree.h +452 -0
  1130. data/ext/lpsolver-highs/highs/util/HighsSort.cpp +364 -0
  1131. data/ext/lpsolver-highs/highs/util/HighsSort.h +131 -0
  1132. data/ext/lpsolver-highs/highs/util/HighsSparseMatrix.cpp +1746 -0
  1133. data/ext/lpsolver-highs/highs/util/HighsSparseMatrix.h +151 -0
  1134. data/ext/lpsolver-highs/highs/util/HighsSparseVectorSum.h +95 -0
  1135. data/ext/lpsolver-highs/highs/util/HighsSplay.h +135 -0
  1136. data/ext/lpsolver-highs/highs/util/HighsTimer.h +385 -0
  1137. data/ext/lpsolver-highs/highs/util/HighsUtils.cpp +1259 -0
  1138. data/ext/lpsolver-highs/highs/util/HighsUtils.h +272 -0
  1139. data/ext/lpsolver-highs/highs/util/stringutil.cpp +131 -0
  1140. data/ext/lpsolver-highs/highs/util/stringutil.h +46 -0
  1141. data/ext/lpsolver-highs/highs.pc.in +12 -0
  1142. data/ext/lpsolver-highs/meson.build +198 -0
  1143. data/ext/lpsolver-highs/meson_options.txt +31 -0
  1144. data/ext/lpsolver-highs/nuget/HiGHS_Logo.png +0 -0
  1145. data/ext/lpsolver-highs/nuget/Highs.csproj +25 -0
  1146. data/ext/lpsolver-highs/nuget/Highs.csproj.in +36 -0
  1147. data/ext/lpsolver-highs/nuget/HowToAlternative.md +77 -0
  1148. data/ext/lpsolver-highs/nuget/README.md +38 -0
  1149. data/ext/lpsolver-highs/nuget/arm-toolchain.cmake +15 -0
  1150. data/ext/lpsolver-highs/nuget/build_linux-arm.sh +13 -0
  1151. data/ext/lpsolver-highs/nuget/build_linux.sh +10 -0
  1152. data/ext/lpsolver-highs/nuget/build_windows.ps1 +27 -0
  1153. data/ext/lpsolver-highs/nuget/generatePackage.ps1 +28 -0
  1154. data/ext/lpsolver-highs/pyproject.toml +221 -0
  1155. data/ext/lpsolver-highs/subprojects/pybind11.wrap +13 -0
  1156. data/ext/lpsolver-highs/tests/test_highspy.py +2310 -0
  1157. data/ext/lpsolver-highs/version.rc.in +50 -0
  1158. data/lib/lpsolver/highs +0 -0
  1159. data/lib/lpsolver/model.rb +28 -4
  1160. data/lib/lpsolver/native.so +0 -0
  1161. data/lib/lpsolver/native_model.rb +261 -0
  1162. data/lib/lpsolver/solution.rb +72 -7
  1163. data/lib/lpsolver/version.rb +1 -1
  1164. data/lpsolver.gemspec +4 -1
  1165. metadata +1176 -4
@@ -0,0 +1,2194 @@
1
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2
+ /* */
3
+ /* This file is part of the HiGHS linear optimization suite */
4
+ /* */
5
+ /* Available as open-source under the MIT License */
6
+ /* */
7
+ /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
8
+ /**@file lp_data/HighsSolution.cpp
9
+ * @brief Class-independent utilities for HiGHS
10
+ */
11
+ #include "lp_data/HighsSolution.h"
12
+
13
+ #include <string>
14
+ #include <vector>
15
+
16
+ #include "io/HighsIO.h"
17
+ #include "ipm/IpxSolution.h"
18
+ #include "ipm/ipx/ipx_status.h"
19
+ #include "ipm/ipx/lp_solver.h"
20
+ #include "lp_data/HighsLpUtils.h"
21
+ #include "lp_data/HighsModelUtils.h"
22
+ #include "lp_data/HighsSolutionDebug.h"
23
+
24
+ const uint8_t kHighsSolutionLo = -1;
25
+ const uint8_t kHighsSolutionNo = 0;
26
+ const uint8_t kHighsSolutionUp = 1;
27
+
28
+ const bool printf_kkt = false; // true; //
29
+
30
+ void getKktFailures(const HighsOptions& options, const HighsModel& model,
31
+ const HighsSolution& solution, const HighsBasis& basis,
32
+ HighsInfo& highs_info) {
33
+ HighsPrimalDualErrors primal_dual_errors;
34
+ getKktFailures(options, model, solution, basis, highs_info,
35
+ primal_dual_errors);
36
+ }
37
+
38
+ void getKktFailures(const HighsOptions& options, const HighsModel& model,
39
+ const HighsSolution& solution, const HighsBasis& basis,
40
+ HighsInfo& highs_info,
41
+ HighsPrimalDualErrors& primal_dual_errors,
42
+ const bool get_residuals) {
43
+ vector<double> gradient;
44
+ model.objectiveGradient(solution.col_value, gradient);
45
+ const HighsLp& lp = model.lp_;
46
+ getKktFailures(options, model.isQp(), lp, gradient, solution, highs_info,
47
+ get_residuals);
48
+ getPrimalDualBasisErrors(options, lp, solution, basis, primal_dual_errors);
49
+ getPrimalDualGlpsolErrors(options, lp, gradient, solution,
50
+ primal_dual_errors);
51
+ }
52
+
53
+ void getLpKktFailures(const HighsOptions& options, const HighsLp& lp,
54
+ const HighsSolution& solution, const HighsBasis& basis,
55
+ HighsInfo& highs_info) {
56
+ HighsPrimalDualErrors primal_dual_errors;
57
+ getLpKktFailures(options, lp, solution, basis, highs_info,
58
+ primal_dual_errors);
59
+ }
60
+
61
+ void getLpKktFailures(const HighsOptions& options, const HighsLp& lp,
62
+ const HighsSolution& solution, const HighsBasis& basis,
63
+ HighsInfo& highs_info,
64
+ HighsPrimalDualErrors& primal_dual_errors,
65
+ const bool get_residuals) {
66
+ getKktFailures(options, false, lp, lp.col_cost_, solution, highs_info,
67
+ get_residuals);
68
+ getPrimalDualBasisErrors(options, lp, solution, basis, primal_dual_errors);
69
+ getPrimalDualGlpsolErrors(options, lp, lp.col_cost_, solution,
70
+ primal_dual_errors);
71
+ }
72
+
73
+ void getKktFailures(const HighsOptions& options, const bool is_qp,
74
+ const HighsLp& lp, const std::vector<double>& gradient,
75
+ const HighsSolution& solution, HighsInfo& highs_info,
76
+ const bool get_residuals) {
77
+ double primal_feasibility_tolerance = options.primal_feasibility_tolerance;
78
+ double dual_feasibility_tolerance = options.dual_feasibility_tolerance;
79
+ double primal_residual_tolerance = options.primal_residual_tolerance;
80
+ double dual_residual_tolerance = options.dual_residual_tolerance;
81
+ double optimality_tolerance = options.optimality_tolerance;
82
+ if (options.kkt_tolerance != kDefaultKktTolerance) {
83
+ primal_feasibility_tolerance = options.kkt_tolerance;
84
+ dual_feasibility_tolerance = options.kkt_tolerance;
85
+ primal_residual_tolerance = options.kkt_tolerance;
86
+ dual_residual_tolerance = options.kkt_tolerance;
87
+ optimality_tolerance = options.kkt_tolerance;
88
+ }
89
+ // highs_info are the values computed in this method
90
+
91
+ HighsInt& num_primal_infeasibility = highs_info.num_primal_infeasibilities;
92
+ double& max_primal_infeasibility = highs_info.max_primal_infeasibility;
93
+ double& sum_primal_infeasibility = highs_info.sum_primal_infeasibilities;
94
+
95
+ HighsInt& num_dual_infeasibility = highs_info.num_dual_infeasibilities;
96
+ double& max_dual_infeasibility = highs_info.max_dual_infeasibility;
97
+ double& sum_dual_infeasibility = highs_info.sum_dual_infeasibilities;
98
+
99
+ HighsInt& num_relative_primal_infeasibility =
100
+ highs_info.num_relative_primal_infeasibilities;
101
+ double& max_relative_primal_infeasibility =
102
+ highs_info.max_relative_primal_infeasibility;
103
+
104
+ HighsInt& num_relative_dual_infeasibility =
105
+ highs_info.num_relative_dual_infeasibilities;
106
+ double& max_relative_dual_infeasibility =
107
+ highs_info.max_relative_dual_infeasibility;
108
+
109
+ HighsInt& num_primal_residual_error = highs_info.num_primal_residual_errors;
110
+ double& max_primal_residual_error = highs_info.max_primal_residual_error;
111
+
112
+ HighsInt& num_dual_residual_error = highs_info.num_dual_residual_errors;
113
+ double& max_dual_residual_error = highs_info.max_dual_residual_error;
114
+
115
+ HighsInt& num_relative_primal_residual_error =
116
+ highs_info.num_relative_primal_residual_errors;
117
+ double& max_relative_primal_residual_error =
118
+ highs_info.max_relative_primal_residual_error;
119
+
120
+ HighsInt& num_relative_dual_residual_error =
121
+ highs_info.num_relative_dual_residual_errors;
122
+ double& max_relative_dual_residual_error =
123
+ highs_info.max_relative_dual_residual_error;
124
+
125
+ HighsInt& num_complementarity_violation =
126
+ highs_info.num_complementarity_violations;
127
+ double& max_complementarity_violation =
128
+ highs_info.max_complementarity_violation;
129
+
130
+ double& primal_dual_objective_error = highs_info.primal_dual_objective_error;
131
+
132
+ const bool& have_primal_solution = solution.value_valid;
133
+ const bool& have_dual_solution = solution.dual_valid;
134
+ const bool have_integrality = (lp.integrality_.size() != 0);
135
+
136
+ // Primal/dual solution status on entry can be feasible or
137
+ // infeasible, because it refers to the previous problem solved, so
138
+ // can't check whether something meaningful is being changed
139
+ highs_info.primal_solution_status = kSolutionStatusNone;
140
+ highs_info.dual_solution_status = kSolutionStatusNone;
141
+
142
+ // Check that there is no dual solution if there's no primal solution
143
+ assert(have_primal_solution || !have_dual_solution);
144
+
145
+ // Invalidate all the KKT measures
146
+ highs_info.invalidateKkt();
147
+
148
+ if (have_primal_solution) {
149
+ // There's a primal solution, so check its size and initialise the
150
+ // infeasibility counts
151
+ assert((int)solution.col_value.size() >= lp.num_col_);
152
+ assert((int)solution.row_value.size() >= lp.num_row_);
153
+ num_primal_infeasibility = 0;
154
+ max_primal_infeasibility = 0;
155
+ sum_primal_infeasibility = 0;
156
+ num_relative_primal_infeasibility = 0;
157
+ max_relative_primal_infeasibility = 0;
158
+ if (get_residuals) {
159
+ num_primal_residual_error = 0;
160
+ max_primal_residual_error = 0;
161
+ num_relative_primal_residual_error = 0;
162
+ max_relative_primal_residual_error = 0;
163
+ }
164
+ }
165
+ if (have_dual_solution) {
166
+ // There's a dual solution, so check its size and initialise the
167
+ // infeasibility counts
168
+ assert((int)solution.col_dual.size() >= lp.num_col_);
169
+ assert((int)solution.row_dual.size() >= lp.num_row_);
170
+ num_dual_infeasibility = 0;
171
+ max_dual_infeasibility = 0;
172
+ sum_dual_infeasibility = 0;
173
+ num_relative_dual_infeasibility = 0;
174
+ max_relative_dual_infeasibility = 0;
175
+ if (get_residuals) {
176
+ num_dual_residual_error = 0;
177
+ max_dual_residual_error = 0;
178
+ num_relative_dual_residual_error = 0;
179
+ max_relative_dual_residual_error = 0;
180
+ }
181
+ }
182
+ // Without a primal solution, nothing can be done!
183
+ if (!have_primal_solution) return;
184
+
185
+ // Possibly compute Ax and A^Ty (to form A^Ty-c) as residual check
186
+ // for solution.row_value and -solution.col_dual
187
+ std::vector<double> primal_activity;
188
+ std::vector<double> dual_activity;
189
+ if (get_residuals)
190
+ lp.a_matrix_.productQuad(primal_activity, solution.col_value);
191
+ if (get_residuals && have_dual_solution)
192
+ lp.a_matrix_.productTransposeQuad(dual_activity, solution.row_dual);
193
+
194
+ double max_col_primal_infeasibility = 0;
195
+ double max_col_dual_infeasibility = 0;
196
+ double max_relative_col_primal_infeasibility = 0;
197
+ double max_relative_col_dual_infeasibility = 0;
198
+
199
+ double primal_infeasibility;
200
+ double relative_primal_infeasibility;
201
+ double dual_infeasibility;
202
+ double cost = 0.0;
203
+ double lower;
204
+ double upper;
205
+ double value;
206
+ double dual = 0;
207
+ uint8_t at_status;
208
+ uint8_t mid_status;
209
+ HighsVarType integrality = HighsVarType::kContinuous;
210
+ HighsBasisStatus status;
211
+ // Compute the infinity norm of all near-active column and row
212
+ // bounds, since they contribute to the magnitude of the row values,
213
+ // and dividing their residual error by the norm gives a relative
214
+ // residual error: don't consider large inactive bounds, since they
215
+ // don't affect the model
216
+ //
217
+ // In IPM without crossover, the columns and rows with values close
218
+ // to their bounds are marginal in driving the algorithm so, by
219
+ // computing the norm as we do, we capture the active bounds of all
220
+ // these variables.
221
+ //
222
+ // In PDLP, only the constraint bounds contribute to the norm, but
223
+ // do the variable bounds not (also) drive the algorithm
224
+ //
225
+ // In simplex the values of the nonbasic variables would be used,
226
+ // since they determine the RHS of the system solved for the values
227
+ // of the basic variables values. That said, by computing the norm
228
+ // as we do, we capture the active bounds of all the nonbasic variables
229
+ double highs_norm_bounds = 0.0;
230
+ // Compute the infinity norm of all near-active column duals, since
231
+ // they contribute to the magnitude of the row values, and dividing
232
+ // their residual error by the norm gives a relative residual error:
233
+ // don't consider large inactive bounds, since they don't affect the
234
+ // model
235
+ double highs_norm_costs = 0.0;
236
+
237
+ // Pass twice through this loop, once to determine the bound and
238
+ // cost norms, and once to use them to assess relative
239
+ // infeasibilities and residual errors
240
+ for (HighsInt pass = 0; pass < 2; pass++) {
241
+ for (HighsInt iVar = 0; iVar < lp.num_col_ + lp.num_row_; iVar++) {
242
+ const bool is_col = iVar < lp.num_col_;
243
+ if (is_col) {
244
+ HighsInt iCol = iVar;
245
+ cost = gradient[iCol];
246
+ lower = lp.col_lower_[iCol];
247
+ upper = lp.col_upper_[iCol];
248
+ value = solution.col_value[iCol];
249
+ if (have_dual_solution) dual = solution.col_dual[iCol];
250
+ if (have_integrality) integrality = lp.integrality_[iCol];
251
+ if (pass == 0) {
252
+ if (dual * dual < dual_feasibility_tolerance) {
253
+ // Dual close to zero
254
+ highs_norm_costs = std::max(std::fabs(cost), highs_norm_costs);
255
+ }
256
+ if (get_residuals && have_dual_solution) {
257
+ // Subtract off the gradient value
258
+ HighsCDouble q_dual_activity = dual_activity[iCol];
259
+ q_dual_activity -= gradient[iCol];
260
+ dual_activity[iCol] = double(q_dual_activity);
261
+ }
262
+ }
263
+ //
264
+ } else {
265
+ HighsInt iRow = iVar - lp.num_col_;
266
+ lower = lp.row_lower_[iRow];
267
+ upper = lp.row_upper_[iRow];
268
+ value = solution.row_value[iRow];
269
+ if (have_dual_solution) dual = solution.row_dual[iRow];
270
+ integrality = HighsVarType::kContinuous;
271
+ }
272
+ // Flip dual according to lp.sense_
273
+ dual *= (HighsInt)lp.sense_;
274
+ // Get the primal and dual infeasibility for this variable, and
275
+ //
276
+ // at_status: Indicates whether the variable is close to its
277
+ // lower bound, upper bound or not at all. Use this as a proxy
278
+ // for being non-basic, so the active bound contributes to
279
+ // highs_norm_bounds for calculating relative primal measures.
280
+ //
281
+ // mid_status: Indicates whether a variable with meaningful
282
+ // bound interval length is below the midpoint of its bound
283
+ // interval, or above the midpoint. The midpoint is infinite for
284
+ // one-sided variables. For free variables, fixed variables, or
285
+ // variables with small positive bound interval lengths,
286
+ // mid_status is returned as kHighsSolutionNo.
287
+ getVariableKktFailures(primal_feasibility_tolerance,
288
+ dual_feasibility_tolerance, lower, upper, value,
289
+ dual, integrality, primal_infeasibility,
290
+ dual_infeasibility, at_status, mid_status);
291
+ if (pass == 0) {
292
+ // If the primal value is close to a bound then include the bound
293
+ // in the active bound norm
294
+ if (at_status == kHighsSolutionLo) {
295
+ highs_norm_bounds = std::max(std::fabs(lower), highs_norm_bounds);
296
+ } else if (at_status == kHighsSolutionUp) {
297
+ highs_norm_bounds = std::max(std::fabs(upper), highs_norm_bounds);
298
+ }
299
+ } else {
300
+ if (primal_infeasibility > 0) {
301
+ // Accumulate primal infeasibilities
302
+ if (primal_infeasibility > primal_feasibility_tolerance)
303
+ num_primal_infeasibility++;
304
+ if (max_primal_infeasibility < primal_infeasibility)
305
+ max_primal_infeasibility = primal_infeasibility;
306
+ sum_primal_infeasibility += primal_infeasibility;
307
+ // Determine the denominator for the relative primal
308
+ // infeasibility
309
+ double relative_bound_measure = highs_norm_bounds;
310
+ if (at_status == kHighsSolutionNo) {
311
+ // Primal value is infeasible, but not close to a bound:
312
+ // unusual, but possible if absolute primal infeasibilities
313
+ // are not small. Bound has not been included in
314
+ // highs_norm_bounds, but should be used for local
315
+ // relative infeasibility
316
+ if (mid_status == kHighsSolutionNo ||
317
+ mid_status == kHighsSolutionLo) {
318
+ // Bound interval is short, or variable is below the
319
+ // midpoint (which is only possible if lower is finite)
320
+ relative_bound_measure =
321
+ std::max(std::fabs(lower), relative_bound_measure);
322
+ } else {
323
+ assert(mid_status == kHighsSolutionUp);
324
+ // Variable is above the midpoint of the bound interval
325
+ // (which is only possible if upper is finite)
326
+ relative_bound_measure =
327
+ std::max(std::fabs(upper), relative_bound_measure);
328
+ }
329
+ }
330
+ double relative_primal_infeasibility =
331
+ primal_infeasibility / (1.0 + relative_bound_measure);
332
+
333
+ if (relative_primal_infeasibility > primal_feasibility_tolerance)
334
+ num_relative_primal_infeasibility++;
335
+ if (max_relative_primal_infeasibility < relative_primal_infeasibility)
336
+ max_relative_primal_infeasibility = relative_primal_infeasibility;
337
+ }
338
+ if (have_dual_solution) {
339
+ if (dual_infeasibility > 0) {
340
+ // Accumulate dual infeasibilities
341
+ if (dual_infeasibility > dual_feasibility_tolerance)
342
+ num_dual_infeasibility++;
343
+ if (max_dual_infeasibility < dual_infeasibility)
344
+ max_dual_infeasibility = dual_infeasibility;
345
+ sum_dual_infeasibility += dual_infeasibility;
346
+
347
+ // Determine the denominator for the relative dual
348
+ // infeasibility
349
+ double relative_cost_measure = highs_norm_costs;
350
+ if (is_col && cost && dual * dual >= dual_feasibility_tolerance) {
351
+ // Dual value is infeasible, but not close to zero:
352
+ // unusual, but possible if absolute dual infeasibilities
353
+ // are not small. Hence the cost has not been included in
354
+ // highs_norm_costs, but should be used for local relative
355
+ // infeasibility.
356
+ //
357
+ // updateRelativeMeasure(cost, relative_cost_measure);
358
+ relative_cost_measure =
359
+ std::max(std::fabs(cost), relative_cost_measure);
360
+ }
361
+ double relative_dual_infeasibility =
362
+ dual_infeasibility / (1.0 + relative_cost_measure);
363
+
364
+ if (relative_dual_infeasibility > dual_feasibility_tolerance)
365
+ num_relative_dual_infeasibility++;
366
+ if (max_relative_dual_infeasibility < relative_dual_infeasibility)
367
+ max_relative_dual_infeasibility = relative_dual_infeasibility;
368
+ }
369
+ }
370
+ if (!is_col && get_residuals) {
371
+ HighsInt iRow = iVar - lp.num_col_;
372
+ assert(iRow >= 0);
373
+ double primal_residual_error =
374
+ std::fabs(primal_activity[iRow] - solution.row_value[iRow]);
375
+ double relative_primal_residual_error =
376
+ primal_residual_error / (1.0 + highs_norm_bounds);
377
+
378
+ if (primal_residual_error > primal_residual_tolerance)
379
+ num_primal_residual_error++;
380
+ if (max_primal_residual_error < primal_residual_error)
381
+ max_primal_residual_error = primal_residual_error;
382
+
383
+ if (relative_primal_residual_error > primal_residual_tolerance)
384
+ num_relative_primal_residual_error++;
385
+ if (max_relative_primal_residual_error <
386
+ relative_primal_residual_error)
387
+ max_relative_primal_residual_error = relative_primal_residual_error;
388
+ }
389
+ if (is_col && get_residuals && have_dual_solution) {
390
+ HighsInt iCol = iVar;
391
+ assert(iCol < lp.num_col_);
392
+ double dual_residual_error =
393
+ std::fabs(dual_activity[iCol] + solution.col_dual[iCol]);
394
+ double relative_dual_residual_error =
395
+ dual_residual_error / (1.0 + highs_norm_costs);
396
+
397
+ if (dual_residual_error > dual_residual_tolerance)
398
+ num_dual_residual_error++;
399
+ if (max_dual_residual_error < dual_residual_error)
400
+ max_dual_residual_error = dual_residual_error;
401
+
402
+ if (relative_dual_residual_error > dual_residual_tolerance)
403
+ num_relative_dual_residual_error++;
404
+ if (max_relative_dual_residual_error < relative_dual_residual_error)
405
+ max_relative_dual_residual_error = relative_dual_residual_error;
406
+ }
407
+ }
408
+ if (pass == 1 && iVar == lp.num_col_ - 1) {
409
+ max_col_primal_infeasibility = max_primal_infeasibility;
410
+ max_col_dual_infeasibility = max_dual_infeasibility;
411
+
412
+ max_relative_col_primal_infeasibility =
413
+ max_relative_primal_infeasibility;
414
+ max_relative_col_dual_infeasibility = max_relative_dual_infeasibility;
415
+
416
+ max_primal_infeasibility = 0;
417
+ max_dual_infeasibility = 0;
418
+
419
+ max_relative_primal_infeasibility = 0;
420
+ max_relative_dual_infeasibility = 0;
421
+ }
422
+ }
423
+ }
424
+
425
+ double max_row_primal_infeasibility = max_primal_infeasibility;
426
+ double max_row_dual_infeasibility = max_dual_infeasibility;
427
+
428
+ double max_relative_row_primal_infeasibility =
429
+ max_relative_primal_infeasibility;
430
+ double max_relative_row_dual_infeasibility = max_relative_dual_infeasibility;
431
+
432
+ max_primal_infeasibility =
433
+ std::max(max_col_primal_infeasibility, max_row_primal_infeasibility);
434
+ max_dual_infeasibility =
435
+ std::max(max_col_dual_infeasibility, max_row_dual_infeasibility);
436
+
437
+ max_relative_primal_infeasibility =
438
+ std::max(max_relative_col_primal_infeasibility,
439
+ max_relative_row_primal_infeasibility);
440
+ max_relative_dual_infeasibility = std::max(
441
+ max_relative_col_dual_infeasibility, max_relative_row_dual_infeasibility);
442
+
443
+ if (have_dual_solution) {
444
+ // Determine the sum of complementarity violations
445
+ const bool have_values = getComplementarityViolations(
446
+ lp, solution, optimality_tolerance, num_complementarity_violation,
447
+ max_complementarity_violation);
448
+ assert(have_values);
449
+ }
450
+
451
+ if (have_dual_solution) {
452
+ // Determine the primal-dual objective error
453
+ //
454
+ // IPX computes objective_gap = (pobjective-dobjective) / (1.0 +
455
+ // 0.5*std::fabs(pobjective+dobjective));
456
+ //
457
+ // PDLP computes dRelObjGap = fabs(dPrimalObj - dDualObj) / (1.0 +
458
+ // fabs(dPrimalObj) + fabs(dDualObj));
459
+ //
460
+ // Use the PDLP relative primal-dual objective error
461
+ //
462
+ // The dual objective for a QP has a -(1/2)x^TQx term, and this
463
+ // can be computed from the gradient (g = Qx + c) as
464
+ // -(1/2)(g-c)^Tx = (1/2)(c-g)^Tx, so pass a pointer to the
465
+ // gradient data if this is necessary
466
+ const double* gradient_p = is_qp ? gradient.data() : nullptr;
467
+ double dual_objective_value;
468
+ bool dual_objective_status = computeDualObjectiveValue(
469
+ gradient_p, lp, solution, dual_objective_value);
470
+ assert(dual_objective_status);
471
+ const double abs_objective_difference =
472
+ std::fabs(highs_info.objective_function_value - dual_objective_value);
473
+ primal_dual_objective_error = abs_objective_difference;
474
+ const double denominator = 1.0 +
475
+ std::fabs(highs_info.objective_function_value) +
476
+ std::fabs(dual_objective_value);
477
+ primal_dual_objective_error = primal_dual_objective_error / denominator;
478
+ }
479
+
480
+ if (printf_kkt || options.log_dev_level > 0) {
481
+ highsLogDev(options.log_options, HighsLogType::kInfo,
482
+ "getKktFailures:: cost norm = %8.3g; bound norm = %8.3g\n",
483
+ highs_norm_costs, highs_norm_bounds);
484
+ highsLogDev(options.log_options, HighsLogType::kInfo,
485
+ "getKktFailures: LP (abs / rel) "
486
+ " Col (abs / rel) Row (abs / rel)\n");
487
+
488
+ highsLogDev(
489
+ options.log_options, HighsLogType::kInfo,
490
+ "getKktFailures: primal infeasibility %8.3g / %8.3g %8.3g / "
491
+ "%8.3g %8.3g / %8.3g\n",
492
+ highs_info.max_primal_infeasibility,
493
+ highs_info.max_relative_primal_infeasibility,
494
+ max_col_primal_infeasibility, max_relative_col_primal_infeasibility,
495
+ max_row_primal_infeasibility, max_relative_row_primal_infeasibility);
496
+ if (have_dual_solution)
497
+ highsLogDev(
498
+ options.log_options, HighsLogType::kInfo,
499
+ "getKktFailures: dual infeasibility %8.3g / %8.3g %8.3g / "
500
+ "%8.3g %8.3g / %8.3g\n",
501
+ highs_info.max_dual_infeasibility,
502
+ highs_info.max_relative_dual_infeasibility,
503
+ max_col_dual_infeasibility, max_relative_col_dual_infeasibility,
504
+ max_row_dual_infeasibility, max_relative_row_dual_infeasibility);
505
+ if (get_residuals) {
506
+ highsLogDev(options.log_options, HighsLogType::kInfo,
507
+ "getKktFailures: primal residual %8.3g / %8.3g\n",
508
+ highs_info.max_primal_residual_error,
509
+ highs_info.max_relative_primal_residual_error);
510
+ if (have_dual_solution)
511
+ highsLogDev(options.log_options, HighsLogType::kInfo,
512
+ "getKktFailures: dual residual %8.3g / %8.3g\n",
513
+ highs_info.max_dual_residual_error,
514
+ highs_info.max_relative_dual_residual_error);
515
+ }
516
+ if (!is_qp && have_dual_solution)
517
+ highsLogDev(options.log_options, HighsLogType::kInfo,
518
+ "getKktFailures: objective gap %8.3g\n",
519
+ highs_info.primal_dual_objective_error);
520
+ }
521
+ // Assign primal (and possibly dual) solution status according to
522
+ // existence of primal and dual feasibilities
523
+ //
524
+ // For LP this may mean that primal/dual feasibility of the solution
525
+ // is claimed when there are residual errors, or denied when PDLP or
526
+ // IPX without crossover are used, since they are deemed feasible
527
+ // according to relative tolerances. This will be cleaned up in
528
+ // Highs::callLpKktCheck, when the existence of a basis determines
529
+ // whether absolute or relative measures are used.
530
+
531
+ if (num_primal_infeasibility) {
532
+ highs_info.primal_solution_status = kSolutionStatusInfeasible;
533
+ } else {
534
+ highs_info.primal_solution_status = kSolutionStatusFeasible;
535
+ }
536
+ if (have_dual_solution) {
537
+ if (num_dual_infeasibility) {
538
+ highs_info.dual_solution_status = kSolutionStatusInfeasible;
539
+ } else {
540
+ highs_info.dual_solution_status = kSolutionStatusFeasible;
541
+ }
542
+ }
543
+ }
544
+
545
+ // Gets the KKT failures for a variable.
546
+ //
547
+ // Value and dual are used compute the primal and dual infeasibility
548
+ // It's up to the calling method to ignore these if the value or dual
549
+ // are not valid.
550
+ void getVariableKktFailures(const double primal_feasibility_tolerance,
551
+ const double dual_feasibility_tolerance,
552
+ const double lower, const double upper,
553
+ const double value, const double dual,
554
+ const HighsVarType integrality,
555
+ double& primal_infeasibility,
556
+ double& dual_infeasibility, uint8_t& at_status,
557
+ uint8_t& mid_status, const HighsInt index) {
558
+ // Return the primal residual (ie infeasibility with zero tolerance)
559
+ // as the primal infeasibility, ensuring (cf #2653) that it doesn't
560
+ // exceed the primal feasibility tolerance if the standard primal
561
+ // infeasibility (ie infeasibility exceeding the tolerance) is zero
562
+ auto infeasibility_residual =
563
+ infeasibility(lower, value, upper, primal_feasibility_tolerance);
564
+ primal_infeasibility = infeasibility_residual.second;
565
+ // Determine whether this value is close to a bound
566
+ at_status = kHighsSolutionNo;
567
+ double bound_residual = std::fabs(lower - value);
568
+ if (bound_residual * bound_residual <= primal_feasibility_tolerance) {
569
+ // Close to lower bound
570
+ at_status = kHighsSolutionLo;
571
+ } else {
572
+ // Not close to lower bound: maybe close to upper bound
573
+ bound_residual = std::fabs(value - upper);
574
+ if (bound_residual * bound_residual <= primal_feasibility_tolerance)
575
+ at_status = kHighsSolutionUp;
576
+ }
577
+ // Look for dual sign errors that exceed the tolerance. For boxed
578
+ // variables the test is discontinuous at the midpoint, but any
579
+ // meaningful dual value on a meaningful interval will show up as a
580
+ // large complementarity error
581
+ mid_status = kHighsSolutionNo;
582
+ if (lower < upper) {
583
+ double length = upper - lower;
584
+ // Non-fixed variable
585
+ if (lower <= -kHighsInf && upper >= kHighsInf) {
586
+ // Free variable
587
+ dual_infeasibility = fabs(dual);
588
+ } else if (length * length > primal_feasibility_tolerance) {
589
+ // Interval length is meaningful
590
+ //
591
+ // Compute the mid-point of the bound interval. This will be
592
+ // +infinity for LB variables; -infinity for UB variables;
593
+ // finite for boxed and fixed variables
594
+ const double middle = (lower + upper) * 0.5;
595
+ if (value < middle) {
596
+ // Below the mid-point, so use lower bound optimality condition:
597
+ // feasibility is dual >= -tolerance
598
+ mid_status = kHighsSolutionLo;
599
+ dual_infeasibility = std::max(-dual, 0.);
600
+ } else {
601
+ // Below the mid-point, so use upper bound optimality condition:
602
+ // feasibility is dual <= tolerance
603
+ mid_status = kHighsSolutionUp;
604
+ dual_infeasibility = std::max(dual, 0.);
605
+ }
606
+ } else {
607
+ // Interval length is less than
608
+ // sqrt(primal_feasibility_tolerance) so dual infeasibility is
609
+ // hard to define
610
+ dual_infeasibility = 0;
611
+ }
612
+ } else {
613
+ // Fixed variable
614
+ dual_infeasibility = 0;
615
+ }
616
+ // Account for semi-variables
617
+ const bool semi_variable = integrality == HighsVarType::kSemiContinuous ||
618
+ integrality == HighsVarType::kSemiInteger;
619
+ if (semi_variable && std::fabs(value) < primal_feasibility_tolerance)
620
+ primal_infeasibility = 0;
621
+ }
622
+
623
+ void getPrimalDualGlpsolErrors(const HighsOptions& options, const HighsLp& lp,
624
+ const std::vector<double>& gradient,
625
+ const HighsSolution& solution,
626
+ HighsPrimalDualErrors& primal_dual_errors) {
627
+ double primal_feasibility_tolerance = options.primal_feasibility_tolerance;
628
+ double dual_feasibility_tolerance = options.dual_feasibility_tolerance;
629
+ double primal_residual_tolerance = options.primal_residual_tolerance;
630
+ double dual_residual_tolerance = options.dual_residual_tolerance;
631
+ double optimality_tolerance = options.optimality_tolerance;
632
+
633
+ // clang-format off
634
+ HighsInt& num_primal_residual_error = primal_dual_errors.glpsol_num_primal_residual_errors;
635
+
636
+ HighsInt& num_dual_residual_error = primal_dual_errors.glpsol_num_dual_residual_errors;
637
+
638
+ double& max_primal_residual_error = primal_dual_errors.glpsol_max_primal_residual.absolute_value;
639
+ HighsInt& max_primal_residual_index = primal_dual_errors.glpsol_max_primal_residual.absolute_index;
640
+
641
+ double& max_relative_primal_residual_error = primal_dual_errors.glpsol_max_primal_residual.relative_value;
642
+ HighsInt& max_relative_primal_residual_index = primal_dual_errors.glpsol_max_primal_residual.relative_index;
643
+
644
+ double& max_primal_infeasibility = primal_dual_errors.glpsol_max_primal_infeasibility.absolute_value;
645
+ HighsInt& max_primal_infeasibility_index = primal_dual_errors.glpsol_max_primal_infeasibility.absolute_index;
646
+
647
+ double& max_relative_primal_infeasibility = primal_dual_errors.glpsol_max_primal_infeasibility.relative_value;
648
+ HighsInt& max_relative_primal_infeasibility_index = primal_dual_errors.glpsol_max_primal_infeasibility.relative_index;
649
+
650
+ double& max_dual_residual_error = primal_dual_errors.glpsol_max_dual_residual.absolute_value;
651
+ HighsInt& max_dual_residual_index = primal_dual_errors.glpsol_max_dual_residual.absolute_index;
652
+
653
+ double& max_relative_dual_residual_error = primal_dual_errors.glpsol_max_dual_residual.relative_value;
654
+ HighsInt& max_relative_dual_residual_index = primal_dual_errors.glpsol_max_dual_residual.relative_index;
655
+
656
+ double& max_dual_infeasibility = primal_dual_errors.glpsol_max_dual_infeasibility.absolute_value;
657
+ HighsInt& max_dual_infeasibility_index = primal_dual_errors.glpsol_max_dual_infeasibility.absolute_index;
658
+ // clang-format on
659
+
660
+ // Relative dual infeasibilities are same as absolute
661
+
662
+ primal_dual_errors.glpsol_max_primal_infeasibility.invalidate();
663
+ primal_dual_errors.glpsol_max_dual_infeasibility.invalidate();
664
+
665
+ const bool have_primal_solution = solution.value_valid;
666
+ const bool have_dual_solution = solution.dual_valid;
667
+ const bool have_integrality = lp.integrality_.size() != 0;
668
+
669
+ // Check that there is no dual solution if there's no primal solution
670
+ assert(have_primal_solution || !have_dual_solution);
671
+
672
+ if (have_primal_solution) {
673
+ // There's a primal solution, so check its size and initialise the
674
+ // infeasibility counts
675
+ assert((int)solution.col_value.size() >= lp.num_col_);
676
+ assert((int)solution.row_value.size() >= lp.num_row_);
677
+ max_primal_infeasibility = 0;
678
+ primal_dual_errors.glpsol_max_primal_infeasibility.reset();
679
+ if (have_dual_solution) {
680
+ // There's a dual solution, so check its size and initialise the
681
+ // infeasibility counts
682
+ assert((int)solution.col_dual.size() >= lp.num_col_);
683
+ assert((int)solution.row_dual.size() >= lp.num_row_);
684
+ max_dual_infeasibility = 0;
685
+ primal_dual_errors.glpsol_max_dual_infeasibility.reset();
686
+ }
687
+ }
688
+
689
+ if (have_primal_solution) {
690
+ num_primal_residual_error = 0;
691
+ max_primal_residual_error = 0;
692
+ max_relative_primal_residual_error = 0;
693
+ primal_dual_errors.glpsol_max_primal_residual.reset();
694
+
695
+ } else {
696
+ num_primal_residual_error = kHighsIllegalResidualCount;
697
+ max_primal_residual_error = kHighsIllegalResidualMeasure;
698
+ max_relative_primal_residual_error = kHighsIllegalResidualMeasure;
699
+ primal_dual_errors.glpsol_max_primal_residual.invalidate();
700
+ }
701
+ if (have_dual_solution) {
702
+ num_dual_residual_error = 0;
703
+ max_dual_residual_error = 0;
704
+ max_relative_dual_residual_error = 0;
705
+ primal_dual_errors.glpsol_max_dual_residual.reset();
706
+ } else {
707
+ num_dual_residual_error = kHighsIllegalResidualCount;
708
+ max_dual_residual_error = kHighsIllegalResidualMeasure;
709
+ max_relative_dual_residual_error = kHighsIllegalResidualMeasure;
710
+ primal_dual_errors.glpsol_max_dual_residual.invalidate();
711
+ }
712
+ // Without a primal solution, nothing can be done!
713
+ if (!have_primal_solution) return;
714
+
715
+ // Residuals are formed for Glpsol via their positive and negative
716
+ // terms so that meaningful relative values can be computed
717
+ std::vector<double> primal_positive_sum;
718
+ std::vector<double> primal_negative_sum;
719
+ std::vector<double> dual_positive_sum;
720
+ std::vector<double> dual_negative_sum;
721
+ primal_positive_sum.assign(lp.num_row_, 0);
722
+ primal_negative_sum.assign(lp.num_row_, 0);
723
+ if (have_dual_solution) {
724
+ dual_positive_sum.resize(lp.num_col_);
725
+ dual_negative_sum.resize(lp.num_col_);
726
+ }
727
+
728
+ double primal_infeasibility;
729
+ double relative_primal_infeasibility;
730
+ double dual_infeasibility;
731
+ double lower;
732
+ double upper;
733
+ double value;
734
+ double dual = 0;
735
+ uint8_t at_status;
736
+ uint8_t mid_status;
737
+ HighsVarType integrality = HighsVarType::kContinuous;
738
+ for (HighsInt iVar = 0; iVar < lp.num_col_ + lp.num_row_; iVar++) {
739
+ if (iVar < lp.num_col_) {
740
+ HighsInt iCol = iVar;
741
+ lower = lp.col_lower_[iCol];
742
+ upper = lp.col_upper_[iCol];
743
+ value = solution.col_value[iCol];
744
+ if (have_dual_solution) dual = solution.col_dual[iCol];
745
+ if (have_integrality) integrality = lp.integrality_[iCol];
746
+ } else {
747
+ HighsInt iRow = iVar - lp.num_col_;
748
+ lower = lp.row_lower_[iRow];
749
+ upper = lp.row_upper_[iRow];
750
+ value = solution.row_value[iRow];
751
+ if (have_dual_solution) dual = solution.row_dual[iRow];
752
+ integrality = HighsVarType::kContinuous;
753
+ }
754
+ // Flip dual according to lp.sense_
755
+ dual *= (HighsInt)lp.sense_;
756
+
757
+ getVariableKktFailures(primal_feasibility_tolerance,
758
+ dual_feasibility_tolerance, lower, upper, value,
759
+ dual, integrality, primal_infeasibility,
760
+ dual_infeasibility, at_status, mid_status);
761
+
762
+ relative_primal_infeasibility = 0;
763
+ if (mid_status == kHighsSolutionLo) {
764
+ relative_primal_infeasibility =
765
+ primal_infeasibility / (1 + std::fabs(lower));
766
+ } else if (mid_status == kHighsSolutionUp) {
767
+ relative_primal_infeasibility =
768
+ primal_infeasibility / (1 + std::fabs(upper));
769
+ } else if (lower > -kHighsInf) {
770
+ // Variable has small bound length
771
+ relative_primal_infeasibility =
772
+ primal_infeasibility / (1 + std::fabs(lower));
773
+ }
774
+
775
+ if (max_primal_infeasibility < primal_infeasibility) {
776
+ max_primal_infeasibility = primal_infeasibility;
777
+ max_primal_infeasibility_index = iVar;
778
+ }
779
+ if (max_relative_primal_infeasibility < relative_primal_infeasibility) {
780
+ max_relative_primal_infeasibility = relative_primal_infeasibility;
781
+ max_relative_primal_infeasibility_index = iVar;
782
+ }
783
+
784
+ if (have_dual_solution) {
785
+ // Accumulate dual infeasibilities
786
+ if (max_dual_infeasibility < dual_infeasibility) {
787
+ max_dual_infeasibility = dual_infeasibility;
788
+ max_dual_infeasibility_index = iVar;
789
+ }
790
+ }
791
+ if (iVar < lp.num_col_) {
792
+ HighsInt iCol = iVar;
793
+ if (have_dual_solution) {
794
+ if (gradient[iCol] > 0) {
795
+ dual_positive_sum[iCol] = gradient[iCol];
796
+ } else {
797
+ dual_negative_sum[iCol] = -gradient[iCol];
798
+ }
799
+ }
800
+ for (HighsInt el = lp.a_matrix_.start_[iCol];
801
+ el < lp.a_matrix_.start_[iCol + 1]; el++) {
802
+ HighsInt iRow = lp.a_matrix_.index_[el];
803
+ double Avalue = lp.a_matrix_.value_[el];
804
+ double term = value * Avalue;
805
+ if (term > 0) {
806
+ primal_positive_sum[iRow] += term;
807
+ } else {
808
+ primal_negative_sum[iRow] -= term;
809
+ }
810
+ // @FlipRowDual += became -=
811
+ if (have_dual_solution) {
812
+ double term = -solution.row_dual[iRow] * Avalue;
813
+ if (term > 0) {
814
+ dual_positive_sum[iCol] += term;
815
+ } else {
816
+ dual_negative_sum[iCol] -= term;
817
+ }
818
+ }
819
+ }
820
+ }
821
+ }
822
+
823
+ // Relative dual infeasibilities are same as absolute
824
+ primal_dual_errors.glpsol_max_dual_infeasibility.relative_value =
825
+ primal_dual_errors.glpsol_max_dual_infeasibility.absolute_value;
826
+
827
+ primal_dual_errors.glpsol_max_dual_infeasibility.relative_index =
828
+ primal_dual_errors.glpsol_max_dual_infeasibility.absolute_index;
829
+ }
830
+
831
+ void getPrimalDualBasisErrors(const HighsOptions& options, const HighsLp& lp,
832
+ const HighsSolution& solution,
833
+ const HighsBasis& basis,
834
+ HighsPrimalDualErrors& primal_dual_errors) {
835
+ double primal_feasibility_tolerance = options.primal_feasibility_tolerance;
836
+ double dual_feasibility_tolerance = options.dual_feasibility_tolerance;
837
+ const bool& have_primal_solution = solution.value_valid;
838
+ const bool& have_dual_solution = solution.dual_valid;
839
+ const bool& have_basis = basis.valid;
840
+
841
+ // Check that there is no dual solution if there's no primal solution
842
+ assert(have_primal_solution || !have_dual_solution);
843
+
844
+ // Check that there is no basis if there's no dual solution
845
+ assert(have_dual_solution || !have_basis);
846
+
847
+ HighsInt& num_nonzero_basic_dual = primal_dual_errors.num_nonzero_basic_duals;
848
+ double& max_nonzero_basic_dual = primal_dual_errors.max_nonzero_basic_dual;
849
+ double& sum_nonzero_basic_dual = primal_dual_errors.sum_nonzero_basic_duals;
850
+
851
+ HighsInt& num_off_bound_nonbasic = primal_dual_errors.num_off_bound_nonbasic;
852
+ double& max_off_bound_nonbasic = primal_dual_errors.max_off_bound_nonbasic;
853
+ double& sum_off_bound_nonbasic = primal_dual_errors.sum_off_bound_nonbasic;
854
+
855
+ if (have_basis) {
856
+ num_nonzero_basic_dual = 0;
857
+ max_nonzero_basic_dual = 0;
858
+ sum_nonzero_basic_dual = 0;
859
+
860
+ num_off_bound_nonbasic = 0;
861
+ max_off_bound_nonbasic = 0;
862
+ sum_off_bound_nonbasic = 0;
863
+ } else {
864
+ num_nonzero_basic_dual = kHighsIllegalInfeasibilityCount;
865
+ max_nonzero_basic_dual = kHighsIllegalInfeasibilityMeasure;
866
+ sum_nonzero_basic_dual = kHighsIllegalInfeasibilityMeasure;
867
+
868
+ num_off_bound_nonbasic = kHighsIllegalInfeasibilityCount;
869
+ max_off_bound_nonbasic = kHighsIllegalInfeasibilityMeasure;
870
+ sum_off_bound_nonbasic = kHighsIllegalInfeasibilityMeasure;
871
+ }
872
+ // Without a primal solution or a basis, nothing can be done!
873
+ if (!have_primal_solution || !have_basis) return;
874
+ // Makes no sense to get primal dual basis failures without a primal
875
+ // solution, dual solution and basis
876
+ assert(have_primal_solution && have_dual_solution && have_basis);
877
+ double primal_infeasibility;
878
+ double relative_primal_infeasibility;
879
+ double dual_infeasibility;
880
+ double value_residual;
881
+ double lower;
882
+ double upper;
883
+ double value;
884
+ double dual = 0;
885
+ HighsBasisStatus status;
886
+ bool status_value_ok;
887
+ for (HighsInt iVar = 0; iVar < lp.num_col_ + lp.num_row_; iVar++) {
888
+ if (iVar < lp.num_col_) {
889
+ HighsInt iCol = iVar;
890
+ lower = lp.col_lower_[iCol];
891
+ upper = lp.col_upper_[iCol];
892
+ value = solution.col_value[iCol];
893
+ dual = solution.col_dual[iCol];
894
+ status = basis.col_status[iCol];
895
+ } else {
896
+ HighsInt iRow = iVar - lp.num_col_;
897
+ lower = lp.row_lower_[iRow];
898
+ upper = lp.row_upper_[iRow];
899
+ value = solution.row_value[iRow];
900
+ dual = solution.row_dual[iRow];
901
+ status = basis.row_status[iRow];
902
+ }
903
+ value_residual =
904
+ std::min(std::fabs(lower - value), std::fabs(value - upper));
905
+ // Flip dual according to lp.sense_
906
+ dual *= (HighsInt)lp.sense_;
907
+ status_value_ok = true;
908
+ // Check that kLower and kUpper are consistent with value and
909
+ // bounds - for debugging QP basis errors
910
+ //
911
+ // With very large values, accuracy is lost in adding/subtracting
912
+ // the feasibility tolerance from the bounds, so skip if this may
913
+ // occur
914
+ if (status == HighsBasisStatus::kLower) {
915
+ if (std::fabs(lower) / primal_feasibility_tolerance < 1e-16)
916
+ status_value_ok = value >= lower - primal_feasibility_tolerance &&
917
+ value <= lower + primal_feasibility_tolerance;
918
+ } else if (status == HighsBasisStatus::kUpper) {
919
+ if (std::fabs(upper) / primal_feasibility_tolerance < 1e-16)
920
+ status_value_ok = value >= upper - primal_feasibility_tolerance &&
921
+ value <= upper + primal_feasibility_tolerance;
922
+ }
923
+
924
+ if (!status_value_ok)
925
+ highsLogUser(
926
+ options.log_options, HighsLogType::kError,
927
+ "getPrimalDualBasisErrors: %s %d status-value error: [%23.18g; "
928
+ "%23.18g; %23.18g] has "
929
+ "residual %g\n",
930
+ iVar < lp.num_col_ ? "Column" : "Row ",
931
+ iVar < lp.num_col_ ? int(iVar) : int(iVar - lp.num_col_), lower,
932
+ value, upper, value_residual);
933
+ assert(status_value_ok);
934
+
935
+ if (status == HighsBasisStatus::kBasic) {
936
+ double abs_basic_dual = std::fabs(dual);
937
+ if (abs_basic_dual > 0) {
938
+ num_nonzero_basic_dual++;
939
+ max_nonzero_basic_dual =
940
+ std::max(abs_basic_dual, max_nonzero_basic_dual);
941
+ sum_nonzero_basic_dual += abs_basic_dual;
942
+ }
943
+ } else {
944
+ double off_bound_nonbasic = value_residual;
945
+ if (off_bound_nonbasic > 0) num_off_bound_nonbasic++;
946
+ max_off_bound_nonbasic =
947
+ std::max(off_bound_nonbasic, max_off_bound_nonbasic);
948
+ sum_off_bound_nonbasic += off_bound_nonbasic;
949
+ }
950
+ }
951
+ }
952
+
953
+ bool getComplementarityViolations(const HighsLp& lp,
954
+ const HighsSolution& solution,
955
+ const double optimality_tolerance,
956
+ HighsInt& num_complementarity_violation,
957
+ double& max_complementarity_violation) {
958
+ num_complementarity_violation = kHighsIllegalComplementarityCount;
959
+ max_complementarity_violation = kHighsIllegalComplementarityViolation;
960
+ if (!solution.dual_valid) return false;
961
+
962
+ num_complementarity_violation = 0;
963
+ max_complementarity_violation = 0;
964
+ double primal_residual = 0;
965
+ for (HighsInt iVar = 0; iVar < lp.num_col_ + lp.num_row_; iVar++) {
966
+ const bool is_col = iVar < lp.num_col_;
967
+ const HighsInt iRow = iVar - lp.num_col_;
968
+ const double primal =
969
+ is_col ? solution.col_value[iVar] : solution.row_value[iRow];
970
+ const double dual =
971
+ is_col ? solution.col_dual[iVar] : solution.row_dual[iRow];
972
+ const double lower = is_col ? lp.col_lower_[iVar] : lp.row_lower_[iRow];
973
+ const double upper = is_col ? lp.col_upper_[iVar] : lp.row_upper_[iRow];
974
+ if (lower <= -kHighsInf && upper >= kHighsInf) {
975
+ // Free
976
+ primal_residual = 1;
977
+ } else {
978
+ const double mid = (lower + upper) * 0.5;
979
+ primal_residual =
980
+ primal < mid ? std::fabs(lower - primal) : std::fabs(upper - primal);
981
+ }
982
+ const double dual_residual = std::fabs(dual);
983
+ const double complementarity_violation = primal_residual * dual_residual;
984
+ if (complementarity_violation > optimality_tolerance)
985
+ num_complementarity_violation++;
986
+ max_complementarity_violation =
987
+ std::max(complementarity_violation, max_complementarity_violation);
988
+ }
989
+ return true;
990
+ }
991
+
992
+ void lpNoBasisKktCheck(HighsModelStatus& model_status, HighsInfo& info,
993
+ const HighsLp& lp, const HighsSolution& solution,
994
+ const HighsOptions& options,
995
+ const std::string& message) {
996
+ HighsBasis basis;
997
+ lpKktCheck(model_status, info, lp, solution, basis, options, message);
998
+ }
999
+
1000
+ void lpKktCheck(HighsModelStatus& model_status, HighsInfo& info,
1001
+ const HighsLp& lp, const HighsSolution& solution,
1002
+ const HighsBasis& basis, const HighsOptions& options,
1003
+ const std::string& message) {
1004
+ if (!solution.value_valid) return;
1005
+ const bool has_dual_values = solution.dual_valid;
1006
+ const HighsLogOptions& log_options = options.log_options;
1007
+ double primal_feasibility_tolerance = options.primal_feasibility_tolerance;
1008
+ double dual_feasibility_tolerance = options.dual_feasibility_tolerance;
1009
+ double primal_residual_tolerance = options.primal_residual_tolerance;
1010
+ double dual_residual_tolerance = options.dual_residual_tolerance;
1011
+ double optimality_tolerance = options.optimality_tolerance;
1012
+ if (options.kkt_tolerance != kDefaultKktTolerance) {
1013
+ primal_feasibility_tolerance = options.kkt_tolerance;
1014
+ dual_feasibility_tolerance = options.kkt_tolerance;
1015
+ primal_residual_tolerance = options.kkt_tolerance;
1016
+ dual_residual_tolerance = options.kkt_tolerance;
1017
+ optimality_tolerance = options.kkt_tolerance;
1018
+ }
1019
+ info.objective_function_value = lp.objectiveValue(solution.col_value);
1020
+ HighsPrimalDualErrors primal_dual_errors;
1021
+ const bool get_residuals = !basis.valid;
1022
+ getLpKktFailures(options, lp, solution, basis, info, primal_dual_errors,
1023
+ get_residuals);
1024
+ if (model_status == HighsModelStatus::kOptimal)
1025
+ reportKktFailures(lp, options, info, message);
1026
+ // get_residuals is false when there is a valid basis, since
1027
+ // residual errors are assumed to be small, so
1028
+ // info.num_primal_residual_errors = -1, since they aren't
1029
+ // known. Hence don't consider this in identifying unboundedness
1030
+ // from HighsModelStatus::kUnboundedOrInfeasible
1031
+ if (model_status == HighsModelStatus::kUnboundedOrInfeasible &&
1032
+ info.num_primal_infeasibilities == 0 &&
1033
+ (!get_residuals || info.num_primal_residual_errors == 0))
1034
+ model_status = HighsModelStatus::kUnbounded;
1035
+ bool was_optimal = model_status == HighsModelStatus::kOptimal;
1036
+ bool kkt_ok = true;
1037
+ bool written_optimality_error_header = false;
1038
+
1039
+ auto foundOptimalityError = [&]() {
1040
+ kkt_ok = false;
1041
+ if (!was_optimal || written_optimality_error_header) return;
1042
+ highsLogUser(log_options, HighsLogType::kWarning,
1043
+ "LP solver claims optimality, but with\n");
1044
+ written_optimality_error_header = true;
1045
+ };
1046
+
1047
+ double max_primal_tolerance_relative_violation = 0;
1048
+ double max_dual_tolerance_relative_violation = 0;
1049
+ double primal_dual_objective_tolerance_relative_violation = 0;
1050
+ const double max_allowed_tolerance_relative_violation = 1e2;
1051
+ if (basis.valid) {
1052
+ if (info.num_primal_infeasibilities > 0) {
1053
+ max_primal_tolerance_relative_violation =
1054
+ std::max(info.max_primal_infeasibility / primal_feasibility_tolerance,
1055
+ max_primal_tolerance_relative_violation);
1056
+ foundOptimalityError();
1057
+ if (was_optimal)
1058
+ highsLogUser(
1059
+ log_options, HighsLogType::kWarning,
1060
+ " num/max/sum %6d / %8.3g / %8.3g primal "
1061
+ "infeasibilities (tolerance = %4.0e)\n",
1062
+ int(info.num_primal_infeasibilities), info.max_primal_infeasibility,
1063
+ info.sum_primal_infeasibilities, primal_feasibility_tolerance);
1064
+ }
1065
+ if (info.num_dual_infeasibilities > 0) {
1066
+ max_dual_tolerance_relative_violation =
1067
+ std::max(info.max_dual_infeasibility / dual_feasibility_tolerance,
1068
+ max_dual_tolerance_relative_violation);
1069
+ foundOptimalityError();
1070
+ if (was_optimal)
1071
+ highsLogUser(log_options, HighsLogType::kWarning,
1072
+ " num/max/sum %6d / %8.3g / %8.3g dual "
1073
+ "infeasibilities (tolerance = %4.0e)\n",
1074
+ int(info.num_dual_infeasibilities),
1075
+ info.max_dual_infeasibility, info.sum_dual_infeasibilities,
1076
+ dual_feasibility_tolerance);
1077
+ }
1078
+ // An optimal basic solution has no complementarity violations
1079
+ // by construction, and can be assumed to have no relative
1080
+ // primal or dual residual errors or meaningful primal dual
1081
+ // objective error
1082
+ bool unexpected_error_if_optimal = info.num_complementarity_violations != 0;
1083
+ double local_dual_objective = 0;
1084
+ if (info.primal_dual_objective_error > optimality_tolerance) {
1085
+ // Ignore primal-dual objective errors if both objectives are small
1086
+ const bool ok_dual_objective = computeDualObjectiveValue(
1087
+ nullptr, lp, solution, local_dual_objective);
1088
+ assert(ok_dual_objective);
1089
+ if (info.objective_function_value * info.objective_function_value >
1090
+ optimality_tolerance &&
1091
+ local_dual_objective * local_dual_objective > optimality_tolerance)
1092
+ unexpected_error_if_optimal = true;
1093
+ }
1094
+ const bool have_residual_errors =
1095
+ info.num_primal_residual_errors != kHighsIllegalResidualCount;
1096
+ if (have_residual_errors) {
1097
+ unexpected_error_if_optimal =
1098
+ unexpected_error_if_optimal ||
1099
+ info.num_relative_primal_residual_errors != 0 ||
1100
+ info.num_relative_dual_residual_errors != 0;
1101
+ max_primal_tolerance_relative_violation = std::max(
1102
+ info.max_relative_primal_residual_error / primal_residual_tolerance,
1103
+ max_primal_tolerance_relative_violation);
1104
+ max_dual_tolerance_relative_violation = std::max(
1105
+ info.max_relative_dual_residual_error / dual_residual_tolerance,
1106
+ max_dual_tolerance_relative_violation);
1107
+ }
1108
+ primal_dual_objective_tolerance_relative_violation =
1109
+ info.primal_dual_objective_error / optimality_tolerance;
1110
+
1111
+ if (was_optimal && unexpected_error_if_optimal) {
1112
+ highsLogUser(
1113
+ log_options, HighsLogType::kWarning,
1114
+ "Optimal basic solution has %d complementarity violations and %g "
1115
+ "primal dual objective error from primal (dual) objective = %g "
1116
+ "(%g)\n",
1117
+ int(info.num_complementarity_violations),
1118
+ info.primal_dual_objective_error, info.objective_function_value,
1119
+ local_dual_objective);
1120
+ if (have_residual_errors) {
1121
+ highsLogUser(
1122
+ log_options, HighsLogType::kWarning,
1123
+ " num/max %6d / %8.3g relative primal residual errors "
1124
+ "(tolerance = %4.0e)\n",
1125
+ int(info.num_relative_primal_residual_errors),
1126
+ info.max_relative_primal_residual_error, primal_residual_tolerance);
1127
+ highsLogUser(
1128
+ log_options, HighsLogType::kWarning,
1129
+ " num/max %6d / %8.3g relative dual residual errors "
1130
+ "(tolerance = %4.0e)\n",
1131
+ int(info.num_relative_dual_residual_errors),
1132
+ info.max_relative_dual_residual_error, dual_residual_tolerance);
1133
+ }
1134
+ assert(info.num_complementarity_violations == 0);
1135
+ assert(info.primal_dual_objective_error <= optimality_tolerance);
1136
+ if (have_residual_errors) {
1137
+ assert(info.num_relative_primal_residual_errors == 0);
1138
+ assert(info.num_relative_dual_residual_errors == 0);
1139
+ }
1140
+ }
1141
+ // Infeasibility of the primal and dual solutions based on number
1142
+ // of primal/dual infeasibilities should have been set in
1143
+ // getKktFailures, but qualify this if the residuals are
1144
+ // meaningful
1145
+ if (info.num_primal_infeasibilities) {
1146
+ assert(info.primal_solution_status == kSolutionStatusInfeasible);
1147
+ } else {
1148
+ info.primal_solution_status = kSolutionStatusFeasible;
1149
+ }
1150
+ if (info.num_dual_infeasibilities) {
1151
+ assert(info.dual_solution_status == kSolutionStatusInfeasible);
1152
+ } else {
1153
+ info.dual_solution_status = kSolutionStatusFeasible;
1154
+ }
1155
+ // Overrule feasibility if large relative tolerance failures have
1156
+ // occurred - pretty inconceivable since absolute residuals should
1157
+ // be small with a basis
1158
+ if (max_primal_tolerance_relative_violation >
1159
+ max_allowed_tolerance_relative_violation)
1160
+ info.primal_solution_status = kSolutionStatusInfeasible;
1161
+ if (max_dual_tolerance_relative_violation >
1162
+ max_allowed_tolerance_relative_violation)
1163
+ info.dual_solution_status = kSolutionStatusInfeasible;
1164
+ } else {
1165
+ // A solution without a basis may have primal or dual residual
1166
+ // errors, and complementarity errors - due to the convergence
1167
+ // being based on relative primal-dual objective error, so test
1168
+ // the latter
1169
+ double tolerance_relative_violation =
1170
+ info.max_relative_primal_infeasibility / primal_feasibility_tolerance;
1171
+ max_primal_tolerance_relative_violation = std::max(
1172
+ tolerance_relative_violation, max_primal_tolerance_relative_violation);
1173
+ if (info.num_relative_primal_infeasibilities > 0) {
1174
+ foundOptimalityError();
1175
+ if (was_optimal)
1176
+ highsLogUser(log_options, HighsLogType::kWarning,
1177
+ " num/max %6d / %8.3g relative primal infeasibilities "
1178
+ "(tolerance = %4.0e)\n",
1179
+ int(info.num_relative_primal_infeasibilities),
1180
+ info.max_relative_primal_infeasibility,
1181
+ primal_feasibility_tolerance);
1182
+ }
1183
+ tolerance_relative_violation =
1184
+ info.max_relative_dual_infeasibility / dual_feasibility_tolerance;
1185
+ max_dual_tolerance_relative_violation = std::max(
1186
+ tolerance_relative_violation, max_dual_tolerance_relative_violation);
1187
+ if (info.num_relative_dual_infeasibilities > 0) {
1188
+ foundOptimalityError();
1189
+ if (was_optimal)
1190
+ highsLogUser(log_options, HighsLogType::kWarning,
1191
+ " num/max %6d / %8.3g relative dual infeasibilities "
1192
+ "(tolerance = %4.0e)\n",
1193
+ int(info.num_relative_dual_infeasibilities),
1194
+ info.max_relative_dual_infeasibility,
1195
+ dual_feasibility_tolerance);
1196
+ }
1197
+ tolerance_relative_violation =
1198
+ info.max_relative_primal_residual_error / primal_residual_tolerance;
1199
+ max_primal_tolerance_relative_violation = std::max(
1200
+ tolerance_relative_violation, max_primal_tolerance_relative_violation);
1201
+ if (info.num_relative_primal_residual_errors > 0) {
1202
+ foundOptimalityError();
1203
+ if (was_optimal)
1204
+ highsLogUser(log_options, HighsLogType::kWarning,
1205
+ " num/max %6d / %8.3g relative primal residual errors "
1206
+ "(tolerance = %4.0e)\n",
1207
+ int(info.num_relative_primal_residual_errors),
1208
+ info.max_relative_primal_residual_error,
1209
+ primal_residual_tolerance);
1210
+ }
1211
+ tolerance_relative_violation =
1212
+ info.max_relative_dual_residual_error / dual_residual_tolerance;
1213
+ max_dual_tolerance_relative_violation = std::max(
1214
+ tolerance_relative_violation, max_dual_tolerance_relative_violation);
1215
+ if (info.num_relative_dual_residual_errors > 0) {
1216
+ foundOptimalityError();
1217
+ if (was_optimal)
1218
+ highsLogUser(log_options, HighsLogType::kWarning,
1219
+ " num/max %6d / %8.3g relative dual residual errors "
1220
+ "(tolerance = %4.0e)\n",
1221
+ int(info.num_relative_dual_residual_errors),
1222
+ info.max_relative_dual_residual_error,
1223
+ dual_residual_tolerance);
1224
+ }
1225
+ if (info.primal_dual_objective_error > optimality_tolerance) {
1226
+ primal_dual_objective_tolerance_relative_violation =
1227
+ info.primal_dual_objective_error / optimality_tolerance;
1228
+ foundOptimalityError();
1229
+ if (was_optimal)
1230
+ highsLogUser(
1231
+ log_options, HighsLogType::kWarning,
1232
+ " %8.3g relative P-D objective error "
1233
+ "(tolerance = %4.0e)\n",
1234
+ info.primal_dual_objective_error, optimality_tolerance);
1235
+ }
1236
+ // Set the primal and dual solution status according to tolerance failure
1237
+ if (max_primal_tolerance_relative_violation >
1238
+ max_allowed_tolerance_relative_violation) {
1239
+ info.primal_solution_status = kSolutionStatusInfeasible;
1240
+ } else {
1241
+ info.primal_solution_status = kSolutionStatusFeasible;
1242
+ }
1243
+ if (max_dual_tolerance_relative_violation >
1244
+ max_allowed_tolerance_relative_violation) {
1245
+ info.dual_solution_status = kSolutionStatusInfeasible;
1246
+ } else {
1247
+ info.dual_solution_status = kSolutionStatusFeasible;
1248
+ }
1249
+ }
1250
+ double max_tolerance_relative_violation =
1251
+ primal_dual_objective_tolerance_relative_violation;
1252
+ max_tolerance_relative_violation =
1253
+ std::max(max_primal_tolerance_relative_violation,
1254
+ max_tolerance_relative_violation);
1255
+ max_tolerance_relative_violation = std::max(
1256
+ max_dual_tolerance_relative_violation, max_tolerance_relative_violation);
1257
+ //
1258
+ // Now see whether optimality is compromised or permitted given the tolerance
1259
+ // failures
1260
+ if (model_status == HighsModelStatus::kOptimal) {
1261
+ if (max_tolerance_relative_violation >
1262
+ max_allowed_tolerance_relative_violation) {
1263
+ model_status = HighsModelStatus::kUnknown;
1264
+ highsLogUser(log_options, HighsLogType::kWarning,
1265
+ "Model status changed from \"Optimal\" to \"Unknown\""
1266
+ " since relative violation of tolerances is %8.3g\n",
1267
+ max_tolerance_relative_violation);
1268
+ } else if (max_allowed_tolerance_relative_violation > 1 &&
1269
+ max_tolerance_relative_violation > 1) {
1270
+ highsLogUser(log_options, HighsLogType::kInfo,
1271
+ "Model status is \"Optimal\" since relative violation of "
1272
+ "tolerances is no more than %8.3g\n",
1273
+ max_tolerance_relative_violation);
1274
+ }
1275
+ } else if (model_status == HighsModelStatus::kUnknown &&
1276
+ max_tolerance_relative_violation <=
1277
+ max_allowed_tolerance_relative_violation) {
1278
+ model_status = HighsModelStatus::kOptimal;
1279
+ highsLogUser(log_options, HighsLogType::kWarning,
1280
+ "Model status changed from \"Unknown\" to \"Optimal\"\n");
1281
+ }
1282
+ highsLogUser(log_options, HighsLogType::kInfo, "\n");
1283
+ return;
1284
+ }
1285
+
1286
+ bool computeDualObjectiveValue(const HighsModel& model,
1287
+ const HighsSolution& solution,
1288
+ double& dual_objective_value) {
1289
+ const HighsLp& lp = model.lp_;
1290
+ if (!model.isQp())
1291
+ return computeDualObjectiveValue(nullptr, lp, solution,
1292
+ dual_objective_value);
1293
+ assert(solution.col_value.size() == static_cast<size_t>(lp.num_col_));
1294
+ // Model is QP, so compute gradient Qx + c so generic
1295
+ // computeDualObjectiveValue can be used
1296
+ std::vector<double> gradient;
1297
+ model.objectiveGradient(solution.col_value, gradient);
1298
+ return computeDualObjectiveValue(gradient.data(), lp, solution,
1299
+ dual_objective_value);
1300
+ }
1301
+
1302
+ bool computeDualObjectiveValue(const double* gradient, const HighsLp& lp,
1303
+ const HighsSolution& solution,
1304
+ double& dual_objective_value) {
1305
+ dual_objective_value = 0;
1306
+ if (!solution.dual_valid) return false;
1307
+ // #2184 Make sure that the solution corresponds to this LP
1308
+ assert(solution.col_value.size() == static_cast<size_t>(lp.num_col_));
1309
+ assert(solution.col_dual.size() == static_cast<size_t>(lp.num_col_));
1310
+ assert(solution.row_value.size() == static_cast<size_t>(lp.num_row_));
1311
+ assert(solution.row_dual.size() == static_cast<size_t>(lp.num_row_));
1312
+
1313
+ dual_objective_value = lp.offset_;
1314
+ if (gradient) {
1315
+ // The dual objective for a QP has a -(1/2)x^TQx term, and this
1316
+ // can be computed from the gradient (g = Qx + c) as
1317
+ // -(1/2)(g-c)^Tx = (1/2)(c-g)^Tx, a pointer to the gradient data
1318
+ // is passed if this is necessary
1319
+ double quad_value = 0;
1320
+ for (HighsInt iCol = 0; iCol < lp.num_col_; iCol++) {
1321
+ quad_value +=
1322
+ (lp.col_cost_[iCol] - gradient[iCol]) * solution.col_value[iCol];
1323
+ }
1324
+ dual_objective_value += 0.5 * quad_value;
1325
+ }
1326
+ double bound = 0;
1327
+ for (HighsInt iVar = 0; iVar < lp.num_col_ + lp.num_row_; iVar++) {
1328
+ const bool is_col = iVar < lp.num_col_;
1329
+ const HighsInt iRow = iVar - lp.num_col_;
1330
+ const double primal =
1331
+ is_col ? solution.col_value[iVar] : solution.row_value[iRow];
1332
+ const double dual =
1333
+ is_col ? solution.col_dual[iVar] : solution.row_dual[iRow];
1334
+ const double lower = is_col ? lp.col_lower_[iVar] : lp.row_lower_[iRow];
1335
+ const double upper = is_col ? lp.col_upper_[iVar] : lp.row_upper_[iRow];
1336
+ if (lower <= -kHighsInf && upper >= kHighsInf) {
1337
+ // Free
1338
+ bound = 1;
1339
+ } else {
1340
+ const double mid = (lower + upper) * 0.5;
1341
+ bound = primal < mid ? lower : upper;
1342
+ }
1343
+ dual_objective_value += bound * dual;
1344
+ }
1345
+ return true;
1346
+ }
1347
+
1348
+ void HighsError::print(std::string message) {
1349
+ printf(
1350
+ "\n%s\nAbsolute value = %11.4g; index = %9d\nRelative value = %11.4g; "
1351
+ "index = %9d\n",
1352
+ message.c_str(), this->absolute_value, (int)this->absolute_index,
1353
+ this->relative_value, (int)this->relative_index);
1354
+ }
1355
+
1356
+ void HighsError::reset() {
1357
+ this->absolute_value = 0;
1358
+ this->absolute_index = 0;
1359
+ this->relative_value = 0;
1360
+ this->relative_index = 0;
1361
+ }
1362
+
1363
+ void HighsError::invalidate() {
1364
+ this->absolute_value = kHighsIllegalErrorValue;
1365
+ this->absolute_index = kHighsIllegalErrorIndex;
1366
+ this->relative_value = kHighsIllegalErrorValue;
1367
+ this->relative_index = kHighsIllegalErrorIndex;
1368
+ }
1369
+
1370
+ double computeObjectiveValue(const HighsLp& lp, const HighsSolution& solution) {
1371
+ double objective_value = 0;
1372
+ for (HighsInt iCol = 0; iCol < lp.num_col_; iCol++)
1373
+ objective_value += lp.col_cost_[iCol] * solution.col_value[iCol];
1374
+ objective_value += lp.offset_;
1375
+ return objective_value;
1376
+ }
1377
+
1378
+ // Refine any HighsBasisStatus::kNonbasic settings according to the LP
1379
+ // and any solution values
1380
+ void refineBasis(const HighsLp& lp, const HighsSolution& solution,
1381
+ HighsBasis& basis) {
1382
+ assert(basis.useful);
1383
+ assert(isBasisRightSize(lp, basis));
1384
+ const bool have_highs_solution = solution.value_valid;
1385
+
1386
+ const HighsInt num_col = lp.num_col_;
1387
+ const HighsInt num_row = lp.num_row_;
1388
+ for (HighsInt iCol = 0; iCol < num_col; iCol++) {
1389
+ if (basis.col_status[iCol] != HighsBasisStatus::kNonbasic) continue;
1390
+ const double lower = lp.col_lower_[iCol];
1391
+ const double upper = lp.col_upper_[iCol];
1392
+ HighsBasisStatus status = HighsBasisStatus::kNonbasic;
1393
+ if (lower == upper) {
1394
+ status = HighsBasisStatus::kLower;
1395
+ } else if (!highs_isInfinity(-lower)) {
1396
+ if (!highs_isInfinity(upper)) {
1397
+ if (have_highs_solution) {
1398
+ if (solution.col_value[iCol] < 0.5 * (lower + upper)) {
1399
+ status = HighsBasisStatus::kLower;
1400
+ } else {
1401
+ status = HighsBasisStatus::kUpper;
1402
+ }
1403
+ } else {
1404
+ if (fabs(lower) < fabs(upper)) {
1405
+ status = HighsBasisStatus::kLower;
1406
+ } else {
1407
+ status = HighsBasisStatus::kUpper;
1408
+ }
1409
+ }
1410
+ } else {
1411
+ status = HighsBasisStatus::kLower;
1412
+ }
1413
+ } else if (!highs_isInfinity(upper)) {
1414
+ status = HighsBasisStatus::kUpper;
1415
+ } else {
1416
+ status = HighsBasisStatus::kZero;
1417
+ }
1418
+ assert(status != HighsBasisStatus::kNonbasic);
1419
+ basis.col_status[iCol] = status;
1420
+ }
1421
+
1422
+ for (HighsInt iRow = 0; iRow < num_row; iRow++) {
1423
+ if (basis.row_status[iRow] != HighsBasisStatus::kNonbasic) continue;
1424
+ const double lower = lp.row_lower_[iRow];
1425
+ const double upper = lp.row_upper_[iRow];
1426
+ HighsBasisStatus status = HighsBasisStatus::kNonbasic;
1427
+ if (lower == upper) {
1428
+ status = HighsBasisStatus::kLower;
1429
+ } else if (!highs_isInfinity(-lower)) {
1430
+ if (!highs_isInfinity(upper)) {
1431
+ if (have_highs_solution) {
1432
+ if (solution.row_value[iRow] < 0.5 * (lower + upper)) {
1433
+ status = HighsBasisStatus::kLower;
1434
+ } else {
1435
+ status = HighsBasisStatus::kUpper;
1436
+ }
1437
+ } else {
1438
+ if (fabs(lower) < fabs(upper)) {
1439
+ status = HighsBasisStatus::kLower;
1440
+ } else {
1441
+ status = HighsBasisStatus::kUpper;
1442
+ }
1443
+ }
1444
+ } else {
1445
+ status = HighsBasisStatus::kLower;
1446
+ }
1447
+ } else if (!highs_isInfinity(upper)) {
1448
+ status = HighsBasisStatus::kUpper;
1449
+ } else {
1450
+ status = HighsBasisStatus::kZero;
1451
+ }
1452
+ assert(status != HighsBasisStatus::kNonbasic);
1453
+ basis.row_status[iRow] = status;
1454
+ }
1455
+ }
1456
+
1457
+ HighsStatus ipxSolutionToHighsSolution(
1458
+ const HighsOptions& options, const HighsLp& lp,
1459
+ const std::vector<double>& rhs, const std::vector<char>& constraint_type,
1460
+ const HighsInt ipx_num_col, const HighsInt ipx_num_row,
1461
+ const std::vector<double>& ipx_x, const std::vector<double>& ipx_slack_vars,
1462
+ const std::vector<double>& ipx_y, const std::vector<double>& ipx_zl,
1463
+ const std::vector<double>& ipx_zu, HighsSolution& highs_solution) {
1464
+ // Resize the HighsSolution
1465
+ highs_solution.col_value.resize(lp.num_col_);
1466
+ highs_solution.row_value.resize(lp.num_row_);
1467
+ highs_solution.col_dual.resize(lp.num_col_);
1468
+ highs_solution.row_dual.resize(lp.num_row_);
1469
+
1470
+ const std::vector<double>& ipx_col_value = ipx_x;
1471
+ const std::vector<double>& ipx_row_value = ipx_slack_vars;
1472
+
1473
+ // Row activities are needed to set activity values of free rows -
1474
+ // which are ignored by IPX
1475
+ vector<double> row_activity;
1476
+ const bool get_row_activities = ipx_num_row < lp.num_row_;
1477
+ if (get_row_activities) row_activity.assign(lp.num_row_, 0);
1478
+ HighsInt ipx_slack = lp.num_col_;
1479
+ assert(ipx_num_row == lp.num_row_);
1480
+ HighsInt dual_infeasibility_count = 0;
1481
+ double primal_infeasibility;
1482
+ double relative_primal_infeasibility;
1483
+ double dual_infeasibility;
1484
+ double value_residual;
1485
+ uint8_t at_status; // Not used
1486
+ uint8_t mid_status; // Not used
1487
+ for (HighsInt iCol = 0; iCol < lp.num_col_; iCol++) {
1488
+ double value = ipx_col_value[iCol];
1489
+ if (get_row_activities) {
1490
+ // Accumulate row activities to assign value to free rows
1491
+ for (HighsInt el = lp.a_matrix_.start_[iCol];
1492
+ el < lp.a_matrix_.start_[iCol + 1]; el++) {
1493
+ HighsInt row = lp.a_matrix_.index_[el];
1494
+ row_activity[row] += value * lp.a_matrix_.value_[el];
1495
+ }
1496
+ }
1497
+ double dual = ipx_zl[iCol] - ipx_zu[iCol];
1498
+ highs_solution.col_value[iCol] = value;
1499
+ highs_solution.col_dual[iCol] = dual;
1500
+ }
1501
+ HighsInt ipx_row = 0;
1502
+ ipx_slack = lp.num_col_;
1503
+ for (HighsInt iRow = 0; iRow < lp.num_row_; iRow++) {
1504
+ double lower = lp.row_lower_[iRow];
1505
+ double upper = lp.row_upper_[iRow];
1506
+ if (lower <= -kHighsInf && upper >= kHighsInf) {
1507
+ // Free row - removed by IPX so set it to its row activity
1508
+ highs_solution.row_value[iRow] = row_activity[iRow];
1509
+ highs_solution.row_dual[iRow] = 0;
1510
+ continue;
1511
+ }
1512
+ // Non-free row, so IPX will have it
1513
+ double value = 0;
1514
+ double dual = 0;
1515
+ if ((lower > -kHighsInf && upper < kHighsInf) && (lower < upper)) {
1516
+ assert(constraint_type[ipx_row] == '=');
1517
+ // Boxed row - look at its slack
1518
+ value = ipx_col_value[ipx_slack];
1519
+ dual = ipx_zl[ipx_slack] - ipx_zu[ipx_slack];
1520
+ // Update the slack to be used for boxed rows
1521
+ ipx_slack++;
1522
+ } else {
1523
+ value = rhs[ipx_row] - ipx_row_value[ipx_row];
1524
+ dual = ipx_y[ipx_row];
1525
+ }
1526
+ highs_solution.row_value[iRow] = value;
1527
+ highs_solution.row_dual[iRow] = dual;
1528
+ // Update the IPX row index
1529
+ ipx_row++;
1530
+ }
1531
+ assert(ipx_row == ipx_num_row);
1532
+ assert(ipx_slack == ipx_num_col);
1533
+ if (lp.sense_ == ObjSense::kMaximize) {
1534
+ // Flip dual values since original LP is maximization
1535
+ for (HighsInt iCol = 0; iCol < lp.num_col_; iCol++)
1536
+ highs_solution.col_dual[iCol] *= -1;
1537
+ for (HighsInt iRow = 0; iRow < lp.num_row_; iRow++)
1538
+ highs_solution.row_dual[iRow] *= -1;
1539
+ }
1540
+
1541
+ // Indicate that the primal and dual solution are known
1542
+ highs_solution.value_valid = true;
1543
+ highs_solution.dual_valid = true;
1544
+ return HighsStatus::kOk;
1545
+ }
1546
+
1547
+ HighsStatus ipxBasicSolutionToHighsBasicSolution(
1548
+ const HighsLogOptions& log_options, const HighsLp& lp,
1549
+ const std::vector<double>& rhs, const std::vector<char>& constraint_type,
1550
+ const IpxSolution& ipx_solution, HighsBasis& highs_basis,
1551
+ HighsSolution& highs_solution) {
1552
+ // Resize the HighsSolution and HighsBasis
1553
+ highs_solution.col_value.resize(lp.num_col_);
1554
+ highs_solution.row_value.resize(lp.num_row_);
1555
+ highs_solution.col_dual.resize(lp.num_col_);
1556
+ highs_solution.row_dual.resize(lp.num_row_);
1557
+ highs_basis.col_status.resize(lp.num_col_);
1558
+ highs_basis.row_status.resize(lp.num_row_);
1559
+
1560
+ const std::vector<double>& ipx_col_value = ipx_solution.ipx_col_value;
1561
+ const std::vector<double>& ipx_row_value = ipx_solution.ipx_row_value;
1562
+ const std::vector<double>& ipx_col_dual = ipx_solution.ipx_col_dual;
1563
+ const std::vector<double>& ipx_row_dual = ipx_solution.ipx_row_dual;
1564
+ const std::vector<ipx::Int>& ipx_col_status = ipx_solution.ipx_col_status;
1565
+ const std::vector<ipx::Int>& ipx_row_status = ipx_solution.ipx_row_status;
1566
+
1567
+ // Set up meaningful names for values of ipx_col_status and ipx_row_status to
1568
+ // be used later in comparisons
1569
+ const ipx::Int ipx_basic = 0;
1570
+ const ipx::Int ipx_nonbasic_at_lb = -1;
1571
+ const ipx::Int ipx_nonbasic_at_ub = -2;
1572
+ const ipx::Int ipx_superbasic = -3;
1573
+ // Row activities are needed to set activity values of free rows -
1574
+ // which are ignored by IPX
1575
+ vector<double> row_activity;
1576
+ bool get_row_activities = ipx_solution.num_row < lp.num_row_;
1577
+ if (get_row_activities) row_activity.assign(lp.num_row_, 0);
1578
+ HighsInt num_basic_variables = 0;
1579
+ for (HighsInt col = 0; col < lp.num_col_; col++) {
1580
+ bool unrecognised = false;
1581
+ if (ipx_col_status[col] == ipx_basic) {
1582
+ // Column is basic
1583
+ highs_basis.col_status[col] = HighsBasisStatus::kBasic;
1584
+ highs_solution.col_value[col] = ipx_col_value[col];
1585
+ highs_solution.col_dual[col] = 0;
1586
+ } else {
1587
+ // Column is nonbasic. Setting of ipx_col_status is consistent
1588
+ // with dual value for fixed columns
1589
+ if (ipx_col_status[col] == ipx_nonbasic_at_lb) {
1590
+ // Column is at lower bound
1591
+ highs_basis.col_status[col] = HighsBasisStatus::kLower;
1592
+ highs_solution.col_value[col] = ipx_col_value[col];
1593
+ highs_solution.col_dual[col] = ipx_col_dual[col];
1594
+ } else if (ipx_col_status[col] == ipx_nonbasic_at_ub) {
1595
+ // Column is at upper bound
1596
+ highs_basis.col_status[col] = HighsBasisStatus::kUpper;
1597
+ highs_solution.col_value[col] = ipx_col_value[col];
1598
+ highs_solution.col_dual[col] = ipx_col_dual[col];
1599
+ } else if (ipx_col_status[col] == ipx_superbasic) {
1600
+ // Column is superbasic
1601
+ highs_basis.col_status[col] = HighsBasisStatus::kZero;
1602
+ highs_solution.col_value[col] = ipx_col_value[col];
1603
+ highs_solution.col_dual[col] = ipx_col_dual[col];
1604
+ } else {
1605
+ unrecognised = true;
1606
+ highsLogDev(log_options, HighsLogType::kError,
1607
+ "\nError in IPX conversion: Unrecognised value "
1608
+ "ipx_col_status[%2" HIGHSINT_FORMAT
1609
+ "] = "
1610
+ "%" HIGHSINT_FORMAT "\n",
1611
+ col, (HighsInt)ipx_col_status[col]);
1612
+ }
1613
+ }
1614
+ if (unrecognised) {
1615
+ highsLogDev(log_options, HighsLogType::kError,
1616
+ "Bounds [%11.4g, %11.4g]\n", lp.col_lower_[col],
1617
+ lp.col_upper_[col]);
1618
+ highsLogDev(log_options, HighsLogType::kError,
1619
+ "Col %2" HIGHSINT_FORMAT " ipx_col_status[%2" HIGHSINT_FORMAT
1620
+ "] = %2" HIGHSINT_FORMAT "; x[%2" HIGHSINT_FORMAT
1621
+ "] = %11.4g; z[%2" HIGHSINT_FORMAT
1622
+ "] = "
1623
+ "%11.4g\n",
1624
+ col, col, (HighsInt)ipx_col_status[col], col,
1625
+ ipx_col_value[col], col, ipx_col_dual[col]);
1626
+ assert(!unrecognised);
1627
+ highsLogUser(log_options, HighsLogType::kError,
1628
+ "Unrecognised ipx_col_status value from IPX\n");
1629
+ return HighsStatus::kError;
1630
+ }
1631
+ if (get_row_activities) {
1632
+ // Accumulate row activities to assign value to free rows
1633
+ for (HighsInt el = lp.a_matrix_.start_[col];
1634
+ el < lp.a_matrix_.start_[col + 1]; el++) {
1635
+ HighsInt row = lp.a_matrix_.index_[el];
1636
+ row_activity[row] +=
1637
+ highs_solution.col_value[col] * lp.a_matrix_.value_[el];
1638
+ }
1639
+ }
1640
+ if (highs_basis.col_status[col] == HighsBasisStatus::kBasic)
1641
+ num_basic_variables++;
1642
+ }
1643
+ HighsInt ipx_row = 0;
1644
+ HighsInt ipx_slack = lp.num_col_;
1645
+ HighsInt num_boxed_rows = 0;
1646
+ HighsInt num_boxed_rows_basic = 0;
1647
+ HighsInt num_boxed_row_slacks_basic = 0;
1648
+ for (HighsInt row = 0; row < lp.num_row_; row++) {
1649
+ bool unrecognised = false;
1650
+ double lower = lp.row_lower_[row];
1651
+ double upper = lp.row_upper_[row];
1652
+ HighsInt this_ipx_row = ipx_row;
1653
+ if (lower <= -kHighsInf && upper >= kHighsInf) {
1654
+ // Free row - removed by IPX so make it basic at its row activity
1655
+ highs_basis.row_status[row] = HighsBasisStatus::kBasic;
1656
+ highs_solution.row_value[row] = row_activity[row];
1657
+ highs_solution.row_dual[row] = 0;
1658
+ } else {
1659
+ // Non-free row, so IPX will have it
1660
+ if ((lower > -kHighsInf && upper < kHighsInf) && (lower < upper)) {
1661
+ // Boxed row - look at its slack
1662
+ num_boxed_rows++;
1663
+ double slack_value = ipx_col_value[ipx_slack];
1664
+ double slack_dual = ipx_col_dual[ipx_slack];
1665
+ double value = slack_value;
1666
+ // @FlipRowDual -slack_dual became slack_dual
1667
+ double dual = slack_dual;
1668
+ if (ipx_row_status[ipx_row] == ipx_basic) {
1669
+ // Row is basic
1670
+ num_boxed_rows_basic++;
1671
+ highs_basis.row_status[row] = HighsBasisStatus::kBasic;
1672
+ highs_solution.row_value[row] = value;
1673
+ highs_solution.row_dual[row] = 0;
1674
+ } else if (ipx_col_status[ipx_slack] == ipx_basic) {
1675
+ // Slack is basic
1676
+ num_boxed_row_slacks_basic++;
1677
+ highs_basis.row_status[row] = HighsBasisStatus::kBasic;
1678
+ highs_solution.row_value[row] = value;
1679
+ highs_solution.row_dual[row] = 0;
1680
+ } else if (ipx_col_status[ipx_slack] == ipx_nonbasic_at_lb) {
1681
+ // Slack at lower bound
1682
+ highs_basis.row_status[row] = HighsBasisStatus::kLower;
1683
+ highs_solution.row_value[row] = value;
1684
+ highs_solution.row_dual[row] = dual;
1685
+ } else if (ipx_col_status[ipx_slack] == ipx_nonbasic_at_ub) {
1686
+ // Slack is at its upper bound
1687
+ assert(ipx_col_status[ipx_slack] == ipx_nonbasic_at_ub);
1688
+ highs_basis.row_status[row] = HighsBasisStatus::kUpper;
1689
+ highs_solution.row_value[row] = value;
1690
+ highs_solution.row_dual[row] = dual;
1691
+ } else {
1692
+ unrecognised = true;
1693
+ highsLogDev(log_options, HighsLogType::kError,
1694
+ "Error in IPX conversion: Row %2" HIGHSINT_FORMAT
1695
+ " (IPX row %2" HIGHSINT_FORMAT
1696
+ ") has "
1697
+ "unrecognised value ipx_col_status[%2" HIGHSINT_FORMAT
1698
+ "] = %" HIGHSINT_FORMAT "\n",
1699
+ row, ipx_row, ipx_slack,
1700
+ (HighsInt)ipx_col_status[ipx_slack]);
1701
+ }
1702
+ // Update the slack to be used for boxed rows
1703
+ ipx_slack++;
1704
+ } else if (ipx_row_status[ipx_row] == ipx_basic) {
1705
+ // Row is basic
1706
+ highs_basis.row_status[row] = HighsBasisStatus::kBasic;
1707
+ highs_solution.row_value[row] = rhs[ipx_row] - ipx_row_value[ipx_row];
1708
+ highs_solution.row_dual[row] = 0;
1709
+ } else {
1710
+ // Nonbasic row at fixed value, lower bound or upper bound
1711
+ assert(ipx_row_status[ipx_row] ==
1712
+ -1); // const ipx::Int ipx_nonbasic_row = -1;
1713
+ double value = rhs[ipx_row] - ipx_row_value[ipx_row];
1714
+ // @FlipRowDual -ipx_row_dual[ipx_row]; became ipx_row_dual[ipx_row];
1715
+ double dual = ipx_row_dual[ipx_row];
1716
+ if (constraint_type[ipx_row] == '>') {
1717
+ // Row is at its lower bound
1718
+ highs_basis.row_status[row] = HighsBasisStatus::kLower;
1719
+ highs_solution.row_value[row] = value;
1720
+ highs_solution.row_dual[row] = dual;
1721
+ } else if (constraint_type[ipx_row] == '<') {
1722
+ // Row is at its upper bound
1723
+ highs_basis.row_status[row] = HighsBasisStatus::kUpper;
1724
+ highs_solution.row_value[row] = value;
1725
+ highs_solution.row_dual[row] = dual;
1726
+ } else if (constraint_type[ipx_row] == '=') {
1727
+ // Row is at its fixed value: set HighsBasisStatus according
1728
+ // to sign of dual.
1729
+ //
1730
+ // Don't worry about maximization problems. IPX solves them
1731
+ // as minimizations with negated costs, so a negative dual
1732
+ // yields HighsBasisStatus::kUpper here, and dual signs are
1733
+ // then flipped below, so HighsBasisStatus::kUpper will have
1734
+ // corresponding positive dual.
1735
+ highs_basis.row_status[row] =
1736
+ dual >= 0 ? HighsBasisStatus::kLower : HighsBasisStatus::kUpper;
1737
+ highs_solution.row_value[row] = value;
1738
+ highs_solution.row_dual[row] = dual;
1739
+ } else {
1740
+ unrecognised = true;
1741
+ highsLogDev(log_options, HighsLogType::kError,
1742
+ "Error in IPX conversion: Row %2" HIGHSINT_FORMAT
1743
+ ": cannot handle "
1744
+ "constraint_type[%2" HIGHSINT_FORMAT
1745
+ "] = %" HIGHSINT_FORMAT "\n",
1746
+ row, ipx_row, constraint_type[ipx_row]);
1747
+ }
1748
+ }
1749
+ // Update the IPX row index
1750
+ ipx_row++;
1751
+ }
1752
+ if (unrecognised) {
1753
+ highsLogDev(log_options, HighsLogType::kError,
1754
+ "Bounds [%11.4g, %11.4g]\n", lp.row_lower_[row],
1755
+ lp.row_upper_[row]);
1756
+ highsLogDev(log_options, HighsLogType::kError,
1757
+ "Row %2" HIGHSINT_FORMAT " ipx_row_status[%2" HIGHSINT_FORMAT
1758
+ "] = %2" HIGHSINT_FORMAT "; s[%2" HIGHSINT_FORMAT
1759
+ "] = %11.4g; y[%2" HIGHSINT_FORMAT
1760
+ "] = "
1761
+ "%11.4g\n",
1762
+ row, this_ipx_row, (HighsInt)ipx_row_status[this_ipx_row],
1763
+ this_ipx_row, ipx_row_value[this_ipx_row], this_ipx_row,
1764
+ ipx_row_dual[this_ipx_row]);
1765
+ assert(!unrecognised);
1766
+ highsLogUser(log_options, HighsLogType::kError,
1767
+ "Unrecognised ipx_row_status value from IPX\n");
1768
+ return HighsStatus::kError;
1769
+ }
1770
+ if (highs_basis.row_status[row] == HighsBasisStatus::kBasic)
1771
+ num_basic_variables++;
1772
+ }
1773
+ assert(num_basic_variables == lp.num_row_);
1774
+ assert(ipx_row == ipx_solution.num_row);
1775
+ assert(ipx_slack == ipx_solution.num_col);
1776
+
1777
+ if (lp.sense_ == ObjSense::kMaximize) {
1778
+ // Flip dual values since original LP is maximization
1779
+ for (HighsInt iCol = 0; iCol < lp.num_col_; iCol++)
1780
+ highs_solution.col_dual[iCol] *= -1;
1781
+ for (HighsInt iRow = 0; iRow < lp.num_row_; iRow++)
1782
+ highs_solution.row_dual[iRow] *= -1;
1783
+ }
1784
+
1785
+ if (num_boxed_rows)
1786
+ highsLogDev(log_options, HighsLogType::kInfo,
1787
+ "Of %" HIGHSINT_FORMAT " boxed rows: %" HIGHSINT_FORMAT
1788
+ " are basic and %" HIGHSINT_FORMAT " have basic slacks\n",
1789
+ num_boxed_rows, num_boxed_rows_basic,
1790
+ num_boxed_row_slacks_basic);
1791
+ // Indicate that the primal solution, dual solution and basis are valid
1792
+ highs_solution.value_valid = true;
1793
+ highs_solution.dual_valid = true;
1794
+ highs_basis.valid = true;
1795
+ highs_basis.useful = true;
1796
+ return HighsStatus::kOk;
1797
+ }
1798
+
1799
+ HighsStatus formSimplexLpBasisAndFactorReturn(
1800
+ const HighsStatus return_status, HighsLpSolverObject& solver_object) {
1801
+ HighsLp& lp = solver_object.lp_;
1802
+ HighsLp& ekk_lp = solver_object.ekk_instance_.lp_;
1803
+ if (lp.is_moved_) lp.moveBackLpAndUnapplyScaling(ekk_lp);
1804
+ return return_status;
1805
+ }
1806
+
1807
+ HighsStatus formSimplexLpBasisAndFactor(HighsLpSolverObject& solver_object,
1808
+ const bool only_from_known_basis) {
1809
+ // Ideally, forms a SimplexBasis from the HighsBasis in the
1810
+ // HighsLpSolverObject
1811
+ //
1812
+ // If only_from_known_basis is true and
1813
+ // initialiseSimplexLpBasisAndFactor finds that there is no simplex
1814
+ // basis, then its error return is passed down
1815
+ //
1816
+ // If only_from_known_basis is false, then the basis is completed
1817
+ // with logicals if it is rank deficient (from singularity or being
1818
+ // incomplete)
1819
+ //
1820
+ HighsStatus return_status = HighsStatus::kOk;
1821
+ HighsStatus call_status;
1822
+ HighsLp& lp = solver_object.lp_;
1823
+ HighsBasis& basis = solver_object.basis_;
1824
+ HighsOptions& options = solver_object.options_;
1825
+ HEkk& ekk_instance = solver_object.ekk_instance_;
1826
+ HighsSimplexStatus& ekk_status = ekk_instance.status_;
1827
+ lp.ensureColwise();
1828
+ const bool passed_scaled = lp.is_scaled_;
1829
+ // Consider scaling the LP
1830
+ if (!passed_scaled) considerScaling(options, lp);
1831
+ const bool check_basis = basis.alien || (!basis.valid && basis.useful);
1832
+ if (check_basis) {
1833
+ // The basis needs to be checked for rank deficiency, and possibly
1834
+ // completed if it is rectangular
1835
+ //
1836
+ // If it's not valid but useful, but not alien,
1837
+ // accommodateAlienBasis will assert, so make the basis alien
1838
+ basis.alien = true;
1839
+ assert(!only_from_known_basis);
1840
+ accommodateAlienBasis(solver_object);
1841
+ basis.alien = false;
1842
+ // Unapply any scaling used only for factorization to check and
1843
+ // complete the basis
1844
+ if (!passed_scaled) lp.unapplyScale();
1845
+ // Check that any scaling the LP arrived with has not been removed
1846
+ assert(lp.is_scaled_ == passed_scaled);
1847
+ return HighsStatus::kOk;
1848
+ }
1849
+ // Move the HighsLpSolverObject's LP to EKK
1850
+ ekk_instance.moveLp(solver_object);
1851
+ if (!ekk_status.has_basis) {
1852
+ // The Ekk instance has no simplex basis, so pass the HiGHS basis
1853
+ HighsStatus call_status = ekk_instance.setBasis(basis);
1854
+ return_status = interpretCallStatus(options.log_options, call_status,
1855
+ return_status, "setBasis");
1856
+ if (return_status == HighsStatus::kError)
1857
+ return formSimplexLpBasisAndFactorReturn(return_status, solver_object);
1858
+ }
1859
+ // Now form the invert
1860
+ assert(ekk_status.has_basis);
1861
+ call_status =
1862
+ ekk_instance.initialiseSimplexLpBasisAndFactor(only_from_known_basis);
1863
+ // If the current basis cannot be inverted, return an error
1864
+ if (call_status != HighsStatus::kOk)
1865
+ return formSimplexLpBasisAndFactorReturn(HighsStatus::kError,
1866
+ solver_object);
1867
+ // Once the invert is formed, move back the LP and remove any scaling.
1868
+ return formSimplexLpBasisAndFactorReturn(HighsStatus::kOk, solver_object);
1869
+ }
1870
+
1871
+ void accommodateAlienBasis(HighsLpSolverObject& solver_object) {
1872
+ HighsLp& lp = solver_object.lp_;
1873
+ HighsBasis& basis = solver_object.basis_;
1874
+ HighsOptions& options = solver_object.options_;
1875
+ assert(basis.alien);
1876
+ HighsInt num_row = lp.num_row_;
1877
+ HighsInt num_col = lp.num_col_;
1878
+ assert((int)basis.col_status.size() >= num_col);
1879
+ assert((int)basis.row_status.size() >= num_row);
1880
+ std::vector<HighsInt> basic_index;
1881
+ for (HighsInt iCol = 0; iCol < num_col; iCol++) {
1882
+ if (basis.col_status[iCol] == HighsBasisStatus::kBasic)
1883
+ basic_index.push_back(iCol);
1884
+ }
1885
+ for (HighsInt iRow = 0; iRow < num_row; iRow++) {
1886
+ if (basis.row_status[iRow] == HighsBasisStatus::kBasic)
1887
+ basic_index.push_back(num_col + iRow);
1888
+ }
1889
+ HighsInt num_basic_variables = basic_index.size();
1890
+ HFactor factor;
1891
+ factor.setupGeneral(&lp.a_matrix_, num_basic_variables, basic_index.data(),
1892
+ kDefaultPivotThreshold, kDefaultPivotTolerance,
1893
+ kHighsDebugLevelMin, &options.log_options);
1894
+ HighsInt rank_deficiency = factor.build();
1895
+ // Must not have timed out
1896
+ assert(rank_deficiency >= 0);
1897
+ // Deduce the basis from basic_index
1898
+ //
1899
+ // Set all basic variables to nonbasic
1900
+ for (HighsInt iCol = 0; iCol < num_col; iCol++) {
1901
+ if (basis.col_status[iCol] == HighsBasisStatus::kBasic)
1902
+ basis.col_status[iCol] = HighsBasisStatus::kNonbasic;
1903
+ }
1904
+ for (HighsInt iRow = 0; iRow < num_row; iRow++) {
1905
+ if (basis.row_status[iRow] == HighsBasisStatus::kBasic)
1906
+ basis.row_status[iRow] = HighsBasisStatus::kNonbasic;
1907
+ }
1908
+ // Set at most the first num_row variables in basic_index to basic
1909
+ const HighsInt use_basic_variables = std::min(num_row, num_basic_variables);
1910
+ // num_basic_variables is no longer needed, so can be used as a check
1911
+ num_basic_variables = 0;
1912
+ for (HighsInt iRow = 0; iRow < use_basic_variables; iRow++) {
1913
+ HighsInt iVar = basic_index[iRow];
1914
+ if (iVar < num_col) {
1915
+ basis.col_status[iVar] = HighsBasisStatus::kBasic;
1916
+ } else {
1917
+ basis.row_status[iVar - num_col] = HighsBasisStatus::kBasic;
1918
+ }
1919
+ num_basic_variables++;
1920
+ }
1921
+ // Complete the assignment of basic variables using the logicals of
1922
+ // non-pivotal rows
1923
+ const HighsInt num_missing = num_row - num_basic_variables;
1924
+ for (HighsInt k = 0; k < num_missing; k++) {
1925
+ HighsInt iRow = factor.row_with_no_pivot[rank_deficiency + k];
1926
+ basis.row_status[iRow] = HighsBasisStatus::kBasic;
1927
+ num_basic_variables++;
1928
+ }
1929
+ assert(num_basic_variables == num_row);
1930
+ }
1931
+
1932
+ void resetModelStatusAndHighsInfo(HighsLpSolverObject& solver_object) {
1933
+ resetModelStatusAndHighsInfo(solver_object.model_status_,
1934
+ solver_object.highs_info_);
1935
+ }
1936
+
1937
+ void resetModelStatusAndHighsInfo(HighsModelStatus& model_status,
1938
+ HighsInfo& highs_info) {
1939
+ model_status = HighsModelStatus::kNotset;
1940
+ highs_info.objective_function_value = 0;
1941
+ highs_info.primal_solution_status = kSolutionStatusNone;
1942
+ highs_info.dual_solution_status = kSolutionStatusNone;
1943
+ highs_info.invalidateKkt();
1944
+ }
1945
+
1946
+ bool isBasisConsistent(const HighsLp& lp, const HighsBasis& basis) {
1947
+ if (!isBasisRightSize(lp, basis)) return false;
1948
+
1949
+ HighsInt num_basic_variables = 0;
1950
+ for (HighsInt iCol = 0; iCol < lp.num_col_; iCol++) {
1951
+ if (basis.col_status[iCol] == HighsBasisStatus::kBasic)
1952
+ num_basic_variables++;
1953
+ }
1954
+ for (HighsInt iRow = 0; iRow < lp.num_row_; iRow++) {
1955
+ if (basis.row_status[iRow] == HighsBasisStatus::kBasic)
1956
+ num_basic_variables++;
1957
+ }
1958
+ return num_basic_variables == lp.num_row_;
1959
+ }
1960
+
1961
+ bool isColPrimalSolutionRightSize(const HighsLp& lp,
1962
+ const HighsSolution& solution) {
1963
+ return solution.col_value.size() == static_cast<size_t>(lp.num_col_);
1964
+ }
1965
+
1966
+ bool isRowPrimalSolutionRightSize(const HighsLp& lp,
1967
+ const HighsSolution& solution) {
1968
+ return solution.row_value.size() == static_cast<size_t>(lp.num_row_);
1969
+ }
1970
+
1971
+ bool isPrimalSolutionRightSize(const HighsLp& lp,
1972
+ const HighsSolution& solution) {
1973
+ return isColPrimalSolutionRightSize(lp, solution) &&
1974
+ isRowPrimalSolutionRightSize(lp, solution);
1975
+ }
1976
+
1977
+ bool isColDualSolutionRightSize(const HighsLp& lp,
1978
+ const HighsSolution& solution) {
1979
+ return solution.col_dual.size() == static_cast<size_t>(lp.num_col_);
1980
+ }
1981
+
1982
+ bool isRowDualSolutionRightSize(const HighsLp& lp,
1983
+ const HighsSolution& solution) {
1984
+ return solution.row_dual.size() == static_cast<size_t>(lp.num_row_);
1985
+ }
1986
+
1987
+ bool isDualSolutionRightSize(const HighsLp& lp, const HighsSolution& solution) {
1988
+ return isColDualSolutionRightSize(lp, solution) &&
1989
+ isRowDualSolutionRightSize(lp, solution);
1990
+ }
1991
+
1992
+ bool isSolutionRightSize(const HighsLp& lp, const HighsSolution& solution) {
1993
+ return isPrimalSolutionRightSize(lp, solution) &&
1994
+ isDualSolutionRightSize(lp, solution);
1995
+ }
1996
+
1997
+ bool isBasisRightSize(const HighsLp& lp, const HighsBasis& basis) {
1998
+ return basis.col_status.size() == static_cast<size_t>(lp.num_col_) &&
1999
+ basis.row_status.size() == static_cast<size_t>(lp.num_row_);
2000
+ }
2001
+
2002
+ bool reportKktFailures(const HighsLp& lp, const HighsOptions& options,
2003
+ const HighsInfo& info, const std::string& message) {
2004
+ const HighsLogOptions& log_options = options.log_options;
2005
+ double mip_feasibility_tolerance = options.mip_feasibility_tolerance;
2006
+ double primal_feasibility_tolerance = options.primal_feasibility_tolerance;
2007
+ double dual_feasibility_tolerance = options.dual_feasibility_tolerance;
2008
+ double primal_residual_tolerance = options.primal_residual_tolerance;
2009
+ double dual_residual_tolerance = options.dual_residual_tolerance;
2010
+ double optimality_tolerance = options.optimality_tolerance;
2011
+ const bool is_mip = lp.isMip();
2012
+ if (is_mip) {
2013
+ primal_feasibility_tolerance = mip_feasibility_tolerance;
2014
+ } else if (options.kkt_tolerance != kDefaultKktTolerance) {
2015
+ mip_feasibility_tolerance = options.kkt_tolerance;
2016
+ primal_feasibility_tolerance = options.kkt_tolerance;
2017
+ dual_feasibility_tolerance = options.kkt_tolerance;
2018
+ primal_residual_tolerance = options.kkt_tolerance;
2019
+ dual_residual_tolerance = options.kkt_tolerance;
2020
+ optimality_tolerance = options.kkt_tolerance;
2021
+ }
2022
+
2023
+ const bool force_report = options.log_dev_level >= kHighsLogDevLevelInfo;
2024
+ const bool complementarity_error =
2025
+ !is_mip && info.primal_dual_objective_error > optimality_tolerance;
2026
+ const bool integrality_error =
2027
+ is_mip && info.max_integrality_violation >= mip_feasibility_tolerance;
2028
+ const bool has_kkt_failures =
2029
+ integrality_error || info.num_primal_infeasibilities > 0 ||
2030
+ info.num_dual_infeasibilities > 0 ||
2031
+ info.num_primal_residual_errors > 0 ||
2032
+ info.num_dual_residual_errors > 0 || complementarity_error;
2033
+ if (!has_kkt_failures && !force_report) return has_kkt_failures;
2034
+
2035
+ HighsLogType log_type =
2036
+ has_kkt_failures ? HighsLogType::kWarning : HighsLogType::kInfo;
2037
+
2038
+ highsLogUser(log_options, log_type, "Solution optimality conditions%s%s\n",
2039
+ message == "" ? "" : ": ", message == "" ? "" : message.c_str());
2040
+ if (is_mip && info.max_integrality_violation >= 0)
2041
+ highsLogUser(log_options, HighsLogType::kInfo,
2042
+ " max %8.3g "
2043
+ "integrality violations"
2044
+ " (tolerance = %4.0e)\n",
2045
+ info.max_integrality_violation, mip_feasibility_tolerance);
2046
+ if (info.num_primal_infeasibilities >= 0)
2047
+ highsLogUser(
2048
+ log_options, HighsLogType::kInfo,
2049
+ "num/max %6d / %8.3g (relative %6d / %8.3g) primal "
2050
+ "infeasibilities (tolerance = %4.0e)\n",
2051
+ int(info.num_primal_infeasibilities), info.max_primal_infeasibility,
2052
+ int(info.num_relative_primal_infeasibilities),
2053
+ info.max_relative_primal_infeasibility, primal_feasibility_tolerance);
2054
+ if (info.num_dual_infeasibilities >= 0)
2055
+ highsLogUser(
2056
+ log_options, HighsLogType::kInfo,
2057
+ "num/max %6d / %8.3g (relative %6d / %8.3g) dual "
2058
+ "infeasibilities (tolerance = %4.0e)\n",
2059
+ int(info.num_dual_infeasibilities), info.max_dual_infeasibility,
2060
+ int(info.num_relative_dual_infeasibilities),
2061
+ info.max_relative_dual_infeasibility, dual_feasibility_tolerance);
2062
+ if (info.num_primal_residual_errors >= 0)
2063
+ highsLogUser(
2064
+ log_options, HighsLogType::kInfo,
2065
+ "num/max %6d / %8.3g (relative %6d / %8.3g) primal residual "
2066
+ "errors (tolerance = %4.0e)\n",
2067
+ int(info.num_primal_residual_errors), info.max_primal_residual_error,
2068
+ int(info.num_relative_primal_residual_errors),
2069
+ info.max_relative_primal_residual_error, primal_residual_tolerance);
2070
+ if (info.num_dual_residual_errors >= 0)
2071
+ highsLogUser(
2072
+ log_options, HighsLogType::kInfo,
2073
+ "num/max %6d / %8.3g (relative %6d / %8.3g) dual residual "
2074
+ "errors (tolerance = %4.0e)\n",
2075
+ int(info.num_dual_residual_errors), info.max_dual_residual_error,
2076
+ int(info.num_relative_dual_residual_errors),
2077
+ info.max_relative_dual_residual_error, dual_residual_tolerance);
2078
+ if (info.primal_dual_objective_error !=
2079
+ kHighsIllegalComplementarityViolation) {
2080
+ highsLogUser(
2081
+ log_options, HighsLogType::kInfo,
2082
+ " "
2083
+ " %1d / %8.3g P-D objective error "
2084
+ "(tolerance = %4.0e)\n",
2085
+ info.primal_dual_objective_error > optimality_tolerance ? 1 : 0,
2086
+ info.primal_dual_objective_error, optimality_tolerance);
2087
+ }
2088
+ if (printf_kkt) {
2089
+ printf("grepKktFailures,%s,%s,%s,%g,%d,%d,%d,%d,%d,%d,%d,%d,%g\n",
2090
+ options.solver.c_str(), lp.model_name_.c_str(),
2091
+ lp.origin_name_.c_str(), info.max_integrality_violation,
2092
+ int(info.num_primal_infeasibilities),
2093
+ int(info.num_dual_infeasibilities),
2094
+ int(info.num_primal_residual_errors),
2095
+ int(info.num_dual_residual_errors),
2096
+ int(info.num_relative_primal_infeasibilities),
2097
+ int(info.num_relative_dual_infeasibilities),
2098
+ int(info.num_relative_primal_residual_errors),
2099
+ int(info.num_relative_dual_residual_errors),
2100
+ info.primal_dual_objective_error);
2101
+ }
2102
+ return has_kkt_failures;
2103
+ }
2104
+
2105
+ bool HighsSolution::hasUndefined() const {
2106
+ for (double value : this->col_value)
2107
+ if (value == kHighsUndefined) return true;
2108
+ return false;
2109
+ }
2110
+
2111
+ void HighsSolution::invalidate() {
2112
+ this->value_valid = false;
2113
+ this->dual_valid = false;
2114
+ }
2115
+
2116
+ void HighsSolution::clear() {
2117
+ this->invalidate();
2118
+ this->col_value.clear();
2119
+ this->row_value.clear();
2120
+ this->col_dual.clear();
2121
+ this->row_dual.clear();
2122
+ }
2123
+
2124
+ void HighsSolution::print(const std::string& prefix,
2125
+ const std::string& message) const {
2126
+ HighsInt num_col = this->col_value.size();
2127
+ HighsInt num_row = this->row_value.size();
2128
+ printf("%s HighsSolution(num_col = %d, num_row = %d): %s\n", prefix.c_str(),
2129
+ int(num_col), int(num_row), message.c_str());
2130
+ for (HighsInt iCol = 0; iCol < num_col; iCol++)
2131
+ printf("%s col_value[%3d] = %11.4g\n", prefix.c_str(), int(iCol),
2132
+ this->col_value[iCol]);
2133
+ for (HighsInt iRow = 0; iRow < num_row; iRow++)
2134
+ printf("%s row_value[%3d] = %11.4g\n", prefix.c_str(), int(iRow),
2135
+ this->row_value[iRow]);
2136
+
2137
+ num_col = this->col_dual.size();
2138
+ num_row = this->row_dual.size();
2139
+ printf("%s HighsSolution(num_col = %d, num_row = %d): %s\n", prefix.c_str(),
2140
+ int(num_col), int(num_row), message.c_str());
2141
+ for (HighsInt iCol = 0; iCol < num_col; iCol++)
2142
+ printf("%s col_dual[%3d] = %11.4g\n", prefix.c_str(), int(iCol),
2143
+ this->col_dual[iCol]);
2144
+ for (HighsInt iRow = 0; iRow < num_row; iRow++)
2145
+ printf("%s row_dual[%3d] = %11.4g\n", prefix.c_str(), int(iRow),
2146
+ this->row_dual[iRow]);
2147
+ }
2148
+
2149
+ void HighsObjectiveSolution::clear() { this->col_value.clear(); }
2150
+
2151
+ void HighsBasis::print(const std::string& prefix,
2152
+ const std::string& message) const {
2153
+ this->printScalars(prefix, message);
2154
+ if (!this->useful) return;
2155
+ for (HighsInt iCol = 0; iCol < HighsInt(this->col_status.size()); iCol++)
2156
+ printf("%s HighsBasis: col_status[%2d] = %d\n", prefix.c_str(), int(iCol),
2157
+ int(this->col_status[iCol]));
2158
+ for (HighsInt iRow = 0; iRow < HighsInt(this->row_status.size()); iRow++)
2159
+ printf("%s HighsBasis: row_status[%2d] = %d\n", prefix.c_str(), int(iRow),
2160
+ int(this->row_status[iRow]));
2161
+ }
2162
+
2163
+ void HighsBasis::printScalars(const std::string& prefix,
2164
+ const std::string& message) const {
2165
+ HighsInt num_col = this->col_status.size();
2166
+ HighsInt num_row = this->row_status.size();
2167
+ printf("\n%s HighsBasis(num_col = %d, num_row = %d): %s\n", prefix.c_str(),
2168
+ int(num_col), int(num_row), message.c_str());
2169
+ printf("%s valid = %d\n", prefix.c_str(), this->valid);
2170
+ printf("%s alien = %d\n", prefix.c_str(), this->alien);
2171
+ printf("%s useful = %d\n", prefix.c_str(), this->useful);
2172
+ printf("%s was_alien = %d\n", prefix.c_str(), this->was_alien);
2173
+ printf("%s debug_id = %d\n", prefix.c_str(), int(this->debug_id));
2174
+ printf("%s debug_update_count = %d\n", prefix.c_str(),
2175
+ int(this->debug_update_count));
2176
+ printf("%s debug_origin_name = %s\n", prefix.c_str(),
2177
+ this->debug_origin_name.c_str());
2178
+ }
2179
+
2180
+ void HighsBasis::invalidate() {
2181
+ this->valid = false;
2182
+ this->alien = true;
2183
+ this->useful = false;
2184
+ this->was_alien = true;
2185
+ this->debug_id = -1;
2186
+ this->debug_update_count = -1;
2187
+ this->debug_origin_name = "None";
2188
+ }
2189
+
2190
+ void HighsBasis::clear() {
2191
+ this->invalidate();
2192
+ this->row_status.clear();
2193
+ this->col_status.clear();
2194
+ }