dit 2.1__tar.gz → 2.3__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 (506) hide show
  1. {dit-2.1 → dit-2.3}/PKG-INFO +10 -7
  2. {dit-2.1 → dit-2.3}/README.rst +1 -1
  3. {dit-2.1 → dit-2.3}/dit/__init__.py +9 -1
  4. {dit-2.1 → dit-2.3}/dit/algorithms/__init__.py +16 -0
  5. dit-2.3/dit/algorithms/caekl_psp.py +215 -0
  6. {dit-2.1 → dit-2.3}/dit/algorithms/distribution_optimizers.py +81 -0
  7. dit-2.3/dit/algorithms/marginal_lifts.py +182 -0
  8. dit-2.3/dit/algorithms/mixture_of_products.py +255 -0
  9. dit-2.3/dit/algorithms/mprojection.py +606 -0
  10. {dit-2.1 → dit-2.3}/dit/algorithms/optimization.py +102 -48
  11. {dit-2.1 → dit-2.3}/dit/algorithms/optimization_jax.py +95 -38
  12. {dit-2.1 → dit-2.3}/dit/algorithms/optimization_pytensor.py +32 -1
  13. {dit-2.1 → dit-2.3}/dit/algorithms/optimization_torch.py +30 -36
  14. dit-2.3/dit/algorithms/submodular.py +165 -0
  15. dit-2.3/dit/algorithms/support_spectrum.py +165 -0
  16. {dit-2.1 → dit-2.3}/dit/coding/__init__.py +12 -0
  17. {dit-2.1 → dit-2.3}/dit/coding/_util.py +26 -0
  18. {dit-2.1 → dit-2.3}/dit/coding/polar.py +1 -10
  19. dit-2.3/dit/coding/source_polar.py +508 -0
  20. {dit-2.1 → dit-2.3}/dit/distribution.py +231 -31
  21. {dit-2.1 → dit-2.3}/dit/divergences/__init__.py +9 -4
  22. dit-2.3/dit/divergences/coupling_metrics.py +274 -0
  23. {dit-2.1 → dit-2.3}/dit/divergences/cross_entropy.py +20 -0
  24. dit-2.3/dit/divergences/earth_movers_distance.py +233 -0
  25. {dit-2.1 → dit-2.3}/dit/divergences/hypercontractivity_coefficient.py +12 -4
  26. {dit-2.1 → dit-2.3}/dit/example_dists/__init__.py +1 -0
  27. dit-2.3/dit/example_dists/empirical/__init__.py +16 -0
  28. dit-2.3/dit/example_dists/empirical/_music.py +127 -0
  29. dit-2.3/dit/example_dists/empirical/bach.py +77 -0
  30. dit-2.3/dit/example_dists/empirical/blood_types.py +203 -0
  31. dit-2.3/dit/example_dists/empirical/car.py +95 -0
  32. dit-2.3/dit/example_dists/empirical/congress.py +109 -0
  33. dit-2.3/dit/example_dists/empirical/corelli.py +132 -0
  34. dit-2.3/dit/example_dists/empirical/penguins.py +77 -0
  35. dit-2.3/dit/example_dists/empirical/student.py +94 -0
  36. dit-2.3/dit/example_dists/empirical/titanic.py +85 -0
  37. {dit-2.1 → dit-2.3}/dit/multivariate/__init__.py +3 -0
  38. {dit-2.1 → dit-2.3}/dit/multivariate/caekl_mutual_information.py +19 -8
  39. {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/__init__.py +1 -0
  40. dit-2.3/dit/multivariate/common_informations/_functional_partition.py +223 -0
  41. {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/base_markov_optimizer.py +12 -1
  42. {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/exact_common_information.py +7 -3
  43. dit-2.3/dit/multivariate/common_informations/functional_common_information.py +572 -0
  44. dit-2.3/dit/multivariate/common_informations/symbolic_ansatz.py +103 -0
  45. dit-2.3/dit/multivariate/common_informations/symbolic_markov.py +196 -0
  46. dit-2.3/dit/multivariate/common_informations/symbolic_solve.py +301 -0
  47. dit-2.3/dit/multivariate/common_informations/tension_common_information.py +234 -0
  48. dit-2.3/dit/multivariate/cross_mutual_information.py +205 -0
  49. {dit-2.1 → dit-2.3}/dit/multivariate/interaction_information.py +1 -1
  50. dit-2.3/dit/multivariate/kirkwood.py +246 -0
  51. dit-2.3/dit/multivariate/mmi_psp.py +247 -0
  52. dit-2.3/dit/multivariate/s_information.py +48 -0
  53. {dit-2.1 → dit-2.3}/dit/other/__init__.py +1 -0
  54. {dit-2.1 → dit-2.3}/dit/other/extropy.py +10 -0
  55. dit-2.3/dit/other/negentropy.py +54 -0
  56. {dit-2.1 → dit-2.3}/dit/pid/measures/__init__.py +4 -1
  57. {dit-2.1 → dit-2.3}/dit/pid/measures/imin.py +19 -0
  58. {dit-2.1 → dit-2.3}/dit/pid/measures/immi.py +6 -1
  59. {dit-2.1 → dit-2.3}/dit/pid/pid.py +19 -2
  60. {dit-2.1 → dit-2.3}/dit/profiles/__init__.py +3 -0
  61. dit-2.3/dit/profiles/binding_mixture.py +138 -0
  62. {dit-2.1 → dit-2.3}/dit/profiles/information_partitions.py +176 -0
  63. dit-2.3/dit/profiles/marginal_lift.py +91 -0
  64. dit-2.3/dit/profiles/mflat.py +127 -0
  65. {dit-2.1 → dit-2.3}/dit/profiles/schneidman.py +10 -3
  66. dit-2.3/dit/rate_distortion/__init__.py +13 -0
  67. dit-2.3/dit/rate_distortion/bottleneck_algorithms.py +501 -0
  68. {dit-2.1 → dit-2.3}/dit/rate_distortion/curves.py +101 -8
  69. dit-2.3/dit/rate_distortion/gray_wyner/__init__.py +63 -0
  70. {dit-2.1 → dit-2.3}/dit/rate_distortion/gray_wyner/network.py +208 -1
  71. {dit-2.1 → dit-2.3}/dit/rate_distortion/gray_wyner/optimizer.py +189 -7
  72. dit-2.3/dit/rate_distortion/gray_wyner/plotting.py +166 -0
  73. dit-2.3/dit/rate_distortion/gray_wyner/region.py +472 -0
  74. dit-2.3/dit/rate_distortion/gray_wyner/shape.py +310 -0
  75. {dit-2.1 → dit-2.3}/dit/rate_distortion/information_bottleneck.py +53 -0
  76. {dit-2.1 → dit-2.3}/dit/shannon/shannon.py +19 -0
  77. dit-2.3/dit/symbolic/__init__.py +33 -0
  78. dit-2.3/dit/symbolic/distributions.py +165 -0
  79. {dit-2.1 → dit-2.3}/dit/utils/optimization.py +33 -0
  80. {dit-2.1 → dit-2.3}/dit/utils/testing.py +6 -1
  81. dit-2.3/dit/visualization/__init__.py +10 -0
  82. dit-2.3/dit/visualization/upset.py +313 -0
  83. {dit-2.1 → dit-2.3}/pyproject.toml +20 -9
  84. {dit-2.1 → dit-2.3}/tests/algorithms/test_admui.py +24 -5
  85. dit-2.3/tests/algorithms/test_caekl_psp_optimizer.py +36 -0
  86. dit-2.3/tests/algorithms/test_mixture_of_products.py +136 -0
  87. dit-2.3/tests/algorithms/test_mprojection.py +200 -0
  88. {dit-2.1 → dit-2.3}/tests/algorithms/test_optimizers.py +4 -0
  89. dit-2.3/tests/algorithms/test_submodular.py +60 -0
  90. dit-2.3/tests/algorithms/test_support_spectrum.py +100 -0
  91. dit-2.3/tests/coding/test_source_polar.py +282 -0
  92. dit-2.3/tests/divergences/test_coupling_metrics.py +94 -0
  93. dit-2.3/tests/divergences/test_emd.py +115 -0
  94. dit-2.3/tests/example_dists/empirical/__init__.py +0 -0
  95. dit-2.3/tests/example_dists/empirical/test_bach.py +44 -0
  96. dit-2.3/tests/example_dists/empirical/test_blood_types.py +67 -0
  97. dit-2.3/tests/example_dists/empirical/test_car.py +69 -0
  98. dit-2.3/tests/example_dists/empirical/test_congress.py +72 -0
  99. dit-2.3/tests/example_dists/empirical/test_corelli.py +47 -0
  100. dit-2.3/tests/example_dists/empirical/test_penguins.py +60 -0
  101. dit-2.3/tests/example_dists/empirical/test_student.py +60 -0
  102. dit-2.3/tests/example_dists/empirical/test_titanic.py +59 -0
  103. {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_exact_common_information.py +16 -0
  104. dit-2.3/tests/multivariate/common_informations/test_functional_common_information.py +386 -0
  105. dit-2.3/tests/multivariate/common_informations/test_tension_common_information.py +127 -0
  106. dit-2.3/tests/multivariate/test_cross_mutual_information.py +100 -0
  107. dit-2.3/tests/multivariate/test_delta_gamma.py +286 -0
  108. dit-2.3/tests/multivariate/test_kirkwood.py +266 -0
  109. dit-2.3/tests/multivariate/test_mmi_psp.py +62 -0
  110. dit-2.3/tests/multivariate/test_s_information.py +56 -0
  111. dit-2.3/tests/other/test_negentropy.py +62 -0
  112. {dit-2.1 → dit-2.3}/tests/pid/test_syndisc.py +6 -4
  113. dit-2.3/tests/profiles/test_binding_mixture.py +32 -0
  114. dit-2.3/tests/profiles/test_dual_dependency_decomposition.py +128 -0
  115. dit-2.3/tests/profiles/test_marginal_lift.py +75 -0
  116. dit-2.3/tests/profiles/test_mflat_connected.py +99 -0
  117. dit-2.3/tests/rate_distortion/test_bottleneck_algorithms.py +83 -0
  118. {dit-2.1 → dit-2.3}/tests/rate_distortion/test_curves.py +56 -0
  119. {dit-2.1 → dit-2.3}/tests/rate_distortion/test_ib.py +15 -0
  120. dit-2.3/tests/rate_distortion/test_tension.py +350 -0
  121. dit-2.3/tests/symbolic/__init__.py +0 -0
  122. dit-2.3/tests/symbolic/test_common_information.py +142 -0
  123. dit-2.3/tests/symbolic/test_cross_validation.py +362 -0
  124. dit-2.3/tests/symbolic/test_symbolic.py +209 -0
  125. {dit-2.1 → dit-2.3}/tests/test_distribution.py +71 -0
  126. {dit-2.1 → dit-2.3}/tests/test_inequalities.py +50 -1
  127. dit-2.3/tests/visualization/__init__.py +3 -0
  128. dit-2.3/tests/visualization/test_upset.py +165 -0
  129. dit-2.1/dit/divergences/coupling_metrics.py +0 -86
  130. dit-2.1/dit/divergences/earth_movers_distance.py +0 -127
  131. dit-2.1/dit/multivariate/common_informations/functional_common_information.py +0 -169
  132. dit-2.1/dit/rate_distortion/__init__.py +0 -7
  133. dit-2.1/dit/rate_distortion/gray_wyner/__init__.py +0 -31
  134. dit-2.1/dit/rate_distortion/gray_wyner/plotting.py +0 -49
  135. dit-2.1/tests/divergences/test_coupling_metrics.py +0 -19
  136. dit-2.1/tests/divergences/test_emd.py +0 -57
  137. dit-2.1/tests/multivariate/common_informations/test_functional_common_information.py +0 -56
  138. dit-2.1/tests/multivariate/test_delta_gamma.py +0 -84
  139. {dit-2.1 → dit-2.3}/.gitignore +0 -0
  140. {dit-2.1 → dit-2.3}/CREDITS.rst +0 -0
  141. {dit-2.1 → dit-2.3}/LICENSE.txt +0 -0
  142. {dit-2.1 → dit-2.3}/dit/abc.py +0 -0
  143. {dit-2.1 → dit-2.3}/dit/abstractdist.py +0 -0
  144. {dit-2.1 → dit-2.3}/dit/algorithms/admui.py +0 -0
  145. {dit-2.1 → dit-2.3}/dit/algorithms/broja_cone.py +0 -0
  146. {dit-2.1 → dit-2.3}/dit/algorithms/broja_method.py +0 -0
  147. {dit-2.1 → dit-2.3}/dit/algorithms/broja_util.py +0 -0
  148. {dit-2.1 → dit-2.3}/dit/algorithms/channelcapacity.py +0 -0
  149. {dit-2.1 → dit-2.3}/dit/algorithms/convex_maximization.py +0 -0
  150. {dit-2.1 → dit-2.3}/dit/algorithms/frankwolfe.py +0 -0
  151. {dit-2.1 → dit-2.3}/dit/algorithms/ipf.py +0 -0
  152. {dit-2.1 → dit-2.3}/dit/algorithms/lattice.py +0 -0
  153. {dit-2.1 → dit-2.3}/dit/algorithms/maxentropy.py +0 -0
  154. {dit-2.1 → dit-2.3}/dit/algorithms/maxentropyfw.py +0 -0
  155. {dit-2.1 → dit-2.3}/dit/algorithms/minimal_sufficient_statistic.py +0 -0
  156. {dit-2.1 → dit-2.3}/dit/algorithms/optutil.py +0 -0
  157. {dit-2.1 → dit-2.3}/dit/algorithms/pid_broja.py +0 -0
  158. {dit-2.1 → dit-2.3}/dit/algorithms/prune_expand.py +0 -0
  159. {dit-2.1 → dit-2.3}/dit/algorithms/stats.py +0 -0
  160. {dit-2.1 → dit-2.3}/dit/bgm.py +0 -0
  161. {dit-2.1 → dit-2.3}/dit/cdisthelpers.py +0 -0
  162. {dit-2.1 → dit-2.3}/dit/channelorder/__init__.py +0 -0
  163. {dit-2.1 → dit-2.3}/dit/channelorder/_utils.py +0 -0
  164. {dit-2.1 → dit-2.3}/dit/channelorder/deficiency.py +0 -0
  165. {dit-2.1 → dit-2.3}/dit/channelorder/orderings.py +0 -0
  166. {dit-2.1 → dit-2.3}/dit/coding/_channel.py +0 -0
  167. {dit-2.1 → dit-2.3}/dit/coding/_gf2.py +0 -0
  168. {dit-2.1 → dit-2.3}/dit/coding/base.py +0 -0
  169. {dit-2.1 → dit-2.3}/dit/coding/block_codes.py +0 -0
  170. {dit-2.1 → dit-2.3}/dit/coding/codes.py +0 -0
  171. {dit-2.1 → dit-2.3}/dit/coding/convolutional.py +0 -0
  172. {dit-2.1 → dit-2.3}/dit/coding/ldpc.py +0 -0
  173. {dit-2.1 → dit-2.3}/dit/coding/linear.py +0 -0
  174. {dit-2.1 → dit-2.3}/dit/coding/symbol_code.py +0 -0
  175. {dit-2.1 → dit-2.3}/dit/coding/tunstall.py +0 -0
  176. {dit-2.1 → dit-2.3}/dit/coding/universal.py +0 -0
  177. {dit-2.1 → dit-2.3}/dit/distconst.py +0 -0
  178. {dit-2.1 → dit-2.3}/dit/divergences/_kl_nonmerge.py +0 -0
  179. {dit-2.1 → dit-2.3}/dit/divergences/copy_mutual_information.py +0 -0
  180. {dit-2.1 → dit-2.3}/dit/divergences/generalized_divergences.py +0 -0
  181. {dit-2.1 → dit-2.3}/dit/divergences/jensen_shannon_divergence.py +0 -0
  182. {dit-2.1 → dit-2.3}/dit/divergences/kullback_leibler_divergence.py +0 -0
  183. {dit-2.1 → dit-2.3}/dit/divergences/maximum_correlation.py +0 -0
  184. {dit-2.1 → dit-2.3}/dit/divergences/pmf.py +0 -0
  185. {dit-2.1 → dit-2.3}/dit/divergences/variational_distance.py +0 -0
  186. {dit-2.1 → dit-2.3}/dit/example_channels/__init__.py +0 -0
  187. {dit-2.1 → dit-2.3}/dit/example_channels/_util.py +0 -0
  188. {dit-2.1 → dit-2.3}/dit/example_channels/binary.py +0 -0
  189. {dit-2.1 → dit-2.3}/dit/example_channels/qary.py +0 -0
  190. {dit-2.1 → dit-2.3}/dit/example_channels/trivial.py +0 -0
  191. {dit-2.1 → dit-2.3}/dit/example_dists/circuits.py +0 -0
  192. {dit-2.1 → dit-2.3}/dit/example_dists/dependencies.py +0 -0
  193. {dit-2.1 → dit-2.3}/dit/example_dists/dice.py +0 -0
  194. {dit-2.1 → dit-2.3}/dit/example_dists/giant_bit.py +0 -0
  195. {dit-2.1 → dit-2.3}/dit/example_dists/intrinsic.py +0 -0
  196. {dit-2.1 → dit-2.3}/dit/example_dists/mdbsi.py +0 -0
  197. {dit-2.1 → dit-2.3}/dit/example_dists/miscellaneous.py +0 -0
  198. {dit-2.1 → dit-2.3}/dit/example_dists/n_mod_m.py +0 -0
  199. {dit-2.1 → dit-2.3}/dit/example_dists/nonsignalling_boxes.py +0 -0
  200. {dit-2.1 → dit-2.3}/dit/example_dists/numeric.py +0 -0
  201. {dit-2.1 → dit-2.3}/dit/exceptions.py +0 -0
  202. {dit-2.1 → dit-2.3}/dit/helpers.py +0 -0
  203. {dit-2.1 → dit-2.3}/dit/inference/__init__.py +0 -0
  204. {dit-2.1 → dit-2.3}/dit/inference/binning.py +0 -0
  205. {dit-2.1 → dit-2.3}/dit/inference/counts.c +0 -0
  206. {dit-2.1 → dit-2.3}/dit/inference/counts.h +0 -0
  207. {dit-2.1 → dit-2.3}/dit/inference/counts.py +0 -0
  208. {dit-2.1 → dit-2.3}/dit/inference/estimators.py +0 -0
  209. {dit-2.1 → dit-2.3}/dit/inference/knn_estimators.py +0 -0
  210. {dit-2.1 → dit-2.3}/dit/inference/pycounts.pyx +0 -0
  211. {dit-2.1 → dit-2.3}/dit/inference/segmentaxis.py +0 -0
  212. {dit-2.1 → dit-2.3}/dit/inference/time_series.py +0 -0
  213. {dit-2.1 → dit-2.3}/dit/math/__init__.py +0 -0
  214. {dit-2.1 → dit-2.3}/dit/math/_close.pyx +0 -0
  215. {dit-2.1 → dit-2.3}/dit/math/_samplediscrete.pyx +0 -0
  216. {dit-2.1 → dit-2.3}/dit/math/aitchison.py +0 -0
  217. {dit-2.1 → dit-2.3}/dit/math/combinatorics.py +0 -0
  218. {dit-2.1 → dit-2.3}/dit/math/equal.py +0 -0
  219. {dit-2.1 → dit-2.3}/dit/math/fraction.py +0 -0
  220. {dit-2.1 → dit-2.3}/dit/math/misc.py +0 -0
  221. {dit-2.1 → dit-2.3}/dit/math/ops.py +0 -0
  222. {dit-2.1 → dit-2.3}/dit/math/pmfops.py +0 -0
  223. {dit-2.1 → dit-2.3}/dit/math/sampling.py +0 -0
  224. {dit-2.1 → dit-2.3}/dit/math/sigmaalgebra.py +0 -0
  225. {dit-2.1 → dit-2.3}/dit/multivariate/_backend.py +0 -0
  226. {dit-2.1 → dit-2.3}/dit/multivariate/cohesion.py +0 -0
  227. {dit-2.1 → dit-2.3}/dit/multivariate/coinformation.py +0 -0
  228. {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/beta_common_information.py +0 -0
  229. {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/gk_common_information.py +0 -0
  230. {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/kamath_common_information.py +0 -0
  231. {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/maxent_function.py +0 -0
  232. {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/mss_common_information.py +0 -0
  233. {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/stochastic_gk_common_information.py +0 -0
  234. {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/wyner_common_information.py +0 -0
  235. {dit-2.1 → dit-2.3}/dit/multivariate/delta_gamma.py +0 -0
  236. {dit-2.1 → dit-2.3}/dit/multivariate/deweese.py +0 -0
  237. {dit-2.1 → dit-2.3}/dit/multivariate/dual_total_correlation.py +0 -0
  238. {dit-2.1 → dit-2.3}/dit/multivariate/entropy.py +0 -0
  239. {dit-2.1 → dit-2.3}/dit/multivariate/logarithmic_decomposition.py +0 -0
  240. {dit-2.1 → dit-2.3}/dit/multivariate/necessary_conditional_entropy.py +0 -0
  241. {dit-2.1 → dit-2.3}/dit/multivariate/o_information.py +0 -0
  242. {dit-2.1 → dit-2.3}/dit/multivariate/quax_synergy.py +0 -0
  243. {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/__init__.py +0 -0
  244. {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/base_skar_optimizers.py +0 -0
  245. {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/interactive_intrinsic_mutual_informations.py +0 -0
  246. {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/intrinsic_mutual_informations.py +0 -0
  247. {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/minimal_intrinsic_mutual_informations.py +0 -0
  248. {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/no_communication.py +0 -0
  249. {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/one_way_skar.py +0 -0
  250. {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/reduced_intrinsic_mutual_informations.py +0 -0
  251. {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/secrecy_capacity.py +0 -0
  252. {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/skar_lower_bounds.py +0 -0
  253. {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/trivial_bounds.py +0 -0
  254. {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/two_part_intrinsic_mutual_informations.py +0 -0
  255. {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/two_way_skar.py +0 -0
  256. {dit-2.1 → dit-2.3}/dit/multivariate/synergistic_disclosure.py +0 -0
  257. {dit-2.1 → dit-2.3}/dit/multivariate/total_correlation.py +0 -0
  258. {dit-2.1 → dit-2.3}/dit/multivariate/transmission.py +0 -0
  259. {dit-2.1 → dit-2.3}/dit/multivariate/tse_complexity.py +0 -0
  260. {dit-2.1 → dit-2.3}/dit/multivariate/union_information.py +0 -0
  261. {dit-2.1 → dit-2.3}/dit/other/cumulative_residual_entropy.py +0 -0
  262. {dit-2.1 → dit-2.3}/dit/other/disequilibrium.py +0 -0
  263. {dit-2.1 → dit-2.3}/dit/other/lautum_information.py +0 -0
  264. {dit-2.1 → dit-2.3}/dit/other/perplexity.py +0 -0
  265. {dit-2.1 → dit-2.3}/dit/other/renyi_entropy.py +0 -0
  266. {dit-2.1 → dit-2.3}/dit/other/sibson_mutual_information.py +0 -0
  267. {dit-2.1 → dit-2.3}/dit/other/tsallis_entropy.py +0 -0
  268. {dit-2.1 → dit-2.3}/dit/params.py +0 -0
  269. {dit-2.1 → dit-2.3}/dit/pid/__init__.py +0 -0
  270. {dit-2.1 → dit-2.3}/dit/pid/distributions/__init__.py +0 -0
  271. {dit-2.1 → dit-2.3}/dit/pid/distributions/bivariate.py +0 -0
  272. {dit-2.1 → dit-2.3}/dit/pid/distributions/trivariate.py +0 -0
  273. {dit-2.1 → dit-2.3}/dit/pid/hcs.py +0 -0
  274. {dit-2.1 → dit-2.3}/dit/pid/helpers.py +0 -0
  275. {dit-2.1 → dit-2.3}/dit/pid/hmos.py +0 -0
  276. {dit-2.1 → dit-2.3}/dit/pid/measures/ibroja.py +0 -0
  277. {dit-2.1 → dit-2.3}/dit/pid/measures/iccs.py +0 -0
  278. {dit-2.1 → dit-2.3}/dit/pid/measures/ict.py +0 -0
  279. {dit-2.1 → dit-2.3}/dit/pid/measures/ideg.py +0 -0
  280. {dit-2.1 → dit-2.3}/dit/pid/measures/idelta.py +0 -0
  281. {dit-2.1 → dit-2.3}/dit/pid/measures/ideltalambda.py +0 -0
  282. {dit-2.1 → dit-2.3}/dit/pid/measures/idep.py +0 -0
  283. {dit-2.1 → dit-2.3}/dit/pid/measures/ido.py +0 -0
  284. {dit-2.1 → dit-2.3}/dit/pid/measures/igh.py +0 -0
  285. {dit-2.1 → dit-2.3}/dit/pid/measures/iig.py +0 -0
  286. {dit-2.1 → dit-2.3}/dit/pid/measures/iipid.py +0 -0
  287. {dit-2.1 → dit-2.3}/dit/pid/measures/imc.py +0 -0
  288. {dit-2.1 → dit-2.3}/dit/pid/measures/imes.py +0 -0
  289. {dit-2.1 → dit-2.3}/dit/pid/measures/ipm.py +0 -0
  290. {dit-2.1 → dit-2.3}/dit/pid/measures/iprec.py +0 -0
  291. {dit-2.1 → dit-2.3}/dit/pid/measures/iproj.py +0 -0
  292. {dit-2.1 → dit-2.3}/dit/pid/measures/irav.py +0 -0
  293. {dit-2.1 → dit-2.3}/dit/pid/measures/irdr.py +0 -0
  294. {dit-2.1 → dit-2.3}/dit/pid/measures/irr.py +0 -0
  295. {dit-2.1 → dit-2.3}/dit/pid/measures/iskar.py +0 -0
  296. {dit-2.1 → dit-2.3}/dit/pid/measures/isx.py +0 -0
  297. {dit-2.1 → dit-2.3}/dit/pid/measures/iwedge.py +0 -0
  298. {dit-2.1 → dit-2.3}/dit/pid/ped.py +0 -0
  299. {dit-2.1 → dit-2.3}/dit/pid/syndisc.py +0 -0
  300. {dit-2.1 → dit-2.3}/dit/profiles/base_profile.py +0 -0
  301. {dit-2.1 → dit-2.3}/dit/profiles/complexity_profile.py +0 -0
  302. {dit-2.1 → dit-2.3}/dit/profiles/entropy_triangle.py +0 -0
  303. {dit-2.1 → dit-2.3}/dit/profiles/marginal_utility_of_information.py +0 -0
  304. {dit-2.1 → dit-2.3}/dit/profiles/shapley_info_decomposition.py +0 -0
  305. {dit-2.1 → dit-2.3}/dit/rate_distortion/blahut_arimoto.py +0 -0
  306. {dit-2.1 → dit-2.3}/dit/rate_distortion/distortions.py +0 -0
  307. {dit-2.1 → dit-2.3}/dit/rate_distortion/gray_wyner/curve.py +0 -0
  308. {dit-2.1 → dit-2.3}/dit/rate_distortion/plotting.py +0 -0
  309. {dit-2.1 → dit-2.3}/dit/rate_distortion/rate_distortion.py +0 -0
  310. {dit-2.1 → dit-2.3}/dit/samplespace.py +0 -0
  311. {dit-2.1 → dit-2.3}/dit/shannon/__init__.py +0 -0
  312. {dit-2.1 → dit-2.3}/dit/utils/__init__.py +0 -0
  313. {dit-2.1 → dit-2.3}/dit/utils/bindargs.py +0 -0
  314. {dit-2.1 → dit-2.3}/dit/utils/context.py +0 -0
  315. {dit-2.1 → dit-2.3}/dit/utils/latexarray.py +0 -0
  316. {dit-2.1 → dit-2.3}/dit/utils/logger.py +0 -0
  317. {dit-2.1 → dit-2.3}/dit/utils/misc.py +0 -0
  318. {dit-2.1 → dit-2.3}/dit/utils/table.py +0 -0
  319. {dit-2.1 → dit-2.3}/dit/utils/units.py +0 -0
  320. {dit-2.1 → dit-2.3}/dit/validate.py +0 -0
  321. {dit-2.1 → dit-2.3}/tests/__init__.py +0 -0
  322. {dit-2.1 → dit-2.3}/tests/_backends.py +0 -0
  323. {dit-2.1 → dit-2.3}/tests/algorithms/__init__.py +0 -0
  324. {dit-2.1 → dit-2.3}/tests/algorithms/test_broja_cone.py +0 -0
  325. {dit-2.1 → dit-2.3}/tests/algorithms/test_channelcapacity.py +0 -0
  326. {dit-2.1 → dit-2.3}/tests/algorithms/test_degrees_of_freedom.py +0 -0
  327. {dit-2.1 → dit-2.3}/tests/algorithms/test_ipf.py +0 -0
  328. {dit-2.1 → dit-2.3}/tests/algorithms/test_lattice.py +0 -0
  329. {dit-2.1 → dit-2.3}/tests/algorithms/test_marginal_constraints.py +0 -0
  330. {dit-2.1 → dit-2.3}/tests/algorithms/test_maxentropy_fast.py +0 -0
  331. {dit-2.1 → dit-2.3}/tests/algorithms/test_minimal_sufficient_statistic.py +0 -0
  332. {dit-2.1 → dit-2.3}/tests/algorithms/test_parallel_sweep.py +0 -0
  333. {dit-2.1 → dit-2.3}/tests/algorithms/test_prune_expand.py +0 -0
  334. {dit-2.1 → dit-2.3}/tests/algorithms/test_stats.py +0 -0
  335. {dit-2.1 → dit-2.3}/tests/channelorder/__init__.py +0 -0
  336. {dit-2.1 → dit-2.3}/tests/channelorder/test_deficiency.py +0 -0
  337. {dit-2.1 → dit-2.3}/tests/channelorder/test_orderings.py +0 -0
  338. {dit-2.1 → dit-2.3}/tests/channelorder/test_properties.py +0 -0
  339. {dit-2.1 → dit-2.3}/tests/channelorder/test_utils.py +0 -0
  340. {dit-2.1 → dit-2.3}/tests/coding/__init__.py +0 -0
  341. {dit-2.1 → dit-2.3}/tests/coding/test_base.py +0 -0
  342. {dit-2.1 → dit-2.3}/tests/coding/test_channel.py +0 -0
  343. {dit-2.1 → dit-2.3}/tests/coding/test_channel_codes.py +0 -0
  344. {dit-2.1 → dit-2.3}/tests/coding/test_edge_cases.py +0 -0
  345. {dit-2.1 → dit-2.3}/tests/coding/test_gf2.py +0 -0
  346. {dit-2.1 → dit-2.3}/tests/coding/test_golomb.py +0 -0
  347. {dit-2.1 → dit-2.3}/tests/coding/test_linear.py +0 -0
  348. {dit-2.1 → dit-2.3}/tests/coding/test_source_edges.py +0 -0
  349. {dit-2.1 → dit-2.3}/tests/coding/test_symbol_codes.py +0 -0
  350. {dit-2.1 → dit-2.3}/tests/coding/test_tunstall.py +0 -0
  351. {dit-2.1 → dit-2.3}/tests/coding/test_universal.py +0 -0
  352. {dit-2.1 → dit-2.3}/tests/conftest.py +0 -0
  353. {dit-2.1 → dit-2.3}/tests/divergences/__init__.py +0 -0
  354. {dit-2.1 → dit-2.3}/tests/divergences/test_copy_mutual_information.py +0 -0
  355. {dit-2.1 → dit-2.3}/tests/divergences/test_cross_entropy.py +0 -0
  356. {dit-2.1 → dit-2.3}/tests/divergences/test_generalized_divergences.py +0 -0
  357. {dit-2.1 → dit-2.3}/tests/divergences/test_hypercontractivity_coefficient.py +0 -0
  358. {dit-2.1 → dit-2.3}/tests/divergences/test_jensen_shannon_divergence.py +0 -0
  359. {dit-2.1 → dit-2.3}/tests/divergences/test_kullback_leibler_divergence.py +0 -0
  360. {dit-2.1 → dit-2.3}/tests/divergences/test_maximum_correlation.py +0 -0
  361. {dit-2.1 → dit-2.3}/tests/divergences/test_nonmerge.py +0 -0
  362. {dit-2.1 → dit-2.3}/tests/divergences/test_variational_distance.py +0 -0
  363. {dit-2.1 → dit-2.3}/tests/example_channels/__init__.py +0 -0
  364. {dit-2.1 → dit-2.3}/tests/example_channels/test_binary.py +0 -0
  365. {dit-2.1 → dit-2.3}/tests/example_channels/test_qary.py +0 -0
  366. {dit-2.1 → dit-2.3}/tests/example_channels/test_trivial.py +0 -0
  367. {dit-2.1 → dit-2.3}/tests/example_channels/test_util.py +0 -0
  368. {dit-2.1 → dit-2.3}/tests/example_dists/__init__.py +0 -0
  369. {dit-2.1 → dit-2.3}/tests/example_dists/test_circuits.py +0 -0
  370. {dit-2.1 → dit-2.3}/tests/example_dists/test_dependencies.py +0 -0
  371. {dit-2.1 → dit-2.3}/tests/example_dists/test_dice.py +0 -0
  372. {dit-2.1 → dit-2.3}/tests/example_dists/test_giant_bit.py +0 -0
  373. {dit-2.1 → dit-2.3}/tests/example_dists/test_mdbsi.py +0 -0
  374. {dit-2.1 → dit-2.3}/tests/example_dists/test_miscellaneous.py +0 -0
  375. {dit-2.1 → dit-2.3}/tests/example_dists/test_n_mod_m.py +0 -0
  376. {dit-2.1 → dit-2.3}/tests/example_dists/test_numeric.py +0 -0
  377. {dit-2.1 → dit-2.3}/tests/example_dists/test_pr_box.py +0 -0
  378. {dit-2.1 → dit-2.3}/tests/inference/__init__.py +0 -0
  379. {dit-2.1 → dit-2.3}/tests/inference/test_binning.py +0 -0
  380. {dit-2.1 → dit-2.3}/tests/inference/test_counts.py +0 -0
  381. {dit-2.1 → dit-2.3}/tests/inference/test_estimators.py +0 -0
  382. {dit-2.1 → dit-2.3}/tests/inference/test_knn_estimators.py +0 -0
  383. {dit-2.1 → dit-2.3}/tests/inference/test_segmentaxis.py +0 -0
  384. {dit-2.1 → dit-2.3}/tests/inference/test_timeseries.py +0 -0
  385. {dit-2.1 → dit-2.3}/tests/math/__init__.py +0 -0
  386. {dit-2.1 → dit-2.3}/tests/math/test_aitchison.py +0 -0
  387. {dit-2.1 → dit-2.3}/tests/math/test_combinatorics.py +0 -0
  388. {dit-2.1 → dit-2.3}/tests/math/test_equal.py +0 -0
  389. {dit-2.1 → dit-2.3}/tests/math/test_fraction.py +0 -0
  390. {dit-2.1 → dit-2.3}/tests/math/test_misc.py +0 -0
  391. {dit-2.1 → dit-2.3}/tests/math/test_ops.py +0 -0
  392. {dit-2.1 → dit-2.3}/tests/math/test_pmfops.py +0 -0
  393. {dit-2.1 → dit-2.3}/tests/math/test_sampling.py +0 -0
  394. {dit-2.1 → dit-2.3}/tests/math/test_sigmaalgebra.py +0 -0
  395. {dit-2.1 → dit-2.3}/tests/multivariate/__init__.py +0 -0
  396. {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/__init__.py +0 -0
  397. {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_backend_switching.py +0 -0
  398. {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_beta_common_information.py +0 -0
  399. {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_common_informations.py +0 -0
  400. {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_gk_common_information.py +0 -0
  401. {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_kamath_common_information.py +0 -0
  402. {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_maxent_function.py +0 -0
  403. {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_mss_common_information.py +0 -0
  404. {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_stochastic_gk_common_information.py +0 -0
  405. {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_wyner_common_information.py +0 -0
  406. {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/__init__.py +0 -0
  407. {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_interactive_intrinsic_mutual_information.py +0 -0
  408. {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_intrinsic_mutual_information.py +0 -0
  409. {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_lower_intrinsic_mutual_information.py +0 -0
  410. {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_minimal_intrinsic_mutual_information.py +0 -0
  411. {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_necessary_intrinsic_mutual_information.py +0 -0
  412. {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_reduced_intrinsic_mutual_information.py +0 -0
  413. {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_secrecy_capacity.py +0 -0
  414. {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_skars.py +0 -0
  415. {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_trivial_bounds.py +0 -0
  416. {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_two_part_intrinsic_mutual_information.py +0 -0
  417. {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_two_way_skar.py +0 -0
  418. {dit-2.1 → dit-2.3}/tests/multivariate/test_caekl_mutual_information.py +0 -0
  419. {dit-2.1 → dit-2.3}/tests/multivariate/test_cohesion.py +0 -0
  420. {dit-2.1 → dit-2.3}/tests/multivariate/test_coinformation.py +0 -0
  421. {dit-2.1 → dit-2.3}/tests/multivariate/test_deweese.py +0 -0
  422. {dit-2.1 → dit-2.3}/tests/multivariate/test_dual_total_correlation.py +0 -0
  423. {dit-2.1 → dit-2.3}/tests/multivariate/test_entropy.py +0 -0
  424. {dit-2.1 → dit-2.3}/tests/multivariate/test_interaction_information.py +0 -0
  425. {dit-2.1 → dit-2.3}/tests/multivariate/test_logarithmic_decomposition.py +0 -0
  426. {dit-2.1 → dit-2.3}/tests/multivariate/test_mutual_informations.py +0 -0
  427. {dit-2.1 → dit-2.3}/tests/multivariate/test_necessary_conditional_entropy.py +0 -0
  428. {dit-2.1 → dit-2.3}/tests/multivariate/test_o_information.py +0 -0
  429. {dit-2.1 → dit-2.3}/tests/multivariate/test_quax_synergy.py +0 -0
  430. {dit-2.1 → dit-2.3}/tests/multivariate/test_synergistic_disclosure.py +0 -0
  431. {dit-2.1 → dit-2.3}/tests/multivariate/test_total_correlation.py +0 -0
  432. {dit-2.1 → dit-2.3}/tests/multivariate/test_transmission.py +0 -0
  433. {dit-2.1 → dit-2.3}/tests/multivariate/test_tse_complexity.py +0 -0
  434. {dit-2.1 → dit-2.3}/tests/multivariate/test_union_information.py +0 -0
  435. {dit-2.1 → dit-2.3}/tests/other/__init__.py +0 -0
  436. {dit-2.1 → dit-2.3}/tests/other/test_cumulative_residual_entropy.py +0 -0
  437. {dit-2.1 → dit-2.3}/tests/other/test_disequilibrium.py +0 -0
  438. {dit-2.1 → dit-2.3}/tests/other/test_extropy.py +0 -0
  439. {dit-2.1 → dit-2.3}/tests/other/test_lautum_information.py +0 -0
  440. {dit-2.1 → dit-2.3}/tests/other/test_perplexity.py +0 -0
  441. {dit-2.1 → dit-2.3}/tests/other/test_renyi_entropy.py +0 -0
  442. {dit-2.1 → dit-2.3}/tests/other/test_sibson_mutual_information.py +0 -0
  443. {dit-2.1 → dit-2.3}/tests/other/test_tsallis_entropy.py +0 -0
  444. {dit-2.1 → dit-2.3}/tests/pid/__init__.py +0 -0
  445. {dit-2.1 → dit-2.3}/tests/pid/test_hcs.py +0 -0
  446. {dit-2.1 → dit-2.3}/tests/pid/test_hmos.py +0 -0
  447. {dit-2.1 → dit-2.3}/tests/pid/test_ibroja.py +0 -0
  448. {dit-2.1 → dit-2.3}/tests/pid/test_iccs.py +0 -0
  449. {dit-2.1 → dit-2.3}/tests/pid/test_ict.py +0 -0
  450. {dit-2.1 → dit-2.3}/tests/pid/test_ideg.py +0 -0
  451. {dit-2.1 → dit-2.3}/tests/pid/test_idelta.py +0 -0
  452. {dit-2.1 → dit-2.3}/tests/pid/test_idep.py +0 -0
  453. {dit-2.1 → dit-2.3}/tests/pid/test_ido.py +0 -0
  454. {dit-2.1 → dit-2.3}/tests/pid/test_igh.py +0 -0
  455. {dit-2.1 → dit-2.3}/tests/pid/test_iig.py +0 -0
  456. {dit-2.1 → dit-2.3}/tests/pid/test_iipid.py +0 -0
  457. {dit-2.1 → dit-2.3}/tests/pid/test_imc.py +0 -0
  458. {dit-2.1 → dit-2.3}/tests/pid/test_imes.py +0 -0
  459. {dit-2.1 → dit-2.3}/tests/pid/test_imin.py +0 -0
  460. {dit-2.1 → dit-2.3}/tests/pid/test_immi.py +0 -0
  461. {dit-2.1 → dit-2.3}/tests/pid/test_ipm.py +0 -0
  462. {dit-2.1 → dit-2.3}/tests/pid/test_iprec.py +0 -0
  463. {dit-2.1 → dit-2.3}/tests/pid/test_iproj.py +0 -0
  464. {dit-2.1 → dit-2.3}/tests/pid/test_irav.py +0 -0
  465. {dit-2.1 → dit-2.3}/tests/pid/test_irdr.py +0 -0
  466. {dit-2.1 → dit-2.3}/tests/pid/test_irr.py +0 -0
  467. {dit-2.1 → dit-2.3}/tests/pid/test_iskar.py +0 -0
  468. {dit-2.1 → dit-2.3}/tests/pid/test_isx.py +0 -0
  469. {dit-2.1 → dit-2.3}/tests/pid/test_iwedge.py +0 -0
  470. {dit-2.1 → dit-2.3}/tests/pid/test_modified_syndisc.py +0 -0
  471. {dit-2.1 → dit-2.3}/tests/pid/test_pid_distribution.py +0 -0
  472. {dit-2.1 → dit-2.3}/tests/pid/test_syndisc_fast.py +0 -0
  473. {dit-2.1 → dit-2.3}/tests/pid/test_syndisc_lattice.py +0 -0
  474. {dit-2.1 → dit-2.3}/tests/profiles/__init__.py +0 -0
  475. {dit-2.1 → dit-2.3}/tests/profiles/test_base_profile.py +0 -0
  476. {dit-2.1 → dit-2.3}/tests/profiles/test_complexity_profile.py +0 -0
  477. {dit-2.1 → dit-2.3}/tests/profiles/test_entropy_triangle.py +0 -0
  478. {dit-2.1 → dit-2.3}/tests/profiles/test_information_partitions.py +0 -0
  479. {dit-2.1 → dit-2.3}/tests/profiles/test_mui.py +0 -0
  480. {dit-2.1 → dit-2.3}/tests/profiles/test_schneidman.py +0 -0
  481. {dit-2.1 → dit-2.3}/tests/profiles/test_shapley_info_decomposition.py +0 -0
  482. {dit-2.1 → dit-2.3}/tests/rate_distortion/__init__.py +0 -0
  483. {dit-2.1 → dit-2.3}/tests/rate_distortion/test_gray_wyner.py +0 -0
  484. {dit-2.1 → dit-2.3}/tests/rate_distortion/test_rd.py +0 -0
  485. {dit-2.1 → dit-2.3}/tests/shannon/__init__.py +0 -0
  486. {dit-2.1 → dit-2.3}/tests/shannon/test_shannon.py +0 -0
  487. {dit-2.1 → dit-2.3}/tests/test_abstractdist.py +0 -0
  488. {dit-2.1 → dit-2.3}/tests/test_bgm.py +0 -0
  489. {dit-2.1 → dit-2.3}/tests/test_cdisthelpers.py +0 -0
  490. {dit-2.1 → dit-2.3}/tests/test_distconst.py +0 -0
  491. {dit-2.1 → dit-2.3}/tests/test_distribution_coverage.py +0 -0
  492. {dit-2.1 → dit-2.3}/tests/test_exceptions.py +0 -0
  493. {dit-2.1 → dit-2.3}/tests/test_helpers.py +0 -0
  494. {dit-2.1 → dit-2.3}/tests/test_params.py +0 -0
  495. {dit-2.1 → dit-2.3}/tests/test_samplespace.py +0 -0
  496. {dit-2.1 → dit-2.3}/tests/test_validate.py +0 -0
  497. {dit-2.1 → dit-2.3}/tests/utils/__init__.py +0 -0
  498. {dit-2.1 → dit-2.3}/tests/utils/test_bindargs.py +0 -0
  499. {dit-2.1 → dit-2.3}/tests/utils/test_bindargs3.py +0 -0
  500. {dit-2.1 → dit-2.3}/tests/utils/test_context.py +0 -0
  501. {dit-2.1 → dit-2.3}/tests/utils/test_latexarray.py +0 -0
  502. {dit-2.1 → dit-2.3}/tests/utils/test_misc.py +0 -0
  503. {dit-2.1 → dit-2.3}/tests/utils/test_optimization.py +0 -0
  504. {dit-2.1 → dit-2.3}/tests/utils/test_table.py +0 -0
  505. {dit-2.1 → dit-2.3}/tests/utils/test_testing.py +0 -0
  506. {dit-2.1 → dit-2.3}/tests/utils/test_units.py +0 -0
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.4
1
+ Metadata-Version: 2.5
2
2
  Name: dit
3
- Version: 2.1
3
+ Version: 2.3
4
4
  Summary: Python package for information theory on discrete random variables.
5
5
  Project-URL: Homepage, http://dit.io
6
6
  Project-URL: Repository, https://github.com/dit/dit
@@ -10,8 +10,6 @@ License-Expression: BSD-3-Clause
10
10
  License-File: LICENSE.txt
11
11
  Classifier: Intended Audience :: Science/Research
12
12
  Classifier: License :: OSI Approved :: BSD License
13
- Classifier: Programming Language :: Python :: 3.9
14
- Classifier: Programming Language :: Python :: 3.10
15
13
  Classifier: Programming Language :: Python :: 3.11
16
14
  Classifier: Programming Language :: Python :: 3.12
17
15
  Classifier: Programming Language :: Python :: 3.13
@@ -22,7 +20,7 @@ Classifier: Topic :: Scientific/Engineering :: Physics
22
20
  Requires-Python: >=3.11
23
21
  Requires-Dist: boltons
24
22
  Requires-Dist: debtcollector
25
- Requires-Dist: lattices>=0.5.0
23
+ Requires-Dist: lattices>=0.5
26
24
  Requires-Dist: loguru
27
25
  Requires-Dist: networkx>=2.6
28
26
  Requires-Dist: numpy>=1.22
@@ -59,6 +57,7 @@ Requires-Dist: slsqp-jax; extra == 'dev'
59
57
  Requires-Dist: sphinx; extra == 'dev'
60
58
  Requires-Dist: sphinx-rtd-theme; extra == 'dev'
61
59
  Requires-Dist: sphinxcontrib-bibtex; extra == 'dev'
60
+ Requires-Dist: sympy; extra == 'dev'
62
61
  Requires-Dist: torch; extra == 'dev'
63
62
  Requires-Dist: ty; extra == 'dev'
64
63
  Provides-Extra: docs
@@ -70,17 +69,19 @@ Requires-Dist: nbconvert; extra == 'docs'
70
69
  Requires-Dist: numdifftools; extra == 'docs'
71
70
  Requires-Dist: pint; extra == 'docs'
72
71
  Requires-Dist: pycddlib-standalone; extra == 'docs'
73
- Requires-Dist: pypoman; extra == 'docs'
74
72
  Requires-Dist: python-ternary; extra == 'docs'
75
73
  Requires-Dist: scikit-learn; extra == 'docs'
76
74
  Requires-Dist: sphinx; extra == 'docs'
77
75
  Requires-Dist: sphinx-rtd-theme; extra == 'docs'
78
76
  Requires-Dist: sphinxcontrib-bibtex; extra == 'docs'
77
+ Requires-Dist: sympy; extra == 'docs'
79
78
  Provides-Extra: jax
80
79
  Requires-Dist: jax; extra == 'jax'
81
80
  Requires-Dist: jaxlib; extra == 'jax'
82
81
  Requires-Dist: optimistix; extra == 'jax'
83
82
  Requires-Dist: slsqp-jax; extra == 'jax'
83
+ Provides-Extra: music
84
+ Requires-Dist: music21; extra == 'music'
84
85
  Provides-Extra: optional
85
86
  Requires-Dist: colorama; extra == 'optional'
86
87
  Requires-Dist: matplotlib; extra == 'optional'
@@ -91,6 +92,8 @@ Requires-Dist: pypoman; extra == 'optional'
91
92
  Requires-Dist: scikit-learn; extra == 'optional'
92
93
  Provides-Extra: pytensor
93
94
  Requires-Dist: pytensor; extra == 'pytensor'
95
+ Provides-Extra: symbolic
96
+ Requires-Dist: sympy; extra == 'symbolic'
94
97
  Provides-Extra: test
95
98
  Requires-Dist: hypothesis>=6.0; extra == 'test'
96
99
  Requires-Dist: hypothesis[numpy]; extra == 'test'
@@ -464,7 +467,7 @@ If you'd like to get in contact about anything, you can reach us through our `sl
464
467
  :target: https://github.com/dit/dit/actions/workflows/build.yml
465
468
  :alt: Continuous Integration Status
466
469
 
467
- .. |codecov| image:: https://codecov.io/gh/dit/dit/branch/master/graph/badge.svg
470
+ .. |codecov| image:: https://codecov.io/gh/dit/dit/branch/main/graph/badge.svg
468
471
  :target: https://codecov.io/gh/dit/dit
469
472
  :alt: Test Coverage Status
470
473
 
@@ -359,7 +359,7 @@ If you'd like to get in contact about anything, you can reach us through our `sl
359
359
  :target: https://github.com/dit/dit/actions/workflows/build.yml
360
360
  :alt: Continuous Integration Status
361
361
 
362
- .. |codecov| image:: https://codecov.io/gh/dit/dit/branch/master/graph/badge.svg
362
+ .. |codecov| image:: https://codecov.io/gh/dit/dit/branch/main/graph/badge.svg
363
363
  :target: https://codecov.io/gh/dit/dit
364
364
  :alt: Test Coverage Status
365
365
 
@@ -10,7 +10,13 @@ Python package for sigma-algebras defined on finite sets.
10
10
 
11
11
  """
12
12
 
13
- __version__ = "1.5"
13
+ from importlib.metadata import PackageNotFoundError
14
+ from importlib.metadata import version as _pkg_version
15
+
16
+ try:
17
+ __version__ = _pkg_version("dit")
18
+ except PackageNotFoundError: # pragma: no cover
19
+ __version__ = "0.0.0"
14
20
 
15
21
  from loguru import logger as _logger
16
22
 
@@ -37,3 +43,5 @@ import dit.other # noqa: E402
37
43
  import dit.pid # noqa: E402
38
44
  import dit.profiles # noqa: E402
39
45
  import dit.shannon # noqa: E402
46
+ import dit.symbolic # noqa: E402
47
+ import dit.visualization # noqa: E402
@@ -12,6 +12,17 @@ from .maxentropyfw import *
12
12
  from .minimal_sufficient_statistic import *
13
13
  from .optimization import *
14
14
  from .distribution_optimizers import *
15
+ from .mixture_of_products import fit_mixture_of_products, mixture_of_products_dists
16
+ from .marginal_lifts import fit_marginal_lift_mixture, lift_marginal, marginal_lift_dists
17
+ from .mprojection import (
18
+ m_projection,
19
+ m_projection_eps_limit,
20
+ m_projection_from_subsets,
21
+ mflat_design_matrix,
22
+ mflat_mprojection_dists,
23
+ mflat_subsets_from_dependency,
24
+ symmetric_smooth,
25
+ )
15
26
  from .prune_expand import expanded_samplespace, pruned_samplespace
16
27
  from .stats import (
17
28
  cdf,
@@ -34,6 +45,11 @@ from .stats import (
34
45
  standard_moment,
35
46
  variance,
36
47
  )
48
+ from .support_spectrum import (
49
+ spectral_entanglement_bound,
50
+ support_biadjacency,
51
+ support_singular_values,
52
+ )
37
53
 
38
54
  # Don't expose anything yet.
39
55
  # from . import pid_broja
@@ -0,0 +1,215 @@
1
+ """
2
+ CAEKL via PSP on marginalized PMF arrays (optimization backends).
3
+ """
4
+
5
+ from __future__ import annotations
6
+
7
+ from collections.abc import Callable, Iterable
8
+ from functools import cache
9
+
10
+ import numpy as np
11
+
12
+ EntropyFn = Callable[..., float]
13
+
14
+
15
+ def _group_rvs_from_sets(rvs: Iterable[int]) -> list[frozenset[int]]:
16
+ return [frozenset({rv}) for rv in sorted(rvs)]
17
+
18
+
19
+ def _cluster_to_rv_part(
20
+ partition: tuple[frozenset[int], ...],
21
+ group_rvs: list[frozenset[int]],
22
+ ) -> tuple[frozenset[int], ...]:
23
+ blocks: list[frozenset[int]] = []
24
+ for cluster in partition:
25
+ block: set[int] = set()
26
+ for group_idx in cluster:
27
+ block |= set(group_rvs[group_idx])
28
+ blocks.append(frozenset(block))
29
+ return tuple(blocks)
30
+
31
+
32
+ def caekl_mutual_information_psp_pmf(
33
+ pmf,
34
+ *,
35
+ all_vars: set[int],
36
+ rvs: set[int],
37
+ crvs: set[int],
38
+ h: EntropyFn,
39
+ sum_axes,
40
+ ) -> float:
41
+ """
42
+ CAEKL of ``rvs`` given ``crvs`` for a joint ``pmf`` using PSP.
43
+
44
+ Parameters
45
+ ----------
46
+ pmf : array
47
+ Full joint PMF including auxiliary variables.
48
+ all_vars : set[int]
49
+ All variable indices in ``pmf``.
50
+ rvs : set[int]
51
+ Target random-variable indices (one group per index).
52
+ crvs : set[int]
53
+ Conditioning variable indices.
54
+ h : callable
55
+ Shannon entropy ``h(marginal_pmf)``.
56
+ sum_axes : callable
57
+ ``sum_axes(pmf, axes)`` marginalizes ``pmf`` over ``axes``.
58
+ """
59
+ value, _ = caekl_mutual_information_psp_pmf_with_partition(
60
+ pmf,
61
+ all_vars=all_vars,
62
+ rvs=rvs,
63
+ crvs=crvs,
64
+ h=h,
65
+ sum_axes=sum_axes,
66
+ )
67
+ return value
68
+
69
+
70
+ def caekl_mutual_information_psp_pmf_with_partition(
71
+ pmf,
72
+ *,
73
+ all_vars: set[int],
74
+ rvs: set[int],
75
+ crvs: set[int],
76
+ h: EntropyFn,
77
+ sum_axes,
78
+ ) -> tuple[float, tuple[frozenset[int], ...]]:
79
+ """
80
+ CAEKL via PSP on a PMF, returning an optimal partition over ``rvs``.
81
+
82
+ The partition is expressed as a tuple of frozensets of elements of ``rvs``.
83
+ """
84
+ group_rvs = _group_rvs_from_sets(rvs)
85
+ n_groups = len(group_rvs)
86
+ idx_crvs = tuple(all_vars - crvs)
87
+ pmf_crvs = sum_axes(pmf, idx_crvs)
88
+
89
+ def conditional_h(vars_set: set[int]) -> float:
90
+ idx = tuple(all_vars - (vars_set | crvs))
91
+ pmf_joint = sum_axes(pmf, idx)
92
+ return h(pmf_joint) - h(pmf_crvs)
93
+
94
+ @cache
95
+ def h_groups(group_indices: frozenset[int]) -> float:
96
+ if not group_indices:
97
+ return 0.0
98
+ vars_set: set[int] = set()
99
+ for group_idx in group_indices:
100
+ vars_set |= set(group_rvs[group_idx])
101
+ return conditional_h(vars_set)
102
+
103
+ from ..multivariate.mmi_psp import caekl_mutual_information_psp_with_partition
104
+
105
+ value, partition = caekl_mutual_information_psp_with_partition(h_groups, n_groups)
106
+ return value, _cluster_to_rv_part(partition, group_rvs)
107
+
108
+
109
+ def caekl_mutual_information_psp_pmf_grad_data(
110
+ pmf,
111
+ *,
112
+ all_vars: set[int],
113
+ rvs: set[int],
114
+ crvs: set[int],
115
+ h: EntropyFn,
116
+ sum_axes,
117
+ ) -> tuple[float, tuple[frozenset[int], ...], tuple[int, ...], tuple[int, ...], dict[frozenset[int], tuple[int, ...]]]:
118
+ """
119
+ CAEKL value, optimal partition, and marginalization indices for gradients.
120
+
121
+ Returns
122
+ -------
123
+ value : float
124
+ partition : tuple of frozenset[int]
125
+ Optimal partition blocks (subsets of ``rvs``).
126
+ idx_joint : tuple[int, ...]
127
+ idx_crvs : tuple[int, ...]
128
+ idx_parts : dict
129
+ Maps each block in ``partition`` to axes to sum for its marginal PMF.
130
+ """
131
+ value, partition = caekl_mutual_information_psp_pmf_with_partition(
132
+ pmf,
133
+ all_vars=all_vars,
134
+ rvs=rvs,
135
+ crvs=crvs,
136
+ h=h,
137
+ sum_axes=sum_axes,
138
+ )
139
+ idx_joint = tuple(all_vars - (rvs | crvs))
140
+ idx_crvs = tuple(all_vars - crvs)
141
+ idx_parts = {block: tuple(all_vars - (set(block) | crvs)) for block in partition}
142
+ return value, partition, idx_joint, idx_crvs, idx_parts
143
+
144
+
145
+ def labels_from_partition(
146
+ partition: tuple[frozenset[int], ...],
147
+ rvs_sorted: tuple[int, ...],
148
+ ) -> np.ndarray:
149
+ """Encode a CAEKL partition as per-RV block labels (for JAX host callbacks)."""
150
+ labels = np.zeros(len(rvs_sorted), dtype=np.int32)
151
+ rv_index = {rv: i for i, rv in enumerate(rvs_sorted)}
152
+ for block_id, block in enumerate(partition):
153
+ for rv in block:
154
+ labels[rv_index[rv]] = block_id
155
+ return labels
156
+
157
+
158
+ def partition_from_labels(
159
+ labels: np.ndarray,
160
+ rvs_sorted: tuple[int, ...],
161
+ ) -> tuple[frozenset[int], ...]:
162
+ """Decode block labels into a CAEKL partition over ``rvs_sorted``."""
163
+ labels = np.asarray(labels, dtype=np.int32)
164
+ blocks: dict[int, set[int]] = {}
165
+ for i, lab in enumerate(labels):
166
+ blocks.setdefault(int(lab), set()).add(rvs_sorted[i])
167
+ return tuple(frozenset(blocks[k]) for k in sorted(blocks))
168
+
169
+
170
+ def caekl_partition_indices(
171
+ pmf,
172
+ *,
173
+ all_vars: set[int],
174
+ rvs: set[int],
175
+ crvs: set[int],
176
+ h: EntropyFn,
177
+ sum_axes,
178
+ ) -> tuple[tuple[frozenset[int], ...], tuple[int, ...], tuple[int, ...], dict[frozenset[int], tuple[int, ...]]]:
179
+ """
180
+ PSP optimal partition and marginalization indices for autodiff backends.
181
+
182
+ Returns ``(partition, idx_joint, idx_crvs, idx_parts)``.
183
+ """
184
+ _, partition = caekl_mutual_information_psp_pmf_with_partition(
185
+ pmf,
186
+ all_vars=all_vars,
187
+ rvs=rvs,
188
+ crvs=crvs,
189
+ h=h,
190
+ sum_axes=sum_axes,
191
+ )
192
+ idx_joint = tuple(all_vars - (rvs | crvs))
193
+ idx_crvs = tuple(all_vars - crvs)
194
+ idx_parts = {block: tuple(all_vars - (set(block) | crvs)) for block in partition}
195
+ return partition, idx_joint, idx_crvs, idx_parts
196
+
197
+
198
+ def caekl_from_partition_pmf(
199
+ pmf,
200
+ partition: tuple[frozenset[int], ...],
201
+ *,
202
+ idx_joint: tuple[int, ...],
203
+ idx_crvs: tuple[int, ...],
204
+ idx_parts: dict[frozenset[int], tuple[int, ...]],
205
+ h: EntropyFn,
206
+ sum_axes,
207
+ ) -> float:
208
+ """Partition information ``I_P`` for a fixed partition (used after PSP selects ``P``)."""
209
+ norm = len(partition) - 1
210
+ pmf_joint = sum_axes(pmf, idx_joint)
211
+ pmf_crvs = sum_axes(pmf, idx_crvs)
212
+ h_crvs = h(pmf_crvs)
213
+ h_joint = h(pmf_joint) - h_crvs
214
+ h_parts = sum(h(sum_axes(pmf, idx_parts[block])) - h_crvs for block in partition)
215
+ return (h_parts - h_joint) / norm
@@ -532,6 +532,87 @@ class MinDualTotalCorrelationOptimizer(BaseDistOptimizer, BaseNonConvexOptimizer
532
532
  return objective
533
533
 
534
534
 
535
+ class MinResidualEntropyOptimizer(BaseDistOptimizer, BaseNonConvexOptimizer):
536
+ """
537
+ Compute minimum residual entropy distributions.
538
+ """
539
+
540
+ def _objective_gradient(self):
541
+ """Gradient of the ``+R`` objective w.r.t. the pmf."""
542
+ return self._residual_entropy_grad(self._rvs)
543
+
544
+ def _objective(self):
545
+ """
546
+ Compute the residual entropy.
547
+
548
+ Returns
549
+ -------
550
+ objective : func
551
+ The objective function.
552
+ """
553
+ residual_entropy = self._residual_entropy(self._rvs)
554
+
555
+ def objective(self, x):
556
+ """
557
+ Compute :math:`R[rvs]`
558
+
559
+ Parameters
560
+ ----------
561
+ x : np.ndarray
562
+ An optimization vector.
563
+
564
+ Returns
565
+ -------
566
+ obj : float
567
+ The value of the objective.
568
+ """
569
+ pmf = self.construct_joint(x)
570
+ return residual_entropy(pmf)
571
+
572
+ return objective
573
+
574
+
575
+ class MaxCAEKLMutualInformationOptimizer(BaseDistOptimizer, BaseNonConvexOptimizer):
576
+ """
577
+ Compute maximum CAEKL mutual information distributions.
578
+ """
579
+
580
+ def _objective_gradient(self):
581
+ """Gradient of the ``-J`` objective w.r.t. the pmf."""
582
+ caekl_grad = self._caekl_mutual_information_grad(self._rvs)
583
+ return lambda pmf: -caekl_grad(pmf)
584
+
585
+ def _objective(self):
586
+ """
587
+ Compute the negative CAEKL mutual information.
588
+
589
+ Returns
590
+ -------
591
+ objective : func
592
+ The objective function.
593
+ """
594
+ caekl_mutual_information = self._caekl_mutual_information(self._rvs)
595
+
596
+ def objective(self, x):
597
+ """
598
+ Compute :math:`-J[rvs]`
599
+
600
+ Parameters
601
+ ----------
602
+ x : np.ndarray
603
+ An optimization vector.
604
+
605
+ Returns
606
+ -------
607
+ obj : float
608
+ The value of the objective.
609
+ """
610
+ pmf = self.construct_joint(x)
611
+ return -caekl_mutual_information(pmf)
612
+
613
+ return objective
614
+
615
+
535
616
  class BROJABivariateOptimizer(MaxCoInfoOptimizer):
536
617
  """
537
618
  An optimizer for constructing the maximum co-information distribution
@@ -0,0 +1,182 @@
1
+ """
2
+ Convex combinations of lifts of a joint's own marginals.
3
+
4
+ At order :math:`k`, form building blocks
5
+
6
+ .. math::
7
+
8
+ \\bigl\\{ U \\bigr\\} \\cup
9
+ \\bigl\\{ \\mathrm{Lift}(P_S) : 1 \\le |S| \\le k \\bigr\\}
10
+
11
+ and fit nonnegative weights summing to one by least squares:
12
+
13
+ .. math::
14
+
15
+ Q^{(k)} = \\arg\\min_{\\alpha \\ge 0,\\ \\sum \\alpha = 1}
16
+ \\bigl\\| P - \\textstyle\\sum_S \\alpha_S \\mathrm{Lift}(P_S) \\bigr\\|_2^2.
17
+
18
+ Lifts:
19
+
20
+ * ``uniform`` — :math:`P_S \\otimes U_{X \\setminus S}`
21
+ * ``product`` — :math:`P_S \\otimes \\prod_{i \\notin S} P_i`
22
+ """
23
+
24
+ from collections import defaultdict
25
+ from copy import deepcopy
26
+ from itertools import combinations, product
27
+
28
+ import numpy as np
29
+ from scipy.optimize import minimize
30
+
31
+ from ..algorithms.optutil import prepare_dist
32
+ from ..distribution import Distribution
33
+ from ..exceptions import ditException
34
+
35
+ __all__ = (
36
+ "lift_marginal",
37
+ "fit_marginal_lift_mixture",
38
+ "marginal_lift_dists",
39
+ )
40
+
41
+
42
+ def _cartesian(dist):
43
+ d = prepare_dist(deepcopy(dist))
44
+ n = d.outcome_length()
45
+ alph = [tuple(sorted({o[i] for o in d.outcomes})) for i in range(n)]
46
+ outs = list(product(*alph))
47
+ pmf_map = {tuple(o): float(p) for o, p in zip(d.outcomes, d.pmf, strict=True)}
48
+ pmf = np.array([pmf_map.get(o, 0.0) for o in outs], dtype=float)
49
+ pmf /= pmf.sum()
50
+ return outs, pmf, alph, d
51
+
52
+
53
+ def lift_marginal(outs, pmf, alph, S, mode="uniform"):
54
+ """
55
+ Lift a marginal on coordinates ``S`` to a full joint pmf.
56
+
57
+ Parameters
58
+ ----------
59
+ outs, pmf, alph
60
+ Dense Cartesian table for the joint.
61
+ S : tuple of int
62
+ Variable indices of the marginal.
63
+ mode : {'uniform', 'product'}
64
+ How to extend off ``S``.
65
+ """
66
+ n = len(alph)
67
+ S = tuple(S)
68
+ marg = defaultdict(float)
69
+ for o, p in zip(outs, pmf, strict=True):
70
+ marg[tuple(o[i] for i in S)] += p
71
+ rest = [i for i in range(n) if i not in S]
72
+ if mode == "uniform":
73
+ rest_size = int(np.prod([len(alph[i]) for i in rest])) if rest else 1
74
+ return np.array([marg[tuple(o[i] for i in S)] / rest_size for o in outs], dtype=float)
75
+ if mode != "product":
76
+ msg = f"unknown lift mode {mode!r}"
77
+ raise ditException(msg)
78
+ ones = []
79
+ for i in range(n):
80
+ m1 = defaultdict(float)
81
+ for o, p in zip(outs, pmf, strict=True):
82
+ m1[o[i]] += p
83
+ ones.append(m1)
84
+ q = np.empty(len(outs), dtype=float)
85
+ for t, o in enumerate(outs):
86
+ val = marg[tuple(o[i] for i in S)]
87
+ for i in rest:
88
+ val *= ones[i][o[i]]
89
+ q[t] = val
90
+ return q / q.sum()
91
+
92
+
93
+ def fit_marginal_lift_mixture(dist, order, mode="uniform", n_init=12, seed=0):
94
+ """
95
+ Fit a convex combination of lifts of marginals of order at most ``order``.
96
+
97
+ Returns
98
+ -------
99
+ result : dict
100
+ Keys ``dist``, ``labels``, ``alpha``, ``L2``.
101
+ """
102
+ if order < 0:
103
+ msg = "order must be nonnegative"
104
+ raise ditException(msg)
105
+ outs, pmf, alph, template = _cartesian(dist)
106
+ n = len(alph)
107
+ order = min(order, n)
108
+
109
+ blocks, labels = [], []
110
+ blocks.append(np.ones(len(outs)) / len(outs))
111
+ labels.append(())
112
+ for k in range(1, order + 1):
113
+ for S in combinations(range(n), k):
114
+ blocks.append(lift_marginal(outs, pmf, alph, S, mode=mode))
115
+ labels.append(S)
116
+ A = np.column_stack(blocks)
117
+ nb = A.shape[1]
118
+
119
+ def loss(x):
120
+ return float(np.sum((A @ x - pmf) ** 2))
121
+
122
+ cons = {"type": "eq", "fun": lambda x: float(x.sum() - 1.0)}
123
+ best = None
124
+ rng = np.random.default_rng(seed)
125
+ for _ in range(n_init):
126
+ x0 = rng.dirichlet(np.ones(nb))
127
+ res = minimize(
128
+ loss,
129
+ x0,
130
+ bounds=[(0.0, None)] * nb,
131
+ constraints=cons,
132
+ method="SLSQP",
133
+ options={"maxiter": 2000, "ftol": 1e-14, "disp": False},
134
+ )
135
+ if best is None or res.fun < best[0]:
136
+ best = (res.fun, res.x)
137
+
138
+ alpha = np.maximum(best[1], 0.0)
139
+ alpha = alpha / alpha.sum()
140
+ q = A @ alpha
141
+ q = np.maximum(q, 0.0)
142
+ q = q / q.sum()
143
+ qd = Distribution(outs, q, base="linear", validate=False)
144
+ qd.normalize()
145
+ if template.get_rv_names() is not None:
146
+ qd.set_rv_names(template.get_rv_names())
147
+ return {
148
+ "dist": qd,
149
+ "labels": labels,
150
+ "alpha": alpha,
151
+ "L2": float(np.sqrt(best[0])),
152
+ }
153
+
154
+
155
+ def marginal_lift_dists(dist, k_max=None, mode="uniform", n_init=12, seed=0):
156
+ """
157
+ Ladder of marginal-lift mixtures for orders :math:`0,\\ldots,k_{\\max}`.
158
+
159
+ Order 0 is the uniform distribution. Order :math:`n` includes the full
160
+ joint as a block and recovers :math:`P` exactly.
161
+ """
162
+ n = dist.outcome_length()
163
+ if k_max is None:
164
+ k_max = n
165
+ k_max = min(int(k_max), n)
166
+
167
+ dists = []
168
+ metas = []
169
+ for k in range(0, k_max + 1):
170
+ if k == 0:
171
+ outs, _, _, template = _cartesian(dist)
172
+ q = Distribution(outs, np.ones(len(outs)) / len(outs), base="linear", validate=False)
173
+ q.normalize()
174
+ if template.get_rv_names() is not None:
175
+ q.set_rv_names(template.get_rv_names())
176
+ dists.append(q)
177
+ metas.append({"labels": [()], "alpha": np.array([1.0]), "L2": None})
178
+ else:
179
+ fit = fit_marginal_lift_mixture(dist, k, mode=mode, n_init=n_init, seed=seed + k)
180
+ dists.append(fit["dist"])
181
+ metas.append({key: fit[key] for key in ("labels", "alpha", "L2")})
182
+ return dists, metas