pytensor 2.31.4__tar.gz → 2.31.5__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 (479) hide show
  1. {pytensor-2.31.4/pytensor.egg-info → pytensor-2.31.5}/PKG-INFO +1 -1
  2. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/gradients.rst +34 -7
  3. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/_version.py +3 -3
  4. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/gradient.py +68 -50
  5. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/graph/replace.py +2 -2
  6. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/basic.py +4 -0
  7. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/random/op.py +7 -0
  8. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/linalg.py +46 -0
  9. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/math.py +31 -0
  10. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/xtensor/__init__.py +1 -1
  11. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/xtensor/math.py +1 -1
  12. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/xtensor/random.py +14 -3
  13. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/xtensor/rewriting/utils.py +11 -1
  14. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/xtensor/rewriting/vectorization.py +1 -1
  15. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/xtensor/shape.py +20 -14
  16. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/xtensor/type.py +10 -4
  17. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/xtensor/vectorization.py +13 -0
  18. {pytensor-2.31.4 → pytensor-2.31.5/pytensor.egg-info}/PKG-INFO +1 -1
  19. {pytensor-2.31.4 → pytensor-2.31.5}/tests/test_gradient.py +201 -150
  20. {pytensor-2.31.4 → pytensor-2.31.5}/LICENSE.txt +0 -0
  21. {pytensor-2.31.4 → pytensor-2.31.5}/MANIFEST.in +0 -0
  22. {pytensor-2.31.4 → pytensor-2.31.5}/README.rst +0 -0
  23. {pytensor-2.31.4 → pytensor-2.31.5}/doc/.templates/PLACEHOLDER +0 -0
  24. {pytensor-2.31.4 → pytensor-2.31.5}/doc/.templates/layout.html +0 -0
  25. {pytensor-2.31.4 → pytensor-2.31.5}/doc/.templates/nb-badges.html +0 -0
  26. {pytensor-2.31.4 → pytensor-2.31.5}/doc/.templates/rendered_citation.html +0 -0
  27. {pytensor-2.31.4 → pytensor-2.31.5}/doc/LICENSE.txt +0 -0
  28. {pytensor-2.31.4 → pytensor-2.31.5}/doc/README.md +0 -0
  29. {pytensor-2.31.4 → pytensor-2.31.5}/doc/acknowledgement.rst +0 -0
  30. {pytensor-2.31.4 → pytensor-2.31.5}/doc/bcast.png +0 -0
  31. {pytensor-2.31.4 → pytensor-2.31.5}/doc/bcast.svg +0 -0
  32. {pytensor-2.31.4 → pytensor-2.31.5}/doc/blog.md +0 -0
  33. {pytensor-2.31.4 → pytensor-2.31.5}/doc/conf.py +0 -0
  34. {pytensor-2.31.4 → pytensor-2.31.5}/doc/core_development_guide.rst +0 -0
  35. {pytensor-2.31.4 → pytensor-2.31.5}/doc/css.inc +0 -0
  36. {pytensor-2.31.4 → pytensor-2.31.5}/doc/dev_start_guide.rst +0 -0
  37. {pytensor-2.31.4 → pytensor-2.31.5}/doc/environment.yml +0 -0
  38. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/apply.png +0 -0
  39. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/apply.svg +0 -0
  40. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/apply2.svg +0 -0
  41. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/creating_a_c_op.rst +0 -0
  42. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/creating_a_numba_jax_op.rst +0 -0
  43. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/creating_an_op.rst +0 -0
  44. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/ctype.rst +0 -0
  45. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/extending_faq.rst +0 -0
  46. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/extending_pytensor_solution_1.py +0 -0
  47. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/graph_rewriting.rst +0 -0
  48. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/graphstructures.rst +0 -0
  49. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/index.rst +0 -0
  50. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/inplace.rst +0 -0
  51. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/op.rst +0 -0
  52. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/other_ops.rst +0 -0
  53. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/pics/symbolic_graph_opt.png +0 -0
  54. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/pics/symbolic_graph_unopt.png +0 -0
  55. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/pipeline.rst +0 -0
  56. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/scan.rst +0 -0
  57. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/tips.rst +0 -0
  58. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/type.rst +0 -0
  59. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/unittest.rst +0 -0
  60. {pytensor-2.31.4 → pytensor-2.31.5}/doc/extending/using_params.rst +0 -0
  61. {pytensor-2.31.4 → pytensor-2.31.5}/doc/faq.rst +0 -0
  62. {pytensor-2.31.4 → pytensor-2.31.5}/doc/gallery/optimize/root.ipynb +0 -0
  63. {pytensor-2.31.4 → pytensor-2.31.5}/doc/gallery/page_footer.md +0 -0
  64. {pytensor-2.31.4 → pytensor-2.31.5}/doc/gallery/rewrites/graph_rewrites.ipynb +0 -0
  65. {pytensor-2.31.4 → pytensor-2.31.5}/doc/gallery/scan/scan_tutorial.ipynb +0 -0
  66. {pytensor-2.31.4 → pytensor-2.31.5}/doc/generate_dtype_tensor_table.py +0 -0
  67. {pytensor-2.31.4 → pytensor-2.31.5}/doc/glossary.rst +0 -0
  68. {pytensor-2.31.4 → pytensor-2.31.5}/doc/images/Elman_srnn.png +0 -0
  69. {pytensor-2.31.4 → pytensor-2.31.5}/doc/images/PyTensor.png +0 -0
  70. {pytensor-2.31.4 → pytensor-2.31.5}/doc/images/PyTensor_RGB.svg +0 -0
  71. {pytensor-2.31.4 → pytensor-2.31.5}/doc/images/PyTensor_logo.png +0 -0
  72. {pytensor-2.31.4 → pytensor-2.31.5}/doc/images/binder.svg +0 -0
  73. {pytensor-2.31.4 → pytensor-2.31.5}/doc/images/blocksparse.png +0 -0
  74. {pytensor-2.31.4 → pytensor-2.31.5}/doc/images/colab.svg +0 -0
  75. {pytensor-2.31.4 → pytensor-2.31.5}/doc/images/github.svg +0 -0
  76. {pytensor-2.31.4 → pytensor-2.31.5}/doc/images/lstm.png +0 -0
  77. {pytensor-2.31.4 → pytensor-2.31.5}/doc/images/lstm_memorycell.png +0 -0
  78. {pytensor-2.31.4 → pytensor-2.31.5}/doc/images/talk2010.gif +0 -0
  79. {pytensor-2.31.4 → pytensor-2.31.5}/doc/images/talk2010.png +0 -0
  80. {pytensor-2.31.4 → pytensor-2.31.5}/doc/index.rst +0 -0
  81. {pytensor-2.31.4 → pytensor-2.31.5}/doc/install.rst +0 -0
  82. {pytensor-2.31.4 → pytensor-2.31.5}/doc/internal/how_to_release.rst +0 -0
  83. {pytensor-2.31.4 → pytensor-2.31.5}/doc/internal/index.rst +0 -0
  84. {pytensor-2.31.4 → pytensor-2.31.5}/doc/internal/metadocumentation.rst +0 -0
  85. {pytensor-2.31.4 → pytensor-2.31.5}/doc/introduction.rst +0 -0
  86. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/compile/debugmode.rst +0 -0
  87. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/compile/function.rst +0 -0
  88. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/compile/index.rst +0 -0
  89. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/compile/io.rst +0 -0
  90. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/compile/mode.rst +0 -0
  91. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/compile/nanguardmode.rst +0 -0
  92. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/compile/opfromgraph.rst +0 -0
  93. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/compile/ops.rst +0 -0
  94. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/compile/profilemode.rst +0 -0
  95. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/compile/shared.rst +0 -0
  96. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/config.rst +0 -0
  97. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/examples/d3viz/css/d3-context-menu.css +0 -0
  98. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/examples/d3viz/css/d3viz.css +0 -0
  99. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/examples/d3viz/js/d3-context-menu.js +0 -0
  100. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/examples/d3viz/js/d3.v3.min.js +0 -0
  101. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/examples/d3viz/js/d3viz.js +0 -0
  102. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/examples/d3viz/js/dagre-d3.min.js +0 -0
  103. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/examples/d3viz/js/graphlib-dot.min.js +0 -0
  104. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/examples/mlp.html +0 -0
  105. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/examples/mlp.png +0 -0
  106. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/examples/mlp2.html +0 -0
  107. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/examples/mlp2.pdf +0 -0
  108. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/examples/mlp2.png +0 -0
  109. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/examples/ofg.html +0 -0
  110. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/examples/ofg2.html +0 -0
  111. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/index.ipynb +0 -0
  112. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/index.rst +0 -0
  113. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/index_files/index_10_0.png +0 -0
  114. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/index_files/index_11_0.png +0 -0
  115. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/index_files/index_24_0.png +0 -0
  116. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/d3viz/index_files/index_25_0.png +0 -0
  117. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/graph/features.rst +0 -0
  118. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/graph/fgraph.rst +0 -0
  119. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/graph/graph.rst +0 -0
  120. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/graph/index.rst +0 -0
  121. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/graph/op.rst +0 -0
  122. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/graph/replace.rst +0 -0
  123. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/graph/type.rst +0 -0
  124. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/graph/utils.rst +0 -0
  125. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/index.rst +0 -0
  126. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/misc/pkl_utils.rst +0 -0
  127. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/printing.rst +0 -0
  128. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/scalar/index.rst +0 -0
  129. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/scan.rst +0 -0
  130. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/sparse/index.rst +0 -0
  131. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/sparse/sandbox.rst +0 -0
  132. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/tensor/basic.rst +0 -0
  133. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/tensor/basic_opt.rst +0 -0
  134. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/tensor/bcast.png +0 -0
  135. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/tensor/bcast.svg +0 -0
  136. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/tensor/conv.rst +0 -0
  137. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/tensor/elemwise.rst +0 -0
  138. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/tensor/extra_ops.rst +0 -0
  139. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/tensor/fft.rst +0 -0
  140. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/tensor/functional.rst +0 -0
  141. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/tensor/index.rst +0 -0
  142. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/tensor/io.rst +0 -0
  143. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/tensor/math_opt.rst +0 -0
  144. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/tensor/nlinalg.rst +0 -0
  145. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/tensor/optimize.rst +0 -0
  146. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/tensor/plot_fft.png +0 -0
  147. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/tensor/random/distributions.rst +0 -0
  148. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/tensor/random/index.rst +0 -0
  149. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/tensor/slinalg.rst +0 -0
  150. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/tensor/utils.rst +0 -0
  151. {pytensor-2.31.4 → pytensor-2.31.5}/doc/library/typed_list.rst +0 -0
  152. {pytensor-2.31.4 → pytensor-2.31.5}/doc/links.rst +0 -0
  153. {pytensor-2.31.4 → pytensor-2.31.5}/doc/optimizations.rst +0 -0
  154. {pytensor-2.31.4 → pytensor-2.31.5}/doc/pylintrc +0 -0
  155. {pytensor-2.31.4 → pytensor-2.31.5}/doc/robots.txt +0 -0
  156. {pytensor-2.31.4 → pytensor-2.31.5}/doc/troubleshooting.rst +0 -0
  157. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/adding.rst +0 -0
  158. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/adding_solution_1.py +0 -0
  159. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/aliasing.rst +0 -0
  160. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/apply.png +0 -0
  161. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/apply.svg +0 -0
  162. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/bcast.png +0 -0
  163. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/broadcasting.rst +0 -0
  164. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/conditions.rst +0 -0
  165. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/debug_faq.rst +0 -0
  166. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/dlogistic.png +0 -0
  167. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/examples.rst +0 -0
  168. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/faq_tutorial.rst +0 -0
  169. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/index.rst +0 -0
  170. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/loading_and_saving.rst +0 -0
  171. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/logistic.gp +0 -0
  172. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/logistic.png +0 -0
  173. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/loop.rst +0 -0
  174. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/loop_solution_1.py +0 -0
  175. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/modes.rst +0 -0
  176. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/modes_solution_1.py +0 -0
  177. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/multi_cores.rst +0 -0
  178. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/nan_tutorial.rst +0 -0
  179. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/pics/d3viz.png +0 -0
  180. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/pics/logreg_pydotprint_predict.png +0 -0
  181. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/pics/logreg_pydotprint_prediction.png +0 -0
  182. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/pics/logreg_pydotprint_train.png +0 -0
  183. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/printing_drawing.rst +0 -0
  184. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/prng.rst +0 -0
  185. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/profiling.rst +0 -0
  186. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/profiling_example.py +0 -0
  187. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/profiling_example_out.prof +0 -0
  188. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/shape_info.rst +0 -0
  189. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/sparse.rst +0 -0
  190. {pytensor-2.31.4 → pytensor-2.31.5}/doc/tutorial/symbolic_graphs.rst +0 -0
  191. {pytensor-2.31.4 → pytensor-2.31.5}/doc/user_guide.rst +0 -0
  192. {pytensor-2.31.4 → pytensor-2.31.5}/pyproject.toml +0 -0
  193. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/__init__.py +0 -0
  194. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/bin/__init__.py +0 -0
  195. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/bin/pytensor_cache.py +0 -0
  196. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/breakpoint.py +0 -0
  197. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/compile/__init__.py +0 -0
  198. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/compile/builders.py +0 -0
  199. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/compile/compiledir.py +0 -0
  200. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/compile/compilelock.py +0 -0
  201. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/compile/debugmode.py +0 -0
  202. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/compile/function/__init__.py +0 -0
  203. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/compile/function/pfunc.py +0 -0
  204. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/compile/function/types.py +0 -0
  205. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/compile/io.py +0 -0
  206. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/compile/mode.py +0 -0
  207. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/compile/monitormode.py +0 -0
  208. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/compile/nanguardmode.py +0 -0
  209. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/compile/ops.py +0 -0
  210. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/compile/profiling.py +0 -0
  211. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/compile/sharedvalue.py +0 -0
  212. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/configdefaults.py +0 -0
  213. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/configparser.py +0 -0
  214. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/d3viz/__init__.py +0 -0
  215. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/d3viz/css/d3-context-menu.css +0 -0
  216. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/d3viz/css/d3viz.css +0 -0
  217. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/d3viz/d3viz.py +0 -0
  218. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/d3viz/formatting.py +0 -0
  219. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/d3viz/html/template.html +0 -0
  220. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/d3viz/js/d3-context-menu.js +0 -0
  221. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/d3viz/js/d3.v3.min.js +0 -0
  222. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/d3viz/js/d3viz.js +0 -0
  223. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/d3viz/js/dagre-d3.min.js +0 -0
  224. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/d3viz/js/graphlib-dot.min.js +0 -0
  225. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/graph/__init__.py +0 -0
  226. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/graph/basic.py +0 -0
  227. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/graph/destroyhandler.py +0 -0
  228. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/graph/features.py +0 -0
  229. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/graph/fg.py +0 -0
  230. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/graph/null_type.py +0 -0
  231. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/graph/op.py +0 -0
  232. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/graph/rewriting/__init__.py +0 -0
  233. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/graph/rewriting/basic.py +0 -0
  234. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/graph/rewriting/db.py +0 -0
  235. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/graph/rewriting/kanren.py +0 -0
  236. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/graph/rewriting/unify.py +0 -0
  237. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/graph/rewriting/utils.py +0 -0
  238. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/graph/type.py +0 -0
  239. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/graph/utils.py +0 -0
  240. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/ifelse.py +0 -0
  241. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/ipython.py +0 -0
  242. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/__init__.py +0 -0
  243. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/basic.py +0 -0
  244. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/c/__init__.py +0 -0
  245. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/c/basic.py +0 -0
  246. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/c/c_code/lazylinker_c.c +0 -0
  247. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/c/c_code/pytensor_mod_helper.h +0 -0
  248. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/c/cmodule.py +0 -0
  249. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/c/cutils.py +0 -0
  250. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/c/cvm.py +0 -0
  251. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/c/exceptions.py +0 -0
  252. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/c/interface.py +0 -0
  253. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/c/lazylinker_c.py +0 -0
  254. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/c/op.py +0 -0
  255. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/c/params_type.py +0 -0
  256. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/c/type.py +0 -0
  257. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/__init__.py +0 -0
  258. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/__init__.py +0 -0
  259. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/basic.py +0 -0
  260. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/blas.py +0 -0
  261. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/blockwise.py +0 -0
  262. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/einsum.py +0 -0
  263. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/elemwise.py +0 -0
  264. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/extra_ops.py +0 -0
  265. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/math.py +0 -0
  266. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/nlinalg.py +0 -0
  267. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/pad.py +0 -0
  268. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/random.py +0 -0
  269. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/scalar.py +0 -0
  270. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/scan.py +0 -0
  271. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/shape.py +0 -0
  272. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/signal/__init__.py +0 -0
  273. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/signal/conv.py +0 -0
  274. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/slinalg.py +0 -0
  275. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/sort.py +0 -0
  276. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/sparse.py +0 -0
  277. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/subtensor.py +0 -0
  278. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/dispatch/tensor_basic.py +0 -0
  279. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/jax/linker.py +0 -0
  280. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/__init__.py +0 -0
  281. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/__init__.py +0 -0
  282. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/basic.py +0 -0
  283. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/blockwise.py +0 -0
  284. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/cython_support.py +0 -0
  285. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/elemwise.py +0 -0
  286. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/extra_ops.py +0 -0
  287. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/linalg/_LAPACK.py +0 -0
  288. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/linalg/__init__.py +0 -0
  289. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/linalg/decomposition/__init__.py +0 -0
  290. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/linalg/decomposition/cholesky.py +0 -0
  291. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/linalg/decomposition/lu.py +0 -0
  292. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/linalg/decomposition/lu_factor.py +0 -0
  293. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/linalg/solve/__init__.py +0 -0
  294. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/linalg/solve/cholesky.py +0 -0
  295. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/linalg/solve/general.py +0 -0
  296. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/linalg/solve/lu_solve.py +0 -0
  297. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/linalg/solve/norm.py +0 -0
  298. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/linalg/solve/posdef.py +0 -0
  299. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/linalg/solve/symmetric.py +0 -0
  300. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/linalg/solve/triangular.py +0 -0
  301. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/linalg/solve/tridiagonal.py +0 -0
  302. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/linalg/solve/utils.py +0 -0
  303. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/linalg/utils.py +0 -0
  304. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/nlinalg.py +0 -0
  305. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/random.py +0 -0
  306. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/scalar.py +0 -0
  307. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/scan.py +0 -0
  308. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/signal/__init__.py +0 -0
  309. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/signal/conv.py +0 -0
  310. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/slinalg.py +0 -0
  311. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/sparse.py +0 -0
  312. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/subtensor.py +0 -0
  313. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/tensor_basic.py +0 -0
  314. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/dispatch/vectorize_codegen.py +0 -0
  315. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/numba/linker.py +0 -0
  316. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/pytorch/dispatch/__init__.py +0 -0
  317. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/pytorch/dispatch/basic.py +0 -0
  318. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/pytorch/dispatch/blas.py +0 -0
  319. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/pytorch/dispatch/blockwise.py +0 -0
  320. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/pytorch/dispatch/elemwise.py +0 -0
  321. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/pytorch/dispatch/extra_ops.py +0 -0
  322. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/pytorch/dispatch/math.py +0 -0
  323. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/pytorch/dispatch/nlinalg.py +0 -0
  324. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/pytorch/dispatch/scalar.py +0 -0
  325. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/pytorch/dispatch/shape.py +0 -0
  326. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/pytorch/dispatch/sort.py +0 -0
  327. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/pytorch/dispatch/subtensor.py +0 -0
  328. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/pytorch/linker.py +0 -0
  329. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/utils.py +0 -0
  330. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/link/vm.py +0 -0
  331. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/misc/__init__.py +0 -0
  332. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/misc/check_blas.py +0 -0
  333. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/misc/check_blas_many.sh +0 -0
  334. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/misc/check_duplicate_key.py +0 -0
  335. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/misc/elemwise_openmp_speedup.py +0 -0
  336. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/misc/elemwise_time_test.py +0 -0
  337. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/misc/frozendict.py +0 -0
  338. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/misc/may_share_memory.py +0 -0
  339. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/misc/ordered_set.py +0 -0
  340. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/misc/pkl_utils.py +0 -0
  341. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/npy_2_compat.py +0 -0
  342. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/printing.py +0 -0
  343. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/py.typed +0 -0
  344. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/raise_op.py +0 -0
  345. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/scalar/__init__.py +0 -0
  346. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/scalar/basic.py +0 -0
  347. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/scalar/c_code/Faddeeva.cc +0 -0
  348. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/scalar/c_code/Faddeeva.hh +0 -0
  349. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/scalar/c_code/gamma.c +0 -0
  350. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/scalar/c_code/incbet.c +0 -0
  351. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/scalar/loop.py +0 -0
  352. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/scalar/math.py +0 -0
  353. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/scalar/sharedvar.py +0 -0
  354. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/scan/__init__.py +0 -0
  355. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/scan/basic.py +0 -0
  356. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/scan/checkpoints.py +0 -0
  357. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/scan/op.py +0 -0
  358. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/scan/rewriting.py +0 -0
  359. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/scan/scan_perform.pyx +0 -0
  360. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/scan/scan_perform_ext.py +0 -0
  361. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/scan/utils.py +0 -0
  362. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/scan/views.py +0 -0
  363. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/sparse/__init__.py +0 -0
  364. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/sparse/basic.py +0 -0
  365. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/sparse/rewriting.py +0 -0
  366. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/sparse/sandbox/__init__.py +0 -0
  367. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/sparse/sandbox/sp.py +0 -0
  368. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/sparse/sandbox/sp2.py +0 -0
  369. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/sparse/sharedvar.py +0 -0
  370. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/sparse/type.py +0 -0
  371. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/sparse/utils.py +0 -0
  372. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/__init__.py +0 -0
  373. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/_linalg/__init__.py +0 -0
  374. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/_linalg/solve/__init__.py +0 -0
  375. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/_linalg/solve/rewriting.py +0 -0
  376. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/_linalg/solve/tridiagonal.py +0 -0
  377. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/blas.py +0 -0
  378. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/blas_c.py +0 -0
  379. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/blas_headers.py +0 -0
  380. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/blas_scipy.py +0 -0
  381. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/blockwise.py +0 -0
  382. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/c_code/alt_blas_common.h +0 -0
  383. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/c_code/alt_blas_template.c +0 -0
  384. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/c_code/dimshuffle.c +0 -0
  385. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/conv/__init__.py +0 -0
  386. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/conv/abstract_conv.py +0 -0
  387. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/einsum.py +0 -0
  388. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/elemwise.py +0 -0
  389. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/elemwise_cgen.py +0 -0
  390. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/exceptions.py +0 -0
  391. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/extra_ops.py +0 -0
  392. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/fft.py +0 -0
  393. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/fourier.py +0 -0
  394. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/functional.py +0 -0
  395. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/inplace.py +0 -0
  396. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/interpolate.py +0 -0
  397. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/io.py +0 -0
  398. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/linalg.py +0 -0
  399. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/math.py +0 -0
  400. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/nlinalg.py +0 -0
  401. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/optimize.py +0 -0
  402. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/pad.py +0 -0
  403. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/random/__init__.py +0 -0
  404. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/random/basic.py +0 -0
  405. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/random/rewriting/__init__.py +0 -0
  406. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/random/rewriting/basic.py +0 -0
  407. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/random/rewriting/jax.py +0 -0
  408. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/random/rewriting/numba.py +0 -0
  409. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/random/type.py +0 -0
  410. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/random/utils.py +0 -0
  411. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/random/var.py +0 -0
  412. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/__init__.py +0 -0
  413. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/basic.py +0 -0
  414. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/blas.py +0 -0
  415. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/blas_c.py +0 -0
  416. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/blas_scipy.py +0 -0
  417. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/blockwise.py +0 -0
  418. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/conv.py +0 -0
  419. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/einsum.py +0 -0
  420. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/elemwise.py +0 -0
  421. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/extra_ops.py +0 -0
  422. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/jax.py +0 -0
  423. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/numba.py +0 -0
  424. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/ofg.py +0 -0
  425. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/shape.py +0 -0
  426. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/special.py +0 -0
  427. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/subtensor.py +0 -0
  428. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/subtensor_lift.py +0 -0
  429. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/rewriting/uncanonicalize.py +0 -0
  430. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/shape.py +0 -0
  431. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/sharedvar.py +0 -0
  432. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/signal/__init__.py +0 -0
  433. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/signal/conv.py +0 -0
  434. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/slinalg.py +0 -0
  435. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/sort.py +0 -0
  436. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/special.py +0 -0
  437. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/subtensor.py +0 -0
  438. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/type.py +0 -0
  439. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/type_other.py +0 -0
  440. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/utils.py +0 -0
  441. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/var.py +0 -0
  442. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/variable.py +0 -0
  443. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/tensor/xlogx.py +0 -0
  444. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/typed_list/__init__.py +0 -0
  445. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/typed_list/basic.py +0 -0
  446. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/typed_list/rewriting.py +0 -0
  447. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/typed_list/type.py +0 -0
  448. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/updates.py +0 -0
  449. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/utils.py +0 -0
  450. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/xtensor/basic.py +0 -0
  451. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/xtensor/indexing.py +0 -0
  452. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/xtensor/linalg.py +0 -0
  453. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/xtensor/reduction.py +0 -0
  454. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/xtensor/rewriting/__init__.py +0 -0
  455. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/xtensor/rewriting/basic.py +0 -0
  456. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/xtensor/rewriting/indexing.py +0 -0
  457. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/xtensor/rewriting/math.py +0 -0
  458. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/xtensor/rewriting/reduction.py +0 -0
  459. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor/xtensor/rewriting/shape.py +0 -0
  460. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor.egg-info/SOURCES.txt +0 -0
  461. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor.egg-info/dependency_links.txt +0 -0
  462. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor.egg-info/entry_points.txt +0 -0
  463. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor.egg-info/requires.txt +0 -0
  464. {pytensor-2.31.4 → pytensor-2.31.5}/pytensor.egg-info/top_level.txt +0 -0
  465. {pytensor-2.31.4 → pytensor-2.31.5}/scripts/mypy-failing.txt +0 -0
  466. {pytensor-2.31.4 → pytensor-2.31.5}/scripts/slowest_tests/update-slowest-times-issue.sh +0 -0
  467. {pytensor-2.31.4 → pytensor-2.31.5}/setup.cfg +0 -0
  468. {pytensor-2.31.4 → pytensor-2.31.5}/setup.py +0 -0
  469. {pytensor-2.31.4 → pytensor-2.31.5}/tests/link/c/c_code/test_cenum.h +0 -0
  470. {pytensor-2.31.4 → pytensor-2.31.5}/tests/link/c/c_code/test_quadratic_function.c +0 -0
  471. {pytensor-2.31.4 → pytensor-2.31.5}/tests/tensor/conv/c_code/corr3d_gemm.c +0 -0
  472. {pytensor-2.31.4 → pytensor-2.31.5}/tests/tensor/conv/c_code/corr_gemm.c +0 -0
  473. {pytensor-2.31.4 → pytensor-2.31.5}/tests/test_breakpoint.py +0 -0
  474. {pytensor-2.31.4 → pytensor-2.31.5}/tests/test_config.py +0 -0
  475. {pytensor-2.31.4 → pytensor-2.31.5}/tests/test_ifelse.py +0 -0
  476. {pytensor-2.31.4 → pytensor-2.31.5}/tests/test_printing.py +0 -0
  477. {pytensor-2.31.4 → pytensor-2.31.5}/tests/test_raise_op.py +0 -0
  478. {pytensor-2.31.4 → pytensor-2.31.5}/tests/test_rop.py +0 -0
  479. {pytensor-2.31.4 → pytensor-2.31.5}/tests/test_updates.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytensor
