ImpExp.py 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. #!/usr/bin/python3
  2. # This file was automatically generated from drawio2cbd with the command:
  3. # ../../drawio2cbd.py ImpExp.xml ImpExp.py -e Experiment
  4. from CBD.src.CBD import *
  5. import matplotlib.pyplot as plt
  6. def plot_signals(block, signals, title):
  7. times = []
  8. outputs = []
  9. for signal in signals:
  10. tvpl = block.getSignal(signal)
  11. times = [t for t, _ in tvpl]
  12. outputs.append([v for _, v in tvpl])
  13. # Plot
  14. plt.figure()
  15. plt.title(title)
  16. plt.xlabel('time')
  17. plt.ylabel('N')
  18. for i in range(len(signals)):
  19. plt.plot(times, outputs[i], label=signals[i])
  20. plt.legend()
  21. plt.show()
  22. class Explicit(CBD):
  23. def __init__(self, block_name, D=(0.1)):
  24. CBD.__init__(self, block_name, input_ports=[], output_ports=['OUT1', 'OUT2'])
  25. # Create the blocks
  26. self.addBlock(DelayBlock(block_name='prev_x'))
  27. self.addBlock(AdderBlock(block_name='sum_x'))
  28. self.addBlock(ConstantBlock(block_name='D', value=(D)))
  29. self.addBlock(ProductBlock(block_name='mul_x'))
  30. self.addBlock(DelayBlock(block_name='prev_y'))
  31. self.addBlock(AdderBlock(block_name='sum_y'))
  32. self.addBlock(NegatorBlock(block_name='neg'))
  33. self.addBlock(ProductBlock(block_name='mul_y'))
  34. self.addBlock(ConstantBlock(block_name='zero', value=(0)))
  35. self.addBlock(ConstantBlock(block_name='one', value=(1)))
  36. # Connect the blocks
  37. self.addConnection('prev_x', 'sum_x')
  38. self.addConnection('D', 'mul_x')
  39. self.addConnection('mul_x', 'sum_x')
  40. self.addConnection('D', 'neg')
  41. self.addConnection('neg', 'mul_y')
  42. self.addConnection('prev_y', 'sum_y')
  43. self.addConnection('mul_y', 'sum_y')
  44. self.addConnection('sum_x', 'prev_x')
  45. self.addConnection('prev_x', 'mul_y')
  46. self.addConnection('sum_y', 'prev_y')
  47. self.addConnection('zero', 'prev_x', input_port_name='IC')
  48. self.addConnection('one', 'prev_y', input_port_name='IC')
  49. self.addConnection('prev_y', 'mul_x')
  50. self.addConnection('sum_x', 'OUT1')
  51. self.addConnection('sum_y', 'OUT2')
  52. class Implicit(CBD):
  53. def __init__(self, block_name, D=(0.1)):
  54. CBD.__init__(self, block_name, input_ports=[], output_ports=['OUT1', 'OUT2'])
  55. # Create the blocks
  56. self.addBlock(DelayBlock(block_name='prev_x'))
  57. self.addBlock(AdderBlock(block_name='sum_x'))
  58. self.addBlock(ConstantBlock(block_name='D', value=(D)))
  59. self.addBlock(ProductBlock(block_name='mul_x'))
  60. self.addBlock(DelayBlock(block_name='prev_y'))
  61. self.addBlock(AdderBlock(block_name='sum_y'))
  62. self.addBlock(NegatorBlock(block_name='neg'))
  63. self.addBlock(ProductBlock(block_name='mul_y'))
  64. self.addBlock(ConstantBlock(block_name='zero', value=(0)))
  65. self.addBlock(ConstantBlock(block_name='one', value=(1)))
  66. # Connect the blocks
  67. self.addConnection('prev_x', 'sum_x')
  68. self.addConnection('D', 'mul_x')
  69. self.addConnection('mul_x', 'sum_x')
  70. self.addConnection('D', 'neg')
  71. self.addConnection('neg', 'mul_y')
  72. self.addConnection('prev_y', 'sum_y')
  73. self.addConnection('mul_y', 'sum_y')
  74. self.addConnection('sum_x', 'prev_x')
  75. self.addConnection('sum_y', 'prev_y')
  76. self.addConnection('zero', 'prev_x', input_port_name='IC')
  77. self.addConnection('one', 'prev_y', input_port_name='IC')
  78. self.addConnection('sum_x', 'OUT1')
  79. self.addConnection('sum_y', 'OUT2')
  80. self.addConnection('sum_x', 'mul_y')
  81. self.addConnection('sum_y', 'mul_x')
  82. class Experiment(CBD):
  83. def __init__(self, block_name, D=(0.1)):
  84. CBD.__init__(self, block_name, input_ports=[], output_ports=['implicit', 'explicit', 'sin(iD)'])
  85. # Create the blocks
  86. self.addBlock(Explicit(block_name='explicitBlock', D=(D)))
  87. self.addBlock(Implicit(block_name='implicitBlock', D=(D)))
  88. self.addBlock(GenericBlock(block_name='sin', block_operator=("sin")))
  89. self.addBlock(ConstantBlock(block_name='D', value=(D)))
  90. self.addBlock(ProductBlock(block_name='prod'))
  91. self.addBlock(TimeBlock(block_name='time'))
  92. # Connect the blocks
  93. self.addConnection('implicitBlock', 'implicit')
  94. self.addConnection('explicitBlock', 'explicit')
  95. self.addConnection('D', 'prod')
  96. self.addConnection('time', 'prod')
  97. self.addConnection('prod', 'sin')
  98. self.addConnection('sin', 'sin(iD)')
  99. if __name__ == '__main__':
  100. import math
  101. for D in [0.1, 0.001]:
  102. cbd = Experiment("experiment", D)
  103. # Run the simulation
  104. cbd.run(int(math.ceil(2 * math.pi / D)))
  105. # cbd.run(500)
  106. # process simulation results
  107. plot_signals(cbd, ['implicit', 'explicit', 'sin(iD)'], f'Explicit vs Implicit (D={D})')
  108. exp = cbd.getSignal('explicit')
  109. imp = cbd.getSignal('implicit')
  110. times = [e[0] for e in exp]
  111. err = [exp[x][1] - imp[x][1] for x in range(len(exp))]
  112. plt.figure()
  113. plt.title(f"ERROR (D = {D})")
  114. plt.xlabel('time')
  115. plt.ylabel('N')
  116. plt.plot(times, err)
  117. plt.show()