eqc-models 0.12.0__tar.gz → 0.14.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 (194) hide show
  1. eqc_models-0.14.0/.gitignore +6 -0
  2. {eqc_models-0.12.0/eqc_models.egg-info → eqc_models-0.14.0}/PKG-INFO +10 -9
  3. {eqc_models-0.12.0 → eqc_models-0.14.0}/docs/source/conf.py +0 -1
  4. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/base/base.py +11 -0
  5. eqc_models-0.14.0/eqc_models/base/binaries.py +33 -0
  6. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/base/constraints.py +39 -0
  7. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/base/polynomial.py +21 -2
  8. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/base/results.py +81 -1
  9. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/graph/__init__.py +2 -0
  10. eqc_models-0.14.0/eqc_models/graph/rcshortestpath.py +81 -0
  11. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/graph/shortestpath.py +52 -19
  12. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/ml/classifierbase.py +0 -5
  13. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/ml/classifierqboost.py +115 -72
  14. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/ml/clustering.py +29 -1
  15. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/ml/clusteringbase.py +29 -7
  16. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/ml/decomposition.py +50 -11
  17. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/ml/regressor.py +14 -0
  18. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/ml/regressorbase.py +24 -6
  19. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/ml/reservoir.py +17 -2
  20. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/solvers/__init__.py +9 -1
  21. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/solvers/eqcdirect.py +27 -6
  22. eqc_models-0.14.0/eqc_models/solvers/mip.py +115 -0
  23. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/solvers/qciclient.py +11 -22
  24. eqc_models-0.14.0/eqc_models/solvers/responselog.py +47 -0
  25. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/utilities/__init__.py +2 -1
  26. eqc_models-0.14.0/eqc_models/utilities/general.py +83 -0
  27. {eqc_models-0.12.0 → eqc_models-0.14.0/eqc_models.egg-info}/PKG-INFO +10 -9
  28. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models.egg-info/SOURCES.txt +10 -2
  29. eqc_models-0.14.0/eqc_models.egg-info/requires.txt +16 -0
  30. {eqc_models-0.12.0 → eqc_models-0.14.0}/pyproject.toml +13 -12
  31. eqc_models-0.14.0/scripts/binary_w_continuous_solver_example.py +46 -0
  32. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/clustering.py +9 -0
  33. eqc_models-0.14.0/scripts/convert_to_json_problem.py +19 -0
  34. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/graph_clustering.py +10 -1
  35. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/integer_job_example.py +1 -1
  36. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/lin_reg_dirac3.py +9 -0
  37. eqc_models-0.14.0/scripts/mip_example.py +47 -0
  38. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/pca_iris_dirac3.py +7 -0
  39. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/port_opt_dirac3.py +0 -1
  40. eqc_models-0.12.0/scripts/qboost_iris_dirac3_direct.py → eqc_models-0.14.0/scripts/qboost_iris_dirac3.py +8 -4
  41. eqc_models-0.14.0/scripts/qboost_iris_dirac3_weak_cls.py +138 -0
  42. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/qplib_benchmark_config.py +1 -1
  43. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/qsvm_dual_iris_dirac3.py +7 -0
  44. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/qsvm_iris_dirac3.py +7 -0
  45. eqc_models-0.14.0/scripts/test_shortestpath.py +65 -0
  46. {eqc_models-0.12.0 → eqc_models-0.14.0}/test/testpolynomialmodel.py +6 -4
  47. {eqc_models-0.12.0 → eqc_models-0.14.0}/test/testshortestpath.py +3 -3
  48. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/run_tests.py +69 -3
  49. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/c6h6_graph_clustering/c6h6_graph_clustering.py +6 -0
  50. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/clustering/clustering.py +6 -0
  51. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/cvqboost_iris/cvqboost_iris.py +7 -0
  52. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/karate_graph_clustering/karate_graph_clustering.py +7 -1
  53. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/pca_iris/pca_iris.py +6 -0
  54. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/protein_design_1MJC/protein_design_1MJC.py +11 -1
  55. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/protein_design_1NXB/protein_design_1NXB.py +11 -1
  56. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/protein_design_1POH/protein_design_1POH.py +11 -1
  57. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/qsvm_dual_iris/qsvm_dual_iris.py +6 -0
  58. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/qsvm_primal_iris/qsvm_primal_iris.py +6 -0
  59. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/synthetic_cls_100/synthetic_cls_100.py +11 -1
  60. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/synthetic_cls_300/synthetic_cls_300.py +11 -1
  61. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/synthetic_cls_500/synthetic_cls_500.py +11 -1
  62. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/synthetic_cls_700/synthetic_cls_700.py +11 -1
  63. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/synthetic_cls_900/synthetic_cls_900.py +11 -1
  64. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_suite_config.json +15 -0
  65. eqc_models-0.14.0/test_suite/test_utils.py +50 -0
  66. eqc_models-0.12.0/eqc_models/base/polyeval.c +0 -12140
  67. eqc_models-0.12.0/eqc_models.egg-info/requires.txt +0 -12
  68. eqc_models-0.12.0/scripts/qboost_iris_dirac3.py +0 -98
  69. eqc_models-0.12.0/scripts/test_shortestpath.py +0 -38
  70. eqc_models-0.12.0/test_suite/test_utils.py +0 -34
  71. {eqc_models-0.12.0 → eqc_models-0.14.0}/.gitlab-ci.yml +0 -0
  72. {eqc_models-0.12.0 → eqc_models-0.14.0}/LICENSE.txt +0 -0
  73. {eqc_models-0.12.0 → eqc_models-0.14.0}/MANIFEST.in +0 -0
  74. {eqc_models-0.12.0 → eqc_models-0.14.0}/README.md +0 -0
  75. {eqc_models-0.12.0 → eqc_models-0.14.0}/compile_extensions.py +0 -0
  76. {eqc_models-0.12.0 → eqc_models-0.14.0}/docs/Makefile +0 -0
  77. {eqc_models-0.12.0 → eqc_models-0.14.0}/docs/build/html/_static/basic.css +0 -0
  78. {eqc_models-0.12.0 → eqc_models-0.14.0}/docs/build/html/_static/css/badge_only.css +0 -0
  79. {eqc_models-0.12.0 → eqc_models-0.14.0}/docs/build/html/_static/css/theme.css +0 -0
  80. {eqc_models-0.12.0 → eqc_models-0.14.0}/docs/build/html/_static/custom.css +0 -0
  81. {eqc_models-0.12.0 → eqc_models-0.14.0}/docs/build/html/_static/file.png +0 -0
  82. {eqc_models-0.12.0 → eqc_models-0.14.0}/docs/build/html/_static/minus.png +0 -0
  83. {eqc_models-0.12.0 → eqc_models-0.14.0}/docs/build/html/_static/plus.png +0 -0
  84. {eqc_models-0.12.0 → eqc_models-0.14.0}/docs/build/html/_static/pygments.css +0 -0
  85. {eqc_models-0.12.0 → eqc_models-0.14.0}/docs/build/html/_static/white_logo.png +0 -0
  86. {eqc_models-0.12.0 → eqc_models-0.14.0}/docs/make.bat +0 -0
  87. {eqc_models-0.12.0 → eqc_models-0.14.0}/docs/source/_static/custom.css +0 -0
  88. {eqc_models-0.12.0 → eqc_models-0.14.0}/docs/source/_static/white_logo.png +0 -0
  89. {eqc_models-0.12.0 → eqc_models-0.14.0}/docs/source/dependencies.rst +0 -0
  90. {eqc_models-0.12.0 → eqc_models-0.14.0}/docs/source/eqc_models.rst +0 -0
  91. {eqc_models-0.12.0 → eqc_models-0.14.0}/docs/source/index.rst +0 -0
  92. {eqc_models-0.12.0 → eqc_models-0.14.0}/docs/source/modules.rst +0 -0
  93. {eqc_models-0.12.0 → eqc_models-0.14.0}/docs/source/usage.rst +0 -0
  94. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/__init__.py +0 -0
  95. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/algorithms/__init__.py +0 -0
  96. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/algorithms/base.py +0 -0
  97. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/algorithms/penaltymultiplier.py +0 -0
  98. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/allocation/__init__.py +0 -0
  99. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/allocation/allocation.py +0 -0
  100. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/allocation/portbase.py +0 -0
  101. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/allocation/portmomentum.py +0 -0
  102. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/assignment/__init__.py +0 -0
  103. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/assignment/qap.py +0 -0
  104. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/assignment/resource.py +0 -0
  105. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/assignment/setpartition.py +0 -0
  106. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/base/__init__.py +0 -0
  107. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/base/operators.py +0 -0
  108. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/base/polyeval.pyx +0 -0
  109. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/base/quadratic.py +0 -0
  110. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/combinatorics/__init__.py +0 -0
  111. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/combinatorics/setcover.py +0 -0
  112. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/combinatorics/setpartition.py +0 -0
  113. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/decoding.py +0 -0
  114. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/graph/base.py +0 -0
  115. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/graph/hypergraph.py +0 -0
  116. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/graph/maxcut.py +0 -0
  117. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/graph/maxkcut.py +0 -0
  118. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/graph/partition.py +0 -0
  119. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/ml/__init__.py +0 -0
  120. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/ml/classifierqsvm.py +0 -0
  121. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/ml/cvqboost_hamiltonian.pyx +0 -0
  122. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/ml/cvqboost_hamiltonian_c_func.c +0 -0
  123. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/ml/cvqboost_hamiltonian_c_func.h +0 -0
  124. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/ml/forecast.py +0 -0
  125. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/ml/forecastbase.py +0 -0
  126. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/process/base.py +0 -0
  127. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/process/mpc.py +0 -0
  128. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/sequence/__init__.py +0 -0
  129. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/sequence/tsp.py +0 -0
  130. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/utilities/fileio.py +0 -0
  131. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/utilities/polynomial.py +0 -0
  132. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models/utilities/qplib.py +0 -0
  133. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models.egg-info/dependency_links.txt +0 -0
  134. {eqc_models-0.12.0 → eqc_models-0.14.0}/eqc_models.egg-info/top_level.txt +0 -0
  135. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/binary_job_example.py +0 -0
  136. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/c6h6_graph_clustering.py +0 -0
  137. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/continuous_job_example.py +0 -0
  138. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/crew_assignment_example.py +0 -0
  139. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/graph_partitioning.py +0 -0
  140. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/hamiltonian_to_polynomial.py +0 -0
  141. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/hypergraph.py +0 -0
  142. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/karate_graph_clustering.py +0 -0
  143. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/mackey_glass_cell_production_series.csv +0 -0
  144. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/qplib_reader.py +0 -0
  145. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/qplib_runner.py +0 -0
  146. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/reservoir_forecast.py +0 -0
  147. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/results_example.py +0 -0
  148. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/rundoctests.py +0 -0
  149. {eqc_models-0.12.0 → eqc_models-0.14.0}/scripts/utils.py +0 -0
  150. {eqc_models-0.12.0 → eqc_models-0.14.0}/setup.cfg +0 -0
  151. {eqc_models-0.12.0 → eqc_models-0.14.0}/test/doctest_base.py +0 -0
  152. {eqc_models-0.12.0 → eqc_models-0.14.0}/test/testallocationmodel.py +0 -0
  153. {eqc_models-0.12.0 → eqc_models-0.14.0}/test/testconstraint.py +0 -0
  154. {eqc_models-0.12.0 → eqc_models-0.14.0}/test/testcvqboost.py +0 -0
  155. {eqc_models-0.12.0 → eqc_models-0.14.0}/test/testeqcdirectsolver.py +0 -0
  156. {eqc_models-0.12.0 → eqc_models-0.14.0}/test/testgraphpartitionmodel.py +0 -0
  157. {eqc_models-0.12.0 → eqc_models-0.14.0}/test/testhypergraphmodel.py +0 -0
  158. {eqc_models-0.12.0 → eqc_models-0.14.0}/test/testmaxcutmodel.py +0 -0
  159. {eqc_models-0.12.0 → eqc_models-0.14.0}/test/testqapmodel.py +0 -0
  160. {eqc_models-0.12.0 → eqc_models-0.14.0}/test/testqciclientsolver.py +0 -0
  161. {eqc_models-0.12.0 → eqc_models-0.14.0}/test/testquadraticmodel.py +0 -0
  162. {eqc_models-0.12.0 → eqc_models-0.14.0}/test/testsetcovermodel.py +0 -0
  163. {eqc_models-0.12.0 → eqc_models-0.14.0}/test/testsetpartitionmodel.py +0 -0
  164. {eqc_models-0.12.0 → eqc_models-0.14.0}/test/testtsp.py +0 -0
  165. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/README.txt +0 -0
  166. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/clustering/data/X.npy +0 -0
  167. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/cvqboost_iris/data/X_test.npy +0 -0
  168. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/cvqboost_iris/data/X_train.npy +0 -0
  169. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/cvqboost_iris/data/y_test.npy +0 -0
  170. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/cvqboost_iris/data/y_train.npy +0 -0
  171. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/protein_design_1MJC/data/C_1MJC.npy +0 -0
  172. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/protein_design_1MJC/data/J_1MJC.npy +0 -0
  173. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/protein_design_1NXB/data/C_1NXB.npy +0 -0
  174. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/protein_design_1NXB/data/J_1NXB.npy +0 -0
  175. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/protein_design_1POH/data/C_1POH.npy +0 -0
  176. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/protein_design_1POH/data/J_1POH.npy +0 -0
  177. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/qsvm_dual_iris/data/X_test.npy +0 -0
  178. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/qsvm_dual_iris/data/X_train.npy +0 -0
  179. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/qsvm_dual_iris/data/y_test.npy +0 -0
  180. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/qsvm_dual_iris/data/y_train.npy +0 -0
  181. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/qsvm_primal_iris/data/X_test.npy +0 -0
  182. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/qsvm_primal_iris/data/X_train.npy +0 -0
  183. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/qsvm_primal_iris/data/y_test.npy +0 -0
  184. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/qsvm_primal_iris/data/y_train.npy +0 -0
  185. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/synthetic_cls_100/data/C_8000000_100.npy +0 -0
  186. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/synthetic_cls_100/data/J_8000000_100.npy +0 -0
  187. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/synthetic_cls_300/data/C_8000000_300.npy +0 -0
  188. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/synthetic_cls_300/data/J_8000000_300.npy +0 -0
  189. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/synthetic_cls_500/data/C_8000000_500.npy +0 -0
  190. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/synthetic_cls_500/data/J_8000000_500.npy +0 -0
  191. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/synthetic_cls_700/data/C_8000000_700.npy +0 -0
  192. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/synthetic_cls_700/data/J_8000000_700.npy +0 -0
  193. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/synthetic_cls_900/data/C_8000000_900.npy +0 -0
  194. {eqc_models-0.12.0 → eqc_models-0.14.0}/test_suite/test_cases/synthetic_cls_900/data/J_8000000_900.npy +0 -0