3
- Version: 2.31.4
3
+ Version: 2.31.5
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
@@ -101,9 +101,12 @@ PyTensor implements the :func:`pytensor.gradient.jacobian` macro that does all
101
101
  that is needed to compute the Jacobian. The following text explains how
102
102
  to do it manually.
103
103
 
104
+ Using Scan
105
+ ----------
106
+
104
107
  In order to manually compute the Jacobian of some function ``y`` with
105
- respect to some parameter ``x`` we need to use `scan`. What we
106
- do is to loop over the entries in ``y`` and compute the gradient of
108
+ respect to some parameter ``x`` we can use `scan`.
109
+ In this case, we loop over the entries in ``y`` and compute the gradient of
107
110
  ``y[i]`` with respect to ``x``.
108
111
 
109
112
  .. note::
@@ -111,8 +114,7 @@ do is to loop over the entries in ``y`` and compute the gradient of
111
114
  `scan` is a generic op in PyTensor that allows writing in a symbolic
112
115
  manner all kinds of recurrent equations. While creating
113
116
  symbolic loops (and optimizing them for performance) is a hard task,
114
- effort is being done for improving the performance of `scan`. We
115
- shall return to :ref:`scan<tutloop>` later in this tutorial.
117
+ efforts are being made to improving the performance of `scan`.
116
118
 
117
119
  >>> import pytensor
118
120
  >>> import pytensor.tensor as pt
@@ -124,9 +126,9 @@ do is to loop over the entries in ``y`` and compute the gradient of
124
126
  array([[ 8., 0.],
125
127
  [ 0., 8.]])
126
128
 
127
- What we do in this code is to generate a sequence of integers from ``0`` to
128
- ``y.shape[0]`` using `pt.arange`. Then we loop through this sequence, and
129
- at each step, we compute the gradient of element ``y[i]`` with respect to
129
+ This code generates a sequence of integers from ``0`` to
130
+ ``y.shape[0]`` using `pt.arange`. Then it loops through this sequence, and
131
+ at each step, computes the gradient of element ``y[i]`` with respect to
130
132
  ``x``. `scan` automatically concatenates all these rows, generating a
131
133
  matrix which corresponds to the Jacobian.
132
134
 
@@ -139,6 +141,31 @@ matrix which corresponds to the Jacobian.
139
141
  ``x`` anymore, while ``y[i]`` still is.
140
142
 
141
143
 
144
+ Using automatic vectorization
145
+ -----------------------------
146
+ An alternative way to build the Jacobian is to vectorize the graph that computes a single row or colum of the jacobian
147
+ We can use `Lop` or `Rop` (more about it below) to obtain the row or column of the jacobian and `vectorize_graph`
148
+ to vectorize it to the full jacobian matrix.
149
+
150
+ >>> import pytensor
151
+ >>> import pytensor.tensor as pt
152
+ >>> from pytensor.gradient import Lop
153
+ >>> from pytensor.graph import vectorize_graph
154
+ >>> x = pt.dvector('x')
155
+ >>> y = x ** 2
156
+ >>> row_cotangent = pt.dvector("row_cotangent") # Helper variable, it will be replaced during vectorization
157
+ >>> J_row = Lop(y, x, row_cotangent)
158
+ >>> J = vectorize_graph(J_row, replace={row_cotangent: pt.eye(x.size)})
159
+ >>> f = pytensor.function([x], J)
160
+ >>> f([4, 4])
161
+ array([[ 8., 0.],
162
+ [ 0., 8.]])
163
+
164
+ This avoids the overhead of scan, at the cost of higher memory usage if the jacobian expression has large intermediate operations.
165
+ Also, not all graphs are safely vectorizable (e.g., if different rows require intermediate operations of different sizes).
166
+ For these reasons `jacobian` uses scan by default. The behavior can be changed by setting `vectorize=True`.
167
+
168
+
142
169
  Computing the Hessian
