pyoframe 1.0.0a0__tar.gz → 1.1.0__tar.gz

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 (274) hide show
  1. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/.github/actions/setup_optimizers_linux/action.yml +29 -27
  2. pyoframe-1.1.0/.github/dependabot.yml +11 -0
  3. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/.github/workflows/ci.yml +10 -6
  4. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/.gitignore +1 -1
  5. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/.pre-commit-config.yaml +1 -1
  6. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/PKG-INFO +13 -14
  7. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/README.md +3 -3
  8. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/.nav.yml +1 -1
  9. pyoframe-1.1.0/docs/contribute/index.md +65 -0
  10. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/examples/diet.md +3 -3
  11. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/examples/facility_location.md +4 -4
  12. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/index.md +1 -1
  13. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/learn/advanced-concepts/internals.md +8 -3
  14. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/learn/advanced-concepts/performance.md +6 -6
  15. pyoframe-1.1.0/docs/learn/concepts/.nav.yml +4 -0
  16. pyoframe-1.1.0/docs/learn/concepts/addition.md +234 -0
  17. pyoframe-1.1.0/docs/learn/concepts/solver-access.md +108 -0
  18. pyoframe-1.1.0/docs/learn/concepts/special-functions.md +12 -0
  19. pyoframe-1.1.0/docs/learn/get-started/.nav.yml +5 -0
  20. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/learn/get-started/basic-example/example-with-dimensions.md +19 -22
  21. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/learn/get-started/basic-example/example.md +4 -4
  22. pyoframe-1.1.0/docs/learn/get-started/basics.md +347 -0
  23. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/learn/get-started/installation.md +21 -13
  24. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/learn/get-started/power_grid_example.ipynb +2 -4
  25. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/learn/migrate/v1.0.md +28 -9
  26. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/overrides/main.html +5 -4
  27. pyoframe-1.1.0/docs/reference/.nav.yml +5 -0
  28. pyoframe-1.1.0/docs/reference/bases/.nav.yml +3 -0
  29. pyoframe-1.1.0/docs/reference/bases/BaseBlock.md +3 -0
  30. pyoframe-1.1.0/docs/reference/bases/BaseOperableBlock.md +3 -0
  31. pyoframe-1.1.0/docs/reference/index.md +28 -0
  32. pyoframe-1.0.0a0/docs/reference/pyoframe.Config.md → pyoframe-1.1.0/docs/reference/public/Config.md +3 -3
  33. pyoframe-1.1.0/docs/reference/types/.nav.yml +2 -0
  34. pyoframe-1.1.0/docs/reference/types/Operable.md +3 -0
  35. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/why-pyoframe/index.md +1 -1
  36. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/why-pyoframe/pyoframe-performance.ipynb +5 -5
  37. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/mkdocs.yml +2 -2
  38. {pyoframe-1.0.0a0/src → pyoframe-1.1.0}/pyoframe.egg-info/PKG-INFO +13 -14
  39. {pyoframe-1.0.0a0/src → pyoframe-1.1.0}/pyoframe.egg-info/SOURCES.txt +50 -9
  40. {pyoframe-1.0.0a0/src → pyoframe-1.1.0}/pyoframe.egg-info/requires.txt +7 -8
  41. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/pyproject.toml +20 -15
  42. pyoframe-1.1.0/scripts/generate_api_reference.py +25 -0
  43. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/scripts/griffe_extensions.py +1 -1
  44. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/src/pyoframe/__init__.py +2 -0
  45. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/src/pyoframe/_arithmetic.py +179 -177
  46. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/src/pyoframe/_constants.py +103 -57
  47. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/src/pyoframe/_core.py +308 -204
  48. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/src/pyoframe/_model.py +49 -29
  49. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/src/pyoframe/_model_element.py +34 -18
  50. pyoframe-1.1.0/src/pyoframe/_monkey_patch.py +38 -0
  51. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/src/pyoframe/_objective.py +4 -6
  52. pyoframe-1.1.0/src/pyoframe/_param.py +99 -0
  53. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/src/pyoframe/_utils.py +10 -11
  54. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/src/pyoframe/_version.py +3 -3
  55. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/README.md +1 -1
  56. pyoframe-1.1.0/tests/examples/cutting_stock_problem/results/problem-copt-machine.lp +89 -0
  57. pyoframe-1.1.0/tests/examples/cutting_stock_problem/results/problem-copt-pretty.lp +190 -0
  58. pyoframe-1.1.0/tests/examples/cutting_stock_problem/results/problem-highs-machine.lp +183 -0
  59. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/diet_problem/model.py +5 -9
  60. pyoframe-1.1.0/tests/examples/diet_problem/results/problem-copt-machine.lp +29 -0
  61. pyoframe-1.1.0/tests/examples/diet_problem/results/problem-copt-pretty.lp +36 -0
  62. pyoframe-1.1.0/tests/examples/diet_problem/results/problem-highs-machine.lp +21 -0
  63. pyoframe-1.1.0/tests/examples/diet_problem/results/solution-copt-machine.sol +11 -0
  64. pyoframe-1.1.0/tests/examples/diet_problem/results/solution-copt-pretty.sol +11 -0
  65. pyoframe-1.1.0/tests/examples/diet_problem/results/solution-highs-machine.sol +69 -0
  66. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_location/model.py +8 -19
  67. pyoframe-1.1.0/tests/examples/facility_problem/results/problem-copt-machine.lp +29 -0
  68. pyoframe-1.1.0/tests/examples/facility_problem/results/problem-copt-pretty.lp +41 -0
  69. pyoframe-1.1.0/tests/examples/facility_problem/results/problem-highs-machine.lp +29 -0
  70. pyoframe-1.1.0/tests/examples/facility_problem/results/solution-copt-machine.sol +27 -0
  71. pyoframe-1.1.0/tests/examples/facility_problem/results/solution-copt-pretty.sol +27 -0
  72. pyoframe-1.1.0/tests/examples/facility_problem/results/solution-highs-machine.sol +50 -0
  73. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/portfolio_optim/model.py +32 -13
  74. pyoframe-1.1.0/tests/examples/portfolio_optim/results/problem-copt-machine.lp +20 -0
  75. pyoframe-1.1.0/tests/examples/portfolio_optim/results/problem-copt-pretty.lp +24 -0
  76. pyoframe-1.1.0/tests/examples/portfolio_optim/results/problem-highs-machine.lp +14 -0
  77. pyoframe-1.1.0/tests/examples/portfolio_optim/results/problem-highs-pretty.lp +14 -0
  78. pyoframe-1.1.0/tests/examples/portfolio_optim/results/solution-copt-machine.sol +7 -0
  79. pyoframe-1.1.0/tests/examples/portfolio_optim/results/solution-copt-pretty.sol +7 -0
  80. pyoframe-1.1.0/tests/examples/portfolio_optim/results/solution-highs-machine.sol +37 -0
  81. pyoframe-1.1.0/tests/examples/portfolio_optim/results/solution-highs-pretty.sol +37 -0
  82. pyoframe-1.1.0/tests/examples/production_planning/results/problem-copt-machine.lp +11 -0
  83. pyoframe-1.1.0/tests/examples/production_planning/results/problem-copt-pretty.lp +13 -0
  84. pyoframe-1.1.0/tests/examples/production_planning/results/problem-highs-machine.lp +9 -0
  85. pyoframe-1.1.0/tests/examples/production_planning/results/solution-copt-machine.sol +5 -0
  86. pyoframe-1.1.0/tests/examples/production_planning/results/solution-copt-pretty.sol +5 -0
  87. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/production_planning/results/solution-highs-machine.sol +10 -10
  88. pyoframe-1.1.0/tests/examples/pumped_storage/results/problem-copt-machine.lp +8146 -0
  89. pyoframe-1.1.0/tests/examples/pumped_storage/results/problem-copt-pretty.lp +20447 -0
  90. pyoframe-1.1.0/tests/examples/pumped_storage/results/problem-highs-machine.lp +8860 -0
  91. pyoframe-1.1.0/tests/examples/pumped_storage/results/solution-copt-machine.sol +4382 -0
  92. pyoframe-1.1.0/tests/examples/pumped_storage/results/solution-copt-pretty.sol +4382 -0
  93. pyoframe-1.1.0/tests/examples/pumped_storage/results/solution-highs-machine.sol +7317 -0
  94. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/sudoku/model.py +1 -1
  95. pyoframe-1.1.0/tests/examples/sudoku/results/problem-copt-machine.lp +1469 -0
  96. pyoframe-1.1.0/tests/examples/sudoku/results/problem-copt-pretty.lp +1513 -0
  97. pyoframe-1.1.0/tests/examples/sudoku/results/problem-highs-machine.lp +1813 -0
  98. pyoframe-1.1.0/tests/examples/sudoku/results/solution-copt-machine.sol +731 -0
  99. pyoframe-1.1.0/tests/examples/sudoku/results/solution-copt-pretty.sol +731 -0
  100. pyoframe-1.1.0/tests/examples/sudoku/results/solution-highs-machine.sol +1090 -0
  101. pyoframe-1.0.0a0/tests/test_arithmetic.py → pyoframe-1.1.0/tests/test_addition.py +132 -249
  102. pyoframe-1.1.0/tests/test_arithmetic.py +259 -0
  103. pyoframe-1.1.0/tests/test_constraint.py +38 -0
  104. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/test_examples.py +27 -9
  105. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/test_io.py +8 -5
  106. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/test_model.py +7 -9
  107. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/test_names.py +3 -3
  108. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/test_objective.py +0 -4
  109. pyoframe-1.1.0/tests/test_param.py +29 -0
  110. pyoframe-1.1.0/tests/test_variable.py +78 -0
  111. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/util.py +5 -2
  112. pyoframe-1.0.0a0/docs/contribute/index.md +0 -51
  113. pyoframe-1.0.0a0/docs/learn/concepts/.nav.yml +0 -4
  114. pyoframe-1.0.0a0/docs/learn/concepts/building-blocks.md +0 -17
  115. pyoframe-1.0.0a0/docs/learn/concepts/solver-access.md +0 -43
  116. pyoframe-1.0.0a0/docs/learn/concepts/special-functions.md +0 -227
  117. pyoframe-1.0.0a0/docs/learn/get-started/.nav.yml +0 -4
  118. pyoframe-1.0.0a0/docs/reference/index.md +0 -7
  119. pyoframe-1.0.0a0/docs/reference/pandas.DataFrame.to_expr.md +0 -3
  120. pyoframe-1.0.0a0/docs/reference/polars.DataFrame.to_expr.md +0 -3
  121. pyoframe-1.0.0a0/scripts/generate_api_reference.py +0 -34
  122. pyoframe-1.0.0a0/src/pyoframe/_monkey_patch.py +0 -80
  123. pyoframe-1.0.0a0/tests/examples/cutting_stock_problem/results/problem-highs-machine.lp +0 -183
  124. pyoframe-1.0.0a0/tests/examples/diet_problem/results/problem-highs-machine.lp +0 -21
  125. pyoframe-1.0.0a0/tests/examples/diet_problem/results/solution-highs-machine.sol +0 -69
  126. pyoframe-1.0.0a0/tests/examples/facility_problem/results/problem-highs-machine.lp +0 -29
  127. pyoframe-1.0.0a0/tests/examples/facility_problem/results/solution-highs-machine.sol +0 -50
  128. pyoframe-1.0.0a0/tests/examples/production_planning/results/problem-highs-machine.lp +0 -9
  129. pyoframe-1.0.0a0/tests/examples/pumped_storage/results/problem-highs-machine.lp +0 -8876
  130. pyoframe-1.0.0a0/tests/examples/pumped_storage/results/solution-highs-machine.sol +0 -7317
  131. pyoframe-1.0.0a0/tests/examples/sudoku/results/problem-highs-machine.lp +0 -1813
  132. pyoframe-1.0.0a0/tests/examples/sudoku/results/solution-highs-machine.sol +0 -1090
  133. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/.gitattributes +0 -0
  134. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/.github/CODEOWNERS +0 -0
  135. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/.github/actions/setup_optimizers_macos/action.yml +0 -0
  136. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/.github/actions/setup_optimizers_windows/action.yml +0 -0
  137. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/.github/workflows/format.yml +0 -0
  138. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/.github/workflows/lines_changed_counter.yml +0 -0
  139. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/.github/workflows/lint.yml +0 -0
  140. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/.github/workflows/publish_doc.yml +0 -0
  141. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/.github/workflows/publish_doc_dev.yml +0 -0
  142. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/.github/workflows/publish_to_pypi.yml +0 -0
  143. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/.github/workflows/test_doc.yml +0 -0
  144. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/.vscode/launch.json +0 -0
  145. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/.vscode/settings.json +0 -0
  146. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/CHANGELOG.md +0 -0
  147. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/LICENSE +0 -0
  148. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/conftest.py +0 -0
  149. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/examples/.nav.yml +0 -0
  150. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/examples/index.md +0 -0
  151. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/examples/portfolio_optimization.md +0 -0
  152. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/examples/production.md +0 -0
  153. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/javascripts/feedback.js +0 -0
  154. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/learn/advanced-concepts/.nav.yml +0 -0
  155. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/learn/advanced-concepts/datastructure.md +0 -0
  156. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/learn/advanced-concepts/quadratics.md +0 -0
  157. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/learn/advanced-concepts/troubleshooting.md +0 -0
  158. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/learn/get-started/basic-example/food_data.csv +0 -0
  159. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/learn/get-started/basic-example/foods.csv +0 -0
  160. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/learn/get-started/basic-example/foods_to_nutrients.csv +0 -0
  161. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/learn/get-started/basic-example/nutrients.csv +0 -0
  162. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/learn/get-started/basic-example/results.csv +0 -0
  163. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/learn/get-started/three-bus.png +0 -0
  164. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/overrides/partials/actions.html +0 -0
  165. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/overrides/partials/comments.html +0 -0
  166. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/overrides/partials/integrations/analytics/custom.html +0 -0
  167. {pyoframe-1.0.0a0/docs/reference → pyoframe-1.1.0/docs/reference/public}/.nav.yml +0 -0
  168. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/stylesheets/extra.css +0 -0
  169. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/why-pyoframe/data_py.parquet +0 -0
  170. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/why-pyoframe/gen_py.parquet +0 -0
  171. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/docs/why-pyoframe/three-bus-four-gen.png +0 -0
  172. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/giscus.json +0 -0
  173. {pyoframe-1.0.0a0/src → pyoframe-1.1.0}/pyoframe.egg-info/dependency_links.txt +0 -0
  174. {pyoframe-1.0.0a0/src → pyoframe-1.1.0}/pyoframe.egg-info/top_level.txt +0 -0
  175. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/scripts/archive/benchmark_assign_ids_constraints.py +0 -0
  176. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/scripts/archive/benchmark_assign_ids_constraints_2.py +0 -0
  177. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/scripts/archive/benchmark_assign_ids_variables.py +0 -0
  178. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/scripts/archive/benchmark_attr_performance.py +0 -0
  179. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/setup.cfg +0 -0
  180. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/__init__.py +0 -0
  181. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/conftest.py +0 -0
  182. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/__init__.py +0 -0
  183. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/cutting_stock_problem/__init__.py +0 -0
  184. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/cutting_stock_problem/input_data/orders.csv +0 -0
  185. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/cutting_stock_problem/input_data/parameters.csv +0 -0
  186. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/cutting_stock_problem/model.py +0 -0
  187. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/cutting_stock_problem/results/objective.csv +0 -0
  188. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/cutting_stock_problem/results/problem-gurobi-machine.lp +0 -0
  189. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/cutting_stock_problem/results/problem-gurobi-pretty.lp +0 -0
  190. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/cutting_stock_problem/results/problem-highs-pretty.lp +0 -0
  191. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/diet_problem/README.md +0 -0
  192. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/diet_problem/__init__.py +0 -0
  193. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/diet_problem/input_data/foods.csv +0 -0
  194. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/diet_problem/input_data/foods_to_nutrients.csv +0 -0
  195. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/diet_problem/input_data/nutrients.csv +0 -0
  196. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/diet_problem/model_gurobipy.py +0 -0
  197. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/diet_problem/results/Buy.csv +0 -0
  198. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/diet_problem/results/Buy_ub.csv +0 -0
  199. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/diet_problem/results/max_nutrients.csv +0 -0
  200. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/diet_problem/results/min_nutrients.csv +0 -0
  201. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/diet_problem/results/objective.csv +0 -0
  202. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/diet_problem/results/problem-gurobi-machine.lp +0 -0
  203. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/diet_problem/results/problem-gurobi-pretty.lp +0 -0
  204. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/diet_problem/results/problem-highs-pretty.lp +0 -0
  205. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/diet_problem/results/solution-gurobi-machine.sol +0 -0
  206. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/diet_problem/results/solution-gurobi-pretty.sol +0 -0
  207. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/diet_problem/results/solution-highs-pretty.sol +0 -0
  208. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_location/__init__.py +0 -0
  209. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_location/results/objective.csv +0 -0
  210. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_location/results/problem-gurobi-machine.lp +0 -0
  211. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_location/results/problem-gurobi-pretty.lp +0 -0
  212. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_problem/__init__.py +0 -0
  213. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_problem/input_data/plants.csv +0 -0
  214. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_problem/input_data/transport_costs.csv +0 -0
  215. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_problem/input_data/wharehouses.csv +0 -0
  216. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_problem/model.py +0 -0
  217. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_problem/model_gurobipy.py +0 -0
  218. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_problem/results/objective.csv +0 -0
  219. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_problem/results/open.csv +0 -0
  220. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_problem/results/problem-gurobi-machine.lp +0 -0
  221. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_problem/results/problem-gurobi-pretty.lp +0 -0
  222. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_problem/results/problem-highs-pretty.lp +0 -0
  223. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_problem/results/solution-gurobi-machine.sol +0 -0
  224. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_problem/results/solution-gurobi-pretty.sol +0 -0
  225. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_problem/results/solution-highs-pretty.sol +0 -0
  226. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/facility_problem/results/transport.csv +0 -0
  227. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/portfolio_optim/input_data/assets.csv +0 -0
  228. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/portfolio_optim/input_data/covariance.csv +0 -0
  229. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/portfolio_optim/input_data/portfolio_params.csv +0 -0
  230. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/portfolio_optim/results/con_min_return.csv +0 -0
  231. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/portfolio_optim/results/con_weights_sum.csv +0 -0
  232. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/portfolio_optim/results/objective.csv +0 -0
  233. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/portfolio_optim/results/problem-gurobi-machine.lp +0 -0
  234. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/portfolio_optim/results/problem-gurobi-pretty.lp +0 -0
  235. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/portfolio_optim/results/solution-gurobi-machine.sol +0 -0
  236. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/portfolio_optim/results/solution-gurobi-pretty.sol +0 -0
  237. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/portfolio_optim/results/weight.csv +0 -0
  238. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/production_planning/__init__.py +0 -0
  239. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/production_planning/input_data/machines_availability.csv +0 -0
  240. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/production_planning/input_data/processing_times.csv +0 -0
  241. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/production_planning/input_data/products_profit.csv +0 -0
  242. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/production_planning/model.py +0 -0
  243. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/production_planning/results/objective.csv +0 -0
  244. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/production_planning/results/problem-gurobi-machine.lp +0 -0
  245. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/production_planning/results/problem-gurobi-pretty.lp +0 -0
  246. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/production_planning/results/problem-highs-pretty.lp +0 -0
  247. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/production_planning/results/solution-gurobi-machine.sol +0 -0
  248. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/production_planning/results/solution-gurobi-pretty.sol +0 -0
  249. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/production_planning/results/solution-highs-pretty.sol +0 -0
  250. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/production_planning/results/solution.csv +0 -0
  251. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/pumped_storage/README.md +0 -0
  252. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/pumped_storage/__init__.py +0 -0
  253. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/pumped_storage/input_data/elspot-prices_2021_hourly_eur.csv +0 -0
  254. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/pumped_storage/model.py +0 -0
  255. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/pumped_storage/results/Pump.csv +0 -0
  256. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/pumped_storage/results/Storage_level.csv +0 -0
  257. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/pumped_storage/results/Turb.csv +0 -0
  258. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/pumped_storage/results/objective.csv +0 -0
  259. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/pumped_storage/results/problem-gurobi-machine.lp +0 -0
  260. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/pumped_storage/results/problem-gurobi-pretty.lp +0 -0
  261. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/pumped_storage/results/problem-highs-pretty.lp +0 -0
  262. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/pumped_storage/results/solution-gurobi-machine.sol +0 -0
  263. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/pumped_storage/results/solution-gurobi-pretty.sol +0 -0
  264. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/pumped_storage/results/solution-highs-pretty.sol +0 -0
  265. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/sudoku/__init__.py +0 -0
  266. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/sudoku/input_data/initial_numbers.csv +0 -0
  267. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/sudoku/results/problem-gurobi-machine.lp +0 -0
  268. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/sudoku/results/problem-gurobi-pretty.lp +0 -0
  269. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/sudoku/results/problem-highs-pretty.lp +0 -0
  270. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/sudoku/results/solution-gurobi-machine.sol +0 -0
  271. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/sudoku/results/solution-gurobi-pretty.sol +0 -0
  272. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/sudoku/results/solution-highs-pretty.sol +0 -0
  273. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/examples/sudoku/results/solution.csv +0 -0
  274. {pyoframe-1.0.0a0 → pyoframe-1.1.0}/tests/test_solver.py +0 -0
