pytensor 2.21.0__tar.gz → 2.22.1__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 (407) hide show
  1. {pytensor-2.21.0/pytensor.egg-info → pytensor-2.22.1}/PKG-INFO +1 -1
  2. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/__init__.py +1 -0
  3. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/_version.py +3 -3
  4. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/graph/basic.py +2 -34
  5. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/graph/rewriting/basic.py +1 -1
  6. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/jax/dispatch/random.py +121 -26
  7. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/numba/dispatch/basic.py +55 -21
  8. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/numba/dispatch/random.py +60 -1
  9. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/scalar/basic.py +2 -2
  10. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/random/basic.py +158 -82
  11. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/random/op.py +4 -0
  12. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/random/rewriting/jax.py +40 -1
  13. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/rewriting/basic.py +27 -33
  14. {pytensor-2.21.0 → pytensor-2.22.1/pytensor.egg-info}/PKG-INFO +1 -1
  15. {pytensor-2.21.0 → pytensor-2.22.1}/LICENSE.txt +0 -0
  16. {pytensor-2.21.0 → pytensor-2.22.1}/MANIFEST.in +0 -0
  17. {pytensor-2.21.0 → pytensor-2.22.1}/README.rst +0 -0
  18. {pytensor-2.21.0 → pytensor-2.22.1}/doc/.templates/PLACEHOLDER +0 -0
  19. {pytensor-2.21.0 → pytensor-2.22.1}/doc/.templates/layout.html +0 -0
  20. {pytensor-2.21.0 → pytensor-2.22.1}/doc/LICENSE.txt +0 -0
  21. {pytensor-2.21.0 → pytensor-2.22.1}/doc/README.md +0 -0
  22. {pytensor-2.21.0 → pytensor-2.22.1}/doc/acknowledgement.rst +0 -0
  23. {pytensor-2.21.0 → pytensor-2.22.1}/doc/bcast.png +0 -0
  24. {pytensor-2.21.0 → pytensor-2.22.1}/doc/bcast.svg +0 -0
  25. {pytensor-2.21.0 → pytensor-2.22.1}/doc/conf.py +0 -0
  26. {pytensor-2.21.0 → pytensor-2.22.1}/doc/core_development_guide.rst +0 -0
  27. {pytensor-2.21.0 → pytensor-2.22.1}/doc/css.inc +0 -0
  28. {pytensor-2.21.0 → pytensor-2.22.1}/doc/dev_start_guide.rst +0 -0
  29. {pytensor-2.21.0 → pytensor-2.22.1}/doc/environment.yml +0 -0
  30. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/apply.png +0 -0
  31. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/apply.svg +0 -0
  32. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/apply2.svg +0 -0
  33. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/creating_a_c_op.rst +0 -0
  34. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/creating_a_numba_jax_op.rst +0 -0
  35. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/creating_an_op.rst +0 -0
  36. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/ctype.rst +0 -0
  37. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/extending_faq.rst +0 -0
  38. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/extending_pytensor_solution_1.py +0 -0
  39. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/graph_rewriting.rst +0 -0
  40. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/graphstructures.rst +0 -0
  41. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/index.rst +0 -0
  42. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/inplace.rst +0 -0
  43. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/op.rst +0 -0
  44. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/other_ops.rst +0 -0
  45. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/pics/symbolic_graph_opt.png +0 -0
  46. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/pics/symbolic_graph_unopt.png +0 -0
  47. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/pipeline.rst +0 -0
  48. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/scan.rst +0 -0
  49. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/tips.rst +0 -0
  50. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/type.rst +0 -0
  51. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/unittest.rst +0 -0
  52. {pytensor-2.21.0 → pytensor-2.22.1}/doc/extending/using_params.rst +0 -0
  53. {pytensor-2.21.0 → pytensor-2.22.1}/doc/faq.rst +0 -0
  54. {pytensor-2.21.0 → pytensor-2.22.1}/doc/generate_dtype_tensor_table.py +0 -0
  55. {pytensor-2.21.0 → pytensor-2.22.1}/doc/glossary.rst +0 -0
  56. {pytensor-2.21.0 → pytensor-2.22.1}/doc/images/Elman_srnn.png +0 -0
  57. {pytensor-2.21.0 → pytensor-2.22.1}/doc/images/PyTensor_RGB.svg +0 -0
  58. {pytensor-2.21.0 → pytensor-2.22.1}/doc/images/blocksparse.png +0 -0
  59. {pytensor-2.21.0 → pytensor-2.22.1}/doc/images/lstm.png +0 -0
  60. {pytensor-2.21.0 → pytensor-2.22.1}/doc/images/lstm_memorycell.png +0 -0
  61. {pytensor-2.21.0 → pytensor-2.22.1}/doc/images/talk2010.gif +0 -0
  62. {pytensor-2.21.0 → pytensor-2.22.1}/doc/images/talk2010.png +0 -0
  63. {pytensor-2.21.0 → pytensor-2.22.1}/doc/index.rst +0 -0
  64. {pytensor-2.21.0 → pytensor-2.22.1}/doc/install.rst +0 -0
  65. {pytensor-2.21.0 → pytensor-2.22.1}/doc/internal/how_to_release.rst +0 -0
  66. {pytensor-2.21.0 → pytensor-2.22.1}/doc/internal/index.rst +0 -0
  67. {pytensor-2.21.0 → pytensor-2.22.1}/doc/internal/metadocumentation.rst +0 -0
  68. {pytensor-2.21.0 → pytensor-2.22.1}/doc/introduction.rst +0 -0
  69. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/compile/debugmode.rst +0 -0
  70. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/compile/function.rst +0 -0
  71. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/compile/index.rst +0 -0
  72. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/compile/io.rst +0 -0
  73. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/compile/mode.rst +0 -0
  74. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/compile/nanguardmode.rst +0 -0
  75. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/compile/opfromgraph.rst +0 -0
  76. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/compile/ops.rst +0 -0
  77. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/compile/profilemode.rst +0 -0
  78. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/compile/shared.rst +0 -0
  79. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/config.rst +0 -0
  80. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/examples/d3viz/css/d3-context-menu.css +0 -0
  81. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/examples/d3viz/css/d3viz.css +0 -0
  82. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/examples/d3viz/js/d3-context-menu.js +0 -0
  83. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/examples/d3viz/js/d3.v3.min.js +0 -0
  84. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/examples/d3viz/js/d3viz.js +0 -0
  85. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/examples/d3viz/js/dagre-d3.min.js +0 -0
  86. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/examples/d3viz/js/graphlib-dot.min.js +0 -0
  87. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/examples/mlp.html +0 -0
  88. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/examples/mlp.png +0 -0
  89. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/examples/mlp2.html +0 -0
  90. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/examples/mlp2.pdf +0 -0
  91. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/examples/mlp2.png +0 -0
  92. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/examples/ofg.html +0 -0
  93. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/examples/ofg2.html +0 -0
  94. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/index.ipynb +0 -0
  95. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/index.rst +0 -0
  96. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/index_files/index_10_0.png +0 -0
  97. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/index_files/index_11_0.png +0 -0
  98. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/index_files/index_24_0.png +0 -0
  99. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/d3viz/index_files/index_25_0.png +0 -0
  100. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/gradient.rst +0 -0
  101. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/graph/features.rst +0 -0
  102. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/graph/fgraph.rst +0 -0
  103. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/graph/graph.rst +0 -0
  104. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/graph/index.rst +0 -0
  105. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/graph/op.rst +0 -0
  106. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/graph/type.rst +0 -0
  107. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/graph/utils.rst +0 -0
  108. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/index.rst +0 -0
  109. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/misc/pkl_utils.rst +0 -0
  110. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/printing.rst +0 -0
  111. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/sandbox/index.rst +0 -0
  112. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/sandbox/linalg.rst +0 -0
  113. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/scalar/index.rst +0 -0
  114. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/scan.rst +0 -0
  115. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/sparse/index.rst +0 -0
  116. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/sparse/sandbox.rst +0 -0
  117. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/tensor/basic.rst +0 -0
  118. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/tensor/basic_opt.rst +0 -0
  119. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/tensor/bcast.png +0 -0
  120. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/tensor/bcast.svg +0 -0
  121. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/tensor/conv.rst +0 -0
  122. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/tensor/elemwise.rst +0 -0
  123. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/tensor/extra_ops.rst +0 -0
  124. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/tensor/fft.rst +0 -0
  125. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/tensor/index.rst +0 -0
  126. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/tensor/io.rst +0 -0
  127. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/tensor/math_opt.rst +0 -0
  128. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/tensor/nlinalg.rst +0 -0
  129. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/tensor/plot_fft.png +0 -0
  130. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/tensor/random/basic.rst +0 -0
  131. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/tensor/random/index.rst +0 -0
  132. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/tensor/random/utils.rst +0 -0
  133. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/tensor/slinalg.rst +0 -0
  134. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/tensor/utils.rst +0 -0
  135. {pytensor-2.21.0 → pytensor-2.22.1}/doc/library/typed_list.rst +0 -0
  136. {pytensor-2.21.0 → pytensor-2.22.1}/doc/links.rst +0 -0
  137. {pytensor-2.21.0 → pytensor-2.22.1}/doc/optimizations.rst +0 -0
  138. {pytensor-2.21.0 → pytensor-2.22.1}/doc/pylintrc +0 -0
  139. {pytensor-2.21.0 → pytensor-2.22.1}/doc/sandbox/ccodegen.rst +0 -0
  140. {pytensor-2.21.0 → pytensor-2.22.1}/doc/sandbox/compilation.rst +0 -0
  141. {pytensor-2.21.0 → pytensor-2.22.1}/doc/sandbox/debugging_with_stepmode.rst +0 -0
  142. {pytensor-2.21.0 → pytensor-2.22.1}/doc/sandbox/elemwise_compiler.rst +0 -0
  143. {pytensor-2.21.0 → pytensor-2.22.1}/doc/sandbox/function.rst +0 -0
  144. {pytensor-2.21.0 → pytensor-2.22.1}/doc/sandbox/functional.rst +0 -0
  145. {pytensor-2.21.0 → pytensor-2.22.1}/doc/sandbox/how_to_make_ops.rst +0 -0
  146. {pytensor-2.21.0 → pytensor-2.22.1}/doc/sandbox/index.rst +0 -0
  147. {pytensor-2.21.0 → pytensor-2.22.1}/doc/sandbox/index2.rst +0 -0
  148. {pytensor-2.21.0 → pytensor-2.22.1}/doc/sandbox/interactive_debugger.rst +0 -0
  149. {pytensor-2.21.0 → pytensor-2.22.1}/doc/sandbox/logistic_regression_example.rst +0 -0
  150. {pytensor-2.21.0 → pytensor-2.22.1}/doc/sandbox/performance.rst +0 -0
  151. {pytensor-2.21.0 → pytensor-2.22.1}/doc/sandbox/randomnumbers.rst +0 -0
  152. {pytensor-2.21.0 → pytensor-2.22.1}/doc/sandbox/rethinkccodegen.rst +0 -0
  153. {pytensor-2.21.0 → pytensor-2.22.1}/doc/sandbox/sandbox.rst +0 -0
  154. {pytensor-2.21.0 → pytensor-2.22.1}/doc/sandbox/software.rst +0 -0
  155. {pytensor-2.21.0 → pytensor-2.22.1}/doc/sandbox/sparse.rst +0 -0
  156. {pytensor-2.21.0 → pytensor-2.22.1}/doc/sandbox/tensoroptools.rst +0 -0
  157. {pytensor-2.21.0 → pytensor-2.22.1}/doc/troubleshooting.rst +0 -0
  158. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/adding.rst +0 -0
  159. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/adding_solution_1.py +0 -0
  160. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/aliasing.rst +0 -0
  161. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/apply.png +0 -0
  162. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/apply.svg +0 -0
  163. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/bcast.png +0 -0
  164. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/broadcasting.rst +0 -0
  165. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/conditions.rst +0 -0
  166. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/debug_faq.rst +0 -0
  167. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/dlogistic.png +0 -0
  168. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/examples.rst +0 -0
  169. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/faq_tutorial.rst +0 -0
  170. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/gradients.rst +0 -0
  171. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/index.rst +0 -0
  172. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/loading_and_saving.rst +0 -0
  173. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/logistic.gp +0 -0
  174. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/logistic.png +0 -0
  175. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/loop.rst +0 -0
  176. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/loop_solution_1.py +0 -0
  177. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/modes.rst +0 -0
  178. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/modes_solution_1.py +0 -0
  179. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/multi_cores.rst +0 -0
  180. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/nan_tutorial.rst +0 -0
  181. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/pics/d3viz.png +0 -0
  182. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/pics/logreg_pydotprint_predict.png +0 -0
  183. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/pics/logreg_pydotprint_prediction.png +0 -0
  184. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/pics/logreg_pydotprint_train.png +0 -0
  185. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/printing_drawing.rst +0 -0
  186. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/profiling.rst +0 -0
  187. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/profiling_example.py +0 -0
  188. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/profiling_example_out.prof +0 -0
  189. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/shape_info.rst +0 -0
  190. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/sparse.rst +0 -0
  191. {pytensor-2.21.0 → pytensor-2.22.1}/doc/tutorial/symbolic_graphs.rst +0 -0
  192. {pytensor-2.21.0 → pytensor-2.22.1}/doc/user_guide.rst +0 -0
  193. {pytensor-2.21.0 → pytensor-2.22.1}/pyproject.toml +0 -0
  194. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/bin/__init__.py +0 -0
  195. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/bin/pytensor_cache.py +0 -0
  196. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/breakpoint.py +0 -0
  197. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/compile/__init__.py +0 -0
  198. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/compile/builders.py +0 -0
  199. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/compile/compiledir.py +0 -0
  200. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/compile/compilelock.py +0 -0
  201. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/compile/debugmode.py +0 -0
  202. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/compile/function/__init__.py +0 -0
  203. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/compile/function/pfunc.py +0 -0
  204. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/compile/function/types.py +0 -0
  205. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/compile/io.py +0 -0
  206. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/compile/mode.py +0 -0
  207. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/compile/monitormode.py +0 -0
  208. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/compile/nanguardmode.py +0 -0
  209. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/compile/ops.py +0 -0
  210. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/compile/profiling.py +0 -0
  211. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/compile/sharedvalue.py +0 -0
  212. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/configdefaults.py +0 -0
  213. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/configparser.py +0 -0
  214. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/d3viz/__init__.py +0 -0
  215. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/d3viz/css/d3-context-menu.css +0 -0
  216. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/d3viz/css/d3viz.css +0 -0
  217. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/d3viz/d3viz.py +0 -0
  218. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/d3viz/formatting.py +0 -0
  219. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/d3viz/js/d3-context-menu.js +0 -0
  220. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/d3viz/js/d3.v3.min.js +0 -0
  221. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/d3viz/js/d3viz.js +0 -0
  222. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/d3viz/js/dagre-d3.min.js +0 -0
  223. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/d3viz/js/graphlib-dot.min.js +0 -0
  224. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/gradient.py +0 -0
  225. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/graph/__init__.py +0 -0
  226. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/graph/destroyhandler.py +0 -0
  227. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/graph/features.py +0 -0
  228. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/graph/fg.py +0 -0
  229. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/graph/null_type.py +0 -0
  230. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/graph/op.py +0 -0
  231. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/graph/replace.py +0 -0
  232. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/graph/rewriting/__init__.py +0 -0
  233. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/graph/rewriting/db.py +0 -0
  234. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/graph/rewriting/kanren.py +0 -0
  235. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/graph/rewriting/unify.py +0 -0
  236. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/graph/rewriting/utils.py +0 -0
  237. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/graph/type.py +0 -0
  238. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/graph/utils.py +0 -0
  239. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/ifelse.py +0 -0
  240. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/__init__.py +0 -0
  241. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/basic.py +0 -0
  242. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/c/__init__.py +0 -0
  243. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/c/basic.py +0 -0
  244. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/c/c_code/lazylinker_c.c +0 -0
  245. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/c/c_code/pytensor_mod_helper.h +0 -0
  246. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/c/cmodule.py +0 -0
  247. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/c/cutils.py +0 -0
  248. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/c/cvm.py +0 -0
  249. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/c/exceptions.py +0 -0
  250. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/c/interface.py +0 -0
  251. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/c/lazylinker_c.py +0 -0
  252. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/c/op.py +0 -0
  253. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/c/params_type.py +0 -0
  254. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/c/type.py +0 -0
  255. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/jax/__init__.py +0 -0
  256. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/jax/dispatch/__init__.py +0 -0
  257. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/jax/dispatch/basic.py +0 -0
  258. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/jax/dispatch/blockwise.py +0 -0
  259. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/jax/dispatch/elemwise.py +0 -0
  260. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/jax/dispatch/extra_ops.py +0 -0
  261. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/jax/dispatch/nlinalg.py +0 -0
  262. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/jax/dispatch/scalar.py +0 -0
  263. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/jax/dispatch/scan.py +0 -0
  264. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/jax/dispatch/shape.py +0 -0
  265. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/jax/dispatch/slinalg.py +0 -0
  266. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/jax/dispatch/sparse.py +0 -0
  267. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/jax/dispatch/subtensor.py +0 -0
  268. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/jax/dispatch/tensor_basic.py +0 -0
  269. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/jax/linker.py +0 -0
  270. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/numba/__init__.py +0 -0
  271. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/numba/dispatch/__init__.py +0 -0
  272. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/numba/dispatch/cython_support.py +0 -0
  273. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/numba/dispatch/elemwise.py +0 -0
  274. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/numba/dispatch/elemwise_codegen.py +0 -0
  275. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/numba/dispatch/extra_ops.py +0 -0
  276. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/numba/dispatch/nlinalg.py +0 -0
  277. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/numba/dispatch/scalar.py +0 -0
  278. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/numba/dispatch/scan.py +0 -0
  279. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/numba/dispatch/slinalg.py +0 -0
  280. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/numba/dispatch/sparse.py +0 -0
  281. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/numba/dispatch/tensor_basic.py +0 -0
  282. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/numba/linker.py +0 -0
  283. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/utils.py +0 -0
  284. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/link/vm.py +0 -0
  285. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/misc/__init__.py +0 -0
  286. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/misc/check_blas.py +0 -0
  287. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/misc/check_blas_many.sh +0 -0
  288. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/misc/check_duplicate_key.py +0 -0
  289. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/misc/elemwise_openmp_speedup.py +0 -0
  290. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/misc/elemwise_time_test.py +0 -0
  291. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/misc/frozendict.py +0 -0
  292. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/misc/may_share_memory.py +0 -0
  293. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/misc/ordered_set.py +0 -0
  294. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/misc/pkl_utils.py +0 -0
  295. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/misc/safe_asarray.py +0 -0
  296. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/printing.py +0 -0
  297. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/py.typed +0 -0
  298. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/raise_op.py +0 -0
  299. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/scalar/__init__.py +0 -0
  300. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/scalar/c_code/Faddeeva.cc +0 -0
  301. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/scalar/c_code/Faddeeva.hh +0 -0
  302. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/scalar/c_code/gamma.c +0 -0
  303. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/scalar/loop.py +0 -0
  304. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/scalar/math.py +0 -0
  305. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/scalar/sharedvar.py +0 -0
  306. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/scan/__init__.py +0 -0
  307. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/scan/basic.py +0 -0
  308. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/scan/checkpoints.py +0 -0
  309. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/scan/op.py +0 -0
  310. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/scan/rewriting.py +0 -0
  311. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/scan/scan_perform.pyx +0 -0
  312. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/scan/scan_perform_ext.py +0 -0
  313. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/scan/utils.py +0 -0
  314. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/scan/views.py +0 -0
  315. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/sparse/__init__.py +0 -0
  316. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/sparse/basic.py +0 -0
  317. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/sparse/rewriting.py +0 -0
  318. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/sparse/sandbox/__init__.py +0 -0
  319. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/sparse/sandbox/sp.py +0 -0
  320. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/sparse/sandbox/sp2.py +0 -0
  321. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/sparse/sharedvar.py +0 -0
  322. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/sparse/type.py +0 -0
  323. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/sparse/utils.py +0 -0
  324. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/__init__.py +0 -0
  325. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/basic.py +0 -0
  326. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/blas.py +0 -0
  327. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/blas_c.py +0 -0
  328. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/blas_headers.py +0 -0
  329. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/blas_scipy.py +0 -0
  330. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/blockwise.py +0 -0
  331. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/c_code/alt_blas_common.h +0 -0
  332. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/c_code/alt_blas_template.c +0 -0
  333. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/c_code/dimshuffle.c +0 -0
  334. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/conv/__init__.py +0 -0
  335. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/conv/abstract_conv.py +0 -0
  336. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/elemwise.py +0 -0
  337. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/elemwise_cgen.py +0 -0
  338. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/exceptions.py +0 -0
  339. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/extra_ops.py +0 -0
  340. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/fft.py +0 -0
  341. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/fourier.py +0 -0
  342. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/functional.py +0 -0
  343. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/inplace.py +0 -0
  344. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/io.py +0 -0
  345. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/linalg.py +0 -0
  346. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/math.py +0 -0
  347. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/nlinalg.py +0 -0
  348. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/random/__init__.py +0 -0
  349. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/random/rewriting/__init__.py +0 -0
  350. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/random/rewriting/basic.py +0 -0
  351. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/random/type.py +0 -0
  352. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/random/utils.py +0 -0
  353. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/random/var.py +0 -0
  354. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/rewriting/__init__.py +0 -0
  355. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/rewriting/blas.py +0 -0
  356. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/rewriting/blas_c.py +0 -0
  357. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/rewriting/blas_scipy.py +0 -0
  358. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/rewriting/blockwise.py +0 -0
  359. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/rewriting/elemwise.py +0 -0
  360. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/rewriting/extra_ops.py +0 -0
  361. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/rewriting/jax.py +0 -0
  362. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/rewriting/linalg.py +0 -0
  363. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/rewriting/math.py +0 -0
  364. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/rewriting/shape.py +0 -0
  365. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/rewriting/special.py +0 -0
  366. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/rewriting/subtensor.py +0 -0
  367. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/rewriting/uncanonicalize.py +0 -0
  368. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/shape.py +0 -0
  369. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/sharedvar.py +0 -0
  370. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/slinalg.py +0 -0
  371. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/sort.py +0 -0
  372. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/special.py +0 -0
  373. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/subtensor.py +0 -0
  374. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/type.py +0 -0
  375. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/type_other.py +0 -0
  376. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/utils.py +0 -0
  377. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/var.py +0 -0
  378. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/variable.py +0 -0
  379. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/tensor/xlogx.py +0 -0
  380. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/typed_list/__init__.py +0 -0
  381. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/typed_list/basic.py +0 -0
  382. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/typed_list/rewriting.py +0 -0
  383. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/typed_list/type.py +0 -0
  384. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/updates.py +0 -0
  385. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/utils.py +0 -0
  386. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor/version.py +0 -0
  387. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor.egg-info/SOURCES.txt +0 -0
  388. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor.egg-info/dependency_links.txt +0 -0
  389. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor.egg-info/entry_points.txt +0 -0
  390. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor.egg-info/requires.txt +0 -0
  391. {pytensor-2.21.0 → pytensor-2.22.1}/pytensor.egg-info/top_level.txt +0 -0
  392. {pytensor-2.21.0 → pytensor-2.22.1}/scripts/mypy-failing.txt +0 -0
  393. {pytensor-2.21.0 → pytensor-2.22.1}/setup.cfg +0 -0
  394. {pytensor-2.21.0 → pytensor-2.22.1}/setup.py +0 -0
  395. {pytensor-2.21.0 → pytensor-2.22.1}/tests/link/c/c_code/test_cenum.h +0 -0
  396. {pytensor-2.21.0 → pytensor-2.22.1}/tests/link/c/c_code/test_quadratic_function.c +0 -0
  397. {pytensor-2.21.0 → pytensor-2.22.1}/tests/tensor/conv/c_code/corr3d_gemm.c +0 -0
  398. {pytensor-2.21.0 → pytensor-2.22.1}/tests/tensor/conv/c_code/corr_gemm.c +0 -0
  399. {pytensor-2.21.0 → pytensor-2.22.1}/tests/test_breakpoint.py +0 -0
  400. {pytensor-2.21.0 → pytensor-2.22.1}/tests/test_config.py +0 -0
  401. {pytensor-2.21.0 → pytensor-2.22.1}/tests/test_gradient.py +0 -0
  402. {pytensor-2.21.0 → pytensor-2.22.1}/tests/test_ifelse.py +0 -0
  403. {pytensor-2.21.0 → pytensor-2.22.1}/tests/test_printing.py +0 -0
  404. {pytensor-2.21.0 → pytensor-2.22.1}/tests/test_raise_op.py +0 -0
  405. {pytensor-2.21.0 → pytensor-2.22.1}/tests/test_rop.py +0 -0
  406. {pytensor-2.21.0 → pytensor-2.22.1}/tests/test_updates.py +0 -0
  407. {pytensor-2.21.0 → pytensor-2.22.1}/versioneer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pytensor
