pytensor 3.1.3__tar.gz → 3.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (615) hide show
  1. {pytensor-3.1.3/pytensor.egg-info → pytensor-3.2.0}/PKG-INFO +7 -5
  2. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/creating_a_c_op.rst +0 -316
  3. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/graph_rewriting.rst +7 -222
  4. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/index.rst +1 -0
  5. pytensor-3.2.0/doc/extending/unification_kanren.rst +250 -0
  6. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/sparse/index.rst +0 -2
  7. {pytensor-3.1.3 → pytensor-3.2.0}/pyproject.toml +8 -5
  8. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/_version.py +3 -3
  9. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/builders.py +1 -1
  10. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/mode.py +3 -1
  11. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/configdefaults.py +1 -1
  12. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/graph/features.py +1 -1
  13. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/graph/rewriting/basic.py +53 -38
  14. pytensor-3.2.0/pytensor/graph/rewriting/kanren.py +329 -0
  15. pytensor-3.2.0/pytensor/graph/rewriting/unify.py +593 -0
  16. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/graph/utils.py +6 -4
  17. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/c/basic.py +1 -1
  18. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/c/cmodule.py +4 -4
  19. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/c/op.py +11 -13
  20. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/subtensor.py +1 -5
  21. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/linker.py +1 -1
  22. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/subtensor.py +3 -7
  23. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/__init__.py +3 -0
  24. pytensor-3.2.0/pytensor/link/numba/dispatch/_llvmlite_self_ref.py +66 -0
  25. pytensor-3.2.0/pytensor/link/numba/dispatch/_patch_pointer_add.py +37 -0
  26. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/blockwise.py +2 -0
  27. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/elemwise.py +227 -31
  28. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/random.py +2 -0
  29. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/subtensor.py +5 -15
  30. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/vectorize_codegen.py +137 -46
  31. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/pytorch/dispatch/subtensor.py +10 -8
  32. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scalar/basic.py +0 -145
  33. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scalar/c_code/gamma.c +0 -16
  34. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scalar/math.py +0 -64
  35. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scan/__init__.py +1 -1
  36. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scan/basic.py +1 -1
  37. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scan/rewriting/inner_graph.py +1 -1
  38. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scan/rewriting/trace.py +1 -1
  39. pytensor-3.2.0/pytensor/sparse/__init__.py +5 -0
  40. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/sparse/basic.py +1 -1
  41. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/sparse/math.py +33 -6
  42. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/basic.py +1 -8
  43. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/elemwise.py +95 -20
  44. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/extra_ops.py +3 -3
  45. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/math.py +66 -63
  46. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/random/rewriting/basic.py +1 -2
  47. pytensor-3.1.3/pytensor/tensor/rewriting/indexed_elemwise.py → pytensor-3.2.0/pytensor/tensor/rewriting/fused_elemwise.py +263 -229
  48. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/math.py +230 -110
  49. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/numba.py +1 -1
  50. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/shape.py +1 -2
  51. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/special.py +1 -3
  52. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/subtensor.py +38 -226
  53. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/subtensor_lift.py +10 -8
  54. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/subtensor.py +288 -470
  55. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/math.py +20 -10
  56. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/rewriting/indexing.py +1 -1
  57. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/type.py +1 -1
  58. {pytensor-3.1.3 → pytensor-3.2.0/pytensor.egg-info}/PKG-INFO +7 -5
  59. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor.egg-info/SOURCES.txt +4 -2
  60. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor.egg-info/requires.txt +7 -4
  61. {pytensor-3.1.3 → pytensor-3.2.0}/tests/test_rop.py +54 -1
  62. pytensor-3.1.3/pytensor/graph/rewriting/kanren.py +0 -99
  63. pytensor-3.1.3/pytensor/graph/rewriting/unify.py +0 -497
  64. pytensor-3.1.3/pytensor/sparse/__init__.py +0 -35
  65. pytensor-3.1.3/pytensor/tensor/c_code/dimshuffle.c +0 -86
  66. {pytensor-3.1.3 → pytensor-3.2.0}/LICENSE.txt +0 -0
  67. {pytensor-3.1.3 → pytensor-3.2.0}/MANIFEST.in +0 -0
  68. {pytensor-3.1.3 → pytensor-3.2.0}/README.rst +0 -0
  69. {pytensor-3.1.3 → pytensor-3.2.0}/doc/.templates/PLACEHOLDER +0 -0
  70. {pytensor-3.1.3 → pytensor-3.2.0}/doc/.templates/layout.html +0 -0
  71. {pytensor-3.1.3 → pytensor-3.2.0}/doc/.templates/nb-badges.html +0 -0
  72. {pytensor-3.1.3 → pytensor-3.2.0}/doc/.templates/rendered_citation.html +0 -0
  73. {pytensor-3.1.3 → pytensor-3.2.0}/doc/LICENSE.txt +0 -0
  74. {pytensor-3.1.3 → pytensor-3.2.0}/doc/README.md +0 -0
  75. {pytensor-3.1.3 → pytensor-3.2.0}/doc/_drafts/benchmark_mlx_v_jax_corrected.ipynb +0 -0
  76. {pytensor-3.1.3 → pytensor-3.2.0}/doc/_thumbnails/autodiff/vector_jacobian_product.png +0 -0
  77. {pytensor-3.1.3 → pytensor-3.2.0}/doc/acknowledgement.rst +0 -0
  78. {pytensor-3.1.3 → pytensor-3.2.0}/doc/bcast.png +0 -0
  79. {pytensor-3.1.3 → pytensor-3.2.0}/doc/bcast.svg +0 -0
  80. {pytensor-3.1.3 → pytensor-3.2.0}/doc/blog.md +0 -0
  81. {pytensor-3.1.3 → pytensor-3.2.0}/doc/conf.py +0 -0
  82. {pytensor-3.1.3 → pytensor-3.2.0}/doc/core_development_guide.rst +0 -0
  83. {pytensor-3.1.3 → pytensor-3.2.0}/doc/css.inc +0 -0
  84. {pytensor-3.1.3 → pytensor-3.2.0}/doc/dev_start_guide.rst +0 -0
  85. {pytensor-3.1.3 → pytensor-3.2.0}/doc/environment.yml +0 -0
  86. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/apply.png +0 -0
  87. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/apply.svg +0 -0
  88. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/apply2.svg +0 -0
  89. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/creating_a_numba_jax_op.rst +0 -0
  90. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/creating_an_op.rst +0 -0
  91. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/ctype.rst +0 -0
  92. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/extending_faq.rst +0 -0
  93. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/extending_pytensor_solution_1.py +0 -0
  94. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/graphstructures.rst +0 -0
  95. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/inplace.rst +0 -0
  96. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/op.rst +0 -0
  97. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/other_ops.rst +0 -0
  98. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/pics/symbolic_graph_opt.png +0 -0
  99. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/pics/symbolic_graph_unopt.png +0 -0
  100. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/pipeline.rst +0 -0
  101. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/scan.rst +0 -0
  102. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/tips.rst +0 -0
  103. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/type.rst +0 -0
  104. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/unittest.rst +0 -0
  105. {pytensor-3.1.3 → pytensor-3.2.0}/doc/extending/using_params.rst +0 -0
  106. {pytensor-3.1.3 → pytensor-3.2.0}/doc/faq.rst +0 -0
  107. {pytensor-3.1.3 → pytensor-3.2.0}/doc/gallery/applications/normalizing_flows_in_pytensor.ipynb +0 -0
  108. {pytensor-3.1.3 → pytensor-3.2.0}/doc/gallery/applications/tiny_transformer_llm.ipynb +0 -0
  109. {pytensor-3.1.3 → pytensor-3.2.0}/doc/gallery/autodiff/vector_jacobian_product.ipynb +0 -0
  110. {pytensor-3.1.3 → pytensor-3.2.0}/doc/gallery/introduction/pytensor_intro.ipynb +0 -0
  111. {pytensor-3.1.3 → pytensor-3.2.0}/doc/gallery/optimize/root.ipynb +0 -0
  112. {pytensor-3.1.3 → pytensor-3.2.0}/doc/gallery/page_footer.md +0 -0
  113. {pytensor-3.1.3 → pytensor-3.2.0}/doc/gallery/rewrites/graph_rewrites.ipynb +0 -0
  114. {pytensor-3.1.3 → pytensor-3.2.0}/doc/gallery/scan/scan_tutorial.ipynb +0 -0
  115. {pytensor-3.1.3 → pytensor-3.2.0}/doc/generate_dtype_tensor_table.py +0 -0
  116. {pytensor-3.1.3 → pytensor-3.2.0}/doc/glossary.rst +0 -0
  117. {pytensor-3.1.3 → pytensor-3.2.0}/doc/images/Elman_srnn.png +0 -0
  118. {pytensor-3.1.3 → pytensor-3.2.0}/doc/images/PyTensor.png +0 -0
  119. {pytensor-3.1.3 → pytensor-3.2.0}/doc/images/PyTensor_RGB.svg +0 -0
  120. {pytensor-3.1.3 → pytensor-3.2.0}/doc/images/PyTensor_logo.png +0 -0
  121. {pytensor-3.1.3 → pytensor-3.2.0}/doc/images/binder.svg +0 -0
  122. {pytensor-3.1.3 → pytensor-3.2.0}/doc/images/blocksparse.png +0 -0
  123. {pytensor-3.1.3 → pytensor-3.2.0}/doc/images/colab.svg +0 -0
  124. {pytensor-3.1.3 → pytensor-3.2.0}/doc/images/github.svg +0 -0
  125. {pytensor-3.1.3 → pytensor-3.2.0}/doc/images/lstm.png +0 -0
  126. {pytensor-3.1.3 → pytensor-3.2.0}/doc/images/lstm_memorycell.png +0 -0
  127. {pytensor-3.1.3 → pytensor-3.2.0}/doc/images/talk2010.gif +0 -0
  128. {pytensor-3.1.3 → pytensor-3.2.0}/doc/images/talk2010.png +0 -0
  129. {pytensor-3.1.3 → pytensor-3.2.0}/doc/index.rst +0 -0
  130. {pytensor-3.1.3 → pytensor-3.2.0}/doc/install.rst +0 -0
  131. {pytensor-3.1.3 → pytensor-3.2.0}/doc/internal/how_to_release.rst +0 -0
  132. {pytensor-3.1.3 → pytensor-3.2.0}/doc/internal/index.rst +0 -0
  133. {pytensor-3.1.3 → pytensor-3.2.0}/doc/internal/metadocumentation.rst +0 -0
  134. {pytensor-3.1.3 → pytensor-3.2.0}/doc/introduction.rst +0 -0
  135. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/compile/debugmode.rst +0 -0
  136. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/compile/function.rst +0 -0
  137. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/compile/index.rst +0 -0
  138. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/compile/io.rst +0 -0
  139. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/compile/mode.rst +0 -0
  140. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/compile/nanguardmode.rst +0 -0
  141. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/compile/opfromgraph.rst +0 -0
  142. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/compile/ops.rst +0 -0
  143. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/compile/profilemode.rst +0 -0
  144. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/compile/shared.rst +0 -0
  145. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/config.rst +0 -0
  146. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/examples/d3viz/css/d3-context-menu.css +0 -0
  147. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/examples/d3viz/css/d3viz.css +0 -0
  148. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/examples/d3viz/js/d3-context-menu.js +0 -0
  149. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/examples/d3viz/js/d3.v3.min.js +0 -0
  150. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/examples/d3viz/js/d3viz.js +0 -0
  151. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/examples/d3viz/js/dagre-d3.min.js +0 -0
  152. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/examples/d3viz/js/graphlib-dot.min.js +0 -0
  153. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/examples/mlp.html +0 -0
  154. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/examples/mlp.png +0 -0
  155. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/examples/mlp2.html +0 -0
  156. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/examples/mlp2.pdf +0 -0
  157. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/examples/mlp2.png +0 -0
  158. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/examples/ofg.html +0 -0
  159. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/examples/ofg2.html +0 -0
  160. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/index.ipynb +0 -0
  161. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/index.rst +0 -0
  162. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/index_files/index_10_0.png +0 -0
  163. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/index_files/index_11_0.png +0 -0
  164. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/index_files/index_24_0.png +0 -0
  165. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/d3viz/index_files/index_25_0.png +0 -0
  166. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/graph/features.rst +0 -0
  167. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/graph/fgraph.rst +0 -0
  168. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/graph/graph.rst +0 -0
  169. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/graph/index.rst +0 -0
  170. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/graph/op.rst +0 -0
  171. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/graph/replace.rst +0 -0
  172. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/graph/type.rst +0 -0
  173. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/graph/utils.rst +0 -0
  174. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/index.rst +0 -0
  175. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/misc/pkl_utils.rst +0 -0
  176. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/printing.rst +0 -0
  177. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/scalar/index.rst +0 -0
  178. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/scan.rst +0 -0
  179. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/sparse/sandbox.rst +0 -0
  180. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/tensor/basic.rst +0 -0
  181. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/tensor/basic_opt.rst +0 -0
  182. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/tensor/bcast.png +0 -0
  183. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/tensor/bcast.svg +0 -0
  184. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/tensor/elemwise.rst +0 -0
  185. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/tensor/extra_ops.rst +0 -0
  186. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/tensor/fft.rst +0 -0
  187. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/tensor/functional.rst +0 -0
  188. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/tensor/index.rst +0 -0
  189. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/tensor/io.rst +0 -0
  190. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/tensor/linalg.rst +0 -0
  191. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/tensor/math_opt.rst +0 -0
  192. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/tensor/nlinalg.rst +0 -0
  193. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/tensor/optimize.rst +0 -0
  194. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/tensor/plot_fft.png +0 -0
  195. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/tensor/random.rst +0 -0
  196. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/tensor/slinalg.rst +0 -0
  197. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/tensor/utils.rst +0 -0
  198. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/typed_list.rst +0 -0
  199. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/xtensor/index.md +0 -0
  200. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/xtensor/linalg.md +0 -0
  201. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/xtensor/math.md +0 -0
  202. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/xtensor/module_functions.md +0 -0
  203. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/xtensor/random.md +0 -0
  204. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/xtensor/signal.md +0 -0
  205. {pytensor-3.1.3 → pytensor-3.2.0}/doc/library/xtensor/type.md +0 -0
  206. {pytensor-3.1.3 → pytensor-3.2.0}/doc/links.rst +0 -0
  207. {pytensor-3.1.3 → pytensor-3.2.0}/doc/optimizations.rst +0 -0
  208. {pytensor-3.1.3 → pytensor-3.2.0}/doc/pylintrc +0 -0
  209. {pytensor-3.1.3 → pytensor-3.2.0}/doc/robots.txt +0 -0
  210. {pytensor-3.1.3 → pytensor-3.2.0}/doc/troubleshooting.rst +0 -0
  211. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/adding.rst +0 -0
  212. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/adding_solution_1.py +0 -0
  213. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/aliasing.rst +0 -0
  214. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/apply.png +0 -0
  215. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/apply.svg +0 -0
  216. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/bcast.png +0 -0
  217. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/broadcasting.rst +0 -0
  218. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/conditions.rst +0 -0
  219. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/debug_faq.rst +0 -0
  220. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/dlogistic.png +0 -0
  221. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/examples.rst +0 -0
  222. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/faq_tutorial.rst +0 -0
  223. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/gradients.rst +0 -0
  224. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/index.rst +0 -0
  225. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/loading_and_saving.rst +0 -0
  226. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/logistic.gp +0 -0
  227. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/logistic.png +0 -0
  228. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/loop.rst +0 -0
  229. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/loop_solution_1.py +0 -0
  230. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/modes.rst +0 -0
  231. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/modes_solution_1.py +0 -0
  232. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/multi_cores.rst +0 -0
  233. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/nan_tutorial.rst +0 -0
  234. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/pics/d3viz.png +0 -0
  235. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/pics/logreg_pydotprint_predict.png +0 -0
  236. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/pics/logreg_pydotprint_prediction.png +0 -0
  237. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/pics/logreg_pydotprint_train.png +0 -0
  238. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/printing_drawing.rst +0 -0
  239. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/prng.rst +0 -0
  240. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/profiling.rst +0 -0
  241. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/profiling_example.py +0 -0
  242. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/profiling_example_out.prof +0 -0
  243. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/shape_info.rst +0 -0
  244. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/sparse.rst +0 -0
  245. {pytensor-3.1.3 → pytensor-3.2.0}/doc/tutorial/symbolic_graphs.rst +0 -0
  246. {pytensor-3.1.3 → pytensor-3.2.0}/doc/user_guide.rst +0 -0
  247. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/__init__.py +0 -0
  248. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/_sparse_lazy.py +0 -0
  249. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/assumptions/__init__.py +0 -0
  250. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/assumptions/alloc.py +0 -0
  251. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/assumptions/blockwise.py +0 -0
  252. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/assumptions/core.py +0 -0
  253. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/assumptions/diagonal.py +0 -0
  254. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/assumptions/dimshuffle.py +0 -0
  255. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/assumptions/dot.py +0 -0
  256. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/assumptions/elemwise.py +0 -0
  257. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/assumptions/orthogonal.py +0 -0
  258. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/assumptions/permutation.py +0 -0
  259. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/assumptions/positive_definite.py +0 -0
  260. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/assumptions/reshape.py +0 -0
  261. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/assumptions/selection.py +0 -0
  262. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/assumptions/shape.py +0 -0
  263. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/assumptions/specify.py +0 -0
  264. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/assumptions/subtensor.py +0 -0
  265. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/assumptions/symmetric.py +0 -0
  266. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/assumptions/triangular.py +0 -0
  267. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/basic.py +0 -0
  268. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/bin/__init__.py +0 -0
  269. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/bin/pytensor_cache.py +0 -0
  270. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/breakpoint.py +0 -0
  271. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/__init__.py +0 -0
  272. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/aliasing.py +0 -0
  273. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/compiledir.py +0 -0
  274. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/compilelock.py +0 -0
  275. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/debug/__init__.py +0 -0
  276. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/debug/debugmode.py +0 -0
  277. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/debug/dump.py +0 -0
  278. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/debug/monitormode.py +0 -0
  279. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/debug/nanguardmode.py +0 -0
  280. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/debug/profiling.py +0 -0
  281. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/executor.py +0 -0
  282. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/inner_function.py +0 -0
  283. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/io.py +0 -0
  284. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/maker.py +0 -0
  285. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/ops.py +0 -0
  286. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/rebuild.py +0 -0
  287. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/rewriting.py +0 -0
  288. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/compile/sharedvalue.py +0 -0
  289. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/configparser.py +0 -0
  290. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/d3viz/__init__.py +0 -0
  291. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/d3viz/css/d3-context-menu.css +0 -0
  292. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/d3viz/css/d3viz.css +0 -0
  293. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/d3viz/d3viz.py +0 -0
  294. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/d3viz/formatting.py +0 -0
  295. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/d3viz/html/template.html +0 -0
  296. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/d3viz/js/d3-context-menu.js +0 -0
  297. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/d3viz/js/d3.v3.min.js +0 -0
  298. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/d3viz/js/d3viz.js +0 -0
  299. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/d3viz/js/dagre-d3.min.js +0 -0
  300. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/d3viz/js/graphlib-dot.min.js +0 -0
  301. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/gradient.py +0 -0
  302. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/graph/__init__.py +0 -0
  303. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/graph/basic.py +0 -0
  304. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/graph/destroyhandler.py +0 -0
  305. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/graph/fg.py +0 -0
  306. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/graph/null_type.py +0 -0
  307. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/graph/op.py +0 -0
  308. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/graph/replace.py +0 -0
  309. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/graph/rewriting/__init__.py +0 -0
  310. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/graph/rewriting/db.py +0 -0
  311. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/graph/rewriting/reachability.py +0 -0
  312. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/graph/rewriting/utils.py +0 -0
  313. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/graph/traversal.py +0 -0
  314. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/graph/type.py +0 -0
  315. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/ifelse.py +0 -0
  316. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/ipython.py +0 -0
  317. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/__init__.py +0 -0
  318. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/basic.py +0 -0
  319. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/c/__init__.py +0 -0
  320. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/c/c_code/lazylinker_c.c +0 -0
  321. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/c/c_code/pytensor_mod_helper.h +0 -0
  322. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/c/cutils.py +0 -0
  323. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/c/cvm.py +0 -0
  324. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/c/exceptions.py +0 -0
  325. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/c/interface.py +0 -0
  326. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/c/lazylinker_c.py +0 -0
  327. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/c/params_type.py +0 -0
  328. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/c/type.py +0 -0
  329. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/__init__.py +0 -0
  330. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/__init__.py +0 -0
  331. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/basic.py +0 -0
  332. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/blas.py +0 -0
  333. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/blockwise.py +0 -0
  334. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/einsum.py +0 -0
  335. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/elemwise.py +0 -0
  336. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/extra_ops.py +0 -0
  337. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/linalg/__init__.py +0 -0
  338. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/linalg/constructors.py +0 -0
  339. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/linalg/decomposition.py +0 -0
  340. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/linalg/inverse.py +0 -0
  341. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/linalg/products.py +0 -0
  342. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/linalg/solvers.py +0 -0
  343. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/linalg/summary.py +0 -0
  344. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/math.py +0 -0
  345. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/pad.py +0 -0
  346. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/random.py +0 -0
  347. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/scalar.py +0 -0
  348. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/scan.py +0 -0
  349. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/shape.py +0 -0
  350. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/signal/__init__.py +0 -0
  351. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/signal/conv.py +0 -0
  352. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/sort.py +0 -0
  353. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/sparse.py +0 -0
  354. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/dispatch/tensor_basic.py +0 -0
  355. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/jax/ops.py +0 -0
  356. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/__init__.py +0 -0
  357. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/__init__.py +0 -0
  358. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/basic.py +0 -0
  359. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/blas.py +0 -0
  360. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/blockwise.py +0 -0
  361. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/einsum.py +0 -0
  362. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/elemwise.py +0 -0
  363. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/extra_ops.py +0 -0
  364. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/linalg/__init__.py +0 -0
  365. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/linalg/decomposition.py +0 -0
  366. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/linalg/inverse.py +0 -0
  367. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/linalg/products.py +0 -0
  368. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/linalg/solvers.py +0 -0
  369. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/linalg/summary.py +0 -0
  370. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/math.py +0 -0
  371. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/pad.py +0 -0
  372. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/scalar.py +0 -0
  373. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/shape.py +0 -0
  374. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/signal/__init__.py +0 -0
  375. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/signal/conv.py +0 -0
  376. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/sort.py +0 -0
  377. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/dispatch/tensor_basic.py +0 -0
  378. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/mlx/linker.py +0 -0
  379. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/__init__.py +0 -0
  380. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/cache.py +0 -0
  381. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/basic.py +0 -0
  382. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/compile_ops.py +0 -0
  383. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/cython_support.py +0 -0
  384. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/extra_ops.py +0 -0
  385. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/_LAPACK.py +0 -0
  386. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/__init__.py +0 -0
  387. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/constructors.py +0 -0
  388. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/decomposition/__init__.py +0 -0
  389. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/decomposition/cholesky.py +0 -0
  390. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/decomposition/dispatch.py +0 -0
  391. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/decomposition/eigen.py +0 -0
  392. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/decomposition/lu.py +0 -0
  393. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/decomposition/lu_factor.py +0 -0
  394. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/decomposition/qr.py +0 -0
  395. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/decomposition/qz.py +0 -0
  396. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/decomposition/schur.py +0 -0
  397. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/decomposition/svd.py +0 -0
  398. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/inverse.py +0 -0
  399. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/products.py +0 -0
  400. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/solvers/__init__.py +0 -0
  401. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/solvers/cholesky.py +0 -0
  402. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/solvers/dispatch.py +0 -0
  403. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/solvers/general.py +0 -0
  404. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/solvers/hermitian.py +0 -0
  405. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/solvers/linear_control.py +0 -0
  406. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/solvers/lu_solve.py +0 -0
  407. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/solvers/posdef.py +0 -0
  408. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/solvers/symmetric.py +0 -0
  409. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/solvers/triangular.py +0 -0
  410. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/solvers/tridiagonal.py +0 -0
  411. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/solvers/utils.py +0 -0
  412. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/summary.py +0 -0
  413. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/linalg/utils.py +0 -0
  414. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/scalar.py +0 -0
  415. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/scan.py +0 -0
  416. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/shape.py +0 -0
  417. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/signal/__init__.py +0 -0
  418. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/signal/conv.py +0 -0
  419. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/sort.py +0 -0
  420. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/sparse/__init__.py +0 -0
  421. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/sparse/basic.py +0 -0
  422. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/sparse/math.py +0 -0
  423. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/sparse/variable.py +0 -0
  424. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/string_codegen.py +0 -0
  425. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/tensor_basic.py +0 -0
  426. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/dispatch/typed_list.py +0 -0
  427. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/numba/linker.py +0 -0
  428. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/pytorch/dispatch/__init__.py +0 -0
  429. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/pytorch/dispatch/basic.py +0 -0
  430. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/pytorch/dispatch/blas.py +0 -0
  431. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/pytorch/dispatch/blockwise.py +0 -0
  432. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/pytorch/dispatch/elemwise.py +0 -0
  433. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/pytorch/dispatch/extra_ops.py +0 -0
  434. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/pytorch/dispatch/linalg/__init__.py +0 -0
  435. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/pytorch/dispatch/linalg/decomposition.py +0 -0
  436. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/pytorch/dispatch/linalg/inverse.py +0 -0
  437. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/pytorch/dispatch/linalg/products.py +0 -0
  438. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/pytorch/dispatch/linalg/summary.py +0 -0
  439. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/pytorch/dispatch/math.py +0 -0
  440. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/pytorch/dispatch/scalar.py +0 -0
  441. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/pytorch/dispatch/shape.py +0 -0
  442. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/pytorch/dispatch/sort.py +0 -0
  443. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/pytorch/linker.py +0 -0
  444. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/utils.py +0 -0
  445. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/link/vm.py +0 -0
  446. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/misc/__init__.py +0 -0
  447. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/misc/check_blas.py +0 -0
  448. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/misc/check_blas_many.sh +0 -0
  449. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/misc/check_duplicate_key.py +0 -0
  450. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/misc/elemwise_openmp_speedup.py +0 -0
  451. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/misc/elemwise_time_test.py +0 -0
  452. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/misc/frozendict.py +0 -0
  453. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/misc/may_share_memory.py +0 -0
  454. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/misc/ordered_set.py +0 -0
  455. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/misc/pkl_utils.py +0 -0
  456. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/npy_2_compat.py +0 -0
  457. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/printing.py +0 -0
  458. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/py.typed +0 -0
  459. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/raise_op.py +0 -0
  460. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scalar/__init__.py +0 -0
  461. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scalar/c_code/Faddeeva.cc +0 -0
  462. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scalar/c_code/Faddeeva.hh +0 -0
  463. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scalar/c_code/incbet.c +0 -0
  464. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scalar/loop.py +0 -0
  465. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scalar/sharedvar.py +0 -0
  466. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scan/checkpoints.py +0 -0
  467. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scan/op.py +0 -0
  468. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scan/rewriting/__init__.py +0 -0
  469. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scan/rewriting/db.py +0 -0
  470. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scan/rewriting/inplace.py +0 -0
  471. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scan/rewriting/io.py +0 -0
  472. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scan/rewriting/merge.py +0 -0
  473. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scan/rewriting/push_out.py +0 -0
  474. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scan/rewriting/utils.py +0 -0
  475. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scan/scan_perform.pyx +0 -0
  476. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scan/scan_perform_ext.py +0 -0
  477. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scan/utils.py +0 -0
  478. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/scan/views.py +0 -0
  479. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/sparse/linalg.py +0 -0
  480. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/sparse/rewriting.py +0 -0
  481. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/sparse/sharedvar.py +0 -0
  482. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/sparse/type.py +0 -0
  483. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/sparse/utils.py +0 -0
  484. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/sparse/variable.py +0 -0
  485. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/__init__.py +0 -0
  486. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/blas/__init__.py +0 -0
  487. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/blas/_core.py +0 -0
  488. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/blas/batched.py +0 -0
  489. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/blas/blas_c.py +0 -0
  490. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/blas/c_code/__init__.py +0 -0
  491. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/blas/c_code/alt_blas_common.h +0 -0
  492. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/blas/c_code/alt_blas_template.c +0 -0
  493. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/blas/c_code/blas_headers.py +0 -0
  494. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/blas/c_code/codegen.py +0 -0
  495. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/blas/gemm.py +0 -0
  496. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/blas/gemv.py +0 -0
  497. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/blas/ger.py +0 -0
  498. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/blockwise.py +0 -0
  499. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/einsum.py +0 -0
  500. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/elemwise_cgen.py +0 -0
  501. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/exceptions.py +0 -0
  502. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/fft.py +0 -0
  503. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/fourier.py +0 -0
  504. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/functional.py +0 -0
  505. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/interpolate.py +0 -0
  506. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/__init__.py +0 -0
  507. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/_lazy.py +0 -0
  508. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/constructors.py +0 -0
  509. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/decomposition/__init__.py +0 -0
  510. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/decomposition/cholesky.py +0 -0
  511. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/decomposition/eigen.py +0 -0
  512. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/decomposition/lu.py +0 -0
  513. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/decomposition/qr.py +0 -0
  514. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/decomposition/schur.py +0 -0
  515. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/decomposition/svd.py +0 -0
  516. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/dtype_utils.py +0 -0
  517. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/inverse.py +0 -0
  518. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/products.py +0 -0
  519. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/solvers/__init__.py +0 -0
  520. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/solvers/core.py +0 -0
  521. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/solvers/general.py +0 -0
  522. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/solvers/linear_control.py +0 -0
  523. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/solvers/lstsq.py +0 -0
  524. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/solvers/psd.py +0 -0
  525. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/solvers/triangular.py +0 -0
  526. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/solvers/tridiagonal.py +0 -0
  527. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/linalg/summary.py +0 -0
  528. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/nlinalg.py +0 -0
  529. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/optimize.py +0 -0
  530. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/pad.py +0 -0
  531. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/random/__init__.py +0 -0
  532. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/random/basic.py +0 -0
  533. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/random/op.py +0 -0
  534. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/random/rewriting/__init__.py +0 -0
  535. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/random/rewriting/jax.py +0 -0
  536. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/random/rewriting/numba.py +0 -0
  537. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/random/type.py +0 -0
  538. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/random/utils.py +0 -0
  539. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/random/variable.py +0 -0
  540. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/reshape.py +0 -0
  541. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/__init__.py +0 -0
  542. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/assumptions.py +0 -0
  543. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/basic.py +0 -0
  544. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/blas.py +0 -0
  545. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/blas_c.py +0 -0
  546. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/blockwise.py +0 -0
  547. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/einsum.py +0 -0
  548. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/elemwise.py +0 -0
  549. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/extra_ops.py +0 -0
  550. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/jax.py +0 -0
  551. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/linalg/__init__.py +0 -0
  552. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/linalg/decomposition.py +0 -0
  553. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/linalg/inverse.py +0 -0
  554. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/linalg/products.py +0 -0
  555. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/linalg/solvers.py +0 -0
  556. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/linalg/summary.py +0 -0
  557. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/linalg/utils.py +0 -0
  558. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/ofg.py +0 -0
  559. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/optimize.py +0 -0
  560. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/reshape.py +0 -0
  561. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/rewriting/uncanonicalize.py +0 -0
  562. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/shape.py +0 -0
  563. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/sharedvar.py +0 -0
  564. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/signal/__init__.py +0 -0
  565. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/signal/conv.py +0 -0
  566. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/slinalg.py +0 -0
  567. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/sort.py +0 -0
  568. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/special.py +0 -0
  569. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/symbolic.py +0 -0
  570. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/type.py +0 -0
  571. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/type_other.py +0 -0
  572. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/utils.py +0 -0
  573. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/var.py +0 -0
  574. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/variable.py +0 -0
  575. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/tensor/xlogx.py +0 -0
  576. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/typed_list/__init__.py +0 -0
  577. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/typed_list/basic.py +0 -0
  578. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/typed_list/rewriting.py +0 -0
  579. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/typed_list/type.py +0 -0
  580. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/utils.py +0 -0
  581. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/__init__.py +0 -0
  582. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/basic.py +0 -0
  583. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/indexing.py +0 -0
  584. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/linalg.py +0 -0
  585. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/random/__init__.py +0 -0
  586. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/random/basic.py +0 -0
  587. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/random/type.py +0 -0
  588. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/random/variable.py +0 -0
  589. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/reduction.py +0 -0
  590. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/rewriting/__init__.py +0 -0
  591. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/rewriting/basic.py +0 -0
  592. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/rewriting/math.py +0 -0
  593. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/rewriting/reduction.py +0 -0
  594. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/rewriting/shape.py +0 -0
  595. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/rewriting/utils.py +0 -0
  596. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/rewriting/vectorization.py +0 -0
  597. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/shape.py +0 -0
  598. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/signal.py +0 -0
  599. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor/xtensor/vectorization.py +0 -0
  600. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor.egg-info/dependency_links.txt +0 -0
  601. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor.egg-info/entry_points.txt +0 -0
  602. {pytensor-3.1.3 → pytensor-3.2.0}/pytensor.egg-info/top_level.txt +0 -0
  603. {pytensor-3.1.3 → pytensor-3.2.0}/scripts/mypy-failing.txt +0 -0
  604. {pytensor-3.1.3 → pytensor-3.2.0}/scripts/slowest_tests/update-slowest-times-issue.sh +0 -0
  605. {pytensor-3.1.3 → pytensor-3.2.0}/setup.cfg +0 -0
  606. {pytensor-3.1.3 → pytensor-3.2.0}/setup.py +0 -0
  607. {pytensor-3.1.3 → pytensor-3.2.0}/tests/link/c/c_code/test_cenum.h +0 -0
  608. {pytensor-3.1.3 → pytensor-3.2.0}/tests/link/c/c_code/test_quadratic_function.c +0 -0
  609. {pytensor-3.1.3 → pytensor-3.2.0}/tests/test_basic.py +0 -0
  610. {pytensor-3.1.3 → pytensor-3.2.0}/tests/test_breakpoint.py +0 -0
  611. {pytensor-3.1.3 → pytensor-3.2.0}/tests/test_config.py +0 -0
  612. {pytensor-3.1.3 → pytensor-3.2.0}/tests/test_gradient.py +0 -0
  613. {pytensor-3.1.3 → pytensor-3.2.0}/tests/test_ifelse.py +0 -0
  614. {pytensor-3.1.3 → pytensor-3.2.0}/tests/test_printing.py +0 -0
  615. {pytensor-3.1.3 → pytensor-3.2.0}/tests/test_raise_op.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytensor
