qilisdk 0.1.8__cp312-cp312-macosx_11_0_arm64.whl

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 (634) hide show
  1. include/eigen3/Eigen/Cholesky +45 -0
  2. include/eigen3/Eigen/CholmodSupport +48 -0
  3. include/eigen3/Eigen/Core +384 -0
  4. include/eigen3/Eigen/Dense +7 -0
  5. include/eigen3/Eigen/Eigen +2 -0
  6. include/eigen3/Eigen/Eigenvalues +60 -0
  7. include/eigen3/Eigen/Geometry +59 -0
  8. include/eigen3/Eigen/Householder +29 -0
  9. include/eigen3/Eigen/IterativeLinearSolvers +48 -0
  10. include/eigen3/Eigen/Jacobi +32 -0
  11. include/eigen3/Eigen/KLUSupport +41 -0
  12. include/eigen3/Eigen/LU +47 -0
  13. include/eigen3/Eigen/MetisSupport +35 -0
  14. include/eigen3/Eigen/OrderingMethods +70 -0
  15. include/eigen3/Eigen/PaStiXSupport +49 -0
  16. include/eigen3/Eigen/PardisoSupport +35 -0
  17. include/eigen3/Eigen/QR +50 -0
  18. include/eigen3/Eigen/QtAlignedMalloc +39 -0
  19. include/eigen3/Eigen/SPQRSupport +34 -0
  20. include/eigen3/Eigen/SVD +50 -0
  21. include/eigen3/Eigen/Sparse +34 -0
  22. include/eigen3/Eigen/SparseCholesky +37 -0
  23. include/eigen3/Eigen/SparseCore +69 -0
  24. include/eigen3/Eigen/SparseLU +50 -0
  25. include/eigen3/Eigen/SparseQR +36 -0
  26. include/eigen3/Eigen/StdDeque +27 -0
  27. include/eigen3/Eigen/StdList +26 -0
  28. include/eigen3/Eigen/StdVector +27 -0
  29. include/eigen3/Eigen/SuperLUSupport +64 -0
  30. include/eigen3/Eigen/UmfPackSupport +40 -0
  31. include/eigen3/Eigen/src/Cholesky/LDLT.h +688 -0
  32. include/eigen3/Eigen/src/Cholesky/LLT.h +558 -0
  33. include/eigen3/Eigen/src/Cholesky/LLT_LAPACKE.h +99 -0
  34. include/eigen3/Eigen/src/CholmodSupport/CholmodSupport.h +682 -0
  35. include/eigen3/Eigen/src/Core/ArithmeticSequence.h +413 -0
  36. include/eigen3/Eigen/src/Core/Array.h +417 -0
  37. include/eigen3/Eigen/src/Core/ArrayBase.h +226 -0
  38. include/eigen3/Eigen/src/Core/ArrayWrapper.h +209 -0
  39. include/eigen3/Eigen/src/Core/Assign.h +90 -0
  40. include/eigen3/Eigen/src/Core/AssignEvaluator.h +1010 -0
  41. include/eigen3/Eigen/src/Core/Assign_MKL.h +178 -0
  42. include/eigen3/Eigen/src/Core/BandMatrix.h +353 -0
  43. include/eigen3/Eigen/src/Core/Block.h +448 -0
  44. include/eigen3/Eigen/src/Core/BooleanRedux.h +162 -0
  45. include/eigen3/Eigen/src/Core/CommaInitializer.h +164 -0
  46. include/eigen3/Eigen/src/Core/ConditionEstimator.h +175 -0
  47. include/eigen3/Eigen/src/Core/CoreEvaluators.h +1741 -0
  48. include/eigen3/Eigen/src/Core/CoreIterators.h +132 -0
  49. include/eigen3/Eigen/src/Core/CwiseBinaryOp.h +183 -0
  50. include/eigen3/Eigen/src/Core/CwiseNullaryOp.h +1001 -0
  51. include/eigen3/Eigen/src/Core/CwiseTernaryOp.h +197 -0
  52. include/eigen3/Eigen/src/Core/CwiseUnaryOp.h +103 -0
  53. include/eigen3/Eigen/src/Core/CwiseUnaryView.h +132 -0
  54. include/eigen3/Eigen/src/Core/DenseBase.h +701 -0
  55. include/eigen3/Eigen/src/Core/DenseCoeffsBase.h +685 -0
  56. include/eigen3/Eigen/src/Core/DenseStorage.h +652 -0
  57. include/eigen3/Eigen/src/Core/Diagonal.h +258 -0
  58. include/eigen3/Eigen/src/Core/DiagonalMatrix.h +391 -0
  59. include/eigen3/Eigen/src/Core/DiagonalProduct.h +28 -0
  60. include/eigen3/Eigen/src/Core/Dot.h +318 -0
  61. include/eigen3/Eigen/src/Core/EigenBase.h +160 -0
  62. include/eigen3/Eigen/src/Core/ForceAlignedAccess.h +150 -0
  63. include/eigen3/Eigen/src/Core/Fuzzy.h +155 -0
  64. include/eigen3/Eigen/src/Core/GeneralProduct.h +465 -0
  65. include/eigen3/Eigen/src/Core/GenericPacketMath.h +1040 -0
  66. include/eigen3/Eigen/src/Core/GlobalFunctions.h +194 -0
  67. include/eigen3/Eigen/src/Core/IO.h +258 -0
  68. include/eigen3/Eigen/src/Core/IndexedView.h +237 -0
  69. include/eigen3/Eigen/src/Core/Inverse.h +117 -0
  70. include/eigen3/Eigen/src/Core/Map.h +171 -0
  71. include/eigen3/Eigen/src/Core/MapBase.h +310 -0
  72. include/eigen3/Eigen/src/Core/MathFunctions.h +2057 -0
  73. include/eigen3/Eigen/src/Core/MathFunctionsImpl.h +200 -0
  74. include/eigen3/Eigen/src/Core/Matrix.h +565 -0
  75. include/eigen3/Eigen/src/Core/MatrixBase.h +547 -0
  76. include/eigen3/Eigen/src/Core/NestByValue.h +85 -0
  77. include/eigen3/Eigen/src/Core/NoAlias.h +109 -0
  78. include/eigen3/Eigen/src/Core/NumTraits.h +335 -0
  79. include/eigen3/Eigen/src/Core/PartialReduxEvaluator.h +232 -0
  80. include/eigen3/Eigen/src/Core/PermutationMatrix.h +605 -0
  81. include/eigen3/Eigen/src/Core/PlainObjectBase.h +1128 -0
  82. include/eigen3/Eigen/src/Core/Product.h +191 -0
  83. include/eigen3/Eigen/src/Core/ProductEvaluators.h +1179 -0
  84. include/eigen3/Eigen/src/Core/Random.h +218 -0
  85. include/eigen3/Eigen/src/Core/Redux.h +515 -0
  86. include/eigen3/Eigen/src/Core/Ref.h +381 -0
  87. include/eigen3/Eigen/src/Core/Replicate.h +142 -0
  88. include/eigen3/Eigen/src/Core/Reshaped.h +454 -0
  89. include/eigen3/Eigen/src/Core/ReturnByValue.h +119 -0
  90. include/eigen3/Eigen/src/Core/Reverse.h +217 -0
  91. include/eigen3/Eigen/src/Core/Select.h +164 -0
  92. include/eigen3/Eigen/src/Core/SelfAdjointView.h +365 -0
  93. include/eigen3/Eigen/src/Core/SelfCwiseBinaryOp.h +47 -0
  94. include/eigen3/Eigen/src/Core/Solve.h +188 -0
  95. include/eigen3/Eigen/src/Core/SolveTriangular.h +235 -0
  96. include/eigen3/Eigen/src/Core/SolverBase.h +168 -0
  97. include/eigen3/Eigen/src/Core/StableNorm.h +251 -0
  98. include/eigen3/Eigen/src/Core/StlIterators.h +463 -0
  99. include/eigen3/Eigen/src/Core/Stride.h +116 -0
  100. include/eigen3/Eigen/src/Core/Swap.h +68 -0
  101. include/eigen3/Eigen/src/Core/Transpose.h +464 -0
  102. include/eigen3/Eigen/src/Core/Transpositions.h +386 -0
  103. include/eigen3/Eigen/src/Core/TriangularMatrix.h +1001 -0
  104. include/eigen3/Eigen/src/Core/VectorBlock.h +96 -0
  105. include/eigen3/Eigen/src/Core/VectorwiseOp.h +784 -0
  106. include/eigen3/Eigen/src/Core/Visitor.h +381 -0
  107. include/eigen3/Eigen/src/Core/arch/AVX/Complex.h +372 -0
  108. include/eigen3/Eigen/src/Core/arch/AVX/MathFunctions.h +228 -0
  109. include/eigen3/Eigen/src/Core/arch/AVX/PacketMath.h +1574 -0
  110. include/eigen3/Eigen/src/Core/arch/AVX/TypeCasting.h +115 -0
  111. include/eigen3/Eigen/src/Core/arch/AVX512/Complex.h +422 -0
  112. include/eigen3/Eigen/src/Core/arch/AVX512/MathFunctions.h +362 -0
  113. include/eigen3/Eigen/src/Core/arch/AVX512/PacketMath.h +2303 -0
  114. include/eigen3/Eigen/src/Core/arch/AVX512/TypeCasting.h +89 -0
  115. include/eigen3/Eigen/src/Core/arch/AltiVec/Complex.h +417 -0
  116. include/eigen3/Eigen/src/Core/arch/AltiVec/MathFunctions.h +90 -0
  117. include/eigen3/Eigen/src/Core/arch/AltiVec/MatrixProduct.h +2937 -0
  118. include/eigen3/Eigen/src/Core/arch/AltiVec/MatrixProductCommon.h +221 -0
  119. include/eigen3/Eigen/src/Core/arch/AltiVec/MatrixProductMMA.h +629 -0
  120. include/eigen3/Eigen/src/Core/arch/AltiVec/PacketMath.h +2711 -0
  121. include/eigen3/Eigen/src/Core/arch/CUDA/Complex.h +258 -0
  122. include/eigen3/Eigen/src/Core/arch/Default/BFloat16.h +700 -0
  123. include/eigen3/Eigen/src/Core/arch/Default/ConjHelper.h +117 -0
  124. include/eigen3/Eigen/src/Core/arch/Default/GenericPacketMathFunctions.h +1649 -0
  125. include/eigen3/Eigen/src/Core/arch/Default/GenericPacketMathFunctionsFwd.h +110 -0
  126. include/eigen3/Eigen/src/Core/arch/Default/Half.h +942 -0
  127. include/eigen3/Eigen/src/Core/arch/Default/Settings.h +49 -0
  128. include/eigen3/Eigen/src/Core/arch/Default/TypeCasting.h +120 -0
  129. include/eigen3/Eigen/src/Core/arch/GPU/MathFunctions.h +103 -0
  130. include/eigen3/Eigen/src/Core/arch/GPU/PacketMath.h +1685 -0
  131. include/eigen3/Eigen/src/Core/arch/GPU/TypeCasting.h +80 -0
  132. include/eigen3/Eigen/src/Core/arch/HIP/hcc/math_constants.h +23 -0
  133. include/eigen3/Eigen/src/Core/arch/MSA/Complex.h +648 -0
  134. include/eigen3/Eigen/src/Core/arch/MSA/MathFunctions.h +387 -0
  135. include/eigen3/Eigen/src/Core/arch/MSA/PacketMath.h +1233 -0
  136. include/eigen3/Eigen/src/Core/arch/NEON/Complex.h +584 -0
  137. include/eigen3/Eigen/src/Core/arch/NEON/GeneralBlockPanelKernel.h +183 -0
  138. include/eigen3/Eigen/src/Core/arch/NEON/MathFunctions.h +75 -0
  139. include/eigen3/Eigen/src/Core/arch/NEON/PacketMath.h +4587 -0
  140. include/eigen3/Eigen/src/Core/arch/NEON/TypeCasting.h +1419 -0
  141. include/eigen3/Eigen/src/Core/arch/SSE/Complex.h +351 -0
  142. include/eigen3/Eigen/src/Core/arch/SSE/MathFunctions.h +199 -0
  143. include/eigen3/Eigen/src/Core/arch/SSE/PacketMath.h +1505 -0
  144. include/eigen3/Eigen/src/Core/arch/SSE/TypeCasting.h +142 -0
  145. include/eigen3/Eigen/src/Core/arch/SVE/MathFunctions.h +44 -0
  146. include/eigen3/Eigen/src/Core/arch/SVE/PacketMath.h +752 -0
  147. include/eigen3/Eigen/src/Core/arch/SVE/TypeCasting.h +49 -0
  148. include/eigen3/Eigen/src/Core/arch/SYCL/InteropHeaders.h +232 -0
  149. include/eigen3/Eigen/src/Core/arch/SYCL/MathFunctions.h +301 -0
  150. include/eigen3/Eigen/src/Core/arch/SYCL/PacketMath.h +670 -0
  151. include/eigen3/Eigen/src/Core/arch/SYCL/SyclMemoryModel.h +694 -0
  152. include/eigen3/Eigen/src/Core/arch/SYCL/TypeCasting.h +85 -0
  153. include/eigen3/Eigen/src/Core/arch/ZVector/Complex.h +426 -0
  154. include/eigen3/Eigen/src/Core/arch/ZVector/MathFunctions.h +233 -0
  155. include/eigen3/Eigen/src/Core/arch/ZVector/PacketMath.h +1060 -0
  156. include/eigen3/Eigen/src/Core/functors/AssignmentFunctors.h +177 -0
  157. include/eigen3/Eigen/src/Core/functors/BinaryFunctors.h +541 -0
  158. include/eigen3/Eigen/src/Core/functors/NullaryFunctors.h +189 -0
  159. include/eigen3/Eigen/src/Core/functors/StlFunctors.h +166 -0
  160. include/eigen3/Eigen/src/Core/functors/TernaryFunctors.h +25 -0
  161. include/eigen3/Eigen/src/Core/functors/UnaryFunctors.h +1131 -0
  162. include/eigen3/Eigen/src/Core/products/GeneralBlockPanelKernel.h +2645 -0
  163. include/eigen3/Eigen/src/Core/products/GeneralMatrixMatrix.h +517 -0
  164. include/eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular.h +317 -0
  165. include/eigen3/Eigen/src/Core/products/GeneralMatrixMatrixTriangular_BLAS.h +145 -0
  166. include/eigen3/Eigen/src/Core/products/GeneralMatrixMatrix_BLAS.h +124 -0
  167. include/eigen3/Eigen/src/Core/products/GeneralMatrixVector.h +518 -0
  168. include/eigen3/Eigen/src/Core/products/GeneralMatrixVector_BLAS.h +136 -0
  169. include/eigen3/Eigen/src/Core/products/Parallelizer.h +180 -0
  170. include/eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix.h +544 -0
  171. include/eigen3/Eigen/src/Core/products/SelfadjointMatrixMatrix_BLAS.h +295 -0
  172. include/eigen3/Eigen/src/Core/products/SelfadjointMatrixVector.h +262 -0
  173. include/eigen3/Eigen/src/Core/products/SelfadjointMatrixVector_BLAS.h +118 -0
  174. include/eigen3/Eigen/src/Core/products/SelfadjointProduct.h +133 -0
  175. include/eigen3/Eigen/src/Core/products/SelfadjointRank2Update.h +94 -0
  176. include/eigen3/Eigen/src/Core/products/TriangularMatrixMatrix.h +472 -0
  177. include/eigen3/Eigen/src/Core/products/TriangularMatrixMatrix_BLAS.h +317 -0
  178. include/eigen3/Eigen/src/Core/products/TriangularMatrixVector.h +350 -0
  179. include/eigen3/Eigen/src/Core/products/TriangularMatrixVector_BLAS.h +255 -0
  180. include/eigen3/Eigen/src/Core/products/TriangularSolverMatrix.h +337 -0
  181. include/eigen3/Eigen/src/Core/products/TriangularSolverMatrix_BLAS.h +167 -0
  182. include/eigen3/Eigen/src/Core/products/TriangularSolverVector.h +148 -0
  183. include/eigen3/Eigen/src/Core/util/BlasUtil.h +583 -0
  184. include/eigen3/Eigen/src/Core/util/ConfigureVectorization.h +512 -0
  185. include/eigen3/Eigen/src/Core/util/Constants.h +563 -0
  186. include/eigen3/Eigen/src/Core/util/DisableStupidWarnings.h +106 -0
  187. include/eigen3/Eigen/src/Core/util/ForwardDeclarations.h +322 -0
  188. include/eigen3/Eigen/src/Core/util/IndexedViewHelper.h +186 -0
  189. include/eigen3/Eigen/src/Core/util/IntegralConstant.h +272 -0
  190. include/eigen3/Eigen/src/Core/util/MKL_support.h +137 -0
  191. include/eigen3/Eigen/src/Core/util/Macros.h +1464 -0
  192. include/eigen3/Eigen/src/Core/util/Memory.h +1163 -0
  193. include/eigen3/Eigen/src/Core/util/Meta.h +812 -0
  194. include/eigen3/Eigen/src/Core/util/NonMPL2.h +3 -0
  195. include/eigen3/Eigen/src/Core/util/ReenableStupidWarnings.h +31 -0
  196. include/eigen3/Eigen/src/Core/util/ReshapedHelper.h +51 -0
  197. include/eigen3/Eigen/src/Core/util/StaticAssert.h +221 -0
  198. include/eigen3/Eigen/src/Core/util/SymbolicIndex.h +293 -0
  199. include/eigen3/Eigen/src/Core/util/XprHelper.h +856 -0
  200. include/eigen3/Eigen/src/Eigenvalues/ComplexEigenSolver.h +346 -0
  201. include/eigen3/Eigen/src/Eigenvalues/ComplexSchur.h +462 -0
  202. include/eigen3/Eigen/src/Eigenvalues/ComplexSchur_LAPACKE.h +91 -0
  203. include/eigen3/Eigen/src/Eigenvalues/EigenSolver.h +622 -0
  204. include/eigen3/Eigen/src/Eigenvalues/GeneralizedEigenSolver.h +418 -0
  205. include/eigen3/Eigen/src/Eigenvalues/GeneralizedSelfAdjointEigenSolver.h +226 -0
  206. include/eigen3/Eigen/src/Eigenvalues/HessenbergDecomposition.h +374 -0
  207. include/eigen3/Eigen/src/Eigenvalues/MatrixBaseEigenvalues.h +158 -0
  208. include/eigen3/Eigen/src/Eigenvalues/RealQZ.h +657 -0
  209. include/eigen3/Eigen/src/Eigenvalues/RealSchur.h +558 -0
  210. include/eigen3/Eigen/src/Eigenvalues/RealSchur_LAPACKE.h +77 -0
  211. include/eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +904 -0
  212. include/eigen3/Eigen/src/Eigenvalues/SelfAdjointEigenSolver_LAPACKE.h +87 -0
  213. include/eigen3/Eigen/src/Eigenvalues/Tridiagonalization.h +561 -0
  214. include/eigen3/Eigen/src/Geometry/AlignedBox.h +486 -0
  215. include/eigen3/Eigen/src/Geometry/AngleAxis.h +247 -0
  216. include/eigen3/Eigen/src/Geometry/EulerAngles.h +114 -0
  217. include/eigen3/Eigen/src/Geometry/Homogeneous.h +501 -0
  218. include/eigen3/Eigen/src/Geometry/Hyperplane.h +282 -0
  219. include/eigen3/Eigen/src/Geometry/OrthoMethods.h +235 -0
  220. include/eigen3/Eigen/src/Geometry/ParametrizedLine.h +232 -0
  221. include/eigen3/Eigen/src/Geometry/Quaternion.h +870 -0
  222. include/eigen3/Eigen/src/Geometry/Rotation2D.h +199 -0
  223. include/eigen3/Eigen/src/Geometry/RotationBase.h +206 -0
  224. include/eigen3/Eigen/src/Geometry/Scaling.h +188 -0
  225. include/eigen3/Eigen/src/Geometry/Transform.h +1563 -0
  226. include/eigen3/Eigen/src/Geometry/Translation.h +202 -0
  227. include/eigen3/Eigen/src/Geometry/Umeyama.h +166 -0
  228. include/eigen3/Eigen/src/Geometry/arch/Geometry_SIMD.h +168 -0
  229. include/eigen3/Eigen/src/Householder/BlockHouseholder.h +110 -0
  230. include/eigen3/Eigen/src/Householder/Householder.h +176 -0
  231. include/eigen3/Eigen/src/Householder/HouseholderSequence.h +545 -0
  232. include/eigen3/Eigen/src/IterativeLinearSolvers/BasicPreconditioners.h +226 -0
  233. include/eigen3/Eigen/src/IterativeLinearSolvers/BiCGSTAB.h +212 -0
  234. include/eigen3/Eigen/src/IterativeLinearSolvers/ConjugateGradient.h +229 -0
  235. include/eigen3/Eigen/src/IterativeLinearSolvers/IncompleteCholesky.h +394 -0
  236. include/eigen3/Eigen/src/IterativeLinearSolvers/IncompleteLUT.h +453 -0
  237. include/eigen3/Eigen/src/IterativeLinearSolvers/IterativeSolverBase.h +444 -0
  238. include/eigen3/Eigen/src/IterativeLinearSolvers/LeastSquareConjugateGradient.h +198 -0
  239. include/eigen3/Eigen/src/IterativeLinearSolvers/SolveWithGuess.h +117 -0
  240. include/eigen3/Eigen/src/Jacobi/Jacobi.h +483 -0
  241. include/eigen3/Eigen/src/KLUSupport/KLUSupport.h +358 -0
  242. include/eigen3/Eigen/src/LU/Determinant.h +117 -0
  243. include/eigen3/Eigen/src/LU/FullPivLU.h +877 -0
  244. include/eigen3/Eigen/src/LU/InverseImpl.h +432 -0
  245. include/eigen3/Eigen/src/LU/PartialPivLU.h +624 -0
  246. include/eigen3/Eigen/src/LU/PartialPivLU_LAPACKE.h +83 -0
  247. include/eigen3/Eigen/src/LU/arch/InverseSize4.h +351 -0
  248. include/eigen3/Eigen/src/MetisSupport/MetisSupport.h +137 -0
  249. include/eigen3/Eigen/src/OrderingMethods/Amd.h +435 -0
  250. include/eigen3/Eigen/src/OrderingMethods/Eigen_Colamd.h +1863 -0
  251. include/eigen3/Eigen/src/OrderingMethods/Ordering.h +153 -0
  252. include/eigen3/Eigen/src/PaStiXSupport/PaStiXSupport.h +678 -0
  253. include/eigen3/Eigen/src/PardisoSupport/PardisoSupport.h +545 -0
  254. include/eigen3/Eigen/src/QR/ColPivHouseholderQR.h +674 -0
  255. include/eigen3/Eigen/src/QR/ColPivHouseholderQR_LAPACKE.h +97 -0
  256. include/eigen3/Eigen/src/QR/CompleteOrthogonalDecomposition.h +635 -0
  257. include/eigen3/Eigen/src/QR/FullPivHouseholderQR.h +713 -0
  258. include/eigen3/Eigen/src/QR/HouseholderQR.h +434 -0
  259. include/eigen3/Eigen/src/QR/HouseholderQR_LAPACKE.h +68 -0
  260. include/eigen3/Eigen/src/SPQRSupport/SuiteSparseQRSupport.h +335 -0
  261. include/eigen3/Eigen/src/SVD/BDCSVD.h +1366 -0
  262. include/eigen3/Eigen/src/SVD/JacobiSVD.h +812 -0
  263. include/eigen3/Eigen/src/SVD/JacobiSVD_LAPACKE.h +91 -0
  264. include/eigen3/Eigen/src/SVD/SVDBase.h +376 -0
  265. include/eigen3/Eigen/src/SVD/UpperBidiagonalization.h +414 -0
  266. include/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky.h +697 -0
  267. include/eigen3/Eigen/src/SparseCholesky/SimplicialCholesky_impl.h +174 -0
  268. include/eigen3/Eigen/src/SparseCore/AmbiVector.h +378 -0
  269. include/eigen3/Eigen/src/SparseCore/CompressedStorage.h +274 -0
  270. include/eigen3/Eigen/src/SparseCore/ConservativeSparseSparseProduct.h +352 -0
  271. include/eigen3/Eigen/src/SparseCore/MappedSparseMatrix.h +67 -0
  272. include/eigen3/Eigen/src/SparseCore/SparseAssign.h +270 -0
  273. include/eigen3/Eigen/src/SparseCore/SparseBlock.h +571 -0
  274. include/eigen3/Eigen/src/SparseCore/SparseColEtree.h +206 -0
  275. include/eigen3/Eigen/src/SparseCore/SparseCompressedBase.h +370 -0
  276. include/eigen3/Eigen/src/SparseCore/SparseCwiseBinaryOp.h +722 -0
  277. include/eigen3/Eigen/src/SparseCore/SparseCwiseUnaryOp.h +150 -0
  278. include/eigen3/Eigen/src/SparseCore/SparseDenseProduct.h +342 -0
  279. include/eigen3/Eigen/src/SparseCore/SparseDiagonalProduct.h +138 -0
  280. include/eigen3/Eigen/src/SparseCore/SparseDot.h +98 -0
  281. include/eigen3/Eigen/src/SparseCore/SparseFuzzy.h +29 -0
  282. include/eigen3/Eigen/src/SparseCore/SparseMap.h +305 -0
  283. include/eigen3/Eigen/src/SparseCore/SparseMatrix.h +1518 -0
  284. include/eigen3/Eigen/src/SparseCore/SparseMatrixBase.h +398 -0
  285. include/eigen3/Eigen/src/SparseCore/SparsePermutation.h +178 -0
  286. include/eigen3/Eigen/src/SparseCore/SparseProduct.h +181 -0
  287. include/eigen3/Eigen/src/SparseCore/SparseRedux.h +49 -0
  288. include/eigen3/Eigen/src/SparseCore/SparseRef.h +397 -0
  289. include/eigen3/Eigen/src/SparseCore/SparseSelfAdjointView.h +659 -0
  290. include/eigen3/Eigen/src/SparseCore/SparseSolverBase.h +124 -0
  291. include/eigen3/Eigen/src/SparseCore/SparseSparseProductWithPruning.h +198 -0
  292. include/eigen3/Eigen/src/SparseCore/SparseTranspose.h +92 -0
  293. include/eigen3/Eigen/src/SparseCore/SparseTriangularView.h +189 -0
  294. include/eigen3/Eigen/src/SparseCore/SparseUtil.h +186 -0
  295. include/eigen3/Eigen/src/SparseCore/SparseVector.h +478 -0
  296. include/eigen3/Eigen/src/SparseCore/SparseView.h +254 -0
  297. include/eigen3/Eigen/src/SparseCore/TriangularSolver.h +315 -0
  298. include/eigen3/Eigen/src/SparseLU/SparseLU.h +923 -0
  299. include/eigen3/Eigen/src/SparseLU/SparseLUImpl.h +66 -0
  300. include/eigen3/Eigen/src/SparseLU/SparseLU_Memory.h +226 -0
  301. include/eigen3/Eigen/src/SparseLU/SparseLU_Structs.h +110 -0
  302. include/eigen3/Eigen/src/SparseLU/SparseLU_SupernodalMatrix.h +375 -0
  303. include/eigen3/Eigen/src/SparseLU/SparseLU_Utils.h +80 -0
  304. include/eigen3/Eigen/src/SparseLU/SparseLU_column_bmod.h +181 -0
  305. include/eigen3/Eigen/src/SparseLU/SparseLU_column_dfs.h +179 -0
  306. include/eigen3/Eigen/src/SparseLU/SparseLU_copy_to_ucol.h +107 -0
  307. include/eigen3/Eigen/src/SparseLU/SparseLU_gemm_kernel.h +280 -0
  308. include/eigen3/Eigen/src/SparseLU/SparseLU_heap_relax_snode.h +126 -0
  309. include/eigen3/Eigen/src/SparseLU/SparseLU_kernel_bmod.h +130 -0
  310. include/eigen3/Eigen/src/SparseLU/SparseLU_panel_bmod.h +223 -0
  311. include/eigen3/Eigen/src/SparseLU/SparseLU_panel_dfs.h +258 -0
  312. include/eigen3/Eigen/src/SparseLU/SparseLU_pivotL.h +137 -0
  313. include/eigen3/Eigen/src/SparseLU/SparseLU_pruneL.h +136 -0
  314. include/eigen3/Eigen/src/SparseLU/SparseLU_relax_snode.h +83 -0
  315. include/eigen3/Eigen/src/SparseQR/SparseQR.h +758 -0
  316. include/eigen3/Eigen/src/StlSupport/StdDeque.h +116 -0
  317. include/eigen3/Eigen/src/StlSupport/StdList.h +106 -0
  318. include/eigen3/Eigen/src/StlSupport/StdVector.h +131 -0
  319. include/eigen3/Eigen/src/StlSupport/details.h +84 -0
  320. include/eigen3/Eigen/src/SuperLUSupport/SuperLUSupport.h +1025 -0
  321. include/eigen3/Eigen/src/UmfPackSupport/UmfPackSupport.h +642 -0
  322. include/eigen3/Eigen/src/misc/Image.h +82 -0
  323. include/eigen3/Eigen/src/misc/Kernel.h +79 -0
  324. include/eigen3/Eigen/src/misc/RealSvd2x2.h +55 -0
  325. include/eigen3/Eigen/src/misc/blas.h +440 -0
  326. include/eigen3/Eigen/src/misc/lapack.h +152 -0
  327. include/eigen3/Eigen/src/misc/lapacke.h +16292 -0
  328. include/eigen3/Eigen/src/misc/lapacke_mangling.h +17 -0
  329. include/eigen3/Eigen/src/plugins/ArrayCwiseBinaryOps.h +358 -0
  330. include/eigen3/Eigen/src/plugins/ArrayCwiseUnaryOps.h +696 -0
  331. include/eigen3/Eigen/src/plugins/BlockMethods.h +1442 -0
  332. include/eigen3/Eigen/src/plugins/CommonCwiseBinaryOps.h +115 -0
  333. include/eigen3/Eigen/src/plugins/CommonCwiseUnaryOps.h +177 -0
  334. include/eigen3/Eigen/src/plugins/IndexedViewMethods.h +262 -0
  335. include/eigen3/Eigen/src/plugins/MatrixCwiseBinaryOps.h +152 -0
  336. include/eigen3/Eigen/src/plugins/MatrixCwiseUnaryOps.h +95 -0
  337. include/eigen3/Eigen/src/plugins/ReshapedMethods.h +149 -0
  338. include/eigen3/signature_of_eigen3_matrix_library +1 -0
  339. include/eigen3/unsupported/Eigen/AdolcForward +159 -0
  340. include/eigen3/unsupported/Eigen/AlignedVector3 +234 -0
  341. include/eigen3/unsupported/Eigen/ArpackSupport +30 -0
  342. include/eigen3/unsupported/Eigen/AutoDiff +46 -0
  343. include/eigen3/unsupported/Eigen/BVH +95 -0
  344. include/eigen3/unsupported/Eigen/CXX11/Tensor +137 -0
  345. include/eigen3/unsupported/Eigen/CXX11/TensorSymmetry +42 -0
  346. include/eigen3/unsupported/Eigen/CXX11/ThreadPool +74 -0
  347. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/Tensor.h +554 -0
  348. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorArgMax.h +329 -0
  349. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorAssign.h +247 -0
  350. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorBase.h +1176 -0
  351. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorBlock.h +1559 -0
  352. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorBroadcasting.h +1093 -0
  353. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorChipping.h +518 -0
  354. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorConcatenation.h +377 -0
  355. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorContraction.h +1023 -0
  356. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorContractionBlocking.h +73 -0
  357. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorContractionCuda.h +6 -0
  358. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorContractionGpu.h +1413 -0
  359. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorContractionMapper.h +575 -0
  360. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorContractionSycl.h +1650 -0
  361. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorContractionThreadPool.h +1679 -0
  362. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorConversion.h +456 -0
  363. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorConvolution.h +1132 -0
  364. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorConvolutionSycl.h +544 -0
  365. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorCostModel.h +214 -0
  366. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorCustomOp.h +347 -0
  367. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDevice.h +137 -0
  368. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceCuda.h +6 -0
  369. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceDefault.h +104 -0
  370. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceGpu.h +389 -0
  371. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceSycl.h +1048 -0
  372. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDeviceThreadPool.h +409 -0
  373. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDimensionList.h +236 -0
  374. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorDimensions.h +490 -0
  375. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorEvalTo.h +236 -0
  376. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorEvaluator.h +983 -0
  377. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorExecutor.h +703 -0
  378. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorExpr.h +388 -0
  379. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorFFT.h +669 -0
  380. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorFixedSize.h +379 -0
  381. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorForcedEval.h +237 -0
  382. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorForwardDeclarations.h +191 -0
  383. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorFunctors.h +488 -0
  384. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorGenerator.h +302 -0
  385. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorGlobalFunctions.h +33 -0
  386. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorGpuHipCudaDefines.h +99 -0
  387. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorGpuHipCudaUndefines.h +44 -0
  388. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorIO.h +79 -0
  389. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorImagePatch.h +603 -0
  390. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorIndexList.h +738 -0
  391. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorInflation.h +247 -0
  392. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorInitializer.h +82 -0
  393. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorIntDiv.h +263 -0
  394. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorLayoutSwap.h +216 -0
  395. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorMacros.h +98 -0
  396. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorMap.h +327 -0
  397. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorMeta.h +311 -0
  398. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorMorphing.h +1102 -0
  399. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorPadding.h +708 -0
  400. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorPatch.h +291 -0
  401. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorRandom.h +322 -0
  402. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorReduction.h +998 -0
  403. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorReductionCuda.h +6 -0
  404. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorReductionGpu.h +966 -0
  405. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorReductionSycl.h +582 -0
  406. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorRef.h +454 -0
  407. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorReverse.h +465 -0
  408. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorScan.h +528 -0
  409. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorScanSycl.h +513 -0
  410. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorShuffling.h +471 -0
  411. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorStorage.h +161 -0
  412. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorStriding.h +346 -0
  413. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorTrace.h +303 -0
  414. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorTraits.h +264 -0
  415. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorUInt128.h +249 -0
  416. include/eigen3/unsupported/Eigen/CXX11/src/Tensor/TensorVolumePatch.h +629 -0
  417. include/eigen3/unsupported/Eigen/CXX11/src/TensorSymmetry/DynamicSymmetry.h +293 -0
  418. include/eigen3/unsupported/Eigen/CXX11/src/TensorSymmetry/StaticSymmetry.h +236 -0
  419. include/eigen3/unsupported/Eigen/CXX11/src/TensorSymmetry/Symmetry.h +338 -0
  420. include/eigen3/unsupported/Eigen/CXX11/src/TensorSymmetry/util/TemplateGroupTheory.h +669 -0
  421. include/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/Barrier.h +67 -0
  422. include/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/EventCount.h +249 -0
  423. include/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/NonBlockingThreadPool.h +486 -0
  424. include/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/RunQueue.h +236 -0
  425. include/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/ThreadCancel.h +23 -0
  426. include/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/ThreadEnvironment.h +40 -0
  427. include/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/ThreadLocal.h +301 -0
  428. include/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/ThreadPoolInterface.h +48 -0
  429. include/eigen3/unsupported/Eigen/CXX11/src/ThreadPool/ThreadYield.h +20 -0
  430. include/eigen3/unsupported/Eigen/CXX11/src/util/CXX11Meta.h +537 -0
  431. include/eigen3/unsupported/Eigen/CXX11/src/util/CXX11Workarounds.h +88 -0
  432. include/eigen3/unsupported/Eigen/CXX11/src/util/EmulateArray.h +261 -0
  433. include/eigen3/unsupported/Eigen/CXX11/src/util/MaxSizeVector.h +158 -0
  434. include/eigen3/unsupported/Eigen/EulerAngles +43 -0
  435. include/eigen3/unsupported/Eigen/FFT +419 -0
  436. include/eigen3/unsupported/Eigen/IterativeSolvers +51 -0
  437. include/eigen3/unsupported/Eigen/KroneckerProduct +36 -0
  438. include/eigen3/unsupported/Eigen/LevenbergMarquardt +49 -0
  439. include/eigen3/unsupported/Eigen/MPRealSupport +213 -0
  440. include/eigen3/unsupported/Eigen/MatrixFunctions +504 -0
  441. include/eigen3/unsupported/Eigen/MoreVectorization +24 -0
  442. include/eigen3/unsupported/Eigen/NonLinearOptimization +140 -0
  443. include/eigen3/unsupported/Eigen/NumericalDiff +56 -0
  444. include/eigen3/unsupported/Eigen/OpenGLSupport +322 -0
  445. include/eigen3/unsupported/Eigen/Polynomials +137 -0
  446. include/eigen3/unsupported/Eigen/Skyline +39 -0
  447. include/eigen3/unsupported/Eigen/SparseExtra +54 -0
  448. include/eigen3/unsupported/Eigen/SpecialFunctions +103 -0
  449. include/eigen3/unsupported/Eigen/Splines +35 -0
  450. include/eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffJacobian.h +108 -0
  451. include/eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffScalar.h +730 -0
  452. include/eigen3/unsupported/Eigen/src/AutoDiff/AutoDiffVector.h +220 -0
  453. include/eigen3/unsupported/Eigen/src/BVH/BVAlgorithms.h +293 -0
  454. include/eigen3/unsupported/Eigen/src/BVH/KdBVH.h +223 -0
  455. include/eigen3/unsupported/Eigen/src/Eigenvalues/ArpackSelfAdjointEigenSolver.h +790 -0
  456. include/eigen3/unsupported/Eigen/src/EulerAngles/EulerAngles.h +355 -0
  457. include/eigen3/unsupported/Eigen/src/EulerAngles/EulerSystem.h +305 -0
  458. include/eigen3/unsupported/Eigen/src/FFT/ei_fftw_impl.h +261 -0
  459. include/eigen3/unsupported/Eigen/src/FFT/ei_kissfft_impl.h +449 -0
  460. include/eigen3/unsupported/Eigen/src/IterativeSolvers/ConstrainedConjGrad.h +187 -0
  461. include/eigen3/unsupported/Eigen/src/IterativeSolvers/DGMRES.h +511 -0
  462. include/eigen3/unsupported/Eigen/src/IterativeSolvers/GMRES.h +335 -0
  463. include/eigen3/unsupported/Eigen/src/IterativeSolvers/IDRS.h +436 -0
  464. include/eigen3/unsupported/Eigen/src/IterativeSolvers/IncompleteLU.h +90 -0
  465. include/eigen3/unsupported/Eigen/src/IterativeSolvers/IterationController.h +154 -0
  466. include/eigen3/unsupported/Eigen/src/IterativeSolvers/MINRES.h +267 -0
  467. include/eigen3/unsupported/Eigen/src/IterativeSolvers/Scaling.h +193 -0
  468. include/eigen3/unsupported/Eigen/src/KroneckerProduct/KroneckerTensorProduct.h +305 -0
  469. include/eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMcovar.h +84 -0
  470. include/eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMonestep.h +202 -0
  471. include/eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMpar.h +160 -0
  472. include/eigen3/unsupported/Eigen/src/LevenbergMarquardt/LMqrsolv.h +188 -0
  473. include/eigen3/unsupported/Eigen/src/LevenbergMarquardt/LevenbergMarquardt.h +396 -0
  474. include/eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h +441 -0
  475. include/eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h +569 -0
  476. include/eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixLogarithm.h +373 -0
  477. include/eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h +705 -0
  478. include/eigen3/unsupported/Eigen/src/MatrixFunctions/MatrixSquareRoot.h +368 -0
  479. include/eigen3/unsupported/Eigen/src/MatrixFunctions/StemFunction.h +117 -0
  480. include/eigen3/unsupported/Eigen/src/MoreVectorization/MathFunctions.h +95 -0
  481. include/eigen3/unsupported/Eigen/src/NonLinearOptimization/HybridNonLinearSolver.h +601 -0
  482. include/eigen3/unsupported/Eigen/src/NonLinearOptimization/LevenbergMarquardt.h +657 -0
  483. include/eigen3/unsupported/Eigen/src/NonLinearOptimization/chkder.h +66 -0
  484. include/eigen3/unsupported/Eigen/src/NonLinearOptimization/covar.h +70 -0
  485. include/eigen3/unsupported/Eigen/src/NonLinearOptimization/dogleg.h +107 -0
  486. include/eigen3/unsupported/Eigen/src/NonLinearOptimization/fdjac1.h +79 -0
  487. include/eigen3/unsupported/Eigen/src/NonLinearOptimization/lmpar.h +298 -0
  488. include/eigen3/unsupported/Eigen/src/NonLinearOptimization/qrsolv.h +91 -0
  489. include/eigen3/unsupported/Eigen/src/NonLinearOptimization/r1mpyq.h +30 -0
  490. include/eigen3/unsupported/Eigen/src/NonLinearOptimization/r1updt.h +99 -0
  491. include/eigen3/unsupported/Eigen/src/NonLinearOptimization/rwupdt.h +49 -0
  492. include/eigen3/unsupported/Eigen/src/NumericalDiff/NumericalDiff.h +130 -0
  493. include/eigen3/unsupported/Eigen/src/Polynomials/Companion.h +280 -0
  494. include/eigen3/unsupported/Eigen/src/Polynomials/PolynomialSolver.h +428 -0
  495. include/eigen3/unsupported/Eigen/src/Polynomials/PolynomialUtils.h +143 -0
  496. include/eigen3/unsupported/Eigen/src/Skyline/SkylineInplaceLU.h +352 -0
  497. include/eigen3/unsupported/Eigen/src/Skyline/SkylineMatrix.h +862 -0
  498. include/eigen3/unsupported/Eigen/src/Skyline/SkylineMatrixBase.h +212 -0
  499. include/eigen3/unsupported/Eigen/src/Skyline/SkylineProduct.h +295 -0
  500. include/eigen3/unsupported/Eigen/src/Skyline/SkylineStorage.h +259 -0
  501. include/eigen3/unsupported/Eigen/src/Skyline/SkylineUtil.h +89 -0
  502. include/eigen3/unsupported/Eigen/src/SparseExtra/BlockOfDynamicSparseMatrix.h +122 -0
  503. include/eigen3/unsupported/Eigen/src/SparseExtra/BlockSparseMatrix.h +1079 -0
  504. include/eigen3/unsupported/Eigen/src/SparseExtra/DynamicSparseMatrix.h +404 -0
  505. include/eigen3/unsupported/Eigen/src/SparseExtra/MarketIO.h +282 -0
  506. include/eigen3/unsupported/Eigen/src/SparseExtra/MatrixMarketIterator.h +247 -0
  507. include/eigen3/unsupported/Eigen/src/SparseExtra/RandomSetter.h +349 -0
  508. include/eigen3/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsArrayAPI.h +286 -0
  509. include/eigen3/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsBFloat16.h +68 -0
  510. include/eigen3/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsFunctors.h +357 -0
  511. include/eigen3/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsHalf.h +66 -0
  512. include/eigen3/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsImpl.h +1959 -0
  513. include/eigen3/unsupported/Eigen/src/SpecialFunctions/BesselFunctionsPacketMath.h +118 -0
  514. include/eigen3/unsupported/Eigen/src/SpecialFunctions/HipVectorCompatibility.h +67 -0
  515. include/eigen3/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsArrayAPI.h +167 -0
  516. include/eigen3/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsBFloat16.h +58 -0
  517. include/eigen3/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsFunctors.h +330 -0
  518. include/eigen3/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsHalf.h +58 -0
  519. include/eigen3/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsImpl.h +2045 -0
  520. include/eigen3/unsupported/Eigen/src/SpecialFunctions/SpecialFunctionsPacketMath.h +79 -0
  521. include/eigen3/unsupported/Eigen/src/SpecialFunctions/arch/AVX/BesselFunctions.h +46 -0
  522. include/eigen3/unsupported/Eigen/src/SpecialFunctions/arch/AVX/SpecialFunctions.h +16 -0
  523. include/eigen3/unsupported/Eigen/src/SpecialFunctions/arch/AVX512/BesselFunctions.h +46 -0
  524. include/eigen3/unsupported/Eigen/src/SpecialFunctions/arch/AVX512/SpecialFunctions.h +16 -0
  525. include/eigen3/unsupported/Eigen/src/SpecialFunctions/arch/GPU/SpecialFunctions.h +369 -0
  526. include/eigen3/unsupported/Eigen/src/SpecialFunctions/arch/NEON/BesselFunctions.h +54 -0
  527. include/eigen3/unsupported/Eigen/src/SpecialFunctions/arch/NEON/SpecialFunctions.h +34 -0
  528. include/eigen3/unsupported/Eigen/src/Splines/Spline.h +507 -0
  529. include/eigen3/unsupported/Eigen/src/Splines/SplineFitting.h +431 -0
  530. include/eigen3/unsupported/Eigen/src/Splines/SplineFwd.h +93 -0
  531. qilisdk/__init__.py +26 -0
  532. qilisdk/__init__.pyi +16 -0
  533. qilisdk/_logging.py +135 -0
  534. qilisdk/_optionals.py +137 -0
  535. qilisdk/analog/__init__.py +18 -0
  536. qilisdk/analog/exceptions.py +17 -0
  537. qilisdk/analog/hamiltonian.py +1068 -0
  538. qilisdk/analog/schedule.py +483 -0
  539. qilisdk/backends/__init__.py +46 -0
  540. qilisdk/backends/__init__.pyi +18 -0
  541. qilisdk/backends/backend.py +132 -0
  542. qilisdk/backends/cuda_backend.py +752 -0
  543. qilisdk/backends/qilisim.py +148 -0
  544. qilisdk/backends/qutip_backend.py +504 -0
  545. qilisdk/core/__init__.py +70 -0
  546. qilisdk/core/exceptions.py +29 -0
  547. qilisdk/core/interpolator.py +640 -0
  548. qilisdk/core/model.py +1012 -0
  549. qilisdk/core/parameterizable.py +133 -0
  550. qilisdk/core/qtensor.py +684 -0
  551. qilisdk/core/result.py +18 -0
  552. qilisdk/core/types.py +49 -0
  553. qilisdk/core/variables.py +2035 -0
  554. qilisdk/cost_functions/__init__.py +18 -0
  555. qilisdk/cost_functions/cost_function.py +77 -0
  556. qilisdk/cost_functions/model_cost_function.py +152 -0
  557. qilisdk/cost_functions/observable_cost_function.py +112 -0
  558. qilisdk/digital/__init__.py +67 -0
  559. qilisdk/digital/ansatz.py +382 -0
  560. qilisdk/digital/circuit.py +371 -0
  561. qilisdk/digital/circuit_transpiler.py +46 -0
  562. qilisdk/digital/circuit_transpiler_passes/__init__.py +18 -0
  563. qilisdk/digital/circuit_transpiler_passes/circuit_transpiler_pass.py +36 -0
  564. qilisdk/digital/circuit_transpiler_passes/decompose_multi_controlled_gates_pass.py +220 -0
  565. qilisdk/digital/circuit_transpiler_passes/numeric_helpers.py +82 -0
  566. qilisdk/digital/exceptions.py +37 -0
  567. qilisdk/digital/gates.py +1308 -0
  568. qilisdk/experiments/__init__.py +36 -0
  569. qilisdk/experiments/experiment_functional.py +212 -0
  570. qilisdk/experiments/experiment_result.py +247 -0
  571. qilisdk/functionals/__init__.py +29 -0
  572. qilisdk/functionals/functional.py +39 -0
  573. qilisdk/functionals/functional_result.py +18 -0
  574. qilisdk/functionals/sampling.py +89 -0
  575. qilisdk/functionals/sampling_result.py +92 -0
  576. qilisdk/functionals/time_evolution.py +111 -0
  577. qilisdk/functionals/time_evolution_result.py +91 -0
  578. qilisdk/functionals/variational_program.py +138 -0
  579. qilisdk/functionals/variational_program_result.py +69 -0
  580. qilisdk/logging_config.yaml +16 -0
  581. qilisdk/noise/__init__.py +56 -0
  582. qilisdk/noise/amplitude_damping.py +71 -0
  583. qilisdk/noise/bit_flip.py +45 -0
  584. qilisdk/noise/dephasing.py +69 -0
  585. qilisdk/noise/depolarizing.py +44 -0
  586. qilisdk/noise/gaussian_perturbation.py +69 -0
  587. qilisdk/noise/noise.py +20 -0
  588. qilisdk/noise/noise_abc.py +31 -0
  589. qilisdk/noise/noise_config.py +77 -0
  590. qilisdk/noise/noise_model.py +259 -0
  591. qilisdk/noise/offset_perturbation.py +39 -0
  592. qilisdk/noise/parameter_perturbation.py +45 -0
  593. qilisdk/noise/pauli_channel.py +115 -0
  594. qilisdk/noise/phase_flip.py +45 -0
  595. qilisdk/noise/protocols.py +107 -0
  596. qilisdk/noise/readout_assignment.py +60 -0
  597. qilisdk/noise/representations.py +149 -0
  598. qilisdk/noise/utils.py +90 -0
  599. qilisdk/optimizers/__init__.py +17 -0
  600. qilisdk/optimizers/optimizer.py +39 -0
  601. qilisdk/optimizers/optimizer_result.py +101 -0
  602. qilisdk/optimizers/scipy_optimizer.py +118 -0
  603. qilisdk/py.typed +0 -0
  604. qilisdk/settings.py +103 -0
  605. qilisdk/speqtrum/__init__.py +41 -0
  606. qilisdk/speqtrum/__init__.pyi +18 -0
  607. qilisdk/speqtrum/keyring.py +58 -0
  608. qilisdk/speqtrum/speqtrum.py +817 -0
  609. qilisdk/speqtrum/speqtrum_models.py +560 -0
  610. qilisdk/utils/__init__.py +13 -0
  611. qilisdk/utils/openfermion/__init__.py +38 -0
  612. qilisdk/utils/openfermion/__init__.pyi +17 -0
  613. qilisdk/utils/openfermion/openfermion.py +45 -0
  614. qilisdk/utils/openqasm2.py +215 -0
  615. qilisdk/utils/serialization.py +128 -0
  616. qilisdk/utils/trotterization/__init__.py +18 -0
  617. qilisdk/utils/trotterization/trotterization.py +127 -0
  618. qilisdk/utils/visualization/PlusJakartaSans-SemiBold.ttf +0 -0
  619. qilisdk/utils/visualization/__init__.py +24 -0
  620. qilisdk/utils/visualization/circuit_renderers.py +781 -0
  621. qilisdk/utils/visualization/schedule_renderers.py +175 -0
  622. qilisdk/utils/visualization/style.py +154 -0
  623. qilisdk/utils/visualization/themes.py +76 -0
  624. qilisdk/yaml.py +260 -0
  625. qilisdk-0.1.8.dist-info/METADATA +657 -0
  626. qilisdk-0.1.8.dist-info/RECORD +634 -0
  627. qilisdk-0.1.8.dist-info/WHEEL +5 -0
  628. qilisdk-0.1.8.dist-info/licenses/LICENCE +201 -0
  629. qilisim_module.cpython-312-darwin.so +0 -0
  630. share/eigen3/cmake/Eigen3Config.cmake +37 -0
  631. share/eigen3/cmake/Eigen3ConfigVersion.cmake +65 -0
  632. share/eigen3/cmake/Eigen3Targets.cmake +106 -0
  633. share/eigen3/cmake/UseEigen3.cmake +6 -0
  634. share/pkgconfig/eigen3.pc +9 -0
@@ -0,0 +1,2035 @@
1
+ # Copyright 2025 Qilimanjaro Quantum Tech
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ from __future__ import annotations
16
+
17
+ import copy
18
+ import re
19
+ from abc import ABC, abstractmethod
20
+ from typing import Iterator, Mapping, Sequence, TypeVar, cast, overload
21
+
22
+ import numpy as np
23
+ from loguru import logger
24
+
25
+ from qilisdk.core.exceptions import EvaluationError, InvalidBoundsError, NotSupportedOperation, OutOfBoundsException
26
+ from qilisdk.settings import get_settings
27
+ from qilisdk.yaml import yaml
28
+
29
+ from .types import Number, QiliEnum, RealNumber
30
+
31
+ GenericVar = TypeVar("GenericVar", bound="Variable")
32
+ CONST_KEY = "_const_"
33
+ MAX_INT = np.iinfo(np.int64).max
34
+ MIN_INT = np.iinfo(np.int64).min
35
+ LARGE_BOUND = 100
36
+
37
+
38
+ def LT(lhs: RealNumber | BaseVariable | Term, rhs: RealNumber | BaseVariable | Term) -> ComparisonTerm:
39
+ """'Less Than' mathematical operation
40
+
41
+ Args:
42
+ lhs (RealNumber | BaseVariable | Term): the left hand side of the comparison term.
43
+ rhs (RealNumber | BaseVariable | Term): the right hand side of the comparison term.
44
+
45
+ Returns:
46
+ ComparisonTerm: a comparison term with the structure lhs < rhs.
47
+ """
48
+ return ComparisonTerm(lhs=lhs, rhs=rhs, operation=ComparisonOperation.LT)
49
+
50
+
51
+ LessThan = LT
52
+
53
+
54
+ def LEQ(lhs: RealNumber | BaseVariable | Term, rhs: RealNumber | BaseVariable | Term) -> ComparisonTerm:
55
+ """'Less Than or equal to' mathematical operation
56
+
57
+ Args:
58
+ lhs (RealNumber | BaseVariable | Term): the left hand side of the comparison term.
59
+ rhs (RealNumber | BaseVariable | Term): the right hand side of the comparison term.
60
+
61
+ Returns:
62
+ ComparisonTerm: a comparison term with the structure lhs <= rhs.
63
+ """
64
+ return ComparisonTerm(lhs=lhs, rhs=rhs, operation=ComparisonOperation.LEQ)
65
+
66
+
67
+ LessThanOrEqual = LEQ
68
+
69
+
70
+ def EQ(lhs: RealNumber | BaseVariable | Term, rhs: RealNumber | BaseVariable | Term) -> ComparisonTerm:
71
+ """'Equal to' mathematical operation
72
+
73
+ Args:
74
+ lhs (RealNumber | BaseVariable | Term): the left hand side of the comparison term.
75
+ rhs (RealNumber | BaseVariable | Term): the right hand side of the comparison term.
76
+
77
+ Returns:
78
+ ComparisonTerm: a comparison term with the structure lhs == rhs.
79
+ """
80
+ return ComparisonTerm(lhs=lhs, rhs=rhs, operation=ComparisonOperation.EQ)
81
+
82
+
83
+ Equal = EQ
84
+
85
+
86
+ def NEQ(lhs: RealNumber | BaseVariable | Term, rhs: RealNumber | BaseVariable | Term) -> ComparisonTerm:
87
+ """'Not Equal to' mathematical operation
88
+
89
+ Args:
90
+ lhs (RealNumber | BaseVariable | Term): the left hand side of the comparison term.
91
+ rhs (RealNumber | BaseVariable | Term): the right hand side of the comparison term.
92
+
93
+ Returns:
94
+ ComparisonTerm: a comparison term with the structure lhs != rhs.
95
+ """
96
+ return ComparisonTerm(lhs=lhs, rhs=rhs, operation=ComparisonOperation.NEQ)
97
+
98
+
99
+ NotEqual = NEQ
100
+
101
+
102
+ def GT(lhs: RealNumber | BaseVariable | Term, rhs: RealNumber | BaseVariable | Term) -> ComparisonTerm:
103
+ """'Greater Than' mathematical operation
104
+
105
+ Args:
106
+ lhs (RealNumber | BaseVariable | Term): the left hand side of the comparison term.
107
+ rhs (RealNumber | BaseVariable | Term): the right hand side of the comparison term.
108
+
109
+ Returns:
110
+ ComparisonTerm: a comparison term with the structure lhs > rhs.
111
+ """
112
+ return ComparisonTerm(lhs=lhs, rhs=rhs, operation=ComparisonOperation.GT)
113
+
114
+
115
+ GreaterThan = GT
116
+
117
+
118
+ def GEQ(lhs: RealNumber | BaseVariable | Term, rhs: RealNumber | BaseVariable | Term) -> ComparisonTerm:
119
+ """'Greater Than or equal to' mathematical operation
120
+
121
+ Args:
122
+ lhs (RealNumber | BaseVariable | Term): the left hand side of the comparison term.
123
+ rhs (RealNumber | BaseVariable | Term): the right hand side of the comparison term.
124
+
125
+ Returns:
126
+ ComparisonTerm: a comparison term with the structure lhs >= rhs.
127
+ """
128
+ return ComparisonTerm(lhs=lhs, rhs=rhs, operation=ComparisonOperation.GEQ)
129
+
130
+
131
+ GreaterThanOrEqual = GEQ
132
+
133
+
134
+ def _extract_number(label: str) -> int:
135
+ """
136
+ Extracts the number from the variable's label.
137
+ Note that this only matches positive integers.
138
+
139
+ Args:
140
+ label (str): variable label that follows the format <label>(<number>).
141
+
142
+ Returns:
143
+ int: the number in the label.
144
+ """
145
+ pattern = re.compile(r"\((\d+)\)$")
146
+ matches = pattern.search(label)
147
+ if matches is not None:
148
+ return int(matches.group(1))
149
+ return 0
150
+
151
+
152
+ def _float_if_real(value: Number) -> Number:
153
+ if isinstance(value, RealNumber):
154
+ return value
155
+ if isinstance(value, complex) and abs(value.imag) < get_settings().atol:
156
+ return value.real
157
+ return value
158
+
159
+
160
+ def _assert_real(value: Number) -> RealNumber:
161
+ _value = _float_if_real(value)
162
+ if isinstance(_value, RealNumber):
163
+ return _value
164
+ raise ValueError(f"Only Real values are allowed but {_value} was provided.")
165
+
166
+
167
+ @yaml.register_class(shared=True)
168
+ class Domain(QiliEnum):
169
+ INTEGER = "Integer Domain"
170
+ POSITIVE_INTEGER = "Positive Integer Domain"
171
+ REAL = "Real Domain"
172
+ BINARY = "Binary Domain"
173
+ SPIN = "Spin Domain"
174
+
175
+ def check_value(self, value: Number) -> bool:
176
+ """checks if the provided value is valid for a given domain
177
+
178
+ Args:
179
+ value (int | float): the value to be evaluated.
180
+
181
+ Returns:
182
+ bool: True if the value provided is valid, False otherwise.
183
+ """
184
+ if self == Domain.BINARY:
185
+ return isinstance(value, Number) and value in {0, 1}
186
+ if self == Domain.SPIN:
187
+ return isinstance(value, Number) and value in {-1, 1}
188
+ if self == Domain.REAL:
189
+ return isinstance(value, (int, float))
190
+ if self == Domain.INTEGER:
191
+ return isinstance(value, int)
192
+ if self == Domain.POSITIVE_INTEGER:
193
+ return isinstance(value, int) and value >= 0
194
+ return False
195
+
196
+ def min(self) -> float:
197
+ """
198
+ Returns:
199
+ float: the minimum value allowed of a given domain.
200
+ """
201
+ if self in {Domain.BINARY, Domain.POSITIVE_INTEGER}:
202
+ return 0
203
+ if self == Domain.SPIN:
204
+ return -1
205
+ if self == Domain.INTEGER:
206
+ return MIN_INT
207
+ return -1e30
208
+
209
+ def max(self) -> float:
210
+ """
211
+ Returns:
212
+ float: the maximum value allowed for a given domain.
213
+ """
214
+ if self in {Domain.BINARY, Domain.SPIN}:
215
+ return 1
216
+ if self in {Domain.POSITIVE_INTEGER, Domain.INTEGER}:
217
+ return MAX_INT
218
+ return 1e30
219
+
220
+
221
+ @yaml.register_class
222
+ class Operation(QiliEnum):
223
+ MUL = "*"
224
+ ADD = "+"
225
+ DIV = "/"
226
+ SUB = "-"
227
+ MATH_MAP = "mathematical_map"
228
+
229
+
230
+ @yaml.register_class
231
+ class ComparisonOperation(QiliEnum):
232
+ LT = "<"
233
+ LEQ = "<="
234
+ EQ = "=="
235
+ NEQ = "!="
236
+ GT = ">"
237
+ GEQ = ">="
238
+
239
+
240
+ @yaml.register_class
241
+ class Encoding(ABC):
242
+ """Represents an abstract variable encoding class.
243
+
244
+ The Encoding is defined on the variable bases, and it defines how the continuous variables are encoded into binary
245
+ variables.
246
+ """
247
+
248
+ @property
249
+ @abstractmethod
250
+ def name(self) -> str:
251
+ """Encoding's name
252
+
253
+ Returns:
254
+ str: The name of the encoding.
255
+ """
256
+
257
+ @staticmethod
258
+ @abstractmethod
259
+ def encode(var: Variable, precision: float = 1e-2) -> Term:
260
+ """Given a continuous variable return a Term that only consists of
261
+ binary variables that represent the continuous variable in the given encoding.
262
+
263
+ Args:
264
+ var (ContinuousVar): The continuous variable to be encoded
265
+ precision (int): the precision to be considered for real variables (Only applies if
266
+ the variable domain is Domain.Real)
267
+
268
+ Returns:
269
+ Term: a term that only contains binary variables
270
+ """
271
+
272
+ @staticmethod
273
+ @abstractmethod
274
+ def encoding_constraint(var: Variable, precision: float = 1e-2) -> ComparisonTerm:
275
+ """Given a continuous variable return a Constraint Term that ensures that the encoding is respected.
276
+
277
+ Args:
278
+ var (ContinuousVar): The continuous variable to be encoded
279
+ precision (float): the precision to be considered for real variables (Only applies if
280
+ the variable domain is Domain.Real)
281
+
282
+ Returns:
283
+ Constraint Term: a constraint term that ensures the encoding is respected.
284
+ """
285
+
286
+ @staticmethod
287
+ @abstractmethod
288
+ def evaluate(var: Variable, value: list[int] | int, precision: float = 1e-2) -> float:
289
+ """Given a binary string, evaluate the value of the continuous variable in the given encoding.
290
+
291
+ Args:
292
+ var (ContinuousVar): the variable to be evaluated
293
+ value (list[int] | int): a list of binary values or an integer value.
294
+ precision (float): the precision to be considered for real variables (Only applies if
295
+ the variable domain is Domain.Real)
296
+
297
+ Returns:
298
+ float: the value of the continuous variable given the specified binary values.
299
+ """
300
+
301
+ @staticmethod
302
+ @abstractmethod
303
+ def num_binary_equivalent(var: "Variable", precision: float = 1e-2) -> int:
304
+ """Give a continuous variable return the number of binary variables needed to encode it.
305
+
306
+ Args:
307
+ var (ContinuousVar): the continuous variable.
308
+ precision (float): the precision to be considered for real variables (Only applies if
309
+ the variable domain is Domain.Real)
310
+
311
+ Returns:
312
+ int: the number of binary variables needed to encode it.
313
+ """
314
+
315
+ @staticmethod
316
+ @abstractmethod
317
+ def check_valid(value: list[int] | int) -> tuple[bool, int]:
318
+ """checks if the binary list sample is a valid sample in this encoding.
319
+
320
+ Args:
321
+ value (list[int] | int): a list of binary values or an integer value.
322
+
323
+ Returns:
324
+ tuple[bool, int]: the boolean is True if the sample is a valid encoding,
325
+ while the int is the error in the encoding.
326
+ """
327
+
328
+
329
+ def _check_output(var: Variable, output: Number) -> RealNumber:
330
+ """Parse the output of an eval, converting it to a real number if possible and ensuring it is within the variable's domain.
331
+
332
+ Args:
333
+ var (Variable): The variable for which the output is being parsed.
334
+ output (Number): The number to be parsed.
335
+
336
+ Returns:
337
+ Number: The output as a valid number within the variable's domain.
338
+
339
+ Raises:
340
+ ValueError: If the output is not a valid real number.
341
+ """
342
+ if isinstance(output, RealNumber):
343
+ out = float(output)
344
+ elif isinstance(output, complex) and abs(output.imag) < get_settings().atol:
345
+ out = float(output.real)
346
+ else:
347
+ raise ValueError(f"Evaluation answer ({output}) is outside the variable domain ({var.domain}).")
348
+
349
+ out = int(out) if var.domain in {Domain.INTEGER, Domain.POSITIVE_INTEGER} else out
350
+
351
+ if not var.domain.check_value(out):
352
+ raise ValueError(f"The value {out} violates the domain {var.domain.__class__.__name__} of the variable {var}")
353
+
354
+ return out
355
+
356
+
357
+ @yaml.register_class
358
+ class Bitwise(Encoding):
359
+ """Represents a Bitwise variable encoding class."""
360
+
361
+ name = "Bitwise"
362
+
363
+ @staticmethod
364
+ def _bitwise_encode(x: int, N: int) -> list[int]:
365
+ """encode the integer x in Bitwise encoding.
366
+
367
+ Args:
368
+ x (int): the integer to be encoded.
369
+ N (int): the number of bits to encode x.
370
+
371
+ Returns:
372
+ list[int]: a binary list representing the Bitwise encoding of the integer x.
373
+ """
374
+ return list(reversed([int(b) for b in format(x, f"0{N}b")]))
375
+
376
+ @staticmethod
377
+ def encode(var: Variable, precision: float = 1e-2) -> Term:
378
+ bounds = var.bounds
379
+ if var.domain is Domain.REAL:
380
+ bounds = (bounds[0] / precision, bounds[1] / precision)
381
+
382
+ abs_bound = np.abs(bounds[1] - bounds[0])
383
+ n_binary = int(np.floor(np.log2(abs_bound if abs_bound != 0 else 1)))
384
+ binary_vars = [BinaryVariable(var.label + f"({i})") for i in range(n_binary + 1)]
385
+
386
+ term = sum(2**i * binary_vars[i] for i in range(n_binary))
387
+ term += (np.abs(bounds[1] - bounds[0]) + 1 - 2**n_binary) * binary_vars[-1]
388
+ term += bounds[0]
389
+ return term * var.precision if var.domain is Domain.REAL else term
390
+
391
+ @staticmethod
392
+ def evaluate(var: Variable, value: list[int] | int, precision: float = 1e-2) -> float:
393
+ term = Bitwise.encode(var, precision)
394
+ binary_var = sorted(
395
+ term.variables(),
396
+ key=lambda x: _extract_number(x.label),
397
+ )
398
+
399
+ binary_list = Bitwise._bitwise_encode(value, len(binary_var)) if isinstance(value, Number) else value
400
+
401
+ if not Bitwise.check_valid(binary_list)[0]:
402
+ raise ValueError(
403
+ f"invalid binary string {binary_list} with the Bitwise encoding."
404
+ ) # can not be reached in the case of Bitwise encoding.
405
+
406
+ if len(binary_list) < len(binary_var):
407
+ for _ in range(len(binary_var) - len(binary_list)):
408
+ binary_list.append(0)
409
+ elif len(binary_list) != len(binary_var):
410
+ raise ValueError(f"expected {len(binary_var)} variables but received {len(binary_list)}")
411
+
412
+ binary_dict: dict[BaseVariable, list[int]] = {binary_var[i]: [binary_list[i]] for i in range(len(binary_list))}
413
+
414
+ _out = term.evaluate(binary_dict)
415
+ out = _check_output(var, _out)
416
+
417
+ return out
418
+
419
+ @staticmethod
420
+ def encoding_constraint(var: Variable, precision: float = 1e-2) -> ComparisonTerm:
421
+ raise NotImplementedError("Bitwise encoding constraints are not supported at the moment")
422
+
423
+ @staticmethod
424
+ def num_binary_equivalent(var: "Variable", precision: float = 1e-2) -> int:
425
+ bounds = var.bounds
426
+ if var.domain is Domain.REAL:
427
+ bounds = (bounds[0] / precision, bounds[1] / precision)
428
+
429
+ n_binary = int(np.floor(np.log2(np.abs(bounds[1] - bounds[0]))))
430
+
431
+ return n_binary + 1
432
+
433
+ @staticmethod
434
+ def check_valid(value: list[int] | int) -> tuple[bool, int]:
435
+ return True, 0
436
+
437
+
438
+ @yaml.register_class
439
+ class OneHot(Encoding):
440
+ """Represents a One-Hot variable encoding class."""
441
+
442
+ name = "One-Hot"
443
+
444
+ @staticmethod
445
+ def _one_hot_encode(x: int, N: int) -> list[int]:
446
+ """One-hot encode integer x in range [0, N-1].
447
+
448
+ Args:
449
+ x (int): the value to be encoded
450
+ N (int): the number of bits to encode x.
451
+
452
+ Raises:
453
+ ValueError: if x is larger than N or less than 0
454
+
455
+ Returns:
456
+ list[int]: a binary list representing the one hot encoding of the integer x.
457
+ """
458
+ if not (0 <= x < N):
459
+ raise ValueError(f"the input value ({x}) must be in range [0, {N - 1}]")
460
+ return [1 if i == x else 0 for i in range(N)]
461
+
462
+ @staticmethod
463
+ def _find_zero(var: Variable) -> int:
464
+ binary_var = var.bin_vars
465
+ term = var.term
466
+ for i in range(var.num_binary_equivalent()):
467
+ if binary_var[i] not in term:
468
+ return i
469
+ return 0
470
+
471
+ @staticmethod
472
+ def encode(var: Variable, precision: float = 1e-2) -> Term:
473
+ bounds = var.bounds
474
+ if var.domain is Domain.REAL:
475
+ bounds = (bounds[0] / precision, bounds[1] / precision)
476
+
477
+ n_binary = int(np.abs(bounds[1] - bounds[0])) + 1
478
+
479
+ binary_vars = [BinaryVariable(var.label + f"({i})") for i in range(n_binary)]
480
+
481
+ term = Term([(bounds[0] + i) * binary_vars[i] for i in range(n_binary)], Operation.ADD)
482
+
483
+ return term * var.precision if var.domain is Domain.REAL else term
484
+
485
+ @staticmethod
486
+ def evaluate(var: Variable, value: list[int] | int, precision: float = 1e-2) -> float:
487
+ term = OneHot.encode(var, precision)
488
+ binary_var = sorted(
489
+ term.variables(),
490
+ key=lambda x: _extract_number(x.label),
491
+ )
492
+
493
+ binary_list = OneHot._one_hot_encode(value, len(binary_var) + 1) if isinstance(value, int) else value
494
+
495
+ if not OneHot.check_valid(binary_list)[0]:
496
+ raise ValueError(f"invalid binary string {binary_list} with the one hot encoding.")
497
+
498
+ # after encoding we will have one less variable than the binary list, because the first variable is multiplied
499
+ # by 0 so it is removed from the term.
500
+ if len(binary_list) < len(binary_var) + 1:
501
+ for _ in range(len(binary_var) - len(binary_list) + 1):
502
+ binary_list.append(0)
503
+ elif len(binary_list) != len(binary_var) + 1:
504
+ raise ValueError(f"expected {len(binary_var) + 1} variables but received {len(binary_list)}")
505
+
506
+ zero_index = OneHot._find_zero(var)
507
+ binary_dict: dict[BaseVariable, list[int]] = {}
508
+ for i in range(var.num_binary_equivalent()):
509
+ if i < zero_index:
510
+ binary_dict[binary_var[i]] = [binary_list[i]]
511
+ if i > zero_index:
512
+ binary_dict[binary_var[i - 1]] = [binary_list[i]]
513
+
514
+ _out = term.evaluate(binary_dict)
515
+ out = _check_output(var, _out)
516
+
517
+ return out
518
+
519
+ @staticmethod
520
+ def encoding_constraint(var: Variable, precision: float = 1e-2) -> ComparisonTerm:
521
+ bounds = var.bounds
522
+ if var.domain is Domain.REAL:
523
+ bounds = (bounds[0] / precision, bounds[1] / precision)
524
+
525
+ n_binary = int(np.abs(bounds[1] - bounds[0])) + 1
526
+
527
+ binary_vars = [BinaryVariable(var.label + f"({i})") for i in range(n_binary)]
528
+ return ComparisonTerm(lhs=sum(binary_vars), rhs=1, operation=ComparisonOperation.EQ)
529
+
530
+ @staticmethod
531
+ def num_binary_equivalent(var: Variable, precision: float = 1e-2) -> int:
532
+ bounds = var.bounds
533
+ if var.domain is Domain.REAL:
534
+ bounds = (bounds[0] / precision, bounds[1] / precision)
535
+
536
+ n_binary = int(np.abs(bounds[1] - bounds[0])) + 1
537
+
538
+ return n_binary
539
+
540
+ @staticmethod
541
+ def check_valid(value: list[int] | int) -> tuple[bool, int]:
542
+ binary_list = OneHot._one_hot_encode(value, value) if isinstance(value, int) else value
543
+ num_ones = binary_list.count(1)
544
+ return num_ones == 1, (num_ones - 1) ** 2
545
+
546
+
547
+ @yaml.register_class
548
+ class DomainWall(Encoding):
549
+ """Represents a Domain-wall variable encoding class."""
550
+
551
+ name = "Domain Wall"
552
+
553
+ @staticmethod
554
+ def _domain_wall_encode(x: int, N: int) -> list[int]:
555
+ """domain wall encode integer x in range [0, N-1].
556
+
557
+ Args:
558
+ x (int): the value to be encoded
559
+ N (int): the number of bits to encode x.
560
+
561
+ Raises:
562
+ ValueError: if x is larger than N or less than 0
563
+
564
+ Returns:
565
+ list[int]: a binary list representing the domain wall encoding of the integer x.
566
+ """
567
+ if not (0 <= x <= N):
568
+ raise ValueError(f"the input value ({x}) must be in range [0, {N}]")
569
+ return [1] * x + [0] * (N - x)
570
+
571
+ @staticmethod
572
+ def encode(var: Variable, precision: float = 1e-2) -> Term:
573
+ bounds = var.bounds
574
+ if var.domain is Domain.REAL:
575
+ bounds = (bounds[0] / precision, bounds[1] / precision)
576
+
577
+ n_binary = int(np.abs(bounds[1] - bounds[0]))
578
+
579
+ binary_vars = [BinaryVariable(var.label + f"({i})") for i in range(n_binary)]
580
+
581
+ term = Term([0], Operation.ADD)
582
+ for i in range(n_binary):
583
+ term += binary_vars[i]
584
+
585
+ term += bounds[0]
586
+
587
+ return term * var.precision if var.domain is Domain.REAL else term
588
+
589
+ @staticmethod
590
+ def evaluate(var: Variable, value: list[int] | int, precision: float = 1e-2) -> float:
591
+ term = DomainWall.encode(var, precision)
592
+ binary_var = term.variables()
593
+ binary_var = sorted(
594
+ term.variables(),
595
+ key=lambda x: _extract_number(x.label),
596
+ )
597
+
598
+ binary_list: list[int] = (
599
+ DomainWall._domain_wall_encode(value, len(binary_var)) if isinstance(value, RealNumber) else value
600
+ )
601
+
602
+ if not DomainWall.check_valid(binary_list)[0]:
603
+ raise ValueError(f"invalid binary string {binary_list} with the domain wall encoding.")
604
+
605
+ if len(binary_list) < len(binary_var):
606
+ for _ in range(len(binary_var) - len(binary_list)):
607
+ binary_list.append(0)
608
+ elif len(binary_list) != len(binary_var):
609
+ raise ValueError(f"expected {len(binary_var)} variables but received {len(binary_list)}")
610
+
611
+ binary_dict: dict[BaseVariable, list[int]] = {binary_var[i]: [binary_list[i]] for i in range(len(binary_list))}
612
+
613
+ _out = term.evaluate(binary_dict)
614
+ out = _check_output(var, _out)
615
+
616
+ return out
617
+
618
+ @staticmethod
619
+ def encoding_constraint(var: Variable, precision: float = 1e-2) -> ComparisonTerm:
620
+ bounds = var.bounds
621
+ if var.domain is Domain.REAL:
622
+ bounds = (bounds[0] / precision, bounds[1] / precision)
623
+
624
+ n_binary = int(np.abs(bounds[1] - bounds[0]))
625
+
626
+ binary_vars = [BinaryVariable(var.label + f"({i})") for i in range(n_binary)]
627
+ return ComparisonTerm(
628
+ lhs=sum(binary_vars[i + 1] * (1 - binary_vars[i]) for i in range(len(binary_vars) - 1)),
629
+ rhs=0,
630
+ operation=ComparisonOperation.EQ,
631
+ )
632
+
633
+ @staticmethod
634
+ def num_binary_equivalent(var: Variable, precision: float = 1e-2) -> int:
635
+ bounds = var.bounds
636
+ if var.domain is Domain.REAL:
637
+ bounds = (bounds[0] / precision, bounds[1] / precision)
638
+
639
+ n_binary = int(np.abs(bounds[1] - bounds[0]))
640
+
641
+ return n_binary
642
+
643
+ @staticmethod
644
+ def check_valid(value: list[int] | int) -> tuple[bool, int]:
645
+ binary_list = DomainWall._domain_wall_encode(value, value) if isinstance(value, int) else value
646
+ value = sum(binary_list[i + 1] * (1 - binary_list[i]) for i in range(len(binary_list) - 1))
647
+ return value == 0, value
648
+
649
+
650
+ # Variables ###
651
+
652
+
653
+ class BaseVariable(ABC):
654
+ """
655
+ Abstract base class for symbolic decision variables.
656
+ """
657
+
658
+ TOL = get_settings().atol
659
+
660
+ def __init__(self, label: str, domain: Domain, bounds: tuple[float | None, float | None] = (None, None)) -> None:
661
+ """initialize a new Variable object
662
+
663
+ Args:
664
+ label (str): The name of the variable.
665
+ domain (Domain): The domain of the values this variable can take.
666
+ bounds (tuple[float | None, float | None], optional): the bounds on the variable's values.
667
+ The bounds follow the structure (lower_bound, Upper_bound) both
668
+ included. Defaults to (None, None).
669
+ Note: if None is selected then the lowest/highest possible value of the
670
+ variable's domain is chosen.
671
+
672
+ Raises:
673
+ OutOfBoundsException: the lower bound or the upper bound don't correspond to the variable domain.
674
+ InvalidBoundsError: the lower bound is higher than the upper bound.
675
+ """
676
+ self._label = label
677
+ self._domain = domain
678
+
679
+ lower_bound, upper_bound = bounds
680
+ if lower_bound is None:
681
+ lower_bound = domain.min()
682
+ if upper_bound is None:
683
+ upper_bound = domain.max()
684
+
685
+ if not self.domain.check_value(upper_bound):
686
+ raise OutOfBoundsException(
687
+ f"the upper bound ({upper_bound}) does not respect the domain of the variable ({self.domain})"
688
+ )
689
+ if not self.domain.check_value(lower_bound):
690
+ raise OutOfBoundsException(
691
+ f"the lower bound ({lower_bound}) does not respect the domain of the variable ({self.domain})"
692
+ )
693
+ if lower_bound > upper_bound:
694
+ raise InvalidBoundsError("lower bound can't be larger than the upper bound.")
695
+ self._bounds = (lower_bound, upper_bound)
696
+ self._hash_cache: int | None = None
697
+
698
+ @property
699
+ def bounds(self) -> tuple[float, float]:
700
+ """Property that stores a tuple representing the bounds of the values a variable is allowed to take.º
701
+
702
+ Returns:
703
+ tuple(float, float): The lower and upper bound of the variable.
704
+ """
705
+ return self._bounds
706
+
707
+ @property
708
+ def lower_bound(self) -> float:
709
+ """The lower bound of the variable.
710
+
711
+ Returns:
712
+ float: the value of the lower bound.
713
+ """
714
+ return self._bounds[0]
715
+
716
+ @property
717
+ def upper_bound(self) -> float:
718
+ """The upper bound of the variable.
719
+
720
+ Returns:
721
+ float: the value of the upper bound.
722
+ """
723
+ return self._bounds[1]
724
+
725
+ @property
726
+ def label(self) -> str:
727
+ """the label (name) of the variable.
728
+
729
+ Returns:
730
+ string: the name of the variable.
731
+ """
732
+ return self._label
733
+
734
+ @property
735
+ def domain(self) -> Domain:
736
+ """The domain of values that the variable is allowed to take.
737
+
738
+ Returns:
739
+ Domain: The domain of the values the variable can take.
740
+ """
741
+ return self._domain
742
+
743
+ def set_bounds(self, lower_bound: float | None, upper_bound: float | None) -> None:
744
+ """set the bounds of the variable.
745
+
746
+ Args:
747
+ lower_bound (float | None): The lower bound (if None the lowest allowed bound in the variable domain is
748
+ selected). Defaults to None.
749
+ upper_bound (float | None): The upper bound (if None the highest allowed bound in the variable domain is
750
+ selected). Defaults to None.
751
+ Raises:
752
+ OutOfBoundsException: the lower bound or the upper bound don't correspond to the variable domain.
753
+ InvalidBoundsError: the lower bound is higher than the upper bound.
754
+ """
755
+ self._hash_cache = None
756
+ if lower_bound is None:
757
+ lower_bound = self._domain.min()
758
+ if upper_bound is None:
759
+ upper_bound = self._domain.max()
760
+ if not self.domain.check_value(lower_bound):
761
+ raise OutOfBoundsException(
762
+ f"the lower bound ({lower_bound}) does not respect the domain of the variable ({self.domain})"
763
+ )
764
+ if not self.domain.check_value(upper_bound):
765
+ raise OutOfBoundsException(
766
+ f"the upper bound ({upper_bound}) does not respect the domain of the variable ({self.domain})"
767
+ )
768
+ if lower_bound > upper_bound:
769
+ raise InvalidBoundsError(
770
+ f"the lower bound ({lower_bound}) should not be greater than the upper bound ({upper_bound})"
771
+ )
772
+ self._bounds = (lower_bound, upper_bound)
773
+
774
+ @abstractmethod
775
+ def num_binary_equivalent(self) -> int:
776
+ """
777
+ Returns:
778
+ int: the number of binary variables that are needed to represent this variable in the given encoding.
779
+ """
780
+
781
+ @abstractmethod
782
+ def evaluate(self, value: list[int] | RealNumber) -> RealNumber:
783
+ """Evaluates the value of the variable given a binary string or a number.
784
+
785
+ Args:
786
+ value (list[int] | int | float): the value used to evaluate the variable.
787
+ If the value provided is binary list (list[int]) then the value of the variable is evaluated based on
788
+ its binary representation. This representation is constructed using the encoding, bounds and domain
789
+ of the variable. To check the binary representation of a variable you can check the method `to_binary()`
790
+
791
+ Returns:
792
+ int | float | complex: the evaluated vale of the variable.
793
+ """
794
+
795
+ def update_variable(self, domain: Domain, bounds: tuple[float | None, float | None] = (None, None)) -> None:
796
+ """Replaces the information of the variable with those coming from the dictionary
797
+ if the variable label is in the dictionary
798
+
799
+ Args:
800
+ domain (Domain): The updated domain of the variable.
801
+ bounds (tuple[float | None, float | None]): The updated bounds of the variable. Defaults to (None, None)
802
+ """
803
+ self._hash_cache = None
804
+ self._domain = domain
805
+ self.set_bounds(bounds[0], bounds[1])
806
+
807
+ @abstractmethod
808
+ def to_binary(self) -> Term:
809
+ """Returns the binary representation of a variable.
810
+
811
+ Returns:
812
+ Term: the binary representation of a variable.
813
+ """
814
+
815
+ def __repr__(self) -> str:
816
+ return f"{self._label}"
817
+
818
+ def __str__(self) -> str:
819
+ return f"{self._label}"
820
+
821
+ def __add__(self, other: Number | BaseVariable | Term) -> Term:
822
+ if not isinstance(other, (Number, BaseVariable, Term)):
823
+ return NotImplemented
824
+ if isinstance(other, Term):
825
+ return other + self
826
+
827
+ if isinstance(other, np.generic):
828
+ other = cast("Number", other.item())
829
+
830
+ return Term(elements=[self, other], operation=Operation.ADD)
831
+
832
+ __radd__ = __add__
833
+ __iadd__ = __add__
834
+
835
+ def __mul__(self, other: Number | BaseVariable | Term) -> Term:
836
+ if not isinstance(other, (Number, BaseVariable, Term)):
837
+ return NotImplemented
838
+ if isinstance(other, Term):
839
+ return other * self
840
+
841
+ if isinstance(other, np.generic):
842
+ other = cast("Number", other.item())
843
+
844
+ return Term(elements=[self, other], operation=Operation.MUL)
845
+
846
+ def __rmul__(self, other: Number | BaseVariable | Term) -> Term:
847
+ if not isinstance(other, (Number, BaseVariable, Term)):
848
+ return NotImplemented
849
+ if isinstance(other, Term):
850
+ return other * self
851
+
852
+ if isinstance(other, np.generic):
853
+ other = cast("Number", other.item())
854
+
855
+ return Term(elements=[other, self], operation=Operation.MUL)
856
+
857
+ __imul__ = __mul__
858
+
859
+ def __sub__(self, other: Number | BaseVariable | Term) -> Term:
860
+ if not isinstance(other, (Number, BaseVariable, Term)):
861
+ return NotImplemented
862
+
863
+ if isinstance(other, np.generic):
864
+ other = cast("Number", other.item())
865
+
866
+ return self + -1 * other
867
+
868
+ def __rsub__(self, other: Number | BaseVariable | Term) -> Term:
869
+ if not isinstance(other, (Number, BaseVariable, Term)):
870
+ return NotImplemented
871
+
872
+ if isinstance(other, np.generic):
873
+ other = cast("Number", other.item())
874
+
875
+ return -1 * self + other
876
+
877
+ __isub__ = __sub__
878
+
879
+ def __neg__(self) -> Term:
880
+ return -1 * self
881
+
882
+ def __truediv__(self, other: RealNumber) -> Term:
883
+ if not isinstance(other, RealNumber):
884
+ raise NotImplementedError("Only division by real numbers is currently supported")
885
+
886
+ if abs(other) < self.TOL:
887
+ raise ValueError("Division by zero is not allowed")
888
+
889
+ if isinstance(other, np.generic):
890
+ other = cast("RealNumber", other.item())
891
+ other = 1 / other
892
+ return self * other
893
+
894
+ __itruediv__ = __truediv__
895
+
896
+ def __rtruediv__(self, other: Number | BaseVariable | Term) -> Term:
897
+ raise NotSupportedOperation("Only division by numbers is currently supported")
898
+
899
+ def __rfloordiv__(self, other: Number | BaseVariable | Term) -> Term:
900
+ raise NotSupportedOperation("Only division by numbers is currently supported")
901
+
902
+ def __pow__(self, a: int) -> Term:
903
+ out: BaseVariable | Term = copy.copy(self)
904
+
905
+ if a < 0:
906
+ raise NotImplementedError("Negative Power is not Supported.")
907
+
908
+ if a == 0:
909
+ return Term(elements=[1], operation=Operation.ADD)
910
+
911
+ for _ in range(a - 1):
912
+ out *= copy.copy(self)
913
+
914
+ if isinstance(out, BaseVariable):
915
+ out = Term(elements=[out], operation=Operation.ADD)
916
+ return out
917
+
918
+ def __hash__(self) -> int:
919
+ if self._hash_cache is None:
920
+ self._hash_cache = hash((self._label, self._domain.value, self._bounds))
921
+ return self._hash_cache
922
+
923
+ def __eq__(self, other: object) -> bool:
924
+ if not isinstance(other, BaseVariable):
925
+ return False
926
+ return hash(self) == hash(other)
927
+
928
+
929
+ @yaml.register_class
930
+ class BinaryVariable(BaseVariable):
931
+ """
932
+ Binary decision variable restricted to the set ``{0, 1}``.
933
+
934
+ Example:
935
+ .. code-block:: python
936
+
937
+ from qilisdk.core.variables import BinaryVariable
938
+
939
+ x = BinaryVariable("x")
940
+ """
941
+
942
+ def __init__(self, label: str) -> None:
943
+ super().__init__(label=label, domain=Domain.BINARY)
944
+
945
+ def num_binary_equivalent(self) -> int: # noqa: PLR6301
946
+ return 1
947
+
948
+ def evaluate(self, value: list[int] | RealNumber) -> RealNumber:
949
+ if isinstance(value, int | float):
950
+ if value in {1.0, 0.0}:
951
+ return int(value)
952
+ if not self.domain.check_value(value):
953
+ raise EvaluationError(f"Evaluating a Binary variable with a value {value} that is outside the domain.")
954
+ return value # I don't think this line is reachable
955
+ if len(value) != 1:
956
+ raise EvaluationError("Evaluating a Binary variable with a binary list of more than one item.")
957
+ return value[0]
958
+
959
+ def update_variable(self, domain: Domain, bounds: tuple[float | None, float | None] = (None, None)) -> None:
960
+ raise NotImplementedError
961
+
962
+ def to_binary(self) -> Term:
963
+ return Term([self], Operation.ADD)
964
+
965
+ def __copy__(self) -> BinaryVariable:
966
+ return BinaryVariable(label=self.label)
967
+
968
+
969
+ @yaml.register_class
970
+ class SpinVariable(BaseVariable):
971
+ """Represents Spin Variable structure."""
972
+
973
+ def __init__(self, label: str) -> None:
974
+ super().__init__(label=label, domain=Domain.SPIN, bounds=(-1, 1))
975
+
976
+ def num_binary_equivalent(self) -> int: # noqa: PLR6301
977
+ return 1
978
+
979
+ def update_variable(self, domain: Domain, bounds: tuple[float | None, float | None] = (None, None)) -> None:
980
+ raise NotImplementedError
981
+
982
+ def evaluate(self, value: list[int] | RealNumber) -> RealNumber:
983
+ if isinstance(value, Number):
984
+ if not self.domain.check_value(value) and value != 0:
985
+ raise EvaluationError(f"Evaluating a Spin variable with a value {value} that is outside the domain.")
986
+ return -1 if value in {0, -1} else 1
987
+ if len(value) != 1:
988
+ raise EvaluationError("Evaluating a Spin variable with a list of more than one item.")
989
+ return -1 if value[0] in {0, -1} else 1
990
+
991
+ def to_binary(self) -> Term:
992
+ return Term([self], Operation.ADD)
993
+
994
+ def __copy__(self) -> SpinVariable:
995
+ return SpinVariable(label=self.label)
996
+
997
+
998
+ @yaml.register_class
999
+ class Variable(BaseVariable):
1000
+ """
1001
+ Generic (possibly continuous) optimization variable with configurable encoding.
1002
+
1003
+ Example:
1004
+ .. code-block:: python
1005
+
1006
+ from qilisdk.core.variables import Domain, Variable
1007
+
1008
+ price = Variable("price", domain=Domain.REAL, bounds=(0, 10))
1009
+ binary_term = price.to_binary()
1010
+ """
1011
+
1012
+ def __init__(
1013
+ self,
1014
+ label: str,
1015
+ domain: Domain,
1016
+ bounds: tuple[float | None, float | None] = (None, None),
1017
+ encoding: type[Encoding] = Bitwise,
1018
+ precision: float = 1e-2,
1019
+ ) -> None:
1020
+ """
1021
+
1022
+ Args:
1023
+ label (str): The name of the variable.
1024
+ domain (Domain): The domain of the values this variable can take.
1025
+ bounds (tuple[float | None, float | None], optional): the bounds on the values of the variable The bounds
1026
+ have the structure (lower_bound, Upper_bound) both values included. Defaults to (None, None).
1027
+ Note: if None is selected then the lowest/highest possible value of the variable's domain is chosen.
1028
+ encoding (type[Encoding], optional): _description_. Defaults to Bitwise.
1029
+ precision (float, optional): The floating point precision for REAL variables. Defaults to 1e-2.
1030
+ """
1031
+ super().__init__(label=label, domain=domain, bounds=bounds)
1032
+ self._encoding = encoding
1033
+ self._precision = 1e-2
1034
+ self._term: Term | None = None
1035
+ self._bin_vars: list[BaseVariable] = []
1036
+ self._precision = precision
1037
+
1038
+ @property
1039
+ def encoding(self) -> type[Encoding]:
1040
+ return self._encoding
1041
+
1042
+ @property
1043
+ def precision(self) -> float:
1044
+ return self._precision
1045
+
1046
+ @property
1047
+ def term(self) -> Term:
1048
+ if self._term is None:
1049
+ if self.bounds[1] > LARGE_BOUND or self.bounds[0] < -LARGE_BOUND:
1050
+ logger.warning(
1051
+ f"Encoding variable {self.label} which has the bounds {self.bounds}"
1052
+ + "is very expensive and may take a very long time."
1053
+ )
1054
+ self._term = self.to_binary()
1055
+ return self._term
1056
+
1057
+ @property
1058
+ def bin_vars(self) -> list[BaseVariable]:
1059
+ if self._term is None:
1060
+ self.to_binary()
1061
+ return self._bin_vars
1062
+
1063
+ def set_precision(self, precision: float) -> None:
1064
+ self._precision = precision
1065
+ self._term = None
1066
+
1067
+ def __copy__(self) -> Variable:
1068
+ return Variable(label=self.label, domain=self.domain, bounds=self.bounds, encoding=self._encoding)
1069
+
1070
+ def __getitem__(self, item: int) -> BaseVariable:
1071
+ if self._term is None:
1072
+ self.to_binary()
1073
+ return self._bin_vars[item]
1074
+
1075
+ def update_variable(
1076
+ self,
1077
+ domain: Domain,
1078
+ bounds: tuple[float | None, float | None] = (None, None),
1079
+ encoding: type[Encoding] | None = None,
1080
+ ) -> None:
1081
+ self._encoding = encoding if encoding is not None else self._encoding
1082
+ self._term = None
1083
+ return super().update_variable(domain, bounds)
1084
+
1085
+ def evaluate(self, value: list[int] | RealNumber) -> RealNumber:
1086
+ if not isinstance(value, (list, RealNumber)):
1087
+ raise ValueError("Invalid Value Provided to evaluate a Variable.")
1088
+ if isinstance(value, int | float):
1089
+ if not self.domain.check_value(value):
1090
+ raise ValueError(f"The value {value} is invalid for the domain {self.domain.value}")
1091
+ if value < self.lower_bound or value > self.upper_bound:
1092
+ raise ValueError(f"The value {value} is outside the defined bounds {self.bounds}")
1093
+ return value
1094
+ return self.encoding.evaluate(self, value, self._precision)
1095
+
1096
+ def to_binary(self) -> Term:
1097
+ if self._term is None:
1098
+ term = self.encoding.encode(self, precision=self._precision)
1099
+ self._term = copy.copy(term)
1100
+ self._bin_vars = [BinaryVariable(f"{self.label}({i})") for i in range(self.num_binary_equivalent())]
1101
+ self._bin_vars = sorted(
1102
+ self._bin_vars,
1103
+ key=lambda x: _extract_number(x.label),
1104
+ )
1105
+ return self._term
1106
+
1107
+ def num_binary_equivalent(self) -> int:
1108
+ """
1109
+ Returns:
1110
+ int: the number of binary variables needed to encode the continuous variable.
1111
+ """
1112
+ return self.encoding.num_binary_equivalent(self, precision=self._precision)
1113
+
1114
+ def check_valid(self, binary_list: list[int]) -> tuple[bool, int]:
1115
+ """checks if the binary list sample is a valid sample in the variable's encoding.
1116
+
1117
+ Args:
1118
+ binary_list (list[int] | int): a list of binary values or an integer value.
1119
+
1120
+ Returns:
1121
+ tuple[bool, int]: the boolean is True if the sample is a valid encoding,
1122
+ and the integer is the error in the encoding.
1123
+ """
1124
+ return self.encoding.check_valid(binary_list)
1125
+
1126
+ def encoding_constraint(self) -> ComparisonTerm:
1127
+ """Given a continuous variable return a Comparison Term that ensures that the encoding is respected.
1128
+
1129
+ Returns:
1130
+ ComparisonTerm: a Comparison Term that ensures the encoding is respected.
1131
+ """
1132
+ return self.encoding.encoding_constraint(self, precision=self._precision)
1133
+
1134
+
1135
+ @yaml.register_class(shared=True)
1136
+ class Parameter(BaseVariable):
1137
+ """
1138
+ Symbolic scalar used to parametrize expressions while remaining differentiable.
1139
+
1140
+ Example:
1141
+ .. code-block:: python
1142
+
1143
+ from qilisdk.core.variables import Parameter
1144
+
1145
+ theta = Parameter("theta", value=0.5)
1146
+ theta.set_value(0.75)
1147
+ """
1148
+
1149
+ def __init__(
1150
+ self,
1151
+ label: str,
1152
+ value: RealNumber,
1153
+ domain: Domain = Domain.REAL,
1154
+ bounds: tuple[float | None, float | None] = (None, None),
1155
+ ) -> None:
1156
+ super().__init__(label=label, domain=domain, bounds=bounds)
1157
+
1158
+ if not self.domain.check_value(value):
1159
+ raise ValueError(
1160
+ f"Parameter value provided ({value}) doesn't correspond to the parameter's domain ({self.domain.name})"
1161
+ )
1162
+ self._value = value
1163
+ self.set_bounds(bounds[0], bounds[1])
1164
+
1165
+ @property
1166
+ def value(self) -> RealNumber:
1167
+ return self._value
1168
+
1169
+ def check_value(self, value: RealNumber) -> None:
1170
+ if not self.domain.check_value(value):
1171
+ raise ValueError(
1172
+ f"Parameter value provided ({value}) doesn't correspond to the parameter's domain ({self.domain.name})"
1173
+ )
1174
+ if value > self.bounds[1] or value < self.bounds[0]:
1175
+ raise ValueError(f"The value provided ({value}) is outside the bound of the parameter {self.bounds}")
1176
+
1177
+ def set_value(self, value: RealNumber) -> None:
1178
+ self.check_value(value)
1179
+
1180
+ if isinstance(value, np.generic):
1181
+ value = cast("RealNumber", value.item())
1182
+ self._value = value
1183
+
1184
+ def num_binary_equivalent(self) -> int: # noqa: PLR6301
1185
+ """
1186
+ Returns:
1187
+ int: the number of binary variables that are needed to represent this variable in the given encoding.
1188
+ """
1189
+ return 0
1190
+
1191
+ def evaluate(self, value: list[int] | RealNumber | None = None) -> RealNumber:
1192
+ """Evaluates the value of the variable given a binary string or a number.
1193
+
1194
+ Args:
1195
+ value (list[int] | int | float): the value used to evaluate the variable.
1196
+ If the value provided is binary list (list[int]) then the value of the variable is evaluated based on
1197
+ its binary representation. This representation is constructed using the encoding, bounds and domain
1198
+ of the variable. To check the binary representation of a variable you can check the method `to_binary()`
1199
+
1200
+ Returns:
1201
+ float: the evaluated vale of the variable.
1202
+ """
1203
+ if value is not None:
1204
+ if isinstance(value, RealNumber):
1205
+ self.check_value(value)
1206
+ return value
1207
+ raise NotImplementedError("Evaluating the value of a parameter with a list is not supported.")
1208
+ return self.value
1209
+
1210
+ def to_binary(self) -> Term:
1211
+ """Returns the binary representation of a variable.
1212
+
1213
+ Returns:
1214
+ Term: the binary representation of a variable.
1215
+ """
1216
+ return Term([self.value], operation=Operation.ADD)
1217
+
1218
+ def set_bounds(self, lower_bound: float | None, upper_bound: float | None) -> None:
1219
+ upper_bound = upper_bound if upper_bound is not None else self.domain.max()
1220
+ lower_bound = lower_bound if lower_bound is not None else self.domain.min()
1221
+ if self.value > upper_bound or self.value < lower_bound:
1222
+ raise ValueError(
1223
+ f"The current value of the parameter ({self.value}) is outside the bounds ({lower_bound}, {upper_bound})"
1224
+ )
1225
+ super().set_bounds(lower_bound, upper_bound)
1226
+
1227
+ def update_variable(self, domain: Domain, bounds: tuple[float | None, float | None] = (None, None)) -> None:
1228
+ if len(bounds) != 2: # noqa: PLR2004
1229
+ raise ValueError(
1230
+ "Invalid bounds provided: the bounds need to be a tuple with the format (lower_bound, upper_bound)"
1231
+ )
1232
+
1233
+ if domain.check_value(self.value):
1234
+ self._domain = domain
1235
+ else:
1236
+ raise ValueError(
1237
+ f"The provided domain ({domain.name}) is incompatible with the current parameter value ({self.value})"
1238
+ )
1239
+
1240
+ self.set_bounds(lower_bound=bounds[0], upper_bound=bounds[1])
1241
+
1242
+ __hash__ = BaseVariable.__hash__
1243
+
1244
+ def __eq__(self, other: object) -> bool:
1245
+ if isinstance(other, BaseVariable):
1246
+ return super().__eq__(other)
1247
+ if isinstance(other, (float, int)):
1248
+ return self.value == other
1249
+ return False
1250
+
1251
+ def __le__(self, other: object) -> bool:
1252
+ if isinstance(other, (float, int)):
1253
+ return self.value <= other
1254
+ return NotImplemented
1255
+
1256
+ def __lt__(self, other: object) -> bool:
1257
+ if isinstance(other, (float, int)):
1258
+ return self.value < other
1259
+ return NotImplemented
1260
+
1261
+ def __ge__(self, other: object) -> bool:
1262
+ if isinstance(other, (float, int)):
1263
+ return self.value >= other
1264
+ return NotImplemented
1265
+
1266
+ def __gt__(self, other: object) -> bool:
1267
+ if isinstance(other, (float, int)):
1268
+ return self.value > other
1269
+ return NotImplemented
1270
+
1271
+
1272
+ # Terms ###
1273
+
1274
+
1275
+ @yaml.register_class
1276
+ class Term:
1277
+ """Represents a mathematical Term (e.g. 3x*y, 2x, ...).
1278
+
1279
+ And they are built from:
1280
+ - ``Variable``'s: The decision variables of the model (x, y, ...).
1281
+ - Other ``Term``'s: Allowing for complex expressions to be constructed.
1282
+ """
1283
+
1284
+ CONST = Variable(CONST_KEY, Domain.REAL)
1285
+ TOL = get_settings().atol
1286
+
1287
+ def __init__(self, elements: Sequence[BaseVariable | Term | Number], operation: Operation) -> None:
1288
+ """initialize a new term object.
1289
+
1290
+ Args:
1291
+ elements (Sequence[BaseVariable | Term | Number]): a list of elements in the term.
1292
+ operation (Operation): the mathematical operation between these elements.
1293
+
1294
+ Raises:
1295
+ ValueError: if the items inside elements are not from the listed types (BaseVariable | Term | Number).
1296
+ """
1297
+ self._operation = operation
1298
+ self._elements: dict[BaseVariable | Term, Number] = {} # The list of elements in the term.
1299
+ # key: the term or variable | value: the coefficient corresponding to that value.
1300
+ for e in elements:
1301
+ if isinstance(e, BaseVariable):
1302
+ if e in self:
1303
+ if self._is_constant(e):
1304
+ self[e] = self._apply_operation_on_constants([self[e], 1])
1305
+ elif isinstance(e, BinaryVariable) and self.operation == Operation.MUL:
1306
+ self[e] = 1
1307
+ else:
1308
+ self[e] += 1
1309
+ else:
1310
+ self[e] = 1
1311
+ elif isinstance(e, Number):
1312
+ if self.CONST in self:
1313
+ self[self.CONST] = self._apply_operation_on_constants([self[self.CONST], e])
1314
+ else:
1315
+ self[self.CONST] = e
1316
+ elif isinstance(e, Term):
1317
+ if len(e) == 0:
1318
+ if self.CONST in self:
1319
+ self[self.CONST] = self._apply_operation_on_constants([self[self.CONST], 0])
1320
+ else:
1321
+ self[self.CONST] = 0
1322
+ elif e.operation == self._operation:
1323
+ for key in e:
1324
+ if key in self:
1325
+ if isinstance(key, BaseVariable) and self._is_constant(key):
1326
+ self[key] = self._apply_operation_on_constants([self[key], e[key]])
1327
+ elif isinstance(key, BinaryVariable) and self.operation == Operation.MUL:
1328
+ self[key] = 1
1329
+ else:
1330
+ self[key] += e[key]
1331
+ else:
1332
+ self[key] = e[key]
1333
+ else:
1334
+ e_copy = copy.copy(e)
1335
+ coeff = complex(1.0)
1336
+ if e_copy.operation == Operation.MUL and self.CONST in e_copy:
1337
+ coeff = e_copy.pop(self.CONST)
1338
+ simple_e = e_copy._simplify() # noqa: SLF001
1339
+ simple_e = self.CONST if isinstance(simple_e, Term) and len(simple_e) == 0 else simple_e
1340
+ if simple_e in self:
1341
+ if isinstance(simple_e, BaseVariable) and self._is_constant(simple_e):
1342
+ self[simple_e] = self._apply_operation_on_constants([self[simple_e], coeff])
1343
+ else:
1344
+ self[simple_e] += coeff
1345
+ else:
1346
+ self[simple_e] = coeff
1347
+ else:
1348
+ raise ValueError(
1349
+ f"Term accepts object of types Term or Variable but an object of type {e.__class__} was given"
1350
+ )
1351
+ self._remove_zeros()
1352
+
1353
+ @property
1354
+ def operation(self) -> Operation:
1355
+ """
1356
+ Returns:
1357
+ Operation: the operation between the term's elements.
1358
+ """
1359
+ return self._operation
1360
+
1361
+ @property
1362
+ def degree(self) -> int:
1363
+ """
1364
+ Returns:
1365
+ int: the highest degree in the term.
1366
+ """
1367
+ degree = 0
1368
+ if self.operation == Operation.MUL:
1369
+ for element in self:
1370
+ if isinstance(element, Term):
1371
+ degree += element.degree
1372
+ elif isinstance(element, BaseVariable) and not self._is_constant(element):
1373
+ degree += int(_assert_real(self[element]))
1374
+ return degree
1375
+
1376
+ for element in self:
1377
+ if isinstance(element, Term):
1378
+ degree = max(degree, element.degree)
1379
+ elif isinstance(element, BaseVariable) and not self._is_constant(element):
1380
+ degree = max(degree, 1)
1381
+ return degree
1382
+
1383
+ def to_binary(self) -> Term:
1384
+ """Returns the term in binary format. That is encoding all continuous variables into
1385
+ binary according to the encoding defined in the variable.
1386
+
1387
+ Raises:
1388
+ ValueError: The term contains operations that are not addition or multiplication.
1389
+ ValueError: the term contains an element that is not a Term or a BaseVariable.
1390
+
1391
+ Returns:
1392
+ Term: the term after transforming all the variables into binary.
1393
+ """
1394
+ if self.operation not in {Operation.ADD, Operation.MUL}:
1395
+ raise ValueError("Can not evaluate any operation that is not Addition of Multiplication")
1396
+ out_list: list[BaseVariable | Term | Number] = []
1397
+ for e in self:
1398
+ if isinstance(e, Term):
1399
+ out_list.append(self[e] * e.to_binary())
1400
+ elif isinstance(e, BaseVariable):
1401
+ if self._is_constant(e):
1402
+ out_list.append(self[e])
1403
+ elif isinstance(e, Variable):
1404
+ x = e.to_binary()
1405
+ if self.operation == Operation.MUL:
1406
+ out_list.append(x ** int(_assert_real(self[e])))
1407
+ else:
1408
+ out_list.append(self[e] * x)
1409
+ else:
1410
+ out_list.append(self[e] * e)
1411
+ else:
1412
+ raise ValueError(f"Evaluating term with elements of type {e.__class__} is not supported.")
1413
+
1414
+ return Term(out_list, self.operation)
1415
+
1416
+ def _apply_operation_on_constants(self, const_list: list[Number]) -> Number:
1417
+ out = complex(const_list[0])
1418
+ for i in range(1, len(const_list)):
1419
+ if self.operation is Operation.ADD:
1420
+ out += const_list[i]
1421
+ elif self.operation is Operation.SUB:
1422
+ out -= const_list[i]
1423
+ elif self.operation is Operation.MUL:
1424
+ out *= const_list[i]
1425
+ elif self.operation is Operation.DIV:
1426
+ out /= const_list[i]
1427
+
1428
+ return out
1429
+
1430
+ def variables(self) -> list[BaseVariable]:
1431
+ """Returns the unique list of variables in the Term
1432
+
1433
+ Returns:
1434
+ list[Variable]: The unique list of variables in the Term.
1435
+ """
1436
+ var = set()
1437
+ for e in self:
1438
+ if isinstance(e, BaseVariable) and not self._is_constant(e):
1439
+ var.add(e)
1440
+ elif isinstance(e, Term):
1441
+ var.update(e.variables())
1442
+ return sorted(var, key=lambda x: x.label)
1443
+
1444
+ def _simplify(self) -> Term | BaseVariable:
1445
+ """Simplify the term object.
1446
+
1447
+ Returns:
1448
+ (Term | BaseVariable): the simplified term.
1449
+ """
1450
+ if len(self) == 1 and not isinstance(self, MathematicalMap):
1451
+ item = next(iter(self._elements.keys()))
1452
+ if self._elements[item] == 1:
1453
+ return item
1454
+ return self
1455
+
1456
+ def pop(self, item: BaseVariable | Term) -> Number:
1457
+ """Remove an item from the term.
1458
+
1459
+ Args:
1460
+ item (BaseVariable | Term): the item to be removed.
1461
+
1462
+ Raises:
1463
+ KeyError: if item is not in the term.
1464
+
1465
+ Returns:
1466
+ Number: the coefficient of the removed item.
1467
+ """
1468
+ try:
1469
+ return self._elements.pop(item)
1470
+ except KeyError as e:
1471
+ raise KeyError(f'item "{item}" not found in the term.') from e
1472
+
1473
+ def _is_constant(self, variable: BaseVariable) -> bool:
1474
+ """Checks if the variable is a constant variable as defined by the Term class.
1475
+
1476
+ Args:
1477
+ variable (BaseVariable): the variable to be checked.
1478
+
1479
+ Returns:
1480
+ bool: True if the variable is a constant, False otherwise.
1481
+ """
1482
+ return variable == self.CONST
1483
+
1484
+ def to_list(self) -> list[BaseVariable | Term | Number]:
1485
+ """Exports the current term into a list of its elements.
1486
+
1487
+ Returns:
1488
+ list[BaseVariable | Term | Number]: A list of the elements inside the term.
1489
+ """
1490
+ out_list: list[BaseVariable | Term | Number] = []
1491
+ for e in self:
1492
+ if isinstance(e, BaseVariable) and self._is_constant(e):
1493
+ out_list.append(self[e])
1494
+ elif self.operation == Operation.MUL:
1495
+ for _ in range(int(_assert_real(self[e]))):
1496
+ out_list.append(e)
1497
+ else:
1498
+ out_list.append(self[e] * e if self[e] != 1 else e)
1499
+ return out_list
1500
+
1501
+ def _unfold_parentheses(self) -> Term:
1502
+ """Simplifies any parentheses in the term expression.
1503
+
1504
+ Returns:
1505
+ Term: A new term with a more simplified form.
1506
+ """
1507
+ out = copy.copy(self)
1508
+ if out.operation != Operation.MUL:
1509
+ return out
1510
+
1511
+ parentheses: list[tuple[Term, Number]] = []
1512
+
1513
+ for e in out:
1514
+ if isinstance(e, Term) and e.operation == Operation.ADD:
1515
+ parentheses.append((copy.copy(e), out[e]))
1516
+
1517
+ for term, _ in parentheses:
1518
+ out.pop(term)
1519
+
1520
+ if len(out) == 0 and len(parentheses) != 0:
1521
+ out = Term([1], Operation.ADD)
1522
+
1523
+ for _term, coeff in parentheses:
1524
+ term = copy.copy(_term)
1525
+ _coeff = _assert_real(coeff)
1526
+ if _coeff > 1:
1527
+ term **= int(_coeff)
1528
+ final_out = []
1529
+ for t in term:
1530
+ final_out.append(t * out * term[t])
1531
+ out = Term(final_out, Operation.ADD)
1532
+
1533
+ return out
1534
+
1535
+ def _remove_zeros(self) -> None:
1536
+ """Simplifies any un-necessary zeros from terms."""
1537
+ to_be_popped = []
1538
+ if self.operation == Operation.MUL and self.CONST in self and self[self.CONST] == 0:
1539
+ l = len(self)
1540
+ for _ in range(l):
1541
+ self._elements.popitem()
1542
+ for e in self:
1543
+ if self[e] == 0:
1544
+ to_be_popped.append(e)
1545
+ for p in to_be_popped:
1546
+ self._elements.pop(p)
1547
+
1548
+ def evaluate(self, var_values: Mapping[BaseVariable, list[int] | RealNumber]) -> Number:
1549
+ """Evaluates the term given a set of values for the variables in the term.
1550
+
1551
+ Args:
1552
+ var_values (Mapping[BaseVariable, list[int] | Number]): the values of the variables in the term.
1553
+ If the value provided is binary list (list[int]) then the value of the variable is evaluated based on
1554
+ its binary representation. This representation is constructed using the encoding, bounds and domain
1555
+ of the variable. To check the binary representation of a variable you can check the method `to_binary()`
1556
+
1557
+ Raises:
1558
+ ValueError: if not all variables in the term are provided a value.
1559
+
1560
+ Returns:
1561
+ float: the result from evaluating the term.
1562
+ """
1563
+ if len(self._elements) == 0:
1564
+ return 0
1565
+ _var_values = dict(var_values)
1566
+ for var in self.variables():
1567
+ if isinstance(var, Parameter):
1568
+ if var not in _var_values:
1569
+ _var_values[var] = var.value
1570
+ else:
1571
+ value = _var_values[var]
1572
+ if not isinstance(value, RealNumber):
1573
+ raise ValueError(f"setting a parameter ({var}) value with a list is not supported.")
1574
+ # var.set_value(value)
1575
+ if var not in _var_values:
1576
+ raise ValueError(f"Can not evaluate term because the value of the variable {var} is not provided.")
1577
+ output = complex(0.0) if self.operation in {Operation.ADD, Operation.SUB} else complex(1.0)
1578
+ for e in self:
1579
+ if isinstance(e, Term):
1580
+ output = self._apply_operation_on_constants([output, e.evaluate(_var_values) * self[e]])
1581
+ elif isinstance(e, BaseVariable):
1582
+ if e == self.CONST:
1583
+ output = self._apply_operation_on_constants([output, self[e]])
1584
+ elif self.operation == Operation.MUL:
1585
+ output = self._apply_operation_on_constants([output, e.evaluate(_var_values[e]) ** self[e]])
1586
+ else:
1587
+ output = self._apply_operation_on_constants([output, e.evaluate(_var_values[e]) * self[e]])
1588
+ if isinstance(output, RealNumber):
1589
+ return float(output)
1590
+ if isinstance(output, complex) and abs(output.imag) < self.TOL:
1591
+ return float(output.real)
1592
+ return output
1593
+
1594
+ def get_constant(self) -> Number:
1595
+ """
1596
+ Returns:
1597
+ Number: The constant value of the term.
1598
+ """
1599
+ if self.CONST in self:
1600
+ return self[self.CONST]
1601
+ return 0 if self.operation in {Operation.ADD, Operation.SUB} else 1
1602
+
1603
+ def is_parameterized_term(self) -> bool:
1604
+ return all(isinstance(var, Parameter) for var in self.variables())
1605
+
1606
+ def __copy__(self) -> Term:
1607
+ return Term(copy.copy(self.to_list()), copy.copy(self.operation))
1608
+
1609
+ def __repr__(self) -> str:
1610
+ if len(self) == 0:
1611
+ return "0"
1612
+ output_string = ""
1613
+ const = self.get_constant()
1614
+ keys = list(self._elements.keys())
1615
+
1616
+ if (
1617
+ (self.operation in {Operation.ADD, Operation.SUB} and const == 0)
1618
+ or (self.operation in {Operation.MUL, Operation.DIV} and const == 1)
1619
+ ) and Term.CONST in keys:
1620
+ keys.remove(Term.CONST)
1621
+
1622
+ for i, e in enumerate(keys):
1623
+ if isinstance(e, Term):
1624
+ term_str = str(e).strip()
1625
+ if len(term_str) > 0:
1626
+ if term_str[0] == "(" and term_str[-1] == ")":
1627
+ term_str = term_str.removeprefix("(").removesuffix(")")
1628
+ output_string += (
1629
+ f"({term_str}) " if self[e] == 1 else f"({_float_if_real(self[e])}) * ({term_str}) "
1630
+ )
1631
+ elif isinstance(e, BaseVariable):
1632
+ if self._is_constant(e):
1633
+ output_string += f"({_float_if_real(self[e])}) "
1634
+ elif (self.operation is Operation.MUL or self.operation is Operation.DIV) and _assert_real(self[e]) > 1:
1635
+ output_string += f"({e}^{_float_if_real(self[e])}) "
1636
+ else:
1637
+ output_string += f"{e} " if self[e] == 1 else f"({_float_if_real(self[e])}) * {e} "
1638
+ else:
1639
+ output_string += f"{e} "
1640
+ if i < len(keys) - 1:
1641
+ output_string += f"{self.operation.value} "
1642
+
1643
+ return output_string.strip()
1644
+
1645
+ __str__ = __repr__
1646
+
1647
+ def __getitem__(self, item: BaseVariable | Term) -> Number:
1648
+ return self._elements[item]
1649
+
1650
+ def __setitem__(self, key: BaseVariable | Term, item: Number) -> None:
1651
+ self._elements[key] = item
1652
+
1653
+ def __iter__(self) -> Iterator[BaseVariable | Term]:
1654
+ yield from self._elements
1655
+
1656
+ def __contains__(self, item: BaseVariable | Term) -> bool:
1657
+ return item in self._elements
1658
+
1659
+ __next__ = __iter__
1660
+
1661
+ def __len__(self) -> int:
1662
+ return len(self._elements)
1663
+
1664
+ def __add__(self, other: Number | BaseVariable | Term) -> Term:
1665
+ if not isinstance(other, (Number, BaseVariable, Term)):
1666
+ return NotImplemented
1667
+ out = self.to_list() if self.operation == Operation.ADD else [copy.copy(self)]
1668
+
1669
+ if isinstance(other, np.generic):
1670
+ other = cast("Number", other.item())
1671
+
1672
+ out.append(other)
1673
+ return Term(out, Operation.ADD)
1674
+
1675
+ __iadd__ = __add__
1676
+
1677
+ def __radd__(self, other: Number | BaseVariable | Term) -> Term:
1678
+ if not isinstance(other, (Number, BaseVariable, Term)):
1679
+ return NotImplemented
1680
+ out = self.to_list() if self.operation == Operation.ADD else [copy.copy(self)]
1681
+
1682
+ if isinstance(other, np.generic):
1683
+ other = cast("Number", other.item())
1684
+ out.insert(0, other)
1685
+ return Term(out, Operation.ADD)
1686
+
1687
+ def __mul__(self, other: Number | BaseVariable | Term) -> Term:
1688
+ if not isinstance(other, (Number, BaseVariable, Term)):
1689
+ return NotImplemented
1690
+ out = self.to_list() if self.operation == Operation.MUL else [copy.copy(self)]
1691
+ if len(out) == 0:
1692
+ out = [0]
1693
+
1694
+ if isinstance(other, np.generic):
1695
+ other = cast("Number", other.item())
1696
+
1697
+ out.append(other)
1698
+ return Term(out, Operation.MUL)._unfold_parentheses()
1699
+
1700
+ __imul__ = __mul__
1701
+
1702
+ def __rmul__(self, other: Number | BaseVariable | Term) -> Term:
1703
+ if not isinstance(other, (Number, BaseVariable, Term)):
1704
+ return NotImplemented
1705
+ out = self.to_list() if self.operation == Operation.MUL else [copy.copy(self)]
1706
+ if len(out) == 0:
1707
+ out = [0]
1708
+
1709
+ if isinstance(other, np.generic):
1710
+ other = cast("Number", other.item())
1711
+
1712
+ out.insert(0, other)
1713
+ return Term(out, Operation.MUL)._unfold_parentheses()
1714
+
1715
+ def __neg__(self) -> Term:
1716
+ return -1 * self
1717
+
1718
+ def __sub__(self, other: Number | BaseVariable | Term) -> Term:
1719
+ if not isinstance(other, (Number, BaseVariable, Term)):
1720
+ return NotImplemented
1721
+
1722
+ if isinstance(other, np.generic):
1723
+ other = cast("Number", other.item())
1724
+
1725
+ return self + -1 * other
1726
+
1727
+ def __rsub__(self, other: Number | BaseVariable | Term) -> Term:
1728
+ if not isinstance(other, (Number, BaseVariable, Term)):
1729
+ return NotImplemented
1730
+ return -1 * self + other
1731
+
1732
+ __isub__ = __sub__
1733
+
1734
+ def __truediv__(self, other: Number) -> Term:
1735
+ if not isinstance(other, Number):
1736
+ raise NotImplementedError("Only division by numbers is currently supported")
1737
+
1738
+ if abs(other) < self.TOL:
1739
+ raise ValueError("Division by zero is not allowed")
1740
+
1741
+ other = 1 / other
1742
+ return self * other
1743
+
1744
+ __itruediv__ = __truediv__
1745
+
1746
+ def __rtruediv__(self, other: Number | BaseVariable | Term) -> Term:
1747
+ raise NotSupportedOperation("Only division by numbers is currently supported")
1748
+
1749
+ def __rfloordiv__(self, other: Number | BaseVariable | Term) -> Term:
1750
+ raise NotSupportedOperation("Only division by numbers is currently supported")
1751
+
1752
+ def __pow__(self, a: int) -> Term:
1753
+ if not isinstance(a, int):
1754
+ raise ValueError(f"Only integer exponents are allowed, but provided {type(a)}")
1755
+ if self.operation == Operation.ADD:
1756
+ out = copy.copy(self)
1757
+ for _ in range(a - 1):
1758
+ out_list = []
1759
+ for element in self:
1760
+ out_list.append(out * copy.copy(element) * self[element])
1761
+ out = Term(out_list, Operation.ADD)
1762
+ return out
1763
+ if self.operation == Operation.MUL:
1764
+ out = copy.copy(self)
1765
+ for element in out:
1766
+ if element is Term.CONST:
1767
+ out[element] **= a
1768
+ else:
1769
+ out[element] *= a
1770
+ return out
1771
+ raise NotImplementedError(
1772
+ "The power operation for terms that are not addition or multiplication is not supported."
1773
+ )
1774
+
1775
+ def __hash__(self) -> int:
1776
+ return hash((frozenset(self._elements.items()), self.operation))
1777
+
1778
+ def __eq__(self, other: object) -> bool:
1779
+ if not isinstance(other, Term):
1780
+ return False
1781
+ return hash(self) == hash(other)
1782
+
1783
+
1784
+ @yaml.register_class
1785
+ class ComparisonTerm:
1786
+ """Represents a mathematical comparison Term, that can be an equality or an inequality between two ``Term`` objects
1787
+ (e.g. x+y>0, x>2, ...).
1788
+
1789
+ They are built from a left and a right hand part, each of which can contain:
1790
+ - ``Variable``'s: The decision variables of the model (x, y, ...).
1791
+ - Other ``Term``'s: Allowing for complex expressions to be constructed (x+y, ...)
1792
+ """
1793
+
1794
+ def __init__(
1795
+ self,
1796
+ lhs: RealNumber | BaseVariable | Term,
1797
+ rhs: RealNumber | BaseVariable | Term,
1798
+ operation: ComparisonOperation,
1799
+ ) -> None:
1800
+ """Initializes a new comparison term.
1801
+
1802
+ Args:
1803
+ lhs (RealNumber | BaseVariable | Term): the left hand side of the comparison term.
1804
+ rhs (RealNumber | BaseVariable | Term): the right hand side of the comparison term.
1805
+ operation (ComparisonOperation): the comparison operations between the left and right hand sides.
1806
+ """
1807
+ term = lhs - rhs
1808
+ if not isinstance(term, Term):
1809
+ term = Term([term], Operation.ADD)
1810
+ const = -1 * term.pop(Term.CONST) if Term.CONST in term else 0
1811
+ self._lhs = term
1812
+ self._rhs = Term([const], Operation.ADD)
1813
+ self._operation = operation
1814
+
1815
+ @property
1816
+ def operation(self) -> ComparisonOperation:
1817
+ """
1818
+ Returns:
1819
+ ComparisonOperation: the comparison operation between the left and right hand sides.
1820
+ """
1821
+ return self._operation
1822
+
1823
+ @property
1824
+ def lhs(self) -> Term:
1825
+ """
1826
+ Returns:
1827
+ Term: the left hand side of the comparison term.
1828
+ """
1829
+ return self._lhs
1830
+
1831
+ @property
1832
+ def rhs(self) -> Term:
1833
+ """
1834
+ Returns:
1835
+ Term: the right hand side of the comparison term.
1836
+ """
1837
+ return self._rhs
1838
+
1839
+ def variables(self) -> list[BaseVariable]:
1840
+ """Returns the unique list of variables in the Term
1841
+
1842
+ Returns:
1843
+ list[Variable]: The unique list of variables in the Term.
1844
+ """
1845
+ lhs_var = self._lhs.variables()
1846
+ rhs_var = self._rhs.variables()
1847
+
1848
+ var = set()
1849
+ var.update(lhs_var)
1850
+ var.update(rhs_var)
1851
+
1852
+ return sorted(var, key=lambda x: x.label)
1853
+
1854
+ @property
1855
+ def degree(self) -> int:
1856
+ """
1857
+ Returns:
1858
+ int: the maximum degree in the left and right hand sides of the comparison term.
1859
+ """
1860
+ return max(self.rhs.degree, self.lhs.degree)
1861
+
1862
+ def to_list(self) -> list:
1863
+ """Exports the comparison term into a list. The elements of the right hand side are first moved to the left hand
1864
+ side before the generation of the list. Therefore, you can assume that the right hand side will be zero.
1865
+
1866
+ Returns:
1867
+ list: a list constructed from all the elements in the left and right hand sides of the comparison term.
1868
+ """
1869
+ logger.info(
1870
+ "to_list(): The elements of output list assume the comparison term has been transformed "
1871
+ + f"from (lhs {self.operation.value} rhs) to (lhs - rhs {self.operation.value} 0).",
1872
+ )
1873
+ out = self.lhs.to_list()
1874
+ out.extend((-1 * self.rhs).to_list())
1875
+ return out
1876
+
1877
+ def to_binary(self) -> ComparisonTerm:
1878
+ """Returns the comparison term in binary format. That is encoding all continuous variables into
1879
+ binary according to the encoding defined in the variable.
1880
+
1881
+ Returns:
1882
+ ComparisonTerm: the comparison term after transforming all the variables into binary.
1883
+ """
1884
+ return ComparisonTerm(rhs=self.rhs.to_binary(), lhs=self.lhs.to_binary(), operation=self.operation)
1885
+
1886
+ def _apply_comparison_operation(self, v1: RealNumber, v2: RealNumber) -> bool:
1887
+ """Compare two arguments.
1888
+
1889
+ Args:
1890
+ v1 (Number): the left hand side value.
1891
+ v2 (Number): the right hand side value.
1892
+
1893
+ Raises:
1894
+ ValueError: if the comparison term's operation is invalid.
1895
+
1896
+ Returns:
1897
+ bool: the result of the comparison between v1 and v2 assuming the
1898
+ comparison operation of the comparison term object.
1899
+ """
1900
+ if self.operation is ComparisonOperation.EQ:
1901
+ return v1 == v2
1902
+ if self.operation is ComparisonOperation.GEQ:
1903
+ return v1 >= v2
1904
+ if self.operation is ComparisonOperation.GT:
1905
+ return v1 > v2
1906
+ if self.operation is ComparisonOperation.LEQ:
1907
+ return v1 <= v2
1908
+ if self.operation is ComparisonOperation.LT:
1909
+ return v1 < v2
1910
+ if self.operation is ComparisonOperation.NEQ:
1911
+ return v1 != v2
1912
+ raise ValueError(f"Unsupported Operation of type {self.operation.value}")
1913
+
1914
+ def evaluate(self, var_values: Mapping[BaseVariable, RealNumber | list[int]]) -> bool:
1915
+ """Evaluates the comparison term given a set of values for the variables in the term.
1916
+
1917
+ Args:
1918
+ var_values (Mapping[BaseVariable, list[int] | RealNumber]): the values of the variables in the comparison term.
1919
+
1920
+ Returns:
1921
+ bool: the result from evaluating the comparison term.
1922
+
1923
+ Raises:
1924
+ ValueError: if the constraint contains imaginary numbers.
1925
+ """
1926
+ lhs = self._lhs.evaluate(var_values)
1927
+ rhs = self._rhs.evaluate(var_values)
1928
+ if isinstance(lhs, complex):
1929
+ if abs(lhs.imag) > get_settings().atol:
1930
+ raise ValueError("evaluating inequality constraints with complex values is not allowed")
1931
+ lhs = lhs.real
1932
+ if isinstance(rhs, complex):
1933
+ if abs(rhs.imag) > get_settings().atol:
1934
+ raise ValueError("evaluating inequality constraints with complex values is not allowed")
1935
+ rhs = rhs.real
1936
+ return self._apply_comparison_operation(lhs, rhs)
1937
+
1938
+ def __copy__(self) -> ComparisonTerm:
1939
+ return ComparisonTerm(rhs=copy.copy(self.rhs), lhs=copy.copy(self.lhs), operation=self.operation)
1940
+
1941
+ def __repr__(self) -> str:
1942
+ return f"{str(self.lhs).strip()} {self.operation.value} {str(self.rhs).strip()}"
1943
+
1944
+ __str__ = __repr__
1945
+
1946
+ def __bool__(self) -> bool:
1947
+ raise TypeError(
1948
+ "Symbolic Constraint Term objects do not have an inherent truth value. "
1949
+ "Use a method like .evaluate() to obtain a Boolean value."
1950
+ )
1951
+
1952
+ def __hash__(self) -> int:
1953
+ return hash((hash(self._lhs), self.operation, hash(self._rhs)))
1954
+
1955
+ def __eq__(self, other: object) -> bool:
1956
+ if not isinstance(other, ComparisonTerm):
1957
+ return False
1958
+ return hash(self) == hash(other)
1959
+
1960
+
1961
+ class MathematicalMap(Term, ABC):
1962
+ """Base class for applying a mathematical map (e.g., sin, cos) to a single term or parameter."""
1963
+
1964
+ MATH_SYMBOL = ""
1965
+
1966
+ @overload
1967
+ def __init__(self, arg: Term, /) -> None: ...
1968
+ @overload
1969
+ def __init__(self, arg: Parameter, /) -> None: ...
1970
+ @overload
1971
+ def __init__(self, arg: BaseVariable, /) -> None: ...
1972
+
1973
+ def __init__(self, arg: Term | Parameter | BaseVariable) -> None:
1974
+ if isinstance(arg, Term):
1975
+ self._initialize_with_term(arg)
1976
+ elif isinstance(arg, Parameter):
1977
+ self._initialize_with_parameter(arg)
1978
+ elif isinstance(arg, BaseVariable):
1979
+ self._initialize_with_variable(arg)
1980
+ else:
1981
+ raise TypeError("Sin expects Term | Parameter | BaseVariable")
1982
+
1983
+ def _initialize_with_term(self, term: Term) -> None:
1984
+ super().__init__(elements=[term], operation=Operation.MATH_MAP)
1985
+
1986
+ def _initialize_with_parameter(self, parameter: Parameter) -> None:
1987
+ super().__init__(elements=[parameter], operation=Operation.MATH_MAP)
1988
+
1989
+ def _initialize_with_variable(self, variable: BaseVariable) -> None:
1990
+ super().__init__(elements=[variable], operation=Operation.MATH_MAP)
1991
+
1992
+ @abstractmethod
1993
+ def _apply_mathematical_map(self, value: Number) -> Number: ...
1994
+
1995
+ def evaluate(self, var_values: Mapping[BaseVariable, list[int] | RealNumber]) -> Number:
1996
+ value: Number = 0
1997
+
1998
+ for e in self:
1999
+ if e not in var_values and isinstance(e, Parameter):
2000
+ aux: Number = e.evaluate()
2001
+ else:
2002
+ aux = e.evaluate(var_values) if isinstance(e, Term) else e.evaluate(var_values[e])
2003
+
2004
+ value += aux * self[e]
2005
+
2006
+ return self._apply_mathematical_map(value)
2007
+
2008
+ def __repr__(self) -> str:
2009
+ return f"{self.MATH_SYMBOL}[{super().__repr__()}]"
2010
+
2011
+ __str__ = __repr__
2012
+
2013
+
2014
+ class Sin(MathematicalMap):
2015
+ """Apply a sine map to a parameter or term."""
2016
+
2017
+ MATH_SYMBOL = "sin"
2018
+
2019
+ def _apply_mathematical_map(self, value: Number) -> Number: # noqa: PLR6301
2020
+ return float(np.sin(_assert_real(value)))
2021
+
2022
+ def __copy__(self) -> Sin:
2023
+ return Sin(super().__copy__())
2024
+
2025
+
2026
+ class Cos(MathematicalMap):
2027
+ """Apply a cosine map to a parameter or term."""
2028
+
2029
+ MATH_SYMBOL = "cos"
2030
+
2031
+ def _apply_mathematical_map(self, value: Number) -> Number: # noqa: PLR6301
2032
+ return float(np.cos(_assert_real(value)))
2033
+
2034
+ def __copy__(self) -> Cos:
2035
+ return Cos(super().__copy__())