3
- Version: 2.21.0
3
+ Version: 2.22.1
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: .. _license:
@@ -159,6 +159,7 @@ def get_underlying_scalar_constant(v):
159
159
  # isort: off
160
160
  import pytensor.tensor.random.var
161
161
  import pytensor.sparse
162
+ from pytensor.ifelse import ifelse
162
163
  from pytensor.scan import checkpoints
163
164
  from pytensor.scan.basic import scan
164
165
  from pytensor.scan.views import foldl, foldr, map, reduce
@@ -8,11 +8,11 @@ import json
8
8
 
9
9
  version_json = '''
10
10
  {
11
- "date": "2024-05-13T21:55:31+0200",
11
+ "date": "2024-05-28T12:10:34+0200",
12
12
  "dirty": false,
13
13
  "error": null,
14
- "full-revisionid": "90da9e61688b0fef8b91106f0e2ae08ee67be1be",
15
- "version": "2.21.0"
14
+ "full-revisionid": "fc21336a67334241d1c9a59383084ce453988d4e",
15
+ "version": "2.22.1"
16
16
  }
17
17
  ''' # END VERSION_JSON
18
18
 
@@ -266,7 +266,7 @@ class Apply(Node, Generic[OpType]):
266
266
 
267
267
  assert isinstance(inputs, list | tuple)