@@ -8,9 +8,12 @@ inputs:
8
8
  GUROBI_WLS:
9
9
  description: "..."
10
10
  required: true
11
- # COPT_CLIENT_INI:
12
- # description: "..."
13
- # required: true
11
+ COPT_LICENSE_KEY:
12
+ description: "..."
13
+ required: true
14
+ COPT_LICENSE_DAT:
15
+ description: "..."
16
+ required: true
14
17
  # MOSEK_LICENSE:
15
18
  # description: "..."
16
19
  # required: true
@@ -46,8 +49,7 @@ runs:
46
49
  run: |
47
50
  curl -L -o ~/installers/gurobi.tar.gz https://packages.gurobi.com/12.0/gurobi12.0.2_linux64.tar.gz
48
51
  curl -L -o ~/installers/idaes-solvers.tar.gz https://github.com/IDAES/idaes-ext/releases/download/3.4.2/idaes-solvers-ubuntu2204-x86_64.tar.gz
49
-
50
- # curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/7.2.8/linux64/CardinalOptimizer-7.2.8-lnx64.tar.gz
52
+ curl -L -o ~/installers/copt.tar.gz https://pub.shanshu.ai/download/copt/7.2.11/linux64/CardinalOptimizer-7.2.11-lnx64.tar.gz
51
53
  # curl -L -o ~/installers/mosek.tar.bz2 https://download.mosek.com/stable/10.2.0/mosektoolslinux64x86.tar.bz2