3
- Version: 3.1.3
3
+ Version: 3.2.0
4
4
  Summary: Optimizing compiler for evaluating mathematical expressions on CPUs and GPUs.
5
5
  Author-email: pymc-devs <pymc.devs@gmail.com>
6
6
  License-Expression: BSD-3-Clause
@@ -32,10 +32,6 @@ Requires-Dist: scipy<2,>=1
32
32
  Requires-Dist: numpy>=2.0
33
33
  Requires-Dist: numba<=0.65.1,>=0.58
34
34
  Requires-Dist: filelock>=3.15
35
- Requires-Dist: etuples
36
- Requires-Dist: logical-unification
37
- Requires-Dist: miniKanren
38
- Requires-Dist: cons
39
35
  Provides-Extra: complete
40
36
  Requires-Dist: pytensor[jax]; extra == "complete"
41
37
  Requires-Dist: pytensor[numba]; extra == "complete"
@@ -51,6 +47,7 @@ Requires-Dist: coverage>=5.1; extra == "tests"
51
47
  Requires-Dist: pytest-benchmark; extra == "tests"
52
48
  Requires-Dist: pytest-mock; extra == "tests"
53
49
  Requires-Dist: pytest-sphinx; extra == "tests"
50
+ Requires-Dist: pytensor[kanren]; extra == "tests"
54
51
  Provides-Extra: rtd
