sofic 0.1.0__py3-none-any.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.
- sofic/__init__.py +185 -0
- sofic/automata/__init__.py +207 -0
- sofic/automata/_config_simulation.py +40 -0
- sofic/automata/active.py +611 -0
- sofic/automata/alergia.py +222 -0
- sofic/automata/algorithms.py +376 -0
- sofic/automata/atomaton.py +58 -0
- sofic/automata/base.py +161 -0
- sofic/automata/buchi.py +23 -0
- sofic/automata/buchi_simulation.py +67 -0
- sofic/automata/canonical_dual.py +18 -0
- sofic/automata/canonical_extraction.py +122 -0
- sofic/automata/dfa.py +85 -0
- sofic/automata/dfasat.py +195 -0
- sofic/automata/edsm.py +219 -0
- sofic/automata/enumeration.py +44 -0
- sofic/automata/icdfa.py +421 -0
- sofic/automata/idfa.py +363 -0
- sofic/automata/languages/__init__.py +39 -0
- sofic/automata/languages/_quotient_utils.py +64 -0
- sofic/automata/languages/atoms.py +31 -0
- sofic/automata/languages/automaton_ops.py +243 -0
- sofic/automata/languages/base.py +67 -0
- sofic/automata/languages/operations.py +78 -0
- sofic/automata/languages/quotients.py +66 -0
- sofic/automata/languages/residuals.py +25 -0
- sofic/automata/learning.py +79 -0
- sofic/automata/nfa.py +39 -0
- sofic/automata/nwa.py +343 -0
- sofic/automata/nwa_simulation.py +56 -0
- sofic/automata/observation.py +40 -0
- sofic/automata/papni.py +301 -0
- sofic/automata/regex.py +128 -0
- sofic/automata/rfsa.py +35 -0
- sofic/automata/rpni.py +193 -0
- sofic/automata/subsequential.py +201 -0
- sofic/automata/transducer_operations.py +350 -0
- sofic/automata/transducer_simulation.py +150 -0
- sofic/automata/transducers.py +365 -0
- sofic/automata/unifilar.py +107 -0
- sofic/automata/vpa.py +1373 -0
- sofic/automata/vpa_simulation.py +53 -0
- sofic/base.py +153 -0
- sofic/core.py +47 -0
- sofic/examples/__init__.py +86 -0
- sofic/examples/epsilon_machines.py +1089 -0
- sofic/examples/processes.py +1491 -0
- sofic/examples/shifts.py +144 -0
- sofic/exceptions.py +33 -0
- sofic/generators/__init__.py +115 -0
- sofic/generators/_word_measures.py +94 -0
- sofic/generators/alternative_complexity.py +104 -0
- sofic/generators/base.py +327 -0
- sofic/generators/bidirectional_construction.py +717 -0
- sofic/generators/bidirectional_epsilon_machine.py +689 -0
- sofic/generators/block_convergence.py +668 -0
- sofic/generators/block_entropy.py +578 -0
- sofic/generators/channel_measures.py +75 -0
- sofic/generators/conversions.py +182 -0
- sofic/generators/directional_flow.py +245 -0
- sofic/generators/edge_emissions.py +36 -0
- sofic/generators/edge_machine.py +178 -0
- sofic/generators/epsilon_construction.py +193 -0
- sofic/generators/epsilon_inference.py +703 -0
- sofic/generators/epsilon_machine.py +557 -0
- sofic/generators/epsilon_transducer.py +168 -0
- sofic/generators/epsilon_transducer_construction.py +185 -0
- sofic/generators/epsilon_transducer_inference.py +499 -0
- sofic/generators/hmm_inference.py +719 -0
- sofic/generators/information_diagram.py +428 -0
- sofic/generators/lumping.py +447 -0
- sofic/generators/markov.py +100 -0
- sofic/generators/mealy.py +156 -0
- sofic/generators/measures.py +257 -0
- sofic/generators/minimal_generative_model.py +821 -0
- sofic/generators/mixed_state.py +250 -0
- sofic/generators/mixed_state_construction.py +163 -0
- sofic/generators/moore.py +75 -0
- sofic/generators/nmachine.py +78 -0
- sofic/generators/nmachine_construction.py +70 -0
- sofic/generators/pfa.py +100 -0
- sofic/generators/prob.py +291 -0
- sofic/generators/process_equivalence.py +207 -0
- sofic/generators/quasi_inference.py +74 -0
- sofic/generators/quasi_realization.py +97 -0
- sofic/generators/reversal.py +66 -0
- sofic/generators/stack_hmm.py +426 -0
- sofic/generators/stack_inference.py +509 -0
- sofic/generators/stationary.py +134 -0
- sofic/generators/stochastic.py +65 -0
- sofic/generators/synchronization.py +407 -0
- sofic/generators/topological_epsilon_enumeration.py +349 -0
- sofic/generators/words.py +226 -0
- sofic/graph.py +135 -0
- sofic/indexing.py +31 -0
- sofic/inference/__init__.py +45 -0
- sofic/inference/bayesian/__init__.py +68 -0
- sofic/inference/bayesian/comparison.py +199 -0
- sofic/inference/bayesian/counts.py +219 -0
- sofic/inference/bayesian/diversity.py +254 -0
- sofic/inference/bayesian/epsilon.py +270 -0
- sofic/inference/bayesian/hdp_hmm.py +340 -0
- sofic/inference/bayesian/markov.py +294 -0
- sofic/inference/bayesian/pymc_backend.py +71 -0
- sofic/inference/bayesian/stack_hmm.py +215 -0
- sofic/inference/model_selection.py +365 -0
- sofic/inference/spectral.py +564 -0
- sofic/operations.py +16 -0
- sofic/properties.py +339 -0
- sofic/serialization.py +450 -0
- sofic/shifts/__init__.py +48 -0
- sofic/shifts/algorithms.py +84 -0
- sofic/shifts/base.py +49 -0
- sofic/shifts/cover_construction.py +76 -0
- sofic/shifts/covers.py +47 -0
- sofic/shifts/dyck_algorithms.py +100 -0
- sofic/shifts/dyck_enumeration.py +275 -0
- sofic/shifts/markov_dyck.py +172 -0
- sofic/shifts/parry_construction.py +82 -0
- sofic/shifts/sft.py +104 -0
- sofic/shifts/sft_construction.py +52 -0
- sofic/shifts/sliding_block_code.py +156 -0
- sofic/shifts/sofic.py +111 -0
- sofic/shifts/sofic_dyck.py +110 -0
- sofic/shifts/sofic_relation.py +64 -0
- sofic/shifts/textile.py +104 -0
- sofic/shifts/tmc.py +46 -0
- sofic/shifts/tmc_construction.py +58 -0
- sofic/shifts/topological_anatomy.py +150 -0
- sofic/states.py +27 -0
- sofic/testing/__init__.py +8 -0
- sofic/testing/strategies.py +154 -0
- sofic/viz/__init__.py +16 -0
- sofic/viz/_context.py +345 -0
- sofic/viz/_edge.py +216 -0
- sofic/viz/_format.py +89 -0
- sofic/viz/_labels.py +34 -0
- sofic/viz/_names.py +17 -0
- sofic/viz/_rational.py +20 -0
- sofic/viz/_tikz_compile.py +177 -0
- sofic/viz/_tikz_format.py +122 -0
- sofic/viz/_tikz_layout.py +218 -0
- sofic/viz/assets/vaucanson.tikz +71 -0
- sofic/viz/graphviz.py +158 -0
- sofic/viz/idiagram.py +350 -0
- sofic/viz/tikz.py +381 -0
- sofic-0.1.0.dist-info/METADATA +444 -0
- sofic-0.1.0.dist-info/RECORD +150 -0
- sofic-0.1.0.dist-info/WHEEL +4 -0
- sofic-0.1.0.dist-info/licenses/LICENSE.txt +29 -0
|
@@ -0,0 +1,444 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: sofic
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python package for hidden Markov models, symbolic dynamics, finite state machines, and stochastic symbol generators.
|
|
5
|
+
Project-URL: Homepage, https://github.com/dit/sofic
|
|
6
|
+
Project-URL: Repository, https://github.com/dit/sofic
|
|
7
|
+
Project-URL: Documentation, https://sofic.readthedocs.io
|
|
8
|
+
Author-email: chebee7i <admin@dit.io>, "Ryan G. James" <dit@autoplectic.com>
|
|
9
|
+
License-Expression: BSD-3-Clause
|
|
10
|
+
License-File: LICENSE.txt
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
17
|
+
Classifier: Topic :: Scientific/Engineering
|
|
18
|
+
Classifier: Topic :: Scientific/Engineering :: Mathematics
|
|
19
|
+
Classifier: Topic :: Scientific/Engineering :: Physics
|
|
20
|
+
Requires-Python: >=3.11
|
|
21
|
+
Requires-Dist: dit>=2.2
|
|
22
|
+
Requires-Dist: networkx>=2.6
|
|
23
|
+
Requires-Dist: numpy>=1.22
|
|
24
|
+
Requires-Dist: pyyaml>=6.0
|
|
25
|
+
Requires-Dist: scipy>=1.7
|
|
26
|
+
Provides-Extra: bayes
|
|
27
|
+
Requires-Dist: arviz; extra == 'bayes'
|
|
28
|
+
Requires-Dist: pymc>=5; extra == 'bayes'
|
|
29
|
+
Provides-Extra: dev
|
|
30
|
+
Requires-Dist: dit[symbolic]>=2.2; extra == 'dev'
|
|
31
|
+
Requires-Dist: graphviz>=0.20; extra == 'dev'
|
|
32
|
+
Requires-Dist: hypothesis>=6.0; extra == 'dev'
|
|
33
|
+
Requires-Dist: hypothesis[numpy]; extra == 'dev'
|
|
34
|
+
Requires-Dist: ipython; extra == 'dev'
|
|
35
|
+
Requires-Dist: matplotlib; extra == 'dev'
|
|
36
|
+
Requires-Dist: matplotlib>=3.5; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest-cov; extra == 'dev'
|
|
38
|
+
Requires-Dist: pytest-rerunfailures; extra == 'dev'
|
|
39
|
+
Requires-Dist: pytest-sugar; extra == 'dev'
|
|
40
|
+
Requires-Dist: pytest-xdist; extra == 'dev'
|
|
41
|
+
Requires-Dist: pytest>=9.0.3; extra == 'dev'
|
|
42
|
+
Requires-Dist: ruff; extra == 'dev'
|
|
43
|
+
Requires-Dist: sphinx; extra == 'dev'
|
|
44
|
+
Requires-Dist: sphinx-rtd-theme; extra == 'dev'
|
|
45
|
+
Requires-Dist: sphinxcontrib-bibtex; extra == 'dev'
|
|
46
|
+
Requires-Dist: sympy>=1.12; extra == 'dev'
|
|
47
|
+
Requires-Dist: ty; extra == 'dev'
|
|
48
|
+
Provides-Extra: docs
|
|
49
|
+
Requires-Dist: dit[symbolic]>=2.2; extra == 'docs'
|
|
50
|
+
Requires-Dist: ipython; extra == 'docs'
|
|
51
|
+
Requires-Dist: matplotlib; extra == 'docs'
|
|
52
|
+
Requires-Dist: sphinx; extra == 'docs'
|
|
53
|
+
Requires-Dist: sphinx-rtd-theme; extra == 'docs'
|
|
54
|
+
Requires-Dist: sphinxcontrib-bibtex; extra == 'docs'
|
|
55
|
+
Requires-Dist: sympy>=1.12; extra == 'docs'
|
|
56
|
+
Provides-Extra: sat
|
|
57
|
+
Requires-Dist: python-sat>=1.8; extra == 'sat'
|
|
58
|
+
Provides-Extra: symbolic
|
|
59
|
+
Requires-Dist: dit[symbolic]>=2.2; extra == 'symbolic'
|
|
60
|
+
Requires-Dist: sympy>=1.12; extra == 'symbolic'
|
|
61
|
+
Provides-Extra: test
|
|
62
|
+
Requires-Dist: graphviz>=0.20; extra == 'test'
|
|
63
|
+
Requires-Dist: hypothesis>=6.0; extra == 'test'
|
|
64
|
+
Requires-Dist: hypothesis[numpy]; extra == 'test'
|
|
65
|
+
Requires-Dist: pytest-cov; extra == 'test'
|
|
66
|
+
Requires-Dist: pytest-rerunfailures; extra == 'test'
|
|
67
|
+
Requires-Dist: pytest-sugar; extra == 'test'
|
|
68
|
+
Requires-Dist: pytest-xdist; extra == 'test'
|
|
69
|
+
Requires-Dist: pytest>=9.0.3; extra == 'test'
|
|
70
|
+
Provides-Extra: viz
|
|
71
|
+
Requires-Dist: graphviz>=0.20; extra == 'viz'
|
|
72
|
+
Requires-Dist: matplotlib>=3.5; extra == 'viz'
|
|
73
|
+
Description-Content-Type: text/x-rst
|
|
74
|
+
|
|
75
|
+
=======
|
|
76
|
+
sofic
|
|
77
|
+
=======
|
|
78
|
+
|
|
79
|
+
``sofic`` is a Python package for hidden Markov models, symbolic dynamics,
|
|
80
|
+
finite state machines, and other stochastic symbol generators.
|
|
81
|
+
|
|
82
|
+
Basic Information
|
|
83
|
+
-----------------
|
|
84
|
+
|
|
85
|
+
Documentation
|
|
86
|
+
~~~~~~~~~~~~~~
|
|
87
|
+
|
|
88
|
+
https://sofic.readthedocs.io
|
|
89
|
+
|
|
90
|
+
Repository
|
|
91
|
+
~~~~~~~~~~
|
|
92
|
+
|
|
93
|
+
https://github.com/dit/sofic
|
|
94
|
+
|
|
95
|
+
Dependencies
|
|
96
|
+
~~~~~~~~~~~~
|
|
97
|
+
|
|
98
|
+
* Python 3.11+
|
|
99
|
+
* `networkx <https://networkx.github.io/>`_
|
|
100
|
+
* `numpy <http://www.numpy.org/>`_
|
|
101
|
+
* `scipy <https://www.scipy.org/>`_
|
|
102
|
+
* `pyyaml <https://pyyaml.org/>`_
|
|
103
|
+
* `dit <https://github.com/dit/dit>`_ (information-theoretic measures)
|
|
104
|
+
|
|
105
|
+
Development
|
|
106
|
+
~~~~~~~~~~~
|
|
107
|
+
|
|
108
|
+
Clone the repository and install development dependencies with ``uv``:
|
|
109
|
+
|
|
110
|
+
.. code-block:: bash
|
|
111
|
+
|
|
112
|
+
git clone https://github.com/dit/sofic.git
|
|
113
|
+
cd sofic
|
|
114
|
+
uv sync --extra dev
|
|
115
|
+
|
|
116
|
+
Run tests with ``uv run pytest``. See the ``generalinfo`` page in the Sphinx
|
|
117
|
+
docs for linting, type checking, and documentation builds.
|
|
118
|
+
|
|
119
|
+
Introduction
|
|
120
|
+
------------
|
|
121
|
+
|
|
122
|
+
Many natural and engineered processes produce sequences of symbols whose
|
|
123
|
+
statistics are governed by latent structure: hidden states, transition rules,
|
|
124
|
+
or algebraic constraints on allowed paths. ``sofic`` collects algorithms and
|
|
125
|
+
data structures for representing, simulating, and analyzing such generators
|
|
126
|
+
behind a single, composable Python API.
|
|
127
|
+
|
|
128
|
+
Every model is a graph-backed state machine, so the same objects support
|
|
129
|
+
construction, validation, simulation, visualization, (de)serialization, and a
|
|
130
|
+
large library of structural and information-theoretic measures. The three
|
|
131
|
+
main families are:
|
|
132
|
+
|
|
133
|
+
* **Stochastic generators** (``sofic.generators``) — Markov chains, hidden
|
|
134
|
+
Markov models (Moore and Mealy presentations), ε-machines, probabilistic
|
|
135
|
+
finite automata, mixed-state presentations, and quasiprobabilistic
|
|
136
|
+
generators. These assign probabilities to sequences.
|
|
137
|
+
* **Finite automata** (``sofic.automata``) — DFAs, NFAs, transducers
|
|
138
|
+
(Mealy/Moore machines), regular languages, Büchi automata, visibly pushdown
|
|
139
|
+
and nested-word automata, and residual finite-state automata. These recognize
|
|
140
|
+
or transform languages.
|
|
141
|
+
* **Symbolic shifts** (``sofic.shifts``) — shifts of finite type, sofic
|
|
142
|
+
shifts, topological Markov chains, and Dyck/sofic-Dyck shifts. These describe
|
|
143
|
+
the *support* (set of allowed sequences) of a process.
|
|
144
|
+
|
|
145
|
+
The package builds on NumPy, SciPy, and NetworkX and is designed to sit
|
|
146
|
+
alongside the `dit <https://github.com/dit/dit>`_ ecosystem for
|
|
147
|
+
information-theoretic analysis of the processes these models describe.
|
|
148
|
+
|
|
149
|
+
Installation
|
|
150
|
+
------------
|
|
151
|
+
|
|
152
|
+
.. code-block:: bash
|
|
153
|
+
|
|
154
|
+
pip install sofic
|
|
155
|
+
|
|
156
|
+
Optional extras:
|
|
157
|
+
|
|
158
|
+
* ``sofic[viz]`` — Graphviz diagrams in terminals and Jupyter
|
|
159
|
+
* ``sofic[bayes]`` — PyMC/ArviZ backends for Bayesian inference
|
|
160
|
+
* ``sofic[test]`` — pytest, hypothesis, and graphviz for the test suite
|
|
161
|
+
* ``sofic[docs]`` — Sphinx, IPython, and matplotlib for the docs
|
|
162
|
+
* ``sofic[dev]`` — linting, type checking, docs, and all of the above
|
|
163
|
+
|
|
164
|
+
Quickstart
|
|
165
|
+
----------
|
|
166
|
+
|
|
167
|
+
The basic workflow is the same for every model: build (or load) a generator,
|
|
168
|
+
call ``validate()``, then compute properties or convert to another
|
|
169
|
+
presentation. States can be any hashable object and every model exposes
|
|
170
|
+
``states()``, ``transitions()``, ``draw()``, and ``to_yaml()``.
|
|
171
|
+
|
|
172
|
+
Stochastic generators
|
|
173
|
+
~~~~~~~~~~~~~~~~~~~~~~~
|
|
174
|
+
|
|
175
|
+
**Markov chain** — a visible-state process. Edges carry ``P(target | source)``:
|
|
176
|
+
|
|
177
|
+
.. code-block:: python
|
|
178
|
+
|
|
179
|
+
from sofic import MarkovChain
|
|
180
|
+
|
|
181
|
+
mc = MarkovChain(initial_distribution={"sunny": 0.5, "rainy": 0.5})
|
|
182
|
+
mc.add_transition("sunny", "sunny", 0.9)
|
|
183
|
+
mc.add_transition("sunny", "rainy", 0.1)
|
|
184
|
+
mc.add_transition("rainy", "sunny", 0.5)
|
|
185
|
+
mc.add_transition("rainy", "rainy", 0.5)
|
|
186
|
+
mc.validate()
|
|
187
|
+
|
|
188
|
+
mc.stationary_distribution() # array([0.8333, 0.1667])
|
|
189
|
+
mc.entropy_rate() # 0.5575 bits/symbol
|
|
190
|
+
mc.is_deterministic() # False
|
|
191
|
+
|
|
192
|
+
**Moore HMM** — hidden states with an emission law ``P(observation | state)`` on
|
|
193
|
+
states and ``P(target | source)`` on edges:
|
|
194
|
+
|
|
195
|
+
.. code-block:: python
|
|
196
|
+
|
|
197
|
+
from sofic import MooreHMM
|
|
198
|
+
|
|
199
|
+
moore = MooreHMM(
|
|
200
|
+
observation_alphabet=frozenset({"H", "T"}),
|
|
201
|
+
initial_distribution={0: 0.5, 1: 0.5},
|
|
202
|
+
)
|
|
203
|
+
moore.add_transition(0, 0, 0.5)
|
|
204
|
+
moore.add_transition(0, 1, 0.5)
|
|
205
|
+
moore.add_transition(1, 0, 0.5)
|
|
206
|
+
moore.add_transition(1, 1, 0.5)
|
|
207
|
+
moore.set_emission_distribution(0, {"H": 0.9, "T": 0.1})
|
|
208
|
+
moore.set_emission_distribution(1, {"H": 0.1, "T": 0.9})
|
|
209
|
+
moore.validate()
|
|
210
|
+
|
|
211
|
+
moore.stationary_distribution() # array([0.5, 0.5])
|
|
212
|
+
moore.log_likelihood(["H", "H", "T", "T"]) # -2.7726 (log2)
|
|
213
|
+
observations, hidden = moore.sample(6) # simulate the process
|
|
214
|
+
|
|
215
|
+
**Mealy HMM** — hidden states with a joint transition/emission law
|
|
216
|
+
``P(target, symbol | source)`` on edges. Here is the golden-mean process
|
|
217
|
+
(consecutive ``1``\ s are forbidden):
|
|
218
|
+
|
|
219
|
+
.. code-block:: python
|
|
220
|
+
|
|
221
|
+
from sofic import MealyHMM
|
|
222
|
+
|
|
223
|
+
gm = MealyHMM(
|
|
224
|
+
observation_alphabet=frozenset({0, 1}),
|
|
225
|
+
initial_distribution={"A": 2 / 3, "B": 1 / 3},
|
|
226
|
+
)
|
|
227
|
+
gm.add_transition("A", "A", 0, 0.5) # source, target, symbol, probability
|
|
228
|
+
gm.add_transition("A", "B", 1, 0.5)
|
|
229
|
+
gm.add_transition("B", "A", 0, 1.0)
|
|
230
|
+
gm.validate()
|
|
231
|
+
|
|
232
|
+
gm.entropy_rate() # 0.6667 bits/symbol
|
|
233
|
+
gm.is_unifilar() # True
|
|
234
|
+
gm.word_probability([1, 0, 1]) # 0.1667
|
|
235
|
+
|
|
236
|
+
Many canonical models ship in ``sofic.examples``, so the golden mean is
|
|
237
|
+
also just ``from sofic.examples import golden_mean; gm = golden_mean(0.5)``.
|
|
238
|
+
|
|
239
|
+
**ε-machine** — the minimal unifilar (causal-state) presentation of a stationary
|
|
240
|
+
process. Build one from any HMM, from an observed sequence, or directly, and
|
|
241
|
+
read off computational-mechanics quantities:
|
|
242
|
+
|
|
243
|
+
.. code-block:: python
|
|
244
|
+
|
|
245
|
+
from sofic import EpsilonMachine
|
|
246
|
+
|
|
247
|
+
eps = EpsilonMachine.from_hmm(gm) # minimize an HMM presentation
|
|
248
|
+
# eps = EpsilonMachine.from_sequence(data, method="cssr", Lmax=4) # infer
|
|
249
|
+
# eps = EpsilonMachine.from_sequence(data, method="spectral", prefix_length=3, rank=2)
|
|
250
|
+
|
|
251
|
+
eps.statistical_complexity() # 0.9183 bits (C_mu)
|
|
252
|
+
eps.entropy_rate() # 0.6667 bits/symbol (h_mu)
|
|
253
|
+
eps.markov_order() # 1
|
|
254
|
+
eps.cryptic_order() # 1
|
|
255
|
+
|
|
256
|
+
Finite automata
|
|
257
|
+
~~~~~~~~~~~~~~~
|
|
258
|
+
|
|
259
|
+
**DFA** — a deterministic recognizer. This one accepts strings with an even
|
|
260
|
+
number of ``b``\ s (states are added before their transitions so determinism can
|
|
261
|
+
be checked as you go):
|
|
262
|
+
|
|
263
|
+
.. code-block:: python
|
|
264
|
+
|
|
265
|
+
from sofic import DFA
|
|
266
|
+
|
|
267
|
+
dfa = DFA(
|
|
268
|
+
input_alphabet=frozenset({"a", "b"}),
|
|
269
|
+
initial_states=frozenset({"even"}),
|
|
270
|
+
accepting_states=frozenset({"even"}),
|
|
271
|
+
)
|
|
272
|
+
dfa.graph.add_state("even")
|
|
273
|
+
dfa.graph.add_state("odd")
|
|
274
|
+
dfa.add_transition("even", "even", "a")
|
|
275
|
+
dfa.add_transition("even", "odd", "b")
|
|
276
|
+
dfa.add_transition("odd", "odd", "a")
|
|
277
|
+
dfa.add_transition("odd", "even", "b")
|
|
278
|
+
dfa.validate()
|
|
279
|
+
|
|
280
|
+
dfa.recognizes("abba") # True (two b's)
|
|
281
|
+
dfa.recognizes("abbb") # False (three b's)
|
|
282
|
+
dfa.minimize() # DFA(2 states, 4 transitions)
|
|
283
|
+
dfa.to_regex() # 'a*|a*b(?:...)*ba*'
|
|
284
|
+
|
|
285
|
+
**NFA** — nondeterministic, with first-class ε-transitions. Determinize to a DFA
|
|
286
|
+
when you need one:
|
|
287
|
+
|
|
288
|
+
.. code-block:: python
|
|
289
|
+
|
|
290
|
+
from sofic import NFA
|
|
291
|
+
|
|
292
|
+
nfa = NFA(
|
|
293
|
+
input_alphabet=frozenset({"a", "b"}),
|
|
294
|
+
initial_states=frozenset({"q0"}),
|
|
295
|
+
accepting_states=frozenset({"q2"}),
|
|
296
|
+
)
|
|
297
|
+
nfa.add_transition("q0", "q0", "a")
|
|
298
|
+
nfa.add_transition("q0", "q0", "b")
|
|
299
|
+
nfa.add_transition("q0", "q1", "a")
|
|
300
|
+
nfa.add_transition("q1", "q2", "b")
|
|
301
|
+
nfa.validate()
|
|
302
|
+
|
|
303
|
+
nfa.recognizes("ab") # True
|
|
304
|
+
dfa = nfa.determinize()
|
|
305
|
+
|
|
306
|
+
**Transducer (Mealy machine)** — maps input words to output words. This one
|
|
307
|
+
inverts bits:
|
|
308
|
+
|
|
309
|
+
.. code-block:: python
|
|
310
|
+
|
|
311
|
+
from sofic import MealyMachine
|
|
312
|
+
|
|
313
|
+
inv = MealyMachine(
|
|
314
|
+
input_alphabet=frozenset({"0", "1"}),
|
|
315
|
+
output_alphabet=frozenset({"0", "1"}),
|
|
316
|
+
initial_states=frozenset({"q"}),
|
|
317
|
+
)
|
|
318
|
+
inv.add_transition("q", "q", "0", "1") # source, target, input, output
|
|
319
|
+
inv.add_transition("q", "q", "1", "0")
|
|
320
|
+
inv.validate()
|
|
321
|
+
|
|
322
|
+
inv.transduce("0110") # {('1', '0', '0', '1')}
|
|
323
|
+
|
|
324
|
+
All automata also support ``union``, ``intersection``, ``complement``,
|
|
325
|
+
``difference``, ``concat``, and ``kleene_star`` (see the
|
|
326
|
+
``LabeledAutomaton`` base class).
|
|
327
|
+
|
|
328
|
+
Symbolic shifts
|
|
329
|
+
~~~~~~~~~~~~~~~
|
|
330
|
+
|
|
331
|
+
**Shift of finite type** — the set of sequences avoiding a finite list of
|
|
332
|
+
forbidden words. The golden-mean shift forbids ``11``:
|
|
333
|
+
|
|
334
|
+
.. code-block:: python
|
|
335
|
+
|
|
336
|
+
from sofic import ShiftOfFiniteType
|
|
337
|
+
|
|
338
|
+
sft = ShiftOfFiniteType.from_forbidden_words(
|
|
339
|
+
{("1", "1")},
|
|
340
|
+
symbol_alphabet=frozenset({"0", "1"}),
|
|
341
|
+
)
|
|
342
|
+
sft.validate()
|
|
343
|
+
|
|
344
|
+
sft.forbidden_words() # frozenset({('1', '1')})
|
|
345
|
+
sorted(sft.factor_language(3)) # allowed length-3 words
|
|
346
|
+
sft.is_unifilar() # True (right-resolving presentation)
|
|
347
|
+
|
|
348
|
+
**Topological Markov chain** — an adjacency-matrix presentation; compute the
|
|
349
|
+
topological entropy or extract the measure of maximal entropy:
|
|
350
|
+
|
|
351
|
+
.. code-block:: python
|
|
352
|
+
|
|
353
|
+
import numpy as np
|
|
354
|
+
from sofic import TopologicalMarkovChain
|
|
355
|
+
|
|
356
|
+
tmc = TopologicalMarkovChain.from_adjacency(
|
|
357
|
+
np.array([[1, 1], [1, 0]], dtype=float), # golden-mean adjacency
|
|
358
|
+
symbol_alphabet=frozenset({0, 1}),
|
|
359
|
+
)
|
|
360
|
+
tmc.validate()
|
|
361
|
+
|
|
362
|
+
tmc.topological_entropy() # 0.4812 (ln of the golden ratio)
|
|
363
|
+
tmc.parry_measure() # MealyHMM at maximal entropy
|
|
364
|
+
|
|
365
|
+
**Sofic shift** — a labeled-graph presentation (the shift-space analog of an
|
|
366
|
+
NFA). This is the even shift (even-length runs of ``0`` between ``1``\ s):
|
|
367
|
+
|
|
368
|
+
.. code-block:: python
|
|
369
|
+
|
|
370
|
+
from sofic import SoficShift
|
|
371
|
+
|
|
372
|
+
even = SoficShift(symbol_alphabet=frozenset({0, 1}))
|
|
373
|
+
even.add_transition("even", "even", 0)
|
|
374
|
+
even.add_transition("even", "odd", 1)
|
|
375
|
+
even.add_transition("odd", "even", 1)
|
|
376
|
+
even.validate()
|
|
377
|
+
|
|
378
|
+
even.topological_entropy() # 0.4812
|
|
379
|
+
|
|
380
|
+
Converting between model types
|
|
381
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
382
|
+
|
|
383
|
+
The presentations are related by a web of conversions. Probabilistic models can
|
|
384
|
+
drop their weights to become automata or shifts (keeping only their support);
|
|
385
|
+
HMMs can be minimized to ε-machines; automata can be determinized, minimized,
|
|
386
|
+
and turned into regular expressions:
|
|
387
|
+
|
|
388
|
+
.. code-block:: python
|
|
389
|
+
|
|
390
|
+
# Between stochastic presentations
|
|
391
|
+
gm.to_mealy() # any HMM -> Mealy HMM
|
|
392
|
+
moore.to_mealy() # Moore -> Mealy (joint edge law)
|
|
393
|
+
EpsilonMachine.from_hmm(gm) # HMM -> minimal causal ε-machine
|
|
394
|
+
eps.to_bidirectional() # ε-machine -> bidirectional presentation
|
|
395
|
+
eps.mixed_state_presentation() # -> observer belief-state dynamics
|
|
396
|
+
EpsilonMachine.from_time_reversed(eps) # forward -> reverse ε-machine
|
|
397
|
+
|
|
398
|
+
# Stochastic -> topological (drop probabilities, keep the support)
|
|
399
|
+
gm.to_sofic_shift() # HMM support as a sofic shift
|
|
400
|
+
gm.to_support_nfa() # HMM support as an NFA
|
|
401
|
+
gm.to_support_dfa() # HMM support as a (determinized) DFA
|
|
402
|
+
|
|
403
|
+
# Between automata
|
|
404
|
+
nfa.determinize() # NFA -> DFA
|
|
405
|
+
DFA.from_nfa(nfa) # NFA -> DFA (same result)
|
|
406
|
+
dfa.minimize() # DFA -> minimal DFA
|
|
407
|
+
dfa.to_regex() # automaton -> regular expression
|
|
408
|
+
|
|
409
|
+
# Between / out of shifts
|
|
410
|
+
tmc.to_sofic_shift() # topological Markov chain -> sofic shift
|
|
411
|
+
tmc.parry_measure() # shift -> max-entropy MealyHMM
|
|
412
|
+
sofic.parry_measure() # sofic shift -> max-entropy MealyHMM
|
|
413
|
+
|
|
414
|
+
Every model can also be round-tripped through YAML:
|
|
415
|
+
|
|
416
|
+
.. code-block:: python
|
|
417
|
+
|
|
418
|
+
text = eps.to_yaml()
|
|
419
|
+
restored = EpsilonMachine.from_yaml(text)
|
|
420
|
+
# or: sofic.model_to_yaml(eps) / sofic.model_from_yaml(text)
|
|
421
|
+
|
|
422
|
+
Information anatomy (advanced)
|
|
423
|
+
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
424
|
+
|
|
425
|
+
With ``dit`` installed, a bidirectional ε-machine exposes the full stored- and
|
|
426
|
+
transient-information anatomy of a process (James, Burke & Crutchfield, 2013):
|
|
427
|
+
|
|
428
|
+
.. code-block:: python
|
|
429
|
+
|
|
430
|
+
from sofic.examples import golden_mean_bidirectional, tent_map_misiurewicz_bidirectional
|
|
431
|
+
|
|
432
|
+
bidir = golden_mean_bidirectional(0.5)
|
|
433
|
+
bidir.statistical_complexity() # 1.5850 bits (C±)
|
|
434
|
+
bidir.excess_entropy() # 0.2516 bits (E)
|
|
435
|
+
bidir.crypticity() # 1.3333 bits (chi = C± - E)
|
|
436
|
+
|
|
437
|
+
tent = tent_map_misiurewicz_bidirectional()
|
|
438
|
+
tent.information_anatomy() # {'rho_mu', 'bound_mu', 'ephemeral_mu',
|
|
439
|
+
# 'entropy_rate', 'excess_entropy', 'crypticity'}
|
|
440
|
+
|
|
441
|
+
License
|
|
442
|
+
-------
|
|
443
|
+
|
|
444
|
+
``sofic`` is distributed under the BSD 3-Clause License; see ``LICENSE.txt``.
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
sofic/__init__.py,sha256=ii_13tOCVcdvHgA3voyBZ7I3IpyPEsFsbjHbXPliPT4,4290
|
|
2
|
+
sofic/base.py,sha256=DwRUWcbDWBrWo3rfFbVCOMk3RoAmhrp7B_-S1YA_TdA,5168
|
|
3
|
+
sofic/core.py,sha256=uEfilrMfffm-T13HguUQxPKmcl_m3YnYFbj52rwHr88,920
|
|
4
|
+
sofic/exceptions.py,sha256=0WKAdfta__X45nnblGJnl-kt4Y4NEI-tEoZVPHXPMBo,921
|
|
5
|
+
sofic/graph.py,sha256=5oomNKxMTreqNfa9EyKZgqlv4d3i0DfL7xJMkWSe7SA,4491
|
|
6
|
+
sofic/indexing.py,sha256=Peb4QdjeoUAFSgn7OmOqTNR61-ZOKpJwtataZUjMBOg,861
|
|
7
|
+
sofic/operations.py,sha256=bM-qyRJbx6lDEMCp-eZZEGH3Ynj_IPFNDHKKMJzTGzE,594
|
|
8
|
+
sofic/properties.py,sha256=cROWDN6PB7AoDK-Di1lpIOyuc165pyMsRCBdbsx3jwg,12538
|
|
9
|
+
sofic/serialization.py,sha256=PsgU3KIVDN3SRkoM6QkUJ38sFVTmOv-o7nRHPeCbrRM,17585
|
|
10
|
+
sofic/states.py,sha256=NnsEaHsKW8qzuFA1x2XV7WeD4OQeBY_du410RTQfxqQ,1111
|
|
11
|
+
sofic/automata/__init__.py,sha256=K3Wom17IgiIQ3DU8Z6LsCjoPW6vFAxje0f-kWwV59VI,5653
|
|
12
|
+
sofic/automata/_config_simulation.py,sha256=OFdq6E_wM9Ih8WuDmvScPlBUvRRi8R_qffvQHhGFm9c,1480
|
|
13
|
+
sofic/automata/active.py,sha256=bryUzkVIN_oGJA70OqwUsE0uzq4K3R7cL7WAPHLBB5g,21549
|
|
14
|
+
sofic/automata/alergia.py,sha256=vHEhb_SN_yjsMfA8b_EYEtmLESDHBh_rVVTK7VfCAug,7862
|
|
15
|
+
sofic/automata/algorithms.py,sha256=xuqFRoy7tP4A_HKDQX1ANNTOlUz8JAPIV1a1ZYoYKA8,13759
|
|
16
|
+
sofic/automata/atomaton.py,sha256=AjUKU9b5yihzHH0EGVrkUPv2DlmEshSBiq6-jCHNRmM,1993
|
|
17
|
+
sofic/automata/base.py,sha256=TAXN3hhDOEkPDAfrMAc2G1-6Mc1ScQIbYyZDcnBfGTk,6371
|
|
18
|
+
sofic/automata/buchi.py,sha256=VnfC-11nTj_Swf_vyLXocJyxJC5wJprU17ab8Z9VXlw,794
|
|
19
|
+
sofic/automata/buchi_simulation.py,sha256=orCoeF199Nl7YxKRF0-r1rgz8vcNKAuS29_Xlogr3-4,2246
|
|
20
|
+
sofic/automata/canonical_dual.py,sha256=3-1rZBCAIuSQMgxpWB05GK_QpLv7nS5X7R7jmkzzjG8,661
|
|
21
|
+
sofic/automata/canonical_extraction.py,sha256=dvp85XAlfMN4fXszp9QZscy4ejmtsOoW3OLn6u21hpY,4551
|
|
22
|
+
sofic/automata/dfa.py,sha256=jzhe7QsweQQsI6fJx1qkDWS4V7KPSB3PvrZhDrIC4fk,3207
|
|
23
|
+
sofic/automata/dfasat.py,sha256=cTuePqzPffX5hTZ5KmJCiX9Bwl3BtBUKGaeY5izsv30,6549
|
|
24
|
+
sofic/automata/edsm.py,sha256=6M1Ux45sQP0zRmXxbCoynjsiVYVrjIRmA8Iv7mnspYc,7352
|
|
25
|
+
sofic/automata/enumeration.py,sha256=77Th5HlQkPWScAkx8UYKsxPnZjN272MpwxxC6OiMGbM,1369
|
|
26
|
+
sofic/automata/icdfa.py,sha256=neEIMajs66DWTSBvglroZ-8bjg_azERPVM8ZkEDAzW0,14164
|
|
27
|
+
sofic/automata/idfa.py,sha256=wKxC4CKrEoDLG_-8zV758ujhR4uehpG_rYUBKfs118I,12006
|
|
28
|
+
sofic/automata/learning.py,sha256=o6zUz92ia5vOZGXyAztR_I6XO7jYy4bxk4Ll0VgmG5Y,2660
|
|
29
|
+
sofic/automata/nfa.py,sha256=FWCkKGJhPAXtOopAvNnYmdbQK2OxfxD6ZcqcRPh5e1I,1313
|
|
30
|
+
sofic/automata/nwa.py,sha256=Jk6yIRAClh6R75-oHcj3cOdr32dWX3b6poCuToW0hSE,14990
|
|
31
|
+
sofic/automata/nwa_simulation.py,sha256=7rE-bfBvLlPDGyOIwNaR-AZ3Q8JGJJelhr06LVYgqp4,2101
|
|
32
|
+
sofic/automata/observation.py,sha256=rdn9-rW2C6wxSc07u8DkuOPPJZptElSo6nqXKsNJzqI,1497
|
|
33
|
+
sofic/automata/papni.py,sha256=-zcfpMBQlwD2Rz5V-4bX1BHs788jSOAcxewYfPK9Mdc,11113
|
|
34
|
+
sofic/automata/regex.py,sha256=iskKWngd593Afo6CObTrD4qeCHzrTF_8kpvp5P7Tl54,4088
|
|
35
|
+
sofic/automata/rfsa.py,sha256=eGWwnv3BJJDiTfTOny-ERi2Z3ggW22PXSXbExwoIIew,1159
|
|
36
|
+
sofic/automata/rpni.py,sha256=bFjaUvlH4PBlk-O3gN79jpfRmonVWesLyFHnTUFIiF0,6384
|
|
37
|
+
sofic/automata/subsequential.py,sha256=E2ntA4v1ZlrPZyDVoIAxVzdPV0BHvr_RpfII6TRMviw,8248
|
|
38
|
+
sofic/automata/transducer_operations.py,sha256=YV8dS5iy_rxFzvmMlCEJN3LnN7JEdG49chyxKxM8kQQ,14125
|
|
39
|
+
sofic/automata/transducer_simulation.py,sha256=9LEvV7BzMyes6ymJPaFqPi3qZi-z7XLY8TLbxeHdGQI,5609
|
|
40
|
+
sofic/automata/transducers.py,sha256=cbYfDtIYSc7OVBnEqkWZPBn5eJTWKFRWFHaxAWEfc2k,15178
|
|
41
|
+
sofic/automata/unifilar.py,sha256=54Qaof-nzFlLbKiPTwFDstPySZoy34D8vjLtXx7k9GE,4486
|
|
42
|
+
sofic/automata/vpa.py,sha256=uBWlqF6qaRv4CJldnPXEUnC5vkP3GcnJ2OZir7BmqqE,58567
|
|
43
|
+
sofic/automata/vpa_simulation.py,sha256=YL3zRQUy4CLMvRWupBLur9ImjUJ7-0y24ha4ZDT-Zsg,2086
|
|
44
|
+
sofic/automata/languages/__init__.py,sha256=hVWvX4ZxePDo7gcThvbNRsL_nGqgxq7l8lUM8SoLKuw,994
|
|
45
|
+
sofic/automata/languages/_quotient_utils.py,sha256=NCIV29vwUP9kQBtqIj9TgNVPU7KHP8EBluxWNsPhVA0,2216
|
|
46
|
+
sofic/automata/languages/atoms.py,sha256=2fDfxlTikWLovDtffGysp0QQTrT8KzkfDesQne35sJk,1383
|
|
47
|
+
sofic/automata/languages/automaton_ops.py,sha256=v7hHPGW9Q9JTyGAFTRv9bi4DuxGobDFmQaTF_mZsXso,8703
|
|
48
|
+
sofic/automata/languages/base.py,sha256=CyBrTUgC3ATMd8JrxdkPvdG61w26K0Uka_JzkeHjFXQ,1997
|
|
49
|
+
sofic/automata/languages/operations.py,sha256=HZRrbgMmJzu8kF3cgLZK850nm0LEjLvAMqqFxZDOhjQ,3633
|
|
50
|
+
sofic/automata/languages/quotients.py,sha256=zeVsQPAQ07Mhhfy3Vhq_qrfc1EUVFTuixNzn_IFEo-Y,2892
|
|
51
|
+
sofic/automata/languages/residuals.py,sha256=JiB3cEsT6ZGg60xShc-hINrvkLjE93OxAXZC0Kos9bo,1046
|
|
52
|
+
sofic/examples/__init__.py,sha256=1GBuCJMFCbKDm9I-hR9vleR3vgOHiVDSTxNNjzzm4vo,2649
|
|
53
|
+
sofic/examples/epsilon_machines.py,sha256=ycpPrxyZy1_s18kAZfS25fMqidtwpzaRqV7Glsi56-o,40571
|
|
54
|
+
sofic/examples/processes.py,sha256=P2KcRN-5I1_EXFJQDqAU0Tl8ssSpxVV1eeHLVsHYye8,52439
|
|
55
|
+
sofic/examples/shifts.py,sha256=uKICqYSUAthqSL8snA_JUzouJfiFveTyNweZSDk4lnk,5415
|
|
56
|
+
sofic/generators/__init__.py,sha256=3XVm0LPR9F-0BWaEjA0YY2Ma3pgeFV91rBnw2sQx5uY,3884
|
|
57
|
+
sofic/generators/_word_measures.py,sha256=Xr4Coupl5do-OLz5OyKUggnD6zqjz74bJXrRpwnBl_A,2955
|
|
58
|
+
sofic/generators/alternative_complexity.py,sha256=Xd_5Cm6nj9nchGsnCS62E88iHJt5-tK4HWNOR3Ne6Ts,3489
|
|
59
|
+
sofic/generators/base.py,sha256=9XhX92SUOyEakHHcmbXtuv8AJ1ubbshuIDU0y4mR6NA,12895
|
|
60
|
+
sofic/generators/bidirectional_construction.py,sha256=PbFlPCR2MkO8_kc9NM3PSoWylc7dY32rYTWC6YcbwF8,27476
|
|
61
|
+
sofic/generators/bidirectional_epsilon_machine.py,sha256=-DHWbCWOoIabRagMC6RUZz8RoBFrj49HXaGQq_qJYIk,30966
|
|
62
|
+
sofic/generators/block_convergence.py,sha256=l3cVnob9a4rEmlmtrEKbR33Cmbi2mF47AwZgM-w7n6Y,25885
|
|
63
|
+
sofic/generators/block_entropy.py,sha256=IdypvElTpJWbieo95Z6n_cp2IqF9Og_Z9PFj6lIxlGA,21587
|
|
64
|
+
sofic/generators/channel_measures.py,sha256=eYYItbcei9rYwZZZTK5NkGe61pacC221nV37HHkyzzc,3386
|
|
65
|
+
sofic/generators/conversions.py,sha256=tpRUaJUXLz8g07QcGO4b5hxEqqzgW7UwwVh5WMaWzMw,6596
|
|
66
|
+
sofic/generators/directional_flow.py,sha256=WyHhLF_l2-p5-F6TT5JHlH4LurqnD_Ion2-FiRpA5Vk,8312
|
|
67
|
+
sofic/generators/edge_emissions.py,sha256=ydNUrclW24gcPmaqbGVAEy0atrr577VhJUi80P5NkMI,1521
|
|
68
|
+
sofic/generators/edge_machine.py,sha256=nnbIXOrruKGiyy4jZzVphjhPBh6rOTyhdx5-U6f8mTY,6222
|
|
69
|
+
sofic/generators/epsilon_construction.py,sha256=H-VQ06MoL2y0u5whKmSVy5jps-1KUrjKQnzXll1wpQA,6888
|
|
70
|
+
sofic/generators/epsilon_inference.py,sha256=3ky0Cw85H6uRLODPu-jCGCpUxrWLVpvX5hnlKdfLhKI,27141
|
|
71
|
+
sofic/generators/epsilon_machine.py,sha256=jBjc2x71MPaN0RzFSHv6AWF9HmGxkW6RYgN7wBXE7nw,25711
|
|
72
|
+
sofic/generators/epsilon_transducer.py,sha256=wNhatXuH7CW-5UAUa6rauCKJYvamr-MjAWWQlw8HGms,7320
|
|
73
|
+
sofic/generators/epsilon_transducer_construction.py,sha256=f_IwrsPPjVSy2XatGG72WzB0Dj1NduUlIh73yh9eFPc,7358
|
|
74
|
+
sofic/generators/epsilon_transducer_inference.py,sha256=gVusFjCOEwNgfohti7PoXQo0xhz8pinMbnN3gwbXma4,19747
|
|
75
|
+
sofic/generators/hmm_inference.py,sha256=FqjlcumjWMUuLY06osp6j3-227RszuAmYn4LKDXvI4c,29280
|
|
76
|
+
sofic/generators/information_diagram.py,sha256=PnBitp04_v6EevAitiFy2zzmMV-Z9MTBPRxiKcuIA3E,15319
|
|
77
|
+
sofic/generators/lumping.py,sha256=AqWeanqXDSpwJ7ZLErLc2zveMm_zVUXcv1PBE6i3TQY,16910
|
|
78
|
+
sofic/generators/markov.py,sha256=ToNzWnH_hJh-B3vxB-SZO8hDMgdunlX85hxF2j23GYI,4091
|
|
79
|
+
sofic/generators/mealy.py,sha256=_5GPCqM9J4vvwi4Bjq4RxQGn5Kcd6YZbw2oks3SyFNQ,5925
|
|
80
|
+
sofic/generators/measures.py,sha256=ai4gAlhqo2Q5_GOM4-LRlVpf-QmQ0--_qn0iGAHiLog,9612
|
|
81
|
+
sofic/generators/minimal_generative_model.py,sha256=7LaVRkvEdvjEbpVtKNe62Pxj_HD2nC17otre8OHobMA,31000
|
|
82
|
+
sofic/generators/mixed_state.py,sha256=qlzV7VygK5vwkd0Lt56868qkHV-NayBUOinhEEm23lI,9161
|
|
83
|
+
sofic/generators/mixed_state_construction.py,sha256=UJNqo8VF7-fNz5HzBHq9UnnUbVyXN0NaT60adybHOVo,6013
|
|
84
|
+
sofic/generators/moore.py,sha256=vyAVzDs8slz_sKl3OGTyAclc_XcOjUehm8v96yA_STk,3209
|
|
85
|
+
sofic/generators/nmachine.py,sha256=WqRuJrEztwEkA1V6i22hxqzYY8LS_whF2fGkUIq_OoQ,3167
|
|
86
|
+
sofic/generators/nmachine_construction.py,sha256=bhh5XXI1cyNYS-qstPngQ9xYLjwg5-lray0HELtDTR0,2548
|
|
87
|
+
sofic/generators/pfa.py,sha256=MA1owkSr_d0fBVLrrdXb7b3AMKUUBYy3KsFa2-za5MI,3972
|
|
88
|
+
sofic/generators/prob.py,sha256=UxqnQed4XvdmKueHKvX-kklmbrmNipLkP0tHNow3qSw,10614
|
|
89
|
+
sofic/generators/process_equivalence.py,sha256=UKORNNeK5Zis6TLJiIknz3NsPD8iL5CWoeeVxnILlfc,7612
|
|
90
|
+
sofic/generators/quasi_inference.py,sha256=a1UdSIpIRH4pTulqrwGCRc6Zt4TnrKll1D7NE5oQha4,2415
|
|
91
|
+
sofic/generators/quasi_realization.py,sha256=QQosziYqNHEPo1Su4Qjp9k0zBxpqi4wzxUwRahZ57Wk,3501
|
|
92
|
+
sofic/generators/reversal.py,sha256=EGf8KP507Ho1oATqdK1dePqZH4hN7eafJF8DHMJGtYY,2453
|
|
93
|
+
sofic/generators/stack_hmm.py,sha256=I_SBENucbWdnTQKKx-HP760X06xKOJylfQC-L70fYp8,18868
|
|
94
|
+
sofic/generators/stack_inference.py,sha256=wCFbP8kbB2Flzp61N8uN6wkcoCY_wE-mDBw-vFTM40I,18000
|
|
95
|
+
sofic/generators/stationary.py,sha256=nN0ugt61Bl1xiY-8ITF-T__0rfkK0icsbwhQapTLZxM,4992
|
|
96
|
+
sofic/generators/stochastic.py,sha256=_mSfLCxGG_NmA42tvV-kBOzWSgqH6n30uX_igITwVxU,2223
|
|
97
|
+
sofic/generators/synchronization.py,sha256=q8VHzMjLFHITpax5wHlG5a3gSfxOgXwNBW5cnng9q5I,16787
|
|
98
|
+
sofic/generators/topological_epsilon_enumeration.py,sha256=ohxAVtEruXzvDbcqB2AmcIvcDyYVz8xoyh2h2X1CoKQ,12572
|
|
99
|
+
sofic/generators/words.py,sha256=ZZMsAumG8_jMy90GcwLBw1-PkljOM2pfI7rGAy40jVA,8382
|
|
100
|
+
sofic/inference/__init__.py,sha256=9x1af3bORgxAKKs4RJRtsXCATsZsK3BmoJPvETCoYi0,1108
|
|
101
|
+
sofic/inference/model_selection.py,sha256=_s38_lYOmvY_t7TOLaOHArYKrdM3qgRyOU9UBzoC5S8,14099
|
|
102
|
+
sofic/inference/spectral.py,sha256=o6XGTaJkQUaV0SWA-5Xun02bHrvKsONo0dMZOXl6WKU,22108
|
|
103
|
+
sofic/inference/bayesian/__init__.py,sha256=xuf70Lejgo-2mdiyDH6MVwocXzMBYiaMUlbmQT9e0yE,2056
|
|
104
|
+
sofic/inference/bayesian/comparison.py,sha256=ZrQbKRS2jkpa7x9gJZp6aIoOv9CFUgeghklZN-LjzNo,7952
|
|
105
|
+
sofic/inference/bayesian/counts.py,sha256=vd-J_plBsr6oFZFfniqdfGSUdVGlucaw2PKb8JmDcvo,8105
|
|
106
|
+
sofic/inference/bayesian/diversity.py,sha256=xfjf8qx6c5cNSFEoutSIz1-JFOwA8ymyTzpe3NTOAZA,9929
|
|
107
|
+
sofic/inference/bayesian/epsilon.py,sha256=sOBoM5oXvqNJG714i30u4JmM472oywRPTCAlWVYaBAI,12035
|
|
108
|
+
sofic/inference/bayesian/hdp_hmm.py,sha256=hbMyknq7RgN-p2akqFc5aKuF2mhSIwy1Aqen-ytPbdY,13749
|
|
109
|
+
sofic/inference/bayesian/markov.py,sha256=_OsE3pZkFxbEGSJ_bDne3NWw5GSM8gBFhMQMitLni6o,12697
|
|
110
|
+
sofic/inference/bayesian/pymc_backend.py,sha256=YMq-2PkUWX3ZXXZSZPdIYfSOXHi2kaeM2mqfaABo6SA,2984
|
|
111
|
+
sofic/inference/bayesian/stack_hmm.py,sha256=wdtv1qOgRxRcdfwaO1OAXx_q2HJRGDqFGszyRVoSoVA,8566
|
|
112
|
+
sofic/shifts/__init__.py,sha256=8MAtvrdAghmtLFwQY0PA5d8jFUg4_5wGl19ESd5Yors,1373
|
|
113
|
+
sofic/shifts/algorithms.py,sha256=JxfvlSWvz9n2j10HCYcclyhk6CfvPc_oOaGkQWcWkHE,2769
|
|
114
|
+
sofic/shifts/base.py,sha256=IFlL_kMv6MTeQD3wMljmnw6G9xBB5Mz7U6rXdRWkHCg,1844
|
|
115
|
+
sofic/shifts/cover_construction.py,sha256=aiRNyhWds7eJ_VAyTzMJlMlNH9L3gf-A0ojba0r9RR0,2901
|
|
116
|
+
sofic/shifts/covers.py,sha256=x8qcbRQIrj6gH8oL9WJLBbeZulmecvsHx1i0daGRCGw,1367
|
|
117
|
+
sofic/shifts/dyck_algorithms.py,sha256=sTuqbjkD2cLydrEwd9i-pKuWOvmzzhwVw84Hsys6KVo,3479
|
|
118
|
+
sofic/shifts/dyck_enumeration.py,sha256=4eQXDu-3J2-J1Pg_qSvhCT9upnFWs9Bof3Qndl0Pthc,10165
|
|
119
|
+
sofic/shifts/markov_dyck.py,sha256=KA8sbHY59xDDVBVNkJUzb8xgBTbcENijlwQFujzcVvs,6813
|
|
120
|
+
sofic/shifts/parry_construction.py,sha256=JLwlXeqvO-bIro5RVXCo0xADsn4s_JhUx-VI2QTn9AI,2823
|
|
121
|
+
sofic/shifts/sft.py,sha256=RSB7zSDlpggdU47AdhtM6xOm02YJHIGZ38JhvKLsMKg,3973
|
|
122
|
+
sofic/shifts/sft_construction.py,sha256=V-PRlhInOOlU_nXQNU7vZLgGEDw-5VueP3K7RaSV5w0,1603
|
|
123
|
+
sofic/shifts/sliding_block_code.py,sha256=RaZXzSNcc1RZsQnglmY7BVhK6VI0HEpvvPuWqRefsyU,6602
|
|
124
|
+
sofic/shifts/sofic.py,sha256=Pghqv4ODoYbRdOhvgUIjaasCXu4vD89bY1cR-AlIBIM,4690
|
|
125
|
+
sofic/shifts/sofic_dyck.py,sha256=MRsImxWj4gAn32KDVAskygHUg3MJX13SmsEoflzEjG4,5569
|
|
126
|
+
sofic/shifts/sofic_relation.py,sha256=PCF30jOSCS5lsWOGOUd0MGCopg6fOBGbMDeV1Yj1ehc,2707
|
|
127
|
+
sofic/shifts/textile.py,sha256=JC8Y6Wjdj5KQdObPDtROdzFdydyRMAtoresaaE5n8PM,4632
|
|
128
|
+
sofic/shifts/tmc.py,sha256=kSwBRGiUyErW8oVBvjinItIFfdUZo-oluqhjzfYzHKo,1442
|
|
129
|
+
sofic/shifts/tmc_construction.py,sha256=bOB8UcaK81P1NfDPwqV3i_IpD2Bz0hDldmSbReYi0aM,2047
|
|
130
|
+
sofic/shifts/topological_anatomy.py,sha256=VzTNX_iih91UZmTDcc856IfquWKmNDnBfmgvIX1XAwg,6687
|
|
131
|
+
sofic/testing/__init__.py,sha256=iXB73G_LmxCYQpE0_QgR5pBkJoRSQBYrKEgKoUQLcZY,167
|
|
132
|
+
sofic/testing/strategies.py,sha256=6CW77uTRioBX9jpSnj-cL4Rep-tCt7zuLIc-WZWW5_A,5210
|
|
133
|
+
sofic/viz/__init__.py,sha256=cvH7NCrlgakhONsUZkQYhwaE0iaIdqdVnNStUWg7jk8,479
|
|
134
|
+
sofic/viz/_context.py,sha256=e8VGhiLyQa7O5WK9FZjrSozEqzl66N9V8oE90TMMVPs,12608
|
|
135
|
+
sofic/viz/_edge.py,sha256=B2TXmelVbqdQ_ulq2E9ZDvvftcisDDnWhLIqQC_J33c,7825
|
|
136
|
+
sofic/viz/_format.py,sha256=-JQSm_Z185OnIpU8hdViCfJnnk6O3dJvlv7NpPRNExo,2730
|
|
137
|
+
sofic/viz/_labels.py,sha256=C67PJVjVMufAUmgoKKc2wvtxfFMuK8BRXzQ82sg5VpE,1314
|
|
138
|
+
sofic/viz/_names.py,sha256=8IE3AbvOTCMU8IRdj-0dOV1LeOtWLPTO4AObcRo9t_0,447
|
|
139
|
+
sofic/viz/_rational.py,sha256=pZ0IAm0LD1WgpScyCy9a5m1sySw5ppSsiVg0wRid1j0,721
|
|
140
|
+
sofic/viz/_tikz_compile.py,sha256=5cVshbDklLtafvNh1lZyf2NccFhtqsmfmt2GxPDnC-E,5942
|
|
141
|
+
sofic/viz/_tikz_format.py,sha256=bYHQt2K22fFoduDm3u8VhD0YBApYi0oGCJKP8wtWQFM,3782
|
|
142
|
+
sofic/viz/_tikz_layout.py,sha256=BzmOYzsCCFRqVRbAwCwJUQq2lSLv0LD0270Qc-6A-As,7406
|
|
143
|
+
sofic/viz/graphviz.py,sha256=0I3JEsJ-dIjR8Wn0Oj0_YRdWPfn_p47lQgEigu9G1Wk,5174
|
|
144
|
+
sofic/viz/idiagram.py,sha256=w1QyptmuwmwXx9O_Xms3oWXdr1NL5naOdD8H5Lf2N5c,12796
|
|
145
|
+
sofic/viz/tikz.py,sha256=FSzRU3WFQDTpe5a4kMiau28xgYf83lAw_w0TTF_Inds,13445
|
|
146
|
+
sofic/viz/assets/vaucanson.tikz,sha256=Mrrrv8zOUfjSUzvAkFUsYVB4AdJH5ymLdO5C-QTsK0c,2657
|
|
147
|
+
sofic-0.1.0.dist-info/METADATA,sha256=Fi8DbQFbtrxMOyyulmyo7P3989MUqsI_cYC2r2-Fk4s,15613
|
|
148
|
+
sofic-0.1.0.dist-info/WHEEL,sha256=zOwg4jB6zX2kU910N-cMawjivD6tO8NEWvE12je1bVk,87
|
|
149
|
+
sofic-0.1.0.dist-info/licenses/LICENSE.txt,sha256=ezk-F-oQ6gQkTLC1BA1JLl26_Ou5W01ofFriVuRY5Qs,1519
|
|
150
|
+
sofic-0.1.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
BSD 3-Clause License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026, sofic contributors.
|
|
4
|
+
All rights reserved.
|
|
5
|
+
|
|
6
|
+
Redistribution and use in source and binary forms, with or without
|
|
7
|
+
modification, are permitted provided that the following conditions are met:
|
|
8
|
+
|
|
9
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
10
|
+
list of conditions and the following disclaimer.
|
|
11
|
+
|
|
12
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
13
|
+
this list of conditions and the following disclaimer in the documentation
|
|
14
|
+
and/or other materials provided with the distribution.
|
|
15
|
+
|
|
16
|
+
* Neither the name of the copyright holder nor the names of its
|
|
17
|
+
contributors may be used to endorse or promote products derived from
|
|
18
|
+
this software without specific prior written permission.
|
|
19
|
+
|
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
21
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
22
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
23
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
24
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
25
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
26
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
27
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
28
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
29
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|