spacecore 0.3.2__tar.gz → 0.4.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (424) hide show
  1. spacecore-0.4.0/CHANGELOG.md +556 -0
  2. {spacecore-0.3.2 → spacecore-0.4.0}/MANIFEST.in +0 -1
  3. spacecore-0.4.0/PKG-INFO +340 -0
  4. spacecore-0.4.0/README.md +296 -0
  5. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/adr/003_space_hierarchy.md +2 -2
  6. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/adr/005_space_subclasses_and_capabilities.md +2 -2
  7. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/adr/008_linop_subclasses.md +2 -2
  8. spacecore-0.4.0/docs/dev/adr/013_tree_structured_spaces.md +54 -0
  9. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/adr/014_check_policy.md +10 -2
  10. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/adr/015_dtype_default_vs_scalar_field.md +5 -3
  11. spacecore-0.4.0/docs/dev/adr/016_kernel_layers.md +242 -0
  12. spacecore-0.4.0/docs/dev/adr/017_tensor_product_spaces.md +131 -0
  13. spacecore-0.4.0/docs/dev/adr/018_external_optimizer_adapters.md +111 -0
  14. spacecore-0.4.0/docs/dev/adr/019_everyday_toolbox.md +159 -0
  15. spacecore-0.4.0/docs/dev/adr/020_sets_and_projection.md +108 -0
  16. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/adr/README.md +6 -3
  17. spacecore-0.4.0/docs/dev/adr/template.md +33 -0
  18. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/contributing/architecture.md +8 -10
  19. spacecore-0.4.0/docs/dev/contributing/linop_generators.md +47 -0
  20. spacecore-0.4.0/docs/dev/current.md +156 -0
  21. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/api/context.rst +3 -0
  22. spacecore-0.4.0/docs/source/api/functionals.rst +160 -0
  23. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/api/index.rst +1 -0
  24. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/api/linops.rst +21 -7
  25. spacecore-0.4.0/docs/source/api/optimize.rst +59 -0
  26. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/api/spaces.rst +17 -26
  27. spacecore-0.4.0/docs/source/design/backend_conformance.rst +452 -0
  28. spacecore-0.4.0/docs/source/design/backend_deviations.rst +138 -0
  29. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/design/batching.rst +6 -0
  30. spacecore-0.4.0/docs/source/design/batching_test_policy.rst +78 -0
  31. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/design/capability_dispatch.rst +2 -2
  32. spacecore-0.4.0/docs/source/design/checking_policy.rst +100 -0
  33. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/design/context_ownership.rst +14 -10
  34. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/design/conversion_policy.rst +3 -3
  35. spacecore-0.4.0/docs/source/design/dtype_policy.rst +92 -0
  36. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/design/index.rst +5 -0
  37. spacecore-0.4.0/docs/source/design/kernels_policy.rst +218 -0
  38. spacecore-0.4.0/docs/source/design/tree_spaces.rst +192 -0
  39. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/dev/contributing.rst +6 -0
  40. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/index.rst +8 -4
  41. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/release_notes.rst +101 -0
  42. spacecore-0.4.0/docs/source/tutorials/01_backend_and_context.rst +349 -0
  43. spacecore-0.4.0/docs/source/tutorials/02_linear_algebra.rst +289 -0
  44. spacecore-0.4.0/docs/source/tutorials/03_functionals.rst +270 -0
  45. spacecore-0.4.0/docs/source/tutorials/04_tree_spaces.rst +302 -0
  46. spacecore-0.4.0/docs/source/tutorials/05_weighted_tikhonov.rst +285 -0
  47. spacecore-0.4.0/docs/source/tutorials/06_optimal_transport.rst +263 -0
  48. spacecore-0.4.0/docs/source/tutorials/07_manifold_descent.rst +235 -0
  49. spacecore-0.4.0/docs/source/tutorials/08_pdhg_conic_program.rst +257 -0
  50. spacecore-0.4.0/docs/source/tutorials/index.rst +36 -0
  51. {spacecore-0.3.2 → spacecore-0.4.0}/pyproject.toml +15 -1
  52. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/__init__.py +49 -17
  53. spacecore-0.4.0/spacecore/_batching.py +59 -0
  54. spacecore-0.4.0/spacecore/_check_policy.py +88 -0
  55. spacecore-0.4.0/spacecore/_checks.py +137 -0
  56. spacecore-0.4.0/spacecore/_contextual/_bound.py +173 -0
  57. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/_contextual/_state.py +77 -25
  58. spacecore-0.4.0/spacecore/_repr.py +150 -0
  59. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/_version.py +1 -1
  60. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/backend/__init__.py +3 -0
  61. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/backend/_context.py +59 -21
  62. spacecore-0.4.0/spacecore/backend/_eager.py +178 -0
  63. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/backend/_ops.py +227 -11
  64. spacecore-0.4.0/spacecore/backend/cupy/_ops.py +154 -0
  65. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/backend/jax/_ops.py +31 -19
  66. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/backend/jax/_pytree.py +1 -1
  67. spacecore-0.4.0/spacecore/backend/numpy/_ops.py +304 -0
  68. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/backend/torch/_ops.py +33 -205
  69. spacecore-0.4.0/spacecore/functional/__init__.py +52 -0
  70. spacecore-0.4.0/spacecore/functional/_base.py +161 -0
  71. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/functional/_composed.py +11 -6
  72. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/functional/_linear.py +48 -54
  73. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/functional/_quadratic.py +16 -34
  74. spacecore-0.4.0/spacecore/functional/tools/__init__.py +29 -0
  75. spacecore-0.4.0/spacecore/functional/tools/_coordinate.py +72 -0
  76. spacecore-0.4.0/spacecore/functional/tools/_entropy.py +148 -0
  77. spacecore-0.4.0/spacecore/functional/tools/_huber.py +79 -0
  78. spacecore-0.4.0/spacecore/functional/tools/_least_squares.py +114 -0
  79. spacecore-0.4.0/spacecore/functional/tools/_norms.py +157 -0
  80. spacecore-0.4.0/spacecore/functional/tools/_proximal.py +226 -0
  81. spacecore-0.4.0/spacecore/functional/tools/_spectral.py +126 -0
  82. spacecore-0.4.0/spacecore/kernels/__init__.py +80 -0
  83. spacecore-0.4.0/spacecore/kernels/core/__init__.py +36 -0
  84. spacecore-0.4.0/spacecore/kernels/core/_rules.py +154 -0
  85. spacecore-0.4.0/spacecore/kernels/core/algebra.py +245 -0
  86. spacecore-0.4.0/spacecore/kernels/core/dense.py +114 -0
  87. spacecore-0.4.0/spacecore/kernels/core/diagonal.py +114 -0
  88. spacecore-0.4.0/spacecore/kernels/core/functional.py +153 -0
  89. spacecore-0.4.0/spacecore/kernels/core/sparse.py +113 -0
  90. spacecore-0.4.0/spacecore/kernels/specs/__init__.py +61 -0
  91. spacecore-0.4.0/spacecore/kernels/specs/_dispatch.py +289 -0
  92. spacecore-0.4.0/spacecore/kernels/specs/_policy.py +210 -0
  93. spacecore-0.4.0/spacecore/kernels/specs/_registry.py +117 -0
  94. spacecore-0.4.0/spacecore/kernels/specs/block_batched.py +159 -0
  95. spacecore-0.4.0/spacecore/kernels/specs/block_diagonal.py +91 -0
  96. spacecore-0.4.0/spacecore/kernels/specs/composed.py +90 -0
  97. spacecore-0.4.0/spacecore/kernels/specs/composed_simplify.py +140 -0
  98. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/linalg/_cg.py +46 -16
  99. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/linalg/_lanczos.py +10 -8
  100. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/linalg/_lsqr.py +27 -20
  101. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/linalg/_power.py +19 -15
  102. spacecore-0.4.0/spacecore/linalg/_utils.py +211 -0
  103. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/linop/__init__.py +3 -2
  104. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/linop/_algebra.py +219 -161
  105. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/linop/_base.py +43 -13
  106. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/linop/_dense.py +24 -103
  107. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/linop/_diagonal.py +18 -102
  108. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/linop/_metric.py +3 -3
  109. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/linop/_sparse.py +53 -110
  110. spacecore-0.4.0/spacecore/linop/tree/__init__.py +14 -0
  111. {spacecore-0.3.2/spacecore/linop/product → spacecore-0.4.0/spacecore/linop/tree}/_base.py +27 -18
  112. spacecore-0.4.0/spacecore/linop/tree/_block.py +408 -0
  113. {spacecore-0.3.2/spacecore/linop/product → spacecore-0.4.0/spacecore/linop/tree}/_from_single.py +18 -22
  114. {spacecore-0.3.2/spacecore/linop/product → spacecore-0.4.0/spacecore/linop/tree}/_to_single.py +17 -21
  115. spacecore-0.4.0/spacecore/optimize/__init__.py +20 -0
  116. spacecore-0.4.0/spacecore/optimize/_common.py +71 -0
  117. spacecore-0.4.0/spacecore/optimize/_optax.py +154 -0
  118. spacecore-0.4.0/spacecore/optimize/_scipy.py +260 -0
  119. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/space/__init__.py +8 -12
  120. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/space/base/_coordinate.py +12 -4
  121. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/space/base/_inner_product.py +18 -1
  122. spacecore-0.4.0/spacecore/space/base/_space.py +137 -0
  123. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/space/checks/__init__.py +2 -4
  124. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/space/checks/_base.py +39 -81
  125. spacecore-0.4.0/spacecore/space/checks/_coordinate.py +10 -0
  126. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/space/concrete/__init__.py +4 -3
  127. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/space/concrete/_dense_coordinate.py +51 -17
  128. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/space/concrete/_dense_vector.py +23 -22
  129. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/space/concrete/_hermitian.py +22 -19
  130. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/space/concrete/_stacked.py +79 -38
  131. spacecore-0.4.0/spacecore/space/concrete/_tree_space.py +930 -0
  132. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/types/_array.py +2 -0
  133. spacecore-0.4.0/spacecore.egg-info/PKG-INFO +340 -0
  134. spacecore-0.4.0/spacecore.egg-info/SOURCES.txt +328 -0
  135. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore.egg-info/requires.txt +5 -1
  136. spacecore-0.4.0/tests/_conformance.py +318 -0
  137. spacecore-0.4.0/tests/backend/_conformance.py +41 -0
  138. spacecore-0.4.0/tests/backend/_references.py +731 -0
  139. spacecore-0.4.0/tests/backend/conftest.py +80 -0
  140. spacecore-0.4.0/tests/backend/test_backend_family.py +79 -0
  141. spacecore-0.4.0/tests/backend/test_context.py +435 -0
  142. spacecore-0.4.0/tests/backend/test_cupy_ops.py +153 -0
  143. spacecore-0.4.0/tests/backend/test_jax_ops.py +299 -0
  144. spacecore-0.4.0/tests/backend/test_jax_pytree_class.py +165 -0
  145. spacecore-0.4.0/tests/backend/test_lazy_namespace.py +59 -0
  146. spacecore-0.4.0/tests/backend/test_numpy_ops.py +191 -0
  147. spacecore-0.4.0/tests/backend/test_operations.py +1388 -0
  148. spacecore-0.4.0/tests/backend/test_torch_ops.py +223 -0
  149. spacecore-0.4.0/tests/backend/test_types_protocols.py +251 -0
  150. spacecore-0.4.0/tests/context/conftest.py +26 -0
  151. spacecore-0.4.0/tests/context/test_check_policy.py +187 -0
  152. spacecore-0.4.0/tests/context/test_check_policy_helpers.py +147 -0
  153. spacecore-0.4.0/tests/context/test_checked_method.py +256 -0
  154. spacecore-0.4.0/tests/context/test_compatibility.py +254 -0
  155. spacecore-0.4.0/tests/context/test_context_bound.py +209 -0
  156. {spacecore-0.3.2 → spacecore-0.4.0}/tests/context/test_enable_checks.py +10 -8
  157. spacecore-0.4.0/tests/context/test_policies_errors.py +183 -0
  158. spacecore-0.4.0/tests/context/test_state_free_functions.py +331 -0
  159. spacecore-0.4.0/tests/functional/conftest.py +46 -0
  160. spacecore-0.4.0/tests/functional/test_composed_functional.py +222 -0
  161. spacecore-0.4.0/tests/functional/test_functional_base.py +254 -0
  162. spacecore-0.4.0/tests/functional/test_generated_functionals.py +266 -0
  163. spacecore-0.4.0/tests/functional/test_inner_product_functional.py +182 -0
  164. spacecore-0.4.0/tests/functional/test_linear_functional.py +82 -0
  165. spacecore-0.4.0/tests/functional/test_linop_quadratic_form.py +190 -0
  166. spacecore-0.4.0/tests/functional/test_matrix_free_linear_functional.py +170 -0
  167. {spacecore-0.3.2 → spacecore-0.4.0}/tests/functional/test_metric_gradient.py +7 -21
  168. spacecore-0.4.0/tests/functional/test_quadratic_form.py +117 -0
  169. spacecore-0.4.0/tests/functional/tools/test_battery_functionals.py +271 -0
  170. spacecore-0.4.0/tests/functional/tools/test_least_squares.py +107 -0
  171. spacecore-0.4.0/tests/functional/tools/test_proximal.py +269 -0
  172. spacecore-0.4.0/tests/functional/tools/test_spectral.py +137 -0
  173. spacecore-0.4.0/tests/generators/__init__.py +82 -0
  174. spacecore-0.4.0/tests/generators/_arrays.py +108 -0
  175. spacecore-0.4.0/tests/generators/_contexts.py +102 -0
  176. spacecore-0.4.0/tests/generators/_hermitian.py +77 -0
  177. spacecore-0.4.0/tests/generators/_metrics.py +79 -0
  178. spacecore-0.4.0/tests/generators/_params.py +60 -0
  179. spacecore-0.4.0/tests/generators/_protocol.py +18 -0
  180. spacecore-0.4.0/tests/generators/_seed.py +28 -0
  181. spacecore-0.4.0/tests/generators/_trees.py +108 -0
  182. spacecore-0.4.0/tests/generators/functionals.py +444 -0
  183. spacecore-0.4.0/tests/generators/linops.py +552 -0
  184. spacecore-0.4.0/tests/generators/spaces.py +590 -0
  185. spacecore-0.4.0/tests/generators/test_registry_completeness.py +155 -0
  186. spacecore-0.4.0/tests/generators/test_smoke.py +89 -0
  187. {spacecore-0.3.2 → spacecore-0.4.0}/tests/integration/test_imports.py +1 -1
  188. {spacecore-0.3.2 → spacecore-0.4.0}/tests/integration/test_public_api.py +36 -10
  189. {spacecore-0.3.2 → spacecore-0.4.0}/tests/integration/test_smoke_numpy.py +1 -1
  190. {spacecore-0.3.2 → spacecore-0.4.0}/tests/integration/test_smoke_torch.py +2 -2
  191. spacecore-0.4.0/tests/kernels/conftest.py +22 -0
  192. spacecore-0.4.0/tests/kernels/test_core_kernel_dispatch.py +251 -0
  193. spacecore-0.4.0/tests/kernels/test_kernel_dispatch.py +574 -0
  194. spacecore-0.4.0/tests/kernels/test_kernel_registry.py +143 -0
  195. spacecore-0.4.0/tests/kernels/test_kernel_spec.py +109 -0
  196. spacecore-0.4.0/tests/kernels/test_kernels_match_generic.py +272 -0
  197. spacecore-0.4.0/tests/linalg/_helpers.py +74 -0
  198. spacecore-0.4.0/tests/linalg/conftest.py +19 -0
  199. spacecore-0.4.0/tests/linalg/test_cg.py +282 -0
  200. spacecore-0.4.0/tests/linalg/test_core_resolution.py +110 -0
  201. spacecore-0.4.0/tests/linalg/test_expm_multiply.py +193 -0
  202. spacecore-0.4.0/tests/linalg/test_generated_solver_matrix.py +129 -0
  203. spacecore-0.4.0/tests/linalg/test_lanczos.py +260 -0
  204. spacecore-0.4.0/tests/linalg/test_lsqr.py +236 -0
  205. spacecore-0.4.0/tests/linalg/test_power_iteration.py +377 -0
  206. spacecore-0.4.0/tests/linalg/test_result_types.py +117 -0
  207. spacecore-0.4.0/tests/linalg/test_solver_contracts.py +114 -0
  208. spacecore-0.4.0/tests/linalg/test_utils.py +186 -0
  209. spacecore-0.4.0/tests/linops/conftest.py +35 -0
  210. spacecore-0.4.0/tests/linops/test_algebra_factories.py +354 -0
  211. spacecore-0.4.0/tests/linops/test_algebra_linops.py +986 -0
  212. spacecore-0.4.0/tests/linops/test_block_diagonal_linop.py +378 -0
  213. spacecore-0.4.0/tests/linops/test_block_matrix_linop.py +156 -0
  214. spacecore-0.4.0/tests/linops/test_dense_linop.py +516 -0
  215. spacecore-0.4.0/tests/linops/test_diagonal_linop.py +327 -0
  216. spacecore-0.4.0/tests/linops/test_fused_algebra_overhead.py +224 -0
  217. spacecore-0.4.0/tests/linops/test_generated_linop_laws.py +149 -0
  218. spacecore-0.4.0/tests/linops/test_linop_base.py +386 -0
  219. spacecore-0.4.0/tests/linops/test_linop_jit.py +201 -0
  220. spacecore-0.4.0/tests/linops/test_metric_helpers.py +255 -0
  221. spacecore-0.4.0/tests/linops/test_sparse_linop.py +359 -0
  222. spacecore-0.4.0/tests/linops/test_stacked_linop.py +289 -0
  223. spacecore-0.4.0/tests/linops/test_sum_to_single_linop.py +290 -0
  224. spacecore-0.4.0/tests/linops/test_tree_helpers.py +100 -0
  225. spacecore-0.4.0/tests/linops/test_tree_linop_base.py +85 -0
  226. spacecore-0.4.0/tests/optim/test_cached_member_checks.py +157 -0
  227. spacecore-0.4.0/tests/optimize/_helpers.py +54 -0
  228. spacecore-0.4.0/tests/optimize/test_contracts.py +126 -0
  229. spacecore-0.4.0/tests/optimize/test_line_search_scipy.py +89 -0
  230. spacecore-0.4.0/tests/optimize/test_metric_handoff.py +63 -0
  231. spacecore-0.4.0/tests/optimize/test_minimize_optax.py +113 -0
  232. spacecore-0.4.0/tests/optimize/test_minimize_scipy.py +133 -0
  233. spacecore-0.4.0/tests/spaces/__init__.py +0 -0
  234. spacecore-0.4.0/tests/spaces/_generated_helpers.py +52 -0
  235. spacecore-0.4.0/tests/spaces/conftest.py +40 -0
  236. spacecore-0.4.0/tests/spaces/test_check_batched.py +181 -0
  237. spacecore-0.4.0/tests/spaces/test_coordinate_space_base.py +113 -0
  238. spacecore-0.4.0/tests/spaces/test_dense_coordinate_space.py +189 -0
  239. spacecore-0.4.0/tests/spaces/test_dense_vector_space.py +70 -0
  240. spacecore-0.4.0/tests/spaces/test_elementwise_jordan_spaces.py +135 -0
  241. spacecore-0.4.0/tests/spaces/test_generated_dense_coordinate.py +132 -0
  242. spacecore-0.4.0/tests/spaces/test_generated_dense_vector.py +60 -0
  243. spacecore-0.4.0/tests/spaces/test_generated_inner_product.py +96 -0
  244. spacecore-0.4.0/tests/spaces/test_generated_jordan_space.py +111 -0
  245. spacecore-0.4.0/tests/spaces/test_generated_space_laws.py +34 -0
  246. spacecore-0.4.0/tests/spaces/test_generated_tree_space.py +105 -0
  247. spacecore-0.4.0/tests/spaces/test_hermitian_space.py +192 -0
  248. spacecore-0.4.0/tests/spaces/test_inner_product.py +164 -0
  249. spacecore-0.4.0/tests/spaces/test_inner_product_space_base.py +114 -0
  250. spacecore-0.4.0/tests/spaces/test_jordan_algebra_spaces.py +182 -0
  251. spacecore-0.4.0/tests/spaces/test_space_base.py +149 -0
  252. spacecore-0.4.0/tests/spaces/test_space_checks.py +392 -0
  253. spacecore-0.4.0/tests/spaces/test_stacked_space.py +335 -0
  254. spacecore-0.4.0/tests/spaces/test_star_space_base.py +80 -0
  255. spacecore-0.4.0/tests/spaces/test_tree_space.py +488 -0
  256. spacecore-0.4.0/tests/spaces/test_tree_spectral_decomposition.py +79 -0
  257. spacecore-0.4.0/tests/spaces/test_vector_space_base.py +82 -0
  258. spacecore-0.4.0/tests/test_repr.py +433 -0
  259. spacecore-0.4.0/tests/test_weighted_tikhonov.py +80 -0
  260. spacecore-0.4.0/tutorials/01_backend_and_context.ipynb +564 -0
  261. spacecore-0.4.0/tutorials/02_linear_algebra.ipynb +502 -0
  262. spacecore-0.4.0/tutorials/03_functionals.ipynb +426 -0
  263. spacecore-0.4.0/tutorials/04_tree_spaces.ipynb +501 -0
  264. spacecore-0.4.0/tutorials/05_weighted_tikhonov.ipynb +476 -0
  265. spacecore-0.4.0/tutorials/06_optimal_transport.ipynb +445 -0
  266. spacecore-0.4.0/tutorials/07_manifold_descent.ipynb +354 -0
  267. spacecore-0.4.0/tutorials/08_pdhg_conic_program.ipynb +416 -0
  268. spacecore-0.4.0/tutorials/README.md +43 -0
  269. spacecore-0.3.2/CHANGELOG.md +0 -315
  270. spacecore-0.3.2/PKG-INFO +0 -206
  271. spacecore-0.3.2/README.md +0 -165
  272. spacecore-0.3.2/docs/dev/adr/013_tree_structured_spaces.md +0 -36
  273. spacecore-0.3.2/docs/dev/current.md +0 -32
  274. spacecore-0.3.2/docs/source/api/functionals.rst +0 -80
  275. spacecore-0.3.2/docs/source/design/checking_policy.rst +0 -69
  276. spacecore-0.3.2/docs/source/design/dtype_policy.rst +0 -62
  277. spacecore-0.3.2/docs/source/tutorials/backend_ops.rst +0 -104
  278. spacecore-0.3.2/docs/source/tutorials/context.rst +0 -103
  279. spacecore-0.3.2/docs/source/tutorials/conversion_policy.rst +0 -102
  280. spacecore-0.3.2/docs/source/tutorials/index.rst +0 -88
  281. spacecore-0.3.2/docs/source/tutorials/linops.rst +0 -139
  282. spacecore-0.3.2/docs/source/tutorials/regularized_ot.rst +0 -662
  283. spacecore-0.3.2/docs/source/tutorials/spaces.rst +0 -124
  284. spacecore-0.3.2/docs/source/tutorials/weighted_tikhonov.rst +0 -194
  285. spacecore-0.3.2/examples/weighted_tikhonov.py +0 -267
  286. spacecore-0.3.2/spacecore/_batching.py +0 -18
  287. spacecore-0.3.2/spacecore/_checks.py +0 -95
  288. spacecore-0.3.2/spacecore/_contextual/_bound.py +0 -57
  289. spacecore-0.3.2/spacecore/_tree.py +0 -26
  290. spacecore-0.3.2/spacecore/backend/cupy/_ops.py +0 -290
  291. spacecore-0.3.2/spacecore/backend/numpy/_ops.py +0 -514
  292. spacecore-0.3.2/spacecore/functional/__init__.py +0 -17
  293. spacecore-0.3.2/spacecore/functional/_base.py +0 -138
  294. spacecore-0.3.2/spacecore/linalg/_utils.py +0 -122
  295. spacecore-0.3.2/spacecore/linop/product/__init__.py +0 -13
  296. spacecore-0.3.2/spacecore/linop/product/_block.py +0 -125
  297. spacecore-0.3.2/spacecore/space/_structure.py +0 -117
  298. spacecore-0.3.2/spacecore/space/base/_space.py +0 -49
  299. spacecore-0.3.2/spacecore/space/checks/_coordinate.py +0 -3
  300. spacecore-0.3.2/spacecore/space/checks/_product.py +0 -3
  301. spacecore-0.3.2/spacecore/space/concrete/_product.py +0 -686
  302. spacecore-0.3.2/spacecore.egg-info/PKG-INFO +0 -206
  303. spacecore-0.3.2/spacecore.egg-info/SOURCES.txt +0 -219
  304. spacecore-0.3.2/tests/backend/test_backend_consistency.py +0 -142
  305. spacecore-0.3.2/tests/backend/test_backend_loops.py +0 -119
  306. spacecore-0.3.2/tests/backend/test_backend_ops_delegation.py +0 -257
  307. spacecore-0.3.2/tests/backend/test_backend_registry.py +0 -102
  308. spacecore-0.3.2/tests/backend/test_cupy_ops.py +0 -66
  309. spacecore-0.3.2/tests/backend/test_jax_ops.py +0 -43
  310. spacecore-0.3.2/tests/backend/test_numpy_ops.py +0 -39
  311. spacecore-0.3.2/tests/backend/test_torch_consistency.py +0 -51
  312. spacecore-0.3.2/tests/backend/test_torch_ops.py +0 -108
  313. spacecore-0.3.2/tests/context/test_checked_method.py +0 -133
  314. spacecore-0.3.2/tests/context/test_context.py +0 -34
  315. spacecore-0.3.2/tests/context/test_context_manager.py +0 -46
  316. spacecore-0.3.2/tests/context/test_context_resolution.py +0 -115
  317. spacecore-0.3.2/tests/context/test_errors.py +0 -46
  318. spacecore-0.3.2/tests/examples/test_weighted_tikhonov.py +0 -109
  319. spacecore-0.3.2/tests/functional/test_functional.py +0 -243
  320. spacecore-0.3.2/tests/linalg/test_expm.py +0 -255
  321. spacecore-0.3.2/tests/linalg/test_krylov.py +0 -939
  322. spacecore-0.3.2/tests/linalg/test_metric_solvers.py +0 -68
  323. spacecore-0.3.2/tests/linops/test_adjoint_identity.py +0 -844
  324. spacecore-0.3.2/tests/linops/test_algebra.py +0 -533
  325. spacecore-0.3.2/tests/linops/test_algebra_linop.py +0 -242
  326. spacecore-0.3.2/tests/linops/test_batched_apply.py +0 -79
  327. spacecore-0.3.2/tests/linops/test_batched_lifting.py +0 -181
  328. spacecore-0.3.2/tests/linops/test_block_diagonal_linop.py +0 -27
  329. spacecore-0.3.2/tests/linops/test_conversion_linops.py +0 -62
  330. spacecore-0.3.2/tests/linops/test_dense_linop.py +0 -322
  331. spacecore-0.3.2/tests/linops/test_diagonal_linop.py +0 -162
  332. spacecore-0.3.2/tests/linops/test_linop_jit.py +0 -166
  333. spacecore-0.3.2/tests/linops/test_product_linop_batching.py +0 -201
  334. spacecore-0.3.2/tests/linops/test_product_structure.py +0 -231
  335. spacecore-0.3.2/tests/linops/test_sparse_linop.py +0 -345
  336. spacecore-0.3.2/tests/linops/test_stacked_linop.py +0 -18
  337. spacecore-0.3.2/tests/linops/test_sum_to_single_linop.py +0 -18
  338. spacecore-0.3.2/tests/linops/test_to_dense.py +0 -277
  339. spacecore-0.3.2/tests/spaces/test_conversion_spaces.py +0 -45
  340. spacecore-0.3.2/tests/spaces/test_geometry.py +0 -243
  341. spacecore-0.3.2/tests/spaces/test_hermitian_space.py +0 -54
  342. spacecore-0.3.2/tests/spaces/test_product_space.py +0 -68
  343. spacecore-0.3.2/tests/spaces/test_product_structure.py +0 -268
  344. spacecore-0.3.2/tests/spaces/test_space_apply.py +0 -159
  345. spacecore-0.3.2/tests/spaces/test_space_checks.py +0 -164
  346. spacecore-0.3.2/tests/spaces/test_space_hierarchy.py +0 -654
  347. spacecore-0.3.2/tests/spaces/test_spectrum.py +0 -237
  348. spacecore-0.3.2/tests/spaces/test_stacked_space.py +0 -156
  349. spacecore-0.3.2/tests/spaces/test_vector_space.py +0 -55
  350. spacecore-0.3.2/tests/spaces/test_vectorized_checks.py +0 -145
  351. spacecore-0.3.2/tests/test_backend_ops_complex.py +0 -41
  352. spacecore-0.3.2/tutorials/1_BackendOps.ipynb +0 -628
  353. spacecore-0.3.2/tutorials/2_Context.ipynb +0 -602
  354. spacecore-0.3.2/tutorials/3_Space.ipynb +0 -821
  355. spacecore-0.3.2/tutorials/4_LinOp.ipynb +0 -951
  356. spacecore-0.3.2/tutorials/5_Conversion_Policy.ipynb +0 -208
  357. spacecore-0.3.2/tutorials/6_Regularized_Opt_Transport.ipynb +0 -789
  358. spacecore-0.3.2/tutorials/7_Quadratic_Program.ipynb +0 -320
  359. spacecore-0.3.2/tutorials/8_Linalg_MatrixFree.ipynb +0 -560
  360. spacecore-0.3.2/tutorials/9_Linalg_Comparison.ipynb +0 -558
  361. spacecore-0.3.2/tutorials/README.md +0 -33
  362. spacecore-0.3.2/tutorials/weighted_tikhonov.ipynb +0 -539
  363. {spacecore-0.3.2 → spacecore-0.4.0}/CONTRIBUTING.md +0 -0
  364. {spacecore-0.3.2 → spacecore-0.4.0}/LICENSE +0 -0
  365. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/0.3.1-docs-inventory.md +0 -0
  366. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/0.3.1-docstring-audit.md +0 -0
  367. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/adr/001_backend_layer.md +0 -0
  368. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/adr/002_context_and_conversion.md +0 -0
  369. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/adr/004_inner_product_and_geometry.md +0 -0
  370. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/adr/006_current_batching_model.md +0 -0
  371. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/adr/007_linop_contract.md +0 -0
  372. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/adr/009_metric_adjoint.md +0 -0
  373. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/adr/010_functional_contract.md +0 -0
  374. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/adr/011_linalg_contract.md +0 -0
  375. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/adr/012_jordan_spectrum.md +0 -0
  376. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/contributing/labels.md +0 -0
  377. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/contributing/prerequisites.md +0 -0
  378. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/contributing/process.md +0 -0
  379. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/contributing/setup.md +0 -0
  380. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/docstring_style.md +0 -0
  381. {spacecore-0.3.2 → spacecore-0.4.0}/docs/dev/vision.md +0 -0
  382. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/_static/custom.css +0 -0
  383. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/api/backend.rst +0 -0
  384. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/api/linalg.rst +0 -0
  385. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/conf.py +0 -0
  386. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/design/backend_ops_array_api.rst +0 -0
  387. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/design/geometry.rst +0 -0
  388. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/design/jax_integration.rst +0 -0
  389. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/design/performance.rst +0 -0
  390. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/dev/adr.rst +0 -0
  391. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/dev/index.rst +0 -0
  392. {spacecore-0.3.2 → spacecore-0.4.0}/docs/source/dev/vision.rst +0 -0
  393. {spacecore-0.3.2 → spacecore-0.4.0}/setup.cfg +0 -0
  394. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/_contextual/__init__.py +0 -0
  395. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/_contextual/_policies.py +0 -0
  396. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/backend/_family.py +0 -0
  397. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/backend/cupy/__init__.py +0 -0
  398. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/backend/jax/__init__.py +0 -0
  399. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/backend/numpy/__init__.py +0 -0
  400. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/backend/torch/__init__.py +0 -0
  401. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/linalg/__init__.py +0 -0
  402. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/linalg/_expm.py +0 -0
  403. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/space/base/__init__.py +0 -0
  404. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/space/base/_jordan.py +0 -0
  405. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/space/base/_star.py +0 -0
  406. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/space/base/_vector.py +0 -0
  407. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/types/__init__.py +0 -0
  408. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/types/_dtype.py +0 -0
  409. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore/types/_misc.py +0 -0
  410. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore.egg-info/dependency_links.txt +0 -0
  411. {spacecore-0.3.2 → spacecore-0.4.0}/spacecore.egg-info/top_level.txt +0 -0
  412. {spacecore-0.3.2/examples → spacecore-0.4.0/tests}/__init__.py +0 -0
  413. {spacecore-0.3.2 → spacecore-0.4.0}/tests/_helpers.py +0 -0
  414. {spacecore-0.3.2/tests → spacecore-0.4.0/tests/backend}/__init__.py +0 -0
  415. {spacecore-0.3.2 → spacecore-0.4.0}/tests/conftest.py +0 -0
  416. {spacecore-0.3.2/tests/backend → spacecore-0.4.0/tests/context}/__init__.py +0 -0
  417. {spacecore-0.3.2/tests/context → spacecore-0.4.0/tests/integration}/__init__.py +0 -0
  418. {spacecore-0.3.2 → spacecore-0.4.0}/tests/integration/test_github_labels.py +0 -0
  419. {spacecore-0.3.2 → spacecore-0.4.0}/tests/integration/test_smoke_jax.py +0 -0
  420. {spacecore-0.3.2/tests/examples → spacecore-0.4.0/tests/kernels}/__init__.py +0 -0
  421. {spacecore-0.3.2 → spacecore-0.4.0}/tests/linalg/__init__.py +0 -0
  422. {spacecore-0.3.2/tests/integration → spacecore-0.4.0/tests/linops}/__init__.py +0 -0
  423. {spacecore-0.3.2/tests/linops → spacecore-0.4.0/tests/optim}/__init__.py +0 -0
  424. {spacecore-0.3.2/tests/spaces → spacecore-0.4.0/tests/optimize}/__init__.py +0 -0
@@ -0,0 +1,556 @@
1
+ # Changelog
2
+
3
+ All notable changes to SpaceCore are documented in this file.
4
+
5
+ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
6
+ and the project adheres to [Semantic Versioning](https://semver.org/).
7
+
8
+ ## [Unreleased]
9
+
10
+ ### Added
11
+
12
+ - ADR-016 optimized-kernel **dispatch** is accepted and implemented (off by
13
+ default). `KernelSpec` gains `dispatch_key`, `priority`, and an optional
14
+ shape-only `cost` estimator (`KernelCost`); a spec that names a `dispatch_key`
15
+ with `rtol == atol == 0` is *dispatch-eligible*. `KernelRegistry` indexes the
16
+ eligible specs by key (descending `priority`) and rejects two eligible specs
17
+ that share a key at equal priority (`DispatchAmbiguityError`). A single
18
+ `spacecore.kernels.dispatch(key, *args, generic=…, ctx=…)` entry point selects
19
+ the first applicable, affordable spec or runs the inline `generic` fallback.
20
+ `dispatch_mode` (`off`/`on`/`verify`) is settable process-globally
21
+ (`set_dispatch_mode`) and per-scope (`dispatch_mode(...)` context manager);
22
+ `check_level="strict"` implies `verify`. A materializing fast path is gated by
23
+ a memory budget computed from `BackendOps.free_memory_bytes()` and
24
+ `set_memory_budget_fraction` — no estimate or no budget means no fuse. The
25
+ composed apply chain (`linop.composed.apply`) and block-diagonal apply
26
+ (`linop.block_diagonal.apply`) call sites are wired through `dispatch`; with
27
+ dispatch off they are result-identical to the prior inline paths. The two
28
+ `0.4.0` catalog specs stay explicit-entry (no `dispatch_key`); activating a
29
+ routed spec under either key is a benchmark-gated follow-up.
30
+ - Three dispatch-eligible algebraic-optimization kernels (exact, `rtol=atol=0`):
31
+ `composed-zero-annihilation` (a chain containing a zero map collapses to
32
+ `codomain.zeros()`) and `composed-identity-elision` (skip identity leaves)
33
+ under `linop.composed.apply`, and `block-diagonal-uniform-dense-batched`
34
+ (uniform flat-dense blocks fold into one batched `matmul`) under
35
+ `linop.block_diagonal.apply`. The block kernel is *materializing*: it carries a
36
+ shape-only `KernelCost` and the dispatcher gates it on the memory budget. All
37
+ three route only under `dispatch_mode("on"/"verify")`; dispatch stays off by
38
+ default. Each has a correctness reference and a `python -m bench` probe.
39
+ - `NumpyOps.free_memory_bytes()` reports available system RAM via the optional
40
+ `psutil` dependency (returns `None` — "no fuse" — when `psutil` is absent), so
41
+ the dispatcher's memory gate can size materializing fast paths on the CPU
42
+ backend.
43
+
44
+ ## [0.4.0] — 2026-06-24
45
+
46
+ SpaceCore 0.4.0 stabilizes the typed linear-algebra core as a validated
47
+ algebra of structured mathematical objects. It ships a public check-policy,
48
+ ADR-015 Stage 1 dtype/field contract, the `TreeSpace` finite direct-product
49
+ abstraction, block-structured LinOps on tree domains, an everyday functional
50
+ and proximal toolbox, external optimizer adapters, reusable test generators,
51
+ and a full backend conformance matrix with deviation catalog.
52
+
53
+ ### Added
54
+
55
+ - ADR-018 **external optimizer adapters** in the new `spacecore.optimize`
56
+ subpackage: `minimize_scipy(F, x0, *, method="L-BFGS-B", jac=True, **kw)` and
57
+ `line_search_scipy(F, x, d, **kw)` drive `scipy.optimize`, and
58
+ `minimize_optax(F, x0, optimizer, *, steps, callback=None)` runs the canonical
59
+ optax update loop with pytree pass-through. Each adapter evaluates the
60
+ objective through `F.value` and converts the metric (Riesz) gradient `F.grad`
61
+ to the coordinate gradient external optimizers expect with
62
+ `X.riesz(F.grad(x))` — the identity on a Euclidean space and mandatory on a
63
+ weighted one, defusing the study's silent metric-gradient trap once and
64
+ centrally. The external optimizer owns iteration, line search, and
65
+ convergence; the SciPy adapters reject complex domains and document the
66
+ structure/geometry/field lost at the boundary. `minimize_scipy` returns the
67
+ SciPy `OptimizeResult` with an added `x_element` field (the minimizer
68
+ unflattened into `F.domain`); `minimize_optax` requires a JAX-backed domain and
69
+ the optional `optax` extra (`pip install spacecore[optax]`). Per ADR-018,
70
+ jaxopt/BlackJAX/pymanopt seams stay as tutorials, not shipped adapters.
71
+ - ADR-019 everyday functional and proximal toolbox in the new
72
+ `spacecore.functional.tools` subpackage (re-exported from
73
+ `spacecore.functional` and the top-level `spacecore` namespace): named
74
+ constructors over the existing `Functional` machinery, with no new core type
75
+ hierarchy. `least_squares(A, b, *, weights=None, scale=0.5)` returns a
76
+ `LinOpQuadraticForm` for `scale·‖Ax−b‖²` (default `½‖Ax−b‖²`, with optional
77
+ diagonal residual weights). New battery functionals `SquaredL2NormFunctional`,
78
+ `LpNormFunctional`, `L1NormFunctional`, `NegativeEntropyFunctional`,
79
+ `KLDivergenceFunctional`, and `HuberFunctional` are coordinate objectives whose
80
+ gradients are the metric (Riesz) gradient under the domain geometry.
81
+ `SpectralLpNormFunctional` (with the `NuclearNormFunctional` wrapper) is the
82
+ spectral analogue — the Schatten-`p` norm of a Jordan spectrum (`HermitianSpace`
83
+ eigenvalues), a spectral function whose gradient is reconstructed through the
84
+ ADR-012 `from_spectrum` API; on an elementwise Jordan space it coincides with
85
+ `LpNormFunctional`. A closed-form proximal primitive
86
+ `generalized_shrinkage(X, *, c, x0, eps, lam=0.0, nonneg=False)` solves the
87
+ separable forward–backward subproblem in the space metric (per-coordinate
88
+ threshold `τᵢ = λ/(2 ε wᵢ)` on a diagonal metric; it **raises** on a
89
+ non-diagonal metric rather than returning a wrong separable answer), with the
90
+ named wrappers `prox_l1`, `prox_l2sq`, and `project_nonneg`. The
91
+ `IndicatorFunctional`/`project_C` surface reserved by ADR-019 is deferred to
92
+ ADR-020 (`Set`).
93
+ - `HermitianSpace.eig_to_dense` (and therefore `from_spectrum`, `psd_proj`, and
94
+ `spectral_apply`) now symmetrizes the `U diag(·) U^*` reconstruction before the
95
+ membership check, so a zero-tolerance Hermitian space no longer rejects its own
96
+ spectral reconstruction over a few-ULP floating-point skew.
97
+ - Public `check_level` policy literal (`"none"`, `"cheap"`, `"standard"`,
98
+ `"strict"`) with `CHECK_LEVELS` ordering and `_checks_at_least` dispatch
99
+ across spaces, LinOps, functionals, and solver preconditions.
100
+ - `Space.field` exposing a `Literal["real", "complex"]` mathematical
101
+ contract derived from the context dtype; capability guards now consult
102
+ `Space.field` instead of inspecting precision-bearing dtypes.
103
+ - `TreeSpace` finite direct-product space organized by an `optree`
104
+ definition; `TreeElement` ordered-leaf binding; `TreeSpace.from_leaf_spaces`
105
+ flat-tuple shortcut.
106
+ - `BlockDiagonalLinOp` and `BlockMatrixLinOp` over `TreeSpace` domains
107
+ including metric-adjoint behavior; `TreeLinOp` base class for tree-shaped
108
+ operators.
109
+ - Reusable test generators under `tests/generators/` for spaces, LinOps,
110
+ functionals, and linalg references; contributor guide at
111
+ `docs/dev/contributing/linop_generators.md`.
112
+ - `spacecore.kernels` subpackage with the optimized-kernel registration
113
+ policy. Two demonstration kernels ship in 0.4.0: `composed-chain-apply`
114
+ (skips the per-link `@checked_method` wrapper for a flat chain of LinOps)
115
+ and `block-diagonal-dense-apply` (tight ``ops.matmul`` loop over dense
116
+ block leaves). Both have correctness references and bench cases. No
117
+ dispatch or fusion is wired in 0.4.0: the ADR-016 dispatch mechanism is
118
+ implemented but ships **off by default** and dormant, with no production
119
+ routing (see Unreleased).
120
+ - Unified benchmark framework at `python -m bench` (subcommands `run`,
121
+ `compare`, `plot`, `summary`, `list`) with generator-driven probes in
122
+ `bench/_operations.py`, peak-memory recording in
123
+ `bench/harness.py:measure_peak_memory`, fixed seeds `(0, 1, 2, 3)`, and
124
+ a self-contained interactive Plotly dashboard at `bench/_dashboard.py`.
125
+ - Kernel policy doc at `docs/source/design/kernels_policy.rst`.
126
+ - Backend conformance matrix at `docs/source/design/backend_conformance.rst`
127
+ with per-op tolerance harness in `tests/backend/_conformance.py`,
128
+ systematic NumpyOps reference (`tests/backend/test_conformance_numpy.py`),
129
+ cross-backend parity (`tests/backend/test_conformance_cross_backend.py`),
130
+ and dedicated modules for optional args, conversion, dtype promotion,
131
+ field consistency, vmap, and JIT.
132
+ - Operator apply cores are organized as a *core-kernel* layer in the
133
+ `spacecore.kernels` subpackage instead of inline in each operator class. The
134
+ check-free cores of `apply`/`rapply`/`vapply`/`rvapply` for **every** operator
135
+ with a fast path — the composite algebra (`ComposedLinOp`, `ScaledLinOp`,
136
+ `SumLinOp`, the adjoint view, `IdentityLinOp`, `ZeroLinOp`, `MatrixFreeLinOp`)
137
+ and the concrete leaves (`DenseLinOp`, `DiagonalLinOp`, `SparseLinOp`) — now
138
+ live as concrete functions in the kernels subpackage (`kernels/algebra.py`,
139
+ `kernels/dense.py`, `kernels/diagonal.py`, `kernels/sparse.py`). Operators
140
+ bind them by declaring the `@core_kernels("...")` class decorator (rules in
141
+ `spacecore/kernels/_core.py`); the base `LinOp` cores remain the generic
142
+ fallback for operators without a registered kernel. Binding is static
143
+ (class-definition time), so routing through the kernel registry costs nothing
144
+ per call — leaf-operator apply latency is unchanged. The lazy-algebra cores
145
+ additionally validate membership only once at the boundary instead of
146
+ re-validating every intermediate link, and `ComposedLinOp` caches a flattened
147
+ `_apply_chain` at construction so a deep `A @ B @ C @ ...` runs one loop rather
148
+ than re-walking the binary tree (a depth-16 composition applies ~9x faster than
149
+ the per-link-checked path and scales flat with depth). All results are
150
+ numerically identical. Public API: `core_kernels`, `CoreKernelSet`,
151
+ `register_core_kernels`, `get_core_kernels`, `core_kernel_names` from
152
+ `spacecore.kernels`.
153
+ - Iterative linalg solvers (`cg`, `lanczos_smallest`, `lsqr`, `power_iteration`)
154
+ consume the check-free operator/space cores in their hot loops. They validate
155
+ the operator and right-hand side once, at entry, then run the iteration through
156
+ the resolved cores — eliminating the per-iteration membership validation that
157
+ dominated eager-backend runtime (CG at `check_level="standard"` is ~3.4x faster
158
+ on NumPy and now matches `check_level="none"`). Resolution is safe: a core is
159
+ used only when it is consistent with the public method (`linalg/_utils.py`
160
+ `resolve_core`/`SpaceCoreOps`), so a user space that overrides `inner` with a
161
+ custom geometry without overriding `_inner_core` keeps its override. Results are
162
+ numerically identical.
163
+ - The `spacecore.kernels` subpackage is reorganized into two subpackages by kind:
164
+ `spacecore.kernels.core` (the check-free apply/eval cores + the `core_kernels`
165
+ binding rules) and `spacecore.kernels.specs` (the benchmarked `KernelSpec`
166
+ layer). Public names are re-exported from `spacecore.kernels`, so
167
+ `spacecore.kernels.core_kernels`, `spacecore.kernels.CoreKernelSet`, and
168
+ `spacecore.kernels.KernelSpec`/`registry` resolve unchanged.
169
+ - The same core-kernel organization now covers the `spacecore.functional`
170
+ submodule. The check-free `value`/`grad`/`vvalue`/`vgrad` cores for
171
+ `InnerProductFunctional`, `MatrixFreeLinearFunctional`, `LinearFunctional`,
172
+ `LinOpQuadraticForm`, and `ComposedFunctional` live in
173
+ `spacecore/kernels/functional.py`; the functionals bind them via
174
+ `@core_kernels("...")`. `CoreKernelSet` gained `value`/`grad`/`vvalue`/`vgrad`
175
+ fields alongside the LinOp `apply`/`rapply`/`vapply`/`rvapply` ones, and the
176
+ base `Functional` carries the generic core fallbacks. Composite functionals now
177
+ reach their operands' cores instead of re-validating intermediates — e.g.
178
+ `LinOpQuadraticForm.value` validates its input once rather than once per
179
+ sub-term (`Q.apply` + `linear.value`), and `ComposedFunctional` evaluates
180
+ `F._value_core(A._apply_core(x))`. Results are numerically identical.
181
+ - `BackendOps.hstack`, `vstack`, `dstack`, and `column_stack` array-stacking
182
+ helpers delegating to the backend's native routines, alongside the existing
183
+ `stack`.
184
+ - `BackendOps.vectorize` for elementwise vectorization of a scalar Python
185
+ function over array arguments. Delegates to the backend's native
186
+ `vectorize` (NumPy, JAX, CuPy) and uses a portable Python-loop fallback on
187
+ backends without one (Torch). Closes the previously unimplemented
188
+ `ops.vectorize` fallback used by `spectral_apply`.
189
+ - Backend deviation catalog at `docs/source/design/backend_deviations.rst`.
190
+ - Batching test policy at `docs/source/design/batching_test_policy.rst`.
191
+
192
+ ### Changed
193
+
194
+ - Spaces, LinOps, and functionals dispatch optional checks via
195
+ `_checks_at_least`; `cheap` covers shape/dtype/backend/tree-structure,
196
+ `standard` adds membership and Hermitian checks, `strict` adds bounded
197
+ expensive probes (matrix-free adjoint identity, CG positive-curvature
198
+ probe).
199
+ - `Context.dtype` is documented as the representation default; `Space.field`
200
+ is the mathematical contract derived from it.
201
+
202
+ ### Removed
203
+
204
+ - `ProductSpace` was removed in favor of `TreeSpace`. Tuple-style products
205
+ use `TreeSpace.from_leaf_spaces((X1, X2, ...))`; nested / dict /
206
+ namedtuple structures use `TreeSpace(template, leaf_spaces)` or
207
+ `TreeSpace.from_template`.
208
+ - `ProductLinOp` was renamed to `TreeLinOp`. `ProductStructure`,
209
+ `TupleStructure`, `PytreeStructure`, `ProductStructureCheck`, and
210
+ `ProductComponentCheck` were removed; tree-structure handling and leaf
211
+ validation are owned by `TreeSpace`.
212
+ - Conversion (`ctx.asarray` and construction helpers) refuses silent
213
+ complex-to-real narrowing per ADR-015 Stage 1.
214
+
215
+ ### Deprecated
216
+
217
+ - `enable_checks=True/False` is deprecated in favor of `check_level`:
218
+ `True` maps to `"standard"`, `False` maps to `"none"`. Passing both
219
+ raises `TypeError`. `enable_checks` continues to work in 0.4.0 but will
220
+ be removed in a future release.
221
+
222
+ ### Fixed
223
+
224
+ - Corrected the matrix-free adjoint contract so `MatrixFreeLinOp` and its
225
+ adjoint view use user-supplied forward and reverse callables directly,
226
+ without applying matrix-backed Riesz-map adjoint corrections.
227
+ - `ComposedLinOp`, `ScaledLinOp`, and `SumLinOp` now implement structural
228
+ `is_hermitian()` inference. A Gram product `R.H @ R` (or `L @ L.H`) reports
229
+ `True` in any geometry, a real-scaled operator propagates its operand's
230
+ verdict, and a sum of provably-Hermitian terms reports `True`. The checks
231
+ are cheap, conservative, and never assert `False`, so the normal operator
232
+ `A.H @ A + lam * Identity` is now correctly recognized as self-adjoint
233
+ instead of reporting `None`.
234
+ - `cg` now rejects an operator that is *provably* non-self-adjoint in its
235
+ geometry (`A.is_hermitian() is False`) at entry with a clear `ValueError`,
236
+ matching the guard already used by `power_iteration`, `lanczos_smallest`,
237
+ and `expm_multiply`. Previously, at the default check level, `cg` would
238
+ silently accept (for example) a symmetric matrix on a weighted
239
+ inner-product space — which is not self-adjoint under the weighted inner
240
+ product — and return a confusing `converged=False` result. Operators with
241
+ unknown Hermiticity (`is_hermitian() is None`, e.g. matrix-free) are still
242
+ accepted unchecked.
243
+
244
+ ### Known limitations
245
+
246
+ - Iterative solvers (`cg`, `lsqr`, `lanczos_smallest`, `power_iteration`,
247
+ `expm_multiply`) remain unbatched. Batched-input invocations raise a
248
+ clear shape error; explicit batched solver entry points are deferred to
249
+ 0.5.0.
250
+ - ADR-015 Stage 2 (operand-dtype-preserving `Context.asarray`, opt-in
251
+ exact dtype membership, operand-dtype solver workspaces) is deferred to
252
+ 0.5.0.
253
+ - Strict check level currently inherits the standard space-membership
254
+ semantics; additional spectral / metric probes at the space layer are
255
+ deferred to 0.5.0.
256
+
257
+ ## [0.3.1] — 2026-06-10
258
+
259
+ SpaceCore 0.3.1 is a release-candidate stabilization release for the `0.3.x`
260
+ API. It focuses on documentation consistency, tutorial execution, release
261
+ artifact checks, and public API audit cleanup. It does not add new solver
262
+ families or SDPLab-specific downstream integration.
263
+
264
+ ### Documentation
265
+
266
+ - Reworked API reference landing pages for backend, context, spaces, linear
267
+ operators, functionals, and linalg.
268
+ - Added design notes for context ownership, batching, and capability dispatch.
269
+ - Clarified conversion and dtype policy documentation for explicit target
270
+ contexts.
271
+ - Clarified adjoint documentation to distinguish coordinate transpose,
272
+ Euclidean adjoint, and metric/Riesz-represented adjoint behavior.
273
+
274
+ ### Examples and Tutorials
275
+
276
+ - Added a SpaceCore-only weighted Tikhonov worked example demonstrating
277
+ weighted spaces, metric adjoints, lazy operator algebra, CG, and an
278
+ independent dense NumPy reference solve.
279
+ - Integrated the weighted Tikhonov example into tests and documentation.
280
+
281
+ ### Testing and CI
282
+
283
+ - Documentation CI now builds Sphinx with warnings as errors.
284
+ - Release-candidate checks include full tests, strict docs build, public API
285
+ audit, artifact build, `twine check`, clean wheel installation, and smoke
286
+ testing.
287
+
288
+ ### Known limitations
289
+
290
+ - Optional backend behavior depends on installed optional dependencies. CuPy is
291
+ not required for the core release-candidate gate.
292
+ - The advanced regularized OT tutorial is an illustrative SpaceCore/JAX/Optax
293
+ example, not a claim that SpaceCore ships a production OT solver.
294
+
295
+ ## [0.3.0]
296
+
297
+ SpaceCore 0.3.0 is a breaking release for the unstable `0.x` series. Space
298
+ capabilities are now derived from actual structure, dtype, and inner product,
299
+ and conversions rebuild spaces through public factories so stale capabilities
300
+ are not retained.
301
+
302
+ ### Migration
303
+
304
+ | 0.2.x | 0.3.0 |
305
+ | --- | --- |
306
+ | `space.eigh(x)` | `space.spectral_decompose(x)` for eigenvalues and frame |
307
+ | `space.eigh(x)` | `space.spectrum(x)` for eigenvalues only |
308
+ | `sc.VectorSpace((n,))` | `sc.DenseVectorSpace((n,))` |
309
+ | `sc.VectorSpace((d, d))` | `sc.DenseCoordinateSpace((d, d))` |
310
+ | `ProductInnerProductSpace(...)` | `ProductSpace(...)` |
311
+ | `ProductStarSpace(...)` | `ProductSpace(...)` |
312
+ | `ProductJordanAlgebraSpace(...)` | `ProductSpace(...)` |
313
+ | `ProductEuclideanJordanAlgebraSpace(...)` | `ProductSpace(...)` |
314
+ | `StackedInnerProductSpace(...)` | `StackedSpace(...)` |
315
+ | `StackedStarSpace(...)` | `StackedSpace(...)` |
316
+ | `StackedJordanAlgebraSpace(...)` | `StackedSpace(...)` |
317
+ | `StackedEuclideanJordanAlgebraSpace(...)` | `StackedSpace(...)` |
318
+ | `BatchSpace` and `space.batch(...)` | leading-axis batched arrays with `vapply(...)` / `rvapply(...)` |
319
+ | `op.vapply(xs, batch_space=...)` | `op.vapply(xs)` |
320
+ | global context conversion policies | explicit `Context` construction and `obj.convert(ctx)` |
321
+ | global dtype preservation policies | target-context dtype during explicit conversion |
322
+
323
+ Prominent `eigh` replacement:
324
+
325
+ ```python
326
+ space.eigh(x)
327
+ # -> space.spectral_decompose(x) # eigenvalues and frame
328
+ # -> space.spectrum(x) # eigenvalues only
329
+ ```
330
+
331
+ ### Added
332
+
333
+ - `spectrum`, `spectral_decompose`, and `from_spectrum` as the public spectral
334
+ contract for Jordan spaces.
335
+ - `ElementwiseJordanSpace` for real or complex elementwise Jordan algebras.
336
+ - `EuclideanElementwiseJordanSpace` for real Euclidean elementwise Jordan
337
+ algebras.
338
+ - Jordan capability hierarchy separating `JordanAlgebraSpace` from
339
+ `EuclideanJordanAlgebraSpace`.
340
+ - `ProductStructure`, `TupleStructure`, `PytreeStructure`, and
341
+ `ProductSpace.from_template` for structured product elements.
342
+ - `ProductSpectralDecomposition` for product spectral data independent of
343
+ product element structure.
344
+ - `StackedSpace` for leading-axis repeated leaf spaces.
345
+ - Vectorizable axis-aware validation checks.
346
+ - `InnerProduct.validate_for(space)` and construction-time validation for
347
+ `WeightedInnerProduct`.
348
+ - `scripts/api_audit.py` for repository and downstream migration audits.
349
+
350
+ ### Changed
351
+
352
+ - `VectorSpace` is an abstract linear-capability base.
353
+ - Previous concrete `VectorSpace` use cases moved to `DenseVectorSpace` for
354
+ one-dimensional dense vectors and `DenseCoordinateSpace` for generic dense
355
+ coordinate arrays.
356
+ - `DenseVectorSpace` is now a plain one-dimensional vector space with star and
357
+ no Jordan capability by default.
358
+ - Elementwise Euclidean-Jordan capability is selected only for real dtype with
359
+ `EuclideanInnerProduct`.
360
+ - `ProductSpace(...)` and `StackedSpace(...)` are the only public product and
361
+ stacked constructors; they auto-dispatch to private implementation classes.
362
+ - `convert()` for elementwise, product, and stacked spaces recomputes
363
+ capabilities through public factories.
364
+ - `ProductSpace.spectral_decompose` returns explicit product spectral data
365
+ rather than routing decompositions through element structure adapters.
366
+
367
+ ### Removed
368
+
369
+ - Removed `eigh` from spaces. Use `spectral_decompose` when both eigenvalues
370
+ and a reconstruction frame are needed, or `spectrum` for eigenvalues only.
371
+ - Removed public specialized product and stacked constructors from the public
372
+ API.
373
+ - Removed `BatchSpace`, `Space.batch`, and `batch_space=` arguments from public
374
+ batching APIs. Use leading-axis vectorization through `vapply` and `rvapply`.
375
+ - Removed global context-policy and dtype-policy APIs. Conversion now follows
376
+ the requested target `Context` directly.
377
+
378
+ ## [0.2.0]
379
+
380
+ SpaceCore 0.2.0 is a major API expansion. The backend layer now sits on the
381
+ Array API standard. Operators gained a lazy algebra with adjoint views,
382
+ composition, sums, and scaling. A new `Functional` hierarchy provides
383
+ scalar-valued maps with gradients and pull-backs. A new `spacecore.linalg`
384
+ module ships four JIT-compatible iterative solvers. Spaces, operators, and
385
+ functionals share a single validation pattern via `checked_method`, and the
386
+ public API is documented to numpydoc standard with doctest coverage.
387
+
388
+ This release introduces breaking changes; see [Migration](#migration-from-01x).
389
+
390
+ ### Added
391
+
392
+ #### Backend
393
+
394
+ - Migrated `BackendOps` to the Array API standard via `array-api-compat`.
395
+ - `CuPyOps` and the `cupy` backend family as an optional install
396
+ (`pip install 'spacecore[cupy]'`).
397
+ - `BackendOps.is_complex_dtype` for backend-aware complex detection.
398
+ - `BackendOps.real_dtype` for extracting the real dtype matching a complex one.
399
+ - Broadened backend coverage for array creation, dtype conversion, sparse
400
+ conversion, indexing, reductions, linear algebra, loop primitives
401
+ (`fori_loop`, `while_loop`, `cond`), tree helpers, and vectorized mapping.
402
+ - JAX pytree registration for operator, space, and functional types so they
403
+ pass through `jax.jit`, `jax.vmap`, and `jax.grad` boundaries.
404
+
405
+ #### Context and checking
406
+
407
+ - Public free-function API in `spacecore._contextual`: `set_context`,
408
+ `get_context`, `resolve_context_priority`, `register_ops`, and the
409
+ resolution-policy accessors.
410
+ - Extended `checked_method` to support validation against `self` and multiple
411
+ input argument positions.
412
+ - Reusable space-validation checks: backend, dtype, shape, Hermitian,
413
+ square-matrix, product-structure, and product-component checks. Documented
414
+ at `docs/source/design/checking_policy.rst`.
415
+
416
+ #### Spaces
417
+
418
+ - `BatchSpace` for batched elements with explicit batch shape and batch-axis
419
+ metadata.
420
+
421
+ #### Linear operators
422
+
423
+ - Lazy operator algebra:
424
+ - `A @ B` composes operators.
425
+ - `A + B` sums operators.
426
+ - `alpha * A` scales an operator.
427
+ - `A.H` returns a cached adjoint view satisfying `A.H.H is A`.
428
+ - Algebraic simplification eliminates `I`, `Zero`, `alpha = 0`, `alpha = 1`,
429
+ and flattens nested sums.
430
+ - New operator types: `IdentityLinOp`, `ZeroLinOp`, `MatrixFreeLinOp`,
431
+ `DiagonalLinOp`.
432
+ - Structural `LinOp.is_hermitian()` reporting `True`, `False`, or `None`
433
+ (unknown) without applying incorrect Euclidean assumptions for custom space
434
+ geometries.
435
+ - `LinOp.to_dense()` for materializing operators as backend arrays.
436
+ - Product-structured operators and batched lifting:
437
+ - `ProductLinOp`
438
+ - `BlockDiagonalLinOp`
439
+ - `StackedLinOp`
440
+ - `SumToSingleLinOp`
441
+ - `vapply` / `rvapply` paths for batched operator application.
442
+
443
+ #### Functionals
444
+
445
+ - `Functional` as an abstract base for scalar-valued maps on spaces, with
446
+ `value`, `grad`, `hess_apply`, and batched counterparts.
447
+ - Linear functionals: `LinearFunctional`, `InnerProductFunctional`,
448
+ `MatrixFreeLinearFunctional`.
449
+ - Quadratic forms: `QuadraticForm`, `LinOpQuadraticForm`.
450
+ - `Functional.compose` and `ComposedFunctional` for pull-backs along linear
451
+ operators, with specializations that preserve the concrete functional type
452
+ when possible.
453
+
454
+ #### Linear algebra
455
+
456
+ The `spacecore.linalg` module is new in 0.2.0. It provides JIT-compatible
457
+ iterative solvers and structured result types.
458
+
459
+ - Iterative solvers:
460
+ - `cg` for Hermitian positive-definite systems.
461
+ - `lsqr` for rectangular least-squares problems.
462
+ - `power_iteration` for dominant-eigenpair estimates of a `LinOp` or
463
+ `QuadraticForm`.
464
+ - `lanczos_smallest` for smallest-Ritz-eigenpair estimates of Hermitian
465
+ operators.
466
+ - `expm_multiply` for Krylov matrix-exponential actions `exp(t A) v` on
467
+ Hermitian operators, with complex `t` supported for Schrodinger-type
468
+ evolution.
469
+ - Structured result types `CGResult`, `LSQRResult`, `PowerIterationResult`,
470
+ `LanczosResult`, and `ExpmMultiplyResult`, each carrying convergence
471
+ diagnostics and a compact `__repr__`.
472
+ - Solvers are geometry-aware: norms, inner products, and the default initial
473
+ vector use `Space.inner` and `Space.norm` rather than assuming Euclidean
474
+ geometry. This makes the solvers correct on custom inner products such as
475
+ RKHS or weighted spaces.
476
+
477
+ #### Documentation
478
+
479
+ - Numpydoc-standard public docstrings with runnable doctests for solvers,
480
+ spaces, operators, functionals, backends, and contextual helpers.
481
+ - API reference pages for backend ops, spaces, linear operators, functionals,
482
+ and linear algebra.
483
+ - JAX integration design note at `docs/source/design/jax_integration.rst`
484
+ covering trace-time operator algebra and recommended JIT usage.
485
+ - Tutorials for backend operations, linear operators, and matrix-free linalg
486
+ workflows.
487
+
488
+ #### Tooling
489
+
490
+ - Optional dependency groups: `[jax]`, `[torch]`, `[cupy]`, `[examples]`,
491
+ `[docs]`, `[dev]`.
492
+ - Explicit `__all__` at the top level covering new backends, operators,
493
+ functionals, solvers, result types, validation checks, and contextual
494
+ helpers.
495
+ - CI runs a JIT-traceability audit in `--check` mode and enforces a 70%
496
+ coverage floor via `pytest-cov`.
497
+ - Cross-backend tests covering NumPy, JAX, Torch, and optional CuPy.
498
+
499
+ ### Changed
500
+
501
+ - Restructured `_contextual` to hide implementation details while preserving
502
+ the public API via free functions.
503
+ - Replaced manual `if self._enable_checks` guards with `checked_method` across
504
+ `Space`, `LinOp`, and `Functional`. Inline guards are now reserved for
505
+ non-membership checks such as dense-array assertions and custom output-shape
506
+ checks.
507
+ - Improved `VectorSpace`, `HermitianSpace`, and `ProductSpace` conversion
508
+ behavior, validation, batching support, and docstrings.
509
+ - Improved linear-operator equality, representation, conversion, and JAX
510
+ pytree behavior.
511
+ - `spacecore.__version__` now resolves from package metadata via
512
+ `importlib.metadata` instead of a hand-maintained constant.
513
+ - Bumped the package version to `0.2.0`.
514
+
515
+ ### Fixed
516
+
517
+ - `LinOp.__eq__` returns `NotImplemented` instead of raising
518
+ `NotImplementedError` on the base class, so `op == None` and
519
+ `op in some_list` no longer raise.
520
+ - `DenseLinOp.is_hermitian` and `SparseLinOp.is_hermitian` return `None` for
521
+ custom space geometries instead of applying an incorrect Euclidean
522
+ matrix-symmetry test.
523
+
524
+ ### Migration from 0.1.x
525
+
526
+ - `BackendOps.eps` is now a method `eps(dtype)` rather than a property.
527
+ Callers must pass a dtype, typically `ctx.dtype`.
528
+ - The implementation attribute `DenseLinOp.A` is now a `cached_property`
529
+ backed by `_A`. The public attribute access `op.A` is unchanged.
530
+ - `LinOp.__eq__` returns `NotImplemented` rather than raising; downstream code
531
+ relying on the exception should be updated to handle the new behavior.
532
+ - Several module-internal helpers in `spacecore._contextual` moved to private
533
+ modules. Use the public functions re-exported from `spacecore._contextual`
534
+ (`set_context`, `get_context`, `resolve_context_priority`, `register_ops`,
535
+ `set_resolution_policy`, and the dtype-policy accessors) rather than
536
+ importing from internal modules.
537
+
538
+ ### Known limitations
539
+
540
+ - `cg`, `lsqr`, and `power_iteration` do not structurally validate operator
541
+ properties (positive-definiteness, full Hermiticity) and may silently
542
+ produce incorrect results on inputs that violate their preconditions. See
543
+ each function's `Notes` section for details.
544
+ - Operator algebra runs Python-level simplification at construction time. For
545
+ maximum JIT efficiency, assemble operator expressions outside the
546
+ `jax.jit` boundary; see the JAX integration design note.
547
+ - `MatrixFreeLinOp` stores its callables in pytree auxiliary data.
548
+ Constructing one inside a JIT-traced function with a new lambda each call
549
+ triggers retracing. Construct outside the traced region with a stable
550
+ callable reference.
551
+ - The CuPy backend is provided as a preview. Coverage of non-standard
552
+ operations and sparse handling may evolve in a subsequent release.
553
+
554
+ [0.3.1]: https://github.com/Pavlo3P/SpaceCore/releases/tag/v0.3.1
555
+ [0.3.0]: https://github.com/Pavlo3P/SpaceCore/releases/tag/v0.3.0
556
+ [0.2.0]: https://github.com/Pavlo3P/SpaceCore/releases/tag/v0.2.0
@@ -3,7 +3,6 @@ include CONTRIBUTING.md
3
3
 
4
4
  recursive-include docs/source *.rst *.py *.css
5
5
  recursive-include docs/dev *.md
6
- recursive-include examples *.py
7
6
  recursive-include tests *.py
8
7
  recursive-include tutorials *.ipynb *.md
9
8