55
52
  Requires-Dist: sphinx<6,>=5.1.0; extra == "rtd"
56
53
  Requires-Dist: pygments; extra == "rtd"
@@ -61,6 +58,11 @@ Requires-Dist: jaxlib; extra == "jax"
61
58
  Provides-Extra: numba
62
59
  Requires-Dist: numba<=0.65.1,>=0.58; extra == "numba"
63
60
  Requires-Dist: llvmlite; extra == "numba"
61
+ Provides-Extra: kanren
62
+ Requires-Dist: etuples; extra == "kanren"
63
+ Requires-Dist: logical-unification; extra == "kanren"
64
+ Requires-Dist: miniKanren; extra == "kanren"
65
+ Requires-Dist: cons; extra == "kanren"
64
66
  Dynamic: license-file
65
67
 
66
68
  .. image:: https://cdn.rawgit.com/pymc-devs/pytensor/main/doc/images/PyTensor_RGB.svg
@@ -713,322 +713,6 @@ C code.
713
713
  return c_code % locals()
714
714
 
715
715
 
716
- Alternate way of defining C :class:`Op`\s
717
- =========================================
718
-
719
- The two previous examples have covered the standard way of implementing C :class:`Op`\s
720
- in PyTensor by inheriting from the class :class:`Op`. This process is mostly
721
- simple but it still involves defining many methods as well as mixing, in the
722
- same file, both Python and C code which tends to make the result less
723
- readable.
724
-
725
- To help with this, PyTensor defines a class, `ExternalCOp`, from which new C :class:`Op`\s
726
- can inherit. The class `ExternalCOp` aims to simplify the process of implementing
727
- C :class:`Op`\s by doing the following :
728
-
729
- * It allows you to define the C implementation of your :class:`Op` in a distinct
730
- C code file. This makes it easier to keep your Python and C code
731
- readable and well indented.
732
-
733
- * It can automatically handle all the methods that return C code,
734
- in addition to :meth:`Op.c_code_cache_version` based on the
735
- provided external C implementation.
736
-
737
- To illustrate how much simpler the class `ExternalCOp` makes the process of defining
738
- a new :class:`Op` with a C implementation, let's revisit the second example of this
739
- tutorial, the `VectorTimesVector`\ :class:`Op`. In that example, we implemented an :class:`Op`
740
- to perform the task of element-wise vector-vector multiplication. The two
741
- following blocks of code illustrate what the :class:`Op` would look like if it was
742
- implemented using the `ExternalCOp` class.
743
-
744
- The new :class:`Op` is defined inside a Python file with the following code :
745
-
746
- .. testcode::
747
-
748
- import pytensor
749
- from pytensor.link.c.op import ExternalCOp
750
-
751
- class VectorTimesVector(ExternalCOp):
752
- __props__ = ()
753
-
754
- func_file = "./vectorTimesVector.c"
755
- func_name = "APPLY_SPECIFIC(vector_times_vector)"
756
-
757
- def __init__(self):
758
- super().__init__(self.func_file, self.func_name)
759
-
760
- def make_node(self, x, y):
761
- # Validate the inputs' type
762
- if x.type.ndim != 1:
763
- raise TypeError('x must be a 1-d vector')
764
- if y.type.ndim != 1:
765
- raise TypeError('y must be a 1-d vector')
766
-
767
- # Create an output variable of the same type as x
768
- output_var = pytensor.tensor.type.TensorType(
769
- dtype=pytensor.scalar.upcast(x.dtype, y.dtype),
770
- shape=(None,))()
771
-
772
- return Apply(self, [x, y], [output_var])
773
-
774
- And the following is the C implementation of the :class:`Op`, defined in an external
775
- C file named ``vectorTimesVector.c``:
776
-
777
- .. code-block:: c
778
-
779
- #section support_code
780
-
781
- // Support code function
782
- bool vector_same_shape(PyArrayObject* arr1, PyArrayObject* arr2)
783
- {
784
- return (PyArray_DIMS(arr1)[0] == PyArray_DIMS(arr2)[0]);
785
- }
786
-
787
-
788
- #section support_code_apply
789
-
790
- // Apply-specific support function
791
- void APPLY_SPECIFIC(vector_elemwise_mult)(
792
- DTYPE_INPUT_0* x_ptr, int x_str,
793
- DTYPE_INPUT_1* y_ptr, int y_str,
794
- DTYPE_OUTPUT_0* z_ptr, int z_str, int nbElements)
795
- {
796
- for (int i=0; i < nbElements; i++){
797
- z_ptr[i * z_str] = x_ptr[i * x_str] * y_ptr[i * y_str];
798
- }
799
- }
800
-
801
- // Apply-specific main function
802
- int APPLY_SPECIFIC(vector_times_vector)(PyArrayObject* input0,
803
- PyArrayObject* input1,
804
- PyArrayObject** output0)
805
- {
806
- // Validate that the inputs have the same shape
807
- if ( !vector_same_shape(input0, input1))
808
- {
809
- PyErr_Format(PyExc_ValueError, "Shape mismatch : "
810
- "input0.shape[0] and input1.shape[0] should "
811
- "match but x.shape[0] == %i and "
812
- "y.shape[0] == %i",
813
- PyArray_DIMS(input0)[0], PyArray_DIMS(input1)[0]);
814
- return 1;
815
- }
816
-
817
- // Validate that the output storage exists and has the same
818
- // dimension as x.
819
- if (NULL == *output0 || !(vector_same_shape(input0, *output0)))
820
- {
821
- /* Reference received to invalid output variable.
822
- Decrease received reference's ref count and allocate new
823
- output variable */
824
- Py_XDECREF(*output0);
825
- *output0 = (PyArrayObject*)PyArray_EMPTY(1,
826
- PyArray_DIMS(input0),
827
- TYPENUM_OUTPUT_0,
828
- 0);
829
-
830
- if (!*output0) {
831
- PyErr_Format(PyExc_ValueError,
832
- "Could not allocate output storage");
833
- return 1;
834
- }
835
- }
836
-
837
- // Perform the actual vector-vector multiplication
838
- APPLY_SPECIFIC(vector_elemwise_mult)(
839
- (DTYPE_INPUT_0*)PyArray_DATA(input0),
840
- PyArray_STRIDES(input0)[0] / ITEMSIZE_INPUT_0,
841
- (DTYPE_INPUT_1*)PyArray_DATA(input1),
842
- PyArray_STRIDES(input1)[0] / ITEMSIZE_INPUT_1,
843
- (DTYPE_OUTPUT_0*)PyArray_DATA(*output0),
844
- PyArray_STRIDES(*output0)[0] / ITEMSIZE_OUTPUT_0,
845
- PyArray_DIMS(input0)[0]);
846
-
847
- return 0;
848
- }
849
-
850
- As you can see from this example, the Python and C implementations are nicely
851
- decoupled which makes them much more readable than when they were intertwined
852
- in the same file and the C code contained string formatting markers.
853
-
854
- Now that we have motivated the `ExternalCOp` class, we can have a more precise look at
855
- what it does for us. For this, we go through the various elements that make up
856
- this new version of the `VectorTimesVector`\ `Op` :
857
-
858
- * Parent class : instead of inheriting from the class :class:`Op`,
859
- VectorTimesVector inherits from the class `ExternalCOp`.
860
-
861
- * Constructor : in our new `COp`, the :meth:`COp.__init__` method has an
862
- important use; to inform the constructor of the `ExternalCOp` class
863
- of the location, on the filesystem of the C implementation of
864
- this `COp`. To do this, it gives a list of file paths containing
865
- the C code for this `COp`. To auto-generate the c_code method
866
- with a function call you can specify the function name as the
867
- second parameter. The paths should be given as a relative
868
- path from the folder where the descendant of the `ExternalCOp` class
869
- is defined.
870
-
871
- * :meth:`ExternalCOp.make_node` : this method is absolutely
872
- identical to the one in our old example. Using the `ExternalCOp`
873
- class doesn't change anything here.
874
-
875
- * External C code : the external C code implements the various
876
- functions associated with the `COp`. Writing this C code
877
- involves a few subtleties which deserve their own respective
878
- sections.
879
-
880
- Main function
881
- -------------
882
-
883
- If you pass a function name to :meth:`ExternalCOp.__init___`, it must respect
884
- the following constraints:
885
-
886
- * It must return an int. The value of that int indicates whether
887
- the `Op` could perform its task or not. A value of 0 indicates
888
- success while any non-zero value will interrupt the execution
889
- of the PyTensor function. When returning non-zero the function
890
- must set a python exception indicating the details of the
891
- problem.
892
-
893
- * It must receive one argument for each input to the `Op` followed
894
- by one pointer to an argument for each output of the `Op`. The
895
- types for the argument is dependent on the Types (that is
896
- pytensor Types) of your inputs and outputs.
897
-
898
- * You can specify the number of inputs and outputs for your `Op`
899
- by setting the ``_cop_num_inputs`` and ``_cop_num_outputs``
900
- attributes on your `COp`. The main function will always be
901
- called with that number of arguments, using NULL to fill in
902
- for missing values at the end. This can be used if your `COp`
903
- has a variable number of inputs or outputs, but with a fixed
904
- maximum.
905
-
906
- For example, the main C function of an `COp` that takes two TensorTypes
907
- (which has ``PyArrayObject *`` as its C type) as inputs and returns
908
- both their sum and the difference between them would have four
909
- parameters (two for the `COp`'s inputs and two for its outputs) and it's
910
- signature would look something like this :
911
-
912
- .. code-block:: c
913
-
914
- int sumAndDiffOfScalars(PyArrayObject* in0, PyArrayObject* in1,
915
- PyArrayObject** out0, PyArrayObject** out1)
916
-
917
- Macros
918
- ------
919
-
920
- For certain section tags, your C code can benefit from a number of
921
- pre-defined macros. These section tags have no macros: ``init_code``,
922
- ``support_code``. All other tags will have the support macros
923
- discussed below.
924
-
925
- * ``APPLY_SPECIFIC(str)`` which will automatically append a name
926
- unique to the :ref:`apply` node that applies the `Op` at the end
927
- of the provided ``str``. The use of this macro is discussed
928
- further below.
929
-
930
- For every input which has a :attr:`dtype` attribute (this means
931
- Tensors), the following macros will be
932
- defined unless your `Op` class has an :attr:`Op.check_input` attribute
933
- defined to False. In these descriptions 'i' refers to the position
934
- (indexed from 0) in the input array.
935
-
936
- * ``DTYPE_INPUT_{i}`` : NumPy dtype of the data in the array.
937
- This is the variable type corresponding to the NumPy dtype, not the
938
- string representation of the NumPy dtype. For instance, if the `Op`'s
939
- first input is a float32 :class:`ndarray`, then the macro ``DTYPE_INPUT_0``
940
- corresponds to ``npy_float32`` and can directly be used to declare a
941
- new variable of the same dtype as the data in the array :
942
-
943
- .. code-block:: c
944
-
945
- DTYPE_INPUT_0 myVar = someValue;
946
-
947
- * ``TYPENUM_INPUT_{i}`` : Typenum of the data in the array
948
-
949
- * ``ITEMSIZE_INPUT_{i}`` : Size, in bytes, of the elements in
950
- the array.
951
-
952
- In the same way, the macros ``DTYPE_OUTPUT_{i}``,
953
- ``ITEMSIZE_OUTPUT_{i}`` and ``TYPENUM_OUTPUT_{i}`` are defined for
954
- every output 'i' of the `Op`.
955
-
956
- In addition to these macros, the ``init_code_struct``, ``code``, and
957
- ``code_cleanup`` section tags also have the following macros:
958
-
959
- * ``FAIL`` : Code to insert at error points. A python exception
960
- should be set prior to this code. An invocation look like this:
961
-
962
- .. code-block:: c
963
-
964
- if (error) {
965
- // Set python exception
966
- FAIL
967
- }
968
-
969
- You can add a semicolon after the macro if it makes your editor
970
- happy.
971
-
972
- * ``PARAMS`` : Name of the params variable for this node. (only
973
- for `Op`\s which have params, which is discussed elsewhere)
974
-
975
- Finally the tag ``code`` and ``code_cleanup`` have macros to
976
- pass the inputs and output names. These are name ``INPUT_{i}`` and
977
- ``OUTPUT_{i}`` where `i` is the 0-based index position in the input
978
- and output arrays respectively.
979
-
980
- Support code
981
- ------------
982
-
983
- Certain section are limited in what you can place in them due to
984
- semantic and syntactic restrictions of the C++ language. Most of
985
- these restrictions apply to the tags that end in ``_struct``.
986
-
987
- When we defined the ``VectorTimesVector`` `Op` without using the ``ExternalCOp``
988
- class, we had to make a distinction between two types of support_code
989
- : the support code that was apply-specific and the support code that
990
- wasn't. The apply-specific code was defined in the
991
- ``c_support_code_apply`` method and the elements defined in that
992
- code (global variables and functions) had to include the name of the
993
- Apply node in their own names to avoid conflicts between the different
994
- versions of the apply-specific code. The code that wasn't
995
- apply-specific was simply defined in the ``c_support_code`` method.
996
-
997
- To make indentifiers that include the :ref:`apply` node name use the
998
- ``APPLY_SPECIFIC(str)`` macro. In the above example, this macro is
999
- used when defining the functions ``vector_elemwise_mult`` and
1000
- ``vector_times_vector`` as well as when calling function
1001
- ``vector_elemwise_mult`` from inside ``vector_times_vector``.
1002
-
1003
- When using the ``ExternalCOp`` class, we still have to make the distinction
1004
- between C code for each of the methods of a C class. These sections of
1005
- code are separated by ``#section <tag>`` markers. The tag determines
1006
- the name of the method this C code applies to with the rule that
1007
- ``<tag>`` applies to `c_<tag>`. Unknown tags are an error and will be
1008
- reported. Duplicate tags will be merged together in the order the
1009
- appear in the C files.
1010
-
1011
- The rules for knowing if where a piece of code should be put can be
1012
- sometimes tricky. The key thing to remember is that things that can
1013
- be shared between instances of the `Op` should be apply-agnostic and go
1014
- into a section which does not end in ``_apply`` or ``_struct``. The
1015
- distinction of ``_apply`` and ``_struct`` mostly hinghes on how you
1016
- want to manage the lifetime of the object. Note that to use an
1017
- apply-specific object, you have to be in a apply-specific section, so
1018
- some portions of the code that might seem apply-agnostic may still be
1019
- apply-specific because of the data they use (this does not include
1020
- arguments).
1021
-
1022
- In the above example, the ``function vector_same_shape`` is
1023
- apply-agnostic because it uses none of the macros defined by the class
1024
- ``ExternalCOp`` and it doesn't rely on any apply-specific code. The function
1025
- ``vector_elemwise_mult`` is apply-specific because it uses the
1026
- macros defined by ``ExternalCOp``. Finally, the function
1027
- ``vector_times_vector`` is apply-specific because it uses those same
1028
- macros and also because it calls ``vector_elemwise_mult`` which is
1029
- an apply-specific function.
1030
-
1031
-
1032
716
  Using GDB to debug :class:`COp`'s C code
1033
717
  ========================================
1034
718
 
@@ -324,229 +324,14 @@ or :class:`PatternNodeRewriter`, it is highly recommended to use them.
324
324
 
325
325
  .. _unification:
326
326
 
327
- Unification and reification
328
- ===========================
329
-
330
- The :class:`PatternNodeRewriter` class uses `unification and reification
331
- <https://en.wikipedia.org/wiki/Unification_(computer_science)>`_ to implement a
332
- more succinct and reusable form of "pattern matching and replacement".
333
- In general, *use of the unification and reification tools is preferable when
334
- a rewrite's matching and replacement are non-trivial*, so we will briefly explain
335
- them in the following.
336
-
337
- PyTensor's unification and reification tools are provided by the
338
- `logical-unification <https://github.com/pythological/unification>`_ package.
339
- The basic tools are :func:`unify`, :func:`reify`, and :class:`var`. The class :class:`var`
340
- construct *logic variables*, which represent the elements to be unified/matched, :func:`unify`
341
- performs the "matching", and :func:`reify` performs the "replacements".
342
-
343
- See :mod:`unification`'s documentation for an introduction to unification and reification.
344
-
345
- In order to use :func:`unify` and :func:`reify` with PyTensor graphs, we need an intermediate
346
- structure that will allow us to represent PyTensor graphs that contain :class:`var`\s, because
347
- PyTensor :class:`Op`\s and :class:`Apply` nodes will not accept these foreign objects as inputs.
348
-
349
- :class:`PatternNodeRewriter` uses Python ``tuple``\s to effectively represent :class:`Apply` nodes and
350
- ``str``\s to represent logic variables (i.e. :class:`var`\s in the :mod:`unification` library).
351
- Behind the scenes, these ``tuple``\s are converted to a ``tuple`` subclass called :class:`ExpressionTuple`\s,
352
- which behave just like normal ``tuple``\s except for some special caching features that allow for easy
353
- evaluation and caching. These :class:`ExpressionTuple`\s are provided by the
354
- `etuples <https://github.com/pythological/etuples>`_ library.
355
-
356
- Here is an illustration of all the above components used together:
357
-
358
- >>> from unification import unify, reify, var
359
- >>> from etuples import etuple
360
- >>> y_lv = var() # Create a logic variable
361
- >>> y_lv
362
- ~_1
363
- >>> s = unify(add(x, y), etuple(add, x, y_lv))
364
- >>> s
365
- {~_1: y}
366
-
367
- In this example, :func:`unify` matched the PyTensor graph in the first argument with the "pattern"
368
- given by the :func:`etuple` in the second. The result is a ``dict`` mapping logic variables to
369
- the objects to which they were successfully unified. When a :func:`unify` doesn't succeed, it will
370
- return ``False``.
371
-
372
- :func:`reify` uses ``dict``\s like the kind produced by :func:`unify` to replace
373
- logic variables within structures:
374
-
375
- >>> res = reify(etuple(add, y_lv, y_lv), s)
376
- >>> res
377
- e(<pytensor.scalar.basic.Add at 0x7f54dfa5a350>, y, y)
378
-
379
- Since :class:`ExpressionTuple`\s can be evaluated, we can produce a complete PyTensor graph from these
380
- results as follows:
381
-
382
- >>> res.evaled_obj
383
- add.0
384
- >>> pytensor.dprint(res.evaled_obj)
385
- add [id A] ''
386
- |y [id B]
387
- |y [id B]
388
-
389
-
390
- Because :class:`ExpressionTuple`\s effectively model `S-expressions
391
- <https://en.wikipedia.org/wiki/S-expression>`_, they can be used with the `cons
392
- <https://github.com/pythological/python-cons>`_ package to unify and reify
393
- graphs structurally.
394
-
395
- Let's say we want to match graphs that use the :class:`add`\ :class:`Op` but could have a
396
- varying number of arguments:
397
-
398
- >>> from cons import cons
399
- >>> op_lv = var()
400
- >>> args_lv = var()
401
- >>> s = unify(cons(op_lv, args_lv), add(x, y))
402
- >>> s
403
- {~_2: <pytensor.scalar.basic.Add at 0x7f54dfa5a350>, ~_3: e(x, y)}
404
- >>> s = unify(cons(op_lv, args_lv), add(x, y, z))
405
- >>> s
406
- {~_2: <pytensor.scalar.basic.Add at 0x7f54dfa5a350>, ~_3: e(x, y, z)}
407
-
408
- From here, we can check ``s[op_lv] == add`` to confirm that we have the correct :class:`Op` and
409
- proceed with our rewrite.
410
-
411
- >>> res = reify(cons(mul, args_lv), s)
412
- >>> res
413
- e(<pytensor.scalar.basic.Mul at 0x7f54dfa5ae10>, x, y, z)
414
- >>> pytensor.dprint(res.evaled_obj)
415
- mul [id A] ''
416
- |x [id B]
417
- |y [id C]
418
- |z [id D]
419
-
420
-
421
- .. _miniKanren_rewrites:
422
-
423
- miniKanren
424
- ==========
425
-
426
- Given that unification and reification are fully implemented for PyTensor objects via the :mod:`unificiation` package,
427
- the `kanren <https://github.com/pythological/kanren>`_ package can be used with PyTensor graphs, as well.
428
- :mod:`kanren` implements the `miniKanren <http://minikanren.org/>`_ domain-specific language for relational programming.
429
-
430
- Refer to the links above for a proper introduction to miniKanren, but suffice it to say that
431
- miniKanren orchestrates the unification and reification operations described in :ref:`unification`, and
432
- it does so in the context of relational operators (e.g. equations like :math:`x + x = 2 x`).
433
- This means that a relation that--say--represents :math:`x + x = 2 x` can be
434
- utilized in both directions.
435
-
436
- Currently, the node rewriter :class:`KanrenRelationSub` provides a means of
437
- turning :mod:`kanren` relations into :class:`NodeRewriter`\s; however,
438
- :mod:`kanren` can always be used directly from within a custom :class:`Rewriter`, so
439
- :class:`KanrenRelationSub` is not necessary.
440
-
441
- The following is an example that distributes dot products across additions.
442
-
443
- .. code::
444
-
445
- import pytensor
446
- import pytensor.tensor as pt
447
- from pytensor.graph.rewriting.kanren import KanrenRelationSub
448
- from pytensor.graph.rewriting.basic import EquilibriumGraphRewriter
449
- from pytensor.graph.rewriting.utils import rewrite_graph
450
- from pytensor.tensor.math import _dot
451
- from etuples import etuple
452
- from kanren import conso, eq, fact, heado, tailo
453
- from kanren.assoccomm import assoc_flatten, associative
454
- from kanren.core import lall
455
- from kanren.graph import mapo
456
- from unification import vars as lvars
457
-
458
-
459
- # Make the graph pretty printing results a little more readable
460
- pytensor.pprint.assign(
461
- _dot, pytensor.printing.OperatorPrinter("@", -1, "left")
462
- )
463
-
464
- # Tell `kanren` that `add` is associative
465
- fact(associative, pt.add)
466
-
467
-
468
- def dot_distributeo(in_lv, out_lv):
469
- """A `kanren` goal constructor relation for the relation ``A.dot(a + b ...) == A.dot(a) + A.dot(b) ...``."""
470
- A_lv, add_term_lv, add_cdr_lv, dot_cdr_lv, add_flat_lv = lvars(5)
471
-
472
- return lall(
473
- # Make sure the input is a `_dot`
474
- eq(in_lv, etuple(_dot, A_lv, add_term_lv)),
475
- # Make sure the term being `_dot`ed is an `add`
476
- heado(pt.add, add_term_lv),
477
- # Flatten the associative pairings of `add` operations
478
- assoc_flatten(add_term_lv, add_flat_lv),
479
- # Get the flattened `add` arguments
480
- tailo(add_cdr_lv, add_flat_lv),
481
- # Add all the `_dot`ed arguments and set the output
482
- conso(pt.add, dot_cdr_lv, out_lv),
483
- # Apply the `_dot` to all the flattened `add` arguments
484
- mapo(lambda x, y: conso(_dot, etuple(A_lv, x), y), add_cdr_lv, dot_cdr_lv),
485
- )
486
-
487
-
488
- dot_distribute_rewrite = EquilibriumGraphRewriter([KanrenRelationSub(dot_distributeo)], max_use_ratio=10)
489
-
490
-
491
- Below, we apply `dot_distribute_rewrite` to a few example graphs. First we create simple test graph:
492
-
493
- >>> x_at = pt.vector("x")
494
- >>> y_at = pt.vector("y")
495
- >>> A_at = pt.matrix("A")
496
- >>> test_at = A_pt.dot(x_at + y_at)
497
- >>> print(pytensor.pprint(test_at))
498
- (A @ (x + y))
499
-
500
- Next we apply the rewrite to the graph:
501
-
502
- >>> res = rewrite_graph(test_at, include=[], custom_rewrite=dot_distribute_rewrite, clone=False)
503
- >>> print(pytensor.pprint(res))
504
- ((A @ x) + (A @ y))
505
-
506
- We see that the dot product has been distributed, as desired. Now, let's try a
507
- few more test cases:
508
-
509
- >>> z_at = pt.vector("z")
510
- >>> w_at = pt.vector("w")
511
- >>> test_at = A_pt.dot((x_at + y_at) + (z_at + w_at))
512
- >>> print(pytensor.pprint(test_at))
513
- (A @ ((x + y) + (z + w)))
514
- >>> res = rewrite_graph(test_at, include=[], custom_rewrite=dot_distribute_rewrite, clone=False)
515
- >>> print(pytensor.pprint(res))
516
- (((A @ x) + (A @ y)) + ((A @ z) + (A @ w)))
517
-
518
- >>> B_at = pt.matrix("B")
519
- >>> w_at = pt.vector("w")
520
- >>> test_at = A_pt.dot(x_at + (y_at + B_pt.dot(z_at + w_at)))
521
- >>> print(pytensor.pprint(test_at))
522
- (A @ (x + (y + ((B @ z) + (B @ w)))))
523
- >>> res = rewrite_graph(test_at, include=[], custom_rewrite=dot_distribute_rewrite, clone=False)
524
- >>> print(pytensor.pprint(res))
525
- ((A @ x) + ((A @ y) + ((A @ (B @ z)) + (A @ (B @ w)))))
526
-
527
-
528
- This example demonstrates how non-trivial matching and replacement logic can
529
- be neatly expressed in miniKanren's DSL, but it doesn't quite demonstrate miniKanren's
530
- relational properties.
531
-
532
- To do that, we will create another :class:`Rewriter` that simply reverses the arguments
533
- to the relation :func:`dot_distributeo` and apply it to the distributed result in ``res``:
534
-
535
- >>> dot_gather_rewrite = EquilibriumGraphRewriter([KanrenRelationSub(lambda x, y: dot_distributeo(y, x))], max_use_ratio=10)
536
- >>> rev_res = rewrite_graph(res, include=[], custom_rewrite=dot_gather_rewrite, clone=False)
537
- >>> print(pytensor.pprint(rev_res))
538
- (A @ (x + (y + (B @ (z + w)))))
539
-
540
- As we can see, the :mod:`kanren` relation works both ways, just like the underlying
541
- mathematical relation does.
542
-
543
- miniKanren relations can be used to explore rewrites of graphs in sophisticated
544
- ways. It also provides a framework that more directly maps to the mathematical
545
- identities that drive graph rewrites. For some simple examples of relational graph rewriting
546
- in :mod:`kanren` see `here <https://github.com/pythological/kanren/blob/master/doc/graphs.md>`_. For a
547
- high-level overview of miniKanren's use as a tool for symbolic computation see
548
- `"miniKanren as a Tool for Symbolic Computation in Python" <https://arxiv.org/abs/2005.11644>`_.
327
+ Unification, reification and miniKanren
328
+ =======================================
549
329
 
330
+ For non-trivial pattern matching and replacement, PyTensor optionally exposes
331
+ :func:`unify` / :func:`reify` over :mod:`logical-unification` and miniKanren
332
+ relations via :class:`KanrenRelationSub`. These rely on a set of optional
333
+ packages (:mod:`logical-unification`, :mod:`kanren`, :mod:`etuples`,
334
+ :mod:`cons`) and are documented separately in :ref:`unification_kanren`.
550
335
 
551
336
  .. _testing_rewrites:
552
337
 
@@ -34,6 +34,7 @@ with PyTensor itself.
34
34
 
35
35
  graphstructures
36
36
  graph_rewriting
37
+ unification_kanren
37
38
  op
38
39
  creating_an_op
39
40
  creating_a_c_op