52
54
 
53
55
  - name: Setup Gurobi Installation
@@ -76,28 +78,28 @@ runs:
76
78
  timeout_minutes: 1
77
79
  command: gurobi_cl
78
80
 
79
- # - name: Setup COPT Installation
80
- # shell: bash
81
- # env:
82
- # COPT_CLIENT_INI: ${{ inputs.COPT_CLIENT_INI }}
83
- # run: |
84
- # tar xfz ~/installers/copt.tar.gz -C ~/
85
- # ls ~/copt72
86
- # # set environment variables
87
- # export COPT_HOME="${HOME}/copt72"
88
- # echo "COPT_HOME=${COPT_HOME}" >> $GITHUB_ENV
89
- # echo "PATH=${PATH}:${COPT_HOME}/bin" >> $GITHUB_ENV
90
- # echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${COPT_HOME}/lib" >> $GITHUB_ENV
91
- # echo $COPT_HOME
92
-
93
- # # Just use the size-limited license
94
- # # echo "$COPT_CLIENT_INI" > ~/client.ini
95
- # # echo "COPT_LICENSE_DIR=${HOME}" >> $GITHUB_ENV
96
- # - name: Test COPT
97
- # if: ${{ inputs.CHECK_LICENSE == 'true' }}
98
- # shell: bash
99
- # run: |
100
- # copt_cmd -c "quit"
81
+ - name: Setup COPT Installation
82
+ shell: bash
83
+ env:
84
+ COPT_LICENSE_KEY: ${{ inputs.COPT_LICENSE_KEY }}
85
+ COPT_LICENSE_DAT: ${{ inputs.COPT_LICENSE_DAT }}
86
+ run: |
87
+ tar xfz ~/installers/copt.tar.gz -C ~/
88
+ ls ~/copt72
89
+ # set environment variables
90
+ export COPT_HOME="${HOME}/copt72"
91
+ echo "COPT_HOME=${COPT_HOME}" >> $GITHUB_ENV
92
+ echo "PATH=${PATH}:${COPT_HOME}/bin" >> $GITHUB_ENV
93
+ echo "LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:${COPT_HOME}/lib" >> $GITHUB_ENV
94
+ echo $COPT_HOME
95
+ echo "$COPT_LICENSE_KEY" > ${COPT_HOME}/license.key
96
+ echo "$COPT_LICENSE_DAT" > ${COPT_HOME}/license.dat
97
+ echo "COPT_LICENSE_DIR=${COPT_HOME}" >> $GITHUB_ENV
98
+ - name: Test COPT
99
+ if: ${{ inputs.CHECK_LICENSE == 'true' }}
100
+ shell: bash
101
+ run: |
102
+ copt_cmd -c "quit"
101
103
 
102
104
  # - name: Setup MOSEK Installation
103
105
  # shell: bash
@@ -0,0 +1,11 @@
1
+ version: 2
2
+ updates:
3
+ - package-ecosystem: pip
4
+ directory: "/"
5
+ schedule:
6
+ interval: daily
7
+ time: "17:00"
8
+ allow:
9
+ - dependency-type: production
10
+ - dependency-name: highsbox
11
+ - dependency-name: llvmlite
@@ -45,9 +45,9 @@ jobs:
45
45
  username: ${{ github.triggering_actor }}
46
46
  env:
47
47
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
48
- # If neither has permissions and no 'safe to test' label throw error
48
+ # If neither has permissions and no 'safe to test' label and not dependabot throw error
49
49
  - name: Check User Permission
50
- if: steps.checkAccess.outputs.require-result == 'false' && steps.checkTriggeringAccess.outputs.require-result == 'false' && !contains(github.event.pull_request.labels.*.name, 'safe to test')
50
+ if: steps.checkAccess.outputs.require-result == 'false' && steps.checkTriggeringAccess.outputs.require-result == 'false' && !contains(github.event.pull_request.labels.*.name, 'safe to test') && (github.actor != 'dependabot[bot]')
51
51
  shell: bash
52
52
  run: |
53
53
  echo "${{ github.triggering_actor }} does not have permissions on this repo."
