GaussSeidelMaster.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175
  1. '''
  2. This follows algorithm 4 in the paper.
  3. '''
  4. import logging
  5. l = logging.getLogger()
  6. class GaussSeidelMaster():
  7. @staticmethod
  8. def start_initialize(order, units):
  9. l.debug(">GaussSeidelMaster.start_initialize()")
  10. for j in order:
  11. unit = units[j];
  12. unit.enterInitMode()
  13. l.debug("<GaussSeidelMaster.start_initialize()")
  14. @staticmethod
  15. def finish_initialize(order, units):
  16. l.debug(">GaussSeidelMaster.finish_initialize()")
  17. for j in order:
  18. unit = units[j];
  19. unit.exitInitMode()
  20. l.debug("<GaussSeidelMaster.finish_initialize()")
  21. @staticmethod
  22. def compute_outputs(step, units, order, coupling, y, u):
  23. l.debug(">GaussSeidelMaster.compute_outputs(%s, %s)", y, u)
  24. for sigmaj in order:
  25. u[sigmaj] = coupling[sigmaj](y)
  26. if u[sigmaj] != None:
  27. units[sigmaj].setValues(step,0,u[sigmaj])
  28. y[sigmaj] = units[sigmaj].getValues(step,0)
  29. l.debug("<GaussSeidelMaster.compute_outputs(%s, %s)", y, u)
  30. @staticmethod
  31. def set_initial_states(units, order, initial_state):
  32. l.debug(">GaussSeidelMaster.set_initial_states()")
  33. for sigmaj in order:
  34. if initial_state[sigmaj] != None:
  35. units[sigmaj].setValues(0,0,initial_state[sigmaj])
  36. l.debug("<GaussSeidelMaster.set_initial_states()")
  37. @staticmethod
  38. def do_cosim_step(t, step, order, units, coupling,
  39. u, y, H_proposed,
  40. H, last_rollback_step,
  41. min_steps_before_increase, max_step_size, step_increase_rate):
  42. l.debug(">GaussSeidelMaster.do_cosim_step(%f, %d, %f)", t, step, H)
  43. ok = False
  44. while not ok:
  45. for sigmaj in order:
  46. u[sigmaj] = coupling[sigmaj](y)
  47. if u[sigmaj] != None:
  48. units[sigmaj].setValues(step,0,u[sigmaj])
  49. (_, H_hat) = units[sigmaj].doStep(t, step, 0, H)
  50. H_proposed[sigmaj] = H_hat
  51. y[sigmaj] = units[sigmaj].getValues(step,0)
  52. min_H = min(H_proposed)
  53. if min_H < H:
  54. l.debug("Rolling back step: %d at time %f", step, t)
  55. for unit in units:
  56. unit.rollback(step)
  57. ok = False
  58. last_rollback_step = step
  59. l.debug("Decreasing step size from %f to %f...", H, min_H)
  60. H = min_H
  61. else:
  62. ok = True
  63. for unit in units:
  64. unit.commit(step)
  65. if (step - last_rollback_step) > min_steps_before_increase \
  66. and H < max_step_size:
  67. new_step_size = H + H * (step_increase_rate/100.0)
  68. l.debug("Increasing step size from %f to %f...", H, new_step_size)
  69. H = new_step_size
  70. if H > max_step_size:
  71. l.debug("Max step size attained: %f.", max_step_size)
  72. H = max_step_size
  73. l.debug("<GaussSeidelMaster.do_cosim_step()=%f , %s", H, H_proposed)
  74. assert H > 0.0
  75. return (H, last_rollback_step)
  76. def simulate(self, order, units, coupling, initial_state,
  77. start_step_size, max_step_size, step_increase_rate, min_steps_before_increase,
  78. stop_time,
  79. plot):
  80. t = 0
  81. H = start_step_size
  82. step = 0
  83. l.debug("Entering init mode...")
  84. GaussSeidelMaster.start_initialize(order,units)
  85. y = []
  86. u = []
  87. H_proposed = []
  88. for _ in units:
  89. y.append(None)
  90. u.append(None)
  91. H_proposed.append(None)
  92. l.debug("Setting initial states...")
  93. GaussSeidelMaster.set_initial_states(units, order, initial_state)
  94. GaussSeidelMaster.compute_outputs(step, units, order, coupling, y, u)
  95. step=1
  96. last_rollback_step = 0
  97. l.debug("Finishing init mode...")
  98. GaussSeidelMaster.finish_initialize(order, units)
  99. plot(t, step, y)
  100. l.debug("Going to step mode...")
  101. while t < stop_time:
  102. l.debug("New cosim step: %d at time %f", step, t)
  103. (H,last_rollback_step) = GaussSeidelMaster.do_cosim_step(t, step, order, units, coupling,
  104. u, y, H_proposed,
  105. H, last_rollback_step,
  106. min_steps_before_increase, max_step_size, step_increase_rate)
  107. """
  108. ok = False
  109. while not ok:
  110. for sigmaj in order:
  111. u[sigmaj] = coupling[sigmaj](y)
  112. if u[sigmaj] != None:
  113. units[sigmaj].setValues(step,0,u[sigmaj])
  114. (_, H_hat) = units[sigmaj].doStep(t, step, 0, H)
  115. H_proposed[sigmaj] = H_hat
  116. y[sigmaj] = units[sigmaj].getValues(step,0)
  117. min_H = min(H_proposed)
  118. if min_H < H:
  119. l.debug("Rolling back step: %d at time %f", step, t)
  120. ok = False
  121. last_rollback_step = step
  122. l.debug("Decreasing step size from %f to %f...", H, min_H)
  123. H = min_H
  124. else:
  125. ok = True
  126. if (step - last_rollback_step) > min_steps_before_increase \
  127. and H < max_step_size:
  128. new_step_size = H + H * (step_increase_rate/100.0)
  129. l.debug("Increasing step size from %f to %f...", H, new_step_size)
  130. H = new_step_size
  131. if H > max_step_size:
  132. l.debug("Max step size attained: %f.", max_step_size)
  133. H = max_step_size
  134. """
  135. t = t + H
  136. plot(t, step, y)
  137. step = step + 1