from __future__ import annotations from synaptopus.hopfield import HopfieldNetwork, HopfieldParams def test_hopfield_zero_matrix_runs_on_arbitrary_grid_shape() -> None: inputs = ( (0.8, 0.2), (0.1, 0.9), (0.4, 0.3), ) size = len(inputs) * len(inputs[0]) weights = tuple(tuple(0.0 for _ in range(size)) for _ in range(size)) result = HopfieldNetwork(weight_matrix=weights).run(inputs) assert result.iterations > 0 assert len(result.state.outputs) == 3 assert len(result.state.outputs[0]) == 2 def test_hopfield_respects_initial_activation_shape() -> None: inputs = ( (0.5, 0.5), (0.5, 0.5), ) weights = tuple(tuple(0.0 for _ in range(4)) for _ in range(4)) network = HopfieldNetwork(weight_matrix=weights, params=HopfieldParams()) result = network.run( inputs, initial_activations=( (0.1, 0.2), (0.3, 0.4), ), ) assert len(result.state.activations) == 2 assert len(result.state.activations[0]) == 2 def test_hopfield_round_trips_through_dict() -> None: weights = tuple(tuple(float(i == j) for j in range(4)) for i in range(4)) network = HopfieldNetwork( weight_matrix=weights, params=HopfieldParams(epsilon=0.01, weight_scale=0.5), ) restored = HopfieldNetwork.from_dict(network.to_dict()) assert restored.weight_matrix == network.weight_matrix assert restored.params == network.params