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.
- {dit-2.1 → dit-2.3}/PKG-INFO +10 -7
- {dit-2.1 → dit-2.3}/README.rst +1 -1
- {dit-2.1 → dit-2.3}/dit/__init__.py +9 -1
- {dit-2.1 → dit-2.3}/dit/algorithms/__init__.py +16 -0
- dit-2.3/dit/algorithms/caekl_psp.py +215 -0
- {dit-2.1 → dit-2.3}/dit/algorithms/distribution_optimizers.py +81 -0
- dit-2.3/dit/algorithms/marginal_lifts.py +182 -0
- dit-2.3/dit/algorithms/mixture_of_products.py +255 -0
- dit-2.3/dit/algorithms/mprojection.py +606 -0
- {dit-2.1 → dit-2.3}/dit/algorithms/optimization.py +102 -48
- {dit-2.1 → dit-2.3}/dit/algorithms/optimization_jax.py +95 -38
- {dit-2.1 → dit-2.3}/dit/algorithms/optimization_pytensor.py +32 -1
- {dit-2.1 → dit-2.3}/dit/algorithms/optimization_torch.py +30 -36
- dit-2.3/dit/algorithms/submodular.py +165 -0
- dit-2.3/dit/algorithms/support_spectrum.py +165 -0
- {dit-2.1 → dit-2.3}/dit/coding/__init__.py +12 -0
- {dit-2.1 → dit-2.3}/dit/coding/_util.py +26 -0
- {dit-2.1 → dit-2.3}/dit/coding/polar.py +1 -10
- dit-2.3/dit/coding/source_polar.py +508 -0
- {dit-2.1 → dit-2.3}/dit/distribution.py +231 -31
- {dit-2.1 → dit-2.3}/dit/divergences/__init__.py +9 -4
- dit-2.3/dit/divergences/coupling_metrics.py +274 -0
- {dit-2.1 → dit-2.3}/dit/divergences/cross_entropy.py +20 -0
- dit-2.3/dit/divergences/earth_movers_distance.py +233 -0
- {dit-2.1 → dit-2.3}/dit/divergences/hypercontractivity_coefficient.py +12 -4
- {dit-2.1 → dit-2.3}/dit/example_dists/__init__.py +1 -0
- dit-2.3/dit/example_dists/empirical/__init__.py +16 -0
- dit-2.3/dit/example_dists/empirical/_music.py +127 -0
- dit-2.3/dit/example_dists/empirical/bach.py +77 -0
- dit-2.3/dit/example_dists/empirical/blood_types.py +203 -0
- dit-2.3/dit/example_dists/empirical/car.py +95 -0
- dit-2.3/dit/example_dists/empirical/congress.py +109 -0
- dit-2.3/dit/example_dists/empirical/corelli.py +132 -0
- dit-2.3/dit/example_dists/empirical/penguins.py +77 -0
- dit-2.3/dit/example_dists/empirical/student.py +94 -0
- dit-2.3/dit/example_dists/empirical/titanic.py +85 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/__init__.py +3 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/caekl_mutual_information.py +19 -8
- {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/__init__.py +1 -0
- dit-2.3/dit/multivariate/common_informations/_functional_partition.py +223 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/base_markov_optimizer.py +12 -1
- {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/exact_common_information.py +7 -3
- dit-2.3/dit/multivariate/common_informations/functional_common_information.py +572 -0
- dit-2.3/dit/multivariate/common_informations/symbolic_ansatz.py +103 -0
- dit-2.3/dit/multivariate/common_informations/symbolic_markov.py +196 -0
- dit-2.3/dit/multivariate/common_informations/symbolic_solve.py +301 -0
- dit-2.3/dit/multivariate/common_informations/tension_common_information.py +234 -0
- dit-2.3/dit/multivariate/cross_mutual_information.py +205 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/interaction_information.py +1 -1
- dit-2.3/dit/multivariate/kirkwood.py +246 -0
- dit-2.3/dit/multivariate/mmi_psp.py +247 -0
- dit-2.3/dit/multivariate/s_information.py +48 -0
- {dit-2.1 → dit-2.3}/dit/other/__init__.py +1 -0
- {dit-2.1 → dit-2.3}/dit/other/extropy.py +10 -0
- dit-2.3/dit/other/negentropy.py +54 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/__init__.py +4 -1
- {dit-2.1 → dit-2.3}/dit/pid/measures/imin.py +19 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/immi.py +6 -1
- {dit-2.1 → dit-2.3}/dit/pid/pid.py +19 -2
- {dit-2.1 → dit-2.3}/dit/profiles/__init__.py +3 -0
- dit-2.3/dit/profiles/binding_mixture.py +138 -0
- {dit-2.1 → dit-2.3}/dit/profiles/information_partitions.py +176 -0
- dit-2.3/dit/profiles/marginal_lift.py +91 -0
- dit-2.3/dit/profiles/mflat.py +127 -0
- {dit-2.1 → dit-2.3}/dit/profiles/schneidman.py +10 -3
- dit-2.3/dit/rate_distortion/__init__.py +13 -0
- dit-2.3/dit/rate_distortion/bottleneck_algorithms.py +501 -0
- {dit-2.1 → dit-2.3}/dit/rate_distortion/curves.py +101 -8
- dit-2.3/dit/rate_distortion/gray_wyner/__init__.py +63 -0
- {dit-2.1 → dit-2.3}/dit/rate_distortion/gray_wyner/network.py +208 -1
- {dit-2.1 → dit-2.3}/dit/rate_distortion/gray_wyner/optimizer.py +189 -7
- dit-2.3/dit/rate_distortion/gray_wyner/plotting.py +166 -0
- dit-2.3/dit/rate_distortion/gray_wyner/region.py +472 -0
- dit-2.3/dit/rate_distortion/gray_wyner/shape.py +310 -0
- {dit-2.1 → dit-2.3}/dit/rate_distortion/information_bottleneck.py +53 -0
- {dit-2.1 → dit-2.3}/dit/shannon/shannon.py +19 -0
- dit-2.3/dit/symbolic/__init__.py +33 -0
- dit-2.3/dit/symbolic/distributions.py +165 -0
- {dit-2.1 → dit-2.3}/dit/utils/optimization.py +33 -0
- {dit-2.1 → dit-2.3}/dit/utils/testing.py +6 -1
- dit-2.3/dit/visualization/__init__.py +10 -0
- dit-2.3/dit/visualization/upset.py +313 -0
- {dit-2.1 → dit-2.3}/pyproject.toml +20 -9
- {dit-2.1 → dit-2.3}/tests/algorithms/test_admui.py +24 -5
- dit-2.3/tests/algorithms/test_caekl_psp_optimizer.py +36 -0
- dit-2.3/tests/algorithms/test_mixture_of_products.py +136 -0
- dit-2.3/tests/algorithms/test_mprojection.py +200 -0
- {dit-2.1 → dit-2.3}/tests/algorithms/test_optimizers.py +4 -0
- dit-2.3/tests/algorithms/test_submodular.py +60 -0
- dit-2.3/tests/algorithms/test_support_spectrum.py +100 -0
- dit-2.3/tests/coding/test_source_polar.py +282 -0
- dit-2.3/tests/divergences/test_coupling_metrics.py +94 -0
- dit-2.3/tests/divergences/test_emd.py +115 -0
- dit-2.3/tests/example_dists/empirical/__init__.py +0 -0
- dit-2.3/tests/example_dists/empirical/test_bach.py +44 -0
- dit-2.3/tests/example_dists/empirical/test_blood_types.py +67 -0
- dit-2.3/tests/example_dists/empirical/test_car.py +69 -0
- dit-2.3/tests/example_dists/empirical/test_congress.py +72 -0
- dit-2.3/tests/example_dists/empirical/test_corelli.py +47 -0
- dit-2.3/tests/example_dists/empirical/test_penguins.py +60 -0
- dit-2.3/tests/example_dists/empirical/test_student.py +60 -0
- dit-2.3/tests/example_dists/empirical/test_titanic.py +59 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_exact_common_information.py +16 -0
- dit-2.3/tests/multivariate/common_informations/test_functional_common_information.py +386 -0
- dit-2.3/tests/multivariate/common_informations/test_tension_common_information.py +127 -0
- dit-2.3/tests/multivariate/test_cross_mutual_information.py +100 -0
- dit-2.3/tests/multivariate/test_delta_gamma.py +286 -0
- dit-2.3/tests/multivariate/test_kirkwood.py +266 -0
- dit-2.3/tests/multivariate/test_mmi_psp.py +62 -0
- dit-2.3/tests/multivariate/test_s_information.py +56 -0
- dit-2.3/tests/other/test_negentropy.py +62 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_syndisc.py +6 -4
- dit-2.3/tests/profiles/test_binding_mixture.py +32 -0
- dit-2.3/tests/profiles/test_dual_dependency_decomposition.py +128 -0
- dit-2.3/tests/profiles/test_marginal_lift.py +75 -0
- dit-2.3/tests/profiles/test_mflat_connected.py +99 -0
- dit-2.3/tests/rate_distortion/test_bottleneck_algorithms.py +83 -0
- {dit-2.1 → dit-2.3}/tests/rate_distortion/test_curves.py +56 -0
- {dit-2.1 → dit-2.3}/tests/rate_distortion/test_ib.py +15 -0
- dit-2.3/tests/rate_distortion/test_tension.py +350 -0
- dit-2.3/tests/symbolic/__init__.py +0 -0
- dit-2.3/tests/symbolic/test_common_information.py +142 -0
- dit-2.3/tests/symbolic/test_cross_validation.py +362 -0
- dit-2.3/tests/symbolic/test_symbolic.py +209 -0
- {dit-2.1 → dit-2.3}/tests/test_distribution.py +71 -0
- {dit-2.1 → dit-2.3}/tests/test_inequalities.py +50 -1
- dit-2.3/tests/visualization/__init__.py +3 -0
- dit-2.3/tests/visualization/test_upset.py +165 -0
- dit-2.1/dit/divergences/coupling_metrics.py +0 -86
- dit-2.1/dit/divergences/earth_movers_distance.py +0 -127
- dit-2.1/dit/multivariate/common_informations/functional_common_information.py +0 -169
- dit-2.1/dit/rate_distortion/__init__.py +0 -7
- dit-2.1/dit/rate_distortion/gray_wyner/__init__.py +0 -31
- dit-2.1/dit/rate_distortion/gray_wyner/plotting.py +0 -49
- dit-2.1/tests/divergences/test_coupling_metrics.py +0 -19
- dit-2.1/tests/divergences/test_emd.py +0 -57
- dit-2.1/tests/multivariate/common_informations/test_functional_common_information.py +0 -56
- dit-2.1/tests/multivariate/test_delta_gamma.py +0 -84
- {dit-2.1 → dit-2.3}/.gitignore +0 -0
- {dit-2.1 → dit-2.3}/CREDITS.rst +0 -0
- {dit-2.1 → dit-2.3}/LICENSE.txt +0 -0
- {dit-2.1 → dit-2.3}/dit/abc.py +0 -0
- {dit-2.1 → dit-2.3}/dit/abstractdist.py +0 -0
- {dit-2.1 → dit-2.3}/dit/algorithms/admui.py +0 -0
- {dit-2.1 → dit-2.3}/dit/algorithms/broja_cone.py +0 -0
- {dit-2.1 → dit-2.3}/dit/algorithms/broja_method.py +0 -0
- {dit-2.1 → dit-2.3}/dit/algorithms/broja_util.py +0 -0
- {dit-2.1 → dit-2.3}/dit/algorithms/channelcapacity.py +0 -0
- {dit-2.1 → dit-2.3}/dit/algorithms/convex_maximization.py +0 -0
- {dit-2.1 → dit-2.3}/dit/algorithms/frankwolfe.py +0 -0
- {dit-2.1 → dit-2.3}/dit/algorithms/ipf.py +0 -0
- {dit-2.1 → dit-2.3}/dit/algorithms/lattice.py +0 -0
- {dit-2.1 → dit-2.3}/dit/algorithms/maxentropy.py +0 -0
- {dit-2.1 → dit-2.3}/dit/algorithms/maxentropyfw.py +0 -0
- {dit-2.1 → dit-2.3}/dit/algorithms/minimal_sufficient_statistic.py +0 -0
- {dit-2.1 → dit-2.3}/dit/algorithms/optutil.py +0 -0
- {dit-2.1 → dit-2.3}/dit/algorithms/pid_broja.py +0 -0
- {dit-2.1 → dit-2.3}/dit/algorithms/prune_expand.py +0 -0
- {dit-2.1 → dit-2.3}/dit/algorithms/stats.py +0 -0
- {dit-2.1 → dit-2.3}/dit/bgm.py +0 -0
- {dit-2.1 → dit-2.3}/dit/cdisthelpers.py +0 -0
- {dit-2.1 → dit-2.3}/dit/channelorder/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/dit/channelorder/_utils.py +0 -0
- {dit-2.1 → dit-2.3}/dit/channelorder/deficiency.py +0 -0
- {dit-2.1 → dit-2.3}/dit/channelorder/orderings.py +0 -0
- {dit-2.1 → dit-2.3}/dit/coding/_channel.py +0 -0
- {dit-2.1 → dit-2.3}/dit/coding/_gf2.py +0 -0
- {dit-2.1 → dit-2.3}/dit/coding/base.py +0 -0
- {dit-2.1 → dit-2.3}/dit/coding/block_codes.py +0 -0
- {dit-2.1 → dit-2.3}/dit/coding/codes.py +0 -0
- {dit-2.1 → dit-2.3}/dit/coding/convolutional.py +0 -0
- {dit-2.1 → dit-2.3}/dit/coding/ldpc.py +0 -0
- {dit-2.1 → dit-2.3}/dit/coding/linear.py +0 -0
- {dit-2.1 → dit-2.3}/dit/coding/symbol_code.py +0 -0
- {dit-2.1 → dit-2.3}/dit/coding/tunstall.py +0 -0
- {dit-2.1 → dit-2.3}/dit/coding/universal.py +0 -0
- {dit-2.1 → dit-2.3}/dit/distconst.py +0 -0
- {dit-2.1 → dit-2.3}/dit/divergences/_kl_nonmerge.py +0 -0
- {dit-2.1 → dit-2.3}/dit/divergences/copy_mutual_information.py +0 -0
- {dit-2.1 → dit-2.3}/dit/divergences/generalized_divergences.py +0 -0
- {dit-2.1 → dit-2.3}/dit/divergences/jensen_shannon_divergence.py +0 -0
- {dit-2.1 → dit-2.3}/dit/divergences/kullback_leibler_divergence.py +0 -0
- {dit-2.1 → dit-2.3}/dit/divergences/maximum_correlation.py +0 -0
- {dit-2.1 → dit-2.3}/dit/divergences/pmf.py +0 -0
- {dit-2.1 → dit-2.3}/dit/divergences/variational_distance.py +0 -0
- {dit-2.1 → dit-2.3}/dit/example_channels/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/dit/example_channels/_util.py +0 -0
- {dit-2.1 → dit-2.3}/dit/example_channels/binary.py +0 -0
- {dit-2.1 → dit-2.3}/dit/example_channels/qary.py +0 -0
- {dit-2.1 → dit-2.3}/dit/example_channels/trivial.py +0 -0
- {dit-2.1 → dit-2.3}/dit/example_dists/circuits.py +0 -0
- {dit-2.1 → dit-2.3}/dit/example_dists/dependencies.py +0 -0
- {dit-2.1 → dit-2.3}/dit/example_dists/dice.py +0 -0
- {dit-2.1 → dit-2.3}/dit/example_dists/giant_bit.py +0 -0
- {dit-2.1 → dit-2.3}/dit/example_dists/intrinsic.py +0 -0
- {dit-2.1 → dit-2.3}/dit/example_dists/mdbsi.py +0 -0
- {dit-2.1 → dit-2.3}/dit/example_dists/miscellaneous.py +0 -0
- {dit-2.1 → dit-2.3}/dit/example_dists/n_mod_m.py +0 -0
- {dit-2.1 → dit-2.3}/dit/example_dists/nonsignalling_boxes.py +0 -0
- {dit-2.1 → dit-2.3}/dit/example_dists/numeric.py +0 -0
- {dit-2.1 → dit-2.3}/dit/exceptions.py +0 -0
- {dit-2.1 → dit-2.3}/dit/helpers.py +0 -0
- {dit-2.1 → dit-2.3}/dit/inference/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/dit/inference/binning.py +0 -0
- {dit-2.1 → dit-2.3}/dit/inference/counts.c +0 -0
- {dit-2.1 → dit-2.3}/dit/inference/counts.h +0 -0
- {dit-2.1 → dit-2.3}/dit/inference/counts.py +0 -0
- {dit-2.1 → dit-2.3}/dit/inference/estimators.py +0 -0
- {dit-2.1 → dit-2.3}/dit/inference/knn_estimators.py +0 -0
- {dit-2.1 → dit-2.3}/dit/inference/pycounts.pyx +0 -0
- {dit-2.1 → dit-2.3}/dit/inference/segmentaxis.py +0 -0
- {dit-2.1 → dit-2.3}/dit/inference/time_series.py +0 -0
- {dit-2.1 → dit-2.3}/dit/math/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/dit/math/_close.pyx +0 -0
- {dit-2.1 → dit-2.3}/dit/math/_samplediscrete.pyx +0 -0
- {dit-2.1 → dit-2.3}/dit/math/aitchison.py +0 -0
- {dit-2.1 → dit-2.3}/dit/math/combinatorics.py +0 -0
- {dit-2.1 → dit-2.3}/dit/math/equal.py +0 -0
- {dit-2.1 → dit-2.3}/dit/math/fraction.py +0 -0
- {dit-2.1 → dit-2.3}/dit/math/misc.py +0 -0
- {dit-2.1 → dit-2.3}/dit/math/ops.py +0 -0
- {dit-2.1 → dit-2.3}/dit/math/pmfops.py +0 -0
- {dit-2.1 → dit-2.3}/dit/math/sampling.py +0 -0
- {dit-2.1 → dit-2.3}/dit/math/sigmaalgebra.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/_backend.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/cohesion.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/coinformation.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/beta_common_information.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/gk_common_information.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/kamath_common_information.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/maxent_function.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/mss_common_information.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/stochastic_gk_common_information.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/common_informations/wyner_common_information.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/delta_gamma.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/deweese.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/dual_total_correlation.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/entropy.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/logarithmic_decomposition.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/necessary_conditional_entropy.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/o_information.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/quax_synergy.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/base_skar_optimizers.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/interactive_intrinsic_mutual_informations.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/intrinsic_mutual_informations.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/minimal_intrinsic_mutual_informations.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/no_communication.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/one_way_skar.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/reduced_intrinsic_mutual_informations.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/secrecy_capacity.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/skar_lower_bounds.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/trivial_bounds.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/two_part_intrinsic_mutual_informations.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/secret_key_agreement/two_way_skar.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/synergistic_disclosure.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/total_correlation.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/transmission.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/tse_complexity.py +0 -0
- {dit-2.1 → dit-2.3}/dit/multivariate/union_information.py +0 -0
- {dit-2.1 → dit-2.3}/dit/other/cumulative_residual_entropy.py +0 -0
- {dit-2.1 → dit-2.3}/dit/other/disequilibrium.py +0 -0
- {dit-2.1 → dit-2.3}/dit/other/lautum_information.py +0 -0
- {dit-2.1 → dit-2.3}/dit/other/perplexity.py +0 -0
- {dit-2.1 → dit-2.3}/dit/other/renyi_entropy.py +0 -0
- {dit-2.1 → dit-2.3}/dit/other/sibson_mutual_information.py +0 -0
- {dit-2.1 → dit-2.3}/dit/other/tsallis_entropy.py +0 -0
- {dit-2.1 → dit-2.3}/dit/params.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/distributions/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/distributions/bivariate.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/distributions/trivariate.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/hcs.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/helpers.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/hmos.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/ibroja.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/iccs.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/ict.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/ideg.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/idelta.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/ideltalambda.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/idep.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/ido.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/igh.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/iig.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/iipid.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/imc.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/imes.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/ipm.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/iprec.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/iproj.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/irav.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/irdr.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/irr.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/iskar.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/isx.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/measures/iwedge.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/ped.py +0 -0
- {dit-2.1 → dit-2.3}/dit/pid/syndisc.py +0 -0
- {dit-2.1 → dit-2.3}/dit/profiles/base_profile.py +0 -0
- {dit-2.1 → dit-2.3}/dit/profiles/complexity_profile.py +0 -0
- {dit-2.1 → dit-2.3}/dit/profiles/entropy_triangle.py +0 -0
- {dit-2.1 → dit-2.3}/dit/profiles/marginal_utility_of_information.py +0 -0
- {dit-2.1 → dit-2.3}/dit/profiles/shapley_info_decomposition.py +0 -0
- {dit-2.1 → dit-2.3}/dit/rate_distortion/blahut_arimoto.py +0 -0
- {dit-2.1 → dit-2.3}/dit/rate_distortion/distortions.py +0 -0
- {dit-2.1 → dit-2.3}/dit/rate_distortion/gray_wyner/curve.py +0 -0
- {dit-2.1 → dit-2.3}/dit/rate_distortion/plotting.py +0 -0
- {dit-2.1 → dit-2.3}/dit/rate_distortion/rate_distortion.py +0 -0
- {dit-2.1 → dit-2.3}/dit/samplespace.py +0 -0
- {dit-2.1 → dit-2.3}/dit/shannon/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/dit/utils/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/dit/utils/bindargs.py +0 -0
- {dit-2.1 → dit-2.3}/dit/utils/context.py +0 -0
- {dit-2.1 → dit-2.3}/dit/utils/latexarray.py +0 -0
- {dit-2.1 → dit-2.3}/dit/utils/logger.py +0 -0
- {dit-2.1 → dit-2.3}/dit/utils/misc.py +0 -0
- {dit-2.1 → dit-2.3}/dit/utils/table.py +0 -0
- {dit-2.1 → dit-2.3}/dit/utils/units.py +0 -0
- {dit-2.1 → dit-2.3}/dit/validate.py +0 -0
- {dit-2.1 → dit-2.3}/tests/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/tests/_backends.py +0 -0
- {dit-2.1 → dit-2.3}/tests/algorithms/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/tests/algorithms/test_broja_cone.py +0 -0
- {dit-2.1 → dit-2.3}/tests/algorithms/test_channelcapacity.py +0 -0
- {dit-2.1 → dit-2.3}/tests/algorithms/test_degrees_of_freedom.py +0 -0
- {dit-2.1 → dit-2.3}/tests/algorithms/test_ipf.py +0 -0
- {dit-2.1 → dit-2.3}/tests/algorithms/test_lattice.py +0 -0
- {dit-2.1 → dit-2.3}/tests/algorithms/test_marginal_constraints.py +0 -0
- {dit-2.1 → dit-2.3}/tests/algorithms/test_maxentropy_fast.py +0 -0
- {dit-2.1 → dit-2.3}/tests/algorithms/test_minimal_sufficient_statistic.py +0 -0
- {dit-2.1 → dit-2.3}/tests/algorithms/test_parallel_sweep.py +0 -0
- {dit-2.1 → dit-2.3}/tests/algorithms/test_prune_expand.py +0 -0
- {dit-2.1 → dit-2.3}/tests/algorithms/test_stats.py +0 -0
- {dit-2.1 → dit-2.3}/tests/channelorder/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/tests/channelorder/test_deficiency.py +0 -0
- {dit-2.1 → dit-2.3}/tests/channelorder/test_orderings.py +0 -0
- {dit-2.1 → dit-2.3}/tests/channelorder/test_properties.py +0 -0
- {dit-2.1 → dit-2.3}/tests/channelorder/test_utils.py +0 -0
- {dit-2.1 → dit-2.3}/tests/coding/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/tests/coding/test_base.py +0 -0
- {dit-2.1 → dit-2.3}/tests/coding/test_channel.py +0 -0
- {dit-2.1 → dit-2.3}/tests/coding/test_channel_codes.py +0 -0
- {dit-2.1 → dit-2.3}/tests/coding/test_edge_cases.py +0 -0
- {dit-2.1 → dit-2.3}/tests/coding/test_gf2.py +0 -0
- {dit-2.1 → dit-2.3}/tests/coding/test_golomb.py +0 -0
- {dit-2.1 → dit-2.3}/tests/coding/test_linear.py +0 -0
- {dit-2.1 → dit-2.3}/tests/coding/test_source_edges.py +0 -0
- {dit-2.1 → dit-2.3}/tests/coding/test_symbol_codes.py +0 -0
- {dit-2.1 → dit-2.3}/tests/coding/test_tunstall.py +0 -0
- {dit-2.1 → dit-2.3}/tests/coding/test_universal.py +0 -0
- {dit-2.1 → dit-2.3}/tests/conftest.py +0 -0
- {dit-2.1 → dit-2.3}/tests/divergences/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/tests/divergences/test_copy_mutual_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/divergences/test_cross_entropy.py +0 -0
- {dit-2.1 → dit-2.3}/tests/divergences/test_generalized_divergences.py +0 -0
- {dit-2.1 → dit-2.3}/tests/divergences/test_hypercontractivity_coefficient.py +0 -0
- {dit-2.1 → dit-2.3}/tests/divergences/test_jensen_shannon_divergence.py +0 -0
- {dit-2.1 → dit-2.3}/tests/divergences/test_kullback_leibler_divergence.py +0 -0
- {dit-2.1 → dit-2.3}/tests/divergences/test_maximum_correlation.py +0 -0
- {dit-2.1 → dit-2.3}/tests/divergences/test_nonmerge.py +0 -0
- {dit-2.1 → dit-2.3}/tests/divergences/test_variational_distance.py +0 -0
- {dit-2.1 → dit-2.3}/tests/example_channels/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/tests/example_channels/test_binary.py +0 -0
- {dit-2.1 → dit-2.3}/tests/example_channels/test_qary.py +0 -0
- {dit-2.1 → dit-2.3}/tests/example_channels/test_trivial.py +0 -0
- {dit-2.1 → dit-2.3}/tests/example_channels/test_util.py +0 -0
- {dit-2.1 → dit-2.3}/tests/example_dists/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/tests/example_dists/test_circuits.py +0 -0
- {dit-2.1 → dit-2.3}/tests/example_dists/test_dependencies.py +0 -0
- {dit-2.1 → dit-2.3}/tests/example_dists/test_dice.py +0 -0
- {dit-2.1 → dit-2.3}/tests/example_dists/test_giant_bit.py +0 -0
- {dit-2.1 → dit-2.3}/tests/example_dists/test_mdbsi.py +0 -0
- {dit-2.1 → dit-2.3}/tests/example_dists/test_miscellaneous.py +0 -0
- {dit-2.1 → dit-2.3}/tests/example_dists/test_n_mod_m.py +0 -0
- {dit-2.1 → dit-2.3}/tests/example_dists/test_numeric.py +0 -0
- {dit-2.1 → dit-2.3}/tests/example_dists/test_pr_box.py +0 -0
- {dit-2.1 → dit-2.3}/tests/inference/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/tests/inference/test_binning.py +0 -0
- {dit-2.1 → dit-2.3}/tests/inference/test_counts.py +0 -0
- {dit-2.1 → dit-2.3}/tests/inference/test_estimators.py +0 -0
- {dit-2.1 → dit-2.3}/tests/inference/test_knn_estimators.py +0 -0
- {dit-2.1 → dit-2.3}/tests/inference/test_segmentaxis.py +0 -0
- {dit-2.1 → dit-2.3}/tests/inference/test_timeseries.py +0 -0
- {dit-2.1 → dit-2.3}/tests/math/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/tests/math/test_aitchison.py +0 -0
- {dit-2.1 → dit-2.3}/tests/math/test_combinatorics.py +0 -0
- {dit-2.1 → dit-2.3}/tests/math/test_equal.py +0 -0
- {dit-2.1 → dit-2.3}/tests/math/test_fraction.py +0 -0
- {dit-2.1 → dit-2.3}/tests/math/test_misc.py +0 -0
- {dit-2.1 → dit-2.3}/tests/math/test_ops.py +0 -0
- {dit-2.1 → dit-2.3}/tests/math/test_pmfops.py +0 -0
- {dit-2.1 → dit-2.3}/tests/math/test_sampling.py +0 -0
- {dit-2.1 → dit-2.3}/tests/math/test_sigmaalgebra.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_backend_switching.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_beta_common_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_common_informations.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_gk_common_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_kamath_common_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_maxent_function.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_mss_common_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_stochastic_gk_common_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/common_informations/test_wyner_common_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_interactive_intrinsic_mutual_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_intrinsic_mutual_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_lower_intrinsic_mutual_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_minimal_intrinsic_mutual_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_necessary_intrinsic_mutual_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_reduced_intrinsic_mutual_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_secrecy_capacity.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_skars.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_trivial_bounds.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_two_part_intrinsic_mutual_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/secret_key_agreement/test_two_way_skar.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/test_caekl_mutual_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/test_cohesion.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/test_coinformation.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/test_deweese.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/test_dual_total_correlation.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/test_entropy.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/test_interaction_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/test_logarithmic_decomposition.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/test_mutual_informations.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/test_necessary_conditional_entropy.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/test_o_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/test_quax_synergy.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/test_synergistic_disclosure.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/test_total_correlation.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/test_transmission.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/test_tse_complexity.py +0 -0
- {dit-2.1 → dit-2.3}/tests/multivariate/test_union_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/other/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/tests/other/test_cumulative_residual_entropy.py +0 -0
- {dit-2.1 → dit-2.3}/tests/other/test_disequilibrium.py +0 -0
- {dit-2.1 → dit-2.3}/tests/other/test_extropy.py +0 -0
- {dit-2.1 → dit-2.3}/tests/other/test_lautum_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/other/test_perplexity.py +0 -0
- {dit-2.1 → dit-2.3}/tests/other/test_renyi_entropy.py +0 -0
- {dit-2.1 → dit-2.3}/tests/other/test_sibson_mutual_information.py +0 -0
- {dit-2.1 → dit-2.3}/tests/other/test_tsallis_entropy.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_hcs.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_hmos.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_ibroja.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_iccs.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_ict.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_ideg.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_idelta.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_idep.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_ido.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_igh.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_iig.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_iipid.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_imc.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_imes.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_imin.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_immi.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_ipm.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_iprec.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_iproj.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_irav.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_irdr.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_irr.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_iskar.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_isx.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_iwedge.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_modified_syndisc.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_pid_distribution.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_syndisc_fast.py +0 -0
- {dit-2.1 → dit-2.3}/tests/pid/test_syndisc_lattice.py +0 -0
- {dit-2.1 → dit-2.3}/tests/profiles/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/tests/profiles/test_base_profile.py +0 -0
- {dit-2.1 → dit-2.3}/tests/profiles/test_complexity_profile.py +0 -0
- {dit-2.1 → dit-2.3}/tests/profiles/test_entropy_triangle.py +0 -0
- {dit-2.1 → dit-2.3}/tests/profiles/test_information_partitions.py +0 -0
- {dit-2.1 → dit-2.3}/tests/profiles/test_mui.py +0 -0
- {dit-2.1 → dit-2.3}/tests/profiles/test_schneidman.py +0 -0
- {dit-2.1 → dit-2.3}/tests/profiles/test_shapley_info_decomposition.py +0 -0
- {dit-2.1 → dit-2.3}/tests/rate_distortion/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/tests/rate_distortion/test_gray_wyner.py +0 -0
- {dit-2.1 → dit-2.3}/tests/rate_distortion/test_rd.py +0 -0
- {dit-2.1 → dit-2.3}/tests/shannon/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/tests/shannon/test_shannon.py +0 -0
- {dit-2.1 → dit-2.3}/tests/test_abstractdist.py +0 -0
- {dit-2.1 → dit-2.3}/tests/test_bgm.py +0 -0
- {dit-2.1 → dit-2.3}/tests/test_cdisthelpers.py +0 -0
- {dit-2.1 → dit-2.3}/tests/test_distconst.py +0 -0
- {dit-2.1 → dit-2.3}/tests/test_distribution_coverage.py +0 -0
- {dit-2.1 → dit-2.3}/tests/test_exceptions.py +0 -0
- {dit-2.1 → dit-2.3}/tests/test_helpers.py +0 -0
- {dit-2.1 → dit-2.3}/tests/test_params.py +0 -0
- {dit-2.1 → dit-2.3}/tests/test_samplespace.py +0 -0
- {dit-2.1 → dit-2.3}/tests/test_validate.py +0 -0
- {dit-2.1 → dit-2.3}/tests/utils/__init__.py +0 -0
- {dit-2.1 → dit-2.3}/tests/utils/test_bindargs.py +0 -0
- {dit-2.1 → dit-2.3}/tests/utils/test_bindargs3.py +0 -0
- {dit-2.1 → dit-2.3}/tests/utils/test_context.py +0 -0
- {dit-2.1 → dit-2.3}/tests/utils/test_latexarray.py +0 -0
- {dit-2.1 → dit-2.3}/tests/utils/test_misc.py +0 -0
- {dit-2.1 → dit-2.3}/tests/utils/test_optimization.py +0 -0
- {dit-2.1 → dit-2.3}/tests/utils/test_table.py +0 -0
- {dit-2.1 → dit-2.3}/tests/utils/test_testing.py +0 -0
- {dit-2.1 → dit-2.3}/tests/utils/test_units.py +0 -0
{dit-2.1 → dit-2.3}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
2
|
Name: dit
|
|
3
|
-
Version: 2.
|
|
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
|
|
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/
|
|
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
|
|
{dit-2.1 → dit-2.3}/README.rst
RENAMED
|
@@ -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/
|
|
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
|
-
|
|
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
|