@@ -55,7 +55,8 @@ jobs:
55
55
  exit 1
56
56
  run:
57
57
  if: |
58
- (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository) ||
58
+ (github.event_name == 'pull_request_target' && github.actor == 'dependabot[bot]') ||
59
+ (github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name == github.repository && github.actor != 'dependabot[bot]') ||
59
60
  (github.event_name == 'pull_request_target' && github.event.pull_request.head.repo.full_name != github.repository) ||
60
61
  (github.event_name != 'pull_request_target' && github.event_name != 'pull_request')
61
62
  runs-on: ubuntu-latest
@@ -80,12 +81,15 @@ jobs:
80
81
  with:
81
82
  python-version: ${{ matrix.python-version }}
82
83
  cache: "pip"
83
- - name: Install dependencies
84
- run: pip install -e .[dev]
85
- - uses: ./.github/actions/setup_optimizers_linux
84
+ - name: Setup optimizers
85
+ uses: ./.github/actions/setup_optimizers_linux
86
86
  with:
87
87
  GUROBI_WLS: ${{ secrets.GUROBI_WLS }}
88
+ COPT_LICENSE_KEY: ${{ secrets.COPT_LICENSE_KEY }}
89
+ COPT_LICENSE_DAT: ${{ secrets.COPT_LICENSE_DAT }}
88
90
  CHECK_LICENSE: true
91
+ - name: Install dependencies
92
+ run: pip install -e .[dev]
89
93
  - name: Run tests and collect coverage
90
94
  run: pytest --cov
91
95
  - name: Upload coverage to Codecov
@@ -13,4 +13,4 @@ site
13
13
  .idea
14
14
  src/pyoframe/_version.py
15
15
  htmlcov/
16
- .snakemake
16
+ .snakemake/
@@ -12,4 +12,4 @@ repos:
12
12
  rev: v2025.4.8
13
13
  hooks:
14
14
  - id: doccmd
15
- args: ["--language", "python", "--no-pad-file", "--command", "ruff format", "docs/"]
15
+ args: ["--language", "python", "--no-pad-file", "--no-use-pty", "--command", "ruff format", "docs/"]
@@ -1,11 +1,11 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pyoframe
3
- Version: 1.0.0a0
3
+ Version: 1.1.0
4
4
  Summary: Blazing fast linear program interface
5
5
  Author-email: Bravos Power <dev@bravospower.com>
6
6
  License-Expression: MIT
7
- Project-URL: Homepage, https://bravos-power.github.io/pyoframe/
8
- Project-URL: documentation, https://bravos-power.github.io/pyoframe/
7
+ Project-URL: Homepage, https://bravos-power.github.io/pyoframe/latest
8
+ Project-URL: documentation, https://bravos-power.github.io/pyoframe/latest
9
9
  Project-URL: repository, https://github.com/Bravos-Power/pyoframe/
10
10
  Project-URL: Issues, https://github.com/Bravos-Power/pyoframe/issues
11
11
  Classifier: Programming Language :: Python :: 3
@@ -16,28 +16,27 @@ Requires-Python: >=3.9
16
16
  Description-Content-Type: text/markdown
17
17
  License-File: LICENSE
18
18
  Requires-Dist: polars~=1.0
19
- Requires-Dist: numpy
20
19
  Requires-Dist: pyarrow
21
- Requires-Dist: pandas
22
- Requires-Dist: pyoptinterface<1,>=0.4.1
20
+ Requires-Dist: pandas<3
21
+ Requires-Dist: pyoptinterface==0.5.1
23
22
  Provides-Extra: highs
24
- Requires-Dist: highsbox; extra == "highs"
23
+ Requires-Dist: highsbox<=1.12.0; extra == "highs"
25
24
  Provides-Extra: ipopt