@@ -0,0 +1,6 @@
1
+ __pycache__
2
+ build
3
+ eqc_models.egg-info
4
+
5
+ *.c
6
+ *.so
@@ -1,22 +1,23 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: eqc-models
3
- Version: 0.12.0
3
+ Version: 0.14.0
4
4
  Summary: Optimization and ML modeling package targeting EQC devices
5
- Author: Quantum Computing Inc.
6
- Author-email: support@quantumcomputinginc.com
5
+ Author-email: "Quantum Computing Inc." <support@quantumcomputinginc.com>
7
6
  Project-URL: Homepage, https://quantumcomputinginc.com
8
7
  Project-URL: Documentation, https://quantumcomputinginc.com/learn/support/software-packages/
9
8
  Project-URL: Issues, https://support.quantumcomputinginc.com/
10
- Requires-Python: <3.11,>=3.9
9
+ Requires-Python: <3.14,>=3.9
11
10
  Description-Content-Type: text/markdown
12
11
  License-File: LICENSE.txt
12
+ Requires-Dist: emucore-direct==1.0.7; python_version < "3.11"
13
+ Requires-Dist: eqc-direct==2.0.2; python_version < "3.11"
13
14
  Requires-Dist: numpy<2,>=1.22.1
14
15
  Requires-Dist: networkx<3,>=2.6.3
