py3plex 1.1.3__tar.gz → 1.1.5__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.
- {py3plex-1.1.3/py3plex.egg-info → py3plex-1.1.5}/PKG-INFO +6 -3
- {py3plex-1.1.3 → py3plex-1.1.5}/README.md +3 -2
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/__init__.py +14 -2
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algebra/backend.py +9 -0
- py3plex-1.1.5/py3plex/algebra/registry.py +119 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/advanced_random_generators.py +110 -34
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/attribute_correlation.py +5 -5
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/centrality/approx_pagerank.py +23 -15
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/auto_select.py +9 -2
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/autocommunity_executor.py +12 -4
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/leiden_uq.py +11 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/runner.py +2 -2
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/node_ranking/node_ranking.py +2 -2
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/statistics/enrichment_modules.py +1 -1
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/cli.py +161 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/config.py +30 -2
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/core/multinet.py +309 -13
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/core/parsers.py +7 -7
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/core/random_generators.py +12 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/counterexamples/__init__.py +7 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/counterfactual/engine.py +3 -3
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/__init__.py +38 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/ast.py +420 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/builder.py +422 -9
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/errors.py +20 -1
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/executor.py +365 -18
- py3plex-1.1.5/py3plex/dsl/fastpath.py +655 -0
- py3plex-1.1.5/py3plex/dsl/predictive.py +692 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/provenance.py +5 -2
- py3plex-1.1.5/py3plex/dsl/reduction.py +420 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/registry.py +3 -3
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/result.py +167 -1
- py3plex-1.1.5/py3plex/embeddings/__init__.py +25 -0
- py3plex-1.1.5/py3plex/embeddings/base.py +719 -0
- py3plex-1.1.5/py3plex/embeddings/cache.py +146 -0
- py3plex-1.1.5/py3plex/embeddings/link_ops.py +155 -0
- py3plex-1.1.5/py3plex/embeddings/metapath2vec.py +614 -0
- py3plex-1.1.5/py3plex/embeddings/netmf.py +420 -0
- py3plex-1.1.5/py3plex/ergonomics.py +388 -0
- py3plex-1.1.5/py3plex/experiments/__init__.py +115 -0
- py3plex-1.1.5/py3plex/experiments/artifacts.py +217 -0
- py3plex-1.1.5/py3plex/experiments/cli.py +330 -0
- py3plex-1.1.5/py3plex/experiments/env.py +75 -0
- py3plex-1.1.5/py3plex/experiments/errors.py +25 -0
- py3plex-1.1.5/py3plex/experiments/model.py +304 -0
- py3plex-1.1.5/py3plex/experiments/runner.py +166 -0
- py3plex-1.1.5/py3plex/experiments/store.py +231 -0
- py3plex-1.1.5/py3plex/experiments/utils.py +71 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/graph_ops.py +32 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/io/multinet_bridge.py +58 -126
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/io/parquet_format.py +25 -6
- py3plex-1.1.5/py3plex/ml/__init__.py +2 -0
- py3plex-1.1.5/py3plex/ml/embedding/__init__.py +27 -0
- py3plex-1.1.5/py3plex/ml/embedding/base.py +8 -0
- py3plex-1.1.5/py3plex/ml/embedding/deepwalk.py +37 -0
- py3plex-1.1.5/py3plex/ml/embedding/evaluation.py +55 -0
- py3plex-1.1.5/py3plex/ml/embedding/line.py +87 -0
- py3plex-1.1.5/py3plex/ml/embedding/metapath2vec.py +73 -0
- py3plex-1.1.5/py3plex/ml/embedding/multiplex.py +95 -0
- py3plex-1.1.5/py3plex/ml/embedding/netmf.py +70 -0
- py3plex-1.1.5/py3plex/ml/embedding/node2vec.py +90 -0
- py3plex-1.1.5/py3plex/ml/embedding/similarity.py +25 -0
- py3plex-1.1.5/py3plex/ml/embedding/trainer.py +141 -0
- py3plex-1.1.5/py3plex/ml/embedding/utils.py +149 -0
- py3plex-1.1.5/py3plex/optimizer/__init__.py +93 -0
- py3plex-1.1.5/py3plex/optimizer/cost_model.py +274 -0
- py3plex-1.1.5/py3plex/optimizer/logical_plan.py +188 -0
- py3plex-1.1.5/py3plex/optimizer/optimizer.py +188 -0
- py3plex-1.1.5/py3plex/optimizer/physical_plan.py +460 -0
- py3plex-1.1.5/py3plex/optimizer/plan_nodes.py +277 -0
- py3plex-1.1.5/py3plex/optimizer/rules.py +552 -0
- py3plex-1.1.5/py3plex/out_of_core/__init__.py +50 -0
- py3plex-1.1.5/py3plex/out_of_core/cli.py +378 -0
- py3plex-1.1.5/py3plex/out_of_core/errors.py +51 -0
- py3plex-1.1.5/py3plex/out_of_core/executor.py +865 -0
- py3plex-1.1.5/py3plex/out_of_core/network.py +405 -0
- py3plex-1.1.5/py3plex/out_of_core/operators.py +330 -0
- py3plex-1.1.5/py3plex/out_of_core/readers.py +308 -0
- py3plex-1.1.5/py3plex/out_of_core/schema.py +87 -0
- py3plex-1.1.5/py3plex/out_of_core/spill.py +280 -0
- py3plex-1.1.5/py3plex/out_of_core/utils.py +90 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/pipeline.py +184 -12
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/provenance/schema.py +20 -2
- py3plex-1.1.5/py3plex/runtime/__init__.py +5 -0
- py3plex-1.1.5/py3plex/runtime/capabilities.py +344 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/selection/community_registry.py +17 -2
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/selection/result.py +5 -5
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/semiring/__init__.py +4 -1
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/selection_execution.py +8 -3
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/utils.py +38 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/visualization/colors.py +2 -2
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/workflows.py +2 -12
- {py3plex-1.1.3 → py3plex-1.1.5/py3plex.egg-info}/PKG-INFO +6 -3
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex.egg-info/SOURCES.txt +95 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex.egg-info/requires.txt +2 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex_mcp/__init__.py +2 -2
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex_mcp/server.py +35 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/pyproject.toml +4 -1
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_agents_ergonomics_features.py +3 -3
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_agents_golden_paths.py +1 -1
- py3plex-1.1.5/tests/test_algebra_backend.py +105 -0
- py3plex-1.1.5/tests/test_algebra_fixed_point.py +228 -0
- py3plex-1.1.5/tests/test_algebra_registry.py +210 -0
- py3plex-1.1.5/tests/test_algebra_witness.py +289 -0
- py3plex-1.1.5/tests/test_algorithms_correlation_networks.py +342 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_algorithms_random_generators.py +12 -11
- py3plex-1.1.5/tests/test_algorithms_statistics_bayesian_distances.py +244 -0
- py3plex-1.1.5/tests/test_autocommunity_executor.py +540 -0
- py3plex-1.1.5/tests/test_autocommunity_successive_halving.py +348 -0
- py3plex-1.1.5/tests/test_bayesian_distances.py +179 -0
- py3plex-1.1.5/tests/test_benchmarks_budget.py +261 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_book_conf.py +1 -1
- py3plex-1.1.5/tests/test_book_manuscript_integrity.py +53 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_book_snippets.py +55 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_builder_dsl_mutate.py +14 -14
- py3plex-1.1.5/tests/test_capabilities_basic.py +416 -0
- py3plex-1.1.5/tests/test_capabilities_optional_missing.py +256 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_cli_check.py +1 -1
- py3plex-1.1.5/tests/test_comparison_executor.py +324 -0
- py3plex-1.1.5/tests/test_comparison_result.py +532 -0
- py3plex-1.1.5/tests/test_contracts_failure_modes.py +182 -0
- py3plex-1.1.5/tests/test_correlation_networks.py +161 -0
- py3plex-1.1.5/tests/test_diagnostics_utils.py +237 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_doc_conf.py +9 -1
- py3plex-1.1.5/tests/test_docs_embeddings_section.py +33 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_docs_examples.py +13 -3
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_community_filtering.py +1 -1
- py3plex-1.1.5/tests/test_dsl_patterns_quick_reference.py +128 -0
- py3plex-1.1.5/tests/test_dsl_predict_reduce.py +237 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_query_zoo.py +2 -2
- py3plex-1.1.5/tests/test_dsl_selection_fastpath.py +286 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_v2.py +17 -0
- py3plex-1.1.5/tests/test_dynamics_utils.py +276 -0
- py3plex-1.1.5/tests/test_ergonomic_helpers.py +276 -0
- py3plex-1.1.5/tests/test_examples_zoo_consolidation.py +34 -0
- py3plex-1.1.5/tests/test_experiments.py +481 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_explain_attribution.py +282 -0
- py3plex-1.1.5/tests/test_fast_examples.py +188 -0
- py3plex-1.1.5/tests/test_hedwig_significance.py +173 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_io_arrow.py +2 -2
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_io_roundtrip.py +7 -7
- py3plex-1.1.5/tests/test_link_checker.py +154 -0
- py3plex-1.1.5/tests/test_metapath2vec.py +218 -0
- py3plex-1.1.5/tests/test_ml_embedding_primitives.py +319 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_multilayer_visualizations.py +4 -4
- py3plex-1.1.5/tests/test_network_version.py +184 -0
- py3plex-1.1.5/tests/test_out_of_core.py +1241 -0
- py3plex-1.1.5/tests/test_paths_executor.py +379 -0
- py3plex-1.1.5/tests/test_paths_result.py +436 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_pymnet_style.py +2 -2
- py3plex-1.1.5/tests/test_query_equivalence.py +415 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_random_generators_additional.py +21 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_roundtrip_invariants.py +13 -13
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_sbm_autocommunity.py +8 -8
- py3plex-1.1.5/tests/test_sbm_metrics.py +175 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_sbm_runner_integration.py +8 -8
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_selection_uq_empty_groups.py +2 -2
- py3plex-1.1.5/tests/test_semiring_registry.py +234 -0
- py3plex-1.1.5/tests/test_semiring_types.py +302 -0
- py3plex-1.1.5/tests/test_stats_provenance.py +270 -0
- py3plex-1.1.5/tests/test_stats_provenance_dataclass.py +287 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_temporal_utils_extended.py +10 -10
- py3plex-1.1.5/tests/test_uncertainty_runner.py +553 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_uq_algebra.py +231 -1
- py3plex-1.1.5/tests/test_user_journey_simulation.py +69 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_utils.py +100 -0
- py3plex-1.1.5/tests/test_version_consistency.py +44 -0
- py3plex-1.1.3/py3plex/algebra/registry.py +0 -121
- {py3plex-1.1.3 → py3plex-1.1.5}/LICENSE +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/MANIFEST.in +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/__main__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/_parallel.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algebra/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algebra/closure.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algebra/fixed_point.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algebra/lift.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algebra/paths.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algebra/semiring.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algebra/witness.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/centrality/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/centrality/approx_betweenness.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/centrality/approx_closeness.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/centrality/explain.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/centrality_toolkit.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_comparison.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/NoRC.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/autocommunity.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/budget.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/community_louvain.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/community_measures.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/community_ranking.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/community_wrapper.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/distributional.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/flow_hierarchy.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/infomap/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/infomap/conftest.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/infomap/examples/python/example-bipartite.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/infomap/examples/python/example-file-io.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/infomap/examples/python/example-multiplex.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/infomap/examples/python/example-networkx.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/infomap/examples/python/example-simple.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/infomap/examples/python/example-trigram-expanded.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/infomap/examples/python/example-trigram.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/infomap/infomap.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/infomap/interfaces/python/setup.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/label_propagation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/leiden_multilayer.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/multilayer_benchmark.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/multilayer_modularity.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/multilayer_quality_metrics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/node_ranking.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/sbm_metrics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/sbm_wrapper.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/spectral_multilayer.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/community_detection/successive_halving.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/curvature/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/curvature/ollivier_ricci_multilayer.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/general/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/general/benchmark_classification.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/general/walkers.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/graph_summarization.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/__main__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/assets/builtin.n3 +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/core/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/core/converters.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/core/example.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/core/helpers.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/core/kb.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/core/load.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/core/predicate.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/core/rule.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/core/settings.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/core/term_parsers.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/learners/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/learners/bottomup.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/learners/learner.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/learners/optimal.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/stats/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/stats/adjustment.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/stats/scorefunctions.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/stats/significance.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/hedwig/stats/validate.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/layer_similarity.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/meta_flow_report.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/multicentrality.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/multilayer_algorithms/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/multilayer_algorithms/centrality.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/multilayer_algorithms/entanglement.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/multilayer_algorithms/multirank.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/multilayer_algorithms/multixrank.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/multilayer_algorithms/supra_matrix_function_centrality.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/multilayer_algorithms/versatility.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/multilayer_clustering.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/network_classification/PPR.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/network_classification/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/network_classification/label_propagation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/node_ranking/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/requirements_registry.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/robustness_testing.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/routing/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/routing/multiplex_paths.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/sbm/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/sbm/conversions.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/sbm/diagnostics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/sbm/inference_vi.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/sbm/model_selection.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/sbm/multilayer_sbm.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/sbm/objectives.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/sbm/uq.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/sbm/utils.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/sir_multiplex.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/statistical_report.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/statistics/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/statistics/basic_statistics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/statistics/bayesian_distances.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/statistics/bayesiantests.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/statistics/correlation_networks.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/statistics/critical_distances.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/statistics/multilayer_statistics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/statistics/powerlaw.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/statistics/stats_comparison.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/statistics/topology.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/temporal/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/temporal/centrality.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/temporal/community.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/temporal_multiplex/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/algorithms/term_parsers/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/alignment/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/alignment/features.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/alignment/metrics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/alignment/solvers.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/benchmarks/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/benchmarks/budget.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/benchmarks/metrics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/benchmarks/runners.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/centrality/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/centrality/robustness.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/claims/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/claims/generator.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/claims/learner.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/claims/scorer.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/claims/types.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/comparison/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/comparison/executor.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/comparison/metrics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/comparison/result.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/compat/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/compat/convert.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/compat/converters/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/compat/converters/dgl_converter.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/compat/converters/igraph_converter.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/compat/converters/networkx_converter.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/compat/converters/pyg_converter.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/compat/converters/scipy_converter.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/compat/equality.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/compat/exceptions.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/compat/ir.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/compat/schema.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/compat/sidecar.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/contracts/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/contracts/contract.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/contracts/engine.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/contracts/failure_modes.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/contracts/predicates.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/contracts/result.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/core/HINMINE/IO.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/core/HINMINE/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/core/HINMINE/dataStructures.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/core/HINMINE/decomposition.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/core/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/core/converters.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/core/immutable.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/core/lazy_evaluation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/core/nx_compat.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/core/schema_validation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/core/supporting.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/core/temporal_multinet.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/core/types.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/counterexamples/claim_lang.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/counterexamples/ddmin.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/counterexamples/engine.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/counterexamples/types.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/counterexamples/witness.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/counterfactual/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/counterfactual/comparator.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/counterfactual/presets.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/counterfactual/result.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/counterfactual/spec.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/datasets/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/datasets/_data/aarhus_cs.edges +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/datasets/_data/synthetic_multilayer.edges +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/datasets/_generators.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/datasets/_loaders.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/diagnostics/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/diagnostics/builders.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/diagnostics/codes.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/diagnostics/core.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/diagnostics/utils.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/algebra.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/attribution.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/benchmark.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/benchmark_result.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/cache.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/communities.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/community_uq.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/compositional_uq.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/context.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/executor_semiring.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/executors/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/executors/benchmark_executor.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/explain.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/export.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/expressions.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/layers.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/lint/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/lint/diagnostic.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/lint/lint_context.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/lint/rules/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/lint/rules/base.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/lint/rules/dsl001_unknown_layer.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/lint/rules/dsl002_unknown_attribute.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/lint/rules/dsl101_type_mismatch.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/lint/rules/dsl201_unsatisfiable.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/lint/rules/dsl202_redundant.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/lint/rules/perf301_full_scan.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/lint/rules/perf302_cross_layer.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/lint/schema.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/lint/type_resolver.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/lint/types.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/operator_registry.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/patterns/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/patterns/builder.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/patterns/compiler.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/patterns/engine.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/patterns/ir.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/patterns/result.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/planner.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/program/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/program/cache.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/program/cost.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/program/diff.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/program/distribution.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/program/executor.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/program/explain.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/program/program.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/program/rewrite.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/program/types.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/selection_uq.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/serializer.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/uq_algebra.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/uq_resolution.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl/warnings.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dsl_legacy.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dynamics/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dynamics/_utils.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dynamics/ast.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dynamics/builder.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dynamics/compartmental.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dynamics/config.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dynamics/core.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dynamics/errors.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dynamics/executor.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dynamics/models.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dynamics/processes.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dynamics/registry.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dynamics/result.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/dynamics/serializer.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/errors.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/exceptions.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/fast_examples.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/io/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/io/api.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/io/canonical_format.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/io/converters.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/io/exceptions.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/io/formats/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/io/formats/arrow_format.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/io/formats/csv_format.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/io/formats/json_format.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/io/schema.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/lab/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/lab/base.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/linter.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/logging_config.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/meta/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/meta/builder.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/meta/result.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/meta/stats.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/meta/utils.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/multinet/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/multinet/aggregation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/nullmodels/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/nullmodels/executor.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/nullmodels/models.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/nullmodels/result.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/paths/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/paths/algorithms.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/paths/executor.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/paths/result.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/plugins/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/plugins/base.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/plugins/examples.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/plugins/registry.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/profiling.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/provenance/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/provenance/bundle.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/provenance/capture.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/provenance/replay.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/requirements.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/robustness/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/robustness/experiments.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/robustness/perturbations.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/selection/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/selection/capabilities.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/selection/evaluate.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/selection/metric_registry.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/selection/wins.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/semiring/core.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/semiring/engine.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/semiring/pareto.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/semiring/registry.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/semiring/types.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/sensitivity/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/sensitivity/executor.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/sensitivity/metrics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/sensitivity/perturbations.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/sensitivity/types.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/stats/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/stats/provenance.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/stats/registry.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/stats/statvalue.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/stats/uncertainty.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/temporal_utils.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/temporal_utils_extended.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/temporal_view.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/bootstrap.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/ci_utils.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/community_ensemble.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/community_result.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/context.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/estimation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/noise_models.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/null_models.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/partition.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/partition_metrics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/partition_reducers.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/partition_types.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/partition_uq.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/plan.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/reducers/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/reducers/base.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/resampling_graph.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/runner.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/selection_reducers.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/selection_types.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/selection_uq.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/stratification.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/uncertainty/types.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/validation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/visualization/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/visualization/benchmark_visualizations.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/visualization/bezier.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/visualization/drawing_machinery.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/visualization/embedding_visualization/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/visualization/embedding_visualization/embedding_tools.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/visualization/embedding_visualization/embedding_visualization.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/visualization/fa2/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/visualization/fa2/fa2util.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/visualization/fa2/forceatlas2.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/visualization/layout_algorithms.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/visualization/multilayer.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/visualization/polyfit.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/visualization/pymnet_style.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/visualization/ricci_layout.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/visualization/ricci_multilayer_vis.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/visualization/sankey.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/wrappers/__init__.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/wrappers/benchmark_nodes.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/wrappers/r_interop.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex/wrappers/train_node2vec_embedding.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex.egg-info/dependency_links.txt +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex.egg-info/entry_points.txt +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex.egg-info/not-zip-safe +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex.egg-info/top_level.txt +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex_mcp/errors.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex_mcp/registry.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex_mcp/safe_paths.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/py3plex_mcp/schemas.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/setup.cfg +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_advanced_metrics_properties.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_aggregation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_algebra_core.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_algebra_paths.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_algorithm_properties.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_algorithms_attribute_correlation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_algorithms_init.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_alignment.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_alignment_contracts.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_alignment_correctness_additional.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_approximate_centrality.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_ast_roundtrip.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_ast_roundtrip_integration.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_attribute_correlation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_attribute_correlation_contracts.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_auto_community.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_autocommunity_benchmarks.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_autocommunity_meta.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_bench_aggregation_unit.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_benchmark_budget_fairness.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_benchmark_dsl_basic.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_benchmark_integration.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_benchmark_multiplex_centrality.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_benchmark_time.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_benchmarks_init.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_centrality_explain.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_centrality_explain_integration.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_centrality_robustness.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_centrality_robustness_oracles.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_centrality_uncertainty.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_centrality_weight_handling.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_check_api_consistency.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_check_doc_coverage.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_check_type_coverage.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_claim_learning.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_claims_types.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_cli.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_cli_ergonomics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_cli_piping.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_clustering_multilayer.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_code_improvements.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_community_detection_modules.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_community_distribution.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_community_measures.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_comparison.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_comparison_metrics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_comparison_metrics_additional.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_comparison_uninitialized_and_resistance_oracles.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_compat_exceptions.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_compat_roundtrip.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_config_api.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_config_benchmark.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_contracts.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_contracts_basic.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_contracts_extended.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_contracts_integration.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_core_functionality.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_core_immutable.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_core_lazy_evaluation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_core_multinet_and_parsers.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_core_multinet_correctness.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_core_multiplex_edges.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_core_schema_validation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_core_supporting.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_counterexamples.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_counterexamples_properties.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_counterfactual.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_counterfactual_presets.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_coverage_grouping.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_create_mosaic_banner.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_create_showcase_flow.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_crosshair_pure_functions.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_data_files_presence.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_datasets.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_datasets_contracts.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_datasets_oracles.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_degenerate_networks.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_determinism_randomness.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_diagnostics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_doctests.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dplyr_integration.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_aggregation_enhancements.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_ast_equivalence.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_auto_community.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_communities.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_community_uq_integration.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_compact_compute.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_compositional_uq.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_condition_semantics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_d_factory.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_documentation_examples.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_dplyr_style.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_dynamics_integration.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_edge_grouping_coverage.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_edge_queries.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_enhancements.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_ergonomics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_errors.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_errors_extended.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_executor_additional.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_explain.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_export.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_expressions.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_extensions.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_graphops_equivalence.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_grouping_coverage.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_interactive.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_joins.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_layer_selection.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_layer_set_algebra.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_legacy_edges.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_lint.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_operators.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_patterns.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_pipes.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_planner.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_program_rewrite.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_program_types.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_progress_logging.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_properties.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_provenance.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_query_optimization.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_semiring_integration.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_serializer.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_smart_defaults.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_temporal_range_execution.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_uncertainty.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_uq_ergonomics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_uq_propagation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dsl_zoo_features.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dynamics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dynamics_algorithm_contracts.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dynamics_config_and_results_correctness.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dynamics_conservation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dynamics_core.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dynamics_executor_edge_cases.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dynamics_parallel_determinism.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dynamics_reference_runs.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_dynamics_uq_integration.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_edge_cases.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_edgelist_format.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_ergonomics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_errors.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_CBSSD.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_community_detection.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_decomposition_and_classification.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_decomposition_ground_truth.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_dsl_builder_api.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_dynamics_core_examples.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_embedding_construction.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_embedding_visualization.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_incidence_gadget_encoding.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_inverse_network.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_layer_extraction.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_manipulation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_multilayer_vectorized_aggregation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_multiplex_aggregate.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_multiplex_dynamics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_n2v_embedding.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_network_decomposition.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_network_decomposition_meta_paths.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_numeric_encoding.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_pattern_matching.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_example_ppr.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_exception_taxonomy.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_exceptions.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_flagship_progress_demo.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_flow_hierarchy.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_fuzzing_properties.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_generate_all_outputs.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_generate_quickstart_outputs.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_generate_visualization_images.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_golden_toy_examples.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_graph_ops.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_graph_summarization.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_hedwig_adjustment.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_improved_errors.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_incidence_gadget_encoding.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_infomap_fix.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_interlayer_links_fix.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_io_api_edge_cases.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_io_contracts_additional.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_io_converters.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_io_exceptions.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_io_integration.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_io_schema.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_issue_19_fix.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_lab.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_lab_additional.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_lab_correctness.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_label_propagation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_layer_extraction_fix.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_layer_similarity.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_layout_algorithms.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_lazy_evaluation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_leiden_multilayer.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_linter.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_logging_conversion.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_main_module.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_master_regulators_example.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_math_invariants.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_mcp_server.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_meta_analysis.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_meta_flow_report.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_metamorphic.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_monoplex_nx_wrapper.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_mpc.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_multilayer_centrality.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_multilayer_clustering_coefficients.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_multilayer_cornercases.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_multilayer_edge_fix.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_multilayer_integration.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_multilayer_leiden_uq.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_multilayer_modularity.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_multilayer_quality_metrics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_multilayer_statistics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_multinet_aggregation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_multinet_aggregation_additional.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_multiplex_layer_interop.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_multiplex_participation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_multiplex_properties.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_multirank.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_multixrank.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_network_conversion.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_networkx_compatibility.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_new_algorithms.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_new_multilayer_metrics.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_node_edge_parity.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_node_ranking_comprehensive.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_norc.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_nullmodel_sanity.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_nullmodels.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_nullmodels_contracts.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_nx_compat_extended.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_ollivier_ricci_multilayer.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_parallel.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_parallel_execution.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_parsers_comprehensive.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_parsers_coverage.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_partition_uq.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_partition_uq_integration.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_paths.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_paths_additional.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_paths_contracts.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_performance_core.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_pipeline.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_plugin_examples.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_plugin_system.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_plugins.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_plugins_contracts.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_profiling.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_program.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_program_cost_executor.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_properties.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_provenance_canonical.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_provenance_replay.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_provenance_schema.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_query_algebra.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_r_interop.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_random_generators_extended.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_random_walkers.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_random_walks.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_readme_flagship_example.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_requirements.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_result_explain_debug.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_ricci_visualization.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_robustness.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_robustness_additional.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_robustness_testing.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_root_conftest.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_run_quickstart_snippets.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_sankey_visualization.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_sbm_generator.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_schema_and_immutable.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_seeding.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_selection_uq.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_selection_uq_integration.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_semiring_negative_cases.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_semiring_verification.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_sidecar.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_sir_epidemic.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_sir_multiplex.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_spectral_multilayer.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_statistical_report.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_stats_comparison.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_stats_core.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_stats_edge_cases.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_stats_registry.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_stats_scalar_uncertainty.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_stats_verify.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_stratified_uq.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_streaming_topk.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_successive_halving.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_supporting_extended.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_supra_matrix_function_centrality.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_temporal.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_temporal_algorithms.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_temporal_builder.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_temporal_dsl.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_temporal_duration_parsing.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_temporal_multinet.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_temporal_utils.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_temporal_view.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_temporal_windowed_queries.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_tensor_representation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_tutorial_10min.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_uncertainty.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_uncertainty_additional.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_uncertainty_builder_integration.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_uncertainty_defaults.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_uncertainty_dsl_integration.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_uncertainty_engines.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_uncertainty_oracles.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_uq_integration.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_uq_resolution.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_uq_spine.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_utils_coverage.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_utils_extended.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_utils_search_paths.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_validation.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_validation_module.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_verification_api_differential.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_verification_centrality.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_verification_communities.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_verification_determinism_parallelism.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_verification_dsl_equivalence.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_verification_metamorphic_harness.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_verification_provenance_oracles.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_versatility.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_visualization_benchmark.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_visualization_bezier.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_visualization_colors.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_visualization_imports.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_visualization_layouts.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_visualization_multilayer_additional.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_visualization_polyfit.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_visualization_supra_heatmap.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_visualize_matrix_fix.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_workflows.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_wrappers_additional.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_wrappers_benchmark_nodes.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_wrappers_node2vec.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_wrappers_r_interop.py +0 -0
- {py3plex-1.1.3 → py3plex-1.1.5}/tests/test_wrappers_train_node2vec.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: py3plex
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.5
|
|
4
4
|
Summary: A Multilayer network analysis python3 library
|
|
5
5
|
Author-email: Blaž Škrlj <blaz.skrlj@ijs.si>
|
|
6
6
|
License: MIT
|
|
@@ -39,6 +39,7 @@ Requires-Dist: pytest>=7.0; extra == "dev"
|
|
|
39
39
|
Requires-Dist: pytest-timeout>=2.1; extra == "dev"
|
|
40
40
|
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
41
41
|
Requires-Dist: pytest-benchmark<5.0,>=4.0; extra == "dev"
|
|
42
|
+
Requires-Dist: pytest-rerunfailures>=12.0; extra == "dev"
|
|
42
43
|
Requires-Dist: black>=23.0; extra == "dev"
|
|
43
44
|
Requires-Dist: ruff>=0.1.0; extra == "dev"
|
|
44
45
|
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
@@ -52,6 +53,7 @@ Provides-Extra: tests
|
|
|
52
53
|
Requires-Dist: pytest>=7.0; extra == "tests"
|
|
53
54
|
Requires-Dist: pytest-timeout>=2.1; extra == "tests"
|
|
54
55
|
Requires-Dist: pytest-cov>=4.0; extra == "tests"
|
|
56
|
+
Requires-Dist: pytest-rerunfailures>=12.0; extra == "tests"
|
|
55
57
|
Requires-Dist: hypothesis>=6.0; extra == "tests"
|
|
56
58
|
Requires-Dist: hypothesis-networkx>=0.2.0; extra == "tests"
|
|
57
59
|
Requires-Dist: networkx>=2.5; extra == "tests"
|
|
@@ -98,10 +100,11 @@ Dynamic: license-file
|
|
|
98
100
|
[](https://github.com/SkBlaz/py3plex/actions/workflows/verify.yml)
|
|
99
101
|
[](https://github.com/SkBlaz/py3plex/actions/workflows/fuzzing.yml)
|
|
100
102
|
[](https://pypi.org/project/py3plex/)
|
|
103
|
+
[](https://pypistats.org/packages/py3plex)
|
|
101
104
|

|
|
102
105
|

|
|
103
|
-

|
|
107
|
+

|
|
105
108
|
|
|
106
109
|
*Multilayer networks* are complex networks with additional information assigned to nodes or edges (or both). This library includes
|
|
107
110
|
some of the state-of-the-art algorithms for decomposition, visualization and analysis of such networks.
|
|
@@ -10,10 +10,11 @@
|
|
|
10
10
|
[](https://github.com/SkBlaz/py3plex/actions/workflows/verify.yml)
|
|
11
11
|
[](https://github.com/SkBlaz/py3plex/actions/workflows/fuzzing.yml)
|
|
12
12
|
[](https://pypi.org/project/py3plex/)
|
|
13
|
+
[](https://pypistats.org/packages/py3plex)
|
|
13
14
|

|
|
14
15
|

|
|
15
|
-

|
|
17
|
+

|
|
17
18
|
|
|
18
19
|
*Multilayer networks* are complex networks with additional information assigned to nodes or edges (or both). This library includes
|
|
19
20
|
some of the state-of-the-art algorithms for decomposition, visualization and analysis of such networks.
|
|
@@ -51,8 +51,8 @@ For detailed documentation, see: https://skblaz.github.io/py3plex/
|
|
|
51
51
|
"""
|
|
52
52
|
|
|
53
53
|
# Version information
|
|
54
|
-
__version__ = "1.1.
|
|
55
|
-
__api_version__ = "1.1.
|
|
54
|
+
__version__ = "1.1.5"
|
|
55
|
+
__api_version__ = "1.1.5"
|
|
56
56
|
|
|
57
57
|
from py3plex.core.multinet import multi_layer_network
|
|
58
58
|
from py3plex.core.types import (
|
|
@@ -146,6 +146,7 @@ from py3plex.pipeline import (
|
|
|
146
146
|
ComputeStats,
|
|
147
147
|
FilterNodes,
|
|
148
148
|
SaveNetwork,
|
|
149
|
+
NodeEmbedding,
|
|
149
150
|
)
|
|
150
151
|
|
|
151
152
|
# Config-driven workflows
|
|
@@ -179,6 +180,12 @@ from py3plex.dynamics import (
|
|
|
179
180
|
)
|
|
180
181
|
|
|
181
182
|
# Uncertainty module for first-class uncertainty estimation
|
|
183
|
+
from py3plex.runtime.capabilities import (
|
|
184
|
+
capabilities,
|
|
185
|
+
capabilities_flat,
|
|
186
|
+
capabilities_fingerprint,
|
|
187
|
+
)
|
|
188
|
+
|
|
182
189
|
from py3plex.uncertainty import (
|
|
183
190
|
StatSeries,
|
|
184
191
|
StatMatrix,
|
|
@@ -278,6 +285,7 @@ __all__ = [
|
|
|
278
285
|
"ComputeStats",
|
|
279
286
|
"FilterNodes",
|
|
280
287
|
"SaveNetwork",
|
|
288
|
+
"NodeEmbedding",
|
|
281
289
|
# Workflows
|
|
282
290
|
"WorkflowConfig",
|
|
283
291
|
"WorkflowRunner",
|
|
@@ -314,4 +322,8 @@ __all__ = [
|
|
|
314
322
|
"set_uncertainty_config",
|
|
315
323
|
"uncertainty_enabled",
|
|
316
324
|
"estimate_uncertainty",
|
|
325
|
+
# Runtime capability discovery
|
|
326
|
+
"capabilities",
|
|
327
|
+
"capabilities_flat",
|
|
328
|
+
"capabilities_fingerprint",
|
|
317
329
|
]
|
|
@@ -5,6 +5,7 @@ Provides abstraction layer for different execution backends:
|
|
|
5
5
|
- Matrix backend (placeholder): future support for matrix operations
|
|
6
6
|
"""
|
|
7
7
|
|
|
8
|
+
from enum import Enum
|
|
8
9
|
from typing import Any, Dict, List, Literal, Tuple
|
|
9
10
|
from py3plex.exceptions import Py3plexException
|
|
10
11
|
|
|
@@ -17,6 +18,14 @@ from .closure import closure
|
|
|
17
18
|
BackendType = Literal["graph", "matrix"]
|
|
18
19
|
|
|
19
20
|
|
|
21
|
+
class AlgebraBackend(str, Enum):
|
|
22
|
+
"""Legacy backend identifiers used by the operation registry tests."""
|
|
23
|
+
|
|
24
|
+
NETWORKX = "networkx"
|
|
25
|
+
SPARSE = "sparse"
|
|
26
|
+
IGRAPH = "igraph"
|
|
27
|
+
|
|
28
|
+
|
|
20
29
|
class GraphBackend:
|
|
21
30
|
"""Default graph-based backend for semiring operations."""
|
|
22
31
|
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
"""Registry helpers for semirings and legacy algebra operations."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from collections import defaultdict
|
|
6
|
+
from typing import Callable, DefaultDict, Dict, List
|
|
7
|
+
|
|
8
|
+
from py3plex.exceptions import Py3plexException
|
|
9
|
+
|
|
10
|
+
from .backend import AlgebraBackend
|
|
11
|
+
from .semiring import (
|
|
12
|
+
BooleanSemiring,
|
|
13
|
+
MaxPlusSemiring,
|
|
14
|
+
MaxTimesSemiring,
|
|
15
|
+
MinPlusSemiring,
|
|
16
|
+
Semiring,
|
|
17
|
+
)
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
class SemiringRegistry:
|
|
21
|
+
"""Global registry for semirings."""
|
|
22
|
+
|
|
23
|
+
def __init__(self):
|
|
24
|
+
self._semirings: Dict[str, Semiring] = {}
|
|
25
|
+
self._register_builtins()
|
|
26
|
+
|
|
27
|
+
def _register_builtins(self):
|
|
28
|
+
self.register("boolean", BooleanSemiring(), overwrite=False)
|
|
29
|
+
self.register("max_plus", MaxPlusSemiring(), overwrite=False)
|
|
30
|
+
self.register("max_times", MaxTimesSemiring(), overwrite=False)
|
|
31
|
+
self.register("min_plus", MinPlusSemiring(), overwrite=False)
|
|
32
|
+
|
|
33
|
+
def register(self, name: str, semiring: Semiring, overwrite: bool = False):
|
|
34
|
+
if name in self._semirings and not overwrite:
|
|
35
|
+
raise Py3plexException(
|
|
36
|
+
f"Semiring '{name}' already registered. Use overwrite=True to replace."
|
|
37
|
+
)
|
|
38
|
+
self._semirings[name] = semiring
|
|
39
|
+
|
|
40
|
+
def get(self, name: str) -> Semiring:
|
|
41
|
+
if name not in self._semirings:
|
|
42
|
+
available = ", ".join(sorted(self._semirings.keys()))
|
|
43
|
+
raise Py3plexException(
|
|
44
|
+
f"Unknown semiring: '{name}'. Available semirings: {available}"
|
|
45
|
+
)
|
|
46
|
+
return self._semirings[name]
|
|
47
|
+
|
|
48
|
+
def list(self) -> List[str]:
|
|
49
|
+
return sorted(self._semirings.keys())
|
|
50
|
+
|
|
51
|
+
def __contains__(self, name: str) -> bool:
|
|
52
|
+
return name in self._semirings
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class AlgebraRegistry:
|
|
56
|
+
"""Legacy operation registry kept for backward compatibility."""
|
|
57
|
+
|
|
58
|
+
def __init__(self):
|
|
59
|
+
self._operations: DefaultDict[str, Dict[AlgebraBackend, Callable]] = defaultdict(
|
|
60
|
+
dict
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
def register(
|
|
64
|
+
self, operation: str, backend: AlgebraBackend, implementation: Callable
|
|
65
|
+
) -> None:
|
|
66
|
+
self._operations[operation][backend] = implementation
|
|
67
|
+
|
|
68
|
+
def get(self, operation: str, backend: AlgebraBackend) -> Callable:
|
|
69
|
+
try:
|
|
70
|
+
return self._operations[operation][backend]
|
|
71
|
+
except KeyError as exc:
|
|
72
|
+
raise KeyError(
|
|
73
|
+
f"No implementation registered for operation '{operation}' on backend "
|
|
74
|
+
f"'{backend.value}'."
|
|
75
|
+
) from exc
|
|
76
|
+
|
|
77
|
+
def list_operations(self) -> List[str]:
|
|
78
|
+
return sorted(self._operations.keys())
|
|
79
|
+
|
|
80
|
+
def clear(self) -> None:
|
|
81
|
+
self._operations.clear()
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
semiring_registry = SemiringRegistry()
|
|
85
|
+
_operation_registry = AlgebraRegistry()
|
|
86
|
+
|
|
87
|
+
|
|
88
|
+
def register_semiring(name: str, semiring: Semiring, overwrite: bool = False):
|
|
89
|
+
semiring_registry.register(name, semiring, overwrite=overwrite)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
def get_semiring(name: str) -> Semiring:
|
|
93
|
+
return semiring_registry.get(name)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def list_semirings() -> List[str]:
|
|
97
|
+
return semiring_registry.list()
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
def get_registry() -> AlgebraRegistry:
|
|
101
|
+
return _operation_registry
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def register_operation(
|
|
105
|
+
operation: str, backend: AlgebraBackend, implementation: Callable
|
|
106
|
+
) -> None:
|
|
107
|
+
_operation_registry.register(operation, backend, implementation)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def get_operation(operation: str, backend: AlgebraBackend) -> Callable:
|
|
111
|
+
return _operation_registry.get(operation, backend)
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
def list_operations() -> List[str]:
|
|
115
|
+
return _operation_registry.list_operations()
|
|
116
|
+
|
|
117
|
+
|
|
118
|
+
def clear_registry() -> None:
|
|
119
|
+
_operation_registry.clear()
|
|
@@ -11,7 +11,7 @@ Authors: py3plex contributors
|
|
|
11
11
|
Date: 2025
|
|
12
12
|
"""
|
|
13
13
|
|
|
14
|
-
from typing import
|
|
14
|
+
from typing import List, Optional, Union
|
|
15
15
|
import numpy as np
|
|
16
16
|
import networkx as nx
|
|
17
17
|
|
|
@@ -23,7 +23,7 @@ def multilayer_barabasi_albert(
|
|
|
23
23
|
interlayer_prob: float = 0.1,
|
|
24
24
|
directed: bool = False,
|
|
25
25
|
seed: Optional[int] = None
|
|
26
|
-
) ->
|
|
26
|
+
) -> Union[nx.MultiGraph, nx.MultiDiGraph]:
|
|
27
27
|
"""Generate multilayer Barabási-Albert preferential attachment network.
|
|
28
28
|
|
|
29
29
|
Creates a scale-free network in each layer with preferential attachment,
|
|
@@ -33,13 +33,17 @@ def multilayer_barabasi_albert(
|
|
|
33
33
|
n: Number of nodes per layer
|
|
34
34
|
m: Number of edges to attach from new node (m < n)
|
|
35
35
|
num_layers: Number of layers
|
|
36
|
-
interlayer_prob: Probability of inter-layer edges
|
|
36
|
+
interlayer_prob: Probability of inter-layer edges (must be in [0, 1])
|
|
37
37
|
directed: Whether to create directed networks
|
|
38
38
|
seed: Random seed for reproducibility
|
|
39
39
|
|
|
40
40
|
Returns:
|
|
41
41
|
NetworkX MultiGraph or MultiDiGraph with multilayer structure
|
|
42
42
|
|
|
43
|
+
Raises:
|
|
44
|
+
ValueError: If parameters are invalid (n <= 0, m <= 0, m >= n,
|
|
45
|
+
num_layers <= 0, or interlayer_prob not in [0, 1])
|
|
46
|
+
|
|
43
47
|
Algorithm:
|
|
44
48
|
For each layer:
|
|
45
49
|
1. Generate BA network with preferential attachment
|
|
@@ -51,8 +55,23 @@ def multilayer_barabasi_albert(
|
|
|
51
55
|
- Gómez, S., et al. (2013). "Diffusion dynamics on multiplex networks."
|
|
52
56
|
Physical Review Letters, 110(2), 028701.
|
|
53
57
|
"""
|
|
54
|
-
|
|
55
|
-
|
|
58
|
+
# Parameter validation
|
|
59
|
+
if n <= 0:
|
|
60
|
+
raise ValueError(f"n must be positive, got {n}")
|
|
61
|
+
if m <= 0:
|
|
62
|
+
raise ValueError(f"m must be positive, got {m}")
|
|
63
|
+
if m >= n:
|
|
64
|
+
raise ValueError(f"m must be less than n, got m={m}, n={n}")
|
|
65
|
+
if num_layers <= 0:
|
|
66
|
+
raise ValueError(f"num_layers must be positive, got {num_layers}")
|
|
67
|
+
if not 0 <= interlayer_prob <= 1:
|
|
68
|
+
raise ValueError(f"interlayer_prob must be in [0, 1], got {interlayer_prob}")
|
|
69
|
+
|
|
70
|
+
# Initialize RNG consistently
|
|
71
|
+
rng = np.random.RandomState(seed)
|
|
72
|
+
|
|
73
|
+
# Use RNG to generate seed for NetworkX functions
|
|
74
|
+
nx_seed = None if seed is None else rng.randint(0, 2**31)
|
|
56
75
|
|
|
57
76
|
if directed:
|
|
58
77
|
G = nx.MultiDiGraph()
|
|
@@ -61,7 +80,7 @@ def multilayer_barabasi_albert(
|
|
|
61
80
|
|
|
62
81
|
# Generate BA network for each layer
|
|
63
82
|
for layer in range(num_layers):
|
|
64
|
-
layer_graph = nx.barabasi_albert_graph(n, m, seed=
|
|
83
|
+
layer_graph = nx.barabasi_albert_graph(n, m, seed=nx_seed)
|
|
65
84
|
|
|
66
85
|
# Add nodes with layer information
|
|
67
86
|
for node in layer_graph.nodes():
|
|
@@ -76,7 +95,7 @@ def multilayer_barabasi_albert(
|
|
|
76
95
|
for node in range(n):
|
|
77
96
|
for l1 in range(num_layers):
|
|
78
97
|
for l2 in range(l1 + 1, num_layers):
|
|
79
|
-
if
|
|
98
|
+
if rng.random() < interlayer_prob:
|
|
80
99
|
G.add_edge(
|
|
81
100
|
(node, l1), (node, l2),
|
|
82
101
|
edge_type='inter',
|
|
@@ -93,7 +112,7 @@ def multilayer_stochastic_block_model(
|
|
|
93
112
|
interlayer_prob: float = 0.1,
|
|
94
113
|
directed: bool = False,
|
|
95
114
|
seed: Optional[int] = None
|
|
96
|
-
) ->
|
|
115
|
+
) -> Union[nx.MultiGraph, nx.MultiDiGraph]:
|
|
97
116
|
"""Generate multilayer stochastic block model network.
|
|
98
117
|
|
|
99
118
|
Creates networks with community structure in each layer, where edges
|
|
@@ -103,13 +122,17 @@ def multilayer_stochastic_block_model(
|
|
|
103
122
|
block_sizes: List of block sizes (number of nodes in each block)
|
|
104
123
|
block_probs: Matrix of edge probabilities between blocks (k x k)
|
|
105
124
|
num_layers: Number of layers
|
|
106
|
-
interlayer_prob: Probability of inter-layer edges
|
|
125
|
+
interlayer_prob: Probability of inter-layer edges (must be in [0, 1])
|
|
107
126
|
directed: Whether to create directed networks
|
|
108
127
|
seed: Random seed for reproducibility
|
|
109
128
|
|
|
110
129
|
Returns:
|
|
111
130
|
NetworkX MultiGraph or MultiDiGraph with block structure
|
|
112
131
|
|
|
132
|
+
Raises:
|
|
133
|
+
ValueError: If parameters are invalid (empty block_sizes, num_layers <= 0,
|
|
134
|
+
or interlayer_prob not in [0, 1])
|
|
135
|
+
|
|
113
136
|
Example:
|
|
114
137
|
>>> # Two blocks with strong within-block, weak between-block connections
|
|
115
138
|
>>> sizes = [50, 50]
|
|
@@ -122,8 +145,21 @@ def multilayer_stochastic_block_model(
|
|
|
122
145
|
- Bazzi, M., et al. (2016). "Community detection in temporal multilayer
|
|
123
146
|
networks." SIAM Journal on Applied Mathematics, 76(2), 504-537.
|
|
124
147
|
"""
|
|
125
|
-
|
|
126
|
-
|
|
148
|
+
# Parameter validation
|
|
149
|
+
if not block_sizes:
|
|
150
|
+
raise ValueError("block_sizes cannot be empty")
|
|
151
|
+
if any(s <= 0 for s in block_sizes):
|
|
152
|
+
raise ValueError(f"All block sizes must be positive, got {block_sizes}")
|
|
153
|
+
if num_layers <= 0:
|
|
154
|
+
raise ValueError(f"num_layers must be positive, got {num_layers}")
|
|
155
|
+
if not 0 <= interlayer_prob <= 1:
|
|
156
|
+
raise ValueError(f"interlayer_prob must be in [0, 1], got {interlayer_prob}")
|
|
157
|
+
|
|
158
|
+
# Initialize RNG consistently
|
|
159
|
+
rng = np.random.RandomState(seed)
|
|
160
|
+
|
|
161
|
+
# Use RNG to generate seed for NetworkX functions
|
|
162
|
+
nx_seed = None if seed is None else rng.randint(0, 2**31)
|
|
127
163
|
|
|
128
164
|
if directed:
|
|
129
165
|
G = nx.MultiDiGraph()
|
|
@@ -133,7 +169,7 @@ def multilayer_stochastic_block_model(
|
|
|
133
169
|
# Generate SBM for each layer
|
|
134
170
|
for layer in range(num_layers):
|
|
135
171
|
layer_graph = nx.stochastic_block_model(
|
|
136
|
-
block_sizes, block_probs, directed=directed, seed=
|
|
172
|
+
block_sizes, block_probs, directed=directed, seed=nx_seed
|
|
137
173
|
)
|
|
138
174
|
|
|
139
175
|
# Add nodes with layer information
|
|
@@ -150,7 +186,7 @@ def multilayer_stochastic_block_model(
|
|
|
150
186
|
for node in range(total_nodes):
|
|
151
187
|
for l1 in range(num_layers):
|
|
152
188
|
for l2 in range(l1 + 1, num_layers):
|
|
153
|
-
if
|
|
189
|
+
if rng.random() < interlayer_prob:
|
|
154
190
|
G.add_edge(
|
|
155
191
|
(node, l1), (node, l2),
|
|
156
192
|
edge_type='inter',
|
|
@@ -166,7 +202,7 @@ def multilayer_sbm_with_dependencies(
|
|
|
166
202
|
interlayer_probs: np.ndarray,
|
|
167
203
|
directed: bool = False,
|
|
168
204
|
seed: Optional[int] = None
|
|
169
|
-
) ->
|
|
205
|
+
) -> Union[nx.MultiGraph, nx.MultiDiGraph]:
|
|
170
206
|
"""Generate multilayer SBM with layer-dependent block probabilities.
|
|
171
207
|
|
|
172
208
|
Each layer can have different within/between block connection probabilities,
|
|
@@ -182,6 +218,9 @@ def multilayer_sbm_with_dependencies(
|
|
|
182
218
|
Returns:
|
|
183
219
|
NetworkX MultiGraph or MultiDiGraph with dependent block structure
|
|
184
220
|
|
|
221
|
+
Raises:
|
|
222
|
+
ValueError: If parameters are invalid (empty block_sizes, empty intralayer_probs)
|
|
223
|
+
|
|
185
224
|
Example:
|
|
186
225
|
>>> sizes = [30, 30]
|
|
187
226
|
>>> # Different connectivity patterns in each layer
|
|
@@ -198,8 +237,16 @@ def multilayer_sbm_with_dependencies(
|
|
|
198
237
|
- Peixoto, T. P. (2015). "Inferring the mesoscale structure of layered,
|
|
199
238
|
edge-valued, and time-varying networks." Physical Review E, 92(4), 042807.
|
|
200
239
|
"""
|
|
201
|
-
|
|
202
|
-
|
|
240
|
+
# Parameter validation
|
|
241
|
+
if not block_sizes:
|
|
242
|
+
raise ValueError("block_sizes cannot be empty")
|
|
243
|
+
if any(s <= 0 for s in block_sizes):
|
|
244
|
+
raise ValueError(f"All block sizes must be positive, got {block_sizes}")
|
|
245
|
+
if not intralayer_probs:
|
|
246
|
+
raise ValueError("intralayer_probs cannot be empty")
|
|
247
|
+
|
|
248
|
+
# Initialize RNG consistently
|
|
249
|
+
rng = np.random.RandomState(seed)
|
|
203
250
|
|
|
204
251
|
num_layers = len(intralayer_probs)
|
|
205
252
|
total_nodes = sum(block_sizes)
|
|
@@ -230,7 +277,7 @@ def multilayer_sbm_with_dependencies(
|
|
|
230
277
|
block_v = node_blocks[v]
|
|
231
278
|
prob = layer_probs[block_u, block_v]
|
|
232
279
|
|
|
233
|
-
if
|
|
280
|
+
if rng.random() < prob:
|
|
234
281
|
G.add_edge((u, layer), (v, layer), layer=layer, edge_type='intra')
|
|
235
282
|
|
|
236
283
|
# Add inter-layer edges based on block-dependent probabilities
|
|
@@ -240,7 +287,7 @@ def multilayer_sbm_with_dependencies(
|
|
|
240
287
|
block = node_blocks[node]
|
|
241
288
|
prob = interlayer_probs[l1, l2, block]
|
|
242
289
|
|
|
243
|
-
if
|
|
290
|
+
if rng.random() < prob:
|
|
244
291
|
G.add_edge(
|
|
245
292
|
(node, l1), (node, l2),
|
|
246
293
|
edge_type='inter',
|
|
@@ -257,29 +304,46 @@ def multilayer_erdos_renyi(
|
|
|
257
304
|
interlayer_prob: float = 0.1,
|
|
258
305
|
directed: bool = False,
|
|
259
306
|
seed: Optional[int] = None
|
|
260
|
-
) ->
|
|
307
|
+
) -> Union[nx.MultiGraph, nx.MultiDiGraph]:
|
|
261
308
|
"""Generate multilayer Erdős-Rényi random network.
|
|
262
309
|
|
|
263
310
|
Creates independent ER graphs in each layer with inter-layer connections.
|
|
264
311
|
|
|
265
312
|
Args:
|
|
266
313
|
n: Number of nodes per layer
|
|
267
|
-
p: Intra-layer edge probability
|
|
314
|
+
p: Intra-layer edge probability (must be in [0, 1])
|
|
268
315
|
num_layers: Number of layers
|
|
269
|
-
interlayer_prob: Probability of inter-layer edges
|
|
316
|
+
interlayer_prob: Probability of inter-layer edges (must be in [0, 1])
|
|
270
317
|
directed: Whether to create directed networks
|
|
271
318
|
seed: Random seed for reproducibility
|
|
272
319
|
|
|
273
320
|
Returns:
|
|
274
321
|
NetworkX MultiGraph or MultiDiGraph
|
|
275
322
|
|
|
323
|
+
Raises:
|
|
324
|
+
ValueError: If parameters are invalid (n <= 0, p not in [0, 1],
|
|
325
|
+
num_layers <= 0, or interlayer_prob not in [0, 1])
|
|
326
|
+
|
|
276
327
|
References:
|
|
277
328
|
- Erdős, P., & Rényi, A. (1960). "On the evolution of random graphs."
|
|
278
329
|
Publication of the Mathematical Institute of the Hungarian Academy
|
|
279
330
|
of Sciences, 5(1), 17-60.
|
|
280
331
|
"""
|
|
281
|
-
|
|
282
|
-
|
|
332
|
+
# Parameter validation
|
|
333
|
+
if n <= 0:
|
|
334
|
+
raise ValueError(f"n must be positive, got {n}")
|
|
335
|
+
if not 0 <= p <= 1:
|
|
336
|
+
raise ValueError(f"p must be in [0, 1], got {p}")
|
|
337
|
+
if num_layers <= 0:
|
|
338
|
+
raise ValueError(f"num_layers must be positive, got {num_layers}")
|
|
339
|
+
if not 0 <= interlayer_prob <= 1:
|
|
340
|
+
raise ValueError(f"interlayer_prob must be in [0, 1], got {interlayer_prob}")
|
|
341
|
+
|
|
342
|
+
# Initialize RNG consistently
|
|
343
|
+
rng = np.random.RandomState(seed)
|
|
344
|
+
|
|
345
|
+
# Use RNG to generate seed for NetworkX functions
|
|
346
|
+
nx_seed = None if seed is None else rng.randint(0, 2**31)
|
|
283
347
|
|
|
284
348
|
if directed:
|
|
285
349
|
G = nx.MultiDiGraph()
|
|
@@ -288,7 +352,7 @@ def multilayer_erdos_renyi(
|
|
|
288
352
|
|
|
289
353
|
# Generate ER network for each layer
|
|
290
354
|
for layer in range(num_layers):
|
|
291
|
-
layer_graph = nx.erdos_renyi_graph(n, p, seed=
|
|
355
|
+
layer_graph = nx.erdos_renyi_graph(n, p, seed=nx_seed, directed=directed)
|
|
292
356
|
|
|
293
357
|
# Add nodes with layer information
|
|
294
358
|
for node in layer_graph.nodes():
|
|
@@ -303,7 +367,7 @@ def multilayer_erdos_renyi(
|
|
|
303
367
|
for node in range(n):
|
|
304
368
|
for l1 in range(num_layers):
|
|
305
369
|
for l2 in range(l1 + 1, num_layers):
|
|
306
|
-
if
|
|
370
|
+
if rng.random() < interlayer_prob:
|
|
307
371
|
G.add_edge(
|
|
308
372
|
(node, l1), (node, l2),
|
|
309
373
|
edge_type='inter',
|
|
@@ -318,26 +382,38 @@ def multilayer_configuration_model(
|
|
|
318
382
|
interlayer_edges: int = 0,
|
|
319
383
|
directed: bool = False,
|
|
320
384
|
seed: Optional[int] = None
|
|
321
|
-
) ->
|
|
385
|
+
) -> Union[nx.MultiGraph, nx.MultiDiGraph]:
|
|
322
386
|
"""Generate multilayer network with specified degree sequences.
|
|
323
387
|
|
|
324
388
|
Creates networks where each layer has a specific degree distribution.
|
|
325
389
|
|
|
326
390
|
Args:
|
|
327
391
|
degree_sequences: List of degree sequences, one per layer
|
|
328
|
-
interlayer_edges: Number of random inter-layer edges to add
|
|
392
|
+
interlayer_edges: Number of random inter-layer edges to add (must be >= 0)
|
|
329
393
|
directed: Whether to create directed networks
|
|
330
394
|
seed: Random seed for reproducibility
|
|
331
395
|
|
|
332
396
|
Returns:
|
|
333
397
|
NetworkX MultiGraph or MultiDiGraph
|
|
334
398
|
|
|
399
|
+
Raises:
|
|
400
|
+
ValueError: If parameters are invalid (empty degree_sequences or interlayer_edges < 0)
|
|
401
|
+
|
|
335
402
|
References:
|
|
336
403
|
- Newman, M. E. (2003). "The structure and function of complex networks."
|
|
337
404
|
SIAM Review, 45(2), 167-256.
|
|
338
405
|
"""
|
|
339
|
-
|
|
340
|
-
|
|
406
|
+
# Parameter validation
|
|
407
|
+
if not degree_sequences:
|
|
408
|
+
raise ValueError("degree_sequences cannot be empty")
|
|
409
|
+
if interlayer_edges < 0:
|
|
410
|
+
raise ValueError(f"interlayer_edges must be non-negative, got {interlayer_edges}")
|
|
411
|
+
|
|
412
|
+
# Initialize RNG consistently
|
|
413
|
+
rng = np.random.RandomState(seed)
|
|
414
|
+
|
|
415
|
+
# Use RNG to generate seed for NetworkX functions
|
|
416
|
+
nx_seed = None if seed is None else rng.randint(0, 2**31)
|
|
341
417
|
|
|
342
418
|
if directed:
|
|
343
419
|
G = nx.MultiDiGraph()
|
|
@@ -353,10 +429,10 @@ def multilayer_configuration_model(
|
|
|
353
429
|
# For directed, need in-degree and out-degree sequences
|
|
354
430
|
# Here we use the same sequence for both
|
|
355
431
|
layer_graph = nx.directed_configuration_model(
|
|
356
|
-
degree_seq, degree_seq, seed=
|
|
432
|
+
degree_seq, degree_seq, seed=nx_seed
|
|
357
433
|
)
|
|
358
434
|
else:
|
|
359
|
-
layer_graph = nx.configuration_model(degree_seq, seed=
|
|
435
|
+
layer_graph = nx.configuration_model(degree_seq, seed=nx_seed)
|
|
360
436
|
|
|
361
437
|
# Remove self-loops and parallel edges
|
|
362
438
|
layer_graph = nx.Graph(layer_graph)
|
|
@@ -392,12 +468,12 @@ def multilayer_configuration_model(
|
|
|
392
468
|
attempts += 1
|
|
393
469
|
|
|
394
470
|
# Pick two random layers
|
|
395
|
-
l1, l2 =
|
|
471
|
+
l1, l2 = rng.choice(num_layers, size=2, replace=False)
|
|
396
472
|
|
|
397
473
|
# Pick random nodes from each layer
|
|
398
474
|
if l1 in nodes_per_layer and l2 in nodes_per_layer:
|
|
399
|
-
node1 =
|
|
400
|
-
node2 =
|
|
475
|
+
node1 = rng.choice(nodes_per_layer[l1])
|
|
476
|
+
node2 = rng.choice(nodes_per_layer[l2])
|
|
401
477
|
|
|
402
478
|
# Add edge if it doesn't exist
|
|
403
479
|
if not G.has_edge((node1, l1), (node2, l2)):
|
|
@@ -80,7 +80,7 @@ def correlate_attributes_with_centrality(
|
|
|
80
80
|
elif centrality_type == "eigenvector":
|
|
81
81
|
try:
|
|
82
82
|
centrality = nx.eigenvector_centrality(G, max_iter=1000)
|
|
83
|
-
except:
|
|
83
|
+
except (nx.PowerIterationFailedConvergence, nx.NetworkXError):
|
|
84
84
|
centrality = dict(G.degree()) # Fallback
|
|
85
85
|
else:
|
|
86
86
|
from py3plex.errors import find_similar
|
|
@@ -304,7 +304,7 @@ def attribute_structural_contingency(
|
|
|
304
304
|
try:
|
|
305
305
|
from scipy.stats import chi2_contingency
|
|
306
306
|
chi2, p_value, _, _ = chi2_contingency(contingency)
|
|
307
|
-
except:
|
|
307
|
+
except Exception:
|
|
308
308
|
chi2, p_value = 0, 1
|
|
309
309
|
|
|
310
310
|
return {
|
|
@@ -406,7 +406,7 @@ def multilayer_assortativity(
|
|
|
406
406
|
subgraph, attribute_name
|
|
407
407
|
)
|
|
408
408
|
results[layer] = assortativity
|
|
409
|
-
except:
|
|
409
|
+
except Exception:
|
|
410
410
|
results[layer] = 0.0
|
|
411
411
|
|
|
412
412
|
return results
|
|
@@ -419,7 +419,7 @@ def multilayer_assortativity(
|
|
|
419
419
|
else:
|
|
420
420
|
assortativity = nx.attribute_assortativity_coefficient(G, attribute_name)
|
|
421
421
|
return {'global': assortativity}
|
|
422
|
-
except:
|
|
422
|
+
except Exception:
|
|
423
423
|
return {'global': 0.0}
|
|
424
424
|
|
|
425
425
|
|
|
@@ -507,7 +507,7 @@ def attribute_centrality_independence_test(
|
|
|
507
507
|
elif centrality_type == "eigenvector":
|
|
508
508
|
try:
|
|
509
509
|
centrality = nx.eigenvector_centrality(G, max_iter=1000)
|
|
510
|
-
except:
|
|
510
|
+
except (nx.PowerIterationFailedConvergence, nx.NetworkXError):
|
|
511
511
|
centrality = dict(G.degree()) # Fallback
|
|
512
512
|
else:
|
|
513
513
|
from py3plex.errors import find_similar
|