143
170
  =====================
144
171
 
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2025-06-24T11:04:32+0200",
11
+ "date": "2025-06-30T17:01:33+0200",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "46c2341072820cc1cebe6f77fe754ed63a703988",
15
- "version": "2.31.4"
14
+ "full-revisionid": "2ab60b39e4622b1d9d677ab3e598d752bd25b17e",
15
+ "version": "2.31.5"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -11,7 +11,7 @@ import numpy as np
11
11
  import pytensor
12
12
  from pytensor.compile.ops import ViewOp
13
13
  from pytensor.configdefaults import config
14
- from pytensor.graph import utils
14
+ from pytensor.graph import utils, vectorize_graph
15
15
  from pytensor.graph.basic import Apply, NominalVariable, Variable
16
16
  from pytensor.graph.null_type import NullType, null_type
17
17
  from pytensor.graph.op import get_test_values
@@ -703,15 +703,15 @@ def grad(
703
703
  grad_dict[var] = g_var
704
704
 
705
705
  def handle_disconnected(var):
706
- message = (
707
- "grad method was asked to compute the gradient "
708
- "with respect to a variable that is not part of "
709
- "the computational graph of the cost, or is used "
710
- f"only by a non-differentiable operator: {var}"
711
- )
712
706
  if disconnected_inputs == "ignore":
713
- pass
707
+ return
714
708
  elif disconnected_inputs == "warn":
709
+ message = (
710
+ "grad method was asked to compute the gradient "
711
+ "with respect to a variable that is not part of "
712
+ "the computational graph of the cost, or is used "
713
+ f"only by a non-differentiable operator: {var}"
714
+ )
715
715
  warnings.warn(message, stacklevel=2)
716
716
  elif disconnected_inputs == "raise":
717
717
  message = utils.get_variable_trace_string(var)
@@ -2021,13 +2021,19 @@ GradientError: numeric gradient and analytic gradient exceed tolerance:
2021
2021
  Exception args: {args_msg}"""
2022
2022
 
2023
2023
 
2024
- def jacobian(expression, wrt, consider_constant=None, disconnected_inputs="raise"):
2024
+ def jacobian(
2025
+ expression,
2026
+ wrt,
2027
+ consider_constant=None,
2028
+ disconnected_inputs="raise",
2029
+ vectorize=False,
2030
+ ):
2025
2031
  """
2026
2032
  Compute the full Jacobian, row by row.
2027
2033
 
2028
2034
  Parameters
2029
2035
  ----------
2030
- expression : Vector (1-dimensional) :class:`~pytensor.graph.basic.Variable`
2036
+ expression :class:`~pytensor.graph.basic.Variable`
2031
2037
  Values that we are differentiating (that we want the Jacobian of)
2032
2038
  wrt : :class:`~pytensor.graph.basic.Variable` or list of Variables
2033
2039
  Term[s] with respect to which we compute the Jacobian
@@ -2051,18 +2057,18 @@ def jacobian(expression, wrt, consider_constant=None, disconnected_inputs="raise
2051
2057
  output, then a zero variable is returned. The return value is
2052
2058
  of same type as `wrt`: a list/tuple or TensorVariable in all cases.
2053
2059
  """
2060
+ from pytensor.tensor.basic import eye
2061
+ from pytensor.tensor.extra_ops import broadcast_to
2054
2062
 
2055
2063
  if not isinstance(expression, Variable):
2056
2064
  raise TypeError("jacobian expects a Variable as `expression`")
2057
2065
 
2058
- if expression.ndim > 1:
2059
- raise ValueError(
2060
- "jacobian expects a 1 dimensional variable as `expression`."
2061
- " If not use flatten to make it a vector"
2062
- )
2063
-
2064
2066
  using_list = isinstance(wrt, list)
2065
2067
  using_tuple = isinstance(wrt, tuple)
2068
+ grad_kwargs = {
2069
+ "consider_constant": consider_constant,
2070
+ "disconnected_inputs": disconnected_inputs,
2071
+ }
2066
2072
 
2067
2073
  if isinstance(wrt, list | tuple):
2068
2074
  wrt = list(wrt)
@@ -2070,43 +2076,55 @@ def jacobian(expression, wrt, consider_constant=None, disconnected_inputs="raise
2070
2076
  wrt = [wrt]
2071
2077
 
2072
2078
  if all(expression.type.broadcastable):
2073
- # expression is just a scalar, use grad
2074
- return as_list_or_tuple(
2075
- using_list,
2076
- using_tuple,
2077
- grad(
2078
- expression.squeeze(),
2079
- wrt,
2080
- consider_constant=consider_constant,
2081
- disconnected_inputs=disconnected_inputs,
2082
- ),
2079
+ jacobian_matrices = grad(expression.squeeze(), wrt, **grad_kwargs)
2080
+
2081
+ elif vectorize:
2082
+ expression_flat = expression.ravel()
2083
+ row_tangent = _float_ones_like(expression_flat).type("row_tangent")
2084
+ jacobian_single_rows = Lop(expression.ravel(), wrt, row_tangent, **grad_kwargs)
2085
+
2086
+ n_rows = expression_flat.size
2087
+ jacobian_matrices = vectorize_graph(
2088
+ jacobian_single_rows,
2089
+ replace={row_tangent: eye(n_rows, dtype=row_tangent.dtype)},
2083
2090
  )
2091
+ if disconnected_inputs != "raise":
2092
+ # If the input is disconnected from the cost, `vectorize_graph` has no effect on the respective jacobian
2093
+ # We have to broadcast the zeros explicitly here
2094
+ for i, (jacobian_single_row, jacobian_matrix) in enumerate(
2095
+ zip(jacobian_single_rows, jacobian_matrices, strict=True)
2096
+ ):
2097
+ if jacobian_single_row.ndim == jacobian_matrix.ndim:
2098
+ jacobian_matrices[i] = broadcast_to(
2099
+ jacobian_matrix, shape=(n_rows, *jacobian_matrix.shape)
2100
+ )
2084
2101
 
2085
- def inner_function(*args):
2086
- idx = args[0]
2087
- expr = args[1]
2088
- rvals = []
2089
- for inp in args[2:]:
2090
- rval = grad(
2091
- expr[idx],
2092
- inp,
2093
- consider_constant=consider_constant,
2094
- disconnected_inputs=disconnected_inputs,
2102
+ else:
2103
+
2104
+ def inner_function(*args):
2105
+ idx, expr, *wrt = args
2106
+ return grad(expr[idx], wrt, **grad_kwargs)
2107
+
2108
+ jacobian_matrices, updates = pytensor.scan(
2109
+ inner_function,
2110
+ sequences=pytensor.tensor.arange(expression.size),
2111
+ non_sequences=[expression.ravel(), *wrt],
2112
+ return_list=True,
2113
+ )
2114
+ if updates:
2115
+ raise ValueError(
2116
+ "The scan used to build the jacobian matrices returned a list of updates"
2095
2117
  )
2096
- rvals.append(rval)
2097
- return rvals
2098
-
2099
- # Computing the gradients does not affect the random seeds on any random
2100
- # generator used n expression (because during computing gradients we are
2101
- # just backtracking over old values. (rp Jan 2012 - if anyone has a
2102
- # counter example please show me)
2103
- jacobs, updates = pytensor.scan(
2104
- inner_function,
2105
- sequences=pytensor.tensor.arange(expression.shape[0]),
2106
- non_sequences=[expression, *wrt],
2107
- )
2108
- assert not updates, "Scan has returned a list of updates; this should not happen."
2109
- return as_list_or_tuple(using_list, using_tuple, jacobs)
2118
+
2119
+ if jacobian_matrices[0].ndim < (expression.ndim + wrt[0].ndim):
2120
+ # There was some raveling or squeezing done prior to getting the jacobians
2121
+ # Reshape into original shapes
2122
+ jacobian_matrices = [
2123
+ jac_matrix.reshape((*expression.shape, *w.shape))
2124
+ for jac_matrix, w in zip(jacobian_matrices, wrt, strict=True)
2125
+ ]
2126
+
2127
+ return as_list_or_tuple(using_list, using_tuple, jacobian_matrices)
2110
2128
 
2111
2129
 
2112
2130
  def hessian(cost, wrt, consider_constant=None, disconnected_inputs="raise"):
@@ -232,13 +232,13 @@ def vectorize_graph(
232
232
  def vectorize_graph(
233
233
  outputs: Sequence[Variable],
234
234
  replace: Mapping[Variable, Variable],
235
- ) -> Sequence[Variable]: ...
235
+ ) -> list[Variable]: ...
236
236
 
237
237
 
238
238
  def vectorize_graph(
239
239
  outputs: Variable | Sequence[Variable],
240
240
  replace: Mapping[Variable, Variable],
241
- ) -> Variable | Sequence[Variable]:
241
+ ) -> Variable | list[Variable]:
242
242
  """Vectorize outputs graph given mapping from old variables to expanded counterparts version.
243
243
 
244
244
  Expanded dimensions must be on the left. Behavior is similar to the functional `numpy.vectorize`.
@@ -3081,6 +3081,10 @@ def flatten(x, ndim=1):
3081
3081
  else:
3082
3082
  dims = (-1,)
3083
3083
 
3084
+ if len(dims) == _x.ndim:
3085
+ # Nothing to ravel
3086
+ return _x
3087
+
3084
3088
  x_reshaped = _x.reshape(dims)
3085
3089
  shape_kept_dims = _x.type.shape[: ndim - 1]
3086
3090
  bcast_new_dim = builtins.all(s == 1 for s in _x.type.shape[ndim - 1 :])
@@ -392,6 +392,13 @@ class RandomVariable(RNGConsumerOp):
392
392
  out_type = TensorType(dtype=self.dtype, shape=static_shape)
393
393
  outputs = (rng.type(), out_type())
394
394
 
395
+ if self.dtype == "floatX":
396
+ # Commit to a specific float type if the Op is still using "floatX"
397
+ dtype = config.floatX
398
+ props = self._props_dict()
399
+ props["dtype"] = dtype
400
+ self = type(self)(**props)
401
+
395
402
  return Apply(self, inputs, outputs)
396
403
 
397
404
  def batch_ndim(self, node: Apply) -> int:
@@ -47,8 +47,10 @@ from pytensor.tensor.rewriting.basic import (
47
47
  from pytensor.tensor.slinalg import (
48
48
  BlockDiagonal,
49
49
  Cholesky,
50
+ CholeskySolve,
50
51
  Solve,
51
52
  SolveBase,
53
+ SolveTriangular,
52
54
  _bilinear_solve_discrete_lyapunov,
53
55
  block_diag,
54
56
  cholesky,
@@ -908,6 +910,11 @@ def rewrite_cholesky_diag_to_sqrt_diag(fgraph, node):
908
910
  return None
909
911
 
910
912
  [input] = node.inputs
913
+
914
+ # Check if input is a (1, 1) matrix
915
+ if all(input.type.broadcastable[-2:]):
916
+ return [pt.sqrt(input)]
917
+
911
918
  # Check for use of pt.diag first
912
919
  if (
913
920
  input.owner
@@ -1020,3 +1027,42 @@ def slogdet_specialization(fgraph, node):
1020
1027
  k: slogdet_specialization_map[v] for k, v in dummy_replacements.items()
1021
1028
  }
1022
1029
  return replacements
1030
+
1031
+
1032
+ @register_stabilize
1033
+ @register_canonicalize
1034
+ @node_rewriter([Blockwise])
1035
+ def scalar_solve_to_division(fgraph, node):
1036
+ """
1037
+ Replace solve(a, b) with b / a if a is a (1, 1) matrix
1038
+ """
1039
+
1040
+ core_op = node.op.core_op
1041
+ if not isinstance(core_op, SolveBase):
1042
+ return None
1043
+
1044
+ a, b = node.inputs
1045
+ old_out = node.outputs[0]
1046
+ if not all(a.broadcastable[-2:]):
1047
+ return None
1048
+
1049
+ # Special handling for different types of solve
1050
+ match core_op:
1051
+ case SolveTriangular():
1052
+ # Corner case: if user asked for a triangular solve with a unit diagonal, a is taken to be 1
1053
+ new_out = b / a if not core_op.unit_diagonal else b
1054
+ case CholeskySolve():
1055
+ new_out = b / a**2
1056
+ case Solve():
1057
+ new_out = b / a
1058
+ case _:
1059
+ raise NotImplementedError(
1060
+ f"Unsupported core_op type: {type(core_op)} in scalar_solve_to_divison"
1061
+ )
1062
+
1063
+ if core_op.b_ndim == 1:
1064
+ new_out = new_out.squeeze(-1)
1065
+
1066
+ copy_stack_trace(old_out, new_out)
1067
+
1068
+ return [new_out]
@@ -400,6 +400,37 @@ def local_exp_log(fgraph, node):
400
400
  return [exp(x)]
401
401
 
402
402
 
403
+ @register_canonicalize
404
+ @register_specialize
405
+ @node_rewriter([sqrt, sqr])
406
+ def local_sqrt_sqr(fgraph, node):
407
+ x = node.inputs[0]
408
+
409
+ if not (x.owner and isinstance(x.owner.op, Elemwise)):
410
+ return
411
+
412
+ prev_op = x.owner.op.scalar_op
413
+ node_op = node.op.scalar_op
414
+
415
+ # Case for sqrt(sqr(x)) -> |x|
416
+ if isinstance(prev_op, ps.Sqrt) and isinstance(node_op, ps.Sqr):
417
+ new_out = pt_abs(x.owner.inputs[0])
418
+ old_out = node.outputs[0]
419
+
420
+ # Handle potential integer to float cast by sqr
421
+ if new_out.dtype != old_out.dtype:
422
+ new_out = cast(new_out, old_out.dtype)
423
+ return [new_out]
424
+
425
+ # Case for sqr(sqrt(x)) -> x
426
+ if isinstance(prev_op, ps.Sqr) and isinstance(node_op, ps.Sqrt):
427
+ x = x.owner.inputs[0]
428
+ old_out = node.outputs[0]
429
+ new_out = switch(ge(x, 0), x, np.asarray(np.nan, old_out.dtype))
430
+
431
+ return [new_out]
432
+
433
+
403
434
  @register_specialize
404
435
  @node_rewriter([exp, expm1])
405
436
  def local_exp_log_nan_switch(fgraph, node):
@@ -1,7 +1,7 @@
1
1
  import warnings
2
2
 
3
3
  import pytensor.xtensor.rewriting
4
- from pytensor.xtensor import linalg
4
+ from pytensor.xtensor import linalg, random
5
5
  from pytensor.xtensor.math import dot
6
6
  from pytensor.xtensor.shape import concat
7
7
  from pytensor.xtensor.type import (
@@ -101,7 +101,7 @@ round = _as_xelemwise(ps.round_half_to_even)
101
101
  maximum = _as_xelemwise(ps.scalar_maximum)
102
102
  minimum = _as_xelemwise(ps.scalar_minimum)
103
103
  second = _as_xelemwise(ps.second)
104
- sigmoid = _as_xelemwise(ps.sigmoid)
104
+ sigmoid = expit = _as_xelemwise(ps.sigmoid)
105
105
  sign = _as_xelemwise(ps.sign)
106
106
  sin = _as_xelemwise(ps.sin)
107
107
  sinh = _as_xelemwise(ps.sinh)
@@ -5,8 +5,8 @@ from typing import Literal
5
5
  import pytensor.tensor.random.basic as ptr
6
6
  from pytensor.graph.basic import Variable
7
7
  from pytensor.tensor.random.op import RandomVariable
8
- from pytensor.xtensor import as_xtensor
9
8
  from pytensor.xtensor.math import sqrt
9
+ from pytensor.xtensor.type import as_xtensor
10
10
  from pytensor.xtensor.vectorization import XRV
11
11
 
12
12
 
@@ -14,6 +14,7 @@ def _as_xrv(
14
14
  core_op: RandomVariable,
15
15
  core_inps_dims_map: Sequence[Sequence[int]] | None = None,
16
16
  core_out_dims_map: Sequence[int] | None = None,
17
+ name: str | None = None,
17
18
  ):
18
19
  """Helper function to define an XRV constructor.
19
20
 
@@ -41,7 +42,14 @@ def _as_xrv(
41
42
  core_out_dims_map = tuple(range(core_op.ndim_supp))
42
43
 
43
44
  core_dims_needed = max(
44
- (*(len(i) for i in core_inps_dims_map), len(core_out_dims_map)), default=0
45
+ max(
46
+ (
47
+ max((entry + 1 for entry in dims_map), default=0)
48
+ for dims_map in core_inps_dims_map
49
+ ),
50
+ default=0,
51
+ ),
52
+ max((entry + 1 for entry in core_out_dims_map), default=0),
45
53
  )
46
54
 
47
55
  @wraps(core_op)
@@ -76,7 +84,10 @@ def _as_xrv(
76
84
  extra_dims = {}
77
85
 
78
86
  return XRV(
79
- core_op, core_dims=full_core_dims, extra_dims=tuple(extra_dims.keys())
87
+ core_op,
88
+ core_dims=full_core_dims,
89
+ extra_dims=tuple(extra_dims.keys()),
90
+ name=name,
80
91
  )(rng, *extra_dims.values(), *params)
81
92
 
82
93
  return xrv_constructor
@@ -1,6 +1,7 @@
1
1
  from pytensor.compile import optdb
2
- from pytensor.graph.rewriting.basic import NodeRewriter
2
+ from pytensor.graph.rewriting.basic import NodeRewriter, in2out
3
3
  from pytensor.graph.rewriting.db import EquilibriumDB, RewriteDatabase
4
+ from pytensor.tensor.rewriting.ofg import inline_ofg_expansion
4
5
 
5
6
 
6
7
  lower_xtensor_db = EquilibriumDB(ignore_newtrees=False)
@@ -14,6 +15,15 @@ optdb.register(
14
15
  position=0.1,
15
16
  )
16
17
 
18
+ # Register OFG inline again after lowering xtensor
19
+ optdb.register(
20
+ "inline_ofg_expansion_xtensor",
21
+ in2out(inline_ofg_expansion),
22
+ "fast_run",
23
+ "fast_compile",
24
+ position=0.11,
25
+ )
26
+
17
27
 
18
28
  def register_lower_xtensor(
19
29
  node_rewriter: RewriteDatabase | NodeRewriter | str, *tags: str, **kwargs
@@ -116,7 +116,7 @@ def lower_rv(fgraph, node):
116
116
  size = [*extra_dim_lengths, *param_batch_shape]
117
117
 
118
118
  # RVs are their own core Op
119
- new_next_rng, tensor_out = core_op(*tensor_params, rng=rng, size=size).owner.outputs
119
+ new_next_rng, tensor_out = core_op.make_node(rng, size, *tensor_params).outputs
120
120
 
121
121
  # Convert output Tensors to XTensors
122
122
  new_out = xtensor_from_tensor(tensor_out, dims=old_out.type.dims)
@@ -189,7 +189,7 @@ class Transpose(XOp):
189
189
 
190
190
  def transpose(
191
191
  x,
192
- *dims: str | EllipsisType,
192
+ *dim: str | EllipsisType,
193
193
  missing_dims: Literal["raise", "warn", "ignore"] = "raise",
194
194
  ):
195
195
  """Transpose dimensions of the tensor.
@@ -198,7 +198,7 @@ def transpose(
198
198
  ----------
199
199
  x : XTensorVariable
200
200
  Input tensor to transpose.
201
- *dims : str
201
+ *dim : str
202
202
  Dimensions to transpose to. Can include ellipsis (...) to represent
203
203
  remaining dimensions in their original order.
204
204
  missing_dims : {"raise", "warn", "ignore"}, optional
@@ -220,7 +220,7 @@ def transpose(
220
220
  # Validate dimensions
221
221
  x = as_xtensor(x)
222
222
  x_dims = x.type.dims
223
- invalid_dims = set(dims) - {..., *x_dims}
223
+ invalid_dims = set(dim) - {..., *x_dims}
224
224
  if invalid_dims:
225
225
  if missing_dims != "ignore":
226
226
  msg = f"Dimensions {invalid_dims} do not exist. Expected one or more of: {x_dims}"
@@ -229,21 +229,27 @@ def transpose(
229
229
  else:
230
230
  warnings.warn(msg)
231
231
  # Handle missing dimensions if not raising
232
- dims = tuple(d for d in dims if d in x_dims or d is ...)
233
-
234
- if dims == () or dims == (...,):
235
- dims = tuple(reversed(x_dims))
236
- elif ... in dims:
237
- if dims.count(...) > 1:
232
+ dim = tuple(d for d in dim if d in x_dims or d is ...)
233
+
234
+ if dim == ():
235
+ dim = tuple(reversed(x_dims))
236
+ elif dim == (...,):
237
+ dim = x_dims
238
+ elif ... in dim:
239
+ if dim.count(...) > 1:
238
240
  raise ValueError("Ellipsis (...) can only appear once in the dimensions")
239
241
  # Handle ellipsis expansion
240
- ellipsis_idx = dims.index(...)
241
- pre = dims[:ellipsis_idx]
242
- post = dims[ellipsis_idx + 1 :]
242
+ ellipsis_idx = dim.index(...)
243
+ pre = dim[:ellipsis_idx]
244
+ post = dim[ellipsis_idx + 1 :]
243
245
  middle = [d for d in x_dims if d not in pre + post]
244
- dims = (*pre, *middle, *post)
246
+ dim = (*pre, *middle, *post)
247
+
248
+ if dim == x_dims:
249
+ # No-op transpose
250
+ return x
245
251
 
246
- return Transpose(typing.cast(tuple[str], dims))(x)
252
+ return Transpose(dims=typing.cast(tuple[str], dim))(x)
247
253
 
248
254
 
249
255
  class Concat(XOp):
@@ -71,6 +71,8 @@ class XTensorType(Type, HasDataType, HasShape):
71
71
  self.name = name
72
72
  self.numpy_dtype = np.dtype(self.dtype)
73
73
  self.filter_checks_isfinite = False
74
+ # broadcastable is here just for code that would work fine with XTensorType but checks for it
75
+ self.broadcastable = (False,) * self.ndim
74
76
 
75
77
  def clone(
76
78
  self,
@@ -93,6 +95,10 @@ class XTensorType(Type, HasDataType, HasShape):
93
95
  self, value, strict=strict, allow_downcast=allow_downcast
94
96
  )
95
97
 
98
+ @staticmethod
99
+ def may_share_memory(a, b):
100
+ return TensorType.may_share_memory(a, b)
101
+
96
102
  def filter_variable(self, other, allow_convert=True):
97
103
  if not isinstance(other, Variable):
98
104
  # The value is not a Variable: we cast it into
@@ -160,7 +166,7 @@ class XTensorType(Type, HasDataType, HasShape):
160
166
  return None
161
167
 
162
168
  def __repr__(self):
163
- return f"XTensorType({self.dtype}, {self.dims}, {self.shape})"
169
+ return f"XTensorType({self.dtype}, shape={self.shape}, dims={self.dims})"
164
170
 
165
171
  def __hash__(self):
166
172
  return hash((type(self), self.dtype, self.shape, self.dims))
@@ -691,14 +697,14 @@ class XTensorVariable(Variable[_XTensorTypeType, OptionalApplyType]):
691
697
  # https://docs.xarray.dev/en/latest/api.html#id8
692
698
  def transpose(
693
699
  self,
694
- *dims: str | EllipsisType,
700
+ *dim: str | EllipsisType,
695
701
  missing_dims: Literal["raise", "warn", "ignore"] = "raise",
696
702
  ):
697
703
  """Transpose dimensions of the tensor.
698
704
 
699
705
  Parameters
700
706
  ----------
701
- *dims : str | Ellipsis
707
+ *dim : str | Ellipsis
702
708
  Dimensions to transpose. If empty, performs a full transpose.
703
709
  Can use ellipsis (...) to represent remaining dimensions.
704
710
  missing_dims : {"raise", "warn", "ignore"}, default="raise"
@@ -718,7 +724,7 @@ class XTensorVariable(Variable[_XTensorTypeType, OptionalApplyType]):
718
724
  If missing_dims="raise" and any dimensions don't exist.
719
725
  If multiple ellipsis are provided.
720
726
  """
721
- return px.shape.transpose(self, *dims, missing_dims=missing_dims)
727
+ return px.shape.transpose(self, *dim, missing_dims=missing_dims)
722
728
 
723
729
  def stack(self, dim, **dims):
724
730
  return px.shape.stack(self, dim, **dims)
@@ -142,8 +142,12 @@ class XRV(XOp, RNGConsumerOp):
142
142
  core_op,
143
143
  core_dims: tuple[tuple[tuple[str, ...], ...], tuple[str, ...]],
144
144
  extra_dims: tuple[str, ...],
145
+ name: str | None = None,
145
146
  ):
146
147
  super().__init__()
148
+ if name is None:
149
+ name = getattr(core_op, "name", None)
150
+ self.name = name
147
151
  self.core_op = core_op
148
152
  inps_core_dims, out_core_dims = core_dims
149
153
  for operand_dims in (*inps_core_dims, out_core_dims):
@@ -154,6 +158,15 @@ class XRV(XOp, RNGConsumerOp):
154
158
  raise ValueError("size_dims must be unique")
155
159
  self.extra_dims = tuple(extra_dims)
156
160
 
161
+ def __str__(self):
162
+ if self.name is not None:
163
+ name = self.name
164
+ attrs = f"(core_dims={self.core_dims}, extra_dims={self.extra_dims})"
165
+ else:
166
+ name = self.__class__.__name__
167
+ attrs = f"(core_op={self.core_op}, core_dims={self.core_dims}, extra_dims={self.extra_dims})"
168
+ return f"{name}({attrs})"
169
+
157
170
  def update(self, node):
158
171
  # RNG input and update are the first input and output respectively
159
172
  return {node.inputs[0]: node.outputs[0]}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: pytensor
3
- Version: 2.31.4
3
+ Version: 2.31.5
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