15
- Requires-Dist: pandas>=2.1.0
16
- Requires-Dist: scikit-learn>=1.2.1
17
- Requires-Dist: qci-client<5,>=4.3.0
18
- Requires-Dist: emucore-direct==1.0.6
19
- Requires-Dist: eqc-direct<3,>=2.0.1
16
+ Requires-Dist: pandas<3,>=2.1.0
17
+ Requires-Dist: scikit-learn<2,>=1.2.1
18
+ Requires-Dist: lightgbm<5,>=4.6.0
19
+ Requires-Dist: xgboost<2,>=1.7.4
20
+ Requires-Dist: qci-client<6,>=5
20
21
  Provides-Extra: dev
21
22
  Requires-Dist: pytest<8,>=7.1.0; extra == "dev"
22
23
  Requires-Dist: pytest-cov; extra == "dev"
@@ -26,7 +26,6 @@ version = f"{project} v{version}"
26
26
  import os
27
27
  import sys
28
28
  import tomli
29
- import eqc_direct
30
29
 
31
30
  sys.path.insert(0, os.path.abspath('../../eqc_models'))
32
31
 
@@ -41,6 +41,7 @@ class EqcModel:
41
41
  _upper_bound = None
42
42
  _H = None
43
43
  _machine_slacks = 0
