From fcc28fa7b0c67c37334d5418e2b3fe6e482e30e5 Mon Sep 17 00:00:00 2001 From: Roberto Nobrega Date: Tue, 17 Dec 2024 09:34:37 -0300 Subject: [PATCH] refactor: replace attrs with `__init__` method in `FiniteStateMachine` --- .../FiniteStateMachine.py | 32 ++++++++----------- 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/src/komm/_finite_state_machine/FiniteStateMachine.py b/src/komm/_finite_state_machine/FiniteStateMachine.py index 73c09842..88b2f2b8 100644 --- a/src/komm/_finite_state_machine/FiniteStateMachine.py +++ b/src/komm/_finite_state_machine/FiniteStateMachine.py @@ -4,7 +4,6 @@ import numpy as np import numpy.typing as npt -from attrs import field, frozen class MetricMemory(TypedDict): @@ -16,7 +15,6 @@ class MetricMemory(TypedDict): MetricFunction = Callable[[int, Z], float] -@frozen class FiniteStateMachine: r""" Finite-state machine (Mealy machine). It is defined by a *set of states* $\mathcal{S}$, an *input alphabet* $\mathcal{X}$, an *output alphabet* $\mathcal{Y}$, and a *transition function* $T : \mathcal{S} \times \mathcal{X} \to \mathcal{S} \times \mathcal{Y}$. Here, for simplicity, the set of states, the input alphabet, and the output alphabet are always taken as $\mathcal{S} = \\{ 0, 1, \ldots, |\mathcal{S}| - 1 \\}$, $\mathcal{X} = \\{ 0, 1, \ldots, |\mathcal{X}| - 1 \\}$, and $\mathcal{Y} = \\{ 0, 1, \ldots, |\mathcal{Y}| - 1 \\}$, respectively. @@ -49,24 +47,22 @@ class FiniteStateMachine: >>> fsm = komm.FiniteStateMachine(next_states=[[0,1], [2,3], [0,1], [2,3]], outputs=[[0,3], [1,2], [3,0], [2,1]]) """ - next_states: npt.NDArray[np.integer] = field( - converter=np.asarray, repr=lambda x: x.tolist() - ) - outputs: npt.NDArray[np.integer] = field( - converter=np.asarray, repr=lambda x: x.tolist() - ) - _input_edges: npt.NDArray[np.integer] = field(init=False, repr=False) - _output_edges: npt.NDArray[np.integer] = field(init=False, repr=False) - - def __attrs_post_init__(self) -> None: - input_edges = np.full((self.num_states, self.num_states), fill_value=-1) - output_edges = np.full((self.num_states, self.num_states), fill_value=-1) + def __init__(self, next_states: npt.ArrayLike, outputs: npt.ArrayLike): + self.next_states = np.asarray(next_states) + self.outputs = np.asarray(outputs) + self._input_edges = np.full((self.num_states, self.num_states), fill_value=-1) + self._output_edges = np.full((self.num_states, self.num_states), fill_value=-1) for state_from in range(self.num_states): for x, state_to in enumerate(self.next_states[state_from, :]): - input_edges[state_from, state_to] = x - output_edges[state_from, state_to] = self.outputs[state_from, x] - object.__setattr__(self, "_input_edges", input_edges) - object.__setattr__(self, "_output_edges", output_edges) + self._input_edges[state_from, state_to] = x + self._output_edges[state_from, state_to] = self.outputs[state_from, x] + + def __repr__(self) -> str: + args = ", ".join([ + f"next_states={self.next_states.tolist()}", + f"outputs={self.outputs.tolist()}", + ]) + return f"{self.__class__.__name__}({args})" @cached_property def num_states(self) -> int: