dit 2.1__tar.gz → 2.2__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.2}/PKG-INFO +9 -4
- {dit-2.1 → dit-2.2}/README.rst +1 -1
- {dit-2.1 → dit-2.2}/dit/__init__.py +2 -0
- dit-2.2/dit/algorithms/caekl_psp.py +215 -0
- {dit-2.1 → dit-2.2}/dit/algorithms/distribution_optimizers.py +81 -0
- {dit-2.1 → dit-2.2}/dit/algorithms/optimization.py +102 -48
- {dit-2.1 → dit-2.2}/dit/algorithms/optimization_jax.py +95 -38
- {dit-2.1 → dit-2.2}/dit/algorithms/optimization_pytensor.py +32 -1
- {dit-2.1 → dit-2.2}/dit/algorithms/optimization_torch.py +30 -36
- dit-2.2/dit/algorithms/submodular.py +165 -0
- {dit-2.1 → dit-2.2}/dit/coding/__init__.py +12 -0
- {dit-2.1 → dit-2.2}/dit/coding/_util.py +26 -0
- {dit-2.1 → dit-2.2}/dit/coding/polar.py +1 -10
- dit-2.2/dit/coding/source_polar.py +508 -0
- {dit-2.1 → dit-2.2}/dit/distribution.py +150 -25
- {dit-2.1 → dit-2.2}/dit/divergences/__init__.py +9 -4
- dit-2.2/dit/divergences/coupling_metrics.py +274 -0
- {dit-2.1 → dit-2.2}/dit/divergences/cross_entropy.py +20 -0
- dit-2.2/dit/divergences/earth_movers_distance.py +233 -0
- {dit-2.1 → dit-2.2}/dit/divergences/hypercontractivity_coefficient.py +12 -4
- {dit-2.1 → dit-2.2}/dit/example_dists/__init__.py +1 -0
- dit-2.2/dit/example_dists/empirical/__init__.py +16 -0
- dit-2.2/dit/example_dists/empirical/_music.py +127 -0
- dit-2.2/dit/example_dists/empirical/bach.py +77 -0
- dit-2.2/dit/example_dists/empirical/blood_types.py +203 -0
- dit-2.2/dit/example_dists/empirical/car.py +95 -0
- dit-2.2/dit/example_dists/empirical/congress.py +109 -0
- dit-2.2/dit/example_dists/empirical/corelli.py +132 -0
- dit-2.2/dit/example_dists/empirical/penguins.py +77 -0
- dit-2.2/dit/example_dists/empirical/student.py +94 -0
- dit-2.2/dit/example_dists/empirical/titanic.py +85 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/__init__.py +2 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/caekl_mutual_information.py +19 -8
- dit-2.2/dit/multivariate/common_informations/_functional_partition.py +223 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/common_informations/base_markov_optimizer.py +12 -1
- dit-2.2/dit/multivariate/common_informations/functional_common_information.py +572 -0
- dit-2.2/dit/multivariate/common_informations/symbolic_ansatz.py +103 -0
- dit-2.2/dit/multivariate/common_informations/symbolic_markov.py +196 -0
- dit-2.2/dit/multivariate/common_informations/symbolic_solve.py +301 -0
- dit-2.2/dit/multivariate/cross_mutual_information.py +205 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/interaction_information.py +1 -1
- dit-2.2/dit/multivariate/mmi_psp.py +247 -0
- dit-2.2/dit/multivariate/s_information.py +48 -0
- {dit-2.1 → dit-2.2}/dit/other/__init__.py +1 -0
- {dit-2.1 → dit-2.2}/dit/other/extropy.py +10 -0
- dit-2.2/dit/other/negentropy.py +54 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/imin.py +19 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/immi.py +6 -1
- {dit-2.1 → dit-2.2}/dit/pid/pid.py +19 -2
- dit-2.2/dit/rate_distortion/__init__.py +13 -0
- dit-2.2/dit/rate_distortion/bottleneck_algorithms.py +501 -0
- {dit-2.1 → dit-2.2}/dit/rate_distortion/curves.py +101 -8
- {dit-2.1 → dit-2.2}/dit/rate_distortion/information_bottleneck.py +53 -0
- {dit-2.1 → dit-2.2}/dit/shannon/shannon.py +19 -0
- dit-2.2/dit/symbolic/__init__.py +33 -0
- dit-2.2/dit/symbolic/distributions.py +165 -0
- {dit-2.1 → dit-2.2}/dit/utils/optimization.py +33 -0
- {dit-2.1 → dit-2.2}/dit/utils/testing.py +6 -1
- dit-2.2/dit/visualization/__init__.py +10 -0
- dit-2.2/dit/visualization/upset.py +313 -0
- {dit-2.1 → dit-2.2}/pyproject.toml +20 -7
- {dit-2.1 → dit-2.2}/tests/algorithms/test_admui.py +24 -5
- dit-2.2/tests/algorithms/test_caekl_psp_optimizer.py +36 -0
- {dit-2.1 → dit-2.2}/tests/algorithms/test_optimizers.py +4 -0
- dit-2.2/tests/algorithms/test_submodular.py +60 -0
- dit-2.2/tests/coding/test_source_polar.py +282 -0
- dit-2.2/tests/divergences/test_coupling_metrics.py +94 -0
- dit-2.2/tests/divergences/test_emd.py +115 -0
- dit-2.2/tests/example_dists/empirical/__init__.py +0 -0
- dit-2.2/tests/example_dists/empirical/test_bach.py +44 -0
- dit-2.2/tests/example_dists/empirical/test_blood_types.py +67 -0
- dit-2.2/tests/example_dists/empirical/test_car.py +69 -0
- dit-2.2/tests/example_dists/empirical/test_congress.py +72 -0
- dit-2.2/tests/example_dists/empirical/test_corelli.py +47 -0
- dit-2.2/tests/example_dists/empirical/test_penguins.py +60 -0
- dit-2.2/tests/example_dists/empirical/test_student.py +60 -0
- dit-2.2/tests/example_dists/empirical/test_titanic.py +59 -0
- dit-2.2/tests/multivariate/common_informations/test_functional_common_information.py +386 -0
- dit-2.2/tests/multivariate/test_cross_mutual_information.py +100 -0
- dit-2.2/tests/multivariate/test_delta_gamma.py +286 -0
- dit-2.2/tests/multivariate/test_mmi_psp.py +62 -0
- dit-2.2/tests/multivariate/test_s_information.py +56 -0
- dit-2.2/tests/other/test_negentropy.py +62 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_syndisc.py +6 -4
- dit-2.2/tests/rate_distortion/test_bottleneck_algorithms.py +83 -0
- {dit-2.1 → dit-2.2}/tests/rate_distortion/test_curves.py +56 -0
- {dit-2.1 → dit-2.2}/tests/rate_distortion/test_ib.py +15 -0
- dit-2.2/tests/symbolic/__init__.py +0 -0
- dit-2.2/tests/symbolic/test_common_information.py +142 -0
- dit-2.2/tests/symbolic/test_cross_validation.py +362 -0
- dit-2.2/tests/symbolic/test_symbolic.py +209 -0
- {dit-2.1 → dit-2.2}/tests/test_inequalities.py +50 -1
- dit-2.2/tests/visualization/__init__.py +3 -0
- dit-2.2/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/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.2}/.gitignore +0 -0
- {dit-2.1 → dit-2.2}/CREDITS.rst +0 -0
- {dit-2.1 → dit-2.2}/LICENSE.txt +0 -0
- {dit-2.1 → dit-2.2}/dit/abc.py +0 -0
- {dit-2.1 → dit-2.2}/dit/abstractdist.py +0 -0
- {dit-2.1 → dit-2.2}/dit/algorithms/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/dit/algorithms/admui.py +0 -0
- {dit-2.1 → dit-2.2}/dit/algorithms/broja_cone.py +0 -0
- {dit-2.1 → dit-2.2}/dit/algorithms/broja_method.py +0 -0
- {dit-2.1 → dit-2.2}/dit/algorithms/broja_util.py +0 -0
- {dit-2.1 → dit-2.2}/dit/algorithms/channelcapacity.py +0 -0
- {dit-2.1 → dit-2.2}/dit/algorithms/convex_maximization.py +0 -0
- {dit-2.1 → dit-2.2}/dit/algorithms/frankwolfe.py +0 -0
- {dit-2.1 → dit-2.2}/dit/algorithms/ipf.py +0 -0
- {dit-2.1 → dit-2.2}/dit/algorithms/lattice.py +0 -0
- {dit-2.1 → dit-2.2}/dit/algorithms/maxentropy.py +0 -0
- {dit-2.1 → dit-2.2}/dit/algorithms/maxentropyfw.py +0 -0
- {dit-2.1 → dit-2.2}/dit/algorithms/minimal_sufficient_statistic.py +0 -0
- {dit-2.1 → dit-2.2}/dit/algorithms/optutil.py +0 -0
- {dit-2.1 → dit-2.2}/dit/algorithms/pid_broja.py +0 -0
- {dit-2.1 → dit-2.2}/dit/algorithms/prune_expand.py +0 -0
- {dit-2.1 → dit-2.2}/dit/algorithms/stats.py +0 -0
- {dit-2.1 → dit-2.2}/dit/bgm.py +0 -0
- {dit-2.1 → dit-2.2}/dit/cdisthelpers.py +0 -0
- {dit-2.1 → dit-2.2}/dit/channelorder/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/dit/channelorder/_utils.py +0 -0
- {dit-2.1 → dit-2.2}/dit/channelorder/deficiency.py +0 -0
- {dit-2.1 → dit-2.2}/dit/channelorder/orderings.py +0 -0
- {dit-2.1 → dit-2.2}/dit/coding/_channel.py +0 -0
- {dit-2.1 → dit-2.2}/dit/coding/_gf2.py +0 -0
- {dit-2.1 → dit-2.2}/dit/coding/base.py +0 -0
- {dit-2.1 → dit-2.2}/dit/coding/block_codes.py +0 -0
- {dit-2.1 → dit-2.2}/dit/coding/codes.py +0 -0
- {dit-2.1 → dit-2.2}/dit/coding/convolutional.py +0 -0
- {dit-2.1 → dit-2.2}/dit/coding/ldpc.py +0 -0
- {dit-2.1 → dit-2.2}/dit/coding/linear.py +0 -0
- {dit-2.1 → dit-2.2}/dit/coding/symbol_code.py +0 -0
- {dit-2.1 → dit-2.2}/dit/coding/tunstall.py +0 -0
- {dit-2.1 → dit-2.2}/dit/coding/universal.py +0 -0
- {dit-2.1 → dit-2.2}/dit/distconst.py +0 -0
- {dit-2.1 → dit-2.2}/dit/divergences/_kl_nonmerge.py +0 -0
- {dit-2.1 → dit-2.2}/dit/divergences/copy_mutual_information.py +0 -0
- {dit-2.1 → dit-2.2}/dit/divergences/generalized_divergences.py +0 -0
- {dit-2.1 → dit-2.2}/dit/divergences/jensen_shannon_divergence.py +0 -0
- {dit-2.1 → dit-2.2}/dit/divergences/kullback_leibler_divergence.py +0 -0
- {dit-2.1 → dit-2.2}/dit/divergences/maximum_correlation.py +0 -0
- {dit-2.1 → dit-2.2}/dit/divergences/pmf.py +0 -0
- {dit-2.1 → dit-2.2}/dit/divergences/variational_distance.py +0 -0
- {dit-2.1 → dit-2.2}/dit/example_channels/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/dit/example_channels/_util.py +0 -0
- {dit-2.1 → dit-2.2}/dit/example_channels/binary.py +0 -0
- {dit-2.1 → dit-2.2}/dit/example_channels/qary.py +0 -0
- {dit-2.1 → dit-2.2}/dit/example_channels/trivial.py +0 -0
- {dit-2.1 → dit-2.2}/dit/example_dists/circuits.py +0 -0
- {dit-2.1 → dit-2.2}/dit/example_dists/dependencies.py +0 -0
- {dit-2.1 → dit-2.2}/dit/example_dists/dice.py +0 -0
- {dit-2.1 → dit-2.2}/dit/example_dists/giant_bit.py +0 -0
- {dit-2.1 → dit-2.2}/dit/example_dists/intrinsic.py +0 -0
- {dit-2.1 → dit-2.2}/dit/example_dists/mdbsi.py +0 -0
- {dit-2.1 → dit-2.2}/dit/example_dists/miscellaneous.py +0 -0
- {dit-2.1 → dit-2.2}/dit/example_dists/n_mod_m.py +0 -0
- {dit-2.1 → dit-2.2}/dit/example_dists/nonsignalling_boxes.py +0 -0
- {dit-2.1 → dit-2.2}/dit/example_dists/numeric.py +0 -0
- {dit-2.1 → dit-2.2}/dit/exceptions.py +0 -0
- {dit-2.1 → dit-2.2}/dit/helpers.py +0 -0
- {dit-2.1 → dit-2.2}/dit/inference/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/dit/inference/binning.py +0 -0
- {dit-2.1 → dit-2.2}/dit/inference/counts.c +0 -0
- {dit-2.1 → dit-2.2}/dit/inference/counts.h +0 -0
- {dit-2.1 → dit-2.2}/dit/inference/counts.py +0 -0
- {dit-2.1 → dit-2.2}/dit/inference/estimators.py +0 -0
- {dit-2.1 → dit-2.2}/dit/inference/knn_estimators.py +0 -0
- {dit-2.1 → dit-2.2}/dit/inference/pycounts.pyx +0 -0
- {dit-2.1 → dit-2.2}/dit/inference/segmentaxis.py +0 -0
- {dit-2.1 → dit-2.2}/dit/inference/time_series.py +0 -0
- {dit-2.1 → dit-2.2}/dit/math/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/dit/math/_close.pyx +0 -0
- {dit-2.1 → dit-2.2}/dit/math/_samplediscrete.pyx +0 -0
- {dit-2.1 → dit-2.2}/dit/math/aitchison.py +0 -0
- {dit-2.1 → dit-2.2}/dit/math/combinatorics.py +0 -0
- {dit-2.1 → dit-2.2}/dit/math/equal.py +0 -0
- {dit-2.1 → dit-2.2}/dit/math/fraction.py +0 -0
- {dit-2.1 → dit-2.2}/dit/math/misc.py +0 -0
- {dit-2.1 → dit-2.2}/dit/math/ops.py +0 -0
- {dit-2.1 → dit-2.2}/dit/math/pmfops.py +0 -0
- {dit-2.1 → dit-2.2}/dit/math/sampling.py +0 -0
- {dit-2.1 → dit-2.2}/dit/math/sigmaalgebra.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/_backend.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/cohesion.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/coinformation.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/common_informations/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/common_informations/beta_common_information.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/common_informations/exact_common_information.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/common_informations/gk_common_information.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/common_informations/kamath_common_information.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/common_informations/maxent_function.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/common_informations/mss_common_information.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/common_informations/stochastic_gk_common_information.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/common_informations/wyner_common_information.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/delta_gamma.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/deweese.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/dual_total_correlation.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/entropy.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/logarithmic_decomposition.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/necessary_conditional_entropy.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/o_information.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/quax_synergy.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/secret_key_agreement/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/secret_key_agreement/base_skar_optimizers.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/secret_key_agreement/interactive_intrinsic_mutual_informations.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/secret_key_agreement/intrinsic_mutual_informations.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/secret_key_agreement/minimal_intrinsic_mutual_informations.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/secret_key_agreement/no_communication.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/secret_key_agreement/one_way_skar.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/secret_key_agreement/reduced_intrinsic_mutual_informations.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/secret_key_agreement/secrecy_capacity.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/secret_key_agreement/skar_lower_bounds.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/secret_key_agreement/trivial_bounds.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/secret_key_agreement/two_part_intrinsic_mutual_informations.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/secret_key_agreement/two_way_skar.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/synergistic_disclosure.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/total_correlation.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/transmission.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/tse_complexity.py +0 -0
- {dit-2.1 → dit-2.2}/dit/multivariate/union_information.py +0 -0
- {dit-2.1 → dit-2.2}/dit/other/cumulative_residual_entropy.py +0 -0
- {dit-2.1 → dit-2.2}/dit/other/disequilibrium.py +0 -0
- {dit-2.1 → dit-2.2}/dit/other/lautum_information.py +0 -0
- {dit-2.1 → dit-2.2}/dit/other/perplexity.py +0 -0
- {dit-2.1 → dit-2.2}/dit/other/renyi_entropy.py +0 -0
- {dit-2.1 → dit-2.2}/dit/other/sibson_mutual_information.py +0 -0
- {dit-2.1 → dit-2.2}/dit/other/tsallis_entropy.py +0 -0
- {dit-2.1 → dit-2.2}/dit/params.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/distributions/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/distributions/bivariate.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/distributions/trivariate.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/hcs.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/helpers.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/hmos.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/ibroja.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/iccs.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/ict.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/ideg.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/idelta.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/ideltalambda.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/idep.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/ido.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/igh.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/iig.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/iipid.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/imc.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/imes.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/ipm.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/iprec.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/iproj.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/irav.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/irdr.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/irr.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/iskar.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/isx.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/measures/iwedge.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/ped.py +0 -0
- {dit-2.1 → dit-2.2}/dit/pid/syndisc.py +0 -0
- {dit-2.1 → dit-2.2}/dit/profiles/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/dit/profiles/base_profile.py +0 -0
- {dit-2.1 → dit-2.2}/dit/profiles/complexity_profile.py +0 -0
- {dit-2.1 → dit-2.2}/dit/profiles/entropy_triangle.py +0 -0
- {dit-2.1 → dit-2.2}/dit/profiles/information_partitions.py +0 -0
- {dit-2.1 → dit-2.2}/dit/profiles/marginal_utility_of_information.py +0 -0
- {dit-2.1 → dit-2.2}/dit/profiles/schneidman.py +0 -0
- {dit-2.1 → dit-2.2}/dit/profiles/shapley_info_decomposition.py +0 -0
- {dit-2.1 → dit-2.2}/dit/rate_distortion/blahut_arimoto.py +0 -0
- {dit-2.1 → dit-2.2}/dit/rate_distortion/distortions.py +0 -0
- {dit-2.1 → dit-2.2}/dit/rate_distortion/gray_wyner/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/dit/rate_distortion/gray_wyner/curve.py +0 -0
- {dit-2.1 → dit-2.2}/dit/rate_distortion/gray_wyner/network.py +0 -0
- {dit-2.1 → dit-2.2}/dit/rate_distortion/gray_wyner/optimizer.py +0 -0
- {dit-2.1 → dit-2.2}/dit/rate_distortion/gray_wyner/plotting.py +0 -0
- {dit-2.1 → dit-2.2}/dit/rate_distortion/plotting.py +0 -0
- {dit-2.1 → dit-2.2}/dit/rate_distortion/rate_distortion.py +0 -0
- {dit-2.1 → dit-2.2}/dit/samplespace.py +0 -0
- {dit-2.1 → dit-2.2}/dit/shannon/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/dit/utils/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/dit/utils/bindargs.py +0 -0
- {dit-2.1 → dit-2.2}/dit/utils/context.py +0 -0
- {dit-2.1 → dit-2.2}/dit/utils/latexarray.py +0 -0
- {dit-2.1 → dit-2.2}/dit/utils/logger.py +0 -0
- {dit-2.1 → dit-2.2}/dit/utils/misc.py +0 -0
- {dit-2.1 → dit-2.2}/dit/utils/table.py +0 -0
- {dit-2.1 → dit-2.2}/dit/utils/units.py +0 -0
- {dit-2.1 → dit-2.2}/dit/validate.py +0 -0
- {dit-2.1 → dit-2.2}/tests/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/tests/_backends.py +0 -0
- {dit-2.1 → dit-2.2}/tests/algorithms/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/tests/algorithms/test_broja_cone.py +0 -0
- {dit-2.1 → dit-2.2}/tests/algorithms/test_channelcapacity.py +0 -0
- {dit-2.1 → dit-2.2}/tests/algorithms/test_degrees_of_freedom.py +0 -0
- {dit-2.1 → dit-2.2}/tests/algorithms/test_ipf.py +0 -0
- {dit-2.1 → dit-2.2}/tests/algorithms/test_lattice.py +0 -0
- {dit-2.1 → dit-2.2}/tests/algorithms/test_marginal_constraints.py +0 -0
- {dit-2.1 → dit-2.2}/tests/algorithms/test_maxentropy_fast.py +0 -0
- {dit-2.1 → dit-2.2}/tests/algorithms/test_minimal_sufficient_statistic.py +0 -0
- {dit-2.1 → dit-2.2}/tests/algorithms/test_parallel_sweep.py +0 -0
- {dit-2.1 → dit-2.2}/tests/algorithms/test_prune_expand.py +0 -0
- {dit-2.1 → dit-2.2}/tests/algorithms/test_stats.py +0 -0
- {dit-2.1 → dit-2.2}/tests/channelorder/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/tests/channelorder/test_deficiency.py +0 -0
- {dit-2.1 → dit-2.2}/tests/channelorder/test_orderings.py +0 -0
- {dit-2.1 → dit-2.2}/tests/channelorder/test_properties.py +0 -0
- {dit-2.1 → dit-2.2}/tests/channelorder/test_utils.py +0 -0
- {dit-2.1 → dit-2.2}/tests/coding/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/tests/coding/test_base.py +0 -0
- {dit-2.1 → dit-2.2}/tests/coding/test_channel.py +0 -0
- {dit-2.1 → dit-2.2}/tests/coding/test_channel_codes.py +0 -0
- {dit-2.1 → dit-2.2}/tests/coding/test_edge_cases.py +0 -0
- {dit-2.1 → dit-2.2}/tests/coding/test_gf2.py +0 -0
- {dit-2.1 → dit-2.2}/tests/coding/test_golomb.py +0 -0
- {dit-2.1 → dit-2.2}/tests/coding/test_linear.py +0 -0
- {dit-2.1 → dit-2.2}/tests/coding/test_source_edges.py +0 -0
- {dit-2.1 → dit-2.2}/tests/coding/test_symbol_codes.py +0 -0
- {dit-2.1 → dit-2.2}/tests/coding/test_tunstall.py +0 -0
- {dit-2.1 → dit-2.2}/tests/coding/test_universal.py +0 -0
- {dit-2.1 → dit-2.2}/tests/conftest.py +0 -0
- {dit-2.1 → dit-2.2}/tests/divergences/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/tests/divergences/test_copy_mutual_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/divergences/test_cross_entropy.py +0 -0
- {dit-2.1 → dit-2.2}/tests/divergences/test_generalized_divergences.py +0 -0
- {dit-2.1 → dit-2.2}/tests/divergences/test_hypercontractivity_coefficient.py +0 -0
- {dit-2.1 → dit-2.2}/tests/divergences/test_jensen_shannon_divergence.py +0 -0
- {dit-2.1 → dit-2.2}/tests/divergences/test_kullback_leibler_divergence.py +0 -0
- {dit-2.1 → dit-2.2}/tests/divergences/test_maximum_correlation.py +0 -0
- {dit-2.1 → dit-2.2}/tests/divergences/test_nonmerge.py +0 -0
- {dit-2.1 → dit-2.2}/tests/divergences/test_variational_distance.py +0 -0
- {dit-2.1 → dit-2.2}/tests/example_channels/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/tests/example_channels/test_binary.py +0 -0
- {dit-2.1 → dit-2.2}/tests/example_channels/test_qary.py +0 -0
- {dit-2.1 → dit-2.2}/tests/example_channels/test_trivial.py +0 -0
- {dit-2.1 → dit-2.2}/tests/example_channels/test_util.py +0 -0
- {dit-2.1 → dit-2.2}/tests/example_dists/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/tests/example_dists/test_circuits.py +0 -0
- {dit-2.1 → dit-2.2}/tests/example_dists/test_dependencies.py +0 -0
- {dit-2.1 → dit-2.2}/tests/example_dists/test_dice.py +0 -0
- {dit-2.1 → dit-2.2}/tests/example_dists/test_giant_bit.py +0 -0
- {dit-2.1 → dit-2.2}/tests/example_dists/test_mdbsi.py +0 -0
- {dit-2.1 → dit-2.2}/tests/example_dists/test_miscellaneous.py +0 -0
- {dit-2.1 → dit-2.2}/tests/example_dists/test_n_mod_m.py +0 -0
- {dit-2.1 → dit-2.2}/tests/example_dists/test_numeric.py +0 -0
- {dit-2.1 → dit-2.2}/tests/example_dists/test_pr_box.py +0 -0
- {dit-2.1 → dit-2.2}/tests/inference/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/tests/inference/test_binning.py +0 -0
- {dit-2.1 → dit-2.2}/tests/inference/test_counts.py +0 -0
- {dit-2.1 → dit-2.2}/tests/inference/test_estimators.py +0 -0
- {dit-2.1 → dit-2.2}/tests/inference/test_knn_estimators.py +0 -0
- {dit-2.1 → dit-2.2}/tests/inference/test_segmentaxis.py +0 -0
- {dit-2.1 → dit-2.2}/tests/inference/test_timeseries.py +0 -0
- {dit-2.1 → dit-2.2}/tests/math/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/tests/math/test_aitchison.py +0 -0
- {dit-2.1 → dit-2.2}/tests/math/test_combinatorics.py +0 -0
- {dit-2.1 → dit-2.2}/tests/math/test_equal.py +0 -0
- {dit-2.1 → dit-2.2}/tests/math/test_fraction.py +0 -0
- {dit-2.1 → dit-2.2}/tests/math/test_misc.py +0 -0
- {dit-2.1 → dit-2.2}/tests/math/test_ops.py +0 -0
- {dit-2.1 → dit-2.2}/tests/math/test_pmfops.py +0 -0
- {dit-2.1 → dit-2.2}/tests/math/test_sampling.py +0 -0
- {dit-2.1 → dit-2.2}/tests/math/test_sigmaalgebra.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/common_informations/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/common_informations/test_backend_switching.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/common_informations/test_beta_common_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/common_informations/test_common_informations.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/common_informations/test_exact_common_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/common_informations/test_gk_common_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/common_informations/test_kamath_common_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/common_informations/test_maxent_function.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/common_informations/test_mss_common_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/common_informations/test_stochastic_gk_common_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/common_informations/test_wyner_common_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/secret_key_agreement/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/secret_key_agreement/test_interactive_intrinsic_mutual_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/secret_key_agreement/test_intrinsic_mutual_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/secret_key_agreement/test_lower_intrinsic_mutual_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/secret_key_agreement/test_minimal_intrinsic_mutual_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/secret_key_agreement/test_necessary_intrinsic_mutual_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/secret_key_agreement/test_reduced_intrinsic_mutual_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/secret_key_agreement/test_secrecy_capacity.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/secret_key_agreement/test_skars.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/secret_key_agreement/test_trivial_bounds.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/secret_key_agreement/test_two_part_intrinsic_mutual_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/secret_key_agreement/test_two_way_skar.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/test_caekl_mutual_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/test_cohesion.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/test_coinformation.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/test_deweese.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/test_dual_total_correlation.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/test_entropy.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/test_interaction_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/test_logarithmic_decomposition.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/test_mutual_informations.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/test_necessary_conditional_entropy.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/test_o_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/test_quax_synergy.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/test_synergistic_disclosure.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/test_total_correlation.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/test_transmission.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/test_tse_complexity.py +0 -0
- {dit-2.1 → dit-2.2}/tests/multivariate/test_union_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/other/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/tests/other/test_cumulative_residual_entropy.py +0 -0
- {dit-2.1 → dit-2.2}/tests/other/test_disequilibrium.py +0 -0
- {dit-2.1 → dit-2.2}/tests/other/test_extropy.py +0 -0
- {dit-2.1 → dit-2.2}/tests/other/test_lautum_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/other/test_perplexity.py +0 -0
- {dit-2.1 → dit-2.2}/tests/other/test_renyi_entropy.py +0 -0
- {dit-2.1 → dit-2.2}/tests/other/test_sibson_mutual_information.py +0 -0
- {dit-2.1 → dit-2.2}/tests/other/test_tsallis_entropy.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_hcs.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_hmos.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_ibroja.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_iccs.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_ict.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_ideg.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_idelta.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_idep.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_ido.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_igh.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_iig.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_iipid.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_imc.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_imes.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_imin.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_immi.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_ipm.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_iprec.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_iproj.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_irav.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_irdr.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_irr.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_iskar.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_isx.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_iwedge.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_modified_syndisc.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_pid_distribution.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_syndisc_fast.py +0 -0
- {dit-2.1 → dit-2.2}/tests/pid/test_syndisc_lattice.py +0 -0
- {dit-2.1 → dit-2.2}/tests/profiles/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/tests/profiles/test_base_profile.py +0 -0
- {dit-2.1 → dit-2.2}/tests/profiles/test_complexity_profile.py +0 -0
- {dit-2.1 → dit-2.2}/tests/profiles/test_entropy_triangle.py +0 -0
- {dit-2.1 → dit-2.2}/tests/profiles/test_information_partitions.py +0 -0
- {dit-2.1 → dit-2.2}/tests/profiles/test_mui.py +0 -0
- {dit-2.1 → dit-2.2}/tests/profiles/test_schneidman.py +0 -0
- {dit-2.1 → dit-2.2}/tests/profiles/test_shapley_info_decomposition.py +0 -0
- {dit-2.1 → dit-2.2}/tests/rate_distortion/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/tests/rate_distortion/test_gray_wyner.py +0 -0
- {dit-2.1 → dit-2.2}/tests/rate_distortion/test_rd.py +0 -0
- {dit-2.1 → dit-2.2}/tests/shannon/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/tests/shannon/test_shannon.py +0 -0
- {dit-2.1 → dit-2.2}/tests/test_abstractdist.py +0 -0
- {dit-2.1 → dit-2.2}/tests/test_bgm.py +0 -0
- {dit-2.1 → dit-2.2}/tests/test_cdisthelpers.py +0 -0
- {dit-2.1 → dit-2.2}/tests/test_distconst.py +0 -0
- {dit-2.1 → dit-2.2}/tests/test_distribution.py +0 -0
- {dit-2.1 → dit-2.2}/tests/test_distribution_coverage.py +0 -0
- {dit-2.1 → dit-2.2}/tests/test_exceptions.py +0 -0
- {dit-2.1 → dit-2.2}/tests/test_helpers.py +0 -0
- {dit-2.1 → dit-2.2}/tests/test_params.py +0 -0
- {dit-2.1 → dit-2.2}/tests/test_samplespace.py +0 -0
- {dit-2.1 → dit-2.2}/tests/test_validate.py +0 -0
- {dit-2.1 → dit-2.2}/tests/utils/__init__.py +0 -0
- {dit-2.1 → dit-2.2}/tests/utils/test_bindargs.py +0 -0
- {dit-2.1 → dit-2.2}/tests/utils/test_bindargs3.py +0 -0
- {dit-2.1 → dit-2.2}/tests/utils/test_context.py +0 -0
- {dit-2.1 → dit-2.2}/tests/utils/test_latexarray.py +0 -0
- {dit-2.1 → dit-2.2}/tests/utils/test_misc.py +0 -0
- {dit-2.1 → dit-2.2}/tests/utils/test_optimization.py +0 -0
- {dit-2.1 → dit-2.2}/tests/utils/test_table.py +0 -0
- {dit-2.1 → dit-2.2}/tests/utils/test_testing.py +0 -0
- {dit-2.1 → dit-2.2}/tests/utils/test_units.py +0 -0
{dit-2.1 → dit-2.2}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dit
|
|
3
|
-
Version: 2.
|
|
3
|
+
Version: 2.2
|
|
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
|
|
@@ -22,7 +22,7 @@ Classifier: Topic :: Scientific/Engineering :: Physics
|
|
|
22
22
|
Requires-Python: >=3.11
|
|
23
23
|
Requires-Dist: boltons
|
|
24
24
|
Requires-Dist: debtcollector
|
|
25
|
-
Requires-Dist: lattices>=0.5
|
|
25
|
+
Requires-Dist: lattices>=0.5
|
|
26
26
|
Requires-Dist: loguru
|
|
27
27
|
Requires-Dist: networkx>=2.6
|
|
28
28
|
Requires-Dist: numpy>=1.22
|
|
@@ -59,6 +59,7 @@ Requires-Dist: slsqp-jax; extra == 'dev'
|
|
|
59
59
|
Requires-Dist: sphinx; extra == 'dev'
|
|
60
60
|
Requires-Dist: sphinx-rtd-theme; extra == 'dev'
|
|
61
61
|
Requires-Dist: sphinxcontrib-bibtex; extra == 'dev'
|
|
62
|
+
Requires-Dist: sympy; extra == 'dev'
|
|
62
63
|
Requires-Dist: torch; extra == 'dev'
|
|
63
64
|
Requires-Dist: ty; extra == 'dev'
|
|
64
65
|
Provides-Extra: docs
|
|
@@ -70,17 +71,19 @@ Requires-Dist: nbconvert; extra == 'docs'
|
|
|
70
71
|
Requires-Dist: numdifftools; extra == 'docs'
|
|
71
72
|
Requires-Dist: pint; extra == 'docs'
|
|
72
73
|
Requires-Dist: pycddlib-standalone; extra == 'docs'
|
|
73
|
-
Requires-Dist: pypoman; extra == 'docs'
|
|
74
74
|
Requires-Dist: python-ternary; extra == 'docs'
|
|
75
75
|
Requires-Dist: scikit-learn; extra == 'docs'
|
|
76
76
|
Requires-Dist: sphinx; extra == 'docs'
|
|
77
77
|
Requires-Dist: sphinx-rtd-theme; extra == 'docs'
|
|
78
78
|
Requires-Dist: sphinxcontrib-bibtex; extra == 'docs'
|
|
79
|
+
Requires-Dist: sympy; extra == 'docs'
|
|
79
80
|
Provides-Extra: jax
|
|
80
81
|
Requires-Dist: jax; extra == 'jax'
|
|
81
82
|
Requires-Dist: jaxlib; extra == 'jax'
|
|
82
83
|
Requires-Dist: optimistix; extra == 'jax'
|
|
83
84
|
Requires-Dist: slsqp-jax; extra == 'jax'
|
|
85
|
+
Provides-Extra: music
|
|
86
|
+
Requires-Dist: music21; extra == 'music'
|
|
84
87
|
Provides-Extra: optional
|
|
85
88
|
Requires-Dist: colorama; extra == 'optional'
|
|
86
89
|
Requires-Dist: matplotlib; extra == 'optional'
|
|
@@ -91,6 +94,8 @@ Requires-Dist: pypoman; extra == 'optional'
|
|
|
91
94
|
Requires-Dist: scikit-learn; extra == 'optional'
|
|
92
95
|
Provides-Extra: pytensor
|
|
93
96
|
Requires-Dist: pytensor; extra == 'pytensor'
|
|
97
|
+
Provides-Extra: symbolic
|
|
98
|
+
Requires-Dist: sympy; extra == 'symbolic'
|
|
94
99
|
Provides-Extra: test
|
|
95
100
|
Requires-Dist: hypothesis>=6.0; extra == 'test'
|
|
96
101
|
Requires-Dist: hypothesis[numpy]; extra == 'test'
|
|
@@ -464,7 +469,7 @@ If you'd like to get in contact about anything, you can reach us through our `sl
|
|
|
464
469
|
:target: https://github.com/dit/dit/actions/workflows/build.yml
|
|
465
470
|
:alt: Continuous Integration Status
|
|
466
471
|
|
|
467
|
-
.. |codecov| image:: https://codecov.io/gh/dit/dit/branch/
|
|
472
|
+
.. |codecov| image:: https://codecov.io/gh/dit/dit/branch/main/graph/badge.svg
|
|
468
473
|
:target: https://codecov.io/gh/dit/dit
|
|
469
474
|
:alt: Test Coverage Status
|
|
470
475
|
|
{dit-2.1 → dit-2.2}/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
|
|
|
@@ -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
|
|
@@ -18,16 +18,21 @@ from boltons.iterutils import pairwise
|
|
|
18
18
|
from loguru import logger
|
|
19
19
|
from scipy.optimize import Bounds, basinhopping, brute, differential_evolution, dual_annealing, minimize, shgo
|
|
20
20
|
|
|
21
|
+
from ..algorithms.caekl_psp import (
|
|
22
|
+
caekl_mutual_information_psp_pmf,
|
|
23
|
+
caekl_mutual_information_psp_pmf_grad_data,
|
|
24
|
+
)
|
|
21
25
|
from ..algorithms.channelcapacity import channel_capacity
|
|
22
26
|
from ..distconst import insert_rvf, modify_outcomes
|
|
23
27
|
from ..distribution import Distribution
|
|
24
28
|
from ..exceptions import OptimizationException, ditException
|
|
25
29
|
from ..helpers import flatten, normalize_rvs, parse_rvs
|
|
26
30
|
from ..math import prod, sample_simplex
|
|
27
|
-
from ..utils import
|
|
31
|
+
from ..utils import powerset
|
|
28
32
|
from ..utils.optimization import (
|
|
29
33
|
BasinHoppingCallBack,
|
|
30
34
|
BasinHoppingInnerCallBack,
|
|
35
|
+
BoundedDisplacement,
|
|
31
36
|
Uniquifier,
|
|
32
37
|
accept_test,
|
|
33
38
|
basinhop_status,
|
|
@@ -610,6 +615,53 @@ class BaseOptimizer(metaclass=ABCMeta):
|
|
|
610
615
|
|
|
611
616
|
return dual_total_correlation
|
|
612
617
|
|
|
618
|
+
def _residual_entropy(self, rvs, crvs=None):
|
|
619
|
+
"""
|
|
620
|
+
Compute the residual entropy (variation of information).
|
|
621
|
+
|
|
622
|
+
Parameters
|
|
623
|
+
----------
|
|
624
|
+
rvs : set
|
|
625
|
+
The random variables to compute the residual entropy of.
|
|
626
|
+
crvs : set
|
|
627
|
+
The random variables to condition on.
|
|
628
|
+
|
|
629
|
+
Returns
|
|
630
|
+
-------
|
|
631
|
+
re : func
|
|
632
|
+
The residual entropy.
|
|
633
|
+
"""
|
|
634
|
+
if crvs is None:
|
|
635
|
+
crvs = set()
|
|
636
|
+
idx_joint = tuple(self._all_vars - (rvs | crvs))
|
|
637
|
+
idx_margs = [tuple(self._all_vars - ((rvs - {rv}) | crvs)) for rv in rvs]
|
|
638
|
+
idx_crvs = tuple(self._all_vars - crvs)
|
|
639
|
+
|
|
640
|
+
def residual_entropy(pmf):
|
|
641
|
+
"""
|
|
642
|
+
Compute the specified residual entropy.
|
|
643
|
+
|
|
644
|
+
Parameters
|
|
645
|
+
----------
|
|
646
|
+
pmf : np.ndarray
|
|
647
|
+
The joint probability distribution.
|
|
648
|
+
|
|
649
|
+
Returns
|
|
650
|
+
-------
|
|
651
|
+
re : float
|
|
652
|
+
The residual entropy.
|
|
653
|
+
"""
|
|
654
|
+
pmf_joint = pmf.sum(axis=idx_joint, keepdims=True)
|
|
655
|
+
pmf_margs = [pmf_joint.sum(axis=marg, keepdims=True) for marg in idx_margs]
|
|
656
|
+
pmf_crvs = pmf_joint.sum(axis=idx_crvs, keepdims=True)
|
|
657
|
+
|
|
658
|
+
h_crvs = self._h(pmf_crvs)
|
|
659
|
+
h_margs = [self._h(marg) - h_crvs for marg in pmf_margs]
|
|
660
|
+
|
|
661
|
+
return sum(h_margs)
|
|
662
|
+
|
|
663
|
+
return residual_entropy
|
|
664
|
+
|
|
613
665
|
###########################################################################
|
|
614
666
|
# Analytic gradients of the objective building blocks.
|
|
615
667
|
#
|
|
@@ -755,6 +807,21 @@ class BaseOptimizer(metaclass=ABCMeta):
|
|
|
755
807
|
|
|
756
808
|
return grad
|
|
757
809
|
|
|
810
|
+
def _residual_entropy_grad(self, rvs, crvs=None):
|
|
811
|
+
"""Gradient builder for :meth:`_residual_entropy`."""
|
|
812
|
+
if crvs is None:
|
|
813
|
+
crvs = set()
|
|
814
|
+
idx_margs = [tuple(self._all_vars - ((rvs - {rv}) | crvs)) for rv in rvs]
|
|
815
|
+
idx_crvs = tuple(self._all_vars - crvs)
|
|
816
|
+
n = len(rvs)
|
|
817
|
+
|
|
818
|
+
def grad(pmf):
|
|
819
|
+
g = sum(self._marginal_entropy_grad(pmf, marg) for marg in idx_margs)
|
|
820
|
+
g = g - n * self._marginal_entropy_grad(pmf, idx_crvs)
|
|
821
|
+
return self._full_grad(g, pmf)
|
|
822
|
+
|
|
823
|
+
return grad
|
|
824
|
+
|
|
758
825
|
def _caekl_mutual_information(self, rvs, crvs=None):
|
|
759
826
|
"""
|
|
760
827
|
Compute the CAEKL mutual information.
|
|
@@ -773,15 +840,6 @@ class BaseOptimizer(metaclass=ABCMeta):
|
|
|
773
840
|
"""
|
|
774
841
|
if crvs is None:
|
|
775
842
|
crvs = set()
|
|
776
|
-
parts = [p for p in partitions(rvs) if len(p) > 1]
|
|
777
|
-
idx_parts = {}
|
|
778
|
-
for part in parts:
|
|
779
|
-
for p in part:
|
|
780
|
-
if p not in idx_parts:
|
|
781
|
-
idx_parts[p] = tuple(self._all_vars - (p | crvs))
|
|
782
|
-
part_norms = [len(part) - 1 for part in parts]
|
|
783
|
-
idx_joint = tuple(self._all_vars - (rvs | crvs))
|
|
784
|
-
idx_crvs = tuple(self._all_vars - crvs)
|
|
785
843
|
|
|
786
844
|
def caekl_mutual_information(pmf):
|
|
787
845
|
"""
|
|
@@ -797,19 +855,14 @@ class BaseOptimizer(metaclass=ABCMeta):
|
|
|
797
855
|
caekl : float
|
|
798
856
|
The CAEKL mutual information.
|
|
799
857
|
"""
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
|
|
807
|
-
|
|
808
|
-
candidates = [(sum(self._h(pmf_parts[p]) - h_crvs for p in part) - h_joint) / norm for part, norm in pairs]
|
|
809
|
-
|
|
810
|
-
caekl = min(candidates)
|
|
811
|
-
|
|
812
|
-
return caekl
|
|
858
|
+
return caekl_mutual_information_psp_pmf(
|
|
859
|
+
pmf,
|
|
860
|
+
all_vars=self._all_vars,
|
|
861
|
+
rvs=rvs,
|
|
862
|
+
crvs=crvs,
|
|
863
|
+
h=self._h,
|
|
864
|
+
sum_axes=lambda p, idx: p.sum(axis=idx, keepdims=True),
|
|
865
|
+
)
|
|
813
866
|
|
|
814
867
|
return caekl_mutual_information
|
|
815
868
|
|
|
@@ -824,34 +877,20 @@ class BaseOptimizer(metaclass=ABCMeta):
|
|
|
824
877
|
"""
|
|
825
878
|
if crvs is None:
|
|
826
879
|
crvs = set()
|
|
827
|
-
parts = [p for p in partitions(rvs) if len(p) > 1]
|
|
828
|
-
idx_parts = {}
|
|
829
|
-
for part in parts:
|
|
830
|
-
for p in part:
|
|
831
|
-
if p not in idx_parts:
|
|
832
|
-
idx_parts[p] = tuple(self._all_vars - (p | crvs))
|
|
833
|
-
part_norms = [len(part) - 1 for part in parts]
|
|
834
|
-
idx_joint = tuple(self._all_vars - (rvs | crvs))
|
|
835
|
-
idx_crvs = tuple(self._all_vars - crvs)
|
|
836
880
|
|
|
837
881
|
def grad(pmf):
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
847
|
-
candidates = [(sum(self._h(pmf_parts[p]) - h_crvs for p in part) - h_joint) / norm for part, norm in pairs]
|
|
848
|
-
|
|
849
|
-
idx_min = min(range(len(candidates)), key=lambda i: candidates[i])
|
|
850
|
-
part, norm = pairs[idx_min]
|
|
882
|
+
_, partition, idx_joint, idx_crvs, idx_parts = caekl_mutual_information_psp_pmf_grad_data(
|
|
883
|
+
pmf,
|
|
884
|
+
all_vars=self._all_vars,
|
|
885
|
+
rvs=rvs,
|
|
886
|
+
crvs=crvs,
|
|
887
|
+
h=self._h,
|
|
888
|
+
sum_axes=lambda p, idx: p.sum(axis=idx, keepdims=True),
|
|
889
|
+
)
|
|
890
|
+
norm = len(partition) - 1
|
|
851
891
|
|
|
852
|
-
|
|
853
|
-
g =
|
|
854
|
-
g = g - (len(part) - 1) * self._marginal_entropy_grad(pmf, idx_crvs)
|
|
892
|
+
g = sum(self._marginal_entropy_grad(pmf, idx_parts[block]) for block in partition)
|
|
893
|
+
g = g - norm * self._marginal_entropy_grad(pmf, idx_crvs)
|
|
855
894
|
g = g - self._marginal_entropy_grad(pmf, idx_joint)
|
|
856
895
|
g = g / norm
|
|
857
896
|
return self._full_grad(g, pmf)
|
|
@@ -1375,6 +1414,7 @@ class BaseNonConvexOptimizer(BaseOptimizer):
|
|
|
1375
1414
|
minimizer_kwargs=minimizer_kwargs,
|
|
1376
1415
|
niter=niter,
|
|
1377
1416
|
accept_test=accept_test,
|
|
1417
|
+
take_step=BoundedDisplacement(rng=self._rng),
|
|
1378
1418
|
callback=self._callback,
|
|
1379
1419
|
**bh_kwargs,
|
|
1380
1420
|
)
|
|
@@ -1384,6 +1424,20 @@ class BaseNonConvexOptimizer(BaseOptimizer):
|
|
|
1384
1424
|
if not success: # pragma: no cover
|
|
1385
1425
|
result = self._callback.minimum() or res_shotgun
|
|
1386
1426
|
|
|
1427
|
+
if result is None:
|
|
1428
|
+
# Basin hopping reported failure and neither the callback minima nor
|
|
1429
|
+
# the (optional) seeding shotgun yielded a usable point. On
|
|
1430
|
+
# near-degenerate distributions (e.g. probabilities ~1e-8 that are
|
|
1431
|
+
# not subnormal, so they survive the test strategy's denormal
|
|
1432
|
+
# filter) this happens intermittently depending on the random
|
|
1433
|
+
# starts, producing flaky "No optima found" failures even though the
|
|
1434
|
+
# problem is solvable. Fall back to a many-start shotgun, which
|
|
1435
|
+
# tolerates SLSQP's spurious ``success=False`` at feasible optima via
|
|
1436
|
+
# ``_best_feasible``. This never overrides a result that already
|
|
1437
|
+
# succeeded.
|
|
1438
|
+
logger.debug("Basin hopping produced no result; retrying with shotgun fallback")
|
|
1439
|
+
result = self._optimize_shotgun(x0, minimizer_kwargs, niter=max(25, niter))
|
|
1440
|
+
|
|
1387
1441
|
return result
|
|
1388
1442
|
|
|
1389
1443
|
def _optimization_diffevo(self, x0, minimizer_kwargs, niter): # pragma: no cover
|