44
+ _is_discrete = None
44
45
 
45
46
  def decode(self, solution : np.ndarray, from_encoding : str=None) -> np.ndarray:
46
47
  """
@@ -117,6 +118,16 @@ class EqcModel:
117
118
  warn("The domains property is deprecated in favor of naming it upper_bound", DeprecationWarning)
118
119
  self._upper_bound = value
119
120
 
121
+ @property
122
+ def is_discrete(self) -> List:
123
+ """ An array of boolean values indicating if variable should be restricted to a discrete domain """
124
+
125
+ return self._is_discrete
126
+
127
+ @is_discrete.setter
128
+ def is_discrete(self, value : List):
129
+ self._is_discrete = value
130
+
120
131
  @property
121
132
  def n(self) -> int:
122
133
  """ Return the number of variables """
@@ -0,0 +1,33 @@
1
+
2
+ def make_binary_penalty(var_idx, slack_idx, max_degree=2, penalty_multiplier=None):
3
+ """
4
+ Make a penalty expression enforcing binary values
5
+
6
+ The expression is formed from the conditions
7
+
8
+ $$
9
+ x + w = 1
10
+ $$
11
+
12
+ $$
13
+ xw = 0
14
+ $$
15
+
16
+ $$
17
+ w^2 + 2xw + x^2 - 2w - 2x + 1 + xw = 0
18
+ $$
19
+
20
+ $$
21
+ 3xw + w^2 + x^2 - 2w - 2x + 1 = 0
22
+ $$
23
+
24
+ """
25
+
26
+ indices = [(0, var_idx), (0, slack_idx), (var_idx, slack_idx), (var_idx, var_idx), (slack_idx, slack_idx)]
27
+ coefficients = [-2, -2, 3, 1, 1]
28
+ offset = 1
29
+ if penalty_multiplier is not None:
30
+ coefficients = [penalty_multiplier * c for c in coefficients]
31
+ offset *- penalty_multiplier
32
+ return coefficients, indices, offset
33
+
@@ -82,6 +82,45 @@ class ConstraintsMixIn:
82
82
  def constraints(self, value: Tuple[np.ndarray, np.ndarray]):
83
83
  self.lhs, self.rhs = value
84
84
 
85
+ @staticmethod
86
+ def _stackLHS(*args):
87
+ """
88
+
89
+ >>> m1 = np.array([1, 1, 1])
90
+ >>> m2 = np.array([[2.0, 2.0]])
91
+ >>> m3 = np.array([[0, 3, 3, 1], [1, 0, 1, 0]])
92
+ >>> ConstraintsMixIn._stackLHS(m1, m2, m3)
93
+ array([[1., 1., 1., 0.],
94
+ [2., 2., 0., 0.],
95
+ [0., 3., 3., 1.],
96
+ [1., 0., 1., 0.]])
97
+
98
+ """
99
+ n = 0
100
+ m = 0
101
+ dtype = np.int32
102
+ def update_dtype(matrix):
103
+ type_rank = ["int8", "int16", "int32", "int64", "float8", "float16", "float32", "float64"]
104
+ try:
105
+ idx = type_rank.index(str(matrix.dtype))
106
+ except ValueError:
107
+ raise TypeError(f"matrix type {matrix.dtype} not supported")
108
+ new_args = []
109
+ for mat in args:
110
+ if len(mat.shape) == 1:
111
+ mat = mat.reshape((1, mat.size))
112
+ if mat.shape[1] > n:
113
+ n = mat.shape[1]
114
+ m += mat.shape[0]
115
+ dtype = update_dtype(mat)
116
+ new_args.append(mat)
117
+ new_lhs = np.zeros((m, n), dtype=dtype)
118
+ idx = 0
119
+ for mat in new_args:
120
+ new_lhs[idx:idx+mat.shape[0],:mat.shape[1]] = mat
121
+ idx += mat.shape[0]
122
+ return new_lhs
123
+
85
124
  @property
86
125
  def offset(self) -> float:
87
126
  """ Calculate the offset due to the conversion of constraints to penalties """
@@ -1,10 +1,13 @@
1
1
  # (C) Quantum Computing Inc., 2024.
2
2
  from typing import Tuple, Union, List
3
+ import logging
3
4
  import numpy as np
4
5
  from eqc_models.base.base import EqcModel
5
6
  from eqc_models.base.operators import Polynomial, QUBO, OperatorNotAvailableError
6
7
  from eqc_models.base.constraints import ConstraintsMixIn
7
8
 
9
+ log = logging.getLogger(name=__name__)
10
+
8
11
  class PolynomialMixin:
9
12
  """This class provides an instance method and property that
