Fibonacci.rst 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. Fibonacci Sequence Generator
  2. ============================
  3. This section describes the usage of the more complex :class:`CBD.lib.std.DelayBlock`.
  4. It will always output the previous value whenever it receives a new one, unless (obviously),
  5. there is no previous value (e.g. at the beginning of the simulation). In that case, its
  6. output is the value it obtains from the :code:`IC`.
  7. We will create a generator that outputs the Fibonacci numbers, starting from :code:`1`,
  8. :code:`1`, :code:`2`, :code:`3`, :code:`5`...; or more mathematically:
  9. .. math::
  10. y(i) &= y(i - 1) + y(i - 2)\\
  11. y(0) &= y(1) = 1
  12. For this we need the :class:`CBD.lib.std.AdderBlock` and obviously the
  13. :class:`CBD.lib.std.DelayBlock`. Additionally, the :class:`CBD.lib.std.ConstantBlock`
  14. will need to be used, as will be discussed later on.
  15. .. code-block:: python
  16. from CBD.CBD import CBD
  17. from CBD.lib.std import ConstantBlock, AdderBlock, DelayBlock
  18. By linking two delay blocks after one another and sending both outputs through the adder,
  19. we can implement the first equation. This yields:
  20. .. code-block:: python
  21. class FibonacciGen(CBD):
  22. def __init__(self, block_name):
  23. CBD.__init__(self, block_name, input_ports=[], output_ports=['OUT1'])
  24. # Create the Blocks
  25. self.addBlock(DelayBlock("delay1"))
  26. self.addBlock(DelayBlock("delay2"))
  27. self.addBlock(AdderBlock("sum"))
  28. # Create the Connections
  29. self.addConnection("delay1", "delay2")
  30. self.addConnection("delay1", "sum")
  31. self.addConnection("delay2", "sum")
  32. self.addConnection("sum", "delay1", input_port_name='IN1')
  33. self.addConnection("sum", "OUT1")
  34. Now, at time :code:`0` **and** at time :code:`1`, we would like to output :code:`1`.
  35. We know:
  36. .. math::
  37. y(0) &= delay1.IC + delay2.IC &= 1 \\
  38. y(1) &= delay1(1) + delay2(1) &= y(0) + delay1.IC\\
  39. & \Leftrightarrow \\
  40. delay1.IC &= 0\\
  41. delay2.IC &= 1
  42. Do, let's add this to our model:
  43. .. code-block:: python
  44. self.addBlock(ConstantBlock("zero", value=0))
  45. self.addBlock(ConstantBlock("one", value=1))
  46. self.addConnection("zero", "delay1", input_port_name='IC')
  47. self.addConnection("one", "delay2", input_port_name='IC')
  48. The complete generator is therefore as follows:
  49. .. code-block:: python
  50. from CBD.CBD import CBD
  51. from CBD.lib.std import ConstantBlock, AdderBlock, DelayBlock
  52. class FibonacciGen(CBD):
  53. def __init__(self, block_name):
  54. CBD.__init__(self, block_name, input_ports=[], output_ports=['OUT1'])
  55. # Create the Blocks
  56. self.addBlock(DelayBlock("delay1"))
  57. self.addBlock(DelayBlock("delay2"))
  58. self.addBlock(AdderBlock("sum"))
  59. self.addBlock(ConstantBlock("zero", value=0))
  60. self.addBlock(ConstantBlock("one", value=1))
  61. # Create the Connections
  62. self.addConnection("delay1", "delay2")
  63. self.addConnection("delay1", "sum")
  64. self.addConnection("delay2", "sum")
  65. self.addConnection("sum", "delay1", input_port_name='IN1')
  66. self.addConnection("sum", "OUT1")
  67. self.addConnection("zero", "delay1", input_port_name='IC')
  68. self.addConnection("one", "delay2", input_port_name='IC')
  69. When running the simulation for 10 time-units, we obtain the first 10 values:
  70. .. code-block:: python
  71. from CBD.simulator import Simulator
  72. cbd = FibonacciGen("FibonacciGen")
  73. sim = Simulator(cbd)
  74. sim.run(10)
  75. data = cbd.getSignal('OUT1')
  76. t, v = [t for t, _ in data], [v for _, v in data]
  77. print(v) # prints [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
  78. .. image:: ../_figures/fib.png
  79. :width: 600