evonet 0.1.0.dev26__tar.gz → 0.1.0.dev27__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (27) hide show
  1. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/PKG-INFO +1 -1
  2. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/connection.py +16 -4
  3. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/core.py +8 -7
  4. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet.egg-info/PKG-INFO +1 -1
  5. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/pyproject.toml +2 -2
  6. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/tests/test_recurrent_dynamics.py +9 -0
  7. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/LICENSE +0 -0
  8. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/README.md +0 -0
  9. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/__init__.py +0 -0
  10. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/activation.py +0 -0
  11. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/core_mit_plot_simple.py +0 -0
  12. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/enums.py +0 -0
  13. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/io.py +0 -0
  14. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/layer.py +0 -0
  15. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/mutation.py +0 -0
  16. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/neuron.py +0 -0
  17. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/serialization.py +0 -0
  18. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/utils.py +0 -0
  19. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet/visualize.py +0 -0
  20. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet.egg-info/SOURCES.txt +0 -0
  21. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet.egg-info/dependency_links.txt +0 -0
  22. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet.egg-info/requires.txt +0 -0
  23. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/evonet.egg-info/top_level.txt +0 -0
  24. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/setup.cfg +0 -0
  25. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/tests/test_activation.py +0 -0
  26. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/tests/test_core.py +0 -0
  27. {evonet-0.1.0.dev26 → evonet-0.1.0.dev27}/tests/test_nnet_io_and_forward.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: evonet
3
- Version: 0.1.0.dev26
3
+ Version: 0.1.0.dev27
4
4
  Summary: Evolvable neural network core for integration with EvoLib
5
5
  Author-email: EvoLib <evolib@dismail.de>
6
6
  License: MIT License
@@ -38,18 +38,30 @@ class Connection:
38
38
  conn_type: ConnectionType = ConnectionType.STANDARD,
39
39
  ) -> None:
40
40
 
41
+ if delay < 0:
42
+ raise ValueError("delay must be >= 0")
43
+
44
+ # Normalize: recurrent implies delay >= 1
45
+ if conn_type is ConnectionType.RECURRENT and delay == 0:
46
+ delay = 1
47
+
41
48
  self.source = source
42
49
  self.target = target
43
50
  self.weight = weight
44
51
  self.delay = delay
45
- self.type: ConnectionType = conn_type
52
+ self.type = conn_type
46
53
 
47
54
  self._history: Optional[Deque[float]] = None
48
- if self.delay > 0:
55
+ if self.type is ConnectionType.RECURRENT:
49
56
  self._history = deque(maxlen=self.delay)
50
57
 
51
- if self.delay < 0:
52
- raise ValueError("delay must be >= 0")
58
+ def set_delay(self, delay: int) -> None:
59
+ if self.type is not ConnectionType.RECURRENT:
60
+ raise ValueError("set_delay is only valid for recurrent connections")
61
+ if delay <= 0:
62
+ delay = 1
63
+ self.delay = int(delay)
64
+ self._history = deque(maxlen=self.delay)
53
65
 
54
66
  def push_source_output(self, value: float) -> None:
55
67
  """
@@ -351,6 +351,12 @@ class Nnet:
351
351
  if weight is None:
352
352
  weight = 0.0
353
353
 
354
+ # Normalize recurrent delays
355
+ if conn_type is ConnectionType.RECURRENT and delay <= 0:
356
+ delay = 1
357
+ if conn_type is not ConnectionType.RECURRENT and delay < 0:
358
+ delay = 0
359
+
354
360
  conn = Connection(
355
361
  source, target, weight=weight, conn_type=conn_type, delay=delay
356
362
  )
@@ -402,12 +408,7 @@ class Nnet:
402
408
  for n in layer.neurons:
403
409
  for c in n.incoming:
404
410
  if c.type is ConnectionType.RECURRENT:
405
- if c.delay > 0:
406
- # Use delayed history if configured
407
- n.input += c.weight * c.delayed_source_output()
408
- else:
409
- # default: 1-step recurrence via last_output
410
- n.input += c.weight * c.source.last_output
411
+ n.input += c.weight * c.delayed_source_output()
411
412
 
412
413
  # Feed-forward by layers: activate first, then propagate non-recurrent edges
413
414
  for layer in self.layers:
@@ -442,7 +443,7 @@ class Nnet:
442
443
 
443
444
  # Update recurrent delay buffers once per time step.
444
445
  for c in self.get_all_connections():
445
- if c.type is ConnectionType.RECURRENT and c.delay > 0:
446
+ if c.type is ConnectionType.RECURRENT:
446
447
  c.push_source_output(c.source.output)
447
448
 
448
449
  return [n.output for n in self.layers[-1].neurons]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: evonet
3
- Version: 0.1.0.dev26
3
+ Version: 0.1.0.dev27
4
4
  Summary: Evolvable neural network core for integration with EvoLib
5
5
  Author-email: EvoLib <evolib@dismail.de>
6
6
  License: MIT License
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "evonet"
7
- version = "0.1.0.dev26"
7
+ version = "0.1.0.dev27"
8
8
  description = "Evolvable neural network core for integration with EvoLib"
9
9
  authors = [
10
10
  { name = "EvoLib", email = "evolib@dismail.de" }
@@ -48,7 +48,7 @@ include = ["evonet*"]
48
48
  # Tool-Konfigurationen
49
49
  [tool.black]
50
50
  line-length = 88
51
- target-version = ["py311"]
51
+ target-version = ["py312"]
52
52
 
53
53
  [tool.isort]
54
54
  profile = "black"
@@ -181,3 +181,12 @@ def test_reset_full_clears_delay_history() -> None:
181
181
  # After full reset, history is gone -> delay contribution must be 0.0
182
182
  y = net.calc([0.0])[0]
183
183
  assert y == pytest.approx(0.0)
184
+
185
+
186
+ def test_recurrent_delay_zero_normalizes_to_one() -> None:
187
+ net, n_in, n_hid, _ = _mk_linear_ih_h_o()
188
+ c = net.add_connection(
189
+ n_hid, n_hid, weight=1.0, conn_type=ConnectionType.RECURRENT, delay=0
190
+ )
191
+ assert c is not None
192
+ assert c.delay == 1
File without changes
File without changes
File without changes
File without changes