10
13
  manage polynomial models.
@@ -46,7 +49,12 @@ class PolynomialMixin:
46
49
 
47
50
  """
48
51
 
49
- value = self.polynomial.evaluate(np.array(solution))
52
+ coefficients, indices = self.H
53
+ log.debug("Coefficients (%d): %s", len(coefficients), coefficients)
54
+ log.debug("Indices (%d): %s", len(indices), indices)
55
+ polynomial = self.polynomial
56
+ log.debug("Polynomial: %s", polynomial)
57
+ value = polynomial.evaluate(np.array(solution))
50
58
 
51
59
  return value
52
60
 
@@ -107,8 +115,19 @@ class PolynomialModel(PolynomialMixin, EqcModel):
107
115
  """
108
116
 
109
117
  def __init__(self, coefficients : Union[List, np.ndarray], indices : Union[List, np.ndarray]) -> None:
118
+ # ensure that the coefficients are ordered and not duplicated
119
+ new_coefficients = {}
120
+ for idx, v in zip(indices, coefficients):
121
+ idx = tuple(idx)
122
+ if idx in new_coefficients:
123
+ new_coefficients[idx] += v
124
+ else:
125
+ new_coefficients[idx] = v
126
+ new_indices = [idx for idx in new_coefficients]
127
+ new_indices.sort()
128
+ coefficients = [new_coefficients[idx] for idx in new_indices]
110
129
  self.coefficients = coefficients
111
- self.indices = indices
130
+ self.indices = new_indices
112
131
 
113
132
  @property
114
133
  def polynomial(self) -> Polynomial:
@@ -1,4 +1,5 @@
1
1
  import dataclasses
2
+ from typing import Dict
2
3
  import warnings
3
4
  import numpy as np
4
5
 
@@ -41,6 +42,14 @@ class SolutionResults:
41
42
  device : str
42
43
  String that represents the device used to solve the model.
43
44
 
45
+ raw_solutions : np.ndarray
46
+ Numpy array of the solutions as returned by the solver device.
47
+
48
+ calibration_time : float
49
+ Total time spend during job exectution where the device performed calibration.
50
+ The calibration is not directly affected by the job submission and the time
51
+ is not included in run_time.
52
+
44
53
  time_units : str
45
54
  String indicator of the unit of time reported in the metrics. Only
46
55
  ns is supported at this time.
