py3plex 1.1.7__tar.gz → 2.0.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {py3plex-1.1.7/py3plex.egg-info → py3plex-2.0.0}/PKG-INFO +27 -2
- {py3plex-1.1.7 → py3plex-2.0.0}/README.md +26 -1
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/__init__.py +2 -2
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/autocommunity_executor.py +1 -1
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/config.py +2 -2
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/ast.py +5 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/builder.py +3 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/uq_resolution.py +8 -7
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/utils.py +0 -42
- {py3plex-1.1.7 → py3plex-2.0.0/py3plex.egg-info}/PKG-INFO +27 -2
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex.egg-info/SOURCES.txt +1 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex_mcp/__init__.py +2 -2
- {py3plex-1.1.7 → py3plex-2.0.0}/pyproject.toml +1 -1
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_book_conf.py +1 -1
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_book_manuscript_integrity.py +1 -1
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_data_files_presence.py +1 -1
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_CBSSD.py +4 -19
- py3plex-2.0.0/tests/test_ml_embedding_evaluation.py +159 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_utils_search_paths.py +0 -23
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_version_consistency.py +27 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/LICENSE +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/MANIFEST.in +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/__main__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/_parallel.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/agent.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algebra/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algebra/backend.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algebra/closure.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algebra/fixed_point.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algebra/lift.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algebra/paths.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algebra/registry.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algebra/semiring.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algebra/witness.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/advanced_random_generators.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/attribute_correlation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/centrality/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/centrality/approx_betweenness.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/centrality/approx_closeness.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/centrality/approx_pagerank.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/centrality/explain.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/centrality_toolkit.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_comparison.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/NoRC.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/auto_select.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/autocommunity.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/budget.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/community_louvain.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/community_measures.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/community_ranking.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/community_wrapper.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/distributional.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/flow_hierarchy.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/infomap/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/infomap/conftest.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/infomap/examples/python/example-bipartite.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/infomap/examples/python/example-file-io.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/infomap/examples/python/example-multiplex.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/infomap/examples/python/example-networkx.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/infomap/examples/python/example-simple.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/infomap/examples/python/example-trigram-expanded.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/infomap/examples/python/example-trigram.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/infomap/infomap.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/infomap/interfaces/python/setup.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/label_propagation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/leiden_multilayer.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/leiden_uq.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/multilayer_benchmark.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/multilayer_modularity.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/multilayer_quality_metrics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/node_ranking.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/runner.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/sbm_metrics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/sbm_wrapper.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/spectral_multilayer.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/successive_halving.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/curvature/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/curvature/ollivier_ricci_multilayer.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/general/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/general/benchmark_classification.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/general/walkers.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/graph_summarization.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/__main__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/assets/builtin.n3 +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/core/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/core/converters.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/core/example.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/core/helpers.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/core/kb.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/core/load.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/core/predicate.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/core/rule.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/core/settings.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/core/term_parsers.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/learners/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/learners/bottomup.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/learners/learner.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/learners/optimal.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/stats/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/stats/adjustment.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/stats/scorefunctions.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/stats/significance.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/hedwig/stats/validate.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/layer_similarity.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/meta_flow_report.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/multicentrality.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/multilayer_algorithms/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/multilayer_algorithms/centrality.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/multilayer_algorithms/entanglement.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/multilayer_algorithms/multirank.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/multilayer_algorithms/multixrank.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/multilayer_algorithms/supra_matrix_function_centrality.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/multilayer_algorithms/versatility.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/multilayer_clustering.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/network_classification/PPR.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/network_classification/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/network_classification/label_propagation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/node_ranking/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/node_ranking/node_ranking.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/requirements_registry.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/robustness_testing.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/routing/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/routing/multiplex_paths.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/sbm/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/sbm/conversions.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/sbm/diagnostics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/sbm/inference_vi.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/sbm/model_selection.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/sbm/multilayer_sbm.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/sbm/objectives.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/sbm/uq.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/sbm/utils.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/sir_multiplex.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/statistical_report.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/statistics/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/statistics/basic_statistics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/statistics/bayesian_distances.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/statistics/bayesiantests.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/statistics/correlation_networks.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/statistics/critical_distances.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/statistics/enrichment_modules.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/statistics/multilayer_statistics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/statistics/powerlaw.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/statistics/stats_comparison.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/statistics/topology.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/temporal/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/temporal/centrality.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/temporal/community.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/temporal_multiplex/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/term_parsers/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/alignment/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/alignment/features.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/alignment/metrics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/alignment/solvers.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/benchmarks/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/benchmarks/budget.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/benchmarks/metrics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/benchmarks/runners.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/centrality/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/centrality/robustness.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/claims/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/claims/generator.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/claims/learner.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/claims/scorer.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/claims/types.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/cli.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/comparison/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/comparison/executor.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/comparison/metrics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/comparison/result.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/compat/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/compat/convert.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/compat/converters/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/compat/converters/dgl_converter.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/compat/converters/igraph_converter.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/compat/converters/networkx_converter.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/compat/converters/pyg_converter.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/compat/converters/scipy_converter.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/compat/equality.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/compat/exceptions.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/compat/ir.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/compat/schema.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/compat/sidecar.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/contracts/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/contracts/contract.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/contracts/engine.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/contracts/failure_modes.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/contracts/predicates.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/contracts/result.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/core/HINMINE/IO.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/core/HINMINE/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/core/HINMINE/dataStructures.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/core/HINMINE/decomposition.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/core/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/core/converters.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/core/immutable.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/core/lazy_evaluation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/core/multinet.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/core/nx_compat.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/core/parsers.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/core/random_generators.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/core/schema_validation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/core/supporting.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/core/temporal_multinet.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/core/types.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/counterexamples/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/counterexamples/claim_lang.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/counterexamples/ddmin.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/counterexamples/engine.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/counterexamples/types.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/counterexamples/witness.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/counterfactual/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/counterfactual/comparator.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/counterfactual/engine.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/counterfactual/presets.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/counterfactual/result.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/counterfactual/spec.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/datasets/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/datasets/_data/aarhus_cs.edges +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/datasets/_data/synthetic_multilayer.edges +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/datasets/_generators.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/datasets/_loaders.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/diagnostics/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/diagnostics/builders.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/diagnostics/codes.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/diagnostics/core.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/diagnostics/utils.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/algebra.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/attribution.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/benchmark.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/benchmark_result.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/cache.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/communities.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/community_uq.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/compositional_uq.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/context.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/errors.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/executor.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/executor_semiring.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/executors/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/executors/benchmark_executor.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/explain.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/export.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/expressions.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/fastpath.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/layers.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/lint/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/lint/diagnostic.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/lint/lint_context.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/lint/rules/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/lint/rules/base.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/lint/rules/dsl001_unknown_layer.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/lint/rules/dsl002_unknown_attribute.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/lint/rules/dsl101_type_mismatch.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/lint/rules/dsl201_unsatisfiable.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/lint/rules/dsl202_redundant.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/lint/rules/perf301_full_scan.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/lint/rules/perf302_cross_layer.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/lint/schema.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/lint/type_resolver.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/lint/types.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/operator_registry.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/patterns/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/patterns/builder.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/patterns/compiler.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/patterns/engine.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/patterns/ir.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/patterns/result.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/planner.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/predictive.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/program/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/program/cache.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/program/cost.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/program/diff.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/program/distribution.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/program/executor.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/program/explain.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/program/program.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/program/rewrite.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/program/types.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/provenance.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/reduction.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/registry.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/result.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/selection_uq.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/serializer.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/uq_algebra.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl/warnings.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dsl_legacy.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dynamics/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dynamics/_utils.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dynamics/ast.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dynamics/builder.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dynamics/compartmental.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dynamics/config.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dynamics/core.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dynamics/errors.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dynamics/executor.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dynamics/models.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dynamics/processes.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dynamics/registry.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dynamics/result.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/dynamics/serializer.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/embeddings/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/embeddings/base.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/embeddings/cache.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/embeddings/link_ops.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/embeddings/metapath2vec.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/embeddings/netmf.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/ergonomics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/errors.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/exceptions.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/experiments/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/experiments/artifacts.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/experiments/cli.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/experiments/env.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/experiments/errors.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/experiments/model.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/experiments/runner.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/experiments/store.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/experiments/utils.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/fast_examples.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/graph_ops.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/io/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/io/api.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/io/canonical_format.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/io/converters.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/io/exceptions.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/io/formats/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/io/formats/arrow_format.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/io/formats/csv_format.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/io/formats/json_format.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/io/multinet_bridge.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/io/parquet_format.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/io/schema.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/lab/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/lab/base.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/linter.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/logging_config.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/meta/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/meta/builder.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/meta/result.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/meta/stats.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/meta/utils.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/ml/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/ml/embedding/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/ml/embedding/base.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/ml/embedding/deepwalk.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/ml/embedding/evaluation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/ml/embedding/line.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/ml/embedding/metapath2vec.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/ml/embedding/multiplex.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/ml/embedding/netmf.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/ml/embedding/node2vec.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/ml/embedding/similarity.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/ml/embedding/trainer.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/ml/embedding/utils.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/multinet/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/multinet/aggregation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/nullmodels/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/nullmodels/executor.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/nullmodels/models.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/nullmodels/result.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/optimizer/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/optimizer/cost_model.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/optimizer/logical_plan.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/optimizer/optimizer.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/optimizer/physical_plan.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/optimizer/plan_nodes.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/optimizer/rules.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/out_of_core/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/out_of_core/cli.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/out_of_core/errors.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/out_of_core/executor.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/out_of_core/network.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/out_of_core/operators.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/out_of_core/readers.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/out_of_core/schema.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/out_of_core/spill.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/out_of_core/utils.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/paths/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/paths/algorithms.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/paths/executor.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/paths/result.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/pipeline.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/plugins/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/plugins/base.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/plugins/examples.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/plugins/registry.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/profiling.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/provenance/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/provenance/bundle.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/provenance/capture.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/provenance/replay.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/provenance/schema.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/requirements.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/robustness/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/robustness/experiments.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/robustness/perturbations.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/runtime/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/runtime/capabilities.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/selection/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/selection/capabilities.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/selection/community_registry.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/selection/evaluate.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/selection/metric_registry.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/selection/result.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/selection/wins.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/semiring/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/semiring/core.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/semiring/engine.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/semiring/pareto.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/semiring/registry.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/semiring/types.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/sensitivity/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/sensitivity/executor.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/sensitivity/metrics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/sensitivity/perturbations.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/sensitivity/types.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/stats/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/stats/provenance.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/stats/registry.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/stats/statvalue.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/stats/uncertainty.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/temporal_utils.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/temporal_utils_extended.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/temporal_view.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/bootstrap.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/ci_utils.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/community_ensemble.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/community_result.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/context.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/estimation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/noise_models.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/null_models.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/partition.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/partition_metrics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/partition_reducers.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/partition_types.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/partition_uq.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/plan.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/reducers/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/reducers/base.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/resampling_graph.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/runner.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/selection_execution.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/selection_reducers.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/selection_types.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/selection_uq.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/stratification.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/uncertainty/types.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/validation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/visualization/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/visualization/benchmark_visualizations.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/visualization/bezier.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/visualization/colors.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/visualization/drawing_machinery.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/visualization/embedding_visualization/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/visualization/embedding_visualization/embedding_tools.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/visualization/embedding_visualization/embedding_visualization.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/visualization/fa2/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/visualization/fa2/fa2util.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/visualization/fa2/forceatlas2.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/visualization/layout_algorithms.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/visualization/multilayer.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/visualization/polyfit.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/visualization/pymnet_style.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/visualization/ricci_layout.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/visualization/ricci_multilayer_vis.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/visualization/sankey.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/workflows.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/wrappers/__init__.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/wrappers/benchmark_nodes.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/wrappers/r_interop.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex/wrappers/train_node2vec_embedding.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex.egg-info/dependency_links.txt +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex.egg-info/entry_points.txt +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex.egg-info/not-zip-safe +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex.egg-info/requires.txt +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex.egg-info/top_level.txt +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex_mcp/errors.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex_mcp/registry.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex_mcp/safe_paths.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex_mcp/schemas.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/py3plex_mcp/server.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/setup.cfg +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_advanced_metrics_properties.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_agent_api.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_agents_documentation_claims.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_agents_ergonomics_features.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_agents_golden_paths.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_aggregation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_algebra_backend.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_algebra_core.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_algebra_fixed_point.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_algebra_paths.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_algebra_registry.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_algebra_witness.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_algorithm_properties.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_algorithms_attribute_correlation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_algorithms_correlation_networks.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_algorithms_init.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_algorithms_random_generators.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_algorithms_requirements_registry.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_algorithms_statistics_bayesian_distances.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_alignment.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_alignment_contracts.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_alignment_correctness_additional.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_approximate_centrality.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_ast_roundtrip.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_ast_roundtrip_integration.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_attribute_correlation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_attribute_correlation_contracts.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_auto_community.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_autocommunity_benchmarks.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_autocommunity_executor.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_autocommunity_meta.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_autocommunity_successive_halving.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_bayesian_distances.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_bench_aggregation_unit.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_benchmark_budget_fairness.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_benchmark_dsl_basic.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_benchmark_integration.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_benchmark_multiplex_centrality.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_benchmark_time.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_benchmarks_budget.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_benchmarks_init.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_book_snippets.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_builder_dsl_mutate.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_capabilities_basic.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_capabilities_optional_missing.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_centrality_explain.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_centrality_explain_integration.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_centrality_robustness.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_centrality_robustness_oracles.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_centrality_uncertainty.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_centrality_weight_handling.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_check_api_consistency.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_check_doc_coverage.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_check_type_coverage.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_ci_python_versions.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_claim_learning.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_claims_types.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_cli.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_cli_check.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_cli_ergonomics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_cli_piping.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_clustering_multilayer.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_code_improvements.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_community_detection_modules.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_community_distribution.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_community_measures.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_comparison.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_comparison_executor.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_comparison_metrics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_comparison_metrics_additional.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_comparison_result.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_comparison_uninitialized_and_resistance_oracles.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_compat_exceptions.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_compat_roundtrip.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_config_api.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_config_benchmark.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_contracts.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_contracts_basic.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_contracts_extended.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_contracts_failure_modes.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_contracts_integration.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_core_functionality.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_core_immutable.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_core_lazy_evaluation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_core_multinet_and_parsers.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_core_multinet_correctness.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_core_multiplex_edges.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_core_schema_validation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_core_supporting.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_correlation_networks.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_counterexamples.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_counterexamples_properties.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_counterfactual.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_counterfactual_presets.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_coverage_grouping.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_create_mosaic_banner.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_create_showcase_flow.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_crosshair_pure_functions.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_datasets.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_datasets_contracts.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_datasets_oracles.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_degenerate_networks.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_determinism_randomness.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_diagnostics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_diagnostics_utils.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_doc_conf.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_docs_embeddings_section.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_docs_examples.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_docs_quality_pass.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_doctests.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dplyr_integration.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_aggregation_enhancements.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_ast_equivalence.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_auto_community.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_communities.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_community_filtering.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_community_uq_integration.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_compact_compute.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_compositional_uq.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_condition_semantics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_d_factory.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_documentation_examples.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_dplyr_style.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_dynamics_integration.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_edge_grouping_coverage.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_edge_queries.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_enhancements.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_ergonomics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_errors.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_errors_extended.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_executor_additional.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_explain.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_export.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_expressions.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_extensions.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_graphops_equivalence.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_grouping_coverage.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_interactive.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_joins.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_layer_selection.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_layer_set_algebra.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_legacy_approximate.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_legacy_edges.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_lint.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_operators.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_patterns.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_patterns_quick_reference.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_pipes.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_planner.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_predict_reduce.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_program_rewrite.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_program_types.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_progress_logging.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_properties.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_provenance.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_query_optimization.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_query_zoo.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_result_algebra_edge_cases.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_selection_fastpath.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_semiring_integration.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_serializer.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_smart_defaults.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_temporal_range_execution.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_uncertainty.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_uq_ergonomics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_uq_propagation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_v2.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dsl_zoo_features.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dynamics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dynamics_algorithm_contracts.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dynamics_config_and_results_correctness.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dynamics_conservation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dynamics_core.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dynamics_executor_edge_cases.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dynamics_parallel_determinism.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dynamics_reference_runs.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dynamics_uq_integration.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_dynamics_utils.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_edge_cases.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_edgelist_format.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_embeddings_direct_units.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_ergonomic_helpers.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_ergonomics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_ergonomics_helpers.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_errors.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_community_detection.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_decomposition_and_classification.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_decomposition_ground_truth.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_dsl_builder_api.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_dynamics_core_examples.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_embedding_construction.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_embedding_visualization.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_incidence_gadget_encoding.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_interactive_multilayer.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_inverse_network.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_layer_extraction.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_manipulation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_multilayer_vectorized_aggregation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_multiplex_aggregate.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_multiplex_dynamics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_n2v_embedding.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_network_decomposition.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_network_decomposition_meta_paths.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_numeric_encoding.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_pattern_matching.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_example_ppr.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_examples_zoo_consolidation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_exception_taxonomy.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_exceptions.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_experiments.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_explain_attribution.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_fast_examples.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_flagship_progress_demo.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_flow_hierarchy.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_fuzzing_properties.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_generate_all_outputs.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_generate_quickstart_outputs.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_generate_visualization_images.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_golden_toy_examples.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_graph_ops.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_graph_summarization.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_hedwig_adjustment.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_hedwig_significance.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_improved_errors.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_incidence_gadget_encoding.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_infomap_fix.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_interlayer_links_fix.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_io_api_edge_cases.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_io_arrow.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_io_contracts_additional.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_io_converters.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_io_exceptions.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_io_integration.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_io_roundtrip.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_io_schema.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_issue_19_fix.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_lab.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_lab_additional.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_lab_correctness.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_label_propagation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_layer_extraction_fix.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_layer_similarity.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_layout_algorithms.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_lazy_evaluation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_leiden_multilayer.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_link_checker.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_linter.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_logging_conversion.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_main_module.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_master_regulators_example.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_math_invariants.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_mcp_server.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_meta_analysis.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_meta_flow_report.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_metamorphic.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_metapath2vec.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_ml_embedding_primitives.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_monoplex_nx_wrapper.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_mpc.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_multilayer_centrality.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_multilayer_clustering_coefficients.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_multilayer_cornercases.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_multilayer_edge_fix.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_multilayer_embedding_models.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_multilayer_integration.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_multilayer_leiden_uq.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_multilayer_modularity.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_multilayer_quality_metrics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_multilayer_statistics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_multilayer_visualizations.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_multinet_aggregation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_multinet_aggregation_additional.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_multiplex_layer_interop.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_multiplex_participation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_multiplex_properties.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_multirank.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_multixrank.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_network_conversion.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_network_version.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_networkx_compatibility.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_new_algorithms.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_new_multilayer_metrics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_node_edge_parity.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_node_ranking_comprehensive.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_norc.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_nullmodel_sanity.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_nullmodels.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_nullmodels_contracts.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_nx_compat_extended.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_ollivier_ricci_multilayer.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_optimizer_submodules.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_out_of_core.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_parallel.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_parallel_execution.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_parsers_comprehensive.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_parsers_coverage.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_partition_uq.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_partition_uq_integration.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_paths.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_paths_additional.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_paths_contracts.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_paths_executor.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_paths_result.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_performance_core.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_pipeline.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_plugin_examples.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_plugin_system.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_plugins.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_plugins_contracts.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_profiling.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_profiling_additional.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_program.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_program_cost_executor.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_properties.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_provenance_canonical.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_provenance_replay.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_provenance_schema.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_public_api_exports.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_pymnet_style.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_pypi_publish_workflow.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_query_algebra.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_query_equivalence.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_r_interop.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_random_generators_additional.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_random_generators_extended.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_random_walkers.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_random_walks.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_readme_contributor_onboarding.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_readme_flagship_example.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_requirements.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_result_explain_debug.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_ricci_visualization.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_robustness.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_robustness_additional.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_robustness_testing.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_root_conftest.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_roundtrip_invariants.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_run_quickstart_snippets.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_sankey_visualization.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_sbm_autocommunity.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_sbm_generator.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_sbm_metrics.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_sbm_runner_integration.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_schema_and_immutable.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_seeding.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_selection_uq.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_selection_uq_empty_groups.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_selection_uq_integration.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_semiring_negative_cases.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_semiring_pareto.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_semiring_registry.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_semiring_types.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_semiring_verification.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_sensitivity_executor.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_sidecar.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_sir_epidemic.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_sir_multiplex.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_spectral_multilayer.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_statistical_report.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_stats_comparison.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_stats_core.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_stats_edge_cases.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_stats_provenance.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_stats_provenance_dataclass.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_stats_registry.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_stats_scalar_uncertainty.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_stats_verify.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_stratified_uq.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_streaming_topk.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_successive_halving.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_supporting_extended.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_supra_matrix_function_centrality.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_temporal.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_temporal_algorithms.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_temporal_builder.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_temporal_dsl.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_temporal_duration_parsing.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_temporal_multinet.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_temporal_utils.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_temporal_utils_extended.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_temporal_view.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_temporal_windowed_queries.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_tensor_representation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_tutorial_10min.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_uncertainty.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_uncertainty_additional.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_uncertainty_builder_integration.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_uncertainty_defaults.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_uncertainty_dsl_integration.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_uncertainty_engines.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_uncertainty_oracles.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_uncertainty_runner.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_uq_algebra.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_uq_integration.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_uq_resolution.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_uq_spine.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_user_journey_simulation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_utils.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_utils_coverage.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_utils_extended.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_validation.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_validation_module.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_verification_api_differential.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_verification_centrality.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_verification_communities.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_verification_determinism_parallelism.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_verification_dsl_equivalence.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_verification_metamorphic_harness.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_verification_provenance_oracles.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_versatility.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_visualization_benchmark.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_visualization_bezier.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_visualization_colors.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_visualization_imports.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_visualization_layouts.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_visualization_multilayer_additional.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_visualization_polyfit.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_visualization_ricci_layout_helpers.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_visualization_supra_heatmap.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_visualize_matrix_fix.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_workflows.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_wrappers_additional.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_wrappers_benchmark_nodes.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_wrappers_node2vec.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_wrappers_r_interop.py +0 -0
- {py3plex-1.1.7 → py3plex-2.0.0}/tests/test_wrappers_train_node2vec.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: py3plex
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: A Multilayer network analysis python3 library
|
|
5
5
|
Author-email: Blaž Škrlj <blaz.skrlj@ijs.si>
|
|
6
6
|
License: MIT
|
|
@@ -113,7 +113,7 @@ Dynamic: license-file
|
|
|
113
113
|

