py3plex 2.0.8__tar.gz → 2.0.93__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (1033) hide show
  1. {py3plex-2.0.8/py3plex.egg-info → py3plex-2.0.93}/PKG-INFO +11 -7
  2. {py3plex-2.0.8 → py3plex-2.0.93}/README.md +6 -4
  3. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/_version.py +1 -1
  4. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/agent.py +1 -1
  5. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/attribute_correlation.py +10 -6
  6. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/centrality/approx_betweenness.py +20 -12
  7. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/centrality/approx_closeness.py +43 -44
  8. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/core/kb.py +4 -4
  9. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/layer_similarity.py +4 -2
  10. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/multilayer_algorithms/centrality.py +1 -1
  11. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/statistics/bayesiantests.py +4 -9
  12. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/statistics/critical_distances.py +34 -15
  13. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/temporal/centrality.py +21 -4
  14. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/benchmarks/runners.py +7 -2
  15. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/centrality/robustness.py +9 -0
  16. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/cli.py +27 -9
  17. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/compat/sidecar.py +3 -1
  18. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/core/lazy_evaluation.py +20 -2
  19. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/core/multinet.py +36 -26
  20. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/core/parsers.py +154 -63
  21. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/core/temporal_multinet.py +47 -17
  22. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/ast.py +34 -6
  23. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/builder.py +28 -2
  24. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/compositional_uq.py +83 -31
  25. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/executor.py +76 -22
  26. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/program/cache.py +2 -0
  27. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/program/explain.py +24 -35
  28. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/program/program.py +14 -1
  29. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/result.py +108 -34
  30. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl_legacy.py +7 -0
  31. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/io/formats/arrow_format.py +26 -13
  32. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/io/multinet_bridge.py +61 -79
  33. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/nullmodels/models.py +27 -23
  34. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/optimizer/logical_plan.py +58 -7
  35. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/optimizer/optimizer.py +52 -9
  36. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/optimizer/physical_plan.py +30 -2
  37. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/optimizer/plan_nodes.py +1 -0
  38. py3plex-2.0.93/py3plex/optimizer/rules.py +1024 -0
  39. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/paths/algorithms.py +5 -1
  40. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/temporal_utils.py +16 -9
  41. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/temporal_view.py +26 -35
  42. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/wrappers/benchmark_nodes.py +5 -2
  43. {py3plex-2.0.8 → py3plex-2.0.93/py3plex.egg-info}/PKG-INFO +11 -7
  44. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex.egg-info/SOURCES.txt +79 -0
  45. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex.egg-info/requires.txt +8 -2
  46. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex_mcp/__init__.py +1 -1
  47. {py3plex-2.0.8 → py3plex-2.0.93}/pyproject.toml +4 -2
  48. py3plex-2.0.93/tests/test_agent_loading_stats.py +63 -0
  49. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_approximate_centrality.py +2 -2
  50. py3plex-2.0.93/tests/test_approximation_dispatch_regressions.py +65 -0
  51. py3plex-2.0.93/tests/test_approximation_sample_scope_regressions.py +65 -0
  52. py3plex-2.0.93/tests/test_arrow_attribute_alignment.py +16 -0
  53. py3plex-2.0.93/tests/test_arrow_scalar_ids.py +75 -0
  54. py3plex-2.0.93/tests/test_ast_json_specs_regressions.py +39 -0
  55. py3plex-2.0.93/tests/test_ast_json_target_regressions.py +41 -0
  56. py3plex-2.0.93/tests/test_benchmark_runner_modes.py +75 -0
  57. py3plex-2.0.93/tests/test_benchmark_runner_seeds.py +55 -0
  58. py3plex-2.0.93/tests/test_betweenness_sampling_scaling_regression.py +69 -0
  59. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_book_conf.py +1 -1
  60. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_book_manuscript_integrity.py +1 -1
  61. py3plex-2.0.93/tests/test_bridge_edge_attributes.py +140 -0
  62. py3plex-2.0.93/tests/test_bridge_empty_export.py +57 -0
  63. py3plex-2.0.93/tests/test_bridge_node_identifiers.py +72 -0
  64. py3plex-2.0.93/tests/test_bridge_replica_collisions.py +40 -0
  65. py3plex-2.0.93/tests/test_builder_ast_replay_regressions.py +37 -0
  66. py3plex-2.0.93/tests/test_cache_method_identity.py +119 -0
  67. py3plex-2.0.93/tests/test_canonical_ast_isolation_regressions.py +74 -0
  68. py3plex-2.0.93/tests/test_canonical_projection_order_regressions.py +42 -0
  69. py3plex-2.0.93/tests/test_canonical_query_settings_regressions.py +85 -0
  70. py3plex-2.0.93/tests/test_closeness_allocation_regressions.py +67 -0
  71. py3plex-2.0.93/tests/test_closeness_direction_regressions.py +48 -0
  72. py3plex-2.0.93/tests/test_closeness_normalization_regressions.py +74 -0
  73. py3plex-2.0.93/tests/test_closeness_seed_regressions.py +46 -0
  74. py3plex-2.0.93/tests/test_configuration_directed_degrees.py +104 -0
  75. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_core_multinet_and_parsers.py +67 -3
  76. py3plex-2.0.93/tests/test_correlation_mixed_identities.py +72 -0
  77. py3plex-2.0.93/tests/test_correlation_probability_bounds.py +12 -0
  78. py3plex-2.0.93/tests/test_critical_distance_rendering.py +46 -0
  79. py3plex-2.0.93/tests/test_critical_distance_tied_ranks.py +19 -0
  80. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dependency_cleanup.py +7 -1
  81. py3plex-2.0.93/tests/test_dependency_cleanup_compat.py +34 -0
  82. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl.py +29 -0
  83. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_community_uq_integration.py +18 -0
  84. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_compositional_uq.py +130 -0
  85. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_executor_additional.py +40 -0
  86. py3plex-2.0.93/tests/test_dsl_optimizer_integration.py +131 -0
  87. py3plex-2.0.93/tests/test_dsl_optimizer_rewrites.py +264 -0
  88. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_edgelist_format.py +24 -2
  89. py3plex-2.0.93/tests/test_edgelist_reload_regression.py +59 -0
  90. py3plex-2.0.93/tests/test_erdos_renyi_directed.py +76 -0
  91. py3plex-2.0.93/tests/test_flow_direction.py +99 -0
  92. py3plex-2.0.93/tests/test_flow_parallel_capacity.py +109 -0
  93. py3plex-2.0.93/tests/test_gml_data_preservation.py +45 -0
  94. py3plex-2.0.93/tests/test_gpickle_directed_conversion.py +37 -0
  95. py3plex-2.0.93/tests/test_gpickle_layer_data.py +51 -0
  96. py3plex-2.0.93/tests/test_graphml_loading.py +77 -0
  97. py3plex-2.0.93/tests/test_hedwig_binary_members.py +28 -0
  98. py3plex-2.0.93/tests/test_json_key_collisions.py +26 -0
  99. py3plex-2.0.93/tests/test_layer_set_json_regressions.py +49 -0
  100. py3plex-2.0.93/tests/test_layer_shuffle_seed_order.py +100 -0
  101. py3plex-2.0.93/tests/test_layer_similarity_edge_orientation.py +39 -0
  102. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_link_checker.py +1 -0
  103. py3plex-2.0.93/tests/test_load_directed_default.py +46 -0
  104. py3plex-2.0.93/tests/test_matrix_network_weights.py +38 -0
  105. py3plex-2.0.93/tests/test_mixed_layer_enumeration.py +44 -0
  106. py3plex-2.0.93/tests/test_multiedgelist_weights_regressions.py +41 -0
  107. py3plex-2.0.93/tests/test_networkx_four_field_replicas.py +26 -0
  108. py3plex-2.0.93/tests/test_networkx_selected_edge_metrics.py +37 -0
  109. py3plex-2.0.93/tests/test_numeric_cache_mutations.py +91 -0
  110. py3plex-2.0.93/tests/test_numeric_parallel_weights.py +90 -0
  111. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_optimizer_submodules.py +3 -1
  112. py3plex-2.0.93/tests/test_parse_nx_direction.py +46 -0
  113. py3plex-2.0.93/tests/test_program_explanation_options.py +20 -0
  114. py3plex-2.0.93/tests/test_program_layerset_explain.py +18 -0
  115. py3plex-2.0.93/tests/test_readme_downloads_badge.py +14 -0
  116. py3plex-2.0.93/tests/test_result_by_id_conflicts.py +174 -0
  117. py3plex-2.0.93/tests/test_result_difference_attributes.py +62 -0
  118. py3plex-2.0.93/tests/test_result_edge_identifier_export.py +66 -0
  119. py3plex-2.0.93/tests/test_result_networkx_direction.py +107 -0
  120. py3plex-2.0.93/tests/test_result_networkx_edge_keys.py +73 -0
  121. py3plex-2.0.93/tests/test_result_networkx_edge_metrics.py +76 -0
  122. py3plex-2.0.93/tests/test_result_networkx_node_lists.py +69 -0
  123. py3plex-2.0.93/tests/test_result_symmetric_difference_attributes.py +135 -0
  124. py3plex-2.0.93/tests/test_result_union_falsy_identifiers.py +93 -0
  125. py3plex-2.0.93/tests/test_robustness_directed_paths.py +40 -0
  126. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_roundtrip_invariants.py +18 -7
  127. py3plex-2.0.93/tests/test_scoped_canonical_embedding_regressions.py +33 -0
  128. py3plex-2.0.93/tests/test_sidecar_empty_tables.py +58 -0
  129. py3plex-2.0.93/tests/test_simplex_degenerate.py +18 -0
  130. py3plex-2.0.93/tests/test_sparse_conversion_preserves_data.py +100 -0
  131. py3plex-2.0.93/tests/test_streaming_degree_normalization.py +65 -0
  132. py3plex-2.0.93/tests/test_streaming_pagerank_dangling.py +100 -0
  133. py3plex-2.0.93/tests/test_streaming_pagerank_selfloops.py +68 -0
  134. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_temporal.py +4 -3
  135. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_temporal_algorithms.py +68 -0
  136. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_temporal_multinet.py +125 -0
  137. py3plex-2.0.93/tests/test_temporal_numeric_strings.py +36 -0
  138. py3plex-2.0.93/tests/test_temporal_single_timestamp.py +89 -0
  139. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_temporal_utils.py +26 -5
  140. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_temporal_view.py +102 -0
  141. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_temporal_windowed_queries.py +27 -0
  142. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_version_consistency.py +3 -3
  143. py3plex-2.0.93/tests/test_weighted_betweenness_identity_regression.py +66 -0
  144. py3plex-2.0.93/tests/test_weighted_multigraph_sampling_regression.py +70 -0
  145. py3plex-2.0.93/tests/test_wrappers_optional_gensim.py +48 -0
  146. py3plex-2.0.93/tests/test_wrappers_topk_zero.py +23 -0
  147. py3plex-2.0.8/py3plex/optimizer/rules.py +0 -536
  148. {py3plex-2.0.8 → py3plex-2.0.93}/LICENSE +0 -0
  149. {py3plex-2.0.8 → py3plex-2.0.93}/MANIFEST.in +0 -0
  150. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/__init__.py +0 -0
  151. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/__main__.py +0 -0
  152. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/_parallel.py +0 -0
  153. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/_safe_expression.py +0 -0
  154. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algebra/__init__.py +0 -0
  155. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algebra/backend.py +0 -0
  156. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algebra/closure.py +0 -0
  157. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algebra/fixed_point.py +0 -0
  158. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algebra/lift.py +0 -0
  159. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algebra/paths.py +0 -0
  160. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algebra/registry.py +0 -0
  161. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algebra/semiring.py +0 -0
  162. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algebra/witness.py +0 -0
  163. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/__init__.py +0 -0
  164. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/advanced_random_generators.py +0 -0
  165. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/centrality/__init__.py +0 -0
  166. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/centrality/approx_pagerank.py +0 -0
  167. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/centrality/explain.py +0 -0
  168. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/centrality_toolkit.py +0 -0
  169. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_comparison.py +0 -0
  170. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/NoRC.py +0 -0
  171. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/__init__.py +0 -0
  172. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/auto_select.py +0 -0
  173. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/autocommunity.py +0 -0
  174. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/autocommunity_executor.py +0 -0
  175. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/budget.py +0 -0
  176. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/community_louvain.py +0 -0
  177. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/community_measures.py +0 -0
  178. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/community_ranking.py +0 -0
  179. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/community_wrapper.py +0 -0
  180. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/distributional.py +0 -0
  181. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/flow_hierarchy.py +0 -0
  182. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/infomap/__init__.py +0 -0
  183. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/infomap/conftest.py +0 -0
  184. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/infomap/examples/python/example-bipartite.py +0 -0
  185. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/infomap/examples/python/example-file-io.py +0 -0
  186. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/infomap/examples/python/example-multiplex.py +0 -0
  187. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/infomap/examples/python/example-networkx.py +0 -0
  188. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/infomap/examples/python/example-simple.py +0 -0
  189. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/infomap/examples/python/example-trigram-expanded.py +0 -0
  190. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/infomap/examples/python/example-trigram.py +0 -0
  191. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/infomap/infomap.py +0 -0
  192. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/infomap/interfaces/python/setup.py +0 -0
  193. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/label_propagation.py +0 -0
  194. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/leiden_multilayer.py +0 -0
  195. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/leiden_uq.py +0 -0
  196. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/mdl_benchmark.py +0 -0
  197. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/multilayer_benchmark.py +0 -0
  198. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/multilayer_modularity.py +0 -0
  199. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/multilayer_quality_metrics.py +0 -0
  200. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/node_ranking.py +0 -0
  201. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/runner.py +0 -0
  202. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/sbm_metrics.py +0 -0
  203. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/sbm_wrapper.py +0 -0
  204. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/spectral_multilayer.py +0 -0
  205. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/community_detection/successive_halving.py +0 -0
  206. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/curvature/__init__.py +0 -0
  207. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/curvature/ollivier_ricci_multilayer.py +0 -0
  208. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/general/__init__.py +0 -0
  209. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/general/benchmark_classification.py +0 -0
  210. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/general/walkers.py +0 -0
  211. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/graph_summarization.py +0 -0
  212. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/__init__.py +0 -0
  213. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/__main__.py +0 -0
  214. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/assets/builtin.n3 +0 -0
  215. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/core/__init__.py +0 -0
  216. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/core/converters.py +0 -0
  217. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/core/example.py +0 -0
  218. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/core/helpers.py +0 -0
  219. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/core/load.py +0 -0
  220. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/core/predicate.py +0 -0
  221. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/core/rule.py +0 -0
  222. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/core/settings.py +0 -0
  223. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/core/term_parsers.py +0 -0
  224. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/learners/__init__.py +0 -0
  225. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/learners/bottomup.py +0 -0
  226. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/learners/learner.py +0 -0
  227. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/learners/optimal.py +0 -0
  228. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/stats/__init__.py +0 -0
  229. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/stats/adjustment.py +0 -0
  230. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/stats/scorefunctions.py +0 -0
  231. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/stats/significance.py +0 -0
  232. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/hedwig/stats/validate.py +0 -0
  233. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/meta_flow_report.py +0 -0
  234. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/multicentrality.py +0 -0
  235. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/multilayer_algorithms/__init__.py +0 -0
  236. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/multilayer_algorithms/entanglement.py +0 -0
  237. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/multilayer_algorithms/multirank.py +0 -0
  238. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/multilayer_algorithms/multixrank.py +0 -0
  239. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/multilayer_algorithms/supra_matrix_function_centrality.py +0 -0
  240. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/multilayer_algorithms/versatility.py +0 -0
  241. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/multilayer_clustering.py +0 -0
  242. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/network_classification/PPR.py +0 -0
  243. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/network_classification/__init__.py +0 -0
  244. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/network_classification/label_propagation.py +0 -0
  245. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/node_ranking/__init__.py +0 -0
  246. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/node_ranking/node_ranking.py +0 -0
  247. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/requirements_registry.py +0 -0
  248. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/robustness_testing.py +0 -0
  249. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/routing/__init__.py +0 -0
  250. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/routing/multiplex_paths.py +0 -0
  251. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/sbm/__init__.py +0 -0
  252. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/sbm/conversions.py +0 -0
  253. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/sbm/diagnostics.py +0 -0
  254. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/sbm/inference_vi.py +0 -0
  255. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/sbm/model_selection.py +0 -0
  256. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/sbm/multilayer_sbm.py +0 -0
  257. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/sbm/objectives.py +0 -0
  258. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/sbm/uq.py +0 -0
  259. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/sbm/utils.py +0 -0
  260. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/sir_multiplex.py +0 -0
  261. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/statistical_report.py +0 -0
  262. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/statistics/__init__.py +0 -0
  263. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/statistics/basic_statistics.py +0 -0
  264. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/statistics/bayesian_distances.py +0 -0
  265. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/statistics/correlation_networks.py +0 -0
  266. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/statistics/enrichment_modules.py +0 -0
  267. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/statistics/multilayer_statistics.py +0 -0
  268. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/statistics/powerlaw.py +0 -0
  269. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/statistics/stats_comparison.py +0 -0
  270. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/statistics/topology.py +0 -0
  271. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/temporal/__init__.py +0 -0
  272. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/temporal/community.py +0 -0
  273. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/temporal_multiplex/__init__.py +0 -0
  274. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/algorithms/term_parsers/__init__.py +0 -0
  275. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/alignment/__init__.py +0 -0
  276. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/alignment/features.py +0 -0
  277. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/alignment/metrics.py +0 -0
  278. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/alignment/solvers.py +0 -0
  279. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/benchmarks/__init__.py +0 -0
  280. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/benchmarks/budget.py +0 -0
  281. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/benchmarks/metrics.py +0 -0
  282. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/centrality/__init__.py +0 -0
  283. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/claims/__init__.py +0 -0
  284. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/claims/generator.py +0 -0
  285. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/claims/learner.py +0 -0
  286. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/claims/scorer.py +0 -0
  287. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/claims/types.py +0 -0
  288. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/comparison/__init__.py +0 -0
  289. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/comparison/executor.py +0 -0
  290. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/comparison/metrics.py +0 -0
  291. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/comparison/result.py +0 -0
  292. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/compat/__init__.py +0 -0
  293. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/compat/convert.py +0 -0
  294. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/compat/converters/__init__.py +0 -0
  295. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/compat/converters/dgl_converter.py +0 -0
  296. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/compat/converters/igraph_converter.py +0 -0
  297. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/compat/converters/networkx_converter.py +0 -0
  298. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/compat/converters/pyg_converter.py +0 -0
  299. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/compat/converters/scipy_converter.py +0 -0
  300. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/compat/equality.py +0 -0
  301. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/compat/exceptions.py +0 -0
  302. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/compat/ir.py +0 -0
  303. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/compat/schema.py +0 -0
  304. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/config.py +0 -0
  305. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/contracts/__init__.py +0 -0
  306. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/contracts/contract.py +0 -0
  307. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/contracts/engine.py +0 -0
  308. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/contracts/failure_modes.py +0 -0
  309. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/contracts/predicates.py +0 -0
  310. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/contracts/result.py +0 -0
  311. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/core/HINMINE/IO.py +0 -0
  312. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/core/HINMINE/__init__.py +0 -0
  313. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/core/HINMINE/dataStructures.py +0 -0
  314. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/core/HINMINE/decomposition.py +0 -0
  315. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/core/__init__.py +0 -0
  316. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/core/converters.py +0 -0
  317. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/core/immutable.py +0 -0
  318. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/core/nx_compat.py +0 -0
  319. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/core/random_generators.py +0 -0
  320. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/core/schema_validation.py +0 -0
  321. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/core/supporting.py +0 -0
  322. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/core/types.py +0 -0
  323. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/counterexamples/__init__.py +0 -0
  324. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/counterexamples/claim_lang.py +0 -0
  325. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/counterexamples/ddmin.py +0 -0
  326. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/counterexamples/engine.py +0 -0
  327. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/counterexamples/types.py +0 -0
  328. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/counterexamples/witness.py +0 -0
  329. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/counterfactual/__init__.py +0 -0
  330. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/counterfactual/comparator.py +0 -0
  331. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/counterfactual/engine.py +0 -0
  332. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/counterfactual/presets.py +0 -0
  333. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/counterfactual/result.py +0 -0
  334. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/counterfactual/spec.py +0 -0
  335. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/datasets/__init__.py +0 -0
  336. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/datasets/_data/aarhus_cs.edges +0 -0
  337. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/datasets/_data/synthetic_multilayer.edges +0 -0
  338. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/datasets/_generators.py +0 -0
  339. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/datasets/_loaders.py +0 -0
  340. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/diagnostics/__init__.py +0 -0
  341. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/diagnostics/builders.py +0 -0
  342. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/diagnostics/codes.py +0 -0
  343. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/diagnostics/core.py +0 -0
  344. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/diagnostics/utils.py +0 -0
  345. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/__init__.py +0 -0
  346. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/algebra.py +0 -0
  347. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/attribution.py +0 -0
  348. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/benchmark.py +0 -0
  349. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/benchmark_result.py +0 -0
  350. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/builder_parser.py +0 -0
  351. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/cache.py +0 -0
  352. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/communities.py +0 -0
  353. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/community_uq.py +0 -0
  354. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/context.py +0 -0
  355. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/errors.py +0 -0
  356. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/executor_semiring.py +0 -0
  357. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/executors/__init__.py +0 -0
  358. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/executors/benchmark_executor.py +0 -0
  359. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/explain.py +0 -0
  360. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/export.py +0 -0
  361. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/expressions.py +0 -0
  362. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/fastpath.py +0 -0
  363. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/layers.py +0 -0
  364. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/lint/__init__.py +0 -0
  365. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/lint/diagnostic.py +0 -0
  366. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/lint/lint_context.py +0 -0
  367. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/lint/rules/__init__.py +0 -0
  368. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/lint/rules/base.py +0 -0
  369. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/lint/rules/dsl001_unknown_layer.py +0 -0
  370. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/lint/rules/dsl002_unknown_attribute.py +0 -0
  371. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/lint/rules/dsl101_type_mismatch.py +0 -0
  372. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/lint/rules/dsl201_unsatisfiable.py +0 -0
  373. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/lint/rules/dsl202_redundant.py +0 -0
  374. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/lint/rules/perf301_full_scan.py +0 -0
  375. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/lint/rules/perf302_cross_layer.py +0 -0
  376. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/lint/schema.py +0 -0
  377. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/lint/type_resolver.py +0 -0
  378. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/lint/types.py +0 -0
  379. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/metrics.py +0 -0
  380. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/operator_registry.py +0 -0
  381. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/operators.py +0 -0
  382. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/patterns/__init__.py +0 -0
  383. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/patterns/builder.py +0 -0
  384. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/patterns/compiler.py +0 -0
  385. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/patterns/engine.py +0 -0
  386. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/patterns/ir.py +0 -0
  387. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/patterns/result.py +0 -0
  388. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/plan.py +0 -0
  389. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/planner.py +0 -0
  390. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/predictive.py +0 -0
  391. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/program/__init__.py +0 -0
  392. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/program/cost.py +0 -0
  393. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/program/diff.py +0 -0
  394. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/program/distribution.py +0 -0
  395. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/program/executor.py +0 -0
  396. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/program/rewrite.py +0 -0
  397. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/program/types.py +0 -0
  398. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/provenance.py +0 -0
  399. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/reduction.py +0 -0
  400. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/registry.py +0 -0
  401. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/selection_uq.py +0 -0
  402. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/serializer.py +0 -0
  403. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/uq_algebra.py +0 -0
  404. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/uq_resolution.py +0 -0
  405. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dsl/warnings.py +0 -0
  406. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dynamics/__init__.py +0 -0
  407. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dynamics/_utils.py +0 -0
  408. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dynamics/ast.py +0 -0
  409. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dynamics/builder.py +0 -0
  410. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dynamics/compartmental.py +0 -0
  411. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dynamics/config.py +0 -0
  412. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dynamics/core.py +0 -0
  413. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dynamics/errors.py +0 -0
  414. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dynamics/executor.py +0 -0
  415. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dynamics/models.py +0 -0
  416. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dynamics/processes.py +0 -0
  417. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dynamics/registry.py +0 -0
  418. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dynamics/result.py +0 -0
  419. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/dynamics/serializer.py +0 -0
  420. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/embeddings/__init__.py +0 -0
  421. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/embeddings/base.py +0 -0
  422. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/embeddings/cache.py +0 -0
  423. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/embeddings/link_ops.py +0 -0
  424. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/embeddings/metapath2vec.py +0 -0
  425. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/embeddings/netmf.py +0 -0
  426. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/ergonomics.py +0 -0
  427. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/errors.py +0 -0
  428. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/exceptions.py +0 -0
  429. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/experiments/__init__.py +0 -0
  430. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/experiments/artifacts.py +0 -0
  431. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/experiments/cli.py +0 -0
  432. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/experiments/env.py +0 -0
  433. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/experiments/errors.py +0 -0
  434. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/experiments/model.py +0 -0
  435. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/experiments/runner.py +0 -0
  436. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/experiments/store.py +0 -0
  437. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/experiments/utils.py +0 -0
  438. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/fast_examples.py +0 -0
  439. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/graph_ops.py +0 -0
  440. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/io/__init__.py +0 -0
  441. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/io/api.py +0 -0
  442. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/io/canonical_format.py +0 -0
  443. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/io/converters.py +0 -0
  444. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/io/exceptions.py +0 -0
  445. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/io/formats/__init__.py +0 -0
  446. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/io/formats/csv_format.py +0 -0
  447. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/io/formats/json_format.py +0 -0
  448. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/io/parquet_format.py +0 -0
  449. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/io/schema.py +0 -0
  450. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/lab/__init__.py +0 -0
  451. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/lab/base.py +0 -0
  452. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/linter.py +0 -0
  453. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/logging_config.py +0 -0
  454. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/meta/__init__.py +0 -0
  455. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/meta/builder.py +0 -0
  456. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/meta/result.py +0 -0
  457. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/meta/stats.py +0 -0
  458. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/meta/utils.py +0 -0
  459. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/ml/__init__.py +0 -0
  460. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/ml/embedding/__init__.py +0 -0
  461. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/ml/embedding/base.py +0 -0
  462. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/ml/embedding/deepwalk.py +0 -0
  463. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/ml/embedding/evaluation.py +0 -0
  464. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/ml/embedding/line.py +0 -0
  465. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/ml/embedding/metapath2vec.py +0 -0
  466. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/ml/embedding/multiplex.py +0 -0
  467. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/ml/embedding/netmf.py +0 -0
  468. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/ml/embedding/node2vec.py +0 -0
  469. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/ml/embedding/similarity.py +0 -0
  470. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/ml/embedding/trainer.py +0 -0
  471. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/ml/embedding/utils.py +0 -0
  472. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/multinet/__init__.py +0 -0
  473. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/multinet/aggregation.py +0 -0
  474. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/nullmodels/__init__.py +0 -0
  475. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/nullmodels/executor.py +0 -0
  476. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/nullmodels/result.py +0 -0
  477. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/optimizer/__init__.py +0 -0
  478. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/optimizer/cost_model.py +0 -0
  479. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/out_of_core/__init__.py +0 -0
  480. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/out_of_core/cli.py +0 -0
  481. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/out_of_core/errors.py +0 -0
  482. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/out_of_core/executor.py +0 -0
  483. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/out_of_core/network.py +0 -0
  484. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/out_of_core/operators.py +0 -0
  485. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/out_of_core/readers.py +0 -0
  486. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/out_of_core/schema.py +0 -0
  487. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/out_of_core/spill.py +0 -0
  488. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/out_of_core/utils.py +0 -0
  489. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/paths/__init__.py +0 -0
  490. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/paths/executor.py +0 -0
  491. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/paths/result.py +0 -0
  492. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/pipeline.py +0 -0
  493. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/plugins/__init__.py +0 -0
  494. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/plugins/base.py +0 -0
  495. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/plugins/examples.py +0 -0
  496. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/plugins/registry.py +0 -0
  497. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/profiling.py +0 -0
  498. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/provenance/__init__.py +0 -0
  499. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/provenance/bundle.py +0 -0
  500. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/provenance/capture.py +0 -0
  501. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/provenance/replay.py +0 -0
  502. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/provenance/schema.py +0 -0
  503. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/requirements.py +0 -0
  504. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/robustness/__init__.py +0 -0
  505. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/robustness/experiments.py +0 -0
  506. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/robustness/perturbations.py +0 -0
  507. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/runtime/__init__.py +0 -0
  508. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/runtime/capabilities.py +0 -0
  509. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/safe_dsl_expression.py +0 -0
  510. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/selection/__init__.py +0 -0
  511. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/selection/capabilities.py +0 -0
  512. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/selection/community_registry.py +0 -0
  513. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/selection/evaluate.py +0 -0
  514. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/selection/metric_registry.py +0 -0
  515. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/selection/result.py +0 -0
  516. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/selection/wins.py +0 -0
  517. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/semiring/__init__.py +0 -0
  518. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/semiring/core.py +0 -0
  519. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/semiring/engine.py +0 -0
  520. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/semiring/pareto.py +0 -0
  521. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/semiring/registry.py +0 -0
  522. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/semiring/types.py +0 -0
  523. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/sensitivity/__init__.py +0 -0
  524. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/sensitivity/executor.py +0 -0
  525. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/sensitivity/metrics.py +0 -0
  526. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/sensitivity/perturbations.py +0 -0
  527. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/sensitivity/types.py +0 -0
  528. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/stats/__init__.py +0 -0
  529. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/stats/provenance.py +0 -0
  530. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/stats/registry.py +0 -0
  531. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/stats/statvalue.py +0 -0
  532. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/stats/uncertainty.py +0 -0
  533. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/temporal_utils_extended.py +0 -0
  534. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/__init__.py +0 -0
  535. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/bootstrap.py +0 -0
  536. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/ci_utils.py +0 -0
  537. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/community_ensemble.py +0 -0
  538. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/community_result.py +0 -0
  539. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/context.py +0 -0
  540. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/estimation.py +0 -0
  541. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/noise_models.py +0 -0
  542. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/null_models.py +0 -0
  543. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/partition.py +0 -0
  544. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/partition_metrics.py +0 -0
  545. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/partition_reducers.py +0 -0
  546. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/partition_types.py +0 -0
  547. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/partition_uq.py +0 -0
  548. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/plan.py +0 -0
  549. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/reducers/__init__.py +0 -0
  550. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/reducers/base.py +0 -0
  551. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/resampling_graph.py +0 -0
  552. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/runner.py +0 -0
  553. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/selection_execution.py +0 -0
  554. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/selection_reducers.py +0 -0
  555. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/selection_types.py +0 -0
  556. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/selection_uq.py +0 -0
  557. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/stratification.py +0 -0
  558. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/uncertainty/types.py +0 -0
  559. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/utils.py +0 -0
  560. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/validation.py +0 -0
  561. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/visualization/__init__.py +0 -0
  562. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/visualization/benchmark_visualizations.py +0 -0
  563. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/visualization/bezier.py +0 -0
  564. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/visualization/colors.py +0 -0
  565. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/visualization/drawing_machinery.py +0 -0
  566. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/visualization/embedding_visualization/__init__.py +0 -0
  567. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/visualization/embedding_visualization/embedding_tools.py +0 -0
  568. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/visualization/embedding_visualization/embedding_visualization.py +0 -0
  569. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/visualization/fa2/__init__.py +0 -0
  570. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/visualization/fa2/fa2util.py +0 -0
  571. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/visualization/fa2/forceatlas2.py +0 -0
  572. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/visualization/layout_algorithms.py +0 -0
  573. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/visualization/multilayer.py +0 -0
  574. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/visualization/polyfit.py +0 -0
  575. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/visualization/pymnet_style.py +0 -0
  576. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/visualization/ricci_layout.py +0 -0
  577. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/visualization/ricci_multilayer_vis.py +0 -0
  578. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/visualization/sankey.py +0 -0
  579. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/workflows.py +0 -0
  580. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/wrappers/__init__.py +0 -0
  581. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/wrappers/r_interop.py +0 -0
  582. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex/wrappers/train_node2vec_embedding.py +0 -0
  583. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex.egg-info/dependency_links.txt +0 -0
  584. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex.egg-info/entry_points.txt +0 -0
  585. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex.egg-info/not-zip-safe +0 -0
  586. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex.egg-info/top_level.txt +0 -0
  587. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex_mcp/errors.py +0 -0
  588. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex_mcp/registry.py +0 -0
  589. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex_mcp/safe_paths.py +0 -0
  590. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex_mcp/schemas.py +0 -0
  591. {py3plex-2.0.8 → py3plex-2.0.93}/py3plex_mcp/server.py +0 -0
  592. {py3plex-2.0.8 → py3plex-2.0.93}/setup.cfg +0 -0
  593. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_advanced_metrics_properties.py +0 -0
  594. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_agent_api.py +0 -0
  595. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_agents_documentation_claims.py +0 -0
  596. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_agents_ergonomics_features.py +0 -0
  597. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_agents_golden_paths.py +0 -0
  598. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_aggregation.py +0 -0
  599. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_algebra_backend.py +0 -0
  600. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_algebra_core.py +0 -0
  601. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_algebra_fixed_point.py +0 -0
  602. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_algebra_paths.py +0 -0
  603. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_algebra_registry.py +0 -0
  604. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_algebra_witness.py +0 -0
  605. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_algorithm_properties.py +0 -0
  606. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_algorithms_attribute_correlation.py +0 -0
  607. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_algorithms_correlation_networks.py +0 -0
  608. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_algorithms_init.py +0 -0
  609. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_algorithms_random_generators.py +0 -0
  610. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_algorithms_requirements_registry.py +0 -0
  611. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_algorithms_statistics_bayesian_distances.py +0 -0
  612. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_alignment.py +0 -0
  613. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_alignment_contracts.py +0 -0
  614. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_alignment_correctness_additional.py +0 -0
  615. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_ast_roundtrip.py +0 -0
  616. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_ast_roundtrip_integration.py +0 -0
  617. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_attribute_correlation.py +0 -0
  618. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_attribute_correlation_contracts.py +0 -0
  619. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_auto_community.py +0 -0
  620. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_autocommunity_benchmarks.py +0 -0
  621. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_autocommunity_executor.py +0 -0
  622. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_autocommunity_meta.py +0 -0
  623. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_autocommunity_successive_halving.py +0 -0
  624. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_bayesian_distances.py +0 -0
  625. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_bench_aggregation_unit.py +0 -0
  626. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_benchmark_budget_fairness.py +0 -0
  627. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_benchmark_dsl_basic.py +0 -0
  628. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_benchmark_integration.py +0 -0
  629. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_benchmark_multiplex_centrality.py +0 -0
  630. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_benchmark_time.py +0 -0
  631. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_benchmarks_budget.py +0 -0
  632. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_benchmarks_init.py +0 -0
  633. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_book_snippets.py +0 -0
  634. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_builder_dsl_mutate.py +0 -0
  635. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_capabilities_basic.py +0 -0
  636. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_capabilities_optional_missing.py +0 -0
  637. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_centrality_explain.py +0 -0
  638. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_centrality_explain_integration.py +0 -0
  639. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_centrality_robustness.py +0 -0
  640. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_centrality_robustness_oracles.py +0 -0
  641. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_centrality_uncertainty.py +0 -0
  642. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_centrality_weight_handling.py +0 -0
  643. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_check_api_consistency.py +0 -0
  644. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_check_doc_coverage.py +0 -0
  645. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_check_type_coverage.py +0 -0
  646. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_ci_python_versions.py +0 -0
  647. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_claim_learning.py +0 -0
  648. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_claims_types.py +0 -0
  649. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_cli.py +0 -0
  650. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_cli_check.py +0 -0
  651. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_cli_ergonomics.py +0 -0
  652. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_cli_piping.py +0 -0
  653. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_clustering_multilayer.py +0 -0
  654. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_code_improvements.py +0 -0
  655. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_community_comparison_coverage.py +0 -0
  656. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_community_detection_modules.py +0 -0
  657. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_community_distribution.py +0 -0
  658. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_community_measures.py +0 -0
  659. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_community_measures_coverage.py +0 -0
  660. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_comparison.py +0 -0
  661. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_comparison_executor.py +0 -0
  662. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_comparison_metrics.py +0 -0
  663. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_comparison_metrics_additional.py +0 -0
  664. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_comparison_result.py +0 -0
  665. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_comparison_uninitialized_and_resistance_oracles.py +0 -0
  666. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_compat_exceptions.py +0 -0
  667. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_compat_roundtrip.py +0 -0
  668. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_config_api.py +0 -0
  669. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_config_benchmark.py +0 -0
  670. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_contracts.py +0 -0
  671. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_contracts_basic.py +0 -0
  672. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_contracts_extended.py +0 -0
  673. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_contracts_failure_modes.py +0 -0
  674. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_contracts_integration.py +0 -0
  675. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_core_functionality.py +0 -0
  676. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_core_immutable.py +0 -0
  677. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_core_lazy_evaluation.py +0 -0
  678. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_core_multinet_correctness.py +0 -0
  679. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_core_multiplex_edges.py +0 -0
  680. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_core_schema_validation.py +0 -0
  681. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_core_supporting.py +0 -0
  682. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_correlation_networks.py +0 -0
  683. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_counterexamples.py +0 -0
  684. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_counterexamples_properties.py +0 -0
  685. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_counterfactual.py +0 -0
  686. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_counterfactual_presets.py +0 -0
  687. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_coverage_grouping.py +0 -0
  688. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_create_mosaic_banner.py +0 -0
  689. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_create_showcase_flow.py +0 -0
  690. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_crosshair_pure_functions.py +0 -0
  691. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_data_files_presence.py +0 -0
  692. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_datasets.py +0 -0
  693. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_datasets_contracts.py +0 -0
  694. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_datasets_oracles.py +0 -0
  695. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_degenerate_networks.py +0 -0
  696. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_determinism_randomness.py +0 -0
  697. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_diagnostics.py +0 -0
  698. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_diagnostics_utils.py +0 -0
  699. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_doc_conf.py +0 -0
  700. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_docs_embeddings_section.py +0 -0
  701. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_docs_examples.py +0 -0
  702. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_docs_quality_pass.py +0 -0
  703. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_doctests.py +0 -0
  704. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dplyr_integration.py +0 -0
  705. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_aggregation_enhancements.py +0 -0
  706. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_ast_equivalence.py +0 -0
  707. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_ast_immutability.py +0 -0
  708. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_auto_community.py +0 -0
  709. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_communities.py +0 -0
  710. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_community_filtering.py +0 -0
  711. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_compact_compute.py +0 -0
  712. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_compiler_explain.py +0 -0
  713. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_compiler_pipeline.py +0 -0
  714. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_condition_semantics.py +0 -0
  715. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_d_factory.py +0 -0
  716. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_documentation_examples.py +0 -0
  717. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_dplyr_style.py +0 -0
  718. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_dynamics_integration.py +0 -0
  719. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_edge_grouping_coverage.py +0 -0
  720. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_edge_queries.py +0 -0
  721. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_enhancements.py +0 -0
  722. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_ergonomics.py +0 -0
  723. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_errors.py +0 -0
  724. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_errors_extended.py +0 -0
  725. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_explain.py +0 -0
  726. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_export.py +0 -0
  727. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_expressions.py +0 -0
  728. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_extensions.py +0 -0
  729. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_graphops_equivalence.py +0 -0
  730. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_grouping_coverage.py +0 -0
  731. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_interactive.py +0 -0
  732. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_joins.py +0 -0
  733. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_layer_resolution.py +0 -0
  734. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_layer_selection.py +0 -0
  735. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_layer_set_algebra.py +0 -0
  736. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_legacy_approximate.py +0 -0
  737. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_legacy_edges.py +0 -0
  738. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_lint.py +0 -0
  739. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_metric_registry.py +0 -0
  740. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_multilayer_measure_topology.py +0 -0
  741. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_operators.py +0 -0
  742. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_patterns.py +0 -0
  743. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_patterns_correctness.py +0 -0
  744. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_patterns_quick_reference.py +0 -0
  745. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_pipes.py +0 -0
  746. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_planner.py +0 -0
  747. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_planner_config.py +0 -0
  748. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_predict_reduce.py +0 -0
  749. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_program_rewrite.py +0 -0
  750. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_program_types.py +0 -0
  751. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_progress_logging.py +0 -0
  752. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_properties.py +0 -0
  753. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_provenance.py +0 -0
  754. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_query_optimization.py +0 -0
  755. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_query_zoo.py +0 -0
  756. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_result_algebra_edge_cases.py +0 -0
  757. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_selection_fastpath.py +0 -0
  758. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_semiring_integration.py +0 -0
  759. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_serializer.py +0 -0
  760. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_smart_defaults.py +0 -0
  761. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_temporal_range_execution.py +0 -0
  762. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_uncertainty.py +0 -0
  763. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_uq_ergonomics.py +0 -0
  764. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_uq_propagation.py +0 -0
  765. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_v2.py +0 -0
  766. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dsl_zoo_features.py +0 -0
  767. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dynamics.py +0 -0
  768. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dynamics_algorithm_contracts.py +0 -0
  769. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dynamics_config_and_results_correctness.py +0 -0
  770. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dynamics_conservation.py +0 -0
  771. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dynamics_core.py +0 -0
  772. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dynamics_executor_edge_cases.py +0 -0
  773. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dynamics_metamorphic.py +0 -0
  774. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dynamics_parallel_determinism.py +0 -0
  775. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dynamics_reference_runs.py +0 -0
  776. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dynamics_uq_integration.py +0 -0
  777. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_dynamics_utils.py +0 -0
  778. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_edge_cases.py +0 -0
  779. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_embeddings_direct_units.py +0 -0
  780. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_ergonomic_helpers.py +0 -0
  781. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_ergonomics.py +0 -0
  782. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_ergonomics_helpers.py +0 -0
  783. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_errors.py +0 -0
  784. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_errors_coverage.py +0 -0
  785. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_CBSSD.py +0 -0
  786. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_community_detection.py +0 -0
  787. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_decomposition_and_classification.py +0 -0
  788. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_decomposition_ground_truth.py +0 -0
  789. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_dsl_builder_api.py +0 -0
  790. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_dynamics_core_examples.py +0 -0
  791. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_embedding_construction.py +0 -0
  792. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_embedding_visualization.py +0 -0
  793. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_incidence_gadget_encoding.py +0 -0
  794. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_interactive_multilayer.py +0 -0
  795. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_inverse_network.py +0 -0
  796. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_layer_extraction.py +0 -0
  797. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_manipulation.py +0 -0
  798. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_multilayer_vectorized_aggregation.py +0 -0
  799. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_multiplex_aggregate.py +0 -0
  800. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_multiplex_dynamics.py +0 -0
  801. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_n2v_embedding.py +0 -0
  802. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_network_decomposition.py +0 -0
  803. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_network_decomposition_meta_paths.py +0 -0
  804. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_numeric_encoding.py +0 -0
  805. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_pattern_matching.py +0 -0
  806. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_example_ppr.py +0 -0
  807. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_examples_zoo_consolidation.py +0 -0
  808. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_exception_taxonomy.py +0 -0
  809. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_exceptions.py +0 -0
  810. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_experiments.py +0 -0
  811. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_explain_attribution.py +0 -0
  812. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_fast_examples.py +0 -0
  813. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_flagship_progress_demo.py +0 -0
  814. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_flow_hierarchy.py +0 -0
  815. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_formal_phase1_alignment.py +0 -0
  816. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_fuzzing_properties.py +0 -0
  817. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_generate_all_outputs.py +0 -0
  818. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_generate_quickstart_outputs.py +0 -0
  819. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_generate_visualization_images.py +0 -0
  820. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_golden_toy_examples.py +0 -0
  821. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_graph_ops.py +0 -0
  822. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_graph_summarization.py +0 -0
  823. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_hedwig_adjustment.py +0 -0
  824. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_hedwig_significance.py +0 -0
  825. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_improved_errors.py +0 -0
  826. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_incidence_gadget_encoding.py +0 -0
  827. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_infomap_fix.py +0 -0
  828. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_interlayer_links_fix.py +0 -0
  829. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_io_api_edge_cases.py +0 -0
  830. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_io_arrow.py +0 -0
  831. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_io_contracts_additional.py +0 -0
  832. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_io_conversion_formats.py +0 -0
  833. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_io_converters.py +0 -0
  834. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_io_exceptions.py +0 -0
  835. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_io_integration.py +0 -0
  836. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_io_roundtrip.py +0 -0
  837. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_io_schema.py +0 -0
  838. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_issue_19_fix.py +0 -0
  839. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_lab.py +0 -0
  840. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_lab_additional.py +0 -0
  841. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_lab_correctness.py +0 -0
  842. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_label_propagation.py +0 -0
  843. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_layer_extraction_fix.py +0 -0
  844. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_layer_similarity.py +0 -0
  845. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_layout_algorithms.py +0 -0
  846. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_lazy_evaluation.py +0 -0
  847. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_leiden_multilayer.py +0 -0
  848. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_linter.py +0 -0
  849. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_logging_config_unit.py +0 -0
  850. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_logging_conversion.py +0 -0
  851. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_main_module.py +0 -0
  852. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_master_regulators_example.py +0 -0
  853. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_math_invariants.py +0 -0
  854. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_mcp_server.py +0 -0
  855. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_mdl_benchmark.py +0 -0
  856. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_mdl_score.py +0 -0
  857. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_mdl_score_corruption_monotonicity.py +0 -0
  858. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_mdl_score_reference_differential.py +0 -0
  859. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_mdl_score_resolution_limit_sweep.py +0 -0
  860. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_meta_analysis.py +0 -0
  861. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_meta_flow_report.py +0 -0
  862. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_meta_utils.py +0 -0
  863. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_metamorphic.py +0 -0
  864. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_metapath2vec.py +0 -0
  865. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_ml_embedding_evaluation.py +0 -0
  866. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_ml_embedding_primitives.py +0 -0
  867. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_monoplex_nx_wrapper.py +0 -0
  868. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_mpc.py +0 -0
  869. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_multilayer_centrality.py +0 -0
  870. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_multilayer_clustering_coefficients.py +0 -0
  871. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_multilayer_cornercases.py +0 -0
  872. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_multilayer_edge_fix.py +0 -0
  873. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_multilayer_embedding_models.py +0 -0
  874. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_multilayer_integration.py +0 -0
  875. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_multilayer_leiden_uq.py +0 -0
  876. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_multilayer_modularity.py +0 -0
  877. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_multilayer_quality_metrics.py +0 -0
  878. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_multilayer_quality_metrics_coverage.py +0 -0
  879. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_multilayer_statistics.py +0 -0
  880. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_multilayer_visualizations.py +0 -0
  881. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_multinet_aggregation.py +0 -0
  882. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_multinet_aggregation_additional.py +0 -0
  883. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_multiplex_layer_interop.py +0 -0
  884. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_multiplex_participation.py +0 -0
  885. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_multiplex_properties.py +0 -0
  886. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_multirank.py +0 -0
  887. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_multixrank.py +0 -0
  888. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_network_conversion.py +0 -0
  889. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_network_version.py +0 -0
  890. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_networkx_compatibility.py +0 -0
  891. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_new_algorithms.py +0 -0
  892. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_new_multilayer_metrics.py +0 -0
  893. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_node_edge_parity.py +0 -0
  894. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_node_ranking_comprehensive.py +0 -0
  895. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_norc.py +0 -0
  896. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_nullmodel_sanity.py +0 -0
  897. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_nullmodels.py +0 -0
  898. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_nullmodels_contracts.py +0 -0
  899. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_nx_compat_extended.py +0 -0
  900. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_ollivier_ricci_multilayer.py +0 -0
  901. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_out_of_core.py +0 -0
  902. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_parallel.py +0 -0
  903. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_parallel_execution.py +0 -0
  904. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_parsers_comprehensive.py +0 -0
  905. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_parsers_coverage.py +0 -0
  906. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_partition_uq.py +0 -0
  907. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_partition_uq_integration.py +0 -0
  908. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_paths.py +0 -0
  909. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_paths_additional.py +0 -0
  910. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_paths_contracts.py +0 -0
  911. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_paths_executor.py +0 -0
  912. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_paths_result.py +0 -0
  913. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_performance_core.py +0 -0
  914. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_pipeline.py +0 -0
  915. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_plugin_examples.py +0 -0
  916. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_plugin_system.py +0 -0
  917. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_plugins.py +0 -0
  918. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_plugins_contracts.py +0 -0
  919. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_profiling.py +0 -0
  920. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_profiling_additional.py +0 -0
  921. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_program.py +0 -0
  922. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_program_cache_identity.py +0 -0
  923. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_program_cost_executor.py +0 -0
  924. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_properties.py +0 -0
  925. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_provenance_canonical.py +0 -0
  926. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_provenance_replay.py +0 -0
  927. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_provenance_schema.py +0 -0
  928. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_public_api_exports.py +0 -0
  929. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_pymnet_style.py +0 -0
  930. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_pypi_publish_workflow.py +0 -0
  931. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_query_algebra.py +0 -0
  932. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_query_equivalence.py +0 -0
  933. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_r_interop.py +0 -0
  934. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_random_generators_additional.py +0 -0
  935. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_random_generators_extended.py +0 -0
  936. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_random_walkers.py +0 -0
  937. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_random_walks.py +0 -0
  938. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_readme_contributor_onboarding.py +0 -0
  939. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_readme_flagship_example.py +0 -0
  940. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_requirements.py +0 -0
  941. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_result_explain_debug.py +0 -0
  942. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_ricci_visualization.py +0 -0
  943. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_robustness.py +0 -0
  944. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_robustness_additional.py +0 -0
  945. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_robustness_testing.py +0 -0
  946. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_root_conftest.py +0 -0
  947. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_run_quickstart_snippets.py +0 -0
  948. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_safe_expression.py +0 -0
  949. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_sankey_visualization.py +0 -0
  950. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_sbm_autocommunity.py +0 -0
  951. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_sbm_generator.py +0 -0
  952. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_sbm_metrics.py +0 -0
  953. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_sbm_runner_integration.py +0 -0
  954. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_schema_and_immutable.py +0 -0
  955. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_seeding.py +0 -0
  956. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_selection_uq.py +0 -0
  957. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_selection_uq_empty_groups.py +0 -0
  958. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_selection_uq_integration.py +0 -0
  959. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_semiring_negative_cases.py +0 -0
  960. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_semiring_pareto.py +0 -0
  961. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_semiring_registry.py +0 -0
  962. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_semiring_types.py +0 -0
  963. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_semiring_verification.py +0 -0
  964. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_sensitivity_executor.py +0 -0
  965. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_sidecar.py +0 -0
  966. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_sir_epidemic.py +0 -0
  967. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_sir_long_convergence.py +0 -0
  968. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_sir_multiplex.py +0 -0
  969. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_spectral_multilayer.py +0 -0
  970. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_statistical_report.py +0 -0
  971. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_stats_comparison.py +0 -0
  972. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_stats_core.py +0 -0
  973. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_stats_edge_cases.py +0 -0
  974. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_stats_provenance.py +0 -0
  975. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_stats_provenance_dataclass.py +0 -0
  976. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_stats_registry.py +0 -0
  977. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_stats_scalar_uncertainty.py +0 -0
  978. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_stats_verify.py +0 -0
  979. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_stratified_uq.py +0 -0
  980. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_streaming_topk.py +0 -0
  981. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_successive_halving.py +0 -0
  982. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_supporting_extended.py +0 -0
  983. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_supra_matrix_function_centrality.py +0 -0
  984. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_temporal_builder.py +0 -0
  985. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_temporal_dsl.py +0 -0
  986. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_temporal_duration_parsing.py +0 -0
  987. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_temporal_utils_extended.py +0 -0
  988. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_tensor_representation.py +0 -0
  989. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_tutorial_10min.py +0 -0
  990. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_type_coverage_scan.py +0 -0
  991. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_uncertainty.py +0 -0
  992. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_uncertainty_additional.py +0 -0
  993. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_uncertainty_builder_integration.py +0 -0
  994. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_uncertainty_defaults.py +0 -0
  995. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_uncertainty_dsl_integration.py +0 -0
  996. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_uncertainty_engines.py +0 -0
  997. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_uncertainty_oracles.py +0 -0
  998. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_uncertainty_runner.py +0 -0
  999. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_uq_algebra.py +0 -0
  1000. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_uq_integration.py +0 -0
  1001. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_uq_resolution.py +0 -0
  1002. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_uq_spine.py +0 -0
  1003. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_user_journey_simulation.py +0 -0
  1004. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_utils.py +0 -0
  1005. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_utils_coverage.py +0 -0
  1006. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_utils_extended.py +0 -0
  1007. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_utils_search_paths.py +0 -0
  1008. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_validation.py +0 -0
  1009. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_validation_module.py +0 -0
  1010. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_verification_api_differential.py +0 -0
  1011. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_verification_centrality.py +0 -0
  1012. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_verification_communities.py +0 -0
  1013. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_verification_determinism_parallelism.py +0 -0
  1014. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_verification_dsl_equivalence.py +0 -0
  1015. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_verification_metamorphic_harness.py +0 -0
  1016. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_verification_provenance_oracles.py +0 -0
  1017. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_versatility.py +0 -0
  1018. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_visualization_benchmark.py +0 -0
  1019. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_visualization_bezier.py +0 -0
  1020. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_visualization_colors.py +0 -0
  1021. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_visualization_imports.py +0 -0
  1022. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_visualization_layouts.py +0 -0
  1023. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_visualization_multilayer_additional.py +0 -0
  1024. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_visualization_polyfit.py +0 -0
  1025. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_visualization_ricci_layout_helpers.py +0 -0
  1026. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_visualization_supra_heatmap.py +0 -0
  1027. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_visualize_matrix_fix.py +0 -0
  1028. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_workflows.py +0 -0
  1029. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_wrappers_additional.py +0 -0
  1030. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_wrappers_benchmark_nodes.py +0 -0
  1031. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_wrappers_node2vec.py +0 -0
  1032. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_wrappers_r_interop.py +0 -0
  1033. {py3plex-2.0.8 → py3plex-2.0.93}/tests/test_wrappers_train_node2vec.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: py3plex