@@ -56,6 +65,7 @@ class SolutionResults:
56
65
  postprocessing_time : np.ndarray
57
66
  penalties : np.ndarray = None
58
67
  device : str = None
68
+ raw_solutions : np.ndarray = None
59
69
  time_units : str = "ns"
60
70
 
61
71
  @property
@@ -95,7 +105,22 @@ class SolutionResults:
95
105
 
96
106
  @classmethod
97
107
  def from_cloud_response(cls, model, response, solver):
98
- """ Fill in the details from the cloud """
108
+ """
109
+ Fill in the details from the cloud
110
+
111
+ Parameters
112
+ ------------
113
+
114
+ model : eqc_models.base.EqcModel
115
+ EqcModel object describing the problem solved in response
116
+
117
+ response : Dict
118
+ Dictionary of the repsonse from the solver device.
119
+
120
+ solver : eqc_models.base.ModelSolver
121
+ ModelSolver object which is used to obtain job metrics.
122
+
123
+ """
99
124
 
100
125
  solutions = np.array(response["results"]["solutions"])
101
126
  if model.machine_slacks > 0:
@@ -164,3 +189,58 @@ class SolutionResults:
164
189
  device=device_type, time_units="ns")
165
190
 
166
191
  return results
192
+
193
+ @classmethod
194
+ def from_eqcdirect_response(cls, model, response, solver):
195
+ """
196
+ Fill in details from the response dictionary and possibly the solver device.
197
+
198
+ Parameters
199
+ ------------
200
+
201
+ model : eqc_models.base.EqcModel
202
+ EqcModel object describing the problem solved in response
203
+
204
+ response : Dict
205
+ Dictionary of the repsonse from the solver device.
206
+
207
+ solver : eqc_models.base.ModelSolver
208
+ ModelSolver object which is used to obtain device information.
209
+
210
+ """
211
+ solutions = np.array(response["solution"])
212
+ if model.machine_slacks > 0:
213
+ solutions = solutions[:,:-model.machine_slacks]
214
+ energies = np.array(response["energy"])
215
+ # interrogate to determine the device type
216
+ info_dict = solver.client.system_info()
217
+ device_type = info_dict["device_type"]
218
+ if hasattr(model, "evaluateObjective"):
219
+ objectives = np.zeros((solutions.shape[0],), dtype=np.float32)
220
+ for i in range(solutions.shape[0]):
221
+ try:
222
+ objective = model.evaluateObjective(solutions[i])
223
+ except NotImplementedError:
224
+ warnings.warn(f"Cannot set objective value in results for {model.__class__}")
225
+ objectives = None
226
+ break
227
+ objectives[i] = objective
228
+ else:
229
+ objectives = None
230
+ if hasattr(model, "evaluatePenalties"):
231
+ penalties = np.zeros((solutions.shape[0],), dtype=np.float32)
232
+ for i in range(solutions.shape[0]):
233
+ penalties[i] = model.evaluatePenalties(solutions[i]) + model.offset
234
+ else:
235
+ penalties = None
236
+ counts = np.ones(solutions.shape[0])
237
+ runtime = response["runtime"]
238
+ post = response["postprocessing_time"]
239
+ pre = response["preprocessing_time"]
240
+ results = SolutionResults(solutions, energies, counts, objectives,
241
+ runtime, pre, post, penalties=penalties,
242
+ device=device_type, time_units="s")
243
+
244
+ return results
245
+
246
+
@@ -3,6 +3,8 @@
3
3
  from .base import EdgeMixin, EdgeModel, GraphModel, NodeModel
4
4
  from .maxcut import MaxCutModel
5
5
  from .partition import GraphPartitionModel
6
+ from .shortestpath import ShortestPathModel
7
+ from .rcshortestpath import RCShortestPathModel
6
8
 