|
|
114
114
|

|
|
115
115
|

|
|
116
|
-

|
|
117
117
|
|
|
118
118
|
*Multilayer networks* are complex networks with additional information assigned to nodes or edges (or both). This library includes
|
|
119
119
|
some of the state-of-the-art algorithms for decomposition, visualization and analysis of such networks.
|
|
@@ -200,6 +200,30 @@ Use a strict two-phase flow:
|
|
|
200
200
|
- **Interpretability**: `.explain()` enriches results with community IDs, top interaction partners, and layer presence
|
|
201
201
|
- **Composite scoring**: Weighted combination of multiple centrality measures for robust ranking
|
|
202
202
|
|
|
203
|
+
### Ecosystem positioning
|
|
204
|
+
|
|
205
|
+
| Comparator | Ecosystem | Primary scope | Where it overlaps with py3plex 2.0 | py3plex 2.0 positioning |
|
|
206
|
+
|---|---|---|---|---|
|
|
207
|
+
| **py3plex 2019** | Python | Multilayer network visualization and analysis | Direct historical predecessor: multilayer representation, aggregation, indexing, traversal, visualization, and embedding-assisted layouts | **Historical foundation.** py3plex 2.0 extends the original toolkit from visualization-oriented analysis into a reproducible, query-driven multilayer network science environment. |
|
|
208
|
+
| **pymnet** | Python | General multilayer network representation, metrics, random models, and visualization | Strong overlap on formal multilayer data structures, multilayer metrics, transformations, random models, and visualization | **Closest Python multilayer comparator.** pymnet is strongest as a formal multilayer framework; py3plex 2.0 is strongest as a workflow, DSL, uncertainty, and reproducibility layer. |
|
|
209
|
+
| **MultiNetX** | Python / NetworkX | NetworkX-style multilayer graph manipulation, spectral analysis, and visualization | Overlap on Python-native multilayer graph objects, supra-adjacency/Laplacian workflows, and visualization | **Lightweight Python comparator.** MultiNetX provides compact multilayer graph utilities; py3plex 2.0 provides a broader end-to-end analysis and workflow environment. |
|
|
210
|
+
| **muxViz** | R / desktop ecosystem | Multilayer and multiplex visual analytics | Overlap on multilayer visualization, centrality, community detection, motifs, structural reducibility, and dynamic visualization | **R visual-analytics comparator.** muxViz is strongest for visual exploration; py3plex 2.0 emphasizes Python-native, scriptable, DSL-driven, reproducible analysis. |
|
|
211
|
+
| **R `multinet`** | R | Multiplex and multilayer social-network analysis and mining | Overlap on multilayer representation, import/export, attributes, centrality, community detection, generation, and plotting | **R social-network comparator.** `multinet` is strongest for multiplex social-network analysis; py3plex 2.0 targets broader heterogeneous scientific multilayer workflows in Python. |
|
|
212
|
+
| **tnetwork** | Python | Temporal-network manipulation and dynamic communities | Overlap on temporal slicing, dynamic graphs, and evolving-community analysis | **Temporal-community comparator.** tnetwork focuses on temporal community workflows; py3plex 2.0 embeds temporal analysis inside a broader multilayer DSL/workflow stack. |
|
|
213
|
+
| **DyNetx** | Python / NetworkX | Dynamic graph extension for NetworkX | Overlap on time-varying graph representation, snapshots, interaction streams, and temporal slicing | **Dynamic-NetworkX comparator.** DyNetx handles dynamic graphs; py3plex 2.0 adds multilayer semantics, declarative analysis, integrated dynamics, and reusable workflows. |
|
|
214
|
+
| **Reticula** | Python with C++ core | Fast static and temporal network / hypergraph analysis | Overlap on temporal networks, reachability, randomized models, and dynamical-process analysis | **Performance temporal/hypergraph comparator.** Reticula is stronger for fast temporal and hypergraph analysis; py3plex 2.0 is stronger for multilayer workflow integration and analyst ergonomics. |
|
|
215
|
+
| **Raphtory** | Rust / Python | Temporal graph engine and deployment platform | Overlap on temporal graph views, time-aware querying, reachability, motifs, and deployment-oriented graph analysis | **Modern temporal-engine comparator.** Raphtory is an engine/platform; py3plex 2.0 is a multilayer network-science workflow layer with DSL, uncertainty, dynamics, and reproducible analysis. |
|
|
216
|
+
| **pathpy / pathpyG** | Python / PyTorch ecosystem | Path-centric temporal-network analytics and graph learning | Overlap on temporal analytics, time-respecting paths, temporal centralities, visualization, and graph-learning handoff | **Temporal graph-learning comparator.** pathpy/pathpyG is adjacent; py3plex 2.0 focuses on multilayer network science, layer-aware querying, uncertainty, and reproducible workflows. |
|
|
217
|
+
| **NetworkX** | Python | General graph creation, manipulation, and algorithms | Overlap on core graph algorithms, graph data structures, centrality, communities, and Python graph workflows | **General graph substrate.** NetworkX is the base graph ecosystem; py3plex 2.0 adds multilayer semantics, DSL queries, layer algebra, temporal/dynamics workflows, and structured outputs. |
|
|
218
|
+
| **igraph** | C / R / Python | Efficient general-purpose network analysis | Overlap on centrality, community detection, graph transformations, and scalable graph analysis | **Efficient general-graph comparator.** igraph is the speed/breadth baseline; py3plex 2.0 differentiates through multilayer-specific workflows and reproducible analyst interfaces. |
|
|
219
|
+
| **graph-tool** | Python with C++ core | High-performance graph algorithms and statistical network modeling | Overlap on large-network statistics, community detection, inference, and performance-sensitive graph analysis | **Performance/statistical comparator.** graph-tool is strongest for efficient statistical graph analysis; py3plex 2.0 prioritizes multilayer expressiveness, querying, uncertainty, and workflow integration. |
|
|
220
|
+
| **tidygraph** | R / tidyverse | Tidy, dplyr-style graph manipulation | Overlap on chainable, analyst-friendly node/edge manipulation and graph-as-table workflows | **Analyst-grammar comparator.** tidygraph motivates fluent graph manipulation; py3plex 2.0 adapts this style to Python multilayer networks with DSL, builder APIs, and layer-aware grouping. |
|
|
221
|
+
| **NDlib** | Python | Diffusion and epidemic processes on networks | Overlap on SIS/SIR-style processes, random walks, spreading dynamics, and simulation workflows | **Dynamics comparator.** NDlib specializes in diffusion; py3plex 2.0 embeds dynamics inside multilayer, temporal, queryable, uncertainty-aware workflows. |
|
|
222
|
+
| **PyTorch Geometric** | Python / PyTorch | Graph neural networks and geometric deep learning | Overlap on graph embeddings, graph data preparation, and downstream graph-learning workflows | **Graph-ML comparator.** PyG trains graph neural models; py3plex 2.0 prepares, queries, explains, summarizes, and analyzes multilayer networks. |
|
|
223
|
+
| **DGL** | Python / deep-learning frameworks | Scalable graph deep learning and message passing | Overlap on heterogeneous graph processing, graph learning, and scalable graph ML pipelines | **Scalable graph-ML comparator.** DGL addresses GNN systems engineering; py3plex 2.0 addresses multilayer network science, query abstractions, uncertainty, temporal analysis, and workflows. |
|
|
224
|
+
| **Neo4j / Cypher** | Database systems | Persistent property-graph storage and declarative graph querying | Overlap on declarative graph querying and pattern-style graph access | **Graph-query comparator.** Cypher queries persistent property graphs; py3plex 2.0 provides an in-memory scientific DSL for multilayer network analysis, metrics, uncertainty, and exports. |
|
|
225
|
+
| **py3plex 2.0** | Python | Query-driven, reproducible multilayer network analysis | Integrates capabilities otherwise spread across multilayer libraries, temporal engines, graph libraries, graph-ML frameworks, graph-query systems, and workflow tools | **Current version** py3plex 2.0 is best framed as a Python-native workflow layer for multilayer network science: DSL + builder API, layer algebra, QueryResult exports, uncertainty-first statistics, temporal/dynamics workflows, null models, CLI/config execution, and agent-facing interfaces. |
|
|
226
|
+
|
|
203
227
|

|
|
204
228
|
|
|
205
229
|
## Getting Started
|
|
@@ -275,6 +299,7 @@ Safety notes for contributors:
|
|
|
275
299
|
- Keep changes focused and add tests next to the feature you modify.
|
|
276
300
|
- Do not add new markdown files unless explicitly requested (enforced by `tests/test_link_checker.py` to prevent documentation drift).
|
|
277
301
|
- Prefer running targeted tests first, then broader checks before opening a PR.
|
|
302
|
+
- For docs-only updates, run `make docs-check` before opening a PR.
|
|
278
303
|
|
|
279
304
|
### MCP Integration (AI Agents)
|
|
280
305
|
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|

|
|
15
15
|

|
|
16
16
|

|
|
17
|
-

|
|
18
18
|
|
|
19
19
|
*Multilayer networks* are complex networks with additional information assigned to nodes or edges (or both). This library includes
|
|
20
20
|
some of the state-of-the-art algorithms for decomposition, visualization and analysis of such networks.
|
|
@@ -101,6 +101,30 @@ Use a strict two-phase flow:
|
|
|
101
101
|
- **Interpretability**: `.explain()` enriches results with community IDs, top interaction partners, and layer presence
|
|
102
102
|
- **Composite scoring**: Weighted combination of multiple centrality measures for robust ranking
|
|
103
103
|
|
|
104
|
+
### Ecosystem positioning
|
|
105
|
+
|
|
106
|
+
| Comparator | Ecosystem | Primary scope | Where it overlaps with py3plex 2.0 | py3plex 2.0 positioning |
|
|
107
|
+
|---|---|---|---|---|
|
|
108
|
+
| **py3plex 2019** | Python | Multilayer network visualization and analysis | Direct historical predecessor: multilayer representation, aggregation, indexing, traversal, visualization, and embedding-assisted layouts | **Historical foundation.** py3plex 2.0 extends the original toolkit from visualization-oriented analysis into a reproducible, query-driven multilayer network science environment. |
|
|
109
|
+
| **pymnet** | Python | General multilayer network representation, metrics, random models, and visualization | Strong overlap on formal multilayer data structures, multilayer metrics, transformations, random models, and visualization | **Closest Python multilayer comparator.** pymnet is strongest as a formal multilayer framework; py3plex 2.0 is strongest as a workflow, DSL, uncertainty, and reproducibility layer. |
|
|
110
|
+
| **MultiNetX** | Python / NetworkX | NetworkX-style multilayer graph manipulation, spectral analysis, and visualization | Overlap on Python-native multilayer graph objects, supra-adjacency/Laplacian workflows, and visualization | **Lightweight Python comparator.** MultiNetX provides compact multilayer graph utilities; py3plex 2.0 provides a broader end-to-end analysis and workflow environment. |
|
|
111
|
+
| **muxViz** | R / desktop ecosystem | Multilayer and multiplex visual analytics | Overlap on multilayer visualization, centrality, community detection, motifs, structural reducibility, and dynamic visualization | **R visual-analytics comparator.** muxViz is strongest for visual exploration; py3plex 2.0 emphasizes Python-native, scriptable, DSL-driven, reproducible analysis. |
|
|
112
|
+
| **R `multinet`** | R | Multiplex and multilayer social-network analysis and mining | Overlap on multilayer representation, import/export, attributes, centrality, community detection, generation, and plotting | **R social-network comparator.** `multinet` is strongest for multiplex social-network analysis; py3plex 2.0 targets broader heterogeneous scientific multilayer workflows in Python. |
|
|
113
|
+
| **tnetwork** | Python | Temporal-network manipulation and dynamic communities | Overlap on temporal slicing, dynamic graphs, and evolving-community analysis | **Temporal-community comparator.** tnetwork focuses on temporal community workflows; py3plex 2.0 embeds temporal analysis inside a broader multilayer DSL/workflow stack. |
|
|
114
|
+
| **DyNetx** | Python / NetworkX | Dynamic graph extension for NetworkX | Overlap on time-varying graph representation, snapshots, interaction streams, and temporal slicing | **Dynamic-NetworkX comparator.** DyNetx handles dynamic graphs; py3plex 2.0 adds multilayer semantics, declarative analysis, integrated dynamics, and reusable workflows. |
|
|
115
|
+
| **Reticula** | Python with C++ core | Fast static and temporal network / hypergraph analysis | Overlap on temporal networks, reachability, randomized models, and dynamical-process analysis | **Performance temporal/hypergraph comparator.** Reticula is stronger for fast temporal and hypergraph analysis; py3plex 2.0 is stronger for multilayer workflow integration and analyst ergonomics. |
|
|
116
|
+
| **Raphtory** | Rust / Python | Temporal graph engine and deployment platform | Overlap on temporal graph views, time-aware querying, reachability, motifs, and deployment-oriented graph analysis | **Modern temporal-engine comparator.** Raphtory is an engine/platform; py3plex 2.0 is a multilayer network-science workflow layer with DSL, uncertainty, dynamics, and reproducible analysis. |
|
|
117
|
+
| **pathpy / pathpyG** | Python / PyTorch ecosystem | Path-centric temporal-network analytics and graph learning | Overlap on temporal analytics, time-respecting paths, temporal centralities, visualization, and graph-learning handoff | **Temporal graph-learning comparator.** pathpy/pathpyG is adjacent; py3plex 2.0 focuses on multilayer network science, layer-aware querying, uncertainty, and reproducible workflows. |
|
|
118
|
+
| **NetworkX** | Python | General graph creation, manipulation, and algorithms | Overlap on core graph algorithms, graph data structures, centrality, communities, and Python graph workflows | **General graph substrate.** NetworkX is the base graph ecosystem; py3plex 2.0 adds multilayer semantics, DSL queries, layer algebra, temporal/dynamics workflows, and structured outputs. |
|
|
119
|
+
| **igraph** | C / R / Python | Efficient general-purpose network analysis | Overlap on centrality, community detection, graph transformations, and scalable graph analysis | **Efficient general-graph comparator.** igraph is the speed/breadth baseline; py3plex 2.0 differentiates through multilayer-specific workflows and reproducible analyst interfaces. |
|
|
120
|
+
| **graph-tool** | Python with C++ core | High-performance graph algorithms and statistical network modeling | Overlap on large-network statistics, community detection, inference, and performance-sensitive graph analysis | **Performance/statistical comparator.** graph-tool is strongest for efficient statistical graph analysis; py3plex 2.0 prioritizes multilayer expressiveness, querying, uncertainty, and workflow integration. |
|
|
121
|
+
| **tidygraph** | R / tidyverse | Tidy, dplyr-style graph manipulation | Overlap on chainable, analyst-friendly node/edge manipulation and graph-as-table workflows | **Analyst-grammar comparator.** tidygraph motivates fluent graph manipulation; py3plex 2.0 adapts this style to Python multilayer networks with DSL, builder APIs, and layer-aware grouping. |
|
|
122
|
+
| **NDlib** | Python | Diffusion and epidemic processes on networks | Overlap on SIS/SIR-style processes, random walks, spreading dynamics, and simulation workflows | **Dynamics comparator.** NDlib specializes in diffusion; py3plex 2.0 embeds dynamics inside multilayer, temporal, queryable, uncertainty-aware workflows. |
|
|
123
|
+
| **PyTorch Geometric** | Python / PyTorch | Graph neural networks and geometric deep learning | Overlap on graph embeddings, graph data preparation, and downstream graph-learning workflows | **Graph-ML comparator.** PyG trains graph neural models; py3plex 2.0 prepares, queries, explains, summarizes, and analyzes multilayer networks. |
|
|
124
|
+
| **DGL** | Python / deep-learning frameworks | Scalable graph deep learning and message passing | Overlap on heterogeneous graph processing, graph learning, and scalable graph ML pipelines | **Scalable graph-ML comparator.** DGL addresses GNN systems engineering; py3plex 2.0 addresses multilayer network science, query abstractions, uncertainty, temporal analysis, and workflows. |
|
|
125
|
+
| **Neo4j / Cypher** | Database systems | Persistent property-graph storage and declarative graph querying | Overlap on declarative graph querying and pattern-style graph access | **Graph-query comparator.** Cypher queries persistent property graphs; py3plex 2.0 provides an in-memory scientific DSL for multilayer network analysis, metrics, uncertainty, and exports. |
|
|
126
|
+
| **py3plex 2.0** | Python | Query-driven, reproducible multilayer network analysis | Integrates capabilities otherwise spread across multilayer libraries, temporal engines, graph libraries, graph-ML frameworks, graph-query systems, and workflow tools | **Current version** py3plex 2.0 is best framed as a Python-native workflow layer for multilayer network science: DSL + builder API, layer algebra, QueryResult exports, uncertainty-first statistics, temporal/dynamics workflows, null models, CLI/config execution, and agent-facing interfaces. |
|
|
127
|
+
|
|
104
128
|

|
|
105
129
|
|
|
106
130
|
## Getting Started
|
|
@@ -176,6 +200,7 @@ Safety notes for contributors:
|
|
|
176
200
|
- Keep changes focused and add tests next to the feature you modify.
|
|
177
201
|
- Do not add new markdown files unless explicitly requested (enforced by `tests/test_link_checker.py` to prevent documentation drift).
|
|
178
202
|
- Prefer running targeted tests first, then broader checks before opening a PR.
|
|
203
|
+
- For docs-only updates, run `make docs-check` before opening a PR.
|
|
179
204
|
|
|
180
205
|
### MCP Integration (AI Agents)
|
|
181
206
|
|
|
@@ -51,8 +51,8 @@ For detailed documentation, see: https://skblaz.github.io/py3plex/
|
|
|
51
51
|
"""
|
|
52
52
|
|
|
53
53
|
# Version information
|
|
54
|
-
__version__ = "
|
|
55
|
-
__api_version__ = "
|
|
54
|
+
__version__ = "2.0.0"
|
|
55
|
+
__api_version__ = "2.0.0"
|
|
56
56
|
|
|
57
57
|
from py3plex.core.multinet import multi_layer_network
|
|
58
58
|
from py3plex.core.types import (
|
{py3plex-1.1.7 → py3plex-2.0.0}/py3plex/algorithms/community_detection/autocommunity_executor.py
RENAMED
|
@@ -1221,7 +1221,7 @@ def execute_autocommunity_sh(
|
|
|
1221
1221
|
import importlib.metadata
|
|
1222
1222
|
py3plex_version = importlib.metadata.version('py3plex')
|
|
1223
1223
|
except Exception:
|
|
1224
|
-
|
|
1224
|
+
from py3plex import __version__ as py3plex_version
|
|
1225
1225
|
|
|
1226
1226
|
provenance = {
|
|
1227
1227
|
'engine': 'autocommunity_successive_halving',
|
|
@@ -218,8 +218,8 @@ WARN_DEPRECATED: bool = True
|
|
|
218
218
|
# Library Metadata
|
|
219
219
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
220
220
|
|
|
221
|
-
__api_version__ = "
|
|
222
|
-
__version__ = "
|
|
221
|
+
__api_version__ = "2.0.0"
|
|
222
|
+
__version__ = "2.0.0"
|
|
223
223
|
|
|
224
224
|
# ─────────────────────────────────────────────────────────────────────────────
|
|
225
225
|
# Helper Functions
|
|
@@ -293,6 +293,11 @@ class ComputeItem:
|
|
|
293
293
|
random_state: Optional[int] = None
|
|
294
294
|
approx: Optional["ApproximationSpec"] = None
|
|
295
295
|
kind: Optional[str] = None
|
|
296
|
+
# Tracks whether compute() explicitly received uncertainty=...
|
|
297
|
+
# None: omitted (query-level UQ may apply)
|
|
298
|
+
# True: explicitly enabled
|
|
299
|
+
# False: explicitly disabled (query-level UQ opt-out for this metric)
|
|
300
|
+
uncertainty_explicit: Optional[bool] = None
|
|
296
301
|
|
|
297
302
|
@property
|
|
298
303
|
def result_name(self) -> str:
|
|
@@ -917,6 +917,7 @@ class QueryBuilder:
|
|
|
917
917
|
random_state=random_state,
|
|
918
918
|
approx=measure_approx_spec,
|
|
919
919
|
kind=kind,
|
|
920
|
+
uncertainty_explicit=uncertainty,
|
|
920
921
|
)
|
|
921
922
|
)
|
|
922
923
|
elif alias and len(measures) == 1:
|
|
@@ -947,6 +948,7 @@ class QueryBuilder:
|
|
|
947
948
|
random_state=random_state,
|
|
948
949
|
approx=measure_approx_spec,
|
|
949
950
|
kind=kind,
|
|
951
|
+
uncertainty_explicit=uncertainty,
|
|
950
952
|
)
|
|
951
953
|
)
|
|
952
954
|
else:
|
|
@@ -977,6 +979,7 @@ class QueryBuilder:
|
|
|
977
979
|
random_state=random_state,
|
|
978
980
|
approx=measure_approx_spec,
|
|
979
981
|
kind=kind,
|
|
982
|
+
uncertainty_explicit=uncertainty,
|
|
980
983
|
)
|
|
981
984
|
)
|
|
982
985
|
|
|
@@ -290,13 +290,14 @@ def resolve_uq_config(
|
|
|
290
290
|
compute_item.n_null is not None,
|
|
291
291
|
])
|
|
292
292
|
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
#
|
|
293
|
+
# Tri-state semantics:
|
|
294
|
+
# - uncertainty_explicit is None: not provided, query-level UQ may apply
|
|
295
|
+
# - uncertainty_explicit is True: explicit enable
|
|
296
|
+
# - uncertainty_explicit is False: explicit disable for this metric unless
|
|
297
|
+
# metric-level UQ params are also provided.
|
|
298
|
+
if compute_item.uncertainty_explicit is False and not has_metric_uq_params:
|
|
299
|
+
# Explicit opt-out from query-level .uq(...), unlike the default None case.
|
|
300
|
+
return None
|
|
300
301
|
|
|
301
302
|
# Check if UQ is explicitly enabled at metric or query level
|
|
302
303
|
uq_enabled = (
|
|
@@ -407,48 +407,6 @@ def get_multilayer_dataset_path(relative_path: str) -> str:
|
|
|
407
407
|
return get_data_path(f"multilayer_datasets/{relative_path}")
|
|
408
408
|
|
|
409
409
|
|
|
410
|
-
def get_background_knowledge_path(filename: str) -> str:
|
|
411
|
-
"""
|
|
412
|
-
Get the absolute path to a background knowledge file or directory.
|
|
413
|
-
|
|
414
|
-
Convenience wrapper around get_data_path() specifically for background knowledge files.
|
|
415
|
-
|
|
416
|
-
Args:
|
|
417
|
-
filename: Name or relative path of the background knowledge file.
|
|
418
|
-
Use empty string or '.' to get the background_knowledge directory itself.
|
|
419
|
-
|
|
420
|
-
Returns:
|
|
421
|
-
str: Absolute path to the background knowledge file or directory
|
|
422
|
-
|
|
423
|
-
Examples:
|
|
424
|
-
>>> from py3plex.utils import get_background_knowledge_path
|
|
425
|
-
>>> path = get_background_knowledge_path("bk.n3")
|
|
426
|
-
>>> dir_path = get_background_knowledge_path(".")
|
|
427
|
-
"""
|
|
428
|
-
# If the filename already includes "background_knowledge/", use it as-is
|
|
429
|
-
if filename.startswith("background_knowledge/"):
|
|
430
|
-
return get_data_path(filename)
|
|
431
|
-
# If empty string or '.', return the directory itself
|
|
432
|
-
if not filename or filename == '.':
|
|
433
|
-
return get_data_path("background_knowledge")
|
|
434
|
-
# Otherwise, prepend "background_knowledge/"
|
|
435
|
-
return get_data_path(f"background_knowledge/{filename}")
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
def get_background_knowledge_dir() -> str:
|
|
439
|
-
"""
|
|
440
|
-
Get the absolute path to the background knowledge directory.
|
|
441
|
-
|
|
442
|
-
Returns:
|
|
443
|
-
str: Absolute path to the background_knowledge directory
|
|
444
|
-
|
|
445
|
-
Examples:
|
|
446
|
-
>>> from py3plex.utils import get_background_knowledge_dir
|
|
447
|
-
>>> dir_path = get_background_knowledge_dir()
|
|
448
|
-
"""
|
|
449
|
-
return get_data_path("background_knowledge")
|
|
450
|
-
|
|
451
|
-
|
|
452
410
|
def get_layer_names(network) -> list:
|
|
453
411
|
"""
|
|
454
412
|
Extract layer names from a multilayer network.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: py3plex
|
|
3
|
-
Version:
|
|
3
|
+
Version: 2.0.0
|
|
4
4
|
Summary: A Multilayer network analysis python3 library
|
|
5
5
|
Author-email: Blaž Škrlj <blaz.skrlj@ijs.si>
|
|
6
6
|
License: MIT
|
|
@@ -113,7 +113,7 @@ Dynamic: license-file
|
|
|
113
113
|

|
|
114
114
|

|
|
115
115
|

|
|
116
|
-

|
|
117
117
|
|
|
118
118
|
*Multilayer networks* are complex networks with additional information assigned to nodes or edges (or both). This library includes
|
|
119
119
|
some of the state-of-the-art algorithms for decomposition, visualization and analysis of such networks.
|
|
@@ -200,6 +200,30 @@ Use a strict two-phase flow:
|
|
|
200
200
|
- **Interpretability**: `.explain()` enriches results with community IDs, top interaction partners, and layer presence
|
|
201
201
|
- **Composite scoring**: Weighted combination of multiple centrality measures for robust ranking
|
|
202
202
|
|
|
203
|
+
### Ecosystem positioning
|
|
204
|
+
|
|
205
|
+
| Comparator | Ecosystem | Primary scope | Where it overlaps with py3plex 2.0 | py3plex 2.0 positioning |
|
|
206
|
+
|---|---|---|---|---|
|
|
207
|
+
| **py3plex 2019** | Python | Multilayer network visualization and analysis | Direct historical predecessor: multilayer representation, aggregation, indexing, traversal, visualization, and embedding-assisted layouts | **Historical foundation.** py3plex 2.0 extends the original toolkit from visualization-oriented analysis into a reproducible, query-driven multilayer network science environment. |
|
|
208
|
+
| **pymnet** | Python | General multilayer network representation, metrics, random models, and visualization | Strong overlap on formal multilayer data structures, multilayer metrics, transformations, random models, and visualization | **Closest Python multilayer comparator.** pymnet is strongest as a formal multilayer framework; py3plex 2.0 is strongest as a workflow, DSL, uncertainty, and reproducibility layer. |
|
|
209
|
+
| **MultiNetX** | Python / NetworkX | NetworkX-style multilayer graph manipulation, spectral analysis, and visualization | Overlap on Python-native multilayer graph objects, supra-adjacency/Laplacian workflows, and visualization | **Lightweight Python comparator.** MultiNetX provides compact multilayer graph utilities; py3plex 2.0 provides a broader end-to-end analysis and workflow environment. |
|
|
210
|
+
| **muxViz** | R / desktop ecosystem | Multilayer and multiplex visual analytics | Overlap on multilayer visualization, centrality, community detection, motifs, structural reducibility, and dynamic visualization | **R visual-analytics comparator.** muxViz is strongest for visual exploration; py3plex 2.0 emphasizes Python-native, scriptable, DSL-driven, reproducible analysis. |
|
|
211
|
+
| **R `multinet`** | R | Multiplex and multilayer social-network analysis and mining | Overlap on multilayer representation, import/export, attributes, centrality, community detection, generation, and plotting | **R social-network comparator.** `multinet` is strongest for multiplex social-network analysis; py3plex 2.0 targets broader heterogeneous scientific multilayer workflows in Python. |
|
|
212
|
+
| **tnetwork** | Python | Temporal-network manipulation and dynamic communities | Overlap on temporal slicing, dynamic graphs, and evolving-community analysis | **Temporal-community comparator.** tnetwork focuses on temporal community workflows; py3plex 2.0 embeds temporal analysis inside a broader multilayer DSL/workflow stack. |
|
|
213
|
+
| **DyNetx** | Python / NetworkX | Dynamic graph extension for NetworkX | Overlap on time-varying graph representation, snapshots, interaction streams, and temporal slicing | **Dynamic-NetworkX comparator.** DyNetx handles dynamic graphs; py3plex 2.0 adds multilayer semantics, declarative analysis, integrated dynamics, and reusable workflows. |
|
|
214
|
+
| **Reticula** | Python with C++ core | Fast static and temporal network / hypergraph analysis | Overlap on temporal networks, reachability, randomized models, and dynamical-process analysis | **Performance temporal/hypergraph comparator.** Reticula is stronger for fast temporal and hypergraph analysis; py3plex 2.0 is stronger for multilayer workflow integration and analyst ergonomics. |
|
|
215
|
+
| **Raphtory** | Rust / Python | Temporal graph engine and deployment platform | Overlap on temporal graph views, time-aware querying, reachability, motifs, and deployment-oriented graph analysis | **Modern temporal-engine comparator.** Raphtory is an engine/platform; py3plex 2.0 is a multilayer network-science workflow layer with DSL, uncertainty, dynamics, and reproducible analysis. |
|
|
216
|
+
| **pathpy / pathpyG** | Python / PyTorch ecosystem | Path-centric temporal-network analytics and graph learning | Overlap on temporal analytics, time-respecting paths, temporal centralities, visualization, and graph-learning handoff | **Temporal graph-learning comparator.** pathpy/pathpyG is adjacent; py3plex 2.0 focuses on multilayer network science, layer-aware querying, uncertainty, and reproducible workflows. |
|
|
217
|
+
| **NetworkX** | Python | General graph creation, manipulation, and algorithms | Overlap on core graph algorithms, graph data structures, centrality, communities, and Python graph workflows | **General graph substrate.** NetworkX is the base graph ecosystem; py3plex 2.0 adds multilayer semantics, DSL queries, layer algebra, temporal/dynamics workflows, and structured outputs. |
|
|
218
|
+
| **igraph** | C / R / Python | Efficient general-purpose network analysis | Overlap on centrality, community detection, graph transformations, and scalable graph analysis | **Efficient general-graph comparator.** igraph is the speed/breadth baseline; py3plex 2.0 differentiates through multilayer-specific workflows and reproducible analyst interfaces. |
|
|
219
|
+
| **graph-tool** | Python with C++ core | High-performance graph algorithms and statistical network modeling | Overlap on large-network statistics, community detection, inference, and performance-sensitive graph analysis | **Performance/statistical comparator.** graph-tool is strongest for efficient statistical graph analysis; py3plex 2.0 prioritizes multilayer expressiveness, querying, uncertainty, and workflow integration. |
|
|
220
|
+
| **tidygraph** | R / tidyverse | Tidy, dplyr-style graph manipulation | Overlap on chainable, analyst-friendly node/edge manipulation and graph-as-table workflows | **Analyst-grammar comparator.** tidygraph motivates fluent graph manipulation; py3plex 2.0 adapts this style to Python multilayer networks with DSL, builder APIs, and layer-aware grouping. |
|
|
221
|
+
| **NDlib** | Python | Diffusion and epidemic processes on networks | Overlap on SIS/SIR-style processes, random walks, spreading dynamics, and simulation workflows | **Dynamics comparator.** NDlib specializes in diffusion; py3plex 2.0 embeds dynamics inside multilayer, temporal, queryable, uncertainty-aware workflows. |
|
|
222
|
+
| **PyTorch Geometric** | Python / PyTorch | Graph neural networks and geometric deep learning | Overlap on graph embeddings, graph data preparation, and downstream graph-learning workflows | **Graph-ML comparator.** PyG trains graph neural models; py3plex 2.0 prepares, queries, explains, summarizes, and analyzes multilayer networks. |
|
|
223
|
+
| **DGL** | Python / deep-learning frameworks | Scalable graph deep learning and message passing | Overlap on heterogeneous graph processing, graph learning, and scalable graph ML pipelines | **Scalable graph-ML comparator.** DGL addresses GNN systems engineering; py3plex 2.0 addresses multilayer network science, query abstractions, uncertainty, temporal analysis, and workflows. |
|
|
224
|
+
| **Neo4j / Cypher** | Database systems | Persistent property-graph storage and declarative graph querying | Overlap on declarative graph querying and pattern-style graph access | **Graph-query comparator.** Cypher queries persistent property graphs; py3plex 2.0 provides an in-memory scientific DSL for multilayer network analysis, metrics, uncertainty, and exports. |
|
|
225
|
+
| **py3plex 2.0** | Python | Query-driven, reproducible multilayer network analysis | Integrates capabilities otherwise spread across multilayer libraries, temporal engines, graph libraries, graph-ML frameworks, graph-query systems, and workflow tools | **Current version** py3plex 2.0 is best framed as a Python-native workflow layer for multilayer network science: DSL + builder API, layer algebra, QueryResult exports, uncertainty-first statistics, temporal/dynamics workflows, null models, CLI/config execution, and agent-facing interfaces. |
|
|
226
|
+
|
|
203
227
|

|
|
204
228
|
|
|
205
229
|
## Getting Started
|
|
@@ -275,6 +299,7 @@ Safety notes for contributors:
|
|
|
275
299
|
- Keep changes focused and add tests next to the feature you modify.
|
|
276
300
|
- Do not add new markdown files unless explicitly requested (enforced by `tests/test_link_checker.py` to prevent documentation drift).
|
|
277
301
|
- Prefer running targeted tests first, then broader checks before opening a PR.
|
|
302
|
+
- For docs-only updates, run `make docs-check` before opening a PR.
|
|
278
303
|
|
|
279
304
|
### MCP Integration (AI Agents)
|
|
280
305
|
|
|
@@ -741,6 +741,7 @@ tests/test_meta_analysis.py
|
|
|
741
741
|
tests/test_meta_flow_report.py
|
|
742
742
|
tests/test_metamorphic.py
|
|
743
743
|
tests/test_metapath2vec.py
|
|
744
|
+
tests/test_ml_embedding_evaluation.py
|
|
744
745
|
tests/test_ml_embedding_primitives.py
|
|
745
746
|
tests/test_monoplex_nx_wrapper.py
|
|
746
747
|
tests/test_mpc.py
|
|
@@ -38,7 +38,7 @@ def test_conf_exposes_expected_metadata(conf_module):
|
|
|
38
38
|
module, expected_path = conf_module
|
|
39
39
|
|
|
40
40
|
assert module.project == "Practical Multilayer Network Analysis with Py3plex"
|
|
41
|
-
assert module.version == module.release == "
|
|
41
|
+
assert module.version == module.release == "2.0.0"
|
|
42
42
|
assert module.language == "en"
|
|
43
43
|
assert module.master_doc == "index"
|
|
44
44
|
assert module.templates_path == ["_templates"]
|
|
@@ -15,10 +15,10 @@ import pytest
|
|
|
15
15
|
"relative_path",
|
|
16
16
|
[
|
|
17
17
|
"datasets/community.dat",
|
|
18
|
+
"datasets/bk.n3",
|
|
18
19
|
"datasets/cora.mat",
|
|
19
20
|
"multilayer_datasets/aarhusCS/CS-Aarhus_multiplex.edges",
|
|
20
21
|
"multilayer_datasets/MLKing/MLKing2013_multiplex.edges",
|
|
21
|
-
"background_knowledge/bk.n3",
|
|
22
22
|
"example_images/communities.png",
|
|
23
23
|
],
|
|
24
24
|
)
|
|
@@ -15,7 +15,6 @@ def load_example_with_fakes(monkeypatch):
|
|
|
15
15
|
"""Load the CBSSD example with lightweight fakes to observe side effects."""
|
|
16
16
|
record = []
|
|
17
17
|
dataset_calls = []
|
|
18
|
-
data_calls = []
|
|
19
18
|
context = {}
|
|
20
19
|
fake_partition = {"P12345": 1, "Q8ABC1": 2}
|
|
21
20
|
|
|
@@ -54,16 +53,6 @@ def load_example_with_fakes(monkeypatch):
|
|
|
54
53
|
record.append(("get_dataset_path", name, path))
|
|
55
54
|
return path
|
|
56
55
|
|
|
57
|
-
def get_data_path(name):
|
|
58
|
-
path = f"/data/{name}"
|
|
59
|
-
data_calls.append((name, path))
|
|
60
|
-
record.append(("get_data_path", name, path))
|
|
61
|
-
return path
|
|
62
|
-
|
|
63
|
-
def get_background_knowledge_dir():
|
|
64
|
-
record.append(("get_background_knowledge_dir",))
|
|
65
|
-
return "/bkdir"
|
|
66
|
-
|
|
67
56
|
def louvain_communities(network):
|
|
68
57
|
record.append(("louvain_communities", network))
|
|
69
58
|
return fake_partition
|
|
@@ -106,8 +95,6 @@ def load_example_with_fakes(monkeypatch):
|
|
|
106
95
|
|
|
107
96
|
utils_mod = types.ModuleType("py3plex.utils")
|
|
108
97
|
utils_mod.get_dataset_path = get_dataset_path
|
|
109
|
-
utils_mod.get_data_path = get_data_path
|
|
110
|
-
utils_mod.get_background_knowledge_dir = get_background_knowledge_dir
|
|
111
98
|
|
|
112
99
|
algorithms_mod.hedwig = hedwig_mod
|
|
113
100
|
algorithms_mod.community_detection = community_detection_mod
|
|
@@ -135,7 +122,6 @@ def load_example_with_fakes(monkeypatch):
|
|
|
135
122
|
"module": module,
|
|
136
123
|
"record": record,
|
|
137
124
|
"dataset_calls": dataset_calls,
|
|
138
|
-
"data_calls": data_calls,
|
|
139
125
|
"context": context,
|
|
140
126
|
"fake_network": fake_network,
|
|
141
127
|
"fake_partition": fake_partition,
|
|
@@ -146,7 +132,6 @@ def test_cbssd_example_triggers_pipeline(monkeypatch, capsys):
|
|
|
146
132
|
result = load_example_with_fakes(monkeypatch)
|
|
147
133
|
record = result["record"]
|
|
148
134
|
dataset_calls = result["dataset_calls"]
|
|
149
|
-
data_calls = result["data_calls"]
|
|
150
135
|
fake_network = result["fake_network"]
|
|
151
136
|
fake_partition = result["fake_partition"]
|
|
152
137
|
out = capsys.readouterr().out
|
|
@@ -161,6 +146,7 @@ def test_cbssd_example_triggers_pipeline(monkeypatch, capsys):
|
|
|
161
146
|
"intact02.gpickle",
|
|
162
147
|
"example_partition_inputs.n3",
|
|
163
148
|
"goa_human.gaf.gz",
|
|
149
|
+
"bk.n3",
|
|
164
150
|
"go.obo.gz",
|
|
165
151
|
"goa_human.gaf.gz",
|
|
166
152
|
"example_partition_inputs.n3",
|
|
@@ -179,18 +165,17 @@ def test_cbssd_example_triggers_pipeline(monkeypatch, capsys):
|
|
|
179
165
|
rdf = result["context"]["rdf"]
|
|
180
166
|
assert rdf.serialized == [("/datasets/example_partition_inputs.n3", "n3")]
|
|
181
167
|
|
|
182
|
-
# background knowledge and OBO conversion use derived paths
|
|
183
|
-
assert data_calls == [("background_knowledge/bk.n3", "/data/background_knowledge/bk.n3")]
|
|
168
|
+
# background knowledge and OBO conversion use derived dataset paths
|
|
184
169
|
obo_call = next(entry for entry in record if entry[0] == "obo2n3")
|
|
185
170
|
assert obo_call[1:] == (
|
|
186
171
|
"/datasets/go.obo.gz",
|
|
187
|
-
"/
|
|
172
|
+
"/datasets/bk.n3",
|
|
188
173
|
"/datasets/goa_human.gaf.gz",
|
|
189
174
|
)
|
|
190
175
|
|
|
191
176
|
# rule learning parameters are propagated intact
|
|
192
177
|
run_params = result["context"]["run_params"]
|
|
193
|
-
assert run_params["bk_dir"] == "/
|
|
178
|
+
assert run_params["bk_dir"] == "/datasets"
|
|
194
179
|
assert run_params["data"] == "/datasets/example_partition_inputs.n3"
|
|
195
180
|
assert run_params["format"] == "n3"
|
|
196
181
|
assert run_params["beam"] == 300
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"""Focused tests for embedding evaluation helpers."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from unittest.mock import Mock
|
|
6
|
+
|
|
7
|
+
import numpy as np
|
|
8
|
+
import pytest
|
|
9
|
+
|
|
10
|
+
from py3plex.embeddings.base import EmbeddingResult
|
|
11
|
+
from py3plex.ml.embedding import evaluation
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def _embedding() -> EmbeddingResult:
|
|
15
|
+
matrix = np.array(
|
|
16
|
+
[
|
|
17
|
+
[1.0, 0.0, 0.5],
|
|
18
|
+
[0.9, 0.1, 0.4],
|
|
19
|
+
[0.0, 1.0, 0.2],
|
|
20
|
+
[0.1, 0.9, 0.3],
|
|
21
|
+
[0.8, 0.2, 0.1],
|
|
22
|
+
[0.2, 0.8, 0.6],
|
|
23
|
+
],
|
|
24
|
+
dtype=np.float32,
|
|
25
|
+
)
|
|
26
|
+
return EmbeddingResult(
|
|
27
|
+
matrix=matrix, item_ids=["a", "b", "c", "d", "e", "f"], method="test"
|
|
28
|
+
)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def test_edge_operator_hadamard_average_l1_l2():
|
|
32
|
+
u = np.array([1.0, 2.0], dtype=np.float32)
|
|
33
|
+
v = np.array([3.0, 4.0], dtype=np.float32)
|
|
34
|
+
|
|
35
|
+
np.testing.assert_allclose(evaluation.edge_operator(u, v, "hadamard"), np.array([3.0, 8.0]))
|
|
36
|
+
np.testing.assert_allclose(evaluation.edge_operator(u, v, "average"), np.array([2.0, 3.0]))
|
|
37
|
+
np.testing.assert_allclose(
|
|
38
|
+
evaluation.edge_operator(u, v, "weighted_l1"), np.array([2.0, 2.0])
|
|
39
|
+
)
|
|
40
|
+
np.testing.assert_allclose(
|
|
41
|
+
evaluation.edge_operator(u, v, "weighted_l2"), np.array([4.0, 4.0])
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def test_edge_operator_cosine_output():
|
|
46
|
+
u = np.array([1.0, 2.0], dtype=np.float32)
|
|
47
|
+
v = np.array([3.0, 4.0], dtype=np.float32)
|
|
48
|
+
cosine = evaluation.edge_operator(u, v, "cosine")
|
|
49
|
+
assert cosine.shape == (1,)
|
|
50
|
+
assert np.isfinite(cosine[0])
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def test_edge_operator_invalid_operator():
|
|
54
|
+
u = np.array([1.0, 2.0], dtype=np.float32)
|
|
55
|
+
v = np.array([3.0, 4.0], dtype=np.float32)
|
|
56
|
+
with pytest.raises(ValueError, match="Unknown edge operator"):
|
|
57
|
+
evaluation.edge_operator(u, v, "invalid")
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def test_build_edge_features_handles_empty_input_and_cosine_shape():
|
|
61
|
+
emb = _embedding()
|
|
62
|
+
|
|
63
|
+
empty_hadamard = evaluation.build_edge_features(emb, [], operator="hadamard")
|
|
64
|
+
assert empty_hadamard.shape == (0, emb.dim)
|
|
65
|
+
|
|
66
|
+
empty_cosine = evaluation.build_edge_features(emb, [], operator="cosine")
|
|
67
|
+
assert empty_cosine.shape == (0, 1)
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
def test_evaluate_link_prediction_embeddings_success_and_error():
|
|
71
|
+
emb = _embedding()
|
|
72
|
+
positive_edges = [("a", "b"), ("a", "d"), ("c", "d"), ("b", "d"), ("e", "f")]
|
|
73
|
+
negative_edges = [("a", "c"), ("b", "c"), ("a", "e"), ("b", "f"), ("c", "e")]
|
|
74
|
+
|
|
75
|
+
metrics = evaluation.evaluate_link_prediction_embeddings(
|
|
76
|
+
emb,
|
|
77
|
+
positive_edges,
|
|
78
|
+
negative_edges,
|
|
79
|
+
operator="average",
|
|
80
|
+
random_state=42,
|
|
81
|
+
)
|
|
82
|
+
assert set(metrics) == {"roc_auc", "average_precision"}
|
|
83
|
+
assert 0.0 <= metrics["roc_auc"] <= 1.0
|
|
84
|
+
assert 0.0 <= metrics["average_precision"] <= 1.0
|
|
85
|
+
|
|
86
|
+
with pytest.raises(ValueError, match="Both positive and negative edges"):
|
|
87
|
+
evaluation.evaluate_link_prediction_embeddings(
|
|
88
|
+
emb,
|
|
89
|
+
positive_edges,
|
|
90
|
+
[],
|
|
91
|
+
operator="hadamard",
|
|
92
|
+
random_state=42,
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def test_evaluate_link_prediction_helper():
|
|
97
|
+
auc = evaluation.evaluate_link_prediction([0, 0, 1, 1], [0.1, 0.2, 0.8, 0.9])
|
|
98
|
+
assert auc == pytest.approx(1.0)
|
|
99
|
+
|
|
100
|
+
|
|
101
|
+
def test_evaluate_node_classification_helper():
|
|
102
|
+
X = np.array(
|
|
103
|
+
[
|
|
104
|
+
[1.0, 0.0],
|
|
105
|
+
[0.9, 0.1],
|
|
106
|
+
[0.1, 0.9],
|
|
107
|
+
[0.0, 1.0],
|
|
108
|
+
[1.0, 0.1],
|
|
109
|
+
[0.1, 1.0],
|
|
110
|
+
],
|
|
111
|
+
dtype=np.float32,
|
|
112
|
+
)
|
|
113
|
+
y = [0, 0, 1, 1, 0, 1]
|
|
114
|
+
|
|
115
|
+
macro_f1 = evaluation.evaluate_node_classification(X, y, test_size=0.33, random_state=7)
|
|
116
|
+
assert 0.0 <= macro_f1 <= 1.0
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
def test_evaluate_clustering_helper():
|
|
120
|
+
clustering = evaluation.evaluate_clustering([0, 0, 1, 1], [0, 0, 1, 1])
|
|
121
|
+
assert clustering["NMI"] == pytest.approx(1.0)
|
|
122
|
+
assert clustering["ARI"] == pytest.approx(1.0)
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
def test_evaluate_node_classification_report_fallback_branch(monkeypatch):
|
|
126
|
+
X_train = np.array([[1.0, 0.0], [0.0, 1.0], [0.8, 0.2], [0.2, 0.8]], dtype=np.float32)
|
|
127
|
+
X_test = np.array([[0.9, 0.1], [0.1, 0.9]], dtype=np.float32)
|
|
128
|
+
y_train = np.array([0, 1, 0, 1])
|
|
129
|
+
y_test = np.array([0, 1])
|
|
130
|
+
|
|
131
|
+
split_mock = Mock(
|
|
132
|
+
side_effect=[
|
|
133
|
+
ValueError("forced split failure"),
|
|
134
|
+
(X_train, X_test, y_train, y_test),
|
|
135
|
+
]
|
|
136
|
+
)
|
|
137
|
+
monkeypatch.setattr(evaluation, "train_test_split", split_mock)
|
|
138
|
+
|
|
139
|
+
report = evaluation.evaluate_node_classification_report(
|
|
140
|
+
np.zeros((6, 2), dtype=np.float32),
|
|
141
|
+
[0, 1, 0, 1, 0, 1],
|
|
142
|
+
random_state=0,
|
|
143
|
+
)
|
|
144
|
+
|
|
145
|
+
assert split_mock.call_count == 2
|
|
146
|
+
assert set(report) == {"accuracy", "micro_f1", "macro_f1"}
|
|
147
|
+
assert 0.0 <= report["accuracy"] <= 1.0
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
def test_evaluate_node_classification_report_raises_when_fallback_also_fails(monkeypatch):
|
|
151
|
+
split_mock = Mock(side_effect=ValueError("split failed"))
|
|
152
|
+
monkeypatch.setattr(evaluation, "train_test_split", split_mock)
|
|
153
|
+
|
|
154
|
+
with pytest.raises(ValueError, match="split failed"):
|
|
155
|
+
evaluation.evaluate_node_classification_report(
|
|
156
|
+
np.zeros((6, 2), dtype=np.float32),
|
|
157
|
+
[0, 1, 0, 1, 0, 1],
|
|
158
|
+
random_state=0,
|
|
159
|
+
)
|