26
25
  Requires-Dist: pyoptinterface[nlp]; extra == "ipopt"
27
- Requires-Dist: llvmlite<=0.44.0; extra == "ipopt"
26
+ Requires-Dist: llvmlite<=0.46.0; extra == "ipopt"
28
27
  Provides-Extra: dev
29
28
  Requires-Dist: ruff==0.12.11; extra == "dev"
30
29
  Requires-Dist: polars>=1.32.3; extra == "dev"
31
30
  Requires-Dist: pytest==8.4.1; extra == "dev"
32
31
  Requires-Dist: pytest-cov==6.2.1; extra == "dev"
33
- Requires-Dist: sybil[pytest]==9.2.0; extra == "dev"
32
+ Requires-Dist: sybil[pytest]==9.3.0; extra == "dev"
34
33
  Requires-Dist: pre-commit==4.3.0; extra == "dev"
35
34
  Requires-Dist: gurobipy==12.0.3; extra == "dev"
36
35
  Requires-Dist: coverage==7.10.6; extra == "dev"
37
36
  Requires-Dist: ipykernel==6.30.1; extra == "dev"
38
- Requires-Dist: highsbox; extra == "dev"
37
+ Requires-Dist: highsbox<=1.12.0; extra == "dev"
39
38
  Requires-Dist: pyoptinterface[nlp]; extra == "dev"
40
- Requires-Dist: llvmlite<=0.44.0; extra == "dev"
39
+ Requires-Dist: numpy; extra == "dev"
41
40
  Provides-Extra: docs
42
41
  Requires-Dist: mkdocs-material~=9.6.18; extra == "docs"
43
42
  Requires-Dist: mkdocstrings[python]~=0.30.0; extra == "docs"
@@ -57,7 +56,7 @@ Dynamic: license-file
57
56
 