7
9
  __all__ = ["MaxCutModel", "GraphPartitionModel",
8
10
  "EdgeMixin", "EdgeModel", "GraphModel",
@@ -0,0 +1,81 @@
1
+ import logging
2
+ from typing import (Any, Dict, Tuple, List)
3
+ import networkx as nx
4
+ import numpy as np
5
+ from eqc_models.graph.shortestpath import ShortestPathModel
6
+
7
+ log = logging.getLogger(name=__name__)
8
+
9
+ class RCShortestPathModel(ShortestPathModel):
10
+ """
11
+ Model for resource constrained shortest path problems.
12
+ Use a shortest path base model to implement the routing
13
+ constraints and objective function. Add resource constraints.
14
+
15
+ """
16
+
17
+ def __init__(self, G : nx.DiGraph, s : Any, t : Any, T : int, resource_key : str="resource"):
18
+ if T <= 0:
19
+ raise ValueError("T must be positive")
20
+ elif round(T, 0) != T:
21
+ raise ValueError("T must be integer-valued")
22
+ self.T = T
23
+ self.resource_key = resource_key
24
+ # determine shortest path by weight
25
+ nx_path = nx.shortest_path(G, s, t)
26
+ path_length = len(nx_path)
27
+ self.resource_mult = resource_mult = 2 * path_length / self.T
28
+ super(RCShortestPathModel, self).__init__(G, s, t)
29
+ upper_bound = np.ones(len(self.variables))
30
+ upper_bound[-1] = np.ceil(resource_mult * T)
31
+ self.upper_bound = upper_bound
32
+ is_discrete = [True for i in range(upper_bound.shape[0])]
33
+ is_discrete[-1] = False
34
+ self.is_discrete = is_discrete
35
+
36
+ @property
37
+ def variables(self):
38
+ variables = super(RCShortestPathModel, self).variables
39
+ return variables + ["resource_slack"]
40
+
41
+ def buildConstraints(self) -> Tuple[np.ndarray,np.ndarray]:
42
+ lhs, rhs = super(RCShortestPathModel, self).buildConstraints()
43
+ # add a single constraint
44
+ G = self.G
45
+ n = len(self.variables)
46
+ resource_lhs = np.zeros((1, n), dtype=np.float32)
47
+ resource_mult = self.resource_mult
48
+ log.debug("Resource multiplier %f", resource_mult)
49
+ for i in range(len(G.edges)):
50
+ (u, v) = self.variables[i]
51
+ # find the time to traverse the arc
52
+ resource_cost = G.edges[(u, v)][self.resource_key]
53
+ resource_cost *= resource_mult
54
+ log.debug(f"Adding resource %s for edge %s", resource_cost, (u, v))
55
+ resource_lhs[0, i] = resource_cost
56
+ resource_lhs[0, -1] = 1
57
+ lhs = self._stackLHS(lhs, resource_lhs)
58
+ rhs = np.hstack([rhs, [self.T*resource_mult]])
59
+ log.debug("LHS shape %s RHS shape %s", lhs.shape, rhs.shape)
60
+ return lhs, rhs
61
+
62
+ def pathCost(self, path):
63
+ """ sum the cost of all legs in the path """
64
+ assert self.s in path
65
+ G = self.G
66
+ node = self.s
67
+ max_len = len(self.G.nodes) - 1
68
+ path_len = 0
69
+ path_cost = 0
70
+ path_resources = 0
71
+ while node != t:
72
+ edge = (node, path[node])
73
+ if edge not in G.edges:
74
+ raise ValueError(f"Edge {edge} not found")
75
+ path_len += 1
76
+ path_cost += G.edges[edge]["weight"]
77
+ path_resources += G.edges[edge][self.resource_key]
78
+ if path_len > max_len:
79
+ raise ValueError("Invalid path. Describes a cycle.")
80
+ return path_cost, path_resources
81
+
@@ -62,6 +62,9 @@ class ShortestPathModel(EdgeMixin, ConstrainedQuadraticModel):
62
62
  self.lhs, self.rhs = self.buildConstraints()
63
63
  C, J = self.buildObjective()
64
64
  super(ShortestPathModel, self).__init__(C, J, self.lhs, self.rhs)
65
+ self.upper_bound = np.ones(self.lhs.shape[1])
66
+ self.is_discrete = [True for i in range(self.lhs.shape[1])]
67
+ self.machine_slacks = 0
65
68
 
66
69
  def buildConstraints(self) -> Tuple[np.ndarray,np.ndarray]:
67
70
  """
@@ -72,7 +75,7 @@ class ShortestPathModel(EdgeMixin, ConstrainedQuadraticModel):
72
75
  $c$ is -1, 1 or 0 for $i=t$, $s$ or all others
73
76
 
74
77
  """
75
- log.info("Building constraints to find path from %s to %s", self.s, self.t)
78
+ log.debug("Building constraints to find path from %s to %s", self.s, self.t)
76
79
  variables = self.variables
77
80
  nodes = [n for n in self.G.nodes]
78
81
  m = len(nodes)
@@ -84,7 +87,8 @@ class ShortestPathModel(EdgeMixin, ConstrainedQuadraticModel):
84
87
  _rhs[node_index, 0] = 1
85
88
  elif k == self.t:
86
89
  _rhs[node_index, 0] = -1
87
- for l, (i, j) in enumerate(variables):
90
+ for l in range(len(self.G.edges)): # don't enumerate the edges because the order could change
91
+ (i, j) = self.variables[l]
88
92
  if i == j:
89
93
  # self loops are not allowed
90
94
  raise ValueError("Self loops are not allowed in ShortestPathModel")
@@ -97,8 +101,8 @@ class ShortestPathModel(EdgeMixin, ConstrainedQuadraticModel):
97
101
  j_index = nodes.index(j)
98
102
  _cons[i_index, l] = 1
99
103
  _cons[j_index, l] = -1
100
- log.info("LHS shape %s RHS shape %s", _cons.shape, _rhs.shape)
101
- log.info("checksum %f min %f", np.sum(_cons), np.min(_cons))
104
+ log.debug("LHS shape %s RHS shape %s", _cons.shape, _rhs.shape)
105
+ log.debug("checksum %f min %f", np.sum(_cons), np.min(_cons))
102
106
  assert np.sum(_rhs) == 0
103
107
  return _cons, np.squeeze(_rhs)
104
108
 
@@ -114,9 +118,10 @@ class ShortestPathModel(EdgeMixin, ConstrainedQuadraticModel):
114
118
  m, n = len(nodes), len(variables)
115
119
  _obj = [0 for i in range(n)]
116
120
  for index, name in enumerate(variables):
117
- i, j = name
118
- _obj[index] = v = G.get_edge_data(i, j)["weight"]
119
- assert not np.isnan(v), f"Got a NaN at {i, j}"
121
+ if type(name) == type((1,2)):
122
+ i, j = name
123
+ _obj[index] = v = G.get_edge_data(i, j)["weight"]
124
+ assert not np.isnan(v), f"Got a NaN at {i, j}"
120
125
  J = np.zeros((n, n))
121
126
  return np.array(_obj), J
122
127
 
@@ -126,32 +131,60 @@ class ShortestPathModel(EdgeMixin, ConstrainedQuadraticModel):
126
131
  a dictionary with each edge described by key, value pairs.
127
132
 
128
133
  """
129
- variables = self.variables
134
+ variables = self.variables[:len(self.G.edges)]
135
+ # log.debug("Using variables %s", variables)
130
136
 
131
137
  lhs, rhs = self.constraints
132
- upper_thresh = max(solution)
138
+ log.debug("LHS shape %s RHS shape %s", lhs.shape, rhs.shape)
139
+ upper_thresh = max(solution[:len(variables)])
133
140
  lower_thresh = 0
141
+ got_path = None
134
142
  while upper_thresh - lower_thresh > 1e-6:
135
- log.info("Lower Value: %f Upper Value %f", lower_thresh, upper_thresh)
143
+ log.debug("Lower Value: %f Upper Value %f", lower_thresh, upper_thresh)
136
144
  thresh = (lower_thresh + upper_thresh) / 2
137
145
  nx_path = None
138
146
  G = nx.DiGraph()
139
147
  for (i, j), value in zip(variables, solution):
140
148
  if value > thresh:
141
149
  G.add_edge(i, j)
150
+ edges = [e for e in G.edges]
151
+ log.debug("Resulting edge count %s", len(edges))
152
+ self.alt_g = G
142
153
  path = {}
143
154
  try:
144
155
  nx_path = nx.shortest_path(G, self.s, self.t)
145
- upper_thresh = thresh
146
156
  lower_thresh = thresh
157
+ got_path = nx_path
158
+ log.debug("Got path size %d", len(got_path))
147
159
  except (nx.exception.NodeNotFound, nx.NetworkXAlgorithmError) as err:
148
- lower_thresh = thresh
149
- if nx_path is None:
160
+ upper_thresh = thresh
161
+ if got_path is None:
150
162
  raise RuntimeError(f"Solution does not describe path from {self.s} to {self.t}")
151
- path = {}
152
- for i, v in enumerate(nx_path):
153
- path[nx_path[i-1]] = v
154
- if self.t in path:
155
- del path[self.t]
156
- return path
163
+ # path = {}
164
+ # log.debug("Translating path to dictionary")
165
+ # for i, v in enumerate(got_path):
166
+ # path[got_path[i-1]] = v
167
+ # log.debug("Updated path %s", path)
168
+ # if self.t in path:
169
+ # log.debug("Removing %s from path keys.", self.t)
170
+ # del path[self.t]
171
+ return got_path
172
+
173
+ def pathCost(self, path):
174
+ """ sum the cost of all legs in the path """
175
+ assert self.s in path
176
+ G = self.G
177
+ node = self.s
178
+ max_len = len(self.G.nodes) - 1
179
+ path_len = 0
180
+ path_cost = 0
181
+ while node != t:
182
+ edge = (node, path[node])
183
+ if edge not in G.edges:
184
+ raise ValueError(f"Edge {edge} not found")
185
+ path_len += 1
186
+ path_cost += G.edges[edge]["weight"]
187
+ if path_len > max_len:
188
+ raise ValueError("Invalid path. Describes a cycle.")
189
+ return path_cost
157
190
 
@@ -31,10 +31,6 @@ class ClassifierBase(QuadraticModel):
31
31
 
32
32
  assert solver_access in ["cloud", "direct"]
33
33
 
34
- if solver_access == "direct":
35
- assert ip_addr is not None, "ip_addr should be set when using direct solver!"
36
- assert port is not None,"port should be set when using direct solver!"
37
-
38
34
  self.solver_access = solver_access
39
35
  self.ip_addr = ip_addr
40
36
  self.port = port
@@ -78,7 +74,6 @@ class ClassifierBase(QuadraticModel):
78
74
  self,
79
75
  sum_constraint=self._sum_constraint,
80
76
  relaxation_schedule=self.relaxation_schedule,
81
- solution_precision=None,
82
77
  num_samples=self.num_samples,
83
78
  )
84
79