synkit 1.6.5__py3-none-win_amd64.whl
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.
- synkit/CRN/Benchmark/__init__.py +53 -0
- synkit/CRN/Benchmark/crosschecks.py +13 -0
- synkit/CRN/Benchmark/kegg.py +12 -0
- synkit/CRN/Benchmark/networks.py +13 -0
- synkit/CRN/Benchmark/scaling.py +13 -0
- synkit/CRN/Benchmark/validate.py +13 -0
- synkit/CRN/Construct/__init__.py +16 -0
- synkit/CRN/Construct/abstract.py +668 -0
- synkit/CRN/Construct/arity.py +36 -0
- synkit/CRN/Construct/builder.py +619 -0
- synkit/CRN/Construct/derivation.py +63 -0
- synkit/CRN/Construct/flattener.py +100 -0
- synkit/CRN/Construct/keys.py +14 -0
- synkit/CRN/Construct/mixtures.py +117 -0
- synkit/CRN/Construct/rdkit_worker.py +69 -0
- synkit/CRN/Construct/smiles.py +99 -0
- synkit/CRN/Construct/state.py +31 -0
- synkit/CRN/Construct/strategy.py +75 -0
- synkit/CRN/Construct/worker.py +42 -0
- synkit/CRN/IO/__init__.py +36 -0
- synkit/CRN/IO/sbml.py +925 -0
- synkit/CRN/Pathway/__init__.py +72 -0
- synkit/CRN/Pathway/_adapter.py +333 -0
- synkit/CRN/Pathway/pathfinder.py +500 -0
- synkit/CRN/Pathway/reachability.py +796 -0
- synkit/CRN/Pathway/realizability.py +1322 -0
- synkit/CRN/Petrinet/__init__.py +93 -0
- synkit/CRN/Petrinet/analyzer.py +486 -0
- synkit/CRN/Petrinet/minimal_semiflows.py +436 -0
- synkit/CRN/Petrinet/net.py +1041 -0
- synkit/CRN/Petrinet/persistence.py +97 -0
- synkit/CRN/Petrinet/semiflows.py +483 -0
- synkit/CRN/Petrinet/siphon_search.py +402 -0
- synkit/CRN/Petrinet/structure.py +286 -0
- synkit/CRN/Props/__init__.py +130 -0
- synkit/CRN/Props/_rank.py +29 -0
- synkit/CRN/Props/deficiency.py +953 -0
- synkit/CRN/Props/dynamics.py +832 -0
- synkit/CRN/Props/helper.py +151 -0
- synkit/CRN/Props/stoich.py +751 -0
- synkit/CRN/Props/thermo.py +584 -0
- synkit/CRN/Query/__init__.py +66 -0
- synkit/CRN/Query/cache.py +41 -0
- synkit/CRN/Query/kegg_api.py +99 -0
- synkit/CRN/Query/kegg_extract.py +714 -0
- synkit/CRN/Query/kegg_impute.py +707 -0
- synkit/CRN/Query/kegg_parse.py +480 -0
- synkit/CRN/Query/to_syncrn.py +290 -0
- synkit/CRN/README.md +234 -0
- synkit/CRN/Structure/__init__.py +12 -0
- synkit/CRN/Structure/_graph_io.py +713 -0
- synkit/CRN/Structure/_matrices.py +88 -0
- synkit/CRN/Structure/_parse.py +544 -0
- synkit/CRN/Structure/reaction.py +237 -0
- synkit/CRN/Structure/rule.py +55 -0
- synkit/CRN/Structure/species.py +46 -0
- synkit/CRN/Structure/syncrn.py +929 -0
- synkit/CRN/Symmetry/__init__.py +20 -0
- synkit/CRN/Symmetry/_common.py +1059 -0
- synkit/CRN/Symmetry/_ir.py +940 -0
- synkit/CRN/Symmetry/automorphism.py +472 -0
- synkit/CRN/Symmetry/canon.py +441 -0
- synkit/CRN/Symmetry/isomorphism.py +412 -0
- synkit/CRN/Symmetry/symmetry.py +61 -0
- synkit/CRN/Symmetry/wl_canon.py +967 -0
- synkit/CRN/Visualize/__init__.py +11 -0
- synkit/CRN/Visualize/labels.py +113 -0
- synkit/CRN/Visualize/layout.py +708 -0
- synkit/CRN/Visualize/palette.py +292 -0
- synkit/CRN/Visualize/validation.py +122 -0
- synkit/CRN/Visualize/vis.py +1152 -0
- synkit/CRN/__init__.py +233 -0
- synkit/CRN/_build.py +50 -0
- synkit/CRN/_native_build.py +175 -0
- synkit/CRN/analysis.py +629 -0
- synkit/CRN/backend.py +74 -0
- synkit/CRN/cpp/CMakeLists.txt +58 -0
- synkit/CRN/cpp/algebra.cpp +46 -0
- synkit/CRN/cpp/closure.cpp +29 -0
- synkit/CRN/cpp/exact.h +55 -0
- synkit/CRN/cpp/pathway.cpp +46 -0
- synkit/CRN/cpp/semiflows.cpp +209 -0
- synkit/CRN/cpp/structural.cpp +240 -0
- synkit/CRN/cpp/symmetry.cpp +45 -0
- synkit/CRN/cpp/write_manifest.cmake +28 -0
- synkit/CRN/kinds.py +137 -0
- synkit/CRN/lib/synkit_crn.dll +0 -0
- synkit/CRN/lib/synkit_crn.json +33 -0
- synkit/CRN/native.py +388 -0
- synkit/CRN/native_analysis.py +459 -0
- synkit/Chem/Cluster/__init__.py +0 -0
- synkit/Chem/Cluster/butina.py +140 -0
- synkit/Chem/Fingerprint/__init__.py +0 -0
- synkit/Chem/Fingerprint/fp_calculator.py +155 -0
- synkit/Chem/Fingerprint/smiles_featurizer.py +258 -0
- synkit/Chem/Fingerprint/transformation_fp.py +139 -0
- synkit/Chem/Mapper/README.rst +43 -0
- synkit/Chem/Mapper/__init__.py +255 -0
- synkit/Chem/Mapper/_compat.py +130 -0
- synkit/Chem/Mapper/adapters/__init__.py +1 -0
- synkit/Chem/Mapper/adapters/prediction.py +126 -0
- synkit/Chem/Mapper/adapters/template.py +412 -0
- synkit/Chem/Mapper/chem/__init__.py +52 -0
- synkit/Chem/Mapper/chem/aam.py +673 -0
- synkit/Chem/Mapper/chem/blind.py +160 -0
- synkit/Chem/Mapper/chem/its.py +309 -0
- synkit/Chem/Mapper/chem/smiles.py +564 -0
- synkit/Chem/Mapper/graph/__init__.py +66 -0
- synkit/Chem/Mapper/graph/automorphism.py +395 -0
- synkit/Chem/Mapper/graph/blockcut.py +98 -0
- synkit/Chem/Mapper/graph/labeled_graph.py +104 -0
- synkit/Chem/Mapper/graph/refine.py +176 -0
- synkit/Chem/Mapper/graph/synkit_adapter.py +110 -0
- synkit/Chem/Mapper/io/__init__.py +13 -0
- synkit/Chem/Mapper/io/idxmapstr.py +82 -0
- synkit/Chem/Mapper/mapper.py +685 -0
- synkit/Chem/Mapper/reaction_search.py +554 -0
- synkit/Chem/Mapper/reporting/__init__.py +1 -0
- synkit/Chem/Mapper/reporting/alternatives.py +451 -0
- synkit/Chem/Mapper/reporting/analysis.py +681 -0
- synkit/Chem/Mapper/reporting/native_analysis.py +485 -0
- synkit/Chem/Mapper/reporting/spectrum.py +642 -0
- synkit/Chem/Mapper/solvers/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/__init__.py +141 -0
- synkit/Chem/Mapper/solvers/exact/assignment/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/assignment/assignment_certificate.py +113 -0
- synkit/Chem/Mapper/solvers/exact/assignment/assignment_domains.py +162 -0
- synkit/Chem/Mapper/solvers/exact/assignment/assignment_verification.py +58 -0
- synkit/Chem/Mapper/solvers/exact/assignment/incremental_assignment.py +247 -0
- synkit/Chem/Mapper/solvers/exact/certificate.py +128 -0
- synkit/Chem/Mapper/solvers/exact/core.py +183 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/bounds.py +319 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/exhaustive.py +179 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/inputs.py +283 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/records.py +242 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/search.py +1025 -0
- synkit/Chem/Mapper/solvers/exact/distance_search/verify.py +378 -0
- synkit/Chem/Mapper/solvers/exact/edit_support.py +375 -0
- synkit/Chem/Mapper/solvers/exact/hybrid.py +224 -0
- synkit/Chem/Mapper/solvers/exact/hydrogen.py +264 -0
- synkit/Chem/Mapper/solvers/exact/kernel_solvers/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/kernel_solvers/branching.py +499 -0
- synkit/Chem/Mapper/solvers/exact/kernel_solvers/enumerate.py +1050 -0
- synkit/Chem/Mapper/solvers/exact/kernel_solvers/enumeration_result.py +30 -0
- synkit/Chem/Mapper/solvers/exact/kernel_solvers/kernel.py +256 -0
- synkit/Chem/Mapper/solvers/exact/kernel_solvers/milp.py +194 -0
- synkit/Chem/Mapper/solvers/exact/native/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/native/build.py +154 -0
- synkit/Chem/Mapper/solvers/exact/native/candidates.py +593 -0
- synkit/Chem/Mapper/solvers/exact/native/canonical.py +396 -0
- synkit/Chem/Mapper/solvers/exact/native/disk_frontier.py +415 -0
- synkit/Chem/Mapper/solvers/exact/native/frontier.py +390 -0
- synkit/Chem/Mapper/solvers/exact/native/hydrogen_quotient.py +213 -0
- synkit/Chem/Mapper/solvers/exact/native/its.py +528 -0
- synkit/Chem/Mapper/solvers/exact/native/native_distance.cpp +2803 -0
- synkit/Chem/Mapper/solvers/exact/native/orbit_aggregation.py +328 -0
- synkit/Chem/Mapper/solvers/exact/native/parallel.py +205 -0
- synkit/Chem/Mapper/solvers/exact/native/pmcd.py +203 -0
- synkit/Chem/Mapper/solvers/exact/native/runtime.py +40 -0
- synkit/Chem/Mapper/solvers/exact/native/search.py +294 -0
- synkit/Chem/Mapper/solvers/exact/native/separator.py +224 -0
- synkit/Chem/Mapper/solvers/exact/native_build.py +12 -0
- synkit/Chem/Mapper/solvers/exact/pabs/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/pabs/cost_lattice.py +43 -0
- synkit/Chem/Mapper/solvers/exact/pabs/factor_spectrum.py +110 -0
- synkit/Chem/Mapper/solvers/exact/pabs/multi_shell.py +368 -0
- synkit/Chem/Mapper/solvers/exact/pabs/propagation.py +679 -0
- synkit/Chem/Mapper/solvers/exact/pabs/propagation_bounds.py +436 -0
- synkit/Chem/Mapper/solvers/exact/pabs/propagation_limits.py +13 -0
- synkit/Chem/Mapper/solvers/exact/pabs/propagation_search.py +856 -0
- synkit/Chem/Mapper/solvers/exact/pabs/propagation_symmetry.py +66 -0
- synkit/Chem/Mapper/solvers/exact/pabs/residual_typed_bonds.py +136 -0
- synkit/Chem/Mapper/solvers/exact/pabs/reward_frontier.py +201 -0
- synkit/Chem/Mapper/solvers/exact/pabs/separator_bound.py +258 -0
- synkit/Chem/Mapper/solvers/exact/pabs/separator_spectrum.py +308 -0
- synkit/Chem/Mapper/solvers/exact/pabs/sparse_reward_bound.py +207 -0
- synkit/Chem/Mapper/solvers/exact/pabs/suffix_spectrum.py +299 -0
- synkit/Chem/Mapper/solvers/exact/search.py +55 -0
- synkit/Chem/Mapper/solvers/exact/seeds/__init__.py +1 -0
- synkit/Chem/Mapper/solvers/exact/seeds/seed.py +104 -0
- synkit/Chem/Mapper/solvers/exact/seeds/seed_fragments.py +148 -0
- synkit/Chem/Mapper/solvers/exact/seeds/seed_relaxation.py +181 -0
- synkit/Chem/Mapper/solvers/exact/symmetry.py +223 -0
- synkit/Chem/Mapper/solvers/native/__init__.py +4 -0
- synkit/Chem/Mapper/solvers/native/assignment.py +99 -0
- synkit/Chem/Mapper/solvers/native/astar.py +22 -0
- synkit/Chem/Mapper/solvers/native/build.py +385 -0
- synkit/Chem/Mapper/solvers/native/classification.py +641 -0
- synkit/Chem/Mapper/solvers/native/core.py +378 -0
- synkit/Chem/Mapper/solvers/native/cpp/CMakeLists.txt +120 -0
- synkit/Chem/Mapper/solvers/native/cpp/examples/map_reaction.cpp +29 -0
- synkit/Chem/Mapper/solvers/native/cpp/examples/slap_graph.cpp +63 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/assignment/assignment.h +18 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/astar/astar.h +18 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/astar/bound.h +33 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/core/pmcd_witness.h +16 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/core/runtime.h +130 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/hydrogen/hydrogen.h +73 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/mapper.h +175 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/mces/mces.h +9 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/pabs/seed.h +34 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/reaction/reaction.h +30 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/sepdp/sepdp.h +21 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/slap.h +72 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/solvers/solvers.h +16 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/symmetry/classification.h +140 -0
- synkit/Chem/Mapper/solvers/native/cpp/include/synkit_mapper/symmetry/cpabs.h +33 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/assignment/abb.cpp +302 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/astar/CMakeLists.txt +12 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/astar/README.md +47 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/astar/astar.cpp +228 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/astar/astar_graph.cpp +37 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/astar/bound.cpp +212 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/core/dispatch.cpp +272 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/core/pmcd_witness.cpp +36 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/hydrogen/hydrogen.cpp +380 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/mces/README.md +57 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/mces/mces.cpp +287 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/bridge.cpp +334 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/chemical_floor.inc +181 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/endpoint_symmetry.inc +104 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/exact_helpers.h +20 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_assignment_certificate.h +165 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_certificate.h +125 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_model.h +365 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_provider.inc +319 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_rounding.inc +170 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/lp_test_hooks.h +342 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/objective_reduction.inc +137 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/overlap_dual.inc +351 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/profile_seed.inc +214 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/seed_heuristics.inc +640 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/sparse_embedding.cpp +430 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/sparse_root_lp.h +176 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/pabs/test_hooks.inc +262 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/reaction/reaction.cpp +611 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/sepdp/README.md +61 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/sepdp/sepdp.cpp +253 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/slap.cpp +810 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/solvers/formulation.h +138 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/solvers/maxsat.cpp +526 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/solvers/ortools.cpp +475 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/solvers/seed.h +80 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/solvers/weighted_cnf.h +256 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/supporting/README.md +43 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/supporting/dfs.cpp +123 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/supporting/edit_support.cpp +224 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/classification.cpp +553 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/classification_pipeline.cpp +124 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/classification_stream.h +13 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/cpabs.cpp +455 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/edge_deck.cpp +743 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/COPYRIGHT +44 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/LICENSE-2.0.txt +202 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naugraph.c +732 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naurng.c +94 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naurng.h +49 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nausparse.c +1771 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nausparse.h +133 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nautil.c +750 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/naututil.h +355 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nauty.c +1256 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/nauty.h +1544 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/schreier.c +1131 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/schreier.h +70 -0
- synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/sorttemplates.c +580 -0
- synkit/Chem/Mapper/solvers/native/hydrogen.py +711 -0
- synkit/Chem/Mapper/solvers/native/implicit.py +506 -0
- synkit/Chem/Mapper/solvers/native/implicit_certificate.py +187 -0
- synkit/Chem/Mapper/solvers/native/implicit_preparation.py +309 -0
- synkit/Chem/Mapper/solvers/native/lib/synkit_mapper.dll +0 -0
- synkit/Chem/Mapper/solvers/native/mces.py +16 -0
- synkit/Chem/Mapper/solvers/native/reaction.py +179 -0
- synkit/Chem/Mapper/solvers/native/reaction_build.py +277 -0
- synkit/Chem/Mapper/solvers/native/reaction_text.py +26 -0
- synkit/Chem/Mapper/solvers/native/runtime.py +242 -0
- synkit/Chem/Mapper/solvers/native/sepdp.py +47 -0
- synkit/Chem/Mapper/solvers/native/slap.py +266 -0
- synkit/Chem/Mapper/solvers/native/solvers.py +67 -0
- synkit/Chem/Mapper/solvers/native/stereo.py +86 -0
- synkit/Chem/Mapper/solvers/native/supporting.py +34 -0
- synkit/Chem/Mapper/solvers/native/symmetry.py +91 -0
- synkit/Chem/Mapper/solvers/slap/__init__.py +29 -0
- synkit/Chem/Mapper/solvers/slap/lap.py +174 -0
- synkit/Chem/Mapper/solvers/slap/sequential.py +696 -0
- synkit/Chem/Mapper/validation/__init__.py +1 -0
- synkit/Chem/Mapper/validation/aam_validator.py +442 -0
- synkit/Chem/Mapper/validation/annotations.py +274 -0
- synkit/Chem/Mapper/validation/bonds.py +124 -0
- synkit/Chem/Mapper/validation/cohorts.py +72 -0
- synkit/Chem/Mapper/validation/identifiability.py +150 -0
- synkit/Chem/Mapper/validation/numerical_scope.py +36 -0
- synkit/Chem/Mapper/validation/orbits.py +137 -0
- synkit/Chem/Molecule/__init__.py +0 -0
- synkit/Chem/Molecule/_chirality_loci.py +165 -0
- synkit/Chem/Molecule/_chirality_types.py +231 -0
- synkit/Chem/Molecule/_helical_loci.py +167 -0
- synkit/Chem/Molecule/_stereo_axis_evidence.py +202 -0
- synkit/Chem/Molecule/_stereo_element_detection.py +193 -0
- synkit/Chem/Molecule/_stereo_orientation_constraints.py +511 -0
- synkit/Chem/Molecule/_tetrahedral_carriers.py +63 -0
- synkit/Chem/Molecule/atom_features.py +379 -0
- synkit/Chem/Molecule/chirality.py +1041 -0
- synkit/Chem/Molecule/cip_assignment.py +569 -0
- synkit/Chem/Molecule/cip_ranking.py +843 -0
- synkit/Chem/Molecule/coordinate_stereo.py +503 -0
- synkit/Chem/Molecule/derived_stereo_naming.py +165 -0
- synkit/Chem/Molecule/descriptors.py +452 -0
- synkit/Chem/Molecule/formula.py +249 -0
- synkit/Chem/Molecule/global_stereo.py +175 -0
- synkit/Chem/Molecule/graph_annotator.py +300 -0
- synkit/Chem/Molecule/standardize.py +817 -0
- synkit/Chem/Molecule/stereo_evidence.py +179 -0
- synkit/Chem/Molecule/stereo_perception.py +1032 -0
- synkit/Chem/Molecule/valence.py +123 -0
- synkit/Chem/Reaction/Mapper/__init__.py +44 -0
- synkit/Chem/Reaction/__init__.py +20 -0
- synkit/Chem/Reaction/aam_validator.py +5 -0
- synkit/Chem/Reaction/balance_check.py +138 -0
- synkit/Chem/Reaction/canon_rsmi.py +249 -0
- synkit/Chem/Reaction/cleaning.py +58 -0
- synkit/Chem/Reaction/deionize.py +199 -0
- synkit/Chem/Reaction/explicit_h_audit.py +232 -0
- synkit/Chem/Reaction/fix_aam.py +64 -0
- synkit/Chem/Reaction/neutralize.py +207 -0
- synkit/Chem/Reaction/radical_wildcard.py +224 -0
- synkit/Chem/Reaction/standardize.py +203 -0
- synkit/Chem/Reaction/tautomerize.py +205 -0
- synkit/Chem/__init__.py +1 -0
- synkit/Chem/utils.py +315 -0
- synkit/Data/__init__.py +0 -0
- synkit/Data/aldol.json.gz +1 -0
- synkit/Data/gen_partial_aam.py +147 -0
- synkit/Data/paracetamol.json.gz +1 -0
- synkit/Graph/Canon/__init__.py +16 -0
- synkit/Graph/Canon/_native/__init__.py +13 -0
- synkit/Graph/Canon/_native/build.py +93 -0
- synkit/Graph/Canon/_native/lib/synkit_canon.dll +0 -0
- synkit/Graph/Canon/_native/prepare.py +49 -0
- synkit/Graph/Canon/_native/runtime.py +140 -0
- synkit/Graph/Canon/_native/search.py +137 -0
- synkit/Graph/Canon/canon_algs.py +228 -0
- synkit/Graph/Canon/canon_graph.py +531 -0
- synkit/Graph/Canon/cpp/CMakeLists.txt +42 -0
- synkit/Graph/Canon/cpp/README.md +123 -0
- synkit/Graph/Canon/cpp/examples/canonical_graph.cpp +16 -0
- synkit/Graph/Canon/cpp/include/synkit_canon/canon.h +85 -0
- synkit/Graph/Canon/cpp/src/canonical.cpp +391 -0
- synkit/Graph/Canon/cpp/src/symmetry.h +83 -0
- synkit/Graph/Canon/cpp/tests/symmetry.cpp +93 -0
- synkit/Graph/Canon/exact.py +1020 -0
- synkit/Graph/Canon/exact_refinement.py +368 -0
- synkit/Graph/Canon/nauty.py +143 -0
- synkit/Graph/Context/__init__.py +0 -0
- synkit/Graph/Context/hier_context.py +244 -0
- synkit/Graph/Context/radius_expand.py +252 -0
- synkit/Graph/FG/__init__.py +19 -0
- synkit/Graph/FG/api.py +39 -0
- synkit/Graph/FG/audit.py +155 -0
- synkit/Graph/FG/catalog.py +919 -0
- synkit/Graph/FG/detector.py +288 -0
- synkit/Graph/FG/model.py +97 -0
- synkit/Graph/FG/recognizers.py +274 -0
- synkit/Graph/FG/ring_system.py +154 -0
- synkit/Graph/Feature/Descriptors/topology.py +857 -0
- synkit/Graph/Feature/Fingerprint/__init__.py +0 -0
- synkit/Graph/Feature/Fingerprint/wl_rxn_fps.py +222 -0
- synkit/Graph/Feature/__init__.py +5 -0
- synkit/Graph/Feature/graph_descriptors.py +323 -0
- synkit/Graph/Feature/graph_fps.py +96 -0
- synkit/Graph/Feature/graph_signature.py +239 -0
- synkit/Graph/Feature/hash_fps.py +133 -0
- synkit/Graph/Feature/morgan_fps.py +88 -0
- synkit/Graph/Feature/path_fps.py +81 -0
- synkit/Graph/Feature/wl_hash.py +134 -0
- synkit/Graph/Fusion/__init__.py +85 -0
- synkit/Graph/Fusion/candidate.py +559 -0
- synkit/Graph/Fusion/constructor.py +877 -0
- synkit/Graph/Fusion/identity.py +184 -0
- synkit/Graph/Fusion/interface.py +700 -0
- synkit/Graph/Fusion/search.py +241 -0
- synkit/Graph/Hyrogen/__init__.py +6 -0
- synkit/Graph/Hyrogen/_misc.py +591 -0
- synkit/Graph/Hyrogen/hcomplete.py +995 -0
- synkit/Graph/Hyrogen/hcomplete_legacy.py +368 -0
- synkit/Graph/Hyrogen/hcompletion_algorithms.py +713 -0
- synkit/Graph/Hyrogen/hextend.py +570 -0
- synkit/Graph/Hyrogen/hextend_legacy.py +215 -0
- synkit/Graph/ITS/__init__.py +4 -0
- synkit/Graph/ITS/its_builder.py +120 -0
- synkit/Graph/ITS/its_construction.py +719 -0
- synkit/Graph/ITS/its_decompose.py +572 -0
- synkit/Graph/ITS/its_destruction.py +331 -0
- synkit/Graph/ITS/its_expand.py +1251 -0
- synkit/Graph/ITS/its_relabel.py +187 -0
- synkit/Graph/ITS/its_reverter.py +356 -0
- synkit/Graph/ITS/normalize_aam.py +145 -0
- synkit/Graph/ITS/partial_its.py +238 -0
- synkit/Graph/ITS/rc_extractor.py +656 -0
- synkit/Graph/ITS/stereo.py +74 -0
- synkit/Graph/MTG/__init__.py +107 -0
- synkit/Graph/MTG/gluing.py +451 -0
- synkit/Graph/MTG/history.py +928 -0
- synkit/Graph/MTG/inventory.py +118 -0
- synkit/Graph/MTG/local.py +447 -0
- synkit/Graph/MTG/mcs_matcher.py +246 -0
- synkit/Graph/MTG/mtg.py +611 -0
- synkit/Graph/MTG/mtg_explore.py +74 -0
- synkit/Graph/MTG/observation.py +209 -0
- synkit/Graph/MTG/process.py +577 -0
- synkit/Graph/MTG/queries.py +66 -0
- synkit/Graph/MTG/realization.py +95 -0
- synkit/Graph/MTG/series_parallel.py +107 -0
- synkit/Graph/MTG/utils.py +424 -0
- synkit/Graph/Matcher/__init__.py +10 -0
- synkit/Graph/Matcher/approx_mcs.py +1264 -0
- synkit/Graph/Matcher/auto_est.py +736 -0
- synkit/Graph/Matcher/automorphism.py +314 -0
- synkit/Graph/Matcher/batch_cluster.py +224 -0
- synkit/Graph/Matcher/dedup_matches.py +247 -0
- synkit/Graph/Matcher/graph_cluster.py +191 -0
- synkit/Graph/Matcher/graph_matcher.py +312 -0
- synkit/Graph/Matcher/graph_morphism.py +421 -0
- synkit/Graph/Matcher/mcs_matcher.py +804 -0
- synkit/Graph/Matcher/multi_turbo_iso.py +186 -0
- synkit/Graph/Matcher/orbit.py +284 -0
- synkit/Graph/Matcher/partial_matcher.py +694 -0
- synkit/Graph/Matcher/sing.py +544 -0
- synkit/Graph/Matcher/subgraph_matcher.py +812 -0
- synkit/Graph/Matcher/turbo_iso.py +272 -0
- synkit/Graph/Matcher/wl_sel.py +537 -0
- synkit/Graph/Mech/__init__.py +26 -0
- synkit/Graph/Mech/conversion.py +1466 -0
- synkit/Graph/Mech/conversion_debug.py +237 -0
- synkit/Graph/Mech/electron_accounting.py +200 -0
- synkit/Graph/Mech/lwg_editor.py +406 -0
- synkit/Graph/Mech/lwg_ops.py +313 -0
- synkit/Graph/Morphism/__init__.py +99 -0
- synkit/Graph/Morphism/constraints.py +460 -0
- synkit/Graph/Morphism/llg.py +999 -0
- synkit/Graph/Morphism/morphism.py +349 -0
- synkit/Graph/Morphism/stereo.py +258 -0
- synkit/Graph/Morphism/stereo_morphism.py +383 -0
- synkit/Graph/Morphism/stereo_morphism_helpers.py +957 -0
- synkit/Graph/Morphism/stereo_morphism_types.py +117 -0
- synkit/Graph/Stereo/__init__.py +376 -0
- synkit/Graph/Stereo/_descriptor_core.py +207 -0
- synkit/Graph/Stereo/_descriptor_serialization.py +138 -0
- synkit/Graph/Stereo/canonical.py +648 -0
- synkit/Graph/Stereo/changes.py +964 -0
- synkit/Graph/Stereo/composition.py +391 -0
- synkit/Graph/Stereo/configured.py +946 -0
- synkit/Graph/Stereo/couplings.py +245 -0
- synkit/Graph/Stereo/descriptors.py +1030 -0
- synkit/Graph/Stereo/enumeration.py +597 -0
- synkit/Graph/Stereo/extended_descriptors.py +406 -0
- synkit/Graph/Stereo/global_configured.py +152 -0
- synkit/Graph/Stereo/global_stereo.py +304 -0
- synkit/Graph/Stereo/identity.py +648 -0
- synkit/Graph/Stereo/interchange.py +496 -0
- synkit/Graph/Stereo/legacy.py +460 -0
- synkit/Graph/Stereo/matching.py +899 -0
- synkit/Graph/Stereo/native.py +154 -0
- synkit/Graph/Stereo/orbits.py +668 -0
- synkit/Graph/Stereo/outcomes.py +99 -0
- synkit/Graph/Stereo/pairwise.py +350 -0
- synkit/Graph/Stereo/rdkit_adapter.py +662 -0
- synkit/Graph/Stereo/rdkit_identity.py +118 -0
- synkit/Graph/Stereo/rdkit_resonance.py +140 -0
- synkit/Graph/Stereo/reaction_interchange.py +266 -0
- synkit/Graph/Stereo/semantics.py +296 -0
- synkit/Graph/Stereo/supports.py +257 -0
- synkit/Graph/Stereo/wire.py +339 -0
- synkit/Graph/Wildcard/__init__.py +0 -0
- synkit/Graph/Wildcard/fuse_graph.py +156 -0
- synkit/Graph/Wildcard/graph_wc.py +303 -0
- synkit/Graph/Wildcard/its_merge.py +857 -0
- synkit/Graph/Wildcard/radwc.py +114 -0
- synkit/Graph/Wildcard/wc_matcher.py +576 -0
- synkit/Graph/Wildcard/wildcard.py +225 -0
- synkit/Graph/__init__.py +17 -0
- synkit/Graph/canon_graph.py +14 -0
- synkit/Graph/syn_graph.py +199 -0
- synkit/Graph/utils.py +324 -0
- synkit/IO/__init__.py +4 -0
- synkit/IO/chem_converter.py +1059 -0
- synkit/IO/combinatorial/__init__.py +8 -0
- synkit/IO/combinatorial/gml_to_graph.py +223 -0
- synkit/IO/combinatorial/graph_to_gml.py +280 -0
- synkit/IO/combinatorial/graph_to_smarts.py +186 -0
- synkit/IO/combinatorial/smarts_expander.py +147 -0
- synkit/IO/combinatorial/smarts_generalizer.py +133 -0
- synkit/IO/combinatorial/smarts_to_graph.py +179 -0
- synkit/IO/conversion.py +42 -0
- synkit/IO/data_io.py +269 -0
- synkit/IO/data_process.py +143 -0
- synkit/IO/debug.py +73 -0
- synkit/IO/gml_to_nx.py +150 -0
- synkit/IO/graph_to_mol.py +199 -0
- synkit/IO/mol_to_graph.py +1105 -0
- synkit/IO/mol_to_graph_chemistry.py +545 -0
- synkit/IO/nx_to_gml.py +209 -0
- synkit/IO/smiles_to_id.py +123 -0
- synkit/Mechanism/__init__.py +151 -0
- synkit/Mechanism/adapters.py +136 -0
- synkit/Mechanism/audit.py +323 -0
- synkit/Mechanism/benchmark.py +638 -0
- synkit/Mechanism/compatibility.py +13 -0
- synkit/Mechanism/drawing.py +85 -0
- synkit/Mechanism/electron_models.py +725 -0
- synkit/Mechanism/equivalence.py +521 -0
- synkit/Mechanism/evidence.py +262 -0
- synkit/Mechanism/interchange.py +141 -0
- synkit/Mechanism/model.py +918 -0
- synkit/Mechanism/neighbor_stereo.py +312 -0
- synkit/Mechanism/radical_data.py +740 -0
- synkit/Mechanism/replay.py +986 -0
- synkit/Mechanism/schema.py +264 -0
- synkit/Mechanism/stereo_state.py +416 -0
- synkit/Mechanism/symbols.py +91 -0
- synkit/Rule/Apply/__init__.py +35 -0
- synkit/Rule/Apply/conditions.py +45 -0
- synkit/Rule/Apply/dpo.py +998 -0
- synkit/Rule/Apply/rule_matcher.py +218 -0
- synkit/Rule/Apply/validation.py +354 -0
- synkit/Rule/Compose/__init__.py +106 -0
- synkit/Rule/Compose/_identity.py +43 -0
- synkit/Rule/Compose/composition.py +976 -0
- synkit/Rule/Compose/laws.py +439 -0
- synkit/Rule/Compose/search.py +771 -0
- synkit/Rule/Compose/synrule.py +170 -0
- synkit/Rule/Modify/__init__.py +0 -0
- synkit/Rule/Modify/implict_rule.py +56 -0
- synkit/Rule/Modify/longest_path.py +92 -0
- synkit/Rule/Modify/molecule_rule.py +115 -0
- synkit/Rule/Modify/prune_templates.py +78 -0
- synkit/Rule/Modify/rule_utils.py +194 -0
- synkit/Rule/Modify/strip_rule.py +97 -0
- synkit/Rule/__init__.py +28 -0
- synkit/Rule/generic_stereo.py +884 -0
- synkit/Rule/stereo_identity.py +271 -0
- synkit/Rule/syn_rule.py +1090 -0
- synkit/Synthesis/MSR/__init__.py +0 -0
- synkit/Synthesis/MSR/path_finder.py +239 -0
- synkit/Synthesis/Metrics/__init__.py +0 -0
- synkit/Synthesis/Metrics/_base.py +52 -0
- synkit/Synthesis/Metrics/_plot.py +129 -0
- synkit/Synthesis/Metrics/_ranking.py +179 -0
- synkit/Synthesis/RBL/__init__.py +80 -0
- synkit/Synthesis/RBL/engine.py +1249 -0
- synkit/Synthesis/RBL/matching.py +652 -0
- synkit/Synthesis/RBL/overlap.py +336 -0
- synkit/Synthesis/RBL/pipeline.py +376 -0
- synkit/Synthesis/RBL/policy.py +139 -0
- synkit/Synthesis/RBL/proof.py +370 -0
- synkit/Synthesis/RBL/reaction.py +506 -0
- synkit/Synthesis/RBL/state.py +169 -0
- synkit/Synthesis/RBL/validation.py +1060 -0
- synkit/Synthesis/Reactor/__init__.py +60 -0
- synkit/Synthesis/Reactor/core/__init__.py +1 -0
- synkit/Synthesis/Reactor/core/engine.py +967 -0
- synkit/Synthesis/Reactor/core/product.py +621 -0
- synkit/Synthesis/Reactor/core/rewrite.py +561 -0
- synkit/Synthesis/Reactor/core/strategy.py +44 -0
- synkit/Synthesis/Reactor/matching/__init__.py +1 -0
- synkit/Synthesis/Reactor/matching/mixin.py +920 -0
- synkit/Synthesis/Reactor/matching/policy.py +345 -0
- synkit/Synthesis/Reactor/matching/symmetry.py +309 -0
- synkit/Synthesis/Reactor/output/__init__.py +1 -0
- synkit/Synthesis/Reactor/output/deduplication.py +703 -0
- synkit/Synthesis/Reactor/output/policy.py +16 -0
- synkit/Synthesis/Reactor/output/serialization.py +485 -0
- synkit/Synthesis/Reactor/output/structural.py +893 -0
- synkit/Synthesis/Reactor/stereo/__init__.py +1 -0
- synkit/Synthesis/Reactor/stereo/assignment.py +35 -0
- synkit/Synthesis/Reactor/stereo/mixin.py +780 -0
- synkit/Synthesis/Reactor/variants/__init__.py +1 -0
- synkit/Synthesis/Reactor/variants/imbalanced.py +180 -0
- synkit/Synthesis/Reactor/variants/partial.py +84 -0
- synkit/Synthesis/Reactor/workflow/__init__.py +1 -0
- synkit/Synthesis/Reactor/workflow/batch.py +550 -0
- synkit/Synthesis/Reactor/workflow/benchmark.py +143 -0
- synkit/Synthesis/Reactor/workflow/postprocess.py +267 -0
- synkit/Synthesis/Reactor/workflow/rule_filter.py +210 -0
- synkit/Synthesis/__init__.py +0 -0
- synkit/Synthesis/reactor_utils.py +316 -0
- synkit/Utils/__init__.py +0 -0
- synkit/Utils/utils.py +172 -0
- synkit/Vis/__init__.py +91 -0
- synkit/Vis/crn/__init__.py +40 -0
- synkit/Vis/epd/__init__.py +20 -0
- synkit/Vis/epd/arrows.py +425 -0
- synkit/Vis/epd/chem.py +197 -0
- synkit/Vis/epd/constants.py +83 -0
- synkit/Vis/epd/layout.py +283 -0
- synkit/Vis/epd/mapping.py +51 -0
- synkit/Vis/epd/models.py +136 -0
- synkit/Vis/epd/render.py +543 -0
- synkit/Vis/epd/utils.py +108 -0
- synkit/Vis/epd/visualizer.py +811 -0
- synkit/Vis/graph_visualizer.py +375 -0
- synkit/Vis/its/__init__.py +19 -0
- synkit/Vis/its/drawer.py +615 -0
- synkit/Vis/its_drawer.py +35 -0
- synkit/Vis/molecule/__init__.py +31 -0
- synkit/Vis/molecule/drawer.py +563 -0
- synkit/Vis/molecule/reaction.py +285 -0
- synkit/Vis/molecule_drawer.py +33 -0
- synkit/Vis/mtg/__init__.py +17 -0
- synkit/Vis/mtg/drawer.py +769 -0
- synkit/Vis/mtg_drawer.py +34 -0
- synkit/Vis/pdf_writer.py +146 -0
- synkit/Vis/reaction/__init__.py +19 -0
- synkit/Vis/reaction/rule.py +141 -0
- synkit/Vis/reaction/rxn.py +532 -0
- synkit/Vis/reaction_drawer.py +41 -0
- synkit/Vis/space/__init__.py +17 -0
- synkit/Vis/space/chemical.py +80 -0
- synkit/Vis/space/embedding.py +87 -0
- synkit/Vis/vis_synedu/Vis/__init__.py +7 -0
- synkit/Vis/vis_synedu/Vis/dpo.py +862 -0
- synkit/Vis/vis_synedu/rxn_vis.py +377 -0
- synkit/Vis/vis_synedu/vis.py +501 -0
- synkit/Vis/visual_drawer.py +215 -0
- synkit/Vis/visual_model.py +520 -0
- synkit/__init__.py +3 -0
- synkit/_native.py +91 -0
- synkit/examples.py +50 -0
- synkit/version.py +23 -0
- synkit-1.6.5.dist-info/METADATA +156 -0
- synkit-1.6.5.dist-info/RECORD +636 -0
- synkit-1.6.5.dist-info/WHEEL +4 -0
- synkit-1.6.5.dist-info/licenses/LICENSE +21 -0
- synkit-1.6.5.dist-info/licenses/synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/COPYRIGHT +44 -0
- synkit-1.6.5.dist-info/licenses/synkit/Chem/Mapper/solvers/native/cpp/src/symmetry/vendor/nauty/LICENSE-2.0.txt +202 -0
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from typing import Any, List, Set, Optional
|
|
5
|
+
|
|
6
|
+
import numpy as np
|
|
7
|
+
from .siphon_search import SiphonSearchLimit, DEFAULT_MAX_NODES
|
|
8
|
+
from .semiflows import find_p_semiflows, stoichiometric_matrix
|
|
9
|
+
from .structure import find_siphons
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass(frozen=True)
|
|
13
|
+
class PersistenceCheckResult:
|
|
14
|
+
"""Structured result of the siphon-based persistence sufficient test."""
|
|
15
|
+
|
|
16
|
+
persistence_ok: Optional[bool]
|
|
17
|
+
siphons: List[Set[str]]
|
|
18
|
+
semiflow_supports: List[Set[str]]
|
|
19
|
+
uncovered_siphons: List[Set[str]]
|
|
20
|
+
complete: bool = True
|
|
21
|
+
termination_reason: str = "complete"
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def siphon_persistence_condition(
|
|
25
|
+
crn: Any,
|
|
26
|
+
*,
|
|
27
|
+
rtol: float = 1e-12,
|
|
28
|
+
max_siphon_size: int | None = None,
|
|
29
|
+
) -> Optional[bool]:
|
|
30
|
+
"""
|
|
31
|
+
Check the Angeli–De Leenheer–Sontag siphon/P-semiflow sufficient condition.
|
|
32
|
+
|
|
33
|
+
The condition holds when every minimal siphon contains the support of some
|
|
34
|
+
P-semiflow.
|
|
35
|
+
"""
|
|
36
|
+
return siphon_persistence_details(
|
|
37
|
+
crn,
|
|
38
|
+
rtol=rtol,
|
|
39
|
+
max_siphon_size=max_siphon_size,
|
|
40
|
+
).persistence_ok
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
def siphon_persistence_details(
|
|
44
|
+
crn: Any,
|
|
45
|
+
*,
|
|
46
|
+
rtol: float = 1e-12,
|
|
47
|
+
max_siphon_size: int | None = None,
|
|
48
|
+
support_tol: float = 1e-8,
|
|
49
|
+
max_nodes: int = DEFAULT_MAX_NODES,
|
|
50
|
+
p_semiflows: Any = None,
|
|
51
|
+
_complete_siphons: Any = None,
|
|
52
|
+
) -> PersistenceCheckResult:
|
|
53
|
+
"""
|
|
54
|
+
Return detailed information for the siphon-based persistence test.
|
|
55
|
+
"""
|
|
56
|
+
try:
|
|
57
|
+
# Enumerate all sizes: a size filter is not a proof of complete coverage.
|
|
58
|
+
siphons = (
|
|
59
|
+
find_siphons(crn, names="id", max_nodes=max_nodes, strict_limit=True)
|
|
60
|
+
if _complete_siphons is None
|
|
61
|
+
else [set(s) for s in _complete_siphons]
|
|
62
|
+
)
|
|
63
|
+
except SiphonSearchLimit:
|
|
64
|
+
return PersistenceCheckResult(None, [], [], [], False, "node_limit")
|
|
65
|
+
if max_siphon_size is not None and any(len(s) > max_siphon_size for s in siphons):
|
|
66
|
+
return PersistenceCheckResult(None, siphons, [], [], False, "size_limit")
|
|
67
|
+
if not siphons:
|
|
68
|
+
return PersistenceCheckResult(True, [], [], [])
|
|
69
|
+
|
|
70
|
+
species_order, _, _ = stoichiometric_matrix(crn)
|
|
71
|
+
# Minimal P-semiflows: non-negative and inclusion-minimal, so their
|
|
72
|
+
# supports are exactly what the Angeli-De Leenheer-Sontag condition needs.
|
|
73
|
+
# A real kernel basis would not do: its vectors can be mixed-sign and its
|
|
74
|
+
# supports depend on the arbitrary choice of basis.
|
|
75
|
+
y = (
|
|
76
|
+
find_p_semiflows(crn, rtol=rtol)
|
|
77
|
+
if p_semiflows is None
|
|
78
|
+
else np.asarray(p_semiflows)
|
|
79
|
+
)
|
|
80
|
+
if y.size == 0:
|
|
81
|
+
return PersistenceCheckResult(False, siphons, [], list(siphons))
|
|
82
|
+
|
|
83
|
+
supports: List[Set[str]] = []
|
|
84
|
+
for j in range(y.shape[1]):
|
|
85
|
+
supp = {
|
|
86
|
+
species_order[i] for i, val in enumerate(y[:, j]) if abs(val) > support_tol
|
|
87
|
+
}
|
|
88
|
+
if supp:
|
|
89
|
+
supports.append(supp)
|
|
90
|
+
|
|
91
|
+
uncovered = [set(s) for s in siphons if not any(t.issubset(s) for t in supports)]
|
|
92
|
+
return PersistenceCheckResult(
|
|
93
|
+
persistence_ok=(len(uncovered) == 0),
|
|
94
|
+
siphons=[set(s) for s in siphons],
|
|
95
|
+
semiflow_supports=supports,
|
|
96
|
+
uncovered_siphons=uncovered,
|
|
97
|
+
)
|
|
@@ -0,0 +1,483 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from typing import Any, Dict, List, Tuple
|
|
4
|
+
|
|
5
|
+
import numpy as np
|
|
6
|
+
|
|
7
|
+
from .net import PetriNet
|
|
8
|
+
from .minimal_semiflows import minimal_semiflows
|
|
9
|
+
from synkit.CRN.Props.helper import _as_graph, _species_and_rule_order
|
|
10
|
+
from synkit.CRN.Props.stoich import (
|
|
11
|
+
left_nullspace,
|
|
12
|
+
right_nullspace,
|
|
13
|
+
stoichiometric_matrix as props_stoichiometric_matrix,
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
__all__ = [
|
|
17
|
+
"stoichiometric_matrix",
|
|
18
|
+
"find_p_semiflows",
|
|
19
|
+
"find_t_semiflows",
|
|
20
|
+
"left_kernel_basis",
|
|
21
|
+
"right_kernel_basis",
|
|
22
|
+
"semiflow_supports",
|
|
23
|
+
]
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def _nullspace(a: np.ndarray, *, rtol: float = 1e-12) -> np.ndarray:
|
|
27
|
+
"""Compute a numerical basis for the right null space of a matrix using SVD.
|
|
28
|
+
|
|
29
|
+
The returned matrix has shape ``(n_cols, k)``, where each column is a basis
|
|
30
|
+
vector spanning ``ker(a)``. This helper is used only for native
|
|
31
|
+
:class:`PetriNet` inputs, because the generic SynCRN-like path delegates to
|
|
32
|
+
:mod:`synkit.CRN.Props.stoich`.
|
|
33
|
+
|
|
34
|
+
:param a:
|
|
35
|
+
Input matrix.
|
|
36
|
+
:type a: np.ndarray
|
|
37
|
+
:param rtol:
|
|
38
|
+
Relative tolerance used to determine the numerical rank.
|
|
39
|
+
:type rtol: float
|
|
40
|
+
:return:
|
|
41
|
+
Matrix whose columns form a basis of the right null space of ``a``.
|
|
42
|
+
:rtype: np.ndarray
|
|
43
|
+
:raises ValueError:
|
|
44
|
+
If ``a`` is not two-dimensional.
|
|
45
|
+
|
|
46
|
+
.. rubric:: Example
|
|
47
|
+
|
|
48
|
+
.. code-block:: python
|
|
49
|
+
|
|
50
|
+
import numpy as np
|
|
51
|
+
from synkit.CRN.Petrinet.semiflows import _nullspace
|
|
52
|
+
|
|
53
|
+
a = np.array([[1.0, -1.0], [2.0, -2.0]])
|
|
54
|
+
ns = _nullspace(a)
|
|
55
|
+
print(ns.shape)
|
|
56
|
+
"""
|
|
57
|
+
from ..Props.stoich import _null_space
|
|
58
|
+
|
|
59
|
+
return _null_space(np.asarray(a, dtype=float), rtol=rtol)
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
def _stoich_from_petri(net: PetriNet) -> Tuple[List[str], List[str], np.ndarray]:
|
|
63
|
+
"""Build a stoichiometric matrix directly from a :class:`PetriNet`.
|
|
64
|
+
|
|
65
|
+
Rows follow :attr:`PetriNet.place_order` and columns follow
|
|
66
|
+
:attr:`PetriNet.transition_order`. Each column corresponds to one
|
|
67
|
+
transition, with reactant coefficients subtracted and product coefficients
|
|
68
|
+
added.
|
|
69
|
+
|
|
70
|
+
:param net:
|
|
71
|
+
Petri net object.
|
|
72
|
+
:type net: PetriNet
|
|
73
|
+
:return:
|
|
74
|
+
Tuple ``(species_order, reaction_order, S)``, where ``S`` is the net
|
|
75
|
+
stoichiometric matrix.
|
|
76
|
+
:rtype: Tuple[List[str], List[str], np.ndarray]
|
|
77
|
+
|
|
78
|
+
.. rubric:: Example
|
|
79
|
+
|
|
80
|
+
.. code-block:: python
|
|
81
|
+
|
|
82
|
+
from synkit.CRN.Petrinet.net import PetriNet
|
|
83
|
+
from synkit.CRN.Petrinet.semiflows import _stoich_from_petri
|
|
84
|
+
|
|
85
|
+
net = PetriNet()
|
|
86
|
+
net.add_transition("r1", pre={"A": 1}, post={"B": 1})
|
|
87
|
+
|
|
88
|
+
species_order, reaction_order, S = _stoich_from_petri(net)
|
|
89
|
+
print(species_order)
|
|
90
|
+
print(reaction_order)
|
|
91
|
+
print(S)
|
|
92
|
+
"""
|
|
93
|
+
species_order = list(net.place_order)
|
|
94
|
+
reaction_order = list(net.transition_order)
|
|
95
|
+
|
|
96
|
+
sidx = {sid: i for i, sid in enumerate(species_order)}
|
|
97
|
+
ridx = {rid: j for j, rid in enumerate(reaction_order)}
|
|
98
|
+
s = np.zeros((len(species_order), len(reaction_order)), dtype=float)
|
|
99
|
+
|
|
100
|
+
for rid in reaction_order:
|
|
101
|
+
t = net.transitions[rid]
|
|
102
|
+
j = ridx[rid]
|
|
103
|
+
for sid, coeff in t.pre.items():
|
|
104
|
+
s[sidx[sid], j] -= float(coeff)
|
|
105
|
+
for sid, coeff in t.post.items():
|
|
106
|
+
s[sidx[sid], j] += float(coeff)
|
|
107
|
+
|
|
108
|
+
return species_order, reaction_order, s
|
|
109
|
+
|
|
110
|
+
|
|
111
|
+
def stoichiometric_matrix(crn: Any) -> Tuple[List[str], List[str], np.ndarray]:
|
|
112
|
+
"""Return row order, column order, and stoichiometric matrix for a network.
|
|
113
|
+
|
|
114
|
+
This is a thin wrapper around :mod:`synkit.CRN.Props.stoich` for
|
|
115
|
+
SynCRN-like graph inputs, augmented with explicit row and column orders so
|
|
116
|
+
semiflow supports can be interpreted. For native :class:`PetriNet` inputs,
|
|
117
|
+
the matrix is assembled directly from the transition multisets.
|
|
118
|
+
|
|
119
|
+
Supported inputs include:
|
|
120
|
+
|
|
121
|
+
- a :class:`PetriNet`
|
|
122
|
+
- a SynCRN-like object accepted by :func:`synkit.CRN.Props.helper._as_graph`
|
|
123
|
+
- a NetworkX bipartite graph in SynCRN species-rule format
|
|
124
|
+
|
|
125
|
+
:param crn:
|
|
126
|
+
Petri net, SynCRN-like object, or supported bipartite graph.
|
|
127
|
+
:type crn: Any
|
|
128
|
+
:return:
|
|
129
|
+
Tuple ``(species_order, reaction_order, S)``, where ``species_order``
|
|
130
|
+
defines the row labels of ``S`` and ``reaction_order`` defines the
|
|
131
|
+
column labels.
|
|
132
|
+
:rtype: Tuple[List[str], List[str], np.ndarray]
|
|
133
|
+
|
|
134
|
+
.. rubric:: Example
|
|
135
|
+
|
|
136
|
+
.. code-block:: python
|
|
137
|
+
|
|
138
|
+
from synkit.CRN.Structure import SynCRN
|
|
139
|
+
from synkit.CRN.Petrinet.semiflows import stoichiometric_matrix
|
|
140
|
+
|
|
141
|
+
syn = SynCRN.from_reaction_strings(["A>>B", "B>>A"])
|
|
142
|
+
species_order, reaction_order, S = stoichiometric_matrix(syn)
|
|
143
|
+
|
|
144
|
+
print(species_order)
|
|
145
|
+
print(reaction_order)
|
|
146
|
+
print(S.shape)
|
|
147
|
+
"""
|
|
148
|
+
if isinstance(crn, PetriNet):
|
|
149
|
+
return _stoich_from_petri(crn)
|
|
150
|
+
|
|
151
|
+
G = _as_graph(crn)
|
|
152
|
+
species_order, reaction_order, _, _ = _species_and_rule_order(G)
|
|
153
|
+
S = props_stoichiometric_matrix(crn)
|
|
154
|
+
# Matrix rows follow source graph order, but Petri-net supports use canonical
|
|
155
|
+
# ids. Preserve row order while normalizing the names into one coordinate system.
|
|
156
|
+
return (
|
|
157
|
+
[str(G.nodes[x].get("syncrn_id", x)) for x in species_order],
|
|
158
|
+
[str(G.nodes[x].get("syncrn_id", x)) for x in reaction_order],
|
|
159
|
+
S,
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def left_kernel_basis(crn: Any, *, rtol: float = 1e-12) -> np.ndarray:
|
|
164
|
+
"""Compute a real basis of the left kernel ``ker(S^T)``.
|
|
165
|
+
|
|
166
|
+
The returned matrix has shape ``(n_species, k)``, where each column is one
|
|
167
|
+
basis vector.
|
|
168
|
+
|
|
169
|
+
.. warning::
|
|
170
|
+
These basis vectors are **not** P-semiflows. They may be negative or
|
|
171
|
+
mixed-sign, and because any rotation of the kernel is an equally valid
|
|
172
|
+
basis, their supports are not meaningful. Use
|
|
173
|
+
:func:`find_p_semiflows` for conservation-law analysis.
|
|
174
|
+
|
|
175
|
+
:param crn:
|
|
176
|
+
Petri net, SynCRN-like object, or supported bipartite graph.
|
|
177
|
+
:type crn: Any
|
|
178
|
+
:param rtol:
|
|
179
|
+
Relative tolerance used for null-space detection.
|
|
180
|
+
:type rtol: float
|
|
181
|
+
:return:
|
|
182
|
+
Matrix whose columns form a basis of ``ker(S^T)``.
|
|
183
|
+
:rtype: np.ndarray
|
|
184
|
+
|
|
185
|
+
.. rubric:: Example
|
|
186
|
+
|
|
187
|
+
.. code-block:: python
|
|
188
|
+
|
|
189
|
+
from synkit.CRN.Structure import SynCRN
|
|
190
|
+
from synkit.CRN.Petrinet.semiflows import left_kernel_basis
|
|
191
|
+
|
|
192
|
+
syn = SynCRN.from_reaction_strings(["A>>B", "B>>A"])
|
|
193
|
+
print(left_kernel_basis(syn).shape)
|
|
194
|
+
"""
|
|
195
|
+
if isinstance(crn, PetriNet):
|
|
196
|
+
_, _, s = stoichiometric_matrix(crn)
|
|
197
|
+
return _nullspace(s.T, rtol=rtol)
|
|
198
|
+
|
|
199
|
+
return left_nullspace(crn, rtol=rtol)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
def right_kernel_basis(crn: Any, *, rtol: float = 1e-12) -> np.ndarray:
|
|
203
|
+
"""Compute a real basis of the right kernel ``ker(S)``.
|
|
204
|
+
|
|
205
|
+
The returned matrix has shape ``(n_reactions, k)``, where each column is
|
|
206
|
+
one basis vector.
|
|
207
|
+
|
|
208
|
+
.. warning::
|
|
209
|
+
These basis vectors are **not** T-semiflows; see
|
|
210
|
+
:func:`left_kernel_basis`. Use :func:`find_t_semiflows` for flux-mode
|
|
211
|
+
analysis.
|
|
212
|
+
|
|
213
|
+
:param crn:
|
|
214
|
+
Petri net, SynCRN-like object, or supported bipartite graph.
|
|
215
|
+
:type crn: Any
|
|
216
|
+
:param rtol:
|
|
217
|
+
Relative tolerance used for null-space detection.
|
|
218
|
+
:type rtol: float
|
|
219
|
+
:return:
|
|
220
|
+
Matrix whose columns form a basis of ``ker(S)``.
|
|
221
|
+
:rtype: np.ndarray
|
|
222
|
+
|
|
223
|
+
.. rubric:: Example
|
|
224
|
+
|
|
225
|
+
.. code-block:: python
|
|
226
|
+
|
|
227
|
+
from synkit.CRN.Structure import SynCRN
|
|
228
|
+
from synkit.CRN.Petrinet.semiflows import right_kernel_basis
|
|
229
|
+
|
|
230
|
+
syn = SynCRN.from_reaction_strings(["A>>B", "B>>A"])
|
|
231
|
+
print(right_kernel_basis(syn).shape)
|
|
232
|
+
"""
|
|
233
|
+
if isinstance(crn, PetriNet):
|
|
234
|
+
_, _, s = stoichiometric_matrix(crn)
|
|
235
|
+
return _nullspace(s, rtol=rtol)
|
|
236
|
+
|
|
237
|
+
return right_nullspace(crn, rtol=rtol)
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
def _semiflow_matrix(crn: Any, *, kind: str, **backend_options) -> np.ndarray:
|
|
241
|
+
"""Build the minimal-semiflow matrix for a CRN-like input.
|
|
242
|
+
|
|
243
|
+
:param crn:
|
|
244
|
+
Petri net, SynCRN-like object, or supported bipartite graph.
|
|
245
|
+
:type crn: Any
|
|
246
|
+
:param kind:
|
|
247
|
+
Either ``"p"`` or ``"t"``.
|
|
248
|
+
:type kind: str
|
|
249
|
+
:return:
|
|
250
|
+
Non-negative integer matrix whose columns are minimal semiflows.
|
|
251
|
+
:rtype: np.ndarray
|
|
252
|
+
"""
|
|
253
|
+
_, _, s = stoichiometric_matrix(crn)
|
|
254
|
+
flows = minimal_semiflows(s, kind=kind, **backend_options)
|
|
255
|
+
|
|
256
|
+
width = s.shape[0] if kind == "p" else s.shape[1]
|
|
257
|
+
if not flows:
|
|
258
|
+
return np.zeros((width, 0), dtype=float)
|
|
259
|
+
dtype = object if any(abs(v) > 2**53 for row in flows for v in row) else float
|
|
260
|
+
return np.asarray(flows, dtype=dtype).T
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def find_p_semiflows(crn: Any, *, rtol: float = 1e-12, **backend_options) -> np.ndarray:
|
|
264
|
+
"""Compute minimal P-semiflows, also called place invariants.
|
|
265
|
+
|
|
266
|
+
A P-semiflow is a vector ``y >= 0`` with ``y^T S = 0``; its support is a
|
|
267
|
+
set of species whose weighted total is conserved by every reaction. The
|
|
268
|
+
returned matrix has shape ``(n_species, k)``, where each column is one
|
|
269
|
+
minimal semiflow with primitive non-negative integer entries.
|
|
270
|
+
|
|
271
|
+
Computation is exact and uses the Farkas / Colom-Silva elimination scheme
|
|
272
|
+
(see :mod:`synkit.CRN.Petrinet.minimal_semiflows`), so results do not
|
|
273
|
+
depend on a floating-point tolerance.
|
|
274
|
+
|
|
275
|
+
:param crn:
|
|
276
|
+
Petri net, SynCRN-like object, or supported bipartite graph.
|
|
277
|
+
:type crn: Any
|
|
278
|
+
:param rtol:
|
|
279
|
+
Accepted for backward compatibility and ignored; the computation is
|
|
280
|
+
exact.
|
|
281
|
+
:type rtol: float
|
|
282
|
+
:return:
|
|
283
|
+
Matrix whose columns are the minimal P-semiflows.
|
|
284
|
+
:rtype: np.ndarray
|
|
285
|
+
|
|
286
|
+
.. rubric:: Example
|
|
287
|
+
|
|
288
|
+
.. code-block:: python
|
|
289
|
+
|
|
290
|
+
from synkit.CRN.Structure import SynCRN
|
|
291
|
+
from synkit.CRN.Petrinet.semiflows import find_p_semiflows
|
|
292
|
+
|
|
293
|
+
syn = SynCRN.from_reaction_strings(["A>>B", "C>>D"])
|
|
294
|
+
print(find_p_semiflows(syn))
|
|
295
|
+
# [[1. 0.]
|
|
296
|
+
# [1. 0.]
|
|
297
|
+
# [0. 1.]
|
|
298
|
+
# [0. 1.]]
|
|
299
|
+
"""
|
|
300
|
+
return _semiflow_matrix(crn, kind="p", **backend_options)
|
|
301
|
+
|
|
302
|
+
|
|
303
|
+
def find_t_semiflows(crn: Any, *, rtol: float = 1e-12, **backend_options) -> np.ndarray:
|
|
304
|
+
"""Compute minimal T-semiflows, also called transition invariants.
|
|
305
|
+
|
|
306
|
+
A T-semiflow is a vector ``x >= 0`` with ``S x = 0``; its support is a set
|
|
307
|
+
of reactions that, fired with the given multiplicities, returns the network
|
|
308
|
+
to its starting marking. The returned matrix has shape
|
|
309
|
+
``(n_reactions, k)``, where each column is one minimal semiflow with
|
|
310
|
+
primitive non-negative integer entries.
|
|
311
|
+
|
|
312
|
+
Computation is exact; see :func:`find_p_semiflows`.
|
|
313
|
+
|
|
314
|
+
:param crn:
|
|
315
|
+
Petri net, SynCRN-like object, or supported bipartite graph.
|
|
316
|
+
:type crn: Any
|
|
317
|
+
:param rtol:
|
|
318
|
+
Accepted for backward compatibility and ignored; the computation is
|
|
319
|
+
exact.
|
|
320
|
+
:type rtol: float
|
|
321
|
+
:return:
|
|
322
|
+
Matrix whose columns are the minimal T-semiflows.
|
|
323
|
+
:rtype: np.ndarray
|
|
324
|
+
|
|
325
|
+
.. rubric:: Example
|
|
326
|
+
|
|
327
|
+
.. code-block:: python
|
|
328
|
+
|
|
329
|
+
from synkit.CRN.Structure import SynCRN
|
|
330
|
+
from synkit.CRN.Petrinet.semiflows import find_t_semiflows
|
|
331
|
+
|
|
332
|
+
syn = SynCRN.from_reaction_strings(["A>>B", "B>>A"])
|
|
333
|
+
print(find_t_semiflows(syn))
|
|
334
|
+
# [[1.]
|
|
335
|
+
# [1.]]
|
|
336
|
+
"""
|
|
337
|
+
return _semiflow_matrix(crn, kind="t", **backend_options)
|
|
338
|
+
|
|
339
|
+
|
|
340
|
+
def _select_semiflow_basis(
|
|
341
|
+
crn: Any,
|
|
342
|
+
*,
|
|
343
|
+
kind: str,
|
|
344
|
+
rtol: float,
|
|
345
|
+
) -> Tuple[List[str], np.ndarray]:
|
|
346
|
+
"""Select the minimal semiflows together with their label order.
|
|
347
|
+
|
|
348
|
+
For P-semiflows, the returned order corresponds to species / places. For
|
|
349
|
+
T-semiflows, the returned order corresponds to reactions / transitions.
|
|
350
|
+
|
|
351
|
+
:param crn:
|
|
352
|
+
Petri net, SynCRN-like object, or supported bipartite graph.
|
|
353
|
+
:type crn: Any
|
|
354
|
+
:param kind:
|
|
355
|
+
Either ``"p"`` for P-semiflows or ``"t"`` for T-semiflows.
|
|
356
|
+
:type kind: str
|
|
357
|
+
:param rtol:
|
|
358
|
+
Accepted for backward compatibility and ignored; the computation is
|
|
359
|
+
exact.
|
|
360
|
+
:type rtol: float
|
|
361
|
+
:return:
|
|
362
|
+
Tuple ``(order, basis)``, where ``order`` labels the rows of ``basis``.
|
|
363
|
+
:rtype: Tuple[List[str], np.ndarray]
|
|
364
|
+
:raises ValueError:
|
|
365
|
+
If ``kind`` is not ``"p"`` or ``"t"``.
|
|
366
|
+
|
|
367
|
+
.. rubric:: Example
|
|
368
|
+
|
|
369
|
+
.. code-block:: python
|
|
370
|
+
|
|
371
|
+
from synkit.CRN.Structure import SynCRN
|
|
372
|
+
from synkit.CRN.Petrinet.semiflows import _select_semiflow_basis
|
|
373
|
+
|
|
374
|
+
syn = SynCRN.from_reaction_strings(["A>>B", "B>>A"])
|
|
375
|
+
order, basis = _select_semiflow_basis(syn, kind="p", rtol=1e-12)
|
|
376
|
+
print(order)
|
|
377
|
+
print(basis.shape)
|
|
378
|
+
"""
|
|
379
|
+
if kind not in {"p", "t"}:
|
|
380
|
+
raise ValueError("kind must be 'p' or 't'")
|
|
381
|
+
|
|
382
|
+
species_order, reaction_order, _ = stoichiometric_matrix(crn)
|
|
383
|
+
order = species_order if kind == "p" else reaction_order
|
|
384
|
+
return order, _semiflow_matrix(crn, kind=kind)
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
def _basis_column_support(
|
|
388
|
+
vec: np.ndarray,
|
|
389
|
+
order: List[str],
|
|
390
|
+
*,
|
|
391
|
+
support_tol: float,
|
|
392
|
+
) -> Dict[str, float]:
|
|
393
|
+
"""Convert one basis vector into a sparsified support dictionary.
|
|
394
|
+
|
|
395
|
+
Entries whose absolute value is less than or equal to ``support_tol`` are
|
|
396
|
+
discarded. Remaining entries are returned as a mapping from row label to
|
|
397
|
+
floating coefficient.
|
|
398
|
+
|
|
399
|
+
:param vec:
|
|
400
|
+
Basis vector.
|
|
401
|
+
:type vec: np.ndarray
|
|
402
|
+
:param order:
|
|
403
|
+
Labels corresponding to entries of ``vec``.
|
|
404
|
+
:type order: List[str]
|
|
405
|
+
:param support_tol:
|
|
406
|
+
Threshold below which coefficients are treated as zero.
|
|
407
|
+
:type support_tol: float
|
|
408
|
+
:return:
|
|
409
|
+
Sparse support mapping for one basis column.
|
|
410
|
+
:rtype: Dict[str, float]
|
|
411
|
+
|
|
412
|
+
.. rubric:: Example
|
|
413
|
+
|
|
414
|
+
.. code-block:: python
|
|
415
|
+
|
|
416
|
+
import numpy as np
|
|
417
|
+
from synkit.CRN.Petrinet.semiflows import _basis_column_support
|
|
418
|
+
|
|
419
|
+
vec = np.array([1.0, 0.0, -2.0])
|
|
420
|
+
order = ["A", "B", "C"]
|
|
421
|
+
supp = _basis_column_support(vec, order, support_tol=1e-8)
|
|
422
|
+
print(supp)
|
|
423
|
+
"""
|
|
424
|
+
return {
|
|
425
|
+
order[i]: float(vec[i]) for i in range(len(order)) if abs(vec[i]) > support_tol
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
|
|
429
|
+
def semiflow_supports(
|
|
430
|
+
crn: Any,
|
|
431
|
+
*,
|
|
432
|
+
kind: str = "p",
|
|
433
|
+
rtol: float = 1e-12,
|
|
434
|
+
support_tol: float = 1e-8,
|
|
435
|
+
) -> List[Dict[str, float]]:
|
|
436
|
+
"""Return sparsified P-semiflow or T-semiflow supports.
|
|
437
|
+
|
|
438
|
+
The result is a list of sparse dictionaries, one per basis column. For
|
|
439
|
+
P-semiflows, keys are species or place identifiers. For T-semiflows, keys
|
|
440
|
+
are reaction or transition identifiers.
|
|
441
|
+
|
|
442
|
+
:param crn:
|
|
443
|
+
Petri net, SynCRN-like object, or supported bipartite graph.
|
|
444
|
+
:type crn: Any
|
|
445
|
+
:param kind:
|
|
446
|
+
Either ``"p"`` for P-semiflows or ``"t"`` for T-semiflows.
|
|
447
|
+
:type kind: str
|
|
448
|
+
:param rtol:
|
|
449
|
+
Relative tolerance used for null-space detection.
|
|
450
|
+
:type rtol: float
|
|
451
|
+
:param support_tol:
|
|
452
|
+
Threshold below which basis coefficients are treated as zero when
|
|
453
|
+
constructing sparse supports.
|
|
454
|
+
:type support_tol: float
|
|
455
|
+
:return:
|
|
456
|
+
List of sparse support dictionaries.
|
|
457
|
+
:rtype: List[Dict[str, float]]
|
|
458
|
+
:raises ValueError:
|
|
459
|
+
If ``kind`` is not ``"p"`` or ``"t"``.
|
|
460
|
+
|
|
461
|
+
.. rubric:: Example
|
|
462
|
+
|
|
463
|
+
.. code-block:: python
|
|
464
|
+
|
|
465
|
+
from synkit.CRN.Structure import SynCRN
|
|
466
|
+
from synkit.CRN.Petrinet.semiflows import semiflow_supports
|
|
467
|
+
|
|
468
|
+
syn = SynCRN.from_reaction_strings(["A>>B", "B>>A"])
|
|
469
|
+
|
|
470
|
+
p_supports = semiflow_supports(syn, kind="p")
|
|
471
|
+
t_supports = semiflow_supports(syn, kind="t")
|
|
472
|
+
|
|
473
|
+
print(p_supports)
|
|
474
|
+
print(t_supports)
|
|
475
|
+
"""
|
|
476
|
+
order, basis = _select_semiflow_basis(crn, kind=kind, rtol=rtol)
|
|
477
|
+
|
|
478
|
+
out: List[Dict[str, float]] = []
|
|
479
|
+
for j in range(basis.shape[1]):
|
|
480
|
+
supp = _basis_column_support(basis[:, j], order, support_tol=support_tol)
|
|
481
|
+
if supp:
|
|
482
|
+
out.append(supp)
|
|
483
|
+
return out
|