58
57
  [![codecov](https://codecov.io/gh/Bravos-Power/pyoframe/graph/badge.svg?token=8258XESRYQ)](https://codecov.io/gh/Bravos-Power/pyoframe)
59
58
  [![Build](https://github.com/Bravos-Power/pyoframe/actions/workflows/ci.yml/badge.svg)](https://github.com/Bravos-Power/pyoframe/actions/workflows/ci.yml)
60
- [![Docs](https://github.com/Bravos-Power/pyoframe/actions/workflows/publish_doc.yml/badge.svg)](https://Bravos-Power.github.io/pyoframe/reference/)
59
+ [![Docs](https://github.com/Bravos-Power/pyoframe/actions/workflows/publish_doc.yml/badge.svg)](https://Bravos-Power.github.io/pyoframe/latest/reference/)
61
60
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
62
61
  [![Issues Needing Triage](https://img.shields.io/github/issues-search/Bravos-Power/pyoframe?query=no%3Alabel%20is%3Aopen&label=Needs%20Triage)](https://github.com/Bravos-Power/pyoframe/issues?q=is%3Aopen+is%3Aissue+no%3Alabel)
63
62
  [![Open Bugs](https://img.shields.io/github/issues-search/Bravos-Power/pyoframe?query=label%3Abug%20is%3Aopen&label=Open%20Bugs)](https://github.com/Bravos-Power/pyoframe/issues?q=is%3Aopen+is%3Aissue+label%3Abug)
@@ -65,9 +64,9 @@ Dynamic: license-file
65
64
 
66
65
  A library to rapidly and memory-efficiently formulate large and sparse optimization models using Pandas or Polars DataFrames.
67
66
 
68
- ## **[Documentation](https://bravos-power.github.io/pyoframe/)**
67
+ ## **[Documentation](https://bravos-power.github.io/pyoframe/latest/)**
69
68
 
70
- [Read the documentation](https://bravos-power.github.io/pyoframe/) to get started or to learn how to [contribute](https://bravos-power.github.io/pyoframe/contribute/index.md).
69
+ [Read the documentation](https://bravos-power.github.io/pyoframe/latest/) to get started or to learn how to [contribute](https://bravos-power.github.io/pyoframe/latest/contribute/index.md).
71
70
 
72
71
 
73
72
  ## Acknowledgments
@@ -2,7 +2,7 @@
2
2
 
3
3
  [![codecov](https://codecov.io/gh/Bravos-Power/pyoframe/graph/badge.svg?token=8258XESRYQ)](https://codecov.io/gh/Bravos-Power/pyoframe)
4
4
  [![Build](https://github.com/Bravos-Power/pyoframe/actions/workflows/ci.yml/badge.svg)](https://github.com/Bravos-Power/pyoframe/actions/workflows/ci.yml)
5
- [![Docs](https://github.com/Bravos-Power/pyoframe/actions/workflows/publish_doc.yml/badge.svg)](https://Bravos-Power.github.io/pyoframe/reference/)
5
+ [![Docs](https://github.com/Bravos-Power/pyoframe/actions/workflows/publish_doc.yml/badge.svg)](https://Bravos-Power.github.io/pyoframe/latest/reference/)
6
6
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
7
7
  [![Issues Needing Triage](https://img.shields.io/github/issues-search/Bravos-Power/pyoframe?query=no%3Alabel%20is%3Aopen&label=Needs%20Triage)](https://github.com/Bravos-Power/pyoframe/issues?q=is%3Aopen+is%3Aissue+no%3Alabel)
8
8
  [![Open Bugs](https://img.shields.io/github/issues-search/Bravos-Power/pyoframe?query=label%3Abug%20is%3Aopen&label=Open%20Bugs)](https://github.com/Bravos-Power/pyoframe/issues?q=is%3Aopen+is%3Aissue+label%3Abug)
@@ -10,9 +10,9 @@
10
10
 
11
11
  A library to rapidly and memory-efficiently formulate large and sparse optimization models using Pandas or Polars DataFrames.
12
12
 
13
- ## **[Documentation](https://bravos-power.github.io/pyoframe/)**
13
+ ## **[Documentation](https://bravos-power.github.io/pyoframe/latest/)**
14
14
 
15
- [Read the documentation](https://bravos-power.github.io/pyoframe/) to get started or to learn how to [contribute](https://bravos-power.github.io/pyoframe/contribute/index.md).
15
+ [Read the documentation](https://bravos-power.github.io/pyoframe/latest/) to get started or to learn how to [contribute](https://bravos-power.github.io/pyoframe/latest/contribute/index.md).
16
16
 
17
17
 
18
18
  ## Acknowledgments
@@ -8,6 +8,6 @@ nav:
8
8
  - learn/advanced-concepts
9
9
  - learn/migrate
10
10
  - examples
11
- - reference
11
+ - Reference API: reference
12
12
  - why-pyoframe/index.md
13
13
  - contribute
@@ -0,0 +1,65 @@
1
+ ---
2
+ hide:
3
+ - navigation
4
+ ---
5
+ # Contribute
6
+
7
+ Contributions are more than welcome! Submit a pull request, or [open an issue](https://github.com/Bravos-Power/pyoframe/issues/new) and I (Martin) will gladly answer your questions on how to contribute.
8
+
9
+ ## Setup a development environment
10
+
11
+ 1. Clone this repository.
12
+ ```console
13
+ git clone https://github.com/Bravos-Power/pyoframe
14
+ ```
15
+
16
+ 2. Install the dependencies.
17
+ ```console
18
+ pip install --editable .[dev,docs]
19
+ ```
20
+
21
+ 3. Install the pre-commit hooks.
22
+ ```console
23
+ pre-commit install
24
+ ```
25
+
26
+ ## Running the test suite
27
+
28
+ Run `pytest` to execute the test suite. (If you'd like to view coverage information add the flag `--cov` and then run `coverage html`.)
29
+
30
+ The only errors you should see when running the test suite are those related to a solver not being installed.
31
+
32
+ Pyoframe has several types of tests.
33
+
34
+ 1. Your typical unit tests under the `tests/` folder.
35
+
36
+ 2. Integration tests in `tests/test_examples.py`. These tests will run all the models in `tests/examples` and make sure that your changes haven't altered the model results (stored under `tests/examples/<model>/results`). In the rare cases where you _want_ the model results to change (e.g. if you've changed the model), you can regenerate the results using `python -m tests.test_examples`.
37
+
38
+ 3. Doctests in the docstrings of the source code (`src/`).
39
+
40
+ 4. Documentation tests (in `docs/`). All Python code blocks in the documentation are run to ensure the documentation doesn't become outdated. This is done using Sybil. Refer to the [Sybil documentation](https://sybil.readthedocs.io/en/latest/markdown.html#code-blocks) to learn how to create setup code or skip code blocks you don't wish to test.
41
+
42
+ !!! warning "Non-breaking spaces"
43
+ Be aware that Pyoframe uses non-breaking spaces to improve the formatting of expressions. If your Sybil tests are unexpectedly failing, make sure that the expected output contains all the needed non-breaking spaces.
44
+
45
+ ## Writing documentation
46
+
47
+ You can preview the documentation website by running `mkdocs serve` and navigating to [`http://127.0.0.1:8000/pyoframe/`](http://127.0.0.1:8000/pyoframe/).
48
+
49
+ We use [Material Docs](https://squidfunk.github.io/mkdocs-material/) for documentation with several plugins to enable features like automatically compiling the docstrings into the reference API. Please follow the [Google docstring style](https://sphinxcontrib-napoleon.readthedocs.io/en/latest/example_google.html) and the [Google style guide](https://developers.google.com/style). We use Mike to allow readers to view the documentation for previous releases (preview available via `mike serve`).
50
+
51
+ ## Linting and formatting
52
+
53
+ We use Ruff for linting and formatting. The pre-commit hooks will run `ruff format` on commit. You should also make sure `ruff check` returns no errors before submitting a PR. To format code blocks in the documentation run: `doccmd --language=python --no-pad-file --command="ruff format" docs/`.
54
+
55
+ ## Additional tips
56
+
57
+ I recommend skimming or reading the [Internal Details](../learn/advanced-concepts/internals.md) page for some background on how Pyoframe works.
58
+
59
+ For core developers:
60
+
61
+ - If you use `.unique`, `.join`, `.sort`, or `.group_by` on a Polars dataframe, make sure to set the `maintain_order` parameter appropriately (typically, `maintain_order=Config.maintain_order`).
62
+
63
+ For repository maintainers:
64
+
65
+ - Our CI pipeline on Github Actions requires a Gurobi and COPT license to run. If the Gurobi license expires, generate a new one and copy the contents of the `guorbi.lic` file into the `GUROBI_WLS` Github secret (Settings -> Secrets and variables -> actions). Similarly, if the COPT license expires, request a new academic license (or email COPT sales for a free one) and copy the contents of both license files to the matching Github secrets.
@@ -28,9 +28,9 @@ m.Buy = pf.Variable(food["food"], lb=0, ub=food[["food", "stock"]])
28
28
 
29
29
  nutrient_intake = (m.Buy * food_nutrients).sum_by("category")
30
30
  m.min_nutrients = (
31
- nutrients[["category", "min"]] <= nutrient_intake.drop_unmatched() # (1)!
31
+ nutrients[["category", "min"]] <= nutrient_intake.drop_extras() # (1)!
32
32
  )
33
- m.max_nutrients = nutrient_intake.drop_unmatched() <= nutrients[["category", "max"]]
33
+ m.max_nutrients = nutrient_intake.drop_extras() <= nutrients[["category", "max"]]
34
34
 
35
35
  total_cost = (m.Buy * food[["food", "cost"]]).sum()
36
36
  m.minimize = total_cost
@@ -39,7 +39,7 @@ m.minimize = total_cost
39
39
  m.optimize()
40
40
  ```
41
41
 
42
- 1. `.drop_unmatched()` ensures that if `min_nutrient` is `null` for certain foods, no constraint will be created for those foods. [Learn more](../learn/concepts/special-functions.md#drop_unmatched-and-keep_unmatched)
42
+ 1. `.drop_extras()` ensures that if `min_nutrient` is `null` for certain foods, no constraint will be created for those foods. [Learn more](../learn/concepts/addition.md)
43
43
 
44
44
  So the solution is...
45
45
 
@@ -26,12 +26,12 @@ model.customers = model.x_axis * model.y_axis # (1)!
26
26
 
27
27
 
28
28
  model.facility_position = pf.Variable(model.facilities, model.axis, lb=0, ub=1)
29
- model.customer_position_x = pd.DataFrame(
29
+ model.customer_position_x = pf.Param(
30
30
  {"x": range(G), "x_pos": [step / (G - 1) for step in range(G)]}
31
- ).to_expr()
32
- model.customer_position_y = pd.DataFrame(
31
+ )
32
+ model.customer_position_y = pf.Param(
33
33
  {"y": range(G), "y_pos": [step / (G - 1) for step in range(G)]}
34
- ).to_expr()
34
+ )
35
35
 
36
36
  model.max_distance = pf.Variable(lb=0)
37
37
 
@@ -12,7 +12,7 @@ hide:
12
12
  - Seamlessly integrates with pandas thanks to its dataframe-centric design.
13
13
  - Extremely **fast and memory efficient** (even for sparse problems) thanks to Polars, Rust, and Pyoptinterface.
14
14
  - Clear Pythonic syntax for writing mathematical models.
15
- - Supports Gurobi, HiGHS, and Ipopt solvers.
15
+ - Supports Gurobi, HiGHS, Ipopt and COPT solvers.
16
16
  - Continuously used in high-stakes production environments.
17
17
  - 100% open-source (MIT License).
18
18
 
@@ -1,7 +1,6 @@
1
1
  # Internal details
2
2
 
3
- Pyoframe's inner workings involve a few tricks that you should be aware of
4
- if you wish to modify Pyoframe's internal code.
3
+ Pyoframe's inner workings involve a few tricks that you should be aware of if you wish to contribute to Pyoframe's code base.
5
4
 
6
5
  ## The zero variable
7
6
 
@@ -16,4 +15,10 @@ constant terms and also simplifies the [handling of quadratics](#quadratics).
16
15
 
17
16
  Internally, [Expression][pyoframe.Expression] is used to represent both linear and quadratic mathematical expressions. When a quadratic expression is formed, column `__quadratic_variable_id` is added to [Expression.data][pyoframe.Expression.data]. If an expression's quadratic terms happen to cancel out (e.g. `(ab + c) - ab`), this column is automatically removed.
18
17
 
19
- Column `__quadratic_variable_id` records the ID of the _second_ variable in a quadratic term (the `b` in `3ab`). For linear terms, which have no second variable, this column contains the [Zero Variable](#the-zero-variable). Quadratic terms are always stored such that the first term's variable ID (in column `__variable_id`) is greater or equal to the second term's variable id (in column `__quadratic_variable_id`). For example, `var_7 * var_8` would be rearranged and stored as `var_8 * var_7`. This helps simplify expressions and provides a useful guarantee: If the variable in the first column (`__variable_id`) is the Zero Variable (`var_0`) we know the variable in the second column must also be the Zero Variable and, thus, the term must be a constant.
18
+ Column `__quadratic_variable_id` records the ID of the _second_ variable in a quadratic term (the `b` in `3ab`). For linear terms, which have no second variable, this column contains the [Zero Variable](#the-zero-variable).
19
+
20
+ Quadratic terms are always stored such that the first term's variable ID (in column `__variable_id`) is greater or equal to the second term's variable id (in column `__quadratic_variable_id`). For example, `var_7 * var_8` would be rearranged and stored as `var_8 * var_7`. This helps simplify expressions and provides a useful guarantee: If the variable in the first column (`__variable_id`) is the Zero Variable (`var_0`) we know the variable in the second column must also be the Zero Variable and, thus, the term must be a constant.
21
+
22
+ ## Division
23
+
24
+ Divisions are rearranged into multiplications when possible. Specifically, `a / b` is computed as `a * (1 / b)` (see `BaseOperableBlock.__truediv__`) except for the special case where `a` is a `float` or `int`. In that case, a Polars operation is used to compute the division (see `Expression.__rtruediv__`).
@@ -6,9 +6,9 @@ Pyoframe is already one of the fastest and most memory-efficient libraries for f
6
6
 
7
7
  [Polars](https://pola.rs/) is much faster than Pandas. Moreover, if you use Pandas, there will be a (very small) overhead because Pyoframe converts all DataFrames to Polars prior to computations.
8
8
 
9
- ## Use integer indices
9
+ ## Use integer labels
10
10
 
11
- Pyoframe will work with all types of indices, however integer indices are faster and more memory efficient than alternatives (e.g. string indices).
11
+ Pyoframe works with any label data type (e.g. string labels, date labels, etc.), but integer labels are fastest and most memory efficient.
12
12
 
13
13
  ## Disable `maintain_order`
14
14
 
@@ -18,14 +18,14 @@ By default, Pyoframe ensures that the order of variables, constraints, and mathe
18
18
  pf.Config.maintain_order = False
19
19
  ```
20
20
 
21
- ## Disable unmatched checks
21
+ ## Disable checks for extra values
22
22
 
23
- Disabling unmatched checks means that, instead of raising [unmatched term exceptions](../concepts/special-functions.md#drop_unmatched-and-keep_unmatched), pyoframe will process sums with unmatched terms as if [`keep_unmatched`][pyoframe.Expression.keep_unmatched] had been applied. While this may improve performance, it will silence potentially important errors meant to help you build your model. If you'd like to disable unmatched checks, we recommend you do so only after thoroughly testing your model and ensuring that all potential unmatched term exceptions have been handled.
23
+ Disabling checks for extra values means that, instead of raising [extra value exceptions](../concepts/addition.md), pyoframe will process sums with extra values as if [`keep_extras`][pyoframe.Expression.keep_extras] had been applied. While this may improve performance, it will silence potentially important errors meant to help you build your model. If you'd like to disable checks for extra values, we recommend you do so only after thoroughly testing your model and ensuring that all potential extra value exceptions have been handled.
24
24
 
25
- The following code disables unmatched checks:
25
+ The following code disables checks for extra values:
26
26
 
27
27
  ```python
28
- pf.Config.disable_unmatched_checks = True
28
+ pf.Config.disable_extras_checks = True
29
29
  ```
30
30
 
31
31
  <!-- TODO REVISIT
@@ -0,0 +1,4 @@
1
+ nav:
2
+ - addition.md
3
+ - special-functions.md
4
+ - solver-access.md