268
268
  remake_node = False
269
- new_inputs: list["Variable"] = list(inputs)
269
+ new_inputs: list[Variable] = list(inputs)
270
270
 
271
271
  # Some Ops like Alloc require the node to always be rebuilt in non-strict mode
272
272
  # as the output type depends on the input values and not just their types
@@ -1272,7 +1272,7 @@ def clone_node_and_cache(
1272
1272
  return None
1273
1273
 
1274
1274
  # Use a cached `Op` clone when available
1275
- new_op: "Op" | None = cast(Optional["Op"], clone_d.get(node.op))
1275
+ new_op: Op | None = cast(Optional["Op"], clone_d.get(node.op))
1276
1276
 
1277
1277
  cloned_inputs: list[Variable] = [cast(Variable, clone_d[i]) for i in node.inputs]
1278
1278
 
@@ -1789,38 +1789,6 @@ def view_roots(node: Variable) -> list[Variable]:
1789
1789
  return [node]
1790
1790
 
1791
1791
 
1792
- def list_of_nodes(
1793
- inputs: Collection[Variable], outputs: Iterable[Variable]
1794
- ) -> list[Apply]:
1795
- r"""Return the `Apply` nodes of the graph between `inputs` and `outputs`.
1796
-
1797
- Parameters
1798
- ----------
1799
- inputs : list of Variable
1800
- Input `Variable`\s.
1801
- outputs : list of Variable
1802
- Output `Variable`\s.
1803
-
1804
- """
1805
-
1806
- def expand(o: Apply) -> list[Apply]:
1807
- return [
1808
- inp.owner
1809
- for inp in o.inputs
1810
- if inp.owner and not any(i in inp.owner.outputs for i in inputs)
1811
- ]
1812
-
1813
- return list(
1814
- cast(
1815
- Iterable[Apply],
1816
- walk(
1817
- [o.owner for o in outputs if o.owner],
1818
- expand,
1819
- ),
1820
- )
1821
- )
1822
-
1823
-
1824
1792
  def apply_depends_on(apply: Apply, depends_on: Apply | Collection[Apply]) -> bool:
1825
1793
  """Determine if any `depends_on` is in the graph given by ``apply``.
1826
1794
 
@@ -1577,7 +1577,7 @@ class PatternNodeRewriter(NodeRewriter):
1577
1577
  """
1578
1578
  from pytensor.graph.rewriting.unify import convert_strs_to_vars
1579
1579
 
1580
- var_map: dict[str, "Var"] = {}
1580
+ var_map: dict[str, Var] = {}
1581
1581
  self.in_pattern = convert_strs_to_vars(in_pattern, var_map=var_map)
1582
1582
  self.out_pattern = convert_strs_to_vars(out_pattern, var_map=var_map)
1583
1583
  self.values_eq_approx = values_eq_approx
@@ -8,6 +8,7 @@ from numpy.random.bit_generator import ( # type: ignore[attr-defined]
8
8
  )
9
9
 
10
10
  import pytensor.tensor.random.basic as ptr
11
+ from pytensor.graph import Constant
11
12
  from pytensor.link.jax.dispatch.basic import jax_funcify, jax_typify
12
13
  from pytensor.link.jax.dispatch.shape import JAXShapeTuple
13
14
  from pytensor.tensor.shape import Shape, Shape_i
@@ -91,33 +92,46 @@ def jax_funcify_RandomVariable(op, node, **kwargs):
91
92
  """JAX implementation of random variables."""
92
93
  rv = node.outputs[1]
93
94
  out_dtype = rv.type.dtype
94
- out_size = rv.type.shape
95
-
96
- if op.ndim_supp > 0:
97
- out_size = node.outputs[1].type.shape[: -op.ndim_supp]
95
+ static_shape = rv.type.shape
96
+
97
+ batch_ndim = op.batch_ndim(node)
98
+
99
+ # Try to pass static size directly to JAX
100
+ static_size = static_shape[:batch_ndim]
101
+ if None in static_size:
102
+ # Sometimes size can be constant folded during rewrites,
103
+ # without the RandomVariable node being updated with new static types
104
+ size_param = node.inputs[1]
105
+ if isinstance(size_param, Constant):
106
+ size_tuple = tuple(size_param.data)
107
+ # PyTensor uses empty size to represent size = None
108
+ if len(size_tuple):
109
+ static_size = tuple(size_param.data)
98
110
 
99
111
  # If one dimension has unknown size, either the size is determined
100
112
  # by a `Shape` operator in which case JAX will compile, or it is
101
113
  # not and we fail gracefully.
102
- if None in out_size:
114
+ if None in static_size:
103
115
  assert_size_argument_jax_compatible(node)
104
116
 
105
117
  def sample_fn(rng, size, dtype, *parameters):
106
118
  # PyTensor uses empty size to represent size = None
107
119
  if jax.numpy.asarray(size).shape == (0,):
108
120
  size = None
109
- return jax_sample_fn(op)(rng, size, out_dtype, *parameters)
121
+ return jax_sample_fn(op, node=node)(rng, size, out_dtype, *parameters)
110
122
 
111
123
  else:
112
124
 
113
125
  def sample_fn(rng, size, dtype, *parameters):
114
- return jax_sample_fn(op)(rng, out_size, out_dtype, *parameters)
126
+ return jax_sample_fn(op, node=node)(
127
+ rng, static_size, out_dtype, *parameters
128
+ )
115
129
 
116
130
  return sample_fn
117
131
 
118
132
 
119
133
  @singledispatch
120
- def jax_sample_fn(op):
134
+ def jax_sample_fn(op, node):
121
135
  name = op.name
122
136
  raise NotImplementedError(
123
137
  f"No JAX implementation for the given distribution: {name}"
@@ -128,7 +142,7 @@ def jax_sample_fn(op):
128
142
  @jax_sample_fn.register(ptr.DirichletRV)
129
143
  @jax_sample_fn.register(ptr.PoissonRV)
130
144
  @jax_sample_fn.register(ptr.MvNormalRV)
131
- def jax_sample_fn_generic(op):
145
+ def jax_sample_fn_generic(op, node):
132
146
  """Generic JAX implementation of random variables."""
133
147
  name = op.name
134
148
  jax_op = getattr(jax.random, name)
@@ -149,7 +163,7 @@ def jax_sample_fn_generic(op):
149
163
  @jax_sample_fn.register(ptr.LogisticRV)
150
164
  @jax_sample_fn.register(ptr.NormalRV)
151
165
  @jax_sample_fn.register(ptr.StandardNormalRV)
152
- def jax_sample_fn_loc_scale(op):
166
+ def jax_sample_fn_loc_scale(op, node):
153
167
  """JAX implementation of random variables in the loc-scale families.
154
168
 
155
169
  JAX only implements the standard version of random variables in the
@@ -174,7 +188,7 @@ def jax_sample_fn_loc_scale(op):
174
188
 
175
189
 
176
190
  @jax_sample_fn.register(ptr.BernoulliRV)
177
- def jax_sample_fn_bernoulli(op):
191
+ def jax_sample_fn_bernoulli(op, node):
178
192
  """JAX implementation of `BernoulliRV`."""
179
193
 
180
194
  # We need a separate dispatch, because there is no dtype argument for Bernoulli in JAX
@@ -189,7 +203,7 @@ def jax_sample_fn_bernoulli(op):
189
203
 
190
204
 
191
205
  @jax_sample_fn.register(ptr.CategoricalRV)
192
- def jax_sample_fn_categorical(op):
206
+ def jax_sample_fn_categorical(op, node):
193
207
  """JAX implementation of `CategoricalRV`."""
194
208
 
195
209
  # We need a separate dispatch because Categorical expects logits in JAX
@@ -208,7 +222,7 @@ def jax_sample_fn_categorical(op):
208
222
  @jax_sample_fn.register(ptr.RandIntRV)
209
223
  @jax_sample_fn.register(ptr.IntegersRV)
210
224
  @jax_sample_fn.register(ptr.UniformRV)
211
- def jax_sample_fn_uniform(op):
225
+ def jax_sample_fn_uniform(op, node):
212
226
  """JAX implementation of random variables with uniform density.
213
227
 
214
228
  We need to pass the arguments as keyword arguments since the order
@@ -236,7 +250,7 @@ def jax_sample_fn_uniform(op):
236
250
 
237
251
  @jax_sample_fn.register(ptr.ParetoRV)
238
252
  @jax_sample_fn.register(ptr.GammaRV)
239
- def jax_sample_fn_shape_scale(op):
253
+ def jax_sample_fn_shape_scale(op, node):
240
254
  """JAX implementation of random variables in the shape-scale family.
241
255
 
242
256
  JAX only implements the standard version of random variables in the
@@ -259,7 +273,7 @@ def jax_sample_fn_shape_scale(op):
259
273
 
260
274
 
261
275
  @jax_sample_fn.register(ptr.ExponentialRV)
262
- def jax_sample_fn_exponential(op):
276
+ def jax_sample_fn_exponential(op, node):
263
277
  """JAX implementation of `ExponentialRV`."""
264
278
 
265
279
  def sample_fn(rng, size, dtype, scale):
@@ -275,7 +289,7 @@ def jax_sample_fn_exponential(op):
275
289
 
276
290
 
277
291
  @jax_sample_fn.register(ptr.StudentTRV)
278
- def jax_sample_fn_t(op):
292
+ def jax_sample_fn_t(op, node):
279
293
  """JAX implementation of `StudentTRV`."""
280
294
 
281
295
  def sample_fn(rng, size, dtype, df, loc, scale):
@@ -290,30 +304,111 @@ def jax_sample_fn_t(op):
290
304
  return sample_fn
291
305
 
292
306
 
293
- @jax_sample_fn.register(ptr.ChoiceRV)
294
- def jax_funcify_choice(op):
307
+ @jax_sample_fn.register(ptr.ChoiceWithoutReplacement)
308
+ def jax_funcify_choice(op, node):
295
309
  """JAX implementation of `ChoiceRV`."""
296
310
 
311
+ batch_ndim = op.batch_ndim(node)
312
+ a, *p, core_shape = node.inputs[3:]
313
+ a_core_ndim, *p_core_ndim, _ = op.ndims_params
314
+
315
+ if batch_ndim and a_core_ndim == 0:
316
+ raise NotImplementedError(
317
+ "Batch dimensions are not supported for 0d arrays. "
318
+ "A default JAX rewrite should have materialized the implicit arange"
319
+ )
320
+
321
+ a_batch_ndim = a.type.ndim - a_core_ndim
322
+ if op.has_p_param:
323
+ [p] = p
324
+ [p_core_ndim] = p_core_ndim
325
+ p_batch_ndim = p.type.ndim - p_core_ndim
326
+
297
327
  def sample_fn(rng, size, dtype, *parameters):
298
328
  rng_key = rng["jax_state"]
299
329
  rng_key, sampling_key = jax.random.split(rng_key, 2)
300
- (a, p, replace) = parameters
301
- smpl_value = jax.random.choice(sampling_key, a, size, replace, p)
330
+
331
+ if op.has_p_param:
332
+ a, p, core_shape = parameters
333
+ else:
334
+ a, core_shape = parameters
335
+ p = None
336
+ core_shape = tuple(np.asarray(core_shape))
337
+
338
+ if batch_ndim == 0:
339
+ sample = jax.random.choice(
340
+ sampling_key, a, shape=core_shape, replace=False, p=p
341
+ )
342
+
343
+ else:
344
+ if size is None:
345
+ if p is None:
346
+ size = a.shape[:a_batch_ndim]
347
+ else:
348
+ size = jax.numpy.broadcast_shapes(
349
+ a.shape[:a_batch_ndim],
350
+ p.shape[:p_batch_ndim],
351
+ )
352
+
353
+ a = jax.numpy.broadcast_to(a, size + a.shape[a_batch_ndim:])
354
+ if p is not None:
355
+ p = jax.numpy.broadcast_to(p, size + p.shape[p_batch_ndim:])
356
+
357
+ batch_sampling_keys = jax.random.split(sampling_key, np.prod(size))
358
+
359
+ # Ravel the batch dimensions because vmap only works along a single axis
360
+ raveled_batch_a = a.reshape((-1,) + a.shape[batch_ndim:])
361
+ if p is None:
362
+ raveled_sample = jax.vmap(
363
+ lambda key, a: jax.random.choice(
364
+ key, a, shape=core_shape, replace=False, p=None
365
+ )
366
+ )(batch_sampling_keys, raveled_batch_a)
367
+ else:
368
+ raveled_batch_p = p.reshape((-1,) + p.shape[batch_ndim:])
369
+ raveled_sample = jax.vmap(
370
+ lambda key, a, p: jax.random.choice(
371
+ key, a, shape=core_shape, replace=False, p=p
372
+ )
373
+ )(batch_sampling_keys, raveled_batch_a, raveled_batch_p)
374
+
375
+ # Reshape the batch dimensions
376
+ sample = raveled_sample.reshape(size + raveled_sample.shape[1:])
377
+
302
378
  rng["jax_state"] = rng_key
303
- return (rng, smpl_value)
379
+ return (rng, sample)
304
380
 
305
381
  return sample_fn
306
382
 
307
383
 
308
384
  @jax_sample_fn.register(ptr.PermutationRV)
309
- def jax_sample_fn_permutation(op):
385
+ def jax_sample_fn_permutation(op, node):
310
386
  """JAX implementation of `PermutationRV`."""
311
387
 
388
+ batch_ndim = op.batch_ndim(node)
389
+ x_batch_ndim = node.inputs[-1].type.ndim - op.ndims_params[0]
390
+
312
391
  def sample_fn(rng, size, dtype, *parameters):
313
392
  rng_key = rng["jax_state"]
314
393
  rng_key, sampling_key = jax.random.split(rng_key, 2)
315
394
  (x,) = parameters
316
- sample = jax.random.permutation(sampling_key, x)
395
+ if batch_ndim:
396
+ # jax.random.permutation has no concept of batch dims
397
+ x_core_shape = x.shape[x_batch_ndim:]
398
+ if size is None:
399
+ size = x.shape[:x_batch_ndim]
400
+ else:
401
+ x = jax.numpy.broadcast_to(x, size + x_core_shape)
402
+
403
+ batch_sampling_keys = jax.random.split(sampling_key, np.prod(size))
404
+ raveled_batch_x = x.reshape((-1,) + x.shape[batch_ndim:])
405
+ raveled_sample = jax.vmap(lambda key, x: jax.random.permutation(key, x))(
406
+ batch_sampling_keys, raveled_batch_x
407
+ )
408
+ sample = raveled_sample.reshape(size + raveled_sample.shape[1:])
409
+ else:
410
+ sample = jax.random.permutation(sampling_key, x)
411
+
317
412
  rng["jax_state"] = rng_key
318
413
  return (rng, sample)
319
414
 
@@ -321,7 +416,7 @@ def jax_sample_fn_permutation(op):
321
416
 
322
417
 
323
418
  @jax_sample_fn.register(ptr.BinomialRV)
324
- def jax_sample_fn_binomial(op):
419
+ def jax_sample_fn_binomial(op, node):
325
420
  if not numpyro_available:
326
421
  raise NotImplementedError(
327
422
  f"No JAX implementation for the given distribution: {op.name}. "
@@ -344,7 +439,7 @@ def jax_sample_fn_binomial(op):
344
439
 
345
440
 
346
441
  @jax_sample_fn.register(ptr.MultinomialRV)
347
- def jax_sample_fn_multinomial(op):
442
+ def jax_sample_fn_multinomial(op, node):
348
443
  if not numpyro_available:
349
444
  raise NotImplementedError(
350
445
  f"No JAX implementation for the given distribution: {op.name}. "
@@ -367,7 +462,7 @@ def jax_sample_fn_multinomial(op):
367
462
 
368
463
 
369
464
  @jax_sample_fn.register(ptr.VonMisesRV)
370
- def jax_sample_fn_vonmises(op):
465
+ def jax_sample_fn_vonmises(op, node):
371
466
  if not numpyro_available:
372
467
  raise NotImplementedError(
373
468
  f"No JAX implementation for the given distribution: {op.name}. "
@@ -604,36 +604,70 @@ def numba_funcify_IncSubtensor(op, node, **kwargs):
604
604
  return numba_njit(incsubtensor_fn, boundscheck=True)
605
605
 
606
606
 
607
- @numba_njit(boundscheck=True)
608
- def advancedincsubtensor1_inplace_set(x, vals, idxs):
609
- for idx, val in zip(idxs, vals):
610
- x[idx] = val
611
- return x
612
-
613
-
614
- @numba_njit(boundscheck=True)
615
- def advancedincsubtensor1_inplace_inc(x, vals, idxs):
616
- for idx, val in zip(idxs, vals):
617
- x[idx] += val
618
- return x
619
-
620
-
621
607
  @numba_funcify.register(AdvancedIncSubtensor1)
622
608
  def numba_funcify_AdvancedIncSubtensor1(op, node, **kwargs):
623
609
  inplace = op.inplace
624
610
  set_instead_of_inc = op.set_instead_of_inc
611
+ x, vals, idxs = node.inputs
612
+ # TODO: Add explicit expand_dims in make_node so we don't need to worry about this here
613
+ broadcast = vals.type.ndim < x.type.ndim or vals.type.broadcastable[0]
625
614
 
626
615
  if set_instead_of_inc:
627
- advancedincsubtensor1_inplace = global_numba_func(
628
- advancedincsubtensor1_inplace_set
629
- )
616
+ if broadcast:
617
+
618
+ @numba_njit(boundscheck=True)
619
+ def advancedincsubtensor1_inplace(x, val, idxs):
620
+ if val.ndim == x.ndim:
621
+ core_val = val[0]
622
+ elif val.ndim == 0:
623
+ # Workaround for https://github.com/numba/numba/issues/9573
624
+ core_val = val.item()
625
+ else:
626
+ core_val = val
627
+
628
+ for idx in idxs:
629
+ x[idx] = core_val
630
+ return x
631
+
632
+ else:
633
+
634
+ @numba_njit(boundscheck=True)
635
+ def advancedincsubtensor1_inplace(x, vals, idxs):
636
+ if not len(idxs) == len(vals):
637
+ raise ValueError("The number of indices and values must match.")
638
+ for idx, val in zip(idxs, vals):
639
+ x[idx] = val
640
+ return x
630
641
  else:
631
- advancedincsubtensor1_inplace = global_numba_func(
632
- advancedincsubtensor1_inplace_inc
633
- )
642
+ if broadcast:
643
+
644
+ @numba_njit(boundscheck=True)
645
+ def advancedincsubtensor1_inplace(x, val, idxs):
646
+ if val.ndim == x.ndim:
647
+ core_val = val[0]
648
+ elif val.ndim == 0:
649
+ # Workaround for https://github.com/numba/numba/issues/9573
650
+ core_val = val.item()
651
+ else:
652
+ core_val = val
653
+
654
+ for idx in idxs:
655
+ x[idx] += core_val
656
+ return x
657
+
658
+ else:
659
+
660
+ @numba_njit(boundscheck=True)
661
+ def advancedincsubtensor1_inplace(x, vals, idxs):
662
+ if not len(idxs) == len(vals):
663
+ raise ValueError("The number of indices and values must match.")
664
+ for idx, val in zip(idxs, vals):
665
+ x[idx] += val
666
+ return x
634
667
 
635
668
  if inplace:
636
- return global_numba_func(advancedincsubtensor1_inplace)
669
+ return advancedincsubtensor1_inplace
670
+
637
671
  else:
638
672
 
639
673
  @numba_njit
@@ -210,7 +210,6 @@ def {sized_fn_name}({random_fn_input_names}):
210
210
  @numba_funcify.register(ptr.BinomialRV)
211
211
  @numba_funcify.register(ptr.MultinomialRV)
212
212
  @numba_funcify.register(ptr.RandIntRV) # only the first two arguments are supported
213
- @numba_funcify.register(ptr.ChoiceRV) # the `p` argument is not supported
214
213
  @numba_funcify.register(ptr.PermutationRV)
215
214
  def numba_funcify_RandomVariable(op, node, **kwargs):
216
215
  name = op.name
@@ -367,3 +366,63 @@ def numba_funcify_DirichletRV(op, node, **kwargs):
367
366
  return (rng, np.random.dirichlet(alphas, size))
368
367
 
369
368
  return dirichlet_rv
369
+
370
+
371
+ @numba_funcify.register(ptr.ChoiceWithoutReplacement)
372
+ def numba_funcify_choice_without_replacement(op, node, **kwargs):
373
+ batch_ndim = op.batch_ndim(node)
374
+ if batch_ndim:
375
+ # The code isn't too hard to write, but Numba doesn't support a with ndim > 1,
376
+ # and I don't want to change the batched tests for this
377
+ # We'll just raise an error for now
378
+ raise NotImplementedError(
379
+ "ChoiceWithoutReplacement with batch_ndim not supported in Numba backend"
380
+ )
381
+
382
+ [core_shape_len] = node.inputs[-1].type.shape
383
+
384
+ if op.has_p_param:
385
+
386
+ @numba_basic.numba_njit
387
+ def choice_without_replacement_rv(rng, size, dtype, a, p, core_shape):
388
+ core_shape = numba_ndarray.to_fixed_tuple(core_shape, core_shape_len)
389
+ samples = np.random.choice(a, size=core_shape, replace=False, p=p)
390
+ return (rng, samples)
391
+ else:
392
+
393
+ @numba_basic.numba_njit
394
+ def choice_without_replacement_rv(rng, size, dtype, a, core_shape):
395
+ core_shape = numba_ndarray.to_fixed_tuple(core_shape, core_shape_len)
396
+ samples = np.random.choice(a, size=core_shape, replace=False)
397
+ return (rng, samples)
398
+
399
+ return choice_without_replacement_rv
400
+
401
+
402
+ @numba_funcify.register(ptr.PermutationRV)
403
+ def numba_funcify_permutation(op, node, **kwargs):
404
+ # PyTensor uses size=() to represent size=None
405
+ size_is_none = node.inputs[1].type.shape == (0,)
406
+ batch_ndim = op.batch_ndim(node)
407
+ x_batch_ndim = node.inputs[-1].type.ndim - op.ndims_params[0]
408
+
409
+ @numba_basic.numba_njit
410
+ def permutation_rv(rng, size, dtype, x):
411
+ if batch_ndim:
412
+ x_core_shape = x.shape[x_batch_ndim:]
413
+ if size_is_none:
414
+ size = x.shape[:batch_ndim]
415
+ else:
416
+ size = numba_ndarray.to_fixed_tuple(size, batch_ndim)
417
+ x = np.broadcast_to(x, size + x_core_shape)
418
+
419
+ samples = np.empty(size + x_core_shape, dtype=x.dtype)
420
+ for index in np.ndindex(size):
421
+ samples[index] = np.random.permutation(x[index])
422
+
423
+ else:
424
+ samples = np.random.permutation(x)
425
+
426
+ return (rng, samples)
427
+
428
+ return permutation_rv
@@ -24,7 +24,7 @@ import pytensor
24
24
  from pytensor import printing
25
25
  from pytensor.configdefaults import config
26
26
  from pytensor.gradient import DisconnectedType, grad_undefined
27
- from pytensor.graph.basic import Apply, Constant, Variable, clone, list_of_nodes
27
+ from pytensor.graph.basic import Apply, Constant, Variable, applys_between, clone
28
28
  from pytensor.graph.fg import FunctionGraph
29
29
  from pytensor.graph.op import HasInnerGraph
30
30
  from pytensor.graph.rewriting.basic import MergeOptimizer
@@ -4125,7 +4125,7 @@ class ScalarInnerGraphOp(ScalarOp, HasInnerGraph):
4125
4125
 
4126
4126
  def prepare_node(self, node, storage_map, compute_map, impl):
4127
4127
  if impl not in self.prepare_node_called:
4128
- for n in list_of_nodes(self.inputs, self.outputs):
4128
+ for n in applys_between(self.inputs, self.outputs):
4129
4129
  n.op.prepare_node(n, None, None, impl)
4130
4130
  self.prepare_node_called.add(impl)
4131
4131