lpsolver 0.1.0 → 0.2.1

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 +104 -26
  4. data/ext/lpsolver/Makefile +269 -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 +35 -7
  1160. data/lib/lpsolver/native.so +0 -0
  1161. data/lib/lpsolver/native_model.rb +261 -0
  1162. data/lib/lpsolver/solution.rb +93 -8
  1163. data/lib/lpsolver/version.rb +1 -1
  1164. data/lpsolver.gemspec +4 -1
  1165. metadata +1176 -4
@@ -0,0 +1,2597 @@
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 util/HFactor.cpp
9
+ * @brief Types of solution classes
10
+ */
11
+ #include "util/HFactor.h"
12
+
13
+ #include <cassert>
14
+ #include <iostream>
15
+
16
+ #include "../extern/pdqsort/pdqsort.h"
17
+ #include "lp_data/HConst.h"
18
+ #include "util/FactorTimer.h"
19
+ #include "util/HFactorDebug.h"
20
+ #include "util/HVector.h"
21
+ #include "util/HVectorBase.h"
22
+ #include "util/HighsTimer.h"
23
+
24
+ // std::vector, std::max and std::min used in HFactor.h for local
25
+ // in-line functions, so HFactor.h has #include <algorithm>
26
+ using std::fabs;
27
+
28
+ using std::copy;
29
+ using std::fill_n;
30
+ using std::make_pair;
31
+ using std::min;
32
+ using std::pair;
33
+
34
+ static void solveMatrixT(const HighsInt X_Start, const HighsInt x_end,
35
+ const HighsInt y_start, const HighsInt y_end,
36
+ const HighsInt* t_index, const double* t_value,
37
+ const double t_pivot, HighsInt* rhs_count,
38
+ HighsInt* rhs_index, double* rhs_array) {
39
+ // Collect by X
40
+ double pivot_multiplier = 0;
41
+ for (HighsInt k = X_Start; k < x_end; k++)
42
+ pivot_multiplier += t_value[k] * rhs_array[t_index[k]];
43
+
44
+ // Scatter by Y
45
+ if (fabs(pivot_multiplier) > kHighsTiny) {
46
+ HighsInt work_count = *rhs_count;
47
+
48
+ pivot_multiplier /= t_pivot;
49
+ for (HighsInt k = y_start; k < y_end; k++) {
50
+ const HighsInt index = t_index[k];
51
+ const double value0 = rhs_array[index];
52
+ const double value1 = value0 - pivot_multiplier * t_value[k];
53
+ if (value0 == 0) rhs_index[work_count++] = index;
54
+ rhs_array[index] = (fabs(value1) < kHighsTiny) ? kHighsZero : value1;
55
+ }
56
+
57
+ *rhs_count = work_count;
58
+ }
59
+ }
60
+
61
+ static void solveHyper(const HighsInt h_size, const HighsInt* h_lookup,
62
+ const HighsInt* h_pivot_index,
63
+ const double* h_pivot_value, const HighsInt* h_start,
64
+ const HighsInt* h_end, const HighsInt* h_index,
65
+ const double* h_value, HVector* rhs) {
66
+ HighsInt rhs_count = rhs->count;
67
+ HighsInt* rhs_index = rhs->index.data();
68
+ double* rhs_array = rhs->array.data();
69
+
70
+ // Take count
71
+
72
+ // Build list
73
+ char* list_mark = rhs->cwork.data();
74
+ HighsInt* list_index = rhs->iwork.data();
75
+ HighsInt* list_stack = &rhs->iwork[h_size];
76
+ HighsInt list_count = 0;
77
+
78
+ HighsInt count_pivot = 0;
79
+ HighsInt count_entry = 0;
80
+
81
+ for (HighsInt i = 0; i < rhs_count; i++) {
82
+ // Skip touched index
83
+ HighsInt i_trans =
84
+ h_lookup[rhs_index[i]]; // XXX: this contains a bug iTran
85
+ if (list_mark[i_trans]) // XXX bug here
86
+ continue;
87
+
88
+ HighsInt Hi = i_trans; // H matrix pivot index
89
+ HighsInt Hk = h_start[Hi]; // H matrix non zero position
90
+ HighsInt n_stack = -1; // Usage of the stack (-1 not used)
91
+
92
+ list_mark[Hi] = 1; // Mark this as touched
93
+
94
+ for (;;) {
95
+ if (Hk < h_end[Hi]) {
96
+ HighsInt Hi_sub = h_lookup[h_index[Hk++]];
97
+ if (list_mark[Hi_sub] == 0) { // Go to a child
98
+ list_mark[Hi_sub] = 1; // Mark as touched
99
+ list_stack[++n_stack] = Hi; // Store current into stack
100
+ list_stack[++n_stack] = Hk;
101
+ Hi = Hi_sub; // Replace current with child
102
+ Hk = h_start[Hi];
103
+ if (Hi >= h_size) {
104
+ count_pivot++;
105
+ count_entry += h_end[Hi] - h_start[Hi];
106
+ }
107
+ }
108
+ } else {
109
+ list_index[list_count++] = Hi;
110
+ if (n_stack == -1) // Quit on empty stack
111
+ break;
112
+ Hk = list_stack[n_stack--]; // Back to last in stack
113
+ Hi = list_stack[n_stack--];
114
+ }
115
+ }
116
+ }
117
+
118
+ rhs->synthetic_tick += count_pivot * 20 + count_entry * 10;
119
+
120
+ // Solve with list
121
+ if (h_pivot_value == 0) {
122
+ rhs_count = 0;
123
+ for (HighsInt iList = list_count - 1; iList >= 0; iList--) {
124
+ HighsInt i = list_index[iList];
125
+ list_mark[i] = 0;
126
+ HighsInt pivotRow = h_pivot_index[i];
127
+ double pivot_multiplier = rhs_array[pivotRow];
128
+ if (fabs(pivot_multiplier) > kHighsTiny) {
129
+ rhs_index[rhs_count++] = pivotRow;
130
+ const HighsInt start = h_start[i];
131
+ const HighsInt end = h_end[i];
132
+ for (HighsInt k = start; k < end; k++)
133
+ rhs_array[h_index[k]] -= pivot_multiplier * h_value[k];
134
+ } else
135
+ rhs_array[pivotRow] = 0;
136
+ }
137
+ rhs->count = rhs_count;
138
+ } else {
139
+ rhs_count = 0;
140
+ for (HighsInt iList = list_count - 1; iList >= 0; iList--) {
141
+ HighsInt i = list_index[iList];
142
+ list_mark[i] = 0;
143
+ HighsInt pivotRow = h_pivot_index[i];
144
+ double pivot_multiplier = rhs_array[pivotRow];
145
+ if (fabs(pivot_multiplier) > kHighsTiny) {
146
+ pivot_multiplier /= h_pivot_value[i];
147
+ rhs_array[pivotRow] = pivot_multiplier;
148
+ rhs_index[rhs_count++] = pivotRow;
149
+ const HighsInt start = h_start[i];
150
+ const HighsInt end = h_end[i];
151
+ for (HighsInt k = start; k < end; k++)
152
+ rhs_array[h_index[k]] -= pivot_multiplier * h_value[k];
153
+ } else
154
+ rhs_array[pivotRow] = 0;
155
+ }
156
+ rhs->count = rhs_count;
157
+ }
158
+ }
159
+
160
+ void HFactor::setup(const HighsSparseMatrix& a_matrix,
161
+ std::vector<HighsInt>& basic_index,
162
+ const double pivot_threshold, const double pivot_tolerance,
163
+ const HighsInt highs_debug_level,
164
+ const HighsLogOptions* log_options) {
165
+ HighsInt basic_index_size = basic_index.size();
166
+ // Nothing to do if basic index has no entries, and mustn't try to
167
+ // pass the pointer to entry 0 of a vector of size 0.
168
+ if (basic_index_size <= 0) return;
169
+ this->setupGeneral(&a_matrix, basic_index_size, basic_index.data(),
170
+ pivot_threshold, pivot_tolerance, highs_debug_level,
171
+ log_options);
172
+ return;
173
+ }
174
+
175
+ void HFactor::setupGeneral(const HighsSparseMatrix* a_matrix,
176
+ HighsInt num_basic, HighsInt* basic_index,
177
+ const double pivot_threshold,
178
+ const double pivot_tolerance,
179
+ const HighsInt highs_debug_level,
180
+ const HighsLogOptions* log_options) {
181
+ this->setupGeneral(a_matrix->num_col_, a_matrix->num_row_, num_basic,
182
+ a_matrix->start_.data(), a_matrix->index_.data(),
183
+ a_matrix->value_.data(), basic_index, pivot_threshold,
184
+ pivot_tolerance, highs_debug_level, log_options, true,
185
+ kUpdateMethodFt);
186
+ }
187
+
188
+ void HFactor::setup(
189
+ const HighsInt num_col_, const HighsInt num_row_, const HighsInt* a_start_,
190
+ const HighsInt* a_index_, const double* a_value_, HighsInt* basic_index_,
191
+ const double pivot_threshold_, const double pivot_tolerance_,
192
+ const HighsInt highs_debug_level_, const HighsLogOptions* log_options_,
193
+ const bool use_original_HFactor_logic_, const HighsInt update_method_) {
194
+ setupGeneral(num_col_, num_row_, num_row_, a_start_, a_index_, a_value_,
195
+ basic_index_, pivot_threshold_, pivot_tolerance_,
196
+ highs_debug_level_, log_options_, use_original_HFactor_logic_,
197
+ update_method_);
198
+ }
199
+
200
+ void HFactor::setupGeneral(
201
+ const HighsInt num_col_, const HighsInt num_row_, HighsInt num_basic_,
202
+ const HighsInt* a_start_, const HighsInt* a_index_, const double* a_value_,
203
+ HighsInt* basic_index_, const double pivot_threshold_,
204
+ const double pivot_tolerance_, const HighsInt highs_debug_level_,
205
+ const HighsLogOptions* log_options_, const bool use_original_HFactor_logic_,
206
+ const HighsInt update_method_) {
207
+ // Copy Problem size and (pointer to) coefficient matrix
208
+ num_row = num_row_;
209
+ num_col = num_col_;
210
+ num_basic = num_basic_;
211
+ inv_num_row = 1.0 / num_row;
212
+ this->a_matrix_valid = true;
213
+ a_start = a_start_;
214
+ a_index = a_index_;
215
+ a_value = a_value_;
216
+ basic_index = basic_index_;
217
+ pivot_threshold =
218
+ max(kMinPivotThreshold, min(pivot_threshold_, kMaxPivotThreshold));
219
+ pivot_tolerance =
220
+ max(kMinPivotTolerance, min(pivot_tolerance_, kMaxPivotTolerance));
221
+ highs_debug_level = highs_debug_level_;
222
+ time_limit_ = kHighsInf;
223
+ log_data = decltype(log_data)(new LogData());
224
+ log_options.output_flag = &log_data->output_flag;
225
+ log_options.log_to_console = &log_data->log_to_console;
226
+ log_options.log_dev_level = &log_data->log_dev_level;
227
+
228
+ if (!log_options_) {
229
+ log_data->output_flag = false;
230
+ log_data->log_to_console = true;
231
+ log_data->log_dev_level = 0;
232
+ log_options.log_stream = nullptr;
233
+ } else {
234
+ log_data->output_flag = *(log_options_->output_flag);
235
+ log_data->log_to_console = *(log_options_->log_to_console);
236
+ log_data->log_dev_level = *(log_options_->log_dev_level);
237
+ log_options.log_stream = log_options_->log_stream;
238
+ }
239
+
240
+ use_original_HFactor_logic = use_original_HFactor_logic_;
241
+ update_method = update_method_;
242
+
243
+ // Allocate for working buffer
244
+ iwork.reserve(num_row * 2);
245
+ dwork.assign(num_row, 0);
246
+
247
+ // Find Basis matrix limit size
248
+ basis_matrix_limit_size = 0;
249
+
250
+ iwork.assign(num_row + 1, 0);
251
+ for (HighsInt i = 0; i < num_col; i++) iwork[a_start[i + 1] - a_start[i]]++;
252
+ const HighsInt b_max_dim = max(num_row, num_basic);
253
+ for (HighsInt i = num_row, counted = 0; i >= 0 && counted < b_max_dim; i--)
254
+ basis_matrix_limit_size += i * iwork[i], counted += iwork[i];
255
+ basis_matrix_limit_size += b_max_dim;
256
+
257
+ // Allocate space for basis matrix, L, U factor and Update buffer
258
+ b_var.resize(b_max_dim);
259
+ b_start.resize(b_max_dim + 1, 0);
260
+ b_index.resize(basis_matrix_limit_size);
261
+ b_value.resize(basis_matrix_limit_size);
262
+
263
+ // Allocate space for pivot records
264
+ const HighsInt permute_max_dim = max(num_row, num_basic);
265
+ permute.resize(permute_max_dim);
266
+
267
+ // Allocate space for Markowitz matrices
268
+ const HighsInt mc_dim = num_basic;
269
+ mc_var.resize(mc_dim);
270
+ mc_start.resize(mc_dim);
271
+ mc_count_a.resize(mc_dim);
272
+ mc_count_n.resize(mc_dim);
273
+ mc_space.resize(mc_dim);
274
+ mc_min_pivot.resize(mc_dim);
275
+ mc_index.resize(basis_matrix_limit_size * kMCExtraEntriesMultiplier);
276
+ mc_value.resize(basis_matrix_limit_size * kMCExtraEntriesMultiplier);
277
+
278
+ mr_start.resize(num_row);
279
+ mr_count.resize(num_row);
280
+ mr_space.resize(num_row);
281
+ mr_count_before.resize(num_row);
282
+ mr_index.resize(basis_matrix_limit_size * kMRExtraEntriesMultiplier);
283
+
284
+ mwz_column_mark.assign(num_row, 0);
285
+ mwz_column_index.resize(num_row);
286
+ mwz_column_array.assign(num_row, 0);
287
+
288
+ // Allocate space for count-link-list
289
+ const HighsInt col_link_max_count = num_row;
290
+ const HighsInt col_link_dim = num_basic;
291
+ col_link_first.assign(col_link_max_count + 1, -1);
292
+ col_link_next.resize(col_link_dim);
293
+ col_link_last.resize(col_link_dim);
294
+
295
+ const HighsInt row_link_max_count = num_basic;
296
+ const HighsInt row_link_dim = num_row;
297
+ // Strictly not necessary, but nice if it's the right size
298
+ row_link_first.resize(row_link_max_count + 1);
299
+ row_link_first.assign(row_link_max_count + 1, -1);
300
+ row_link_next.resize(row_link_dim);
301
+ row_link_last.resize(row_link_dim);
302
+
303
+ // Allocate space for L factor
304
+ l_pivot_lookup.resize(num_row);
305
+ l_pivot_index.reserve(num_row);
306
+ l_start.reserve(num_row + 1);
307
+ l_index.reserve(basis_matrix_limit_size * kLFactorExtraEntriesMultiplier);
308
+ l_value.reserve(basis_matrix_limit_size * kLFactorExtraEntriesMultiplier);
309
+
310
+ lr_start.reserve(num_row + 1);
311
+ lr_index.reserve(basis_matrix_limit_size * kLFactorExtraEntriesMultiplier);
312
+ lr_value.reserve(basis_matrix_limit_size * kLFactorExtraEntriesMultiplier);
313
+
314
+ // Allocate space for U factor
315
+ u_pivot_lookup.resize(num_row);
316
+ u_pivot_index.reserve(num_row + kUFactorExtraVectors);
317
+ u_pivot_value.reserve(num_row + kUFactorExtraVectors);
318
+
319
+ u_start.reserve(num_row + kUFactorExtraVectors + 1);
320
+ u_last_p.reserve(num_row + kUFactorExtraVectors);
321
+ u_index.reserve(basis_matrix_limit_size * kUFactorExtraEntriesMultiplier);
322
+ u_value.reserve(basis_matrix_limit_size * kUFactorExtraEntriesMultiplier);
323
+
324
+ ur_start.reserve(num_row + kUFactorExtraVectors + 1);
325
+ ur_lastp.reserve(num_row + kUFactorExtraVectors);
326
+ ur_space.reserve(num_row + kUFactorExtraVectors);
327
+ ur_index.reserve(basis_matrix_limit_size * kUFactorExtraEntriesMultiplier);
328
+ ur_value.reserve(basis_matrix_limit_size * kUFactorExtraEntriesMultiplier);
329
+
330
+ // Allocate spaces for Update buffer
331
+ pf_pivot_value.reserve(kPFFPivotEntries);
332
+ pf_pivot_index.reserve(kPFFPivotEntries);
333
+ pf_start.reserve(kPFVectors + 1);
334
+ pf_index.reserve(basis_matrix_limit_size * kPFEntriesMultiplier);
335
+ pf_value.reserve(basis_matrix_limit_size * kPFEntriesMultiplier);
336
+
337
+ // Set up the local HVector for use when RHS is
338
+ // std::vector<double>.
339
+ rhs_.setup(num_row);
340
+ rhs_.count = -1;
341
+ }
342
+
343
+ void HFactor::setupMatrix(const HighsInt* a_start_, const HighsInt* a_index_,
344
+ const double* a_value_) {
345
+ a_start = a_start_;
346
+ a_index = a_index_;
347
+ a_value = a_value_;
348
+ this->a_matrix_valid = true;
349
+ }
350
+
351
+ void HFactor::setupMatrix(const HighsSparseMatrix* a_matrix) {
352
+ setupMatrix(a_matrix->start_.data(), a_matrix->index_.data(),
353
+ a_matrix->value_.data());
354
+ }
355
+
356
+ HighsInt HFactor::build(HighsTimerClock* factor_timer_clock_pointer) {
357
+ // Set up a timer to prevent build running longer than time_limit_,
358
+ // which is kHighsInf by default, and only set to a finite value in
359
+ // HPresolve::removeDependentEquations
360
+ HighsTimer build_timer;
361
+ build_timer_ = &build_timer;
362
+ build_timer.start();
363
+
364
+ const bool report_lu = false;
365
+ // Ensure that the A matrix is valid for factorization
366
+ assert(this->a_matrix_valid);
367
+ FactorTimer factor_timer;
368
+ // Possibly use the refactorization information!
369
+ if (refactor_info_.use) {
370
+ factor_timer.start(FactorReinvert, factor_timer_clock_pointer);
371
+ rank_deficiency = rebuild(factor_timer_clock_pointer);
372
+ factor_timer.stop(FactorReinvert, factor_timer_clock_pointer);
373
+ if (!rank_deficiency) return 0;
374
+ }
375
+ // Refactoring from just the list of basic variables. Initialise the
376
+ // refactorization information.
377
+ refactor_info_.clear();
378
+ // Start the timer
379
+ factor_timer.start(FactorInvert, factor_timer_clock_pointer);
380
+ build_synthetic_tick = 0;
381
+ factor_timer.start(FactorInvertSimple, factor_timer_clock_pointer);
382
+ // Build the L, U factor
383
+ buildSimple();
384
+ if (report_lu) {
385
+ printf("\nAfter units and singletons\n");
386
+ reportLu(kReportLuBoth, false);
387
+ }
388
+ factor_timer.stop(FactorInvertSimple, factor_timer_clock_pointer);
389
+ factor_timer.start(FactorInvertKernel, factor_timer_clock_pointer);
390
+ const HighsInt build_kernel_return = buildKernel();
391
+ factor_timer.stop(FactorInvertKernel, factor_timer_clock_pointer);
392
+ //
393
+ // build_kernel_return of kBuildKernelReturnTimeout (<0) indicates
394
+ // that time limit has been reached, otherwise it's the rank
395
+ // deficiency of the basic variables. If num_basic < num_row, then
396
+ // have to identify the logicals required to complete the basis by
397
+ // continuing as if a full-dimension set of basic variables was rank
398
+ // deficient.
399
+ if (build_kernel_return == kBuildKernelReturnTimeout)
400
+ return kBuildKernelReturnTimeout;
401
+ rank_deficiency = build_kernel_return;
402
+ const bool incomplete_basis = num_basic < num_row;
403
+ if (rank_deficiency || incomplete_basis) {
404
+ factor_timer.start(FactorInvertDeficient, factor_timer_clock_pointer);
405
+ if (num_basic == num_row)
406
+ highsLogDev(log_options, HighsLogType::kWarning,
407
+ "Rank deficiency of %" HIGHSINT_FORMAT
408
+ " identified in basis matrix\n",
409
+ rank_deficiency);
410
+ // Singular matrix B: reorder the basic variables so that the
411
+ // singular columns are in the position corresponding to the
412
+ // logical which replaces them
413
+ buildHandleRankDeficiency();
414
+ buildMarkSingC();
415
+ factor_timer.stop(FactorInvertDeficient, factor_timer_clock_pointer);
416
+ }
417
+ if (incomplete_basis) {
418
+ // Completing the factorization is not relevant if the basis
419
+ // matrix is incomplete, so clear any refactorization information
420
+ // and return
421
+ this->refactor_info_.clear();
422
+ assert(!this->refactor_info_.use);
423
+ const HighsInt basic_index_rank_deficiency =
424
+ rank_deficiency - (num_row - num_basic);
425
+ return basic_index_rank_deficiency;
426
+ }
427
+ // Complete INVERT
428
+ if (report_lu) {
429
+ printf("\nFactored INVERT\n");
430
+ reportLu(kReportLuBoth, false);
431
+ }
432
+ factor_timer.start(FactorInvertFinish, factor_timer_clock_pointer);
433
+ buildFinish();
434
+ factor_timer.stop(FactorInvertFinish, factor_timer_clock_pointer);
435
+ //
436
+ // Indicate that the refactorization information is known unless the basis was
437
+ // rank deficient
438
+ if (rank_deficiency) {
439
+ this->refactor_info_.clear();
440
+ } else {
441
+ // Check that the refactorization information is not (yet) flagged
442
+ // to be used in a future call
443
+ assert(!this->refactor_info_.use);
444
+ // Record build_synthetic_tick to use as the value of
445
+ // build_synthetic_tick if refactorization is performed. Not only
446
+ // is there no build_synthetic_tick measure for refactorization,
447
+ // if there were it would give an unrealistic underestimate of the
448
+ // cost of factorization from scratch
449
+ this->refactor_info_.build_synthetic_tick = this->build_synthetic_tick;
450
+ }
451
+
452
+ // Record the number of entries in the INVERT
453
+ invert_num_el = l_start[num_row] + u_last_p[num_row - 1] + num_row;
454
+
455
+ kernel_dim -= rank_deficiency;
456
+ debugLogRankDeficiency(highs_debug_level, log_options, rank_deficiency,
457
+ basis_matrix_num_el, invert_num_el, kernel_dim,
458
+ kernel_num_el, nwork);
459
+ factor_timer.stop(FactorInvert, factor_timer_clock_pointer);
460
+ return rank_deficiency;
461
+ }
462
+
463
+ void HFactor::ftranCall(HVector& vector, const double expected_density,
464
+ HighsTimerClock* factor_timer_clock_pointer) const {
465
+ const bool use_indices = vector.count >= 0;
466
+ FactorTimer factor_timer;
467
+ factor_timer.start(FactorFtran, factor_timer_clock_pointer);
468
+ ftranL(vector, expected_density, factor_timer_clock_pointer);
469
+ ftranU(vector, expected_density, factor_timer_clock_pointer);
470
+ // Possibly find the indices in order
471
+ if (use_indices) vector.reIndex();
472
+ factor_timer.stop(FactorFtran, factor_timer_clock_pointer);
473
+ }
474
+
475
+ void HFactor::ftranCall(std::vector<double>& vector,
476
+ HighsTimerClock* factor_timer_clock_pointer) {
477
+ FactorTimer factor_timer;
478
+ factor_timer.start(FactorFtran, factor_timer_clock_pointer);
479
+ // Only have to clear the scalars of the local HVector, since the
480
+ // array is moved in. Set the count to -1 to indicate that indices
481
+ // aren't known.
482
+ this->rhs_.clearScalars();
483
+ this->rhs_.array = std::move(vector);
484
+ this->rhs_.count = -1;
485
+ const double expected_density = 1;
486
+ ftranCall(this->rhs_, expected_density, factor_timer_clock_pointer);
487
+ vector = std::move(this->rhs_.array);
488
+ factor_timer.stop(FactorFtran, factor_timer_clock_pointer);
489
+ }
490
+
491
+ void HFactor::btranCall(HVector& vector, const double expected_density,
492
+ HighsTimerClock* factor_timer_clock_pointer) const {
493
+ const bool use_indices = vector.count >= 0;
494
+ FactorTimer factor_timer;
495
+ factor_timer.start(FactorBtran, factor_timer_clock_pointer);
496
+ btranU(vector, expected_density, factor_timer_clock_pointer);
497
+ btranL(vector, expected_density, factor_timer_clock_pointer);
498
+ // Possibly find the indices in order
499
+ if (use_indices) vector.reIndex();
500
+ factor_timer.stop(FactorBtran, factor_timer_clock_pointer);
501
+ }
502
+
503
+ void HFactor::btranCall(std::vector<double>& vector,
504
+ HighsTimerClock* factor_timer_clock_pointer) {
505
+ // Only have to clear the scalars of the local HVector, since the
506
+ // array is moved in. Set the count to -1 to indicate that indices
507
+ // aren't known.
508
+ this->rhs_.clearScalars();
509
+ this->rhs_.array = std::move(vector);
510
+ this->rhs_.count = -1;
511
+ const double expected_density = 1;
512
+ btranCall(this->rhs_, expected_density, factor_timer_clock_pointer);
513
+ vector = std::move(this->rhs_.array);
514
+ }
515
+
516
+ void HFactor::update(HVector* aq, HVector* ep, HighsInt* iRow, HighsInt* hint) {
517
+ // Updating implies a change of basis. Since the refactorizaion info
518
+ // no longer corresponds to the current basis, it must be
519
+ // invalidated
520
+ this->refactor_info_.clear();
521
+ // Special case
522
+ if (aq->next) {
523
+ updateCFT(aq, ep, iRow);
524
+ return;
525
+ }
526
+
527
+ if (update_method == kUpdateMethodFt) updateFT(aq, ep, *iRow);
528
+ if (update_method == kUpdateMethodPf) updatePF(aq, *iRow, hint);
529
+ if (update_method == kUpdateMethodMpf) updateMPF(aq, ep, *iRow, hint);
530
+ if (update_method == kUpdateMethodApf) updateAPF(aq, ep, *iRow);
531
+ }
532
+
533
+ bool HFactor::setPivotThreshold(const double new_pivot_threshold) {
534
+ if (new_pivot_threshold < kMinPivotThreshold) return false;
535
+ if (new_pivot_threshold > kMaxPivotThreshold) return false;
536
+ pivot_threshold = new_pivot_threshold;
537
+ return true;
538
+ }
539
+
540
+ void HFactor::setTimeLimit(const double time_limit) {
541
+ this->time_limit_ = kHighsInf;
542
+ if (time_limit < 0) return;
543
+ this->time_limit_ = time_limit;
544
+ }
545
+
546
+ void HFactor::luClear() {
547
+ l_start.clear();
548
+ l_start.push_back(0);
549
+ l_index.clear();
550
+ l_value.clear();
551
+
552
+ u_pivot_index.clear();
553
+ u_pivot_value.clear();
554
+ u_start.clear();
555
+ u_start.push_back(0);
556
+ u_index.clear();
557
+ u_value.clear();
558
+ }
559
+
560
+ void HFactor::buildSimple() {
561
+ /**
562
+ * 0. Clear L and U factor
563
+ */
564
+ luClear();
565
+
566
+ const bool progress_report = false;
567
+ const HighsInt progress_frequency = 100000;
568
+
569
+ // Set all values of permute to -1 so that unpermuted (rank
570
+ // deficient) columns can be identified
571
+ const HighsInt permute_dim = num_basic;
572
+ // Strictly not necessary, but nice if it's the right size
573
+ permute.resize(permute_dim);
574
+ permute.assign(permute_dim, -1);
575
+
576
+ /**
577
+ * 1. Prepare basis matrix and deal with unit columns
578
+ */
579
+ const bool report_unit = false;
580
+ const bool report_singletons = false;
581
+ const bool report_markowitz = false;
582
+ const bool report_anything =
583
+ report_unit || report_singletons || report_markowitz;
584
+ HighsInt BcountX = 0;
585
+ fill_n(mr_count_before.data(), num_row, 0);
586
+ nwork = 0;
587
+ if (report_anything) printf("\nFactor\n");
588
+ // Compile a vector iwork of the indices within basic_index of the
589
+ // its nwork non-unit structural columns: they will be formed into
590
+ // the B matrix as the kernel
591
+ const HighsInt iwork_dim = num_basic;
592
+ // Strictly not necessary, but nice if it's the right size
593
+ iwork.resize(iwork_dim + 1, 0);
594
+ iwork.assign(iwork_dim + 1, 0);
595
+ for (HighsInt iCol = 0; iCol < num_basic; iCol++) {
596
+ if (progress_report && iCol) {
597
+ if (iCol % progress_frequency == 0)
598
+ printf("HFactor::buildSimple stage = %6d\n", (int)iCol);
599
+ }
600
+
601
+ HighsInt iMat = basic_index[iCol];
602
+ HighsInt iRow = -1;
603
+ int8_t pivot_type = kPivotIllegal;
604
+ // Look for unit columns as pivots. If there is already a pivot
605
+ // corresponding to the nonzero in a unit column - evidenced by
606
+ // mr_count_before[iRow] being negative - then, obviously, it
607
+ // can't be used. However, it doesn't imply an error, or even rank
608
+ // deficiency now that build() is being used to determine
609
+ // rank. Treat it as a column to be handled in the kernel, so that
610
+ // any rank deficiency or singularity is detected as late as
611
+ // possible.
612
+ if (iMat >= num_col) {
613
+ // 1.1 Logical column
614
+ //
615
+ // Check for double pivot
616
+ HighsInt lc_iRow = iMat - num_col;
617
+ if (mr_count_before[lc_iRow] >= 0) {
618
+ if (report_unit)
619
+ printf("Stage %d: Logical\n", (int)(l_start.size() - 1));
620
+ pivot_type = kPivotLogical;
621
+ iRow = lc_iRow;
622
+ } else {
623
+ mr_count_before[lc_iRow]++;
624
+ b_index[BcountX] = lc_iRow;
625
+ b_value[BcountX++] = 1.0;
626
+ iwork[nwork++] = iCol;
627
+ }
628
+ } else {
629
+ // 1.2 Structural column
630
+ HighsInt start = a_start[iMat];
631
+ HighsInt count = a_start[iMat + 1] - start;
632
+ // If this column and all subsequent columns are zero (so count
633
+ // is 0) then a_index[start] and a_value[start] are unassigned,
634
+ // so determine a unit column in two stages
635
+ bool ok_unit_col = false;
636
+ if (count == 1) {
637
+ // Column has only one nonzero, but have to make sure that the
638
+ // value is 1 and that there's not already a pivot
639
+ // corresponding to this unit column
640
+ ok_unit_col =
641
+ a_value[start] == 1 && mr_count_before[a_index[start]] >= 0;
642
+ }
643
+ if (ok_unit_col) {
644
+ if (report_unit) printf("Stage %d: Unit\n", (int)(l_start.size() - 1));
645
+ // Don't exploit this special case in case the matrix is
646
+ // re-factorized after scaling has been applied, making this
647
+ // column non-unit.
648
+ pivot_type = kPivotColSingleton; //;kPivotUnit;//
649
+ iRow = a_index[start];
650
+ } else {
651
+ for (HighsInt k = start; k < start + count; k++) {
652
+ mr_count_before[a_index[k]]++;
653
+ assert(BcountX < (HighsInt)b_index.size());
654
+ b_index[BcountX] = a_index[k];
655
+ b_value[BcountX++] = a_value[k];
656
+ }
657
+ iwork[nwork++] = iCol;
658
+ }
659
+ }
660
+
661
+ if (iRow >= 0) {
662
+ // 1.3 Record unit column
663
+ permute[iCol] = iRow;
664
+ l_start.push_back(l_index.size());
665
+ u_pivot_index.push_back(iRow);
666
+ u_pivot_value.push_back(1);
667
+ u_start.push_back(u_index.size());
668
+ // Was -num_row, but this is incorrect since the negation needs
669
+ // to be great enough so that, starting from it, the accumulated
670
+ // count can never reach zero
671
+ mr_count_before[iRow] = -num_basic;
672
+ assert(pivot_type != kPivotIllegal);
673
+ this->refactor_info_.pivot_row.push_back(iRow);
674
+ this->refactor_info_.pivot_var.push_back(iMat);
675
+ this->refactor_info_.pivot_type.push_back(pivot_type);
676
+ }
677
+ b_start[iCol + 1] = BcountX;
678
+ b_var[iCol] = iMat;
679
+ }
680
+ // Record the number of elements in the basis matrix
681
+ basis_matrix_num_el = num_row - nwork + BcountX;
682
+
683
+ // count1 = 0;
684
+ // Comments: for pds-20, dfl001: 60 / 80
685
+ // Comments: when system is large: enlarge
686
+ // Comments: when system is small: decrease
687
+ build_synthetic_tick += BcountX * 60 + (num_row - nwork) * 80;
688
+
689
+ /**
690
+ * 2. Search for and deal with singletons
691
+ */
692
+ double t2_search = 0;
693
+ double t2_store_l = l_index.size();
694
+ double t2_store_u = u_index.size();
695
+ double t2_store_p = nwork;
696
+ while (nwork > 0) {
697
+ HighsInt nworkLast = nwork;
698
+ nwork = 0;
699
+ for (HighsInt i = 0; i < nworkLast; i++) {
700
+ const HighsInt iCol = iwork[i];
701
+ const HighsInt start = b_start[iCol];
702
+ const HighsInt end = b_start[iCol + 1];
703
+ HighsInt pivot_k = -1;
704
+ HighsInt found_row_singleton = 0;
705
+ HighsInt count = 0;
706
+
707
+ // 2.1 Search for singleton
708
+ t2_search += end - start;
709
+ for (HighsInt k = start; k < end; k++) {
710
+ const HighsInt iRow = b_index[k];
711
+ if (mr_count_before[iRow] == 1) {
712
+ pivot_k = k;
713
+ found_row_singleton = 1;
714
+ break;
715
+ }
716
+ if (mr_count_before[iRow] > 1) {
717
+ pivot_k = k;
718
+ count++;
719
+ }
720
+ }
721
+
722
+ if (found_row_singleton) {
723
+ // 2.2 Deal with row singleton
724
+ const double pivot_multiplier = 1 / b_value[pivot_k];
725
+ if (report_singletons)
726
+ printf("Stage %d: Row singleton (%4d, %g)\n",
727
+ (int)(l_start.size() - 1), (int)pivot_k, pivot_multiplier);
728
+ for (HighsInt section = 0; section < 2; section++) {
729
+ HighsInt p0 = section == 0 ? start : pivot_k + 1;
730
+ HighsInt p1 = section == 0 ? pivot_k : end;
731
+ for (HighsInt k = p0; k < p1; k++) {
732
+ HighsInt iRow = b_index[k];
733
+ if (mr_count_before[iRow] > 0) {
734
+ if (report_singletons)
735
+ printf("Row singleton: L En (%4d, %11.4g)\n", (int)iRow,
736
+ b_value[k] * pivot_multiplier);
737
+ l_index.push_back(iRow);
738
+ l_value.push_back(b_value[k] * pivot_multiplier);
739
+ } else {
740
+ if (report_singletons)
741
+ printf("Row singleton: U En (%4d, %11.4g)\n", (int)iRow,
742
+ b_value[k]);
743
+ u_index.push_back(iRow);
744
+ u_value.push_back(b_value[k]);
745
+ }
746
+ mr_count_before[iRow]--;
747
+ }
748
+ }
749
+ HighsInt iRow = b_index[pivot_k];
750
+ mr_count_before[iRow] = 0;
751
+ permute[iCol] = iRow;
752
+ l_start.push_back(l_index.size());
753
+
754
+ if (report_singletons)
755
+ printf("Row singleton: U Pv (%4d, %11.4g)\n", (int)iRow,
756
+ b_value[pivot_k]);
757
+ u_pivot_index.push_back(iRow);
758
+ u_pivot_value.push_back(b_value[pivot_k]);
759
+ u_start.push_back(u_index.size());
760
+ assert(b_var[iCol] == basic_index[iCol]);
761
+
762
+ this->refactor_info_.pivot_row.push_back(iRow);
763
+ this->refactor_info_.pivot_var.push_back(basic_index[iCol]);
764
+ this->refactor_info_.pivot_type.push_back(kPivotRowSingleton);
765
+ } else if (count == 1) {
766
+ if (report_singletons)
767
+ printf("Stage %d: Col singleton \n", (int)(l_start.size() - 1));
768
+ // 2.3 Deal with column singleton
769
+ for (HighsInt k = start; k < pivot_k; k++) {
770
+ if (report_singletons)
771
+ printf("Col singleton: U En (%4d, %11.4g)\n", (int)b_index[k],
772
+ b_value[k]);
773
+ u_index.push_back(b_index[k]);
774
+ u_value.push_back(b_value[k]);
775
+ }
776
+ for (HighsInt k = pivot_k + 1; k < end; k++) {
777
+ if (report_singletons)
778
+ printf("Col singleton: U En (%4d, %11.4g)\n", (int)b_index[k],
779
+ b_value[k]);
780
+ u_index.push_back(b_index[k]);
781
+ u_value.push_back(b_value[k]);
782
+ }
783
+
784
+ HighsInt iRow = b_index[pivot_k];
785
+ mr_count_before[iRow] = 0;
786
+ permute[iCol] = iRow;
787
+ l_start.push_back(l_index.size());
788
+
789
+ if (report_singletons)
790
+ printf("Col singleton: U Pv (%4d, %11.4g)\n", (int)iRow,
791
+ b_value[pivot_k]);
792
+ u_pivot_index.push_back(iRow);
793
+ u_pivot_value.push_back(b_value[pivot_k]);
794
+ u_start.push_back(u_index.size());
795
+ assert(b_var[iCol] == basic_index[iCol]);
796
+ this->refactor_info_.pivot_row.push_back(iRow);
797
+ this->refactor_info_.pivot_var.push_back(basic_index[iCol]);
798
+ this->refactor_info_.pivot_type.push_back(kPivotColSingleton);
799
+ } else {
800
+ iwork[nwork++] = iCol;
801
+ }
802
+ }
803
+
804
+ // No singleton found in the last pass
805
+ if (nworkLast == nwork) break;
806
+ }
807
+ if (report_anything) reportLu(kReportLuBoth, false);
808
+ t2_store_l = static_cast<double>(l_index.size()) - t2_store_l;
809
+ t2_store_u = static_cast<double>(u_index.size()) - t2_store_u;
810
+ t2_store_p = t2_store_p - nwork;
811
+
812
+ build_synthetic_tick +=
813
+ t2_search * 20 + (t2_store_p + t2_store_l + t2_store_u) * 80;
814
+
815
+ /**
816
+ * 3. Prepare the kernel parts
817
+ */
818
+ // 3.1 Prepare row links, row matrix spaces
819
+ row_link_first.assign(num_basic + 1, -1);
820
+ mr_count.assign(num_row, 0);
821
+ HighsInt mr_countX = 0;
822
+ // Determine the number of entries in the kernel
823
+ kernel_num_el = 0;
824
+ for (HighsInt iRow = 0; iRow < num_row; iRow++) {
825
+ HighsInt count = mr_count_before[iRow];
826
+ if (count > 0) {
827
+ mr_start[iRow] = mr_countX;
828
+ mr_space[iRow] = count * 2;
829
+ mr_countX += count * 2;
830
+ rlinkAdd(iRow, count);
831
+ kernel_num_el += count + 1;
832
+ }
833
+ }
834
+ mr_index.resize(mr_countX);
835
+
836
+ // 3.2 Prepare column links, kernel matrix
837
+ col_link_first.assign(num_row + 1, -1);
838
+ const HighsInt mc_dim = num_basic;
839
+ mc_index.clear();
840
+ mc_value.clear();
841
+ mc_count_a.assign(mc_dim, 0);
842
+ mc_count_n.assign(mc_dim, 0);
843
+ HighsInt MCcountX = 0;
844
+ for (HighsInt i = 0; i < nwork; i++) {
845
+ HighsInt iCol = iwork[i];
846
+ mc_var[iCol] = b_var[iCol];
847
+ mc_start[iCol] = MCcountX;
848
+ mc_space[iCol] = (b_start[iCol + 1] - b_start[iCol]) * 2;
849
+ MCcountX += mc_space[iCol];
850
+ mc_index.resize(MCcountX);
851
+ mc_value.resize(MCcountX);
852
+ for (HighsInt k = b_start[iCol]; k < b_start[iCol + 1]; k++) {
853
+ const HighsInt iRow = b_index[k];
854
+ const double value = b_value[k];
855
+ if (mr_count_before[iRow] > 0) {
856
+ colInsert(iCol, iRow, value);
857
+ rowInsert(iCol, iRow);
858
+ } else {
859
+ colStoreN(iCol, iRow, value);
860
+ }
861
+ }
862
+ colFixMax(iCol);
863
+ clinkAdd(iCol, mc_count_a[iCol]);
864
+ }
865
+ build_synthetic_tick += (num_row + nwork + MCcountX) * 40 + mr_countX * 20;
866
+ // Record the kernel dimension
867
+ kernel_dim = nwork;
868
+ assert((HighsInt)this->refactor_info_.pivot_row.size() == num_basic - nwork);
869
+ }
870
+
871
+ HighsInt HFactor::buildKernel() {
872
+ // Deal with the kernel part by 'n-work' pivoting
873
+
874
+ double fake_search = 0;
875
+ double fake_fill = 0;
876
+ double fake_eliminate = 0;
877
+
878
+ const bool progress_report = false; // num_basic != num_row;
879
+ const HighsInt progress_frequency = 10000;
880
+ // Initial timer frequency: may be reduced if iterations get slow
881
+ HighsInt timer_frequency = 100;
882
+ double previous_iteration_time = 0;
883
+ double average_iteration_time = 0;
884
+ const bool check_for_timeout = this->time_limit_ < kHighsInf;
885
+ HighsInt search_k = 0;
886
+
887
+ const HighsInt check_nwork = -11;
888
+ while (nwork-- > 0) {
889
+ // printf("\nnwork = %d\n", (int)nwork);
890
+ if (nwork == check_nwork) {
891
+ reportAsm();
892
+ }
893
+ // Determine whether to return due to exceeding the time limit
894
+ if (check_for_timeout && search_k % timer_frequency == 0) {
895
+ double current_time = build_timer_->read();
896
+ double time_difference = current_time - previous_iteration_time;
897
+ previous_iteration_time = current_time;
898
+ double iteration_time = time_difference / (1.0 * timer_frequency);
899
+ average_iteration_time =
900
+ 0.9 * average_iteration_time + 0.1 * iteration_time;
901
+
902
+ if (time_difference > this->time_limit_ / 1e3)
903
+ timer_frequency = std::max(HighsInt(1), timer_frequency / 10);
904
+ HighsInt iterations_left = kernel_dim - search_k + 1;
905
+ double remaining_time_bound = average_iteration_time * iterations_left;
906
+ double total_time_bound = current_time + remaining_time_bound;
907
+ if (current_time > this->time_limit_ ||
908
+ total_time_bound > this->time_limit_)
909
+ return kBuildKernelReturnTimeout;
910
+ }
911
+
912
+ /**
913
+ * 1. Search for the pivot
914
+ */
915
+ HighsInt jColPivot = -1;
916
+ HighsInt iRowPivot = -1;
917
+ // int8_t pivot_type = kPivotIllegal;
918
+ // 1.1. Setup search merits
919
+ HighsInt searchLimit = min(nwork, HighsInt{8});
920
+ HighsInt searchCount = 0;
921
+
922
+ double merit_limit = 1.0 * num_basic * num_row;
923
+ double merit_pivot = merit_limit;
924
+
925
+ if (progress_report && search_k) {
926
+ if (search_k % progress_frequency == 0) {
927
+ HighsInt min_col_count = kHighsIInf;
928
+ HighsInt min_row_count = kHighsIInf;
929
+ for (HighsInt count = 1; count < num_row; count++) {
930
+ if (col_link_first[count] >= 0) {
931
+ min_col_count = count;
932
+ break;
933
+ }
934
+ }
935
+ for (HighsInt count = 1; count < num_basic; count++) {
936
+ if (row_link_first[count] >= 0) {
937
+ min_row_count = count;
938
+ break;
939
+ }
940
+ }
941
+ printf(
942
+ "HFactor::buildKernel stage = %6d: min_col_count = %3d; "
943
+ "min_row_count = %3d\n",
944
+ (int)search_k, (int)min_col_count, (int)min_row_count);
945
+ }
946
+ }
947
+ search_k++;
948
+ // 1.2. Search for local singletons
949
+ bool foundPivot = false;
950
+ // jColPivot = col_link_first[1];
951
+ if (!foundPivot && col_link_first[1] != -1) {
952
+ // Not yet found a pivot and there is at least one column
953
+ // singleton
954
+ jColPivot = col_link_first[1];
955
+ iRowPivot = mc_index[mc_start[jColPivot]];
956
+ foundPivot = true;
957
+ }
958
+ if (!foundPivot && row_link_first[1] != -1) {
959
+ iRowPivot = row_link_first[1];
960
+ jColPivot = mr_index[mr_start[iRowPivot]];
961
+ foundPivot = true;
962
+ }
963
+ const bool singleton_pivot = foundPivot;
964
+ #ifndef NDEBUG
965
+ double candidate_pivot_value = 0;
966
+ #endif
967
+ // 1.3. Major search loop
968
+ //
969
+ // Row count can be more than the number of rows if num_basic >
970
+ // num_row
971
+ const HighsInt max_count = max(num_row, num_basic);
972
+ for (HighsInt count = 2; !foundPivot && count <= max_count; count++) {
973
+ // Column count cannot exceed the number of rows
974
+ if (count <= num_row) {
975
+ // 1.3.1 Search for columns
976
+ for (HighsInt j = col_link_first[count]; j != -1;
977
+ j = col_link_next[j]) {
978
+ double min_pivot = mc_min_pivot[j];
979
+ HighsInt start = mc_start[j];
980
+ HighsInt end = start + mc_count_a[j];
981
+ for (HighsInt k = start; k < end; k++) {
982
+ if (fabs(mc_value[k]) >= min_pivot) {
983
+ HighsInt i = mc_index[k];
984
+ HighsInt row_count = mr_count[i];
985
+ double merit_local = 1.0 * (count - 1) * (row_count - 1);
986
+ if (merit_pivot > merit_local) {
987
+ #ifndef NDEBUG
988
+ candidate_pivot_value = fabs(mc_value[k]);
989
+ #endif
990
+ merit_pivot = merit_local;
991
+ jColPivot = j;
992
+ iRowPivot = i;
993
+ foundPivot = foundPivot || (row_count < count);
994
+ }
995
+ }
996
+ }
997
+
998
+ if (searchCount++ >= searchLimit && merit_pivot < merit_limit)
999
+ foundPivot = true;
1000
+ if (foundPivot) break;
1001
+
1002
+ fake_search += count;
1003
+ }
1004
+ }
1005
+
1006
+ // Row count cannot exceed the number of basic variables
1007
+ if (count <= num_basic) {
1008
+ // 1.3.2 Search for rows
1009
+ for (HighsInt i = row_link_first[count]; i != -1;
1010
+ i = row_link_next[i]) {
1011
+ HighsInt start = mr_start[i];
1012
+ HighsInt end = start + mr_count[i];
1013
+ for (HighsInt k = start; k < end; k++) {
1014
+ HighsInt j = mr_index[k];
1015
+ HighsInt column_count = mc_count_a[j];
1016
+ double merit_local = 1.0 * (count - 1) * (column_count - 1);
1017
+ if (merit_local < merit_pivot) {
1018
+ HighsInt ifind = mc_start[j];
1019
+ while (mc_index[ifind] != i) ifind++;
1020
+ if (fabs(mc_value[ifind]) >= mc_min_pivot[j]) {
1021
+ #ifndef NDEBUG
1022
+ candidate_pivot_value = fabs(mc_value[ifind]);
1023
+ #endif
1024
+ merit_pivot = merit_local;
1025
+ jColPivot = j;
1026
+ iRowPivot = i;
1027
+ foundPivot = foundPivot || (column_count <= count);
1028
+ }
1029
+ }
1030
+ }
1031
+ if (searchCount++ >= searchLimit && merit_pivot < merit_limit)
1032
+ foundPivot = true;
1033
+ if (foundPivot) break;
1034
+ }
1035
+
1036
+ fake_search += count;
1037
+ }
1038
+ }
1039
+ // 1.4. If we found nothing: tell singular
1040
+ if (iRowPivot < 0) {
1041
+ // To detect the absence of a pivot, it should be sufficient
1042
+ // that iRowPivot is (still) -1, but add sanity asserts that
1043
+ // jColPivot is (still) -1 and foundPivot is false
1044
+ assert(jColPivot < 0);
1045
+ assert(!foundPivot);
1046
+ rank_deficiency = nwork + 1;
1047
+ highsLogDev(log_options, HighsLogType::kWarning,
1048
+ "Factorization identifies rank deficiency of %d\n",
1049
+ (int)rank_deficiency);
1050
+ return rank_deficiency;
1051
+ }
1052
+
1053
+ /**
1054
+ * 2. Elimination other elements by the pivot
1055
+ */
1056
+ #ifndef NDEBUG
1057
+ const HighsInt original_pivotal_row_count = mr_count[iRowPivot];
1058
+ const HighsInt original_pivotal_col_count = mc_count_a[jColPivot];
1059
+ #endif
1060
+ // 2.1. Delete the pivot
1061
+ //
1062
+ // Remove the pivot row index from the pivotal column of the
1063
+ // col-wise matrix. Also decreases the column count
1064
+ double pivot_multiplier = colDelete(jColPivot, iRowPivot);
1065
+ // Remove the pivot column index from the pivotal row of the
1066
+ // row-wise matrix. Also decreases the row count
1067
+ rowDelete(jColPivot, iRowPivot);
1068
+ // Remove the pivotal column from the linked list of columns
1069
+ // containing it
1070
+ clinkDel(jColPivot);
1071
+ // Remove the pivotal row from the linked list of rows containing
1072
+ // it
1073
+ rlinkDel(iRowPivot);
1074
+ if (!singleton_pivot)
1075
+ assert(candidate_pivot_value == fabs(pivot_multiplier));
1076
+ if (fabs(pivot_multiplier) < pivot_tolerance) {
1077
+ highsLogDev(log_options, HighsLogType::kWarning,
1078
+ "Defer singular pivot = %11.4g\n", pivot_multiplier);
1079
+ // Matrix is singular, but defer return since other valid pivots
1080
+ // may exist.
1081
+ assert(mr_count[iRowPivot] == original_pivotal_row_count - 1);
1082
+ if (mr_count[iRowPivot] == 0) {
1083
+ // The pivot corresponds to a singleton row. Entry is zeroed,
1084
+ // and do no more since there may be other valid entries in
1085
+ // the pivotal column
1086
+ //
1087
+ // Add the pivotal column to the linked list of columns with
1088
+ // its new count
1089
+ assert(mc_count_a[jColPivot] == original_pivotal_col_count - 1);
1090
+ clinkAdd(jColPivot, mc_count_a[jColPivot]);
1091
+ } else {
1092
+ // Otherwise, other entries in the pivotal column will be
1093
+ // smaller than the pivot, so zero the column
1094
+ zeroCol(jColPivot);
1095
+ // Add the pivotal row to the linked list of rows with its new
1096
+ // count
1097
+ assert(mr_count[iRowPivot] == original_pivotal_row_count - 1);
1098
+ rlinkAdd(iRowPivot, mr_count[iRowPivot]);
1099
+ }
1100
+ // No pivot found, so have to increment nwork
1101
+ nwork++;
1102
+ continue;
1103
+ }
1104
+ permute[jColPivot] = iRowPivot;
1105
+ assert(mc_var[jColPivot] == basic_index[jColPivot]);
1106
+
1107
+ this->refactor_info_.pivot_row.push_back(iRowPivot);
1108
+ this->refactor_info_.pivot_var.push_back(basic_index[jColPivot]);
1109
+ this->refactor_info_.pivot_type.push_back(kPivotMarkowitz);
1110
+
1111
+ // 2.2. Store active pivot column to L
1112
+ HighsInt start_A = mc_start[jColPivot];
1113
+ HighsInt end_A = start_A + mc_count_a[jColPivot];
1114
+ HighsInt mwz_column_count = 0;
1115
+ for (HighsInt k = start_A; k < end_A; k++) {
1116
+ const HighsInt iRow = mc_index[k];
1117
+ const double value = mc_value[k] / pivot_multiplier;
1118
+ mwz_column_index[mwz_column_count++] = iRow;
1119
+ mwz_column_array[iRow] = value;
1120
+ mwz_column_mark[iRow] = 1;
1121
+ l_index.push_back(iRow);
1122
+ l_value.push_back(value);
1123
+ mr_count_before[iRow] = mr_count[iRow];
1124
+ rowDelete(jColPivot, (int)iRow);
1125
+ }
1126
+ l_start.push_back(l_index.size());
1127
+ fake_fill += 2 * mc_count_a[jColPivot];
1128
+
1129
+ // 2.3. Store non active pivot column to U
1130
+ HighsInt end_N = start_A + mc_space[jColPivot];
1131
+ HighsInt start_N = end_N - mc_count_n[jColPivot];
1132
+ for (HighsInt i = start_N; i < end_N; i++) {
1133
+ u_index.push_back(mc_index[i]);
1134
+ u_value.push_back(mc_value[i]);
1135
+ }
1136
+ u_pivot_index.push_back(iRowPivot);
1137
+ u_pivot_value.push_back(pivot_multiplier);
1138
+ u_start.push_back(u_index.size());
1139
+ fake_fill += end_N - start_N;
1140
+
1141
+ // 2.4. Loop over pivot row to eliminate other column
1142
+ const HighsInt row_start = mr_start[iRowPivot];
1143
+ const HighsInt row_end = row_start + mr_count[iRowPivot];
1144
+ for (HighsInt row_k = row_start; row_k < row_end; row_k++) {
1145
+ // 2.4.1. My pointer
1146
+ HighsInt iCol = mr_index[row_k];
1147
+ const HighsInt my_count = mc_count_a[iCol];
1148
+ const HighsInt my_start = mc_start[iCol];
1149
+ const HighsInt my_end = my_start + my_count - 1;
1150
+ double my_pivot = colDelete(iCol, iRowPivot);
1151
+ colStoreN(iCol, iRowPivot, my_pivot);
1152
+
1153
+ // 2.4.2. Elimination on the overlapping part
1154
+ HighsInt nFillin = mwz_column_count;
1155
+ HighsInt nCancel = 0;
1156
+ for (HighsInt my_k = my_start; my_k < my_end; my_k++) {
1157
+ HighsInt iRow = mc_index[my_k];
1158
+ double value = mc_value[my_k];
1159
+ if (mwz_column_mark[iRow]) {
1160
+ mwz_column_mark[iRow] = 0;
1161
+ nFillin--;
1162
+ value -= my_pivot * mwz_column_array[iRow];
1163
+ if (fabs(value) < kHighsTiny) {
1164
+ value = 0;
1165
+ nCancel++;
1166
+ }
1167
+ mc_value[my_k] = value;
1168
+ }
1169
+ }
1170
+ fake_eliminate += mwz_column_count;
1171
+ fake_eliminate += nFillin * 2;
1172
+
1173
+ // 2.4.3. Remove cancellation gaps
1174
+ if (nCancel > 0) {
1175
+ HighsInt new_end = my_start;
1176
+ for (HighsInt my_k = my_start; my_k < my_end; my_k++) {
1177
+ if (mc_value[my_k] != 0) {
1178
+ mc_index[new_end] = mc_index[my_k];
1179
+ mc_value[new_end++] = mc_value[my_k];
1180
+ } else {
1181
+ rowDelete(iCol, mc_index[my_k]);
1182
+ }
1183
+ }
1184
+ mc_count_a[iCol] = new_end - my_start;
1185
+ }
1186
+
1187
+ // 2.4.4. Insert fill-in
1188
+ if (nFillin > 0) {
1189
+ // 2.4.4.1 Check column size
1190
+ if (mc_count_a[iCol] + mc_count_n[iCol] + nFillin > mc_space[iCol]) {
1191
+ // p1&2=active, p3&4=non active, p5=new p1, p7=new p3
1192
+ HighsInt p1 = mc_start[iCol];
1193
+ HighsInt p2 = p1 + mc_count_a[iCol];
1194
+ HighsInt p3 = p1 + mc_space[iCol] - mc_count_n[iCol];
1195
+ HighsInt p4 = p1 + mc_space[iCol];
1196
+ mc_space[iCol] += max(mc_space[iCol], nFillin);
1197
+ HighsInt p5 = mc_start[iCol] = mc_index.size();
1198
+ HighsInt p7 = p5 + mc_space[iCol] - mc_count_n[iCol];
1199
+ mc_index.resize(p5 + mc_space[iCol]);
1200
+ mc_value.resize(p5 + mc_space[iCol]);
1201
+ copy(&mc_index[p1], &mc_index[p2], &mc_index[p5]);
1202
+ copy(&mc_value[p1], &mc_value[p2], &mc_value[p5]);
1203
+ copy(&mc_index[p3], &mc_index[p4], &mc_index[p7]);
1204
+ copy(&mc_value[p3], &mc_value[p4], &mc_value[p7]);
1205
+ }
1206
+
1207
+ // 2.4.4.2 Fill into column copy
1208
+ for (HighsInt i = 0; i < mwz_column_count; i++) {
1209
+ HighsInt iRow = mwz_column_index[i];
1210
+ if (mwz_column_mark[iRow])
1211
+ colInsert(iCol, iRow, -my_pivot * mwz_column_array[iRow]);
1212
+ }
1213
+
1214
+ // 2.4.4.3 Fill into the row copy
1215
+ for (HighsInt i = 0; i < mwz_column_count; i++) {
1216
+ HighsInt iRow = mwz_column_index[i];
1217
+ if (mwz_column_mark[iRow]) {
1218
+ // Expand row space
1219
+ if (mr_count[iRow] == mr_space[iRow]) {
1220
+ HighsInt p1 = mr_start[iRow];
1221
+ HighsInt p2 = p1 + mr_count[iRow];
1222
+ HighsInt p3 = mr_start[iRow] = mr_index.size();
1223
+ mr_space[iRow] *= 2;
1224
+ mr_index.resize(p3 + mr_space[iRow]);
1225
+ copy(&mr_index[p1], &mr_index[p2], &mr_index[p3]);
1226
+ }
1227
+ rowInsert(iCol, iRow);
1228
+ }
1229
+ }
1230
+ }
1231
+
1232
+ // 2.4.5. Reset pivot column mark
1233
+ for (HighsInt i = 0; i < mwz_column_count; i++)
1234
+ mwz_column_mark[mwz_column_index[i]] = 1;
1235
+
1236
+ // 2.4.6. Fix max value and link list
1237
+ colFixMax(iCol);
1238
+ if (my_count != mc_count_a[iCol]) {
1239
+ clinkDel(iCol);
1240
+ clinkAdd(iCol, mc_count_a[iCol]);
1241
+ }
1242
+ }
1243
+
1244
+ // 2.5. Clear pivot column buffer
1245
+ for (HighsInt i = 0; i < mwz_column_count; i++)
1246
+ mwz_column_mark[mwz_column_index[i]] = 0;
1247
+
1248
+ // 2.6. Correct row links for the remain active part
1249
+ for (HighsInt i = start_A; i < end_A; i++) {
1250
+ HighsInt iRow = mc_index[i];
1251
+ if (mr_count_before[iRow] != mr_count[iRow]) {
1252
+ rlinkDel(iRow);
1253
+ rlinkAdd(iRow, mr_count[iRow]);
1254
+ }
1255
+ }
1256
+ }
1257
+ build_synthetic_tick +=
1258
+ fake_search * 20 + fake_fill * 160 + fake_eliminate * 80;
1259
+ rank_deficiency = 0;
1260
+ return rank_deficiency;
1261
+ }
1262
+
1263
+ void HFactor::buildHandleRankDeficiency() {
1264
+ debugReportRankDeficiency(0, highs_debug_level, log_options, num_row, permute,
1265
+ iwork, basic_index, rank_deficiency,
1266
+ row_with_no_pivot, col_with_no_pivot);
1267
+ // iwork can now be used as workspace: use it to accumulate the new
1268
+ // basic_index. iwork is set to -1 and basic_index is permuted into it.
1269
+ // Indices of iwork corresponding to missing indices in permute
1270
+ // remain -1. Hence the -1's become markers for the logicals which
1271
+ // will replace singular columns. Once basic_index[i] is read, it can
1272
+ // be used to pack up the entries in basic_index which are not
1273
+ // permuted anywhere - and so will be singular columns.
1274
+ //
1275
+ // On entry, rank_deficiency is the rank deficiency of basic_index, which is
1276
+ //
1277
+ // * Less than the rank deficiency of the basis matrix if num_basic < num_row
1278
+ //
1279
+ //
1280
+ if (num_basic < num_row) {
1281
+ rank_deficiency += num_row - num_basic;
1282
+ }
1283
+ row_with_no_pivot.resize(rank_deficiency);
1284
+ col_with_no_pivot.resize(rank_deficiency);
1285
+ HighsInt lc_rank_deficiency = 0;
1286
+ if (num_basic < num_row) {
1287
+ // iwork still has to be used to indicate the rows with no pivots,
1288
+ // so resize it
1289
+ iwork.resize(num_row);
1290
+ } else if (num_basic > num_row) {
1291
+ // iwork only has to be used to indicate the rows with no pivots,
1292
+ // so resize it
1293
+ iwork.resize(num_basic);
1294
+ }
1295
+ // ToDo: surely this is neater as iwork.assign(num_row, -1);
1296
+ for (HighsInt i = 0; i < num_row; i++) iwork[i] = -1;
1297
+ for (HighsInt i = 0; i < num_basic; i++) {
1298
+ HighsInt perm_i = permute[i];
1299
+ if (perm_i >= 0) {
1300
+ iwork[perm_i] = basic_index[i];
1301
+ } else {
1302
+ col_with_no_pivot[lc_rank_deficiency++] = i;
1303
+ }
1304
+ }
1305
+ if (num_basic < num_row) {
1306
+ // Resize permute and complete iwork and col_with_no_pivot with
1307
+ // fictitious indices and entries of basic_index
1308
+ permute.resize(num_row);
1309
+ for (HighsInt i = num_basic; i < num_row; i++) {
1310
+ col_with_no_pivot[lc_rank_deficiency++] = i;
1311
+ permute[i] = -1;
1312
+ }
1313
+ }
1314
+ assert(lc_rank_deficiency == rank_deficiency);
1315
+ lc_rank_deficiency = 0;
1316
+ for (HighsInt i = 0; i < num_row; i++) {
1317
+ if (iwork[i] < 0) {
1318
+ // Record the rows with no pivots in row_with_no_pivot and indicate them
1319
+ // within iwork by storing the negation of one more than their
1320
+ // rank deficiency counter [since we can't have -0].
1321
+ row_with_no_pivot[lc_rank_deficiency] = i;
1322
+ iwork[i] = -(lc_rank_deficiency + 1);
1323
+ lc_rank_deficiency++;
1324
+ }
1325
+ }
1326
+ if (num_row < num_basic) {
1327
+ // Record fictitious rows with no pivots for the excess basic
1328
+ // variables so that permute will be constructed as a permutation
1329
+ // of all entries in basic_index
1330
+ for (HighsInt i = num_row; i < num_basic; i++) {
1331
+ row_with_no_pivot[lc_rank_deficiency] = i;
1332
+ iwork[i] = -(lc_rank_deficiency + 1);
1333
+ lc_rank_deficiency++;
1334
+ }
1335
+ }
1336
+ assert(lc_rank_deficiency == rank_deficiency);
1337
+ debugReportRankDeficiency(1, highs_debug_level, log_options, num_row, permute,
1338
+ iwork, basic_index, rank_deficiency,
1339
+ row_with_no_pivot, col_with_no_pivot);
1340
+ const HighsInt row_rank_deficiency =
1341
+ rank_deficiency - max(num_basic - num_row, (HighsInt)0);
1342
+ // Complete the permutation using the indices of rows with no pivot,
1343
+ // the last max(num_basic-num_row, 0) of which will be fictitious
1344
+ for (HighsInt k = 0; k < rank_deficiency; k++) {
1345
+ HighsInt iRow = row_with_no_pivot[k];
1346
+ HighsInt iCol = col_with_no_pivot[k];
1347
+ assert(permute[iCol] == -1);
1348
+ permute[iCol] = iRow;
1349
+ if (k < row_rank_deficiency) {
1350
+ // Only correct the factorization for the true rows
1351
+ l_start.push_back(l_index.size());
1352
+ u_pivot_index.push_back(iRow);
1353
+ u_pivot_value.push_back(1);
1354
+ u_start.push_back(u_index.size());
1355
+ }
1356
+ }
1357
+ debugReportRankDeficiency(2, highs_debug_level, log_options, num_row, permute,
1358
+ iwork, basic_index, rank_deficiency,
1359
+ row_with_no_pivot, col_with_no_pivot);
1360
+ debugReportRankDeficientASM(
1361
+ highs_debug_level, log_options, num_row, mc_start, mc_count_a, mc_index,
1362
+ mc_value, iwork, rank_deficiency, col_with_no_pivot, row_with_no_pivot);
1363
+ }
1364
+
1365
+ void HFactor::buildMarkSingC() {
1366
+ // Singular matrix B: reorder the basic variables so that the
1367
+ // singular columns are in the position corresponding to the
1368
+ // logical which replaces them
1369
+ debugReportMarkSingC(0, highs_debug_level, log_options, num_row, iwork,
1370
+ basic_index);
1371
+
1372
+ const HighsInt basic_index_rank_deficiency =
1373
+ rank_deficiency - max(num_row - num_basic, (HighsInt)0);
1374
+ var_with_no_pivot.resize(rank_deficiency);
1375
+ for (HighsInt k = 0; k < rank_deficiency; k++) {
1376
+ HighsInt ASMrow = row_with_no_pivot[k];
1377
+ HighsInt ASMcol = col_with_no_pivot[k];
1378
+ assert(ASMrow < (HighsInt)iwork.size());
1379
+ assert(-iwork[ASMrow] - 1 >= 0 && -iwork[ASMrow] - 1 < rank_deficiency);
1380
+ // Store negation of 1+ASMcol so that removing column 0 can be
1381
+ // identified!
1382
+ iwork[ASMrow] = -(ASMcol + 1);
1383
+ // Only update basic_index for the true entries
1384
+ if (ASMcol < num_basic) {
1385
+ assert(k < basic_index_rank_deficiency);
1386
+ // Record the variable in basic_index that had no pivot, and
1387
+ // replace it with the logical
1388
+ var_with_no_pivot[k] = basic_index[ASMcol];
1389
+ basic_index[ASMcol] = num_col + ASMrow;
1390
+ } else if (num_basic < num_row) {
1391
+ assert(ASMcol == num_basic + k - basic_index_rank_deficiency);
1392
+ // Record an illegal variable when there's no index to displace
1393
+ var_with_no_pivot[k] = -1;
1394
+ }
1395
+ }
1396
+ debugReportMarkSingC(1, highs_debug_level, log_options, num_row, iwork,
1397
+ basic_index);
1398
+ }
1399
+
1400
+ void HFactor::buildFinish() {
1401
+ // Must only be called in the case where there are at least as many basic
1402
+ // variables as rows
1403
+ assert(num_basic >= num_row);
1404
+ // debugPivotValueAnalysis(highs_debug_level, log_options, num_row,
1405
+ // u_pivot_value);
1406
+ // The look up table
1407
+ for (HighsInt i = 0; i < num_row; i++) u_pivot_lookup[u_pivot_index[i]] = i;
1408
+ l_pivot_index = u_pivot_index;
1409
+ l_pivot_lookup = u_pivot_lookup;
1410
+
1411
+ // LR space
1412
+ HighsInt LcountX = l_index.size();
1413
+ lr_index.resize(LcountX);
1414
+ lr_value.resize(LcountX);
1415
+
1416
+ // LR pointer
1417
+ iwork.assign(num_row, 0);
1418
+ for (HighsInt k = 0; k < LcountX; k++) iwork[l_pivot_lookup[l_index[k]]]++;
1419
+
1420
+ lr_start.assign(num_row + 1, 0);
1421
+ for (HighsInt i = 1; i <= num_row; i++)
1422
+ lr_start[i] = lr_start[i - 1] + iwork[i - 1];
1423
+
1424
+ // LR elements
1425
+ iwork.assign(&lr_start[0], &lr_start[num_row]);
1426
+ for (HighsInt i = 0; i < num_row; i++) {
1427
+ const HighsInt index = l_pivot_index[i];
1428
+ for (HighsInt k = l_start[i]; k < l_start[i + 1]; k++) {
1429
+ HighsInt iRow = l_pivot_lookup[l_index[k]];
1430
+ HighsInt i_put = iwork[iRow]++;
1431
+ lr_index[i_put] = index;
1432
+ lr_value[i_put] = l_value[k];
1433
+ }
1434
+ }
1435
+
1436
+ // U pointer
1437
+ u_start.push_back(0);
1438
+ u_last_p.assign(&u_start[1], &u_start[num_row + 1]);
1439
+ u_start.resize(num_row);
1440
+
1441
+ // UR space
1442
+ HighsInt u_countX = u_index.size();
1443
+ HighsInt ur_stuff_size = update_method == kUpdateMethodFt ? 5 : 0;
1444
+ HighsInt ur_count_size = u_countX + ur_stuff_size * num_row;
1445
+ ur_index.resize(ur_count_size);
1446
+ ur_value.resize(ur_count_size);
1447
+
1448
+ // UR pointer
1449
+ //
1450
+ // NB ur_lastp just being used as temporary storage here
1451
+ ur_start.assign(num_row + 1, 0);
1452
+ ur_lastp.assign(num_row, 0);
1453
+ ur_space.assign(num_row, ur_stuff_size);
1454
+ for (HighsInt k = 0; k < u_countX; k++)
1455
+ ur_lastp[u_pivot_lookup[u_index[k]]]++;
1456
+ for (HighsInt i = 1; i <= num_row; i++)
1457
+ ur_start[i] = ur_start[i - 1] + ur_lastp[i - 1] + ur_stuff_size;
1458
+ ur_start.resize(num_row);
1459
+
1460
+ // UR element
1461
+ //
1462
+ // NB ur_lastp initialised here!
1463
+ ur_lastp = ur_start;
1464
+ for (HighsInt i = 0; i < num_row; i++) {
1465
+ const HighsInt index = u_pivot_index[i];
1466
+ for (HighsInt k = u_start[i]; k < u_last_p[i]; k++) {
1467
+ HighsInt iRow = u_pivot_lookup[u_index[k]];
1468
+ HighsInt i_put = ur_lastp[iRow]++;
1469
+ ur_index[i_put] = index;
1470
+ ur_value[i_put] = u_value[k];
1471
+ }
1472
+ }
1473
+
1474
+ // Re-factor merit
1475
+ u_merit_x = num_row + (LcountX + u_countX) * 1.5;
1476
+ u_total_x = u_countX;
1477
+ if (update_method == kUpdateMethodPf) u_merit_x = num_row + u_countX * 4;
1478
+ if (update_method == kUpdateMethodMpf) u_merit_x = num_row + u_countX * 3;
1479
+
1480
+ // Clear update buffer
1481
+ pf_pivot_value.clear();
1482
+ pf_pivot_index.clear();
1483
+ pf_start.clear();
1484
+ pf_start.push_back(0);
1485
+ pf_index.clear();
1486
+ pf_value.clear();
1487
+
1488
+ if (!this->refactor_info_.use) {
1489
+ // Finally, if not calling buildFinish after refactorizing,
1490
+ // permute the basic variables
1491
+ iwork.assign(basic_index, basic_index + num_basic);
1492
+ for (HighsInt i = 0; i < num_basic; i++) basic_index[permute[i]] = iwork[i];
1493
+ // If there are more basic variables than rows, basic_index
1494
+ // should have been permuted so that its last num_basic-num_row
1495
+ // entries are logicals
1496
+ for (HighsInt i = num_row; i < num_basic; i++)
1497
+ assert(basic_index[i] >= num_col);
1498
+ // Add cost of buildFinish to build_synthetic_tick
1499
+ build_synthetic_tick += num_row * 80 + (LcountX + u_countX) * 60;
1500
+ }
1501
+ }
1502
+
1503
+ void HFactor::zeroCol(const HighsInt jCol) {
1504
+ const HighsInt a_count = mc_count_a[jCol];
1505
+ const HighsInt a_start = mc_start[jCol];
1506
+ const HighsInt a_end = a_start + a_count;
1507
+ for (HighsInt iEl = a_start; iEl < a_end; iEl++) {
1508
+ const double abs_value = std::abs(mc_value[iEl]);
1509
+ const HighsInt iRow = mc_index[iEl];
1510
+ const HighsInt original_row_count = mr_count[iRow];
1511
+ // Remove the column index from this row of the row-wise
1512
+ // matrix. Also decreases the row count
1513
+ rowDelete(jCol, iRow);
1514
+ // Remove this row from the linked list of rows containing it
1515
+ rlinkDel(iRow);
1516
+ // Add the this row to the linked list of rows with this reduced
1517
+ // count
1518
+ assert(mr_count[iRow] == original_row_count - 1);
1519
+ rlinkAdd(iRow, mr_count[iRow]);
1520
+ assert(abs_value < pivot_tolerance);
1521
+ }
1522
+ // Remove the column from the linked list of columns containing it
1523
+ clinkDel(jCol);
1524
+ // Zero the counts of the active and inactive sections of the column
1525
+ mc_count_a[jCol] = 0;
1526
+ mc_count_n[jCol] = 0;
1527
+ }
1528
+
1529
+ void HFactor::ftranL(HVector& rhs, const double expected_density,
1530
+ HighsTimerClock* factor_timer_clock_pointer) const {
1531
+ FactorTimer factor_timer;
1532
+ factor_timer.start(FactorFtranLower, factor_timer_clock_pointer);
1533
+ if (update_method == kUpdateMethodApf) {
1534
+ assert(!(update_method == kUpdateMethodApf));
1535
+ factor_timer.start(FactorFtranLowerAPF, factor_timer_clock_pointer);
1536
+ rhs.tight();
1537
+ rhs.pack();
1538
+ ftranAPF(rhs);
1539
+ factor_timer.stop(FactorFtranLowerAPF, factor_timer_clock_pointer);
1540
+ rhs.tight();
1541
+ }
1542
+
1543
+ // Determine style of solve
1544
+ double current_density = 1.0 * rhs.count * inv_num_row;
1545
+ const bool sparse_solve = rhs.count < 0 || current_density > kHyperCancel ||
1546
+ expected_density > kHyperFtranL;
1547
+ if (sparse_solve) {
1548
+ factor_timer.start(FactorFtranLowerSps, factor_timer_clock_pointer);
1549
+ // Alias to RHS
1550
+ HighsInt* rhs_index = rhs.index.data();
1551
+ double* rhs_array = rhs.array.data();
1552
+ // Alias to factor L
1553
+ const HighsInt* l_start = this->l_start.data();
1554
+ const HighsInt* l_index = this->l_index.data();
1555
+ const double* l_value = this->l_value.data();
1556
+ // Local accumulation of RHS count
1557
+ HighsInt rhs_count = 0;
1558
+ // Transform
1559
+ for (HighsInt i = 0; i < num_row; i++) {
1560
+ HighsInt pivotRow = l_pivot_index[i];
1561
+ const double pivot_multiplier = rhs_array[pivotRow];
1562
+ if (fabs(pivot_multiplier) > kHighsTiny) {
1563
+ rhs_index[rhs_count++] = pivotRow;
1564
+ const HighsInt start = l_start[i];
1565
+ const HighsInt end = l_start[i + 1];
1566
+ for (HighsInt k = start; k < end; k++)
1567
+ rhs_array[l_index[k]] -= pivot_multiplier * l_value[k];
1568
+ } else
1569
+ rhs_array[pivotRow] = 0;
1570
+ }
1571
+ // Save the count
1572
+ rhs.count = rhs_count;
1573
+ factor_timer.stop(FactorFtranLowerSps, factor_timer_clock_pointer);
1574
+ } else {
1575
+ // Hyper-sparse solve
1576
+ factor_timer.start(FactorFtranLowerHyper, factor_timer_clock_pointer);
1577
+ const HighsInt* l_index = this->l_index.data();
1578
+ const double* l_value = this->l_value.data();
1579
+ solveHyper(num_row, l_pivot_lookup.data(), l_pivot_index.data(), 0,
1580
+ l_start.data(), &l_start[1], &l_index[0], &l_value[0], &rhs);
1581
+ factor_timer.stop(FactorFtranLowerHyper, factor_timer_clock_pointer);
1582
+ }
1583
+ factor_timer.stop(FactorFtranLower, factor_timer_clock_pointer);
1584
+ }
1585
+
1586
+ void HFactor::btranL(HVector& rhs, const double expected_density,
1587
+ HighsTimerClock* factor_timer_clock_pointer) const {
1588
+ FactorTimer factor_timer;
1589
+ factor_timer.start(FactorBtranLower, factor_timer_clock_pointer);
1590
+
1591
+ // Determine style of solve
1592
+ const double current_density = 1.0 * rhs.count * inv_num_row;
1593
+ const bool sparse_solve = rhs.count < 0 || current_density > kHyperCancel ||
1594
+ expected_density > kHyperBtranL;
1595
+ if (sparse_solve) {
1596
+ factor_timer.start(FactorBtranLowerSps, factor_timer_clock_pointer);
1597
+ // Alias to RHS
1598
+ HighsInt* rhs_index = rhs.index.data();
1599
+ double* rhs_array = rhs.array.data();
1600
+ // Alias to factor L
1601
+ const HighsInt* lr_start = this->lr_start.data();
1602
+ const HighsInt* lr_index = this->lr_index.data();
1603
+ const double* lr_value = this->lr_value.data();
1604
+ // Local accumulation of RHS count
1605
+ HighsInt rhs_count = 0;
1606
+ // Transform
1607
+ for (HighsInt i = num_row - 1; i >= 0; i--) {
1608
+ HighsInt pivotRow = l_pivot_index[i];
1609
+ const double pivot_multiplier = rhs_array[pivotRow];
1610
+ if (fabs(pivot_multiplier) > kHighsTiny) {
1611
+ rhs_index[rhs_count++] = pivotRow;
1612
+ rhs_array[pivotRow] = pivot_multiplier;
1613
+ const HighsInt start = lr_start[i];
1614
+ const HighsInt end = lr_start[i + 1];
1615
+ for (HighsInt k = start; k < end; k++)
1616
+ rhs_array[lr_index[k]] -= pivot_multiplier * lr_value[k];
1617
+ } else
1618
+ rhs_array[pivotRow] = 0;
1619
+ }
1620
+ // Save the count
1621
+ rhs.count = rhs_count;
1622
+ factor_timer.stop(FactorBtranLowerSps, factor_timer_clock_pointer);
1623
+ } else {
1624
+ // Hyper-sparse solve
1625
+ factor_timer.start(FactorBtranLowerHyper, factor_timer_clock_pointer);
1626
+ const HighsInt* lr_index = this->lr_index.data();
1627
+ const double* lr_value = this->lr_value.data();
1628
+ solveHyper(num_row, l_pivot_lookup.data(), l_pivot_index.data(), 0,
1629
+ lr_start.data(), &lr_start[1], &lr_index[0], &lr_value[0], &rhs);
1630
+ factor_timer.stop(FactorBtranLowerHyper, factor_timer_clock_pointer);
1631
+ }
1632
+
1633
+ if (update_method == kUpdateMethodApf) {
1634
+ factor_timer.start(FactorBtranLowerAPF, factor_timer_clock_pointer);
1635
+ btranAPF(rhs);
1636
+ rhs.tight();
1637
+ rhs.pack();
1638
+ factor_timer.stop(FactorBtranLowerAPF, factor_timer_clock_pointer);
1639
+ }
1640
+ factor_timer.stop(FactorBtranLower, factor_timer_clock_pointer);
1641
+ }
1642
+
1643
+ void HFactor::ftranU(HVector& rhs, const double expected_density,
1644
+ HighsTimerClock* factor_timer_clock_pointer) const {
1645
+ assert(rhs.count >= 0);
1646
+ FactorTimer factor_timer;
1647
+ factor_timer.start(FactorFtranUpper, factor_timer_clock_pointer);
1648
+ // The update part
1649
+ if (update_method == kUpdateMethodFt) {
1650
+ factor_timer.start(FactorFtranUpperFT, factor_timer_clock_pointer);
1651
+ ftranFT(rhs);
1652
+ rhs.tight();
1653
+ rhs.pack();
1654
+ factor_timer.stop(FactorFtranUpperFT, factor_timer_clock_pointer);
1655
+ } else if (update_method == kUpdateMethodMpf) {
1656
+ assert(!(update_method == kUpdateMethodMpf));
1657
+ factor_timer.start(FactorFtranUpperMPF, factor_timer_clock_pointer);
1658
+ ftranMPF(rhs);
1659
+ rhs.tight();
1660
+ rhs.pack();
1661
+ factor_timer.stop(FactorFtranUpperMPF, factor_timer_clock_pointer);
1662
+ }
1663
+
1664
+ // The regular part
1665
+ //
1666
+ // Determine style of solve
1667
+ const double current_density = 1.0 * rhs.count * inv_num_row;
1668
+ const bool sparse_solve = rhs.count < 0 || current_density > kHyperCancel ||
1669
+ expected_density > kHyperFtranU;
1670
+ if (sparse_solve) {
1671
+ const bool report_ftran_upper_sparse =
1672
+ false; // current_density < kHyperCancel;
1673
+ HighsInt use_clock;
1674
+ if (current_density < 0.1)
1675
+ use_clock = FactorFtranUpperSps2;
1676
+ else if (current_density < 0.5)
1677
+ use_clock = FactorFtranUpperSps1;
1678
+ else
1679
+ use_clock = FactorFtranUpperSps0;
1680
+ factor_timer.start(use_clock, factor_timer_clock_pointer);
1681
+ // Alias to non constant
1682
+ double rhs_synthetic_tick = 0;
1683
+ // Alias to RHS
1684
+ HighsInt* rhs_index = rhs.index.data();
1685
+ double* rhs_array = rhs.array.data();
1686
+ // Alias to factor U
1687
+ const HighsInt* u_start = this->u_start.data();
1688
+ const HighsInt* u_end = this->u_last_p.data();
1689
+ const HighsInt* u_index = this->u_index.data();
1690
+ const double* u_value = this->u_value.data();
1691
+ // Local accumulation of RHS count
1692
+ HighsInt rhs_count = 0;
1693
+ // Transform
1694
+ HighsInt u_pivot_count = u_pivot_index.size();
1695
+ for (HighsInt i_logic = u_pivot_count - 1; i_logic >= 0; i_logic--) {
1696
+ // Skip void
1697
+ if (u_pivot_index[i_logic] == -1) continue;
1698
+ // Normal part
1699
+ const HighsInt pivotRow = u_pivot_index[i_logic];
1700
+ double pivot_multiplier = rhs_array[pivotRow];
1701
+ if (fabs(pivot_multiplier) > kHighsTiny) {
1702
+ pivot_multiplier /= u_pivot_value[i_logic];
1703
+ rhs_index[rhs_count++] = pivotRow;
1704
+ rhs_array[pivotRow] = pivot_multiplier;
1705
+ const HighsInt start = u_start[i_logic];
1706
+ const HighsInt end = u_end[i_logic];
1707
+ if (i_logic >= num_row) {
1708
+ rhs_synthetic_tick += (end - start);
1709
+ }
1710
+ for (HighsInt k = start; k < end; k++)
1711
+ rhs_array[u_index[k]] -= pivot_multiplier * u_value[k];
1712
+ } else
1713
+ rhs_array[pivotRow] = 0;
1714
+ }
1715
+ // Save the count
1716
+ rhs.count = rhs_count;
1717
+ rhs.synthetic_tick +=
1718
+ rhs_synthetic_tick * 15 + (u_pivot_count - num_row) * 10;
1719
+ factor_timer.stop(use_clock, factor_timer_clock_pointer);
1720
+ if (report_ftran_upper_sparse) {
1721
+ const double final_density = 1.0 * rhs.count * inv_num_row;
1722
+ printf(
1723
+ "FactorFtranUpperSps: expected_density = %10.4g; current_density = "
1724
+ "%10.4g; final_density = %10.4g\n",
1725
+ expected_density, current_density, final_density);
1726
+ }
1727
+ } else {
1728
+ HighsInt use_clock = -1;
1729
+ if (current_density < 5e-6)
1730
+ use_clock = FactorFtranUpperHyper5;
1731
+ else if (current_density < 1e-5)
1732
+ use_clock = FactorFtranUpperHyper4;
1733
+ else if (current_density < 1e-4)
1734
+ use_clock = FactorFtranUpperHyper3;
1735
+ else if (current_density < 1e-3)
1736
+ use_clock = FactorFtranUpperHyper2;
1737
+ else if (current_density < 1e-2)
1738
+ use_clock = FactorFtranUpperHyper1;
1739
+ else
1740
+ use_clock = FactorFtranUpperHyper0;
1741
+ factor_timer.start(use_clock, factor_timer_clock_pointer);
1742
+ const HighsInt* u_index = this->u_index.data();
1743
+ const double* u_value = this->u_value.data();
1744
+ solveHyper(num_row, u_pivot_lookup.data(), u_pivot_index.data(),
1745
+ u_pivot_value.data(), u_start.data(), u_last_p.data(),
1746
+ &u_index[0], &u_value[0], &rhs);
1747
+ factor_timer.stop(use_clock, factor_timer_clock_pointer);
1748
+ }
1749
+ if (update_method == kUpdateMethodPf) {
1750
+ assert(!(update_method == kUpdateMethodPf));
1751
+ factor_timer.start(FactorFtranUpperPF, factor_timer_clock_pointer);
1752
+ ftranPF(rhs);
1753
+ rhs.tight();
1754
+ rhs.pack();
1755
+ factor_timer.stop(FactorFtranUpperPF, factor_timer_clock_pointer);
1756
+ }
1757
+ factor_timer.stop(FactorFtranUpper, factor_timer_clock_pointer);
1758
+ }
1759
+
1760
+ void HFactor::btranU(HVector& rhs, const double expected_density,
1761
+ HighsTimerClock* factor_timer_clock_pointer) const {
1762
+ FactorTimer factor_timer;
1763
+ factor_timer.start(FactorBtranUpper, factor_timer_clock_pointer);
1764
+ if (update_method == kUpdateMethodPf) {
1765
+ assert(!(update_method == kUpdateMethodPf));
1766
+ factor_timer.start(FactorBtranUpperPF, factor_timer_clock_pointer);
1767
+ btranPF(rhs);
1768
+ factor_timer.stop(FactorBtranUpperPF, factor_timer_clock_pointer);
1769
+ }
1770
+
1771
+ // The regular part
1772
+ //
1773
+ // Determine style of solve
1774
+ const double current_density = 1.0 * rhs.count * inv_num_row;
1775
+ const bool sparse_solve = rhs.count < 0 || current_density > kHyperCancel ||
1776
+ expected_density > kHyperBtranU;
1777
+ if (sparse_solve) {
1778
+ factor_timer.start(FactorBtranUpperSps, factor_timer_clock_pointer);
1779
+ // Alias to non constant
1780
+ double rhs_synthetic_tick = 0;
1781
+ // Alias to RHS
1782
+ double* rhs_array = rhs.array.data();
1783
+ HighsInt* rhs_index = rhs.index.data();
1784
+ // Alias to factor U
1785
+ const HighsInt* ur_start = this->ur_start.data();
1786
+ const HighsInt* ur_end = this->ur_lastp.data();
1787
+ const HighsInt* ur_index = this->ur_index.data();
1788
+ const double* ur_value = this->ur_value.data();
1789
+ // Local accumulation of RHS count
1790
+ HighsInt rhs_count = 0;
1791
+ // Transform
1792
+ HighsInt u_pivot_count = u_pivot_index.size();
1793
+ for (HighsInt i_logic = 0; i_logic < u_pivot_count; i_logic++) {
1794
+ // Skip void
1795
+ if (u_pivot_index[i_logic] == -1) continue;
1796
+ // Normal part
1797
+ const HighsInt pivotRow = u_pivot_index[i_logic];
1798
+ double pivot_multiplier = rhs_array[pivotRow];
1799
+ if (fabs(pivot_multiplier) > kHighsTiny) {
1800
+ pivot_multiplier /= u_pivot_value[i_logic];
1801
+ rhs_index[rhs_count++] = pivotRow;
1802
+ rhs_array[pivotRow] = pivot_multiplier;
1803
+ const HighsInt start = ur_start[i_logic];
1804
+ const HighsInt end = ur_end[i_logic];
1805
+ if (i_logic >= num_row) {
1806
+ rhs_synthetic_tick += (end - start);
1807
+ }
1808
+ for (HighsInt k = start; k < end; k++)
1809
+ rhs_array[ur_index[k]] -= pivot_multiplier * ur_value[k];
1810
+ } else
1811
+ rhs_array[pivotRow] = 0;
1812
+ }
1813
+ // Save the count
1814
+ rhs.count = rhs_count;
1815
+ rhs.synthetic_tick +=
1816
+ rhs_synthetic_tick * 15 + (u_pivot_count - num_row) * 10;
1817
+ factor_timer.stop(FactorBtranUpperSps, factor_timer_clock_pointer);
1818
+ } else {
1819
+ factor_timer.start(FactorBtranUpperHyper, factor_timer_clock_pointer);
1820
+ solveHyper(num_row, u_pivot_lookup.data(), u_pivot_index.data(),
1821
+ u_pivot_value.data(), &ur_start[0], ur_lastp.data(),
1822
+ &ur_index[0], &ur_value[0], &rhs);
1823
+ factor_timer.stop(FactorBtranUpperHyper, factor_timer_clock_pointer);
1824
+ }
1825
+
1826
+ // The update part
1827
+ assert(rhs.count >= 0);
1828
+ if (update_method == kUpdateMethodFt) {
1829
+ factor_timer.start(FactorBtranUpperFT, factor_timer_clock_pointer);
1830
+ rhs.tight();
1831
+ rhs.pack();
1832
+ btranFT(rhs);
1833
+ rhs.tight();
1834
+ factor_timer.stop(FactorBtranUpperFT, factor_timer_clock_pointer);
1835
+ }
1836
+ if (update_method == kUpdateMethodMpf) {
1837
+ assert(!(update_method == kUpdateMethodMpf));
1838
+ factor_timer.start(FactorBtranUpperMPF, factor_timer_clock_pointer);
1839
+ rhs.tight();
1840
+ rhs.pack();
1841
+ btranMPF(rhs);
1842
+ rhs.tight();
1843
+ factor_timer.stop(FactorBtranUpperMPF, factor_timer_clock_pointer);
1844
+ }
1845
+ factor_timer.stop(FactorBtranUpper, factor_timer_clock_pointer);
1846
+ }
1847
+
1848
+ void HFactor::ftranFT(HVector& vector) const {
1849
+ // Alias to non constant
1850
+ assert(vector.count >= 0);
1851
+ HighsInt rhs_count = vector.count;
1852
+ HighsInt* rhs_index = vector.index.data();
1853
+ double* rhs_array = vector.array.data();
1854
+ // Alias to PF buffer
1855
+ const HighsInt pf_pivot_count = pf_pivot_index.size();
1856
+ const HighsInt* pf_pivot_index = this->pf_pivot_index.data();
1857
+ const HighsInt* pf_start = this->pf_start.data();
1858
+ const HighsInt* pf_index = this->pf_index.data();
1859
+ const double* pf_value = this->pf_value.data();
1860
+ for (HighsInt i = 0; i < pf_pivot_count; i++) {
1861
+ HighsInt iRow = pf_pivot_index[i];
1862
+ double value0 = rhs_array[iRow];
1863
+ double value1 = value0;
1864
+ const HighsInt start = pf_start[i];
1865
+ const HighsInt end = pf_start[i + 1];
1866
+ for (HighsInt k = start; k < end; k++)
1867
+ value1 -= rhs_array[pf_index[k]] * pf_value[k];
1868
+ // This would skip the situation where they are both zeros
1869
+ if (value0 || value1) {
1870
+ if (value0 == 0) rhs_index[rhs_count++] = iRow;
1871
+ rhs_array[iRow] = (fabs(value1) < kHighsTiny) ? kHighsZero : value1;
1872
+ }
1873
+ }
1874
+ // Save count back
1875
+ vector.count = rhs_count;
1876
+ vector.synthetic_tick += pf_pivot_count * 20 + pf_start[pf_pivot_count] * 5;
1877
+ if (pf_start[pf_pivot_count] / (pf_pivot_count + 1) < 5) {
1878
+ vector.synthetic_tick += pf_start[pf_pivot_count] * 5;
1879
+ }
1880
+ }
1881
+
1882
+ void HFactor::btranFT(HVector& vector) const {
1883
+ // Alias to non constant
1884
+ assert(vector.count >= 0);
1885
+ HighsInt rhs_count = vector.count;
1886
+ HighsInt* rhs_index = vector.index.data();
1887
+ double* rhs_array = vector.array.data();
1888
+ // Alias to PF buffer
1889
+ const HighsInt pf_pivot_count = pf_pivot_index.size();
1890
+ const HighsInt* pf_pivot_index = this->pf_pivot_index.data();
1891
+ const HighsInt* pf_start = this->pf_start.data();
1892
+ const HighsInt* pf_index = this->pf_index.data();
1893
+ const double* pf_value = this->pf_value.data();
1894
+ // Apply row ETA backward
1895
+ double rhs_synthetic_tick = 0;
1896
+ for (HighsInt i = pf_pivot_count - 1; i >= 0; i--) {
1897
+ HighsInt pivotRow = pf_pivot_index[i];
1898
+ double pivot_multiplier = rhs_array[pivotRow];
1899
+ if (pivot_multiplier) {
1900
+ const HighsInt start = pf_start[i];
1901
+ const HighsInt end = pf_start[i + 1];
1902
+ rhs_synthetic_tick += (end - start);
1903
+ for (HighsInt k = start; k < end; k++) {
1904
+ HighsInt iRow = pf_index[k];
1905
+ double value0 = rhs_array[iRow];
1906
+ double value1 = value0 - pivot_multiplier * pf_value[k];
1907
+ if (value0 == 0) rhs_index[rhs_count++] = iRow;
1908
+ rhs_array[iRow] = (fabs(value1) < kHighsTiny) ? kHighsZero : value1;
1909
+ }
1910
+ }
1911
+ }
1912
+ vector.synthetic_tick += rhs_synthetic_tick * 15 + pf_pivot_count * 10;
1913
+ // Save count back
1914
+ vector.count = rhs_count;
1915
+ }
1916
+
1917
+ void HFactor::ftranPF(HVector& vector) const {
1918
+ // Alias to PF buffer
1919
+ const HighsInt pf_pivot_count = pf_pivot_index.size();
1920
+ const HighsInt* pf_pivot_index = this->pf_pivot_index.data();
1921
+ const double* pf_pivot_value = this->pf_pivot_value.data();
1922
+ const HighsInt* pf_start = this->pf_start.data();
1923
+ const HighsInt* pf_index = this->pf_index.data();
1924
+ const double* pf_value = this->pf_value.data();
1925
+
1926
+ // Alias to non constant
1927
+ HighsInt rhs_count = vector.count;
1928
+ HighsInt* rhs_index = vector.index.data();
1929
+ double* rhs_array = vector.array.data();
1930
+
1931
+ // Forwardly
1932
+ for (HighsInt i = 0; i < pf_pivot_count; i++) {
1933
+ HighsInt pivotRow = pf_pivot_index[i];
1934
+ double pivot_multiplier = rhs_array[pivotRow];
1935
+ if (fabs(pivot_multiplier) > kHighsTiny) {
1936
+ pivot_multiplier /= pf_pivot_value[i];
1937
+ rhs_array[pivotRow] = pivot_multiplier;
1938
+ for (HighsInt k = pf_start[i]; k < pf_start[i + 1]; k++) {
1939
+ const HighsInt index = pf_index[k];
1940
+ const double value0 = rhs_array[index];
1941
+ const double value1 = value0 - pivot_multiplier * pf_value[k];
1942
+ if (value0 == 0) rhs_index[rhs_count++] = index;
1943
+ rhs_array[index] = (fabs(value1) < kHighsTiny) ? kHighsZero : value1;
1944
+ }
1945
+ }
1946
+ }
1947
+
1948
+ // Save count
1949
+ vector.count = rhs_count;
1950
+ }
1951
+
1952
+ void HFactor::btranPF(HVector& vector) const {
1953
+ // Alias to PF buffer
1954
+ const HighsInt pf_pivot_count = pf_pivot_index.size();
1955
+ const HighsInt* pf_pivot_index = this->pf_pivot_index.data();
1956
+ const double* pf_pivot_value = this->pf_pivot_value.data();
1957
+ const HighsInt* pf_start = this->pf_start.data();
1958
+ const HighsInt* pf_index = this->pf_index.data();
1959
+ const double* pf_value = this->pf_value.data();
1960
+
1961
+ // Alias to non constant
1962
+ HighsInt rhs_count = vector.count;
1963
+ HighsInt* rhs_index = vector.index.data();
1964
+ double* rhs_array = vector.array.data();
1965
+
1966
+ // Backwardly
1967
+ for (HighsInt i = pf_pivot_count - 1; i >= 0; i--) {
1968
+ HighsInt pivotRow = pf_pivot_index[i];
1969
+ double pivot_multiplier = rhs_array[pivotRow];
1970
+ for (HighsInt k = pf_start[i]; k < pf_start[i + 1]; k++)
1971
+ pivot_multiplier -= pf_value[k] * rhs_array[pf_index[k]];
1972
+ pivot_multiplier /= pf_pivot_value[i];
1973
+
1974
+ if (rhs_array[pivotRow] == 0) rhs_index[rhs_count++] = pivotRow;
1975
+ rhs_array[pivotRow] =
1976
+ (fabs(pivot_multiplier) < kHighsTiny) ? 1e-100 : pivot_multiplier;
1977
+ }
1978
+
1979
+ // Save count
1980
+ vector.count = rhs_count;
1981
+ }
1982
+
1983
+ void HFactor::ftranMPF(HVector& vector) const {
1984
+ // Alias to non constant
1985
+ HighsInt rhs_count = vector.count;
1986
+ HighsInt* rhs_index = vector.index.data();
1987
+ double* rhs_array = vector.array.data();
1988
+
1989
+ // Forwardly
1990
+ HighsInt pf_pivot_count = pf_pivot_value.size();
1991
+ for (HighsInt i = 0; i < pf_pivot_count; i++) {
1992
+ solveMatrixT(pf_start[i * 2 + 1], pf_start[i * 2 + 2], pf_start[i * 2],
1993
+ pf_start[i * 2 + 1], pf_index.data(), pf_value.data(),
1994
+ pf_pivot_value[i], &rhs_count, rhs_index, rhs_array);
1995
+ }
1996
+
1997
+ // Remove cancellation
1998
+ vector.count = rhs_count;
1999
+ }
2000
+
2001
+ void HFactor::btranMPF(HVector& vector) const {
2002
+ // Alias to non constant
2003
+ HighsInt rhs_count = vector.count;
2004
+ HighsInt* rhs_index = vector.index.data();
2005
+ double* rhs_array = vector.array.data();
2006
+
2007
+ // Backwardly
2008
+ for (HighsInt i = pf_pivot_value.size() - 1; i >= 0; i--) {
2009
+ solveMatrixT(pf_start[i * 2], pf_start[i * 2 + 1], pf_start[i * 2 + 1],
2010
+ pf_start[i * 2 + 2], pf_index.data(), pf_value.data(),
2011
+ pf_pivot_value[i], &rhs_count, rhs_index, rhs_array);
2012
+ }
2013
+
2014
+ // Remove cancellation
2015
+ vector.count = rhs_count;
2016
+ }
2017
+
2018
+ void HFactor::ftranAPF(HVector& vector) const {
2019
+ // Alias to non constant
2020
+ HighsInt rhs_count = vector.count;
2021
+ HighsInt* rhs_index = vector.index.data();
2022
+ double* rhs_array = vector.array.data();
2023
+
2024
+ // Backwardly
2025
+ HighsInt pf_pivot_count = pf_pivot_value.size();
2026
+ for (HighsInt i = pf_pivot_count - 1; i >= 0; i--) {
2027
+ solveMatrixT(pf_start[i * 2 + 1], pf_start[i * 2 + 2], pf_start[i * 2],
2028
+ pf_start[i * 2 + 1], pf_index.data(), pf_value.data(),
2029
+ pf_pivot_value[i], &rhs_count, rhs_index, rhs_array);
2030
+ }
2031
+
2032
+ // Remove cancellation
2033
+ vector.count = rhs_count;
2034
+ }
2035
+
2036
+ void HFactor::btranAPF(HVector& vector) const {
2037
+ // Alias to non constant
2038
+ HighsInt rhs_count = vector.count;
2039
+ HighsInt* rhs_index = vector.index.data();
2040
+ double* rhs_array = vector.array.data();
2041
+
2042
+ // Forwardly
2043
+ HighsInt pf_pivot_count = pf_pivot_value.size();
2044
+ for (HighsInt i = 0; i < pf_pivot_count; i++) {
2045
+ solveMatrixT(pf_start[i * 2], pf_start[i * 2 + 1], pf_start[i * 2 + 1],
2046
+ pf_start[i * 2 + 2], pf_index.data(), pf_value.data(),
2047
+ pf_pivot_value[i], &rhs_count, rhs_index, rhs_array);
2048
+ }
2049
+ vector.count = rhs_count;
2050
+ }
2051
+
2052
+ void HFactor::updateCFT(HVector* aq, HVector* ep, HighsInt* iRow
2053
+ //, HighsInt* hint
2054
+ ) {
2055
+ /*
2056
+ * In the major update loop, the prefix
2057
+ *
2058
+ * c(p) = current working pivot
2059
+ * p(p) = previous pivot (0 =< pp < cp)
2060
+ */
2061
+
2062
+ HighsInt num_update = 0;
2063
+ for (HVector* vec = aq; vec != 0; vec = vec->next) num_update++;
2064
+
2065
+ HVector** aq_work = new HVector*[num_update];
2066
+ HVector** ep_work = new HVector*[num_update];
2067
+
2068
+ for (HighsInt i = 0; i < num_update; i++) {
2069
+ aq_work[i] = aq;
2070
+ ep_work[i] = ep;
2071
+ aq = aq->next;
2072
+ ep = ep->next;
2073
+ }
2074
+
2075
+ // Pivot related buffers
2076
+ HighsInt pf_np0 = pf_pivot_index.size();
2077
+ HighsInt* p_logic = new HighsInt[num_update];
2078
+ double* p_value = new double[num_update];
2079
+ double* p_alpha = new double[num_update];
2080
+ for (HighsInt cp = 0; cp < num_update; cp++) {
2081
+ HighsInt c_row = iRow[cp];
2082
+ HighsInt i_logic = u_pivot_lookup[c_row];
2083
+ p_logic[cp] = i_logic;
2084
+ p_value[cp] = u_pivot_value[i_logic];
2085
+ p_alpha[cp] = aq_work[cp]->array[c_row];
2086
+ }
2087
+
2088
+ // Temporary U pointers
2089
+ HighsInt* t_start = new HighsInt[num_update + 1];
2090
+ double* t_pivot = new double[num_update];
2091
+ t_start[0] = u_index.size();
2092
+
2093
+ // Logically sorted previous row_ep
2094
+ vector<pair<HighsInt, HighsInt>> sorted_pp;
2095
+
2096
+ // Major update loop
2097
+ for (HighsInt cp = 0; cp < num_update; cp++) {
2098
+ // 1. Expand partial FTRAN result to buffer
2099
+ iwork.clear();
2100
+ for (HighsInt i = 0; i < aq_work[cp]->packCount; i++) {
2101
+ HighsInt index = aq_work[cp]->packIndex[i];
2102
+ double value = aq_work[cp]->packValue[i];
2103
+ iwork.push_back(index);
2104
+ dwork[index] = value;
2105
+ }
2106
+
2107
+ // 2. Update partial FTRAN result by recent FT matrix
2108
+ for (HighsInt pp = 0; pp < cp; pp++) {
2109
+ HighsInt p_row = iRow[pp];
2110
+ double value = dwork[p_row];
2111
+ HighsInt pf_pp = pp + pf_np0;
2112
+ for (HighsInt i = pf_start[pf_pp]; i < pf_start[pf_pp + 1]; i++)
2113
+ value -= dwork[pf_index[i]] * pf_value[i];
2114
+ iwork.push_back(p_row); // OK to duplicate
2115
+ dwork[p_row] = value;
2116
+ }
2117
+
2118
+ // 3. Store the partial FTRAN result to matrix U
2119
+ double ppaq = dwork[iRow[cp]]; // pivot of the partial aq
2120
+ dwork[iRow[cp]] = 0;
2121
+ HighsInt u_countX = t_start[cp];
2122
+ HighsInt u_startX = u_countX;
2123
+ for (HighsInt index : iwork) {
2124
+ double value = dwork[index];
2125
+ dwork[index] = 0; // This effectively removes all duplication
2126
+ if (fabs(value) > kHighsTiny) {
2127
+ u_index.push_back(index);
2128
+ u_value.push_back(value);
2129
+ }
2130
+ }
2131
+ u_countX = u_index.size();
2132
+ t_start[cp + 1] = u_countX;
2133
+ t_pivot[cp] = p_value[cp] * p_alpha[cp];
2134
+
2135
+ // 4. Expand partial BTRAN result to buffer
2136
+ iwork.clear();
2137
+ for (HighsInt i = 0; i < ep_work[cp]->packCount; i++) {
2138
+ HighsInt index = ep_work[cp]->packIndex[i];
2139
+ double value = ep_work[cp]->packValue[i];
2140
+ iwork.push_back(index);
2141
+ dwork[index] = value;
2142
+ }
2143
+
2144
+ // 5. Delete logical later rows (in logical order)
2145
+ for (HighsInt isort = 0; isort < cp; isort++) {
2146
+ HighsInt pp = sorted_pp[isort].second;
2147
+ HighsInt p_row = iRow[pp];
2148
+ double multiplier = -p_value[pp] * dwork[p_row];
2149
+ if (fabs(dwork[p_row]) > kHighsTiny) {
2150
+ for (HighsInt i = 0; i < ep_work[pp]->packCount; i++) {
2151
+ HighsInt index = ep_work[pp]->packIndex[i];
2152
+ double value = ep_work[pp]->packValue[i];
2153
+ iwork.push_back(index);
2154
+ dwork[index] += value * multiplier;
2155
+ }
2156
+ }
2157
+ dwork[p_row] = 0; // Force to be 0
2158
+ }
2159
+
2160
+ // 6. Update partial BTRAN result by recent U columns
2161
+ for (HighsInt pp = 0; pp < cp; pp++) {
2162
+ HighsInt kpivot = iRow[pp];
2163
+ double value = dwork[kpivot];
2164
+ for (HighsInt k = t_start[pp]; k < t_start[pp + 1]; k++)
2165
+ value -= dwork[u_index[k]] * u_value[k];
2166
+ value /= t_pivot[pp];
2167
+ iwork.push_back(kpivot);
2168
+ dwork[kpivot] = value; // Again OK to duplicate
2169
+ }
2170
+
2171
+ // 6.x compute current alpha
2172
+ double thex = 0;
2173
+ for (HighsInt k = u_startX; k < u_countX; k++) {
2174
+ HighsInt index = u_index[k];
2175
+ double value = u_value[k];
2176
+ thex += dwork[index] * value;
2177
+ }
2178
+ t_pivot[cp] = ppaq + thex * p_value[cp];
2179
+
2180
+ // 7. Store BTRAN result to FT elimination, update logic helper
2181
+ dwork[iRow[cp]] = 0;
2182
+ double pivot_multiplier = -p_value[cp];
2183
+ for (HighsInt index : iwork) {
2184
+ double value = dwork[index];
2185
+ dwork[index] = 0;
2186
+ if (fabs(value) > kHighsTiny) {
2187
+ pf_index.push_back(index);
2188
+ pf_value.push_back(value * pivot_multiplier);
2189
+ }
2190
+ }
2191
+ pf_pivot_index.push_back(iRow[cp]);
2192
+ u_total_x += pf_index.size() - pf_start.back();
2193
+ pf_start.push_back(pf_index.size());
2194
+
2195
+ // 8. Update the sorted ep
2196
+ sorted_pp.push_back(make_pair(p_logic[cp], cp));
2197
+ pdqsort(sorted_pp.begin(), sorted_pp.end());
2198
+ }
2199
+
2200
+ // Now modify the U matrix
2201
+ for (HighsInt cp = 0; cp < num_update; cp++) {
2202
+ // 1. Delete pivotal row from U
2203
+ HighsInt cIndex = iRow[cp];
2204
+ HighsInt cLogic = p_logic[cp];
2205
+ u_total_x -= ur_lastp[cLogic] - ur_start[cLogic];
2206
+ for (HighsInt k = ur_start[cLogic]; k < ur_lastp[cLogic]; k++) {
2207
+ // Find the pivotal position
2208
+ HighsInt i_logic = u_pivot_lookup[ur_index[k]];
2209
+ HighsInt i_find = u_start[i_logic];
2210
+ HighsInt i_last = --u_last_p[i_logic];
2211
+ for (; i_find <= i_last; i_find++)
2212
+ if (u_index[i_find] == cIndex) break;
2213
+ // Put last to find, and delete last
2214
+ u_index[i_find] = u_index[i_last];
2215
+ u_value[i_find] = u_value[i_last];
2216
+ }
2217
+
2218
+ // 2. Delete pivotal column from UR
2219
+ u_total_x -= u_last_p[cLogic] - u_start[cLogic];
2220
+ for (HighsInt k = u_start[cLogic]; k < u_last_p[cLogic]; k++) {
2221
+ // Find the pivotal position
2222
+ HighsInt i_logic = u_pivot_lookup[u_index[k]];
2223
+ HighsInt i_find = ur_start[i_logic];
2224
+ HighsInt i_last = --ur_lastp[i_logic];
2225
+ for (; i_find <= i_last; i_find++)
2226
+ if (ur_index[i_find] == cIndex) break;
2227
+ // Put last to find, and delete last
2228
+ ur_space[i_logic]++;
2229
+ ur_index[i_find] = ur_index[i_last];
2230
+ ur_value[i_find] = ur_value[i_last];
2231
+ }
2232
+
2233
+ // 3. Insert the (stored) partial FTRAN to the row matrix
2234
+ HighsInt u_startX = t_start[cp];
2235
+ HighsInt u_endX = t_start[cp + 1];
2236
+ u_total_x += u_endX - u_startX;
2237
+ // Store column as UR elements
2238
+ for (HighsInt k = u_startX; k < u_endX; k++) {
2239
+ // Which ETA file
2240
+ HighsInt i_logic = u_pivot_lookup[u_index[k]];
2241
+
2242
+ // Move row to the end if necessary
2243
+ if (ur_space[i_logic] == 0) {
2244
+ // Make pointers
2245
+ HighsInt row_start = ur_start[i_logic];
2246
+ HighsInt row_count = ur_lastp[i_logic] - row_start;
2247
+ HighsInt new_start = ur_index.size();
2248
+ HighsInt new_space = row_count * 1.1 + 5;
2249
+
2250
+ // Check matrix UR
2251
+ ur_index.resize(new_start + new_space);
2252
+ ur_value.resize(new_start + new_space);
2253
+
2254
+ // Move elements
2255
+ HighsInt i_from = row_start;
2256
+ HighsInt i_end = row_start + row_count;
2257
+ HighsInt i_to = new_start;
2258
+ copy(&ur_index[i_from], &ur_index[i_end], &ur_index[i_to]);
2259
+ copy(&ur_value[i_from], &ur_value[i_end], &ur_value[i_to]);
2260
+
2261
+ // Save new pointers
2262
+ ur_start[i_logic] = new_start;
2263
+ ur_lastp[i_logic] = new_start + row_count;
2264
+ ur_space[i_logic] = new_space - row_count;
2265
+ }
2266
+
2267
+ // Put into the next available space
2268
+ ur_space[i_logic]--;
2269
+ HighsInt i_put = ur_lastp[i_logic]++;
2270
+ ur_index[i_put] = cIndex;
2271
+ ur_value[i_put] = u_value[k];
2272
+ }
2273
+
2274
+ // 4. Save pointers
2275
+ u_start.push_back(u_startX);
2276
+ u_last_p.push_back(u_endX);
2277
+
2278
+ ur_start.push_back(ur_start[cLogic]);
2279
+ ur_lastp.push_back(ur_start[cLogic]);
2280
+ ur_space.push_back(ur_space[cLogic] + ur_lastp[cLogic] - ur_start[cLogic]);
2281
+
2282
+ u_pivot_lookup[cIndex] = u_pivot_index.size();
2283
+ u_pivot_index[cLogic] = -1;
2284
+ u_pivot_index.push_back(cIndex);
2285
+ u_pivot_value.push_back(t_pivot[cp]);
2286
+ }
2287
+
2288
+ // // See if we want refactor
2289
+ // if (u_total_x > u_merit_x && pf_pivot_index.size() > 100)
2290
+ // *hint = 1;
2291
+ delete[] aq_work;
2292
+ delete[] ep_work;
2293
+ delete[] p_logic;
2294
+ delete[] p_value;
2295
+ delete[] p_alpha;
2296
+ delete[] t_start;
2297
+ delete[] t_pivot;
2298
+ }
2299
+
2300
+ void HFactor::updateFT(HVector* aq, HVector* ep, HighsInt iRow
2301
+ //, HighsInt* hint
2302
+ ) {
2303
+ // Store pivot
2304
+ HighsInt p_logic = u_pivot_lookup[iRow];
2305
+ double pivot = u_pivot_value[p_logic];
2306
+ double alpha = aq->array[iRow];
2307
+ u_pivot_index[p_logic] = -1;
2308
+
2309
+ // Delete pivotal row from U
2310
+ for (HighsInt k = ur_start[p_logic]; k < ur_lastp[p_logic]; k++) {
2311
+ // Find the pivotal position
2312
+ HighsInt i_logic = u_pivot_lookup[ur_index[k]];
2313
+ HighsInt i_find = u_start[i_logic];
2314
+ HighsInt i_last = --u_last_p[i_logic];
2315
+ for (; i_find <= i_last; i_find++)
2316
+ if (u_index[i_find] == iRow) break;
2317
+ // Put last to find, and delete last
2318
+ u_index[i_find] = u_index[i_last];
2319
+ u_value[i_find] = u_value[i_last];
2320
+ }
2321
+
2322
+ // Delete pivotal column from UR
2323
+ for (HighsInt k = u_start[p_logic]; k < u_last_p[p_logic]; k++) {
2324
+ // Find the pivotal position
2325
+ HighsInt i_logic = u_pivot_lookup[u_index[k]];
2326
+ HighsInt i_find = ur_start[i_logic];
2327
+ HighsInt i_last = --ur_lastp[i_logic];
2328
+ for (; i_find <= i_last; i_find++)
2329
+ if (ur_index[i_find] == iRow) break;
2330
+ // Put last to find, and delete last
2331
+ ur_space[i_logic]++;
2332
+ ur_index[i_find] = ur_index[i_last];
2333
+ ur_value[i_find] = ur_value[i_last];
2334
+ }
2335
+
2336
+ // Store column to U
2337
+ u_start.push_back(u_index.size());
2338
+ for (HighsInt i = 0; i < aq->packCount; i++)
2339
+ if (aq->packIndex[i] != iRow) {
2340
+ u_index.push_back(aq->packIndex[i]);
2341
+ u_value.push_back(aq->packValue[i]);
2342
+ }
2343
+ u_last_p.push_back(u_index.size());
2344
+ HighsInt u_startX = u_start.back();
2345
+ HighsInt u_endX = u_last_p.back();
2346
+ u_total_x += u_endX - u_startX + 1;
2347
+
2348
+ // Store column as UR elements
2349
+ for (HighsInt k = u_startX; k < u_endX; k++) {
2350
+ // Which ETA file
2351
+ HighsInt i_logic = u_pivot_lookup[u_index[k]];
2352
+
2353
+ // Move row to the end if necessary
2354
+ if (ur_space[i_logic] == 0) {
2355
+ // Make pointers
2356
+ HighsInt row_start = ur_start[i_logic];
2357
+ HighsInt row_count = ur_lastp[i_logic] - row_start;
2358
+ HighsInt new_start = ur_index.size();
2359
+ HighsInt new_space = row_count * 1.1 + 5;
2360
+
2361
+ // Check matrix UR
2362
+ ur_index.resize(new_start + new_space);
2363
+ ur_value.resize(new_start + new_space);
2364
+
2365
+ // Move elements
2366
+ HighsInt i_from = row_start;
2367
+ HighsInt i_end = row_start + row_count;
2368
+ HighsInt i_to = new_start;
2369
+ copy(&ur_index[i_from], &ur_index[i_end], &ur_index[i_to]);
2370
+ copy(&ur_value[i_from], &ur_value[i_end], &ur_value[i_to]);
2371
+
2372
+ // Save new pointers
2373
+ ur_start[i_logic] = new_start;
2374
+ ur_lastp[i_logic] = new_start + row_count;
2375
+ ur_space[i_logic] = new_space - row_count;
2376
+ }
2377
+
2378
+ // Put into the next available space
2379
+ ur_space[i_logic]--;
2380
+ HighsInt i_put = ur_lastp[i_logic]++;
2381
+ ur_index[i_put] = iRow;
2382
+ ur_value[i_put] = u_value[k];
2383
+ }
2384
+
2385
+ // Store UR pointers
2386
+ ur_start.push_back(ur_start[p_logic]);
2387
+ ur_lastp.push_back(ur_start[p_logic]);
2388
+ ur_space.push_back(ur_space[p_logic] + ur_lastp[p_logic] - ur_start[p_logic]);
2389
+
2390
+ // Update pivot count
2391
+ u_pivot_lookup[iRow] = u_pivot_index.size();
2392
+ u_pivot_index.push_back(iRow);
2393
+ u_pivot_value.push_back(pivot * alpha);
2394
+
2395
+ // Store row_ep as R matrix
2396
+ for (HighsInt i = 0; i < ep->packCount; i++) {
2397
+ if (ep->packIndex[i] != iRow) {
2398
+ pf_index.push_back(ep->packIndex[i]);
2399
+ pf_value.push_back(-ep->packValue[i] * pivot);
2400
+ }
2401
+ }
2402
+ u_total_x += pf_index.size() - pf_start.back();
2403
+
2404
+ // Store R matrix pivot
2405
+ pf_pivot_index.push_back(iRow);
2406
+ pf_start.push_back(pf_index.size());
2407
+
2408
+ // Update total countX
2409
+ u_total_x -= u_last_p[p_logic] - u_start[p_logic];
2410
+ u_total_x -= ur_lastp[p_logic] - ur_start[p_logic];
2411
+
2412
+ // // See if we want refactor
2413
+ // if (u_total_x > u_merit_x && pf_pivot_index.size() > 100)
2414
+ // *hint = 1;
2415
+ }
2416
+
2417
+ void HFactor::updatePF(HVector* aq, HighsInt iRow, HighsInt* hint) {
2418
+ // Check space
2419
+ const HighsInt column_count = aq->packCount;
2420
+ const HighsInt* variable_index = aq->packIndex.data();
2421
+ const double* columnArray = aq->packValue.data();
2422
+
2423
+ // Copy the pivotal column
2424
+ for (HighsInt i = 0; i < column_count; i++) {
2425
+ HighsInt index = variable_index[i];
2426
+ double value = columnArray[i];
2427
+ if (index != iRow) {
2428
+ pf_index.push_back(index);
2429
+ pf_value.push_back(value);
2430
+ }
2431
+ }
2432
+
2433
+ // Save pivot
2434
+ pf_pivot_index.push_back(iRow);
2435
+ pf_pivot_value.push_back(aq->array[iRow]);
2436
+ pf_start.push_back(pf_index.size());
2437
+
2438
+ // Check refactor
2439
+ u_total_x += aq->packCount;
2440
+ if (u_total_x > u_merit_x) *hint = 1;
2441
+ }
2442
+
2443
+ void HFactor::updateMPF(HVector* aq, HVector* ep, HighsInt iRow,
2444
+ HighsInt* hint) {
2445
+ // Store elements
2446
+ for (HighsInt i = 0; i < aq->packCount; i++) {
2447
+ pf_index.push_back(aq->packIndex[i]);
2448
+ pf_value.push_back(aq->packValue[i]);
2449
+ }
2450
+ HighsInt p_logic = u_pivot_lookup[iRow];
2451
+ HighsInt u_startX = u_start[p_logic];
2452
+ HighsInt u_endX = u_start[p_logic + 1];
2453
+ for (HighsInt k = u_startX; k < u_endX; k++) {
2454
+ pf_index.push_back(u_index[k]);
2455
+ pf_value.push_back(-u_value[k]);
2456
+ }
2457
+ pf_index.push_back(iRow);
2458
+ pf_value.push_back(-u_pivot_value[p_logic]);
2459
+ pf_start.push_back(pf_index.size());
2460
+
2461
+ for (HighsInt i = 0; i < ep->packCount; i++) {
2462
+ pf_index.push_back(ep->packIndex[i]);
2463
+ pf_value.push_back(ep->packValue[i]);
2464
+ }
2465
+ pf_start.push_back(pf_index.size());
2466
+
2467
+ // Store pivot
2468
+ pf_pivot_value.push_back(aq->array[iRow]);
2469
+
2470
+ // Refactor or not
2471
+ u_total_x += aq->packCount + ep->packCount;
2472
+ if (u_total_x > u_merit_x) *hint = 1;
2473
+ }
2474
+
2475
+ void HFactor::updateAPF(HVector* aq, HVector* ep, HighsInt iRow
2476
+ //, HighsInt* hint
2477
+ ) {
2478
+ // Store elements
2479
+ for (HighsInt i = 0; i < aq->packCount; i++) {
2480
+ pf_index.push_back(aq->packIndex[i]);
2481
+ pf_value.push_back(aq->packValue[i]);
2482
+ }
2483
+
2484
+ HighsInt variable_out = basic_index[iRow];
2485
+ if (variable_out >= num_col) {
2486
+ pf_index.push_back(variable_out - num_col);
2487
+ pf_value.push_back(-1);
2488
+ } else {
2489
+ for (HighsInt k = a_start[variable_out]; k < a_start[variable_out + 1];
2490
+ k++) {
2491
+ pf_index.push_back(a_index[k]);
2492
+ pf_value.push_back(-a_value[k]);
2493
+ }
2494
+ }
2495
+ pf_start.push_back(pf_index.size());
2496
+
2497
+ for (HighsInt i = 0; i < ep->packCount; i++) {
2498
+ pf_index.push_back(ep->packIndex[i]);
2499
+ pf_value.push_back(ep->packValue[i]);
2500
+ }
2501
+ pf_start.push_back(pf_index.size());
2502
+
2503
+ // Store pivot
2504
+ pf_pivot_value.push_back(aq->array[iRow]);
2505
+ }
2506
+
2507
+ InvertibleRepresentation HFactor::getInvert() const {
2508
+ InvertibleRepresentation invert;
2509
+ invert.l_pivot_index = this->l_pivot_index;
2510
+ invert.l_pivot_lookup = this->l_pivot_lookup;
2511
+ invert.l_start = this->l_start;
2512
+ invert.l_index = this->l_index;
2513
+ invert.l_value = this->l_value;
2514
+ invert.lr_start = this->lr_start;
2515
+ invert.lr_index = this->lr_index;
2516
+ invert.lr_value = this->lr_value;
2517
+
2518
+ invert.u_pivot_lookup = this->u_pivot_lookup;
2519
+ invert.u_pivot_index = this->u_pivot_index;
2520
+ invert.u_pivot_value = this->u_pivot_value;
2521
+ invert.u_start = this->u_start;
2522
+ invert.u_last_p = this->u_last_p;
2523
+ invert.u_index = this->u_index;
2524
+ invert.u_value = this->u_value;
2525
+
2526
+ invert.ur_start = this->ur_start;
2527
+ invert.ur_lastp = this->ur_lastp;
2528
+ invert.ur_space = this->ur_space;
2529
+ invert.ur_index = this->ur_index;
2530
+ invert.ur_value = this->ur_value;
2531
+ invert.pf_start = this->pf_start;
2532
+ invert.pf_index = this->pf_index;
2533
+ invert.pf_value = this->pf_value;
2534
+ invert.pf_pivot_index = this->pf_pivot_index;
2535
+ invert.pf_pivot_value = this->pf_pivot_value;
2536
+ return invert;
2537
+ }
2538
+
2539
+ void HFactor::setInvert(const InvertibleRepresentation& invert) {
2540
+ this->l_pivot_index = invert.l_pivot_index;
2541
+ this->l_pivot_lookup = invert.l_pivot_lookup;
2542
+ this->l_start = invert.l_start;
2543
+ this->l_index = invert.l_index;
2544
+ this->l_value = invert.l_value;
2545
+ this->lr_start = invert.lr_start;
2546
+ this->lr_index = invert.lr_index;
2547
+ this->lr_value = invert.lr_value;
2548
+
2549
+ this->u_pivot_lookup = invert.u_pivot_lookup;
2550
+ this->u_pivot_index = invert.u_pivot_index;
2551
+ this->u_pivot_value = invert.u_pivot_value;
2552
+ this->u_start = invert.u_start;
2553
+ this->u_last_p = invert.u_last_p;
2554
+ this->u_index = invert.u_index;
2555
+ this->u_value = invert.u_value;
2556
+
2557
+ this->ur_start = invert.ur_start;
2558
+ this->ur_lastp = invert.ur_lastp;
2559
+ this->ur_space = invert.ur_space;
2560
+ this->ur_index = invert.ur_index;
2561
+ this->ur_value = invert.ur_value;
2562
+ this->pf_start = invert.pf_start;
2563
+ this->pf_index = invert.pf_index;
2564
+ this->pf_value = invert.pf_value;
2565
+ this->pf_pivot_index = invert.pf_pivot_index;
2566
+ this->pf_pivot_value = invert.pf_pivot_value;
2567
+ }
2568
+
2569
+ void InvertibleRepresentation::clear() {
2570
+ this->l_pivot_index.clear();
2571
+ this->l_pivot_lookup.clear();
2572
+ this->l_start.clear();
2573
+ this->l_index.clear();
2574
+ this->l_value.clear();
2575
+ this->lr_start.clear();
2576
+ this->lr_index.clear();
2577
+ this->lr_value.clear();
2578
+
2579
+ this->u_pivot_lookup.clear();
2580
+ this->u_pivot_index.clear();
2581
+ this->u_pivot_value.clear();
2582
+ this->u_start.clear();
2583
+ this->u_last_p.clear();
2584
+ this->u_index.clear();
2585
+ this->u_value.clear();
2586
+
2587
+ this->ur_start.clear();
2588
+ this->ur_lastp.clear();
2589
+ this->ur_space.clear();
2590
+ this->ur_index.clear();
2591
+ this->ur_value.clear();
2592
+ this->pf_start.clear();
2593
+ this->pf_index.clear();
2594
+ this->pf_value.clear();
2595
+ this->pf_pivot_index.clear();
2596
+ this->pf_pivot_value.clear();
2597
+ }