3
- Version: 2.0.8
3
+ Version: 2.0.93
4
4
  Summary: A Multilayer network analysis python3 library
5
5
  Author-email: Blaž Škrlj <blaz.skrlj@ijs.si>
6
6
  License: MIT
@@ -33,7 +33,8 @@ Requires-Dist: scikit-learn>=0.24.0
33
33
  Requires-Dist: bitarray>=2.0.0
34
34
  Requires-Dist: seaborn>=0.11.0
35
35
  Provides-Extra: dev
36
- Requires-Dist: pytest>=7.0; extra == "dev"
36
+ Requires-Dist: pytest<9,>=7.0; extra == "dev"
37
+ Requires-Dist: tomli>=1.1.0; python_version < "3.11" and extra == "dev"
37
38
  Requires-Dist: pytest-timeout>=2.1; extra == "dev"
38
39
  Requires-Dist: pytest-cov>=4.0; extra == "dev"
39
40
  Requires-Dist: pytest-benchmark<5.0,>=4.0; extra == "dev"
@@ -48,7 +49,8 @@ Requires-Dist: icontract>=2.6.0; extra == "dev"
48
49
  Requires-Dist: z3-solver>=4.12.0; extra == "dev"
49
50
  Requires-Dist: hypothesis>=6.0; extra == "dev"
50
51
  Provides-Extra: tests
51
- Requires-Dist: pytest>=7.0; extra == "tests"
52
+ Requires-Dist: pytest<9,>=7.0; extra == "tests"
53
+ Requires-Dist: tomli>=1.1.0; python_version < "3.11" and extra == "tests"
52
54
  Requires-Dist: pytest-timeout>=2.1; extra == "tests"
53
55
  Requires-Dist: pytest-cov>=4.0; extra == "tests"
54
56
  Requires-Dist: pytest-rerunfailures>=12.0; extra == "tests"
@@ -116,12 +118,12 @@ Dynamic: license-file
116
118
  [![Formal Verification](https://github.com/SkBlaz/py3plex/actions/workflows/verify.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/verify.yml)
117
119
  [![Lean formal verification](https://github.com/SkBlaz/py3plex/actions/workflows/formal.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/formal.yml)
118
120
  [![Fuzzing](https://github.com/SkBlaz/py3plex/actions/workflows/fuzzing.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/fuzzing.yml)
119
- [![PyPI version](https://img.shields.io/pypi/v/py3plex.svg?cacheSeconds=300)](https://pypi.org/project/py3plex/)
120
- [![PyPI - Downloads](https://img.shields.io/pypi/dm/py3plex)](https://pypistats.org/packages/py3plex)
121
+ [![PyPI version](https://img.shields.io/pypi/v/py3plex)](https://pypi.org/project/py3plex/)
122
+ [![PyPI downloads (last month)](https://img.shields.io/pypi/dm/py3plex?cacheSeconds=3600)](https://pypistats.org/packages/py3plex)
121
123
  ![CLI Tool](https://img.shields.io/badge/CLI%20Tool-Available-brightgreen)
122
124
  ![Docker](https://img.shields.io/badge/Docker-Available-blue)
123
- ![Lines of Code](https://img.shields.io/badge/lines-213.8K-blue)
124
- ![Test Count](https://img.shields.io/badge/tests-9.7K-blue)
125
+ ![Lines of Code](https://img.shields.io/badge/lines-214.9K-blue)
126
+ ![Test Count](https://img.shields.io/badge/tests-10.0K-blue)
125
127
 
126
128
  *Multilayer networks* are complex networks with additional information assigned to nodes or edges (or both). This library includes
127
129
  some of the state-of-the-art algorithms for decomposition, visualization and analysis of such networks.
@@ -301,6 +303,8 @@ Safety notes for contributors:
301
303
  - Prefer running targeted tests first, then broader checks before opening a PR.
302
304
  - For docs-only updates, run `make docs-check` before opening a PR.
303
305
 
306
+ To report a bug, request a feature, or ask for help using py3plex, open an issue in the [issue tracker](https://github.com/SkBlaz/py3plex/issues). Include a minimal example and the py3plex and Python versions where relevant.
307
+
304
308
  ### MCP Integration (AI Agents)
305
309
 
306
310
  py3plex provides a Model Context Protocol (MCP) server for integration with AI coding assistants:
@@ -12,12 +12,12 @@
12
12
  [![Formal Verification](https://github.com/SkBlaz/py3plex/actions/workflows/verify.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/verify.yml)
13
13
  [![Lean formal verification](https://github.com/SkBlaz/py3plex/actions/workflows/formal.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/formal.yml)
14
14
  [![Fuzzing](https://github.com/SkBlaz/py3plex/actions/workflows/fuzzing.yml/badge.svg)](https://github.com/SkBlaz/py3plex/actions/workflows/fuzzing.yml)
15
- [![PyPI version](https://img.shields.io/pypi/v/py3plex.svg?cacheSeconds=300)](https://pypi.org/project/py3plex/)
16
- [![PyPI - Downloads](https://img.shields.io/pypi/dm/py3plex)](https://pypistats.org/packages/py3plex)
15
+ [![PyPI version](https://img.shields.io/pypi/v/py3plex)](https://pypi.org/project/py3plex/)
16
+ [![PyPI downloads (last month)](https://img.shields.io/pypi/dm/py3plex?cacheSeconds=3600)](https://pypistats.org/packages/py3plex)
17
17
  ![CLI Tool](https://img.shields.io/badge/CLI%20Tool-Available-brightgreen)
18
18
  ![Docker](https://img.shields.io/badge/Docker-Available-blue)
19
- ![Lines of Code](https://img.shields.io/badge/lines-213.8K-blue)
20
- ![Test Count](https://img.shields.io/badge/tests-9.7K-blue)
19
+ ![Lines of Code](https://img.shields.io/badge/lines-214.9K-blue)
20
+ ![Test Count](https://img.shields.io/badge/tests-10.0K-blue)
21
21
 
22
22
  *Multilayer networks* are complex networks with additional information assigned to nodes or edges (or both). This library includes
23
23
  some of the state-of-the-art algorithms for decomposition, visualization and analysis of such networks.
@@ -197,6 +197,8 @@ Safety notes for contributors:
197
197
  - Prefer running targeted tests first, then broader checks before opening a PR.
198
198
  - For docs-only updates, run `make docs-check` before opening a PR.
199
199
 
200
+ To report a bug, request a feature, or ask for help using py3plex, open an issue in the [issue tracker](https://github.com/SkBlaz/py3plex/issues). Include a minimal example and the py3plex and Python versions where relevant.
201
+
200
202
  ### MCP Integration (AI Agents)
201
203
 
202
204
  py3plex provides a Model Context Protocol (MCP) server for integration with AI coding assistants:
@@ -1,3 +1,3 @@
1
1
  """Single source for py3plex release version metadata."""
2
2
 
3
- __version__ = "2.0.8"
3
+ __version__ = "2.0.93"
@@ -46,7 +46,7 @@ def load_network_from_path(
46
46
  """Load a network from path and return stable machine-facing payload."""
47
47
  net = multinet.multi_layer_network(directed=directed)
48
48
  net.load_network(path, input_type=input_type)
49
- layers = list(net.get_layers())
49
+ layers = net.layers
50
50
  return {
51
51
  "status": "ok",
52
52
  "assumptions": ["Network path is trusted and readable."],
@@ -200,11 +200,11 @@ def correlate_attributes_across_layers(
200
200
  for i, l1 in enumerate(layers):
201
201
  for l2 in layers[i+1:]:
202
202
  # Find common nodes
203
- common_nodes = set(layer_attrs[l1].keys()) & set(layer_attrs[l2].keys())
203
+ common_nodes = [node for node in layer_attrs[l1] if node in layer_attrs[l2]]
204
204
 
205
205
  if len(common_nodes) > 1:
206
- vals1 = np.array([layer_attrs[l1][node] for node in sorted(common_nodes)])
207
- vals2 = np.array([layer_attrs[l2][node] for node in sorted(common_nodes)])
206
+ vals1 = np.array([layer_attrs[l1][node] for node in common_nodes])
207
+ vals2 = np.array([layer_attrs[l2][node] for node in common_nodes])
208
208
 
209
209
  corr, pval = _compute_correlation(vals1, vals2, correlation_method)
210
210
  results[(l1, l2)] = (corr, pval)
@@ -329,11 +329,11 @@ def _compute_correlation(x: np.ndarray, y: np.ndarray, method: str) -> Tuple[flo
329
329
  """
330
330
  valid_methods = ["pearson", "spearman", "kendall"]
331
331
  if method == "pearson":
332
- return pearsonr(x, y)
332
+ result = pearsonr(x, y)
333
333
  elif method == "spearman":
334
- return spearmanr(x, y)
334
+ result = spearmanr(x, y)
335
335
  elif method == "kendall":
336
- return kendalltau(x, y)
336
+ result = kendalltau(x, y)
337
337
  else:
338
338
  from py3plex.errors import find_similar
339
339
  did_you_mean = find_similar(method, valid_methods)
@@ -349,6 +349,9 @@ def _compute_correlation(x: np.ndarray, y: np.ndarray, method: str) -> Tuple[flo
349
349
  did_you_mean=did_you_mean
350
350
  )
351
351
 
352
+ corr, pval = result
353
+ return float(np.clip(corr, -1.0, 1.0)), float(np.clip(pval, 0.0, 1.0))
354
+
352
355
 
353
356
  def multilayer_assortativity(
354
357
  network: Any,
@@ -613,3 +616,4 @@ def attribute_centrality_independence_test(
613
616
  'n_nodes': len(attrs)
614
617
  }
615
618
 
619
+
@@ -77,7 +77,8 @@ def _brandes_sssp_weighted(
77
77
  - dist: Dict mapping each node to distance from source (inf if unreachable)
78
78
  """
79
79
  import heapq
80
-
80
+ from itertools import count
81
+
81
82
  S = []
82
83
  P = {v: [] for v in G}
83
84
  sigma = dict.fromkeys(G, 0.0)
@@ -85,22 +86,28 @@ def _brandes_sssp_weighted(
85
86
  dist = {v: float('inf') for v in G}
86
87
  dist[source] = 0.0
87
88
  seen = {source: 0.0}
88
- # Priority queue: (distance, node)
89
- Q = [(0.0, source)]
89
+ # A unique tie-breaker avoids comparing arbitrary node identifiers.
90
+ counter = count()
91
+ Q = [(0.0, next(counter), source)]
90
92
 
91
93
  while Q:
92
- (dist_v, v) = heapq.heappop(Q)
94
+ (dist_v, _, v) = heapq.heappop(Q)
93
95
  if dist_v > seen.get(v, float('inf')):
94
96
  continue # Already processed with shorter distance
95
97
  S.append(v)
96
98
 
97
99
  for w in G.neighbors(v):
98
- # Get edge weight
99
- vw_dist = dist[v] + G[v][w].get(weight, 1.0)
100
+ # NetworkX shortest paths use the minimum parallel-edge weight.
101
+ edge_data = G[v][w]
102
+ if G.is_multigraph():
103
+ edge_weight = min(data.get(weight, 1.0) for data in edge_data.values())
104
+ else:
105
+ edge_weight = edge_data.get(weight, 1.0)
106
+ vw_dist = dist[v] + edge_weight
100
107
  if vw_dist < dist[w]:
101
108
  dist[w] = vw_dist
102
109
  seen[w] = vw_dist
103
- heapq.heappush(Q, (vw_dist, w))
110
+ heapq.heappush(Q, (vw_dist, next(counter), w))
104
111
  sigma[w] = 0.0
105
112
  P[w] = []
106
113
  if vw_dist == dist[w]:
@@ -204,9 +211,9 @@ def approximate_betweenness_sampling(
204
211
  sumsq_c[v] += x * x
205
212
 
206
213
  # Scale to estimate sum over all sources
207
- # Estimator: (N-1) / n_samples * sum_over_samples
208
- # This is unbiased when sampling with replacement
209
- scale = (N - 1) / float(n_samples)
214
+ # Sources are sampled uniformly from all N nodes, including each target.
215
+ # The estimated population total is N times the sample mean.
216
+ scale = N / float(n_samples)
210
217
  betw = {v: scale * sum_c[v] for v in nodes}
211
218
 
212
219
  # Compute standard error if requested
@@ -217,8 +224,9 @@ def approximate_betweenness_sampling(
217
224
  mean = sum_c[v] / n_samples
218
225
  # Sample variance: E[X^2] - E[X]^2
219
226
  var = max(0.0, (sumsq_c[v] / n_samples) - mean * mean)
220
- # Standard error of scaled mean: scale * sqrt(var / n_samples)
221
- stderr[v] = scale * math.sqrt(var / n_samples) if var > 0 else 0.0
227
+ # The estimate is N times the sample mean, so its standard error
228
+ # scales by N (not the N / n_samples factor applied to the sum).
229
+ stderr[v] = N * math.sqrt(var / n_samples) if var > 0 else 0.0
222
230
 
223
231
  # Apply normalization and undirected correction
224
232
  # For undirected graphs, betweenness counts each path twice
@@ -56,7 +56,8 @@ def _allocate_landmarks(
56
56
 
57
57
  Args:
58
58
  components: List of connected components (sets of nodes)
59
- n_landmarks: Total number of landmarks to allocate
59
+ n_landmarks: Requested total, expanded if needed to cover each
60
+ non-trivial component
60
61
 
61
62
  Returns:
62
63
  List of landmark counts for each component (at least 1 for each non-trivial component)
@@ -64,31 +65,24 @@ def _allocate_landmarks(
64
65
  if not components:
65
66
  return []
66
67
 
67
- # Compute component sizes
68
- sizes = [len(c) for c in components]
69
- total_size = sum(sizes)
70
-
71
- if total_size == 0:
72
- return [0] * len(components)
73
-
74
- # Allocate proportionally, with at least 1 for non-trivial components
75
- allocation = []
76
- remaining = n_landmarks
77
-
78
- for i, size in enumerate(sizes):
79
- if size == 1:
80
- # Singleton component - no landmarks needed
81
- allocation.append(0)
82
- elif i == len(sizes) - 1:
83
- # Last component gets remaining landmarks
84
- allocation.append(max(1, remaining))
85
- else:
86
- # Allocate proportionally, at least 1
87
- count = max(1, int(round(n_landmarks * size / total_size)))
88
- count = min(count, remaining - (len(sizes) - i - 1)) # Save at least 1 for each remaining
89
- allocation.append(count)
90
- remaining -= count
91
-
68
+ allocation = [0] * len(components)
69
+ active = [i for i, comp in enumerate(components) if len(comp) > 1]
70
+ if not active:
71
+ return allocation
72
+
73
+ # Cover every non-trivial component, then apportion the remaining budget.
74
+ # A budget below the component count is expanded to retain that guarantee.
75
+ remaining = max(n_landmarks, len(active)) - len(active)
76
+ total_size = sum(len(components[i]) for i in active)
77
+ remainders = {}
78
+ for i in active:
79
+ extra, remainder = divmod(remaining * len(components[i]), total_size)
80
+ allocation[i] = 1 + extra
81
+ remainders[i] = remainder
82
+
83
+ leftover = max(n_landmarks, len(active)) - sum(allocation)
84
+ for i in sorted(active, key=lambda i: (-remainders[i], i))[:leftover]:
85
+ allocation[i] += 1
92
86
  return allocation
93
87
 
94
88
 
@@ -102,7 +96,8 @@ def approximate_closeness_landmarks(
102
96
  """Compute approximate closeness centrality using landmark sampling.
103
97
 
104
98
  For each node, this estimates closeness by computing average distance
105
- to randomly sampled landmark nodes. For undirected graphs, components
99
+ from randomly sampled landmark nodes, matching NetworkX inward
100
+ closeness for directed graphs. For undirected graphs, components
106
101
  are handled separately to avoid biasing estimates.
107
102
 
108
103
  Args:
@@ -118,9 +113,12 @@ def approximate_closeness_landmarks(
118
113
  - stderr_dict: Per-node standard error (None if diagnostics=False)
119
114
 
120
115
  Note:
121
- - For undirected graphs, landmarks are sampled per component
116
+ - For undirected graphs, landmarks are sampled per component, with at
117
+ least one per non-trivial component even if this exceeds n_landmarks
122
118
  - For directed graphs, landmarks are sampled globally
123
- - Closeness is defined as 1 / (average distance to reachable nodes)
119
+ - Directed closeness uses inward distances from reachable nodes
120
+ - Self-landmarks are excluded from the average and reachable fraction
121
+ - Uses NetworkX default Wasserman-Faust scaling for disconnected graphs
124
122
  - Time complexity: O(n_landmarks * (m + n log n)) for weighted graphs
125
123
  """
126
124
  rng = random.Random(seed)
@@ -139,9 +137,11 @@ def approximate_closeness_landmarks(
139
137
  comp_landmarks = _allocate_landmarks(comps, n_landmarks)
140
138
 
141
139
  # Sample landmarks from each component
140
+ # Preserve graph insertion order; component sets vary with PYTHONHASHSEED.
141
+ node_order = {node: i for i, node in enumerate(nodes)}
142
142
  landmarks = []
143
143
  for comp, k in zip(comps, comp_landmarks):
144
- comp_nodes = list(comp)
144
+ comp_nodes = sorted(comp, key=node_order.__getitem__)
145
145
  for _ in range(k):
146
146
  landmarks.append(comp_nodes[rng.randrange(len(comp_nodes))])
147
147
 
@@ -156,11 +156,11 @@ def approximate_closeness_landmarks(
156
156
  node_to_comp = None
157
157
 
158
158
  # Compute distances from each landmark
159
- # For directed graphs, we want distances TO landmarks, so we reverse
159
+ # Distances FROM landmarks estimate inward closeness for directed graphs.
160
160
  dist_maps = []
161
161
  for l in landmarks:
162
162
  dist = _single_source_shortest_path_lengths(
163
- G, l, weight=weight, reverse_for_directed=G.is_directed()
163
+ G, l, weight=weight
164
164
  )
165
165
  dist_maps.append(dist)
166
166
 
@@ -169,7 +169,7 @@ def approximate_closeness_landmarks(
169
169
  stderr = {} if diagnostics else None
170
170
 
171
171
  for v in nodes:
172
- # Collect distances from v to landmarks
172
+ # Collect distances from landmarks to v
173
173
  if node_to_comp is not None:
174
174
  # Undirected: use only landmarks from same component
175
175
  v_comp = node_to_comp[v]
@@ -177,11 +177,12 @@ def approximate_closeness_landmarks(
177
177
  for i, dist in enumerate(dist_maps):
178
178
  landmark = landmarks[i]
179
179
  l_comp = node_to_comp[landmark]
180
- if l_comp == v_comp and v in dist:
180
+ if l_comp == v_comp and landmark != v and v in dist:
181
181
  dists.append(dist[v])
182
182
  else:
183
183
  # Directed: use all landmarks
184
- dists = [dist[v] for dist in dist_maps if v in dist]
184
+ dists = [dist[v] for landmark, dist in zip(landmarks, dist_maps)
185
+ if landmark != v and v in dist]
185
186
 
186
187
  if not dists:
187
188
  # No reachable landmarks
@@ -199,12 +200,14 @@ def approximate_closeness_landmarks(
199
200
  else:
200
201
  base_closeness = 1.0 / mean_d
201
202
 
202
- # For directed graphs, adjust by reachable fraction
203
+ # NetworkX excludes the node itself and applies the Wasserman-Faust
204
+ # reachable fraction. Self-landmarks are not draws from other nodes.
203
205
  if G.is_directed():
204
- reachable_frac = len(dists) / float(len(landmarks)) if landmarks else 0.0
205
- closeness[v] = base_closeness * reachable_frac
206
+ other_landmarks = sum(landmark != v for landmark in landmarks)
207
+ reachable_frac = len(dists) / float(other_landmarks)
206
208
  else:
207
- closeness[v] = base_closeness
209
+ reachable_frac = (len(comps[v_comp]) - 1) / float(N - 1)
210
+ closeness[v] = base_closeness * reachable_frac
208
211
 
209
212
  # Compute standard error using delta method
210
213
  if diagnostics:
@@ -214,14 +217,10 @@ def approximate_closeness_landmarks(
214
217
  # Standard error of mean
215
218
  se_mean = math.sqrt(var_d / len(dists))
216
219
  # Delta method: var(1/X) ≈ (se/mean^2)^2 for small se
217
- stderr[v] = se_mean / (mean_d * mean_d)
220
+ stderr[v] = reachable_frac * se_mean / (mean_d * mean_d)
218
221
  else:
219
222
  stderr[v] = 0.0
220
223
 
221
- # Optional normalization (consistent with NetworkX)
222
- # NetworkX closeness_centrality normalizes by (N-1) for simple graphs
223
- # We keep raw estimates for now, but could add normalization flag if needed
224
-
225
224
  return closeness, stderr
226
225
 
227
226
 
@@ -44,7 +44,7 @@ class ExperimentKB:
44
44
  self._calc_predicate_members(triplets)
45
45
  self._find_roots(all_annotations)
46
46
  self._calc_members_closure()
47
- self._calc_binary_members()
47
+ self._calc_binary_members(triplets)
48
48
  self._propagate_annotation_names(triplets)
49
49
 
50
50
  # Statistics
@@ -236,7 +236,7 @@ class ExperimentKB:
236
236
  # Run the closure from root
237
237
  closure(self.dummy_root, 0)
238
238
 
239
- def _calc_binary_members(self):
239
+ def _calc_binary_members(self, g):
240
240
  self.binary_members = defaultdict(dict)
241
241
  self.reverse_binary_members = defaultdict(dict)
242
242
 
@@ -245,13 +245,13 @@ class ExperimentKB:
245
245
 
246
246
  for pair in pairs:
247
247
  el1, el2 = self.uri_to_idx[pair[0]], self.uri_to_idx[pair[1]]
248
- if self.binary_members[pred].has_key(el1):
248
+ if el1 in self.binary_members[pred]:
249
249
  self.binary_members[pred][el1].append(el2)
250
250
  else:
251
251
  self.binary_members[pred][el1] = [el2]
252
252
 
253
253
  # Add the reverse as well
254
- if self.reverse_binary_members[pred].has_key(el2):
254
+ if el2 in self.reverse_binary_members[pred]:
255
255
  self.reverse_binary_members[pred][el2].append(el1)
256
256
  else:
257
257
  self.reverse_binary_members[pred][el2] = [el1]
@@ -60,10 +60,12 @@ def jaccard_layer_similarity(
60
60
  if isinstance(node, tuple) and len(node) >= 2 and node[1] == layer2}
61
61
 
62
62
  elif element == "edges":
63
- set1 = {(u[0], v[0]) for u, v in G.edges()
63
+ # Undirected edges are unordered, regardless of node insertion order.
64
+ edge_identity = tuple if G.is_directed() else frozenset
65
+ set1 = {edge_identity((u[0], v[0])) for u, v in G.edges()
64
66
  if isinstance(u, tuple) and isinstance(v, tuple) and
65
67
  len(u) >= 2 and len(v) >= 2 and u[1] == layer1 and v[1] == layer1}
66
- set2 = {(u[0], v[0]) for u, v in G.edges()
68
+ set2 = {edge_identity((u[0], v[0])) for u, v in G.edges()
67
69
  if isinstance(u, tuple) and isinstance(v, tuple) and
68
70
  len(u) >= 2 and len(v) >= 2 and u[1] == layer2 and v[1] == layer2}
69
71
  else:
@@ -1011,7 +1011,7 @@ class MultilayerCentrality:
1011
1011
  # Map back to node-layer pairs
1012
1012
  results = {}
1013
1013
  for node_layer, idx in node_layer_mapping.items():
1014
- results[node_layer] = nx_current_flow.get(idx, 0.0)
1014
+ results[node_layer] = max(0.0, nx_current_flow.get(idx, 0.0))
1015
1015
 
1016
1016
  return results
1017
1017
 
@@ -649,15 +649,6 @@ def plot_simplex(points, names=("C1", "C2"), proba_triplet=None):
649
649
  fig = plt.figure()
650
650
  fig.set_size_inches(8, 7)
651
651
 
652
- nl, ne, nr = np.max(points, axis=0)
653
- for i, n in enumerate((nl, ne, nr)):
654
- if n < 0.001:
655
- print(
656
- "p{} is too small, switching to 2d plot".format(names[::-1] + ["rope"])
657
- )
658
- coords = sorted(set(range(3)) - i)
659
- return plot2d(points[:, coords], labels[coords])
660
-
661
652
  # triangle
662
653
  fig.gca().add_line(
663
654
  Line2D([0, 0.5, 1.0, 0], [0, np.sqrt(3) / 2, 0, 0], color="black")
@@ -669,6 +660,10 @@ def plot_simplex(points, names=("C1", "C2"), proba_triplet=None):
669
660
  [vert0[0, 0], vert0[i, 0]], [vert0[0, 1], vert0[i, 1]], color="black"
670
661
  )
671
662
  )
663
+ # Degenerate posteriors remain valid points on a simplex edge.
664
+ if proba_triplet is None:
665
+ proba_triplet = np.mean(points, axis=0)
666
+
672
667
  # vertex labels
673
668
  rcParams.update({"font.size": 16})
674
669
  fig.gca().text(-0.08, -0.08, f"p({names[0]} ({proba_triplet[0]}))", color="black")
@@ -35,13 +35,14 @@ def diagram(
35
35
  the_algorithm_candidate: Optional[str],
36
36
  output_figure_file: Optional[str],
37
37
  fontsize: int = 10,
38
+ critical_distance: Optional[float] = None,
38
39
  ) -> Optional[str]:
39
40
  """
40
41
  Draws critical distance diagram for Nemenyi or Bonferroni-Dunn post-hoc test.
41
42
  The diagram is shown if output_figure_file is None, and saved otherwise
42
43
  to the file.
43
44
  :param list_of_algorithms: [[(alg_name1, avg_rank1)], ...]
44
- :param critical_distance:
45
+ :param critical_distance: Optional positive Nemenyi critical distance.
45
46
  :param output_figure_file: If not none, the diagram produced is saved to the specified file.
46
47
  Otherwise, the diagram is shown.
47
48
  :param the_algorithm_candidate: If we were performing Bonferroni-Dunn post-hcc test (1 vs all),
@@ -50,6 +51,10 @@ def diagram(
50
51
  :return: output_figure_file
51
52
  """
52
53
 
54
+ if critical_distance is not None and (
55
+ not np.isfinite(critical_distance) or critical_distance <= 0
56
+ ):
57
+ raise ValueError("critical_distance must be a positive finite number")
53
58
  n = len(list_of_algorithms)
54
59
  sorted_algorithms = sorted(list_of_algorithms, key=lambda t: t[1])
55
60
  the_index = None
@@ -96,7 +101,7 @@ def diagram(
96
101
  weight="normal",
97
102
  stretch="normal",
98
103
  )
99
- rc("text", usetex=True)
104
+ # Respect the caller's text renderer; plotting does not require LaTeX.
100
105
  rc("font", **fontProperties)
101
106
 
102
107
  def name_length(name: str) -> float:
@@ -256,9 +261,9 @@ def diagram(
256
261
  plot_algorithm(i, alg_rank_tuple[0], alg_rank_tuple[1])
257
262
  # critical distance
258
263
 
259
- # plot_critical_distance()
260
- # algorithm groups
261
- # plot_groups(algorithm_groups())
264
+ if critical_distance is not None:
265
+ plot_critical_distance()
266
+ plot_groups(algorithm_groups())
262
267
  # save / show the results
263
268
  if output_figure_file is not None:
264
269
  folder_end = output_figure_file.rfind("/")
@@ -333,7 +338,6 @@ def plot_critical_distance(
333
338
  fontsize: int = 10,
334
339
  ) -> None:
335
340
 
336
- import operator
337
341
  from collections import defaultdict
338
342
 
339
343
  if groupby is None:
@@ -350,10 +354,12 @@ def plot_critical_distance(
350
354
 
351
355
  for _k, v in ranks.items():
352
356
  a = dict(v)
353
- sorted_d = sorted(a.items(), key=operator.itemgetter(1))
354
- for en, j in enumerate(sorted_d):
355
- logger.debug("Rank %d: %s", en, j[0])
356
- clf_ranks[j[0]].append(len(sorted_d) - en)
357
+ from scipy.stats import rankdata
358
+ names = list(a)
359
+ # Higher scores are better; ties receive their shared average rank.
360
+ dataset_ranks = rankdata([-a[name] for name in names], method="average")
361
+ for name, rank in zip(names, dataset_ranks):
362
+ clf_ranks[name].append(float(rank))
357
363
 
358
364
  fname[groupby[0]].nunique()
359
365
  clf_score = {k: np.mean(v) for k, v in clf_ranks.items()}
@@ -361,9 +367,22 @@ def plot_critical_distance(
361
367
  avranks = list(clf_score.values())
362
368
  pairs = list(zip(names, avranks))
363
369
  if crit_dist:
364
- cd = Orange.evaluation.compute_CD( # type: ignore[name-defined]
365
- avranks[0 : (len(avranks) - 1)], comparisons, alpha="0.05" # type: ignore[name-defined]
366
- )
370
+ # Nemenyi's CD uses the full algorithm count and independent datasets.
371
+ k = len(avranks)
372
+ comparisons = len(ranks)
373
+ if k < 2 or comparisons < 1:
374
+ raise ValueError("Critical distance requires at least two algorithms and one dataset")
375
+ algorithms = set(clf_score)
376
+ if any({name for name, _ in rows} != algorithms for rows in ranks.values()):
377
+ raise ValueError("Critical distance requires the same algorithms in every dataset")
378
+ if not np.all(np.isfinite(rkx.to_numpy())):
379
+ raise ValueError("Critical distance requires finite scores")
380
+ try:
381
+ from scipy.stats import studentized_range
382
+ except ImportError as exc:
383
+ raise ImportError("Critical distance plotting requires scipy>=1.7") from exc
384
+ q_alpha = studentized_range.ppf(0.95, k, np.inf) / np.sqrt(2)
385
+ cd = float(q_alpha * np.sqrt(k * (k + 1) / (6 * comparisons)))
386
+ diagram(pairs, None, outfile, fontsize=fontsize, critical_distance=cd)
367
387
  else:
368
- cd = None
369
- diagram(pairs, cd, outfile, fontsize=fontsize)
388
+ diagram(pairs, None, outfile, fontsize=fontsize)
@@ -28,6 +28,9 @@ def streaming_pagerank(
28
28
  incrementally, using the previous window's scores as the starting point
29
29
  for the next window. This is much faster than recomputing from scratch
30
30
  for each window.
31
+
32
+ Scores held by nodes without outgoing edges are redistributed uniformly
33
+ among the current window's nodes at each power iteration.
31
34
 
32
35
  Args:
33
36
  temporal_network: TemporalMultiLayerNetwork instance
@@ -97,6 +100,11 @@ def streaming_pagerank(
97
100
  # Run limited power iteration
98
101
  for _ in range(max_iter_per_window):
99
102
  new_scores = {}
103
+ dangling_mass = sum(
104
+ scores[node]
105
+ for node in nodes
106
+ if (graph.out_degree(node) if graph.is_directed() else graph.degree(node)) == 0
107
+ ) / len(nodes)
100
108
 
101
109
  for node in nodes:
102
110
  # Compute incoming contribution
@@ -105,16 +113,24 @@ def streaming_pagerank(
105
113
  if pred in scores:
106
114
  # Get out-degree of predecessor
107
115
  out_degree = graph.out_degree(pred) if graph.is_directed() else graph.degree(pred)
116
+ if not graph.is_directed():
117
+ # Degree counts self-loops twice; PageRank traverses them once.
118
+ out_degree -= graph.number_of_edges(pred, pred)
108
119
  if out_degree > 0:
109
- incoming_score += scores[pred] / out_degree
120
+ edge_count = graph.number_of_edges(pred, node)
121
+ incoming_score += scores[pred] * edge_count / out_degree
110
122
 
111
123
  # Apply damping
112
- new_scores[node] = (1 - damping_factor) / len(nodes) + damping_factor * incoming_score
124
+ new_scores[node] = (
125
+ (1 - damping_factor) / len(nodes)
126
+ + damping_factor * (incoming_score + dangling_mass)
127
+ )
113
128
 
114
129
  # Check convergence
115
130
  if scores:
116
131
  max_change = max(abs(new_scores.get(n, 0) - scores.get(n, 0)) for n in nodes)
117
132
  if max_change < tolerance:
133
+ scores = new_scores
118
134
  break
119
135
 
120
136
  scores = new_scores
@@ -145,7 +161,8 @@ def streaming_degree_centrality(
145
161
  temporal_network: TemporalMultiLayerNetwork instance
146
162
  window_size: Size of each time window (required)
147
163
  step: Step size between windows (defaults to window_size)
148
- normalize: Whether to normalize by max possible degree (default: True)
164
+ normalize: Whether to divide total degree by n - 1 (default: True).
165
+ Directed, parallel, or self-loop degrees may yield values above 1.
149
166
 
150
167
  Yields:
151
168
  Tuples of (t_start, t_end, centrality_dict)
@@ -181,7 +198,7 @@ def streaming_degree_centrality(
181
198
  # Normalize if requested
182
199
  if normalize and degrees:
183
200
  n = graph.number_of_nodes()
184
- max_degree = 2 * (n - 1) if not graph.is_directed() else (n - 1)
201
+ max_degree = n - 1
185
202
  if max_degree > 0:
186
203
  degrees = {node: deg / max_degree for node, deg in degrees.items()}
187
204