def ha(env, cstate=0): """This is the ha itself. This is very similar to the 'C' code that we generate from the haskell model, except that the whole thing is event drive. """ delta = None # None to cause failure # Some constants v1 = 30 v2 = -10.0 le = 1 # The continous variables used in this ha x = 0 # The initial value y = 1 # The initial value th = 0 # The initial value ph = 1 # The initial value loc1_ode_x = ODE(env, lvalue=S.sympify('diff(x(t))'), rvalue=S.sympify(S.sympify('cos(th(t))')*v1), ttol=10**-2, iterations=1000) loc1_ode_y = ODE(env, S.sympify('diff(y(t))'), S.sympify(S.sympify('sin(th(t))')*v1), ttol=10**-2, iterations=1000) loc1_ode_th = ODE(env, S.sympify('diff(th(t))'), S.sympify((S.sympify('tan(ph(t))')/le)*v1), ttol=10**-2, iterations=1000) loc1_ode_ph = ODE(env, S.sympify('diff(ph(t))'), S.sympify(v2), ttol=10**-2, iterations=1000) loc1_FT = False loc2_FT = False # XXX: DEBUG # print(loc1_ode, loc2_ode) # The computations in location1 # Returning state, delta, value, loc1_FT, loc2_FT def location1(x, y, th, ph, loc1_FT, loc2_FT, prev_time): curr_time = env.now vals = {S.sympify('x(t)'): x, S.sympify('y(t)'): y, S.sympify('th(t)'): th, S.sympify('ph(t)'): ph} # The edge guard takes preference if ((y >= 1.8 and x <= 2.8) or (y <= 0.8 and x <= 2.8)): print('%7.4f: %7.4f %7.4f %7.4f %7.4f' % (curr_time, x, y, th, ph)) return 1, 0, x, y, th, ph, None, True, curr_time # The invariant elif not ((y >= 1.8 and x <= 2.8) or (y <= 0.8 and x <= 2.8)): # Compute the x value and print it. if not loc1_FT: x = loc1_ode_x.compute(vals, curr_time-prev_time) y = loc1_ode_y.compute(vals, curr_time-prev_time) th = loc1_ode_th.compute(vals, curr_time-prev_time) ph = loc1_ode_ph.compute(vals, curr_time-prev_time) loc1_FT = True print('%7.4f: %7.4f %7.4f %7.4f %7.4f' % (curr_time, x, y, th, ph)) dx, dy = 0, 0 if abs(x-3.2) > loc1_ode_x.vtol: dx = loc1_ode_x.delta(vals, quanta=(3.2-x), other_odes=[loc1_ode_y, loc1_ode_th, loc1_ode_ph]) else: x = 3.2 dx = 0 if abs(x-2.8) > loc1_ode_x.vtol: dx = min(loc1_ode_x.delta(vals, quanta=(2.8-x), other_odes=[loc1_ode_y, loc1_ode_th, loc1_ode_ph]), dx) else: x = 2.8 dx = 0 if abs(y-0.8) > loc1_ode_y.vtol: dy = loc1_ode_y.delta(vals, quanta=(abs(0.8-y)), other_odes=[loc1_ode_x, loc1_ode_th, loc1_ode_ph]) else: y = 0.8 dy = 0 if abs(y-1.8) > loc1_ode_y.vtol: # Purposely relaxing this value, else Python does not # recurse correctly! dy = min(loc1_ode_y.delta(vals, quanta=(1.8-y), other_odes=[loc1_ode_x, loc1_ode_th, loc1_ode_ph]), dy) else: y = 1.8 dy = 0 return 0, min(dx, dy), x, y, th, ph, False, None, curr_time else: raise RuntimeError('Reached unreachable branch' ' in location1') # Location 2 is end state in this example. def location2(x, y, th, ph, loc1_FT, loc2_FT, prev_time): global step print('total steps: ', step) # Done sys.exit(1) # The dictionary for the switch statement. switch_case = { 0: location1, 1: location2 } prev_time = env.now while(True): (cstate, delta, x, y, th, ph, loc1_FT, loc2_FT, prev_time) = switch_case[cstate](x, y, th, ph, loc1_FT, loc2_FT, prev_time) # This should always be the final statement in this function global step step += 1 yield env.timeout(delta)
def NoName(env, cstate=0): delta = None # None to cause failure #define constants #define continuous variables used in this ha x = 0 y = 1 #define location equations Loc0_ode_x = ODE(env, lvalue=S.sympify('diff(x(t))'), rvalue=S.sympify('1.00000000000000'), ttol=10**-3, iterations=100, vtol=0) Loc0_ode_y = ODE(env, lvalue=S.sympify('diff(y(t))'), rvalue=S.sympify('1.00000000000000'), ttol=10**-3, iterations=100, vtol=0) Loc1_ode_x = ODE(env, lvalue=S.sympify('diff(x(t))'), rvalue=S.sympify('1.00000000000000'), ttol=10**-3, iterations=100, vtol=0) Loc1_ode_y = ODE(env, lvalue=S.sympify('diff(y(t))'), rvalue=S.sympify('1.00000000000000'), ttol=10**-3, iterations=100, vtol=0) Loc2_ode_x = ODE(env, lvalue=S.sympify('diff(x(t))'), rvalue=S.sympify('1.00000000000000'), ttol=10**-3, iterations=100, vtol=0) Loc2_ode_y = ODE(env, lvalue=S.sympify('diff(y(t))'), rvalue=S.sympify('1.00000000000000'), ttol=10**-3, iterations=100, vtol=0) Loc3_ode_x = ODE(env, lvalue=S.sympify('diff(x(t))'), rvalue=S.sympify('1.00000000000000'), ttol=10**-3, iterations=100, vtol=0) Loc3_ode_y = ODE(env, lvalue=S.sympify('diff(y(t))'), rvalue=S.sympify('1.00000000000000'), ttol=10**-3, iterations=100, vtol=0) #define location init value Loc0_FT = False Loc1_FT = False Loc2_FT = False Loc3_FT = False #define location function # The computations in Loc0 # Returning state, delta, value, loc1_FT, loc2_FT def Loc0(x, y, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, prev_time): curr_time = env.now vals = {S.sympify('x(t)'): x, S.sympify('y(t)'): y} # the edge guard take preference if y == 10: x = 0 print('%s %7.4f:%7.4f:%7.4f' % ('Loc0-1', curr_time, x, y)) Loc1_FT = True Loc0_FT = None return 1, 0, x, y, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, curr_time elif y <= 10: if not Loc0_FT: x = Loc0_ode_x.compute(vals, curr_time - prev_time) y = Loc0_ode_y.compute(vals, curr_time - prev_time) Loc0_FT = True #else: Loc0_FT = False print('%s %7.4f:%7.4f:%7.4f' % ('Loc0-2', curr_time, x, y)) #set a Maximum value for delta dy = 9999999 if abs(y - 10) > Loc0_ode_y.vtol: dy = min( Loc0_ode_y.delta(vals, quanta=(10 - y), other_odes=[Loc0_ode_x]), dy) else: y = 10 dy = 0 Return_Delta = min(99999, dy) return 0, Return_Delta, x, y, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, curr_time else: raise RuntimeError('Reached unreachable branch' ' in Loc0') # The computations in Loc1 # Returning state, delta, value, loc1_FT, loc2_FT def Loc1(x, y, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, prev_time): curr_time = env.now vals = {S.sympify('x(t)'): x, S.sympify('y(t)'): y} # the edge guard take preference if x == 2: print('%s %7.4f:%7.4f:%7.4f' % ('Loc1-1', curr_time, x, y)) Loc2_FT = True Loc1_FT = None return 2, 0, x, y, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, curr_time elif x <= 2: if not Loc1_FT: x = Loc1_ode_x.compute(vals, curr_time - prev_time) y = Loc1_ode_y.compute(vals, curr_time - prev_time) Loc1_FT = True #else: Loc1_FT = False print('%s %7.4f:%7.4f:%7.4f' % ('Loc1-2', curr_time, x, y)) #set a Maximum value for delta dx = 9999999 if abs(x - 2) > Loc1_ode_x.vtol: dx = min( Loc1_ode_x.delta(vals, quanta=(2 - x), other_odes=[Loc1_ode_y]), dx) else: x = 2 dx = 0 Return_Delta = min(99999, dx) return 1, Return_Delta, x, y, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, curr_time else: raise RuntimeError('Reached unreachable branch' ' in Loc1') # The computations in Loc2 # Returning state, delta, value, loc1_FT, loc2_FT def Loc2(x, y, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, prev_time): curr_time = env.now vals = {S.sympify('x(t)'): x, S.sympify('y(t)'): y} # the edge guard take preference if y == 5: x = 0 print('%s %7.4f:%7.4f:%7.4f' % ('Loc2-1', curr_time, x, y)) Loc3_FT = True Loc2_FT = None return 3, 0, x, y, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, curr_time elif y >= 5: if not Loc2_FT: x = Loc2_ode_x.compute(vals, curr_time - prev_time) y = Loc2_ode_y.compute(vals, curr_time - prev_time) Loc2_FT = True #else: Loc2_FT = False print('%s %7.4f:%7.4f:%7.4f' % ('Loc2-2', curr_time, x, y)) #set a Maximum value for delta dy = 9999999 if abs(y - 5) > Loc2_ode_y.vtol: dy = min( Loc2_ode_y.delta(vals, quanta=(5 - y), other_odes=[Loc2_ode_x]), dy) else: y = 5 dy = 0 Return_Delta = min(99999, dy) return 2, Return_Delta, x, y, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, curr_time else: raise RuntimeError('Reached unreachable branch' ' in Loc2') # The computations in Loc3 # Returning state, delta, value, loc1_FT, loc2_FT def Loc3(x, y, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, prev_time): curr_time = env.now vals = {S.sympify('x(t)'): x, S.sympify('y(t)'): y} # the edge guard take preference if x == 2: print('%s %7.4f:%7.4f:%7.4f' % ('Loc3-1', curr_time, x, y)) Loc0_FT = True Loc3_FT = None return 0, 0, x, y, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, curr_time elif x <= 2: if not Loc3_FT: x = Loc3_ode_x.compute(vals, curr_time - prev_time) y = Loc3_ode_y.compute(vals, curr_time - prev_time) Loc3_FT = True #else: Loc3_FT = False print('%s %7.4f:%7.4f:%7.4f' % ('Loc3-2', curr_time, x, y)) #set a Maximum value for delta dx = 9999999 if abs(x - 2) > Loc3_ode_x.vtol: dx = min( Loc3_ode_x.delta(vals, quanta=(2 - x), other_odes=[Loc3_ode_y]), dx) else: x = 2 dx = 0 Return_Delta = min(99999, dx) return 3, Return_Delta, x, y, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, curr_time else: raise RuntimeError('Reached unreachable branch' ' in Loc3') # The dictionary for the switch statement. switch_case = {0: Loc0, 1: Loc1, 2: Loc2, 3: Loc3} prev_time = env.now while (True): (cstate, delta, x, y, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, prev_time) = switch_case[cstate](x, y, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, prev_time) # This should always be the final statement in this function global step step += 1 yield env.timeout(delta)
def ha(env, cstate=0): """This is the ha itself. This is very similar to the 'C' code that we generate from the haskell model, except that the whole thing is event drive. """ delta = None # None to cause failure # The continous variables used in this ha x = 0 # clock variable y = 1 # The initial value loc0_ode_x = ODE(env, S.sympify('diff(x(t))'), S.sympify('1.0'), ttol=10**-3, iterations=100) loc0_ode_y = ODE(env, S.sympify('diff(y(t))'), S.sympify('1.0'), ttol=10**-3, iterations=100) loc0_FT = False loc1_ode_x = ODE(env, S.sympify('diff(x(t))'), S.sympify('1.0'), ttol=10**-3, iterations=100) loc1_ode_y = ODE(env, S.sympify('diff(y(t))'), S.sympify('1.0'), ttol=10**-3, iterations=100) loc1_FT = False loc2_ode_x = ODE(env, S.sympify('diff(x(t))'), S.sympify('1.0'), ttol=10**-3, iterations=100) loc2_ode_y = ODE(env, S.sympify('diff(y(t))'), S.sympify('-2.0'), ttol=10**-3, iterations=100) loc2_FT = False loc3_ode_x = ODE(env, S.sympify('diff(x(t))'), S.sympify('1.0'), ttol=10**-3, iterations=100) loc3_ode_y = ODE(env, S.sympify('diff(y(t))'), S.sympify('-2.0'), ttol=10**-3, iterations=100) loc3_FT = False # Location 0 def location0(x, y, loc0_FT, loc1_FT, loc2_FT, loc3_FT, prev_time): curr_time = env.now # The edge guard takes preference if y == 10: x = 0 # Reset relation on x print('%7.4f %7.4f %7.4f' % (curr_time, x, y)) return 1, 0, x, y, None, True, None, None, curr_time # The invariant elif y <= 10: if not loc0_FT: x = loc0_ode_x.compute( { S.sympify('x(t)'): x, S.sympify('y(t)'): y }, curr_time - prev_time) y = loc0_ode_y.compute( { S.sympify('x(t)'): x, S.sympify('y(t)'): y }, curr_time - prev_time) loc0_FT = True print('%7.4f %7.4f %7.4f' % (curr_time, x, y)) # XXX: Call the ODE class that will give the delta back iff # the calculated "x" is greater than the error. if abs(y - 10) > loc0_ode_y.vtol: delta = loc0_ode_y.delta( { S.sympify('x(t)'): x, S.sympify('y(t)'): y }, quanta=(10 - y)) else: # If within the error bound just make it 10 y = 10 delta = 0 return 0, delta, x, y, False, None, None, None, curr_time else: raise RuntimeError('Reached unreachable branch' ' in location 0') # Location 1 def location1(x, y, loc0_FT, loc1_FT, loc2_FT, loc3_FT, prev_time): curr_time = env.now # The edge guard takes preference if x == 2: print('%7.4f %7.4f %7.4f' % (curr_time, x, y)) return 2, 0, x, y, None, None, True, None, curr_time # The invariant elif x <= 2: if not loc1_FT: x = loc1_ode_x.compute( { S.sympify('x(t)'): x, S.sympify('y(t)'): y }, curr_time - prev_time) y = loc1_ode_y.compute( { S.sympify('x(t)'): x, S.sympify('y(t)'): y }, curr_time - prev_time) loc1_FT = True print('%7.4f %7.4f %7.4f' % (curr_time, x, y)) if abs(x - 2) > loc1_ode_x.vtol: delta = loc1_ode_x.delta( { S.sympify('x(t)'): x, S.sympify('y(t)'): y }, quanta=(2 - x)) else: # If within the error bound just make it 2 x = 2 delta = 0 return 1, delta, x, y, None, False, None, None, curr_time else: raise RuntimeError('Reached unreachable branch' ' in location 1') # Location 2 def location2(x, y, loc0_FT, loc1_FT, loc2_FT, loc3_FT, prev_time): curr_time = env.now # The edge guard takes preference if y == 5: x = 0 # Reset relation on x print('%7.4f %7.4f %7.4f' % (curr_time, x, y)) return 3, 0, x, y, None, None, None, True, curr_time # The invariant elif y >= 5: if not loc2_FT: x = loc2_ode_x.compute( { S.sympify('x(t)'): x, S.sympify('y(t)'): y }, curr_time - prev_time) y = loc2_ode_y.compute( { S.sympify('x(t)'): x, S.sympify('y(t)'): y }, curr_time - prev_time) loc2_FT = True print('%7.4f %7.4f %7.4f' % (curr_time, x, y)) if abs(y - 5) > loc2_ode_y.vtol: delta = loc2_ode_y.delta( { S.sympify('x(t)'): x, S.sympify('y(t)'): y }, quanta=(5 - y)) else: # If within the error bound just make it 10 y = 5 delta = 0 return 2, delta, x, y, None, None, False, None, curr_time else: raise RuntimeError('Reached unreachable branch' ' in location 2') # Location 3 def location3(x, y, loc0_FT, loc1_FT, loc2_FT, loc3_FT, prev_time): curr_time = env.now # The edge guard takes preference if x == 2: print('%7.4f %7.4f %7.4f' % (curr_time, x, y)) return 0, 0, x, y, None, None, True, None, curr_time # The invariant elif x <= 2: if not loc3_FT: x = loc3_ode_x.compute( { S.sympify('x(t)'): x, S.sympify('y(t)'): y }, curr_time - prev_time) y = loc3_ode_y.compute( { S.sympify('x(t)'): x, S.sympify('y(t)'): y }, curr_time - prev_time) loc3_FT = True print('%7.4f %7.4f %7.4f' % (curr_time, x, y)) if abs(x - 2) > loc3_ode_x.vtol: delta = loc3_ode_x.delta( { S.sympify('x(t)'): x, S.sympify('y(t)'): y }, quanta=(2 - x)) else: # If within the error bound just make it 2 x = 2 delta = 0 return 3, delta, x, y, False, None, None, None, curr_time else: raise RuntimeError('Reached unreachable branch' ' in location 2') # The dictionary for the switch statement. switch_case = {0: location0, 1: location1, 2: location2, 3: location3} prev_time = env.now while (True): (cstate, delta, x, y, loc0_FT, loc1_FT, loc2_FT, loc3_FT, prev_time) = switch_case[cstate](x, y, loc0_FT, loc1_FT, loc2_FT, loc3_FT, prev_time) # This should always be the final statement in this function global step step += 1 yield env.timeout(delta)
def ha(env, cstate=0): """This is the ha itself. This is very similar to the 'C' code that we generate from the haskell model, except that the whole thing is event drive. """ delta = None # None to cause failure # The continous variables used in this ha x = 1 # The initial value y = 0 # The initial value loc1_xode = ODE(env, lvalue=S.sympify('diff(x(t))'), rvalue=S.sympify('y(t)+x(t)+1'), ttol=10**-3, iterations=100) loc1_yode = ODE(env, lvalue=S.sympify('diff(y(t))'), rvalue=S.sympify('x(t)^2'), ttol=10**-3, iterations=1000) loc2_xode = ODE(env, S.sympify('diff(x(t))'), S.sympify('-2*y(t)'), ttol=10**-3, iterations=100) loc2_yode = ODE(env, S.sympify('diff(x(t))'), S.sympify('-x(t)+1'), ttol=10**-3, iterations=100) loc1_FT = False loc2_FT = False # XXX: DEBUG # print(loc1_ode, loc2_ode) # The computations in location1 # Returning state, delta, value, loc1_FT, loc2_FT def location1(x, y, loc1_FT, loc2_FT, prev_time): curr_time = env.now # The edge guard takes preference if x >= 5 and y >= 3: print('%7.4f %7.4f' % (curr_time, x)) # import sys # sys.exit(1) return 1, 0, x, None, True, curr_time # The invariant elif x <= 5 and y <= 3: # Compute the x value and print it. if not loc1_FT: # All the dependent initial conditions x = loc1_xode.compute( { S.sympify('y(t)'): y, S.sympify('x(t)'): x }, curr_time - prev_time) y = loc1_yode.compute( { S.sympify('y(t)'): y, S.sympify('x(t)'): x }, curr_time - prev_time) loc1_FT = True print('%7.7f %7.7f %7.7f' % (curr_time, x, y)) if abs(x - 5) > loc1_xode.vtol: x_delta = loc1_xode.delta( { S.sympify('y(t)'): y, S.sympify('x(t)'): x }, quanta=(5 - x), other_odes=[loc1_yode]) # DEBUG print('xδ: ', x_delta) else: # If within the error bound just make it 10 x = 5 x_delta = 0 if abs(y - 3) > loc1_yode.vtol: y_delta = loc1_yode.delta( { S.sympify('y(t)'): y, S.sympify('x(t)'): x }, quanta=(3 - y), other_odes=[loc1_xode]) # DEBUG print('yδ: ', y_delta) else: # If within the error bound just make it 10 y = 3 y_delta = 0 # DEBUG print('min δ: ', min(x_delta, y_delta)) return 0, min(x_delta, y_delta), (x, y), False, None, curr_time else: raise RuntimeError('Reached unreachable branch' ' in location1') # The computations in location2 def location2(x, y, loc1_FT, loc2_FT, prev_time): curr_time = env.now if x <= 1 and y <= 1: print('%7.7f %7.7f' % (curr_time, x)) return 0, 0, x, True, None, curr_time elif x >= 1 and y >= 1: # TODO: Call the ODE class to get delta if not loc2_FT: x = loc2_xode.compute( { S.sympify('y(t)'): y, S.sympify('x(t)'): x }, curr_time - prev_time) y = loc2_yode.compute( { S.sympify('y(t)'): y, S.sympify('x(t)'): x }, curr_time - prev_time) print('%7.7f %7.7f %7.7f' % (curr_time, x, y)) if abs(x - 1) > loc2_xode.vtol: x_delta = loc2_xode.delta( { S.sympify('y(t)'): y, S.sympify('x(t)'): x }, quanta=(1 - x), other_odes=[loc2_yode]) else: # If within error bound then just make it the level. x = 1 x_delta = 0 if abs(y - 1) > loc2_yode.vtol: y_delta = loc2_yode.delta( { S.sympify('y(t)'): y, S.sympify('x(t)'): x }, quanta=(1 - y), other_odes=[loc2_xode]) else: # If within error bound then just make it the level. y = 1 y_delta = 0 return 1, min(x_delta, y_delta), (x, y), None, False, curr_time else: raise RuntimeError('Reached unreachable branch' ' in location2') # The dictionary for the switch statement. switch_case = {0: location1, 1: location2} prev_time = env.now while (True): (cstate, delta, (x, y), loc1_FT, loc2_FT, prev_time) = switch_case[cstate](x, y, loc1_FT, loc2_FT, prev_time) # This should always be the final statement in this function yield env.timeout(delta)
import math import numpy as np from src.ivp import IVP from src.ode import ODE from src.results import ResultsComparator from src.solver import AdamsBashforthSecondSolver, ForwardEulerSolver g = lambda u, t: np.array([-1 * u[0]]) h = lambda u, t: np.array([-2 * u[0] + math.cos(t)]) true_value = lambda t: math.exp(-2 * t) + (1 / 5.0) * (2 * math.cos(t) + math. sin(t)) de = ODE(h) u_0 = np.array([1.4]) t_0 = 0 step = 0.001 precision = 3 t_n = 10 problem = IVP(de, u_0, t_0) first_step_slv = ForwardEulerSolver(problem, t_n, step, precision) adams_slv = AdamsBashforthSecondSolver(problem, first_step_slv, t_n, step, precision) adams_slv.solve()
import numpy as np from src.ivp import IVP from src.ode import ODE from src.results import ResultsComparator from src.solver import ForwardEulerSolver f = lambda u, t: np.array([u[0] + u[1] - t, u[0] - u[1]]) true_value = lambda t: np.array([ math.exp(t * math.sqrt(2)) + math.exp(-1 * t * math.sqrt( 2)) + 0.5 + 0.5 * t, (math.sqrt(2) - 1) * math.exp(t * math.sqrt(2)) - (1 + math.sqrt(2)) * math.exp(-1 * t * math.sqrt(2)) - 0.5 + 0.5 * t ]) de = ODE(f) u_0 = np.array([2.5, -2.5]) t_0 = 0 step = 0.25 precision = 2 t_n = 3 problem = IVP(de, u_0, t_0) slv = ForwardEulerSolver(problem, t_n, step, precision) slv.solve() print(slv.solution.value_mesh)
def ha(env, cstate=0): """This is the ha itself. This is very similar to the 'C' code that we generate from the haskell model, except that the whole thing is event drive. """ delta = None # None to cause failure # The continous variables used in this ha x = 20 # The initial value loc1_xode = ODE(env, lvalue=S.sympify('diff(x(t))'), rvalue=S.sympify('-0.25*x(t)'), ttol=10**-3, iterations=100) loc2_xode = ODE(env, S.sympify('diff(x(t))'), S.sympify('125-0.25*x(t)'), ttol=10**-3, iterations=100) loc1_FT = False loc2_FT = False # The computations in location1 # Returning state, delta, value, loc1_FT, loc2_FT def location1(x, loc1_FT, loc2_FT, prev_time): curr_time = env.now # The edge guard takes preference if x <= 18.5: print('%7.7f: %7.7f' % (curr_time, x)) return 1, 0, x, None, True, curr_time # The invariant elif x >= 18.5: # Compute the x value and print it. if not loc1_FT: # All the dependent initial conditions x = loc1_xode.compute({S.sympify('x(t)'): x}, curr_time-prev_time) loc1_FT = True print('%7.7f: %7.7f' % (curr_time, x)) if abs(x-18.5) > loc1_xode.vtol: x_delta = loc1_xode.delta({S.sympify('x(t)'): x}, quanta=(18.5-x)) else: # If within the error bound just make it 10 x = 18.5 x_delta = 0 return 0, x_delta, x, False, None, curr_time else: raise RuntimeError('Reached unreachable branch' ' in location1') # The computations in location2 def location2(x, loc1_FT, loc2_FT, prev_time): curr_time = env.now if x >= 19.5: print('%7.7f: %7.7f' % (curr_time, x)) return 0, 0, x, True, None, curr_time elif x <= 19.5: if not loc2_FT: x = loc2_xode.compute({S.sympify('x(t)'): x}, curr_time-prev_time) print('%7.7f: %7.7f' % (curr_time, x)) if abs(x-19.5) > loc2_xode.vtol: x_delta = loc2_xode.delta({S.sympify('x(t)'): x}, quanta=(19.5 - x)) else: # If within error bound then just make it the level. x = 19.5 x_delta = 0 return 1, x_delta, x, None, False, curr_time else: raise RuntimeError('Reached unreachable branch' ' in location2') # The dictionary for the switch statement. switch_case = { 0: location1, 1: location2 } prev_time = env.now while(True): (cstate, delta, x, loc1_FT, loc2_FT, prev_time) = switch_case[cstate](x, loc1_FT, loc2_FT, prev_time) # This should always be the final statement in this function global step step += 1 yield env.timeout(delta)
def q(env, cstate=0): delta = None # None to cause failure #define constants EPIKS = 2.0994 EPIKSO = 2.0458 EPIKWM = 65.0 EPITFI = 0.11 EPITHV = 0.3 EPITO1 = 0.007 EPITO2 = 6 EPITS1 = 2.7342 EPITS2 = 16.0 EPITSI = 1.8875 EPITSO1 = 30.0181 EPITSO2 = 0.9957 EPITVM1 = 1150.0 EPITVM2 = 60.0 EPITVP = 1.4506 EPITWINF = 0.07 EPITWM1 = 60 EPITWM2 = 15.0 EPITWP = 200.0 EPIUS = 0.9087 EPIUSO = 0.65 EPIUU = 1.55 EPIUWM = 0.03 jfi1 = 0.0 jfi2 = 0.0 jfi3 = 0.0 jsi1 = 0.0 jsi2 = 0.0 stim = 1.0 #define continuous variables used in this ha s = 0.0 tau = 0.0 u = 0.0 v = 1.0 w = 1.0 #define location equations Loc0_ode_tau = ODE(env, lvalue=S.sympify('diff(tau(t))'), rvalue=S.sympify('1.00000000000000'), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) Loc0_ode_u = ODE(env, lvalue=S.sympify('diff(u(t))'), rvalue=S.sympify(-jfi1 + stim - jsi1 - S.sympify('u(t)') / EPITO1), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) Loc0_ode_w = ODE( env, lvalue=S.sympify('diff(w(t))'), rvalue=S.sympify( (-S.sympify('w(t)') + 1.0 - S.sympify('u(t)') / EPITWINF) / (EPITWM1 + (-EPITWM1 + EPITWM2) * (1.0 / (S.exp( ((-2) * EPIKWM) * (-EPIUS + S.sympify('u(t)'))) + 1)))), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) Loc0_ode_v = ODE(env, lvalue=S.sympify('diff(v(t))'), rvalue=S.sympify((-S.sympify('v(t)') + 1.0) / EPITVM1), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) Loc0_ode_s = ODE(env, lvalue=S.sympify('diff(s(t))'), rvalue=S.sympify((-S.sympify('s(t)') + 1 / (S.exp( ((-2) * EPIKS) * (-EPIUS + S.sympify('u(t)'))) + 1)) / EPITS1), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) Loc1_ode_tau = ODE(env, lvalue=S.sympify('diff(tau(t))'), rvalue=S.sympify('1.00000000000000'), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) Loc1_ode_u = ODE( env, lvalue=S.sympify('diff(u(t))'), rvalue=S.sympify(-jfi3 + stim - 1.0 / ((-EPITSO1 + EPITSO2) * (S.exp(S.sympify('u(t)') * ((-2) * EPIKSO)) + 1))), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) Loc1_ode_w = ODE(env, lvalue=S.sympify('diff(w(t))'), rvalue=S.sympify((-S.sympify('w(t)')) / EPITWP), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) Loc1_ode_v = ODE(env, lvalue=S.sympify('diff(v(t))'), rvalue=S.sympify((-S.sympify('v(t)')) / EPITVM2), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) Loc1_ode_s = ODE(env, lvalue=S.sympify('diff(s(t))'), rvalue=S.sympify((-S.sympify('s(t)') + 1 / (S.exp( ((-2) * EPIKS) * (-EPIUS + S.sympify('u(t)'))) + 1)) / EPITS2), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) Loc2_ode_tau = ODE(env, lvalue=S.sympify('diff(tau(t))'), rvalue=S.sympify('1.00000000000000'), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) Loc2_ode_u = ODE( env, lvalue=S.sympify('diff(u(t))'), rvalue=S.sympify(-jfi3 + stim - 1.0 / ((-EPITSO1 + EPITSO2) * (S.exp(S.sympify('u(t)') * ((-2) * EPIKSO)) + 1))), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) Loc2_ode_w = ODE(env, lvalue=S.sympify('diff(w(t))'), rvalue=S.sympify((-S.sympify('w(t)')) / EPITWP), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) Loc2_ode_v = ODE(env, lvalue=S.sympify('diff(v(t))'), rvalue=S.sympify((-S.sympify('v(t)')) / EPITVP), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) Loc2_ode_s = ODE(env, lvalue=S.sympify('diff(s(t))'), rvalue=S.sympify((-S.sympify('s(t)') + 1 / (S.exp( ((-2) * EPIKS) * (-EPIUS + S.sympify('u(t)'))) + 1)) / EPITS2), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) loc3_ode_tau = ODE(env, lvalue=S.sympify('diff(tau(t))'), rvalue=S.sympify('1.00000000000000'), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) loc3_ode_u = ODE( env, lvalue=S.sympify('diff(u(t))'), rvalue=S.sympify(stim + S.sympify('v(t)') * (-EPITHV + S.sympify('u(t)')) * (EPIUU - S.sympify('u(t)')) / EPITFI - (-EPITSO1 + EPITSO2) / (S.exp(((-2) * EPIKSO) * (-EPIUSO + S.sympify('u(t)'))) + 1) - 1.0 / EPITSO1 - S.sympify('s(t)') * w / EPITSI), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) loc3_ode_w = ODE(env, lvalue=S.sympify('diff(w(t))'), rvalue=S.sympify((-S.sympify('w(t)')) / EPITWP), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) loc3_ode_v = ODE(env, lvalue=S.sympify('diff(v(t))'), rvalue=S.sympify((-S.sympify('v(t)')) / EPITVP), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) loc3_ode_s = ODE(env, lvalue=S.sympify('diff(s(t))'), rvalue=S.sympify((-S.sympify('s(t)') + 1 / (S.exp( ((-2) * EPIKS) * (-EPIUS + S.sympify('u(t)'))) + 1)) / EPITS2), ttol=10**-3, iterations=100, vtol=0, simplify_poly=True) #define location init value Loc0_FT = False Loc1_FT = False Loc2_FT = False loc3_FT = False #define location function # The computations in Loc0 # Returning state, delta, value, loc1_FT, loc2_FT def Loc0(tau, u, w, v, s, Loc0_FT, Loc1_FT, Loc2_FT, loc3_FT, prev_time): curr_time = env.now vals = { S.sympify('tau(t)'): tau, S.sympify('u(t)'): u, S.sympify('w(t)'): w, S.sympify('v(t)'): v, S.sympify('s(t)'): s } # the edge guard take preference if u >= 0.006: print('%s %7.4f:%7.4f:%7.4f:%7.4f:%7.4f:%7.4f' % ('Loc0-1', curr_time, tau, u, w, v, s)) Loc1_FT = True Loc0_FT = None return 1, 0, tau, u, w, v, s, Loc0_FT, Loc1_FT, Loc2_FT, loc3_FT, curr_time elif u <= 0.006: if not Loc0_FT: tau = Loc0_ode_tau.compute(vals, curr_time - prev_time) u = Loc0_ode_u.compute(vals, curr_time - prev_time) w = Loc0_ode_w.compute(vals, curr_time - prev_time) v = Loc0_ode_v.compute(vals, curr_time - prev_time) s = Loc0_ode_s.compute(vals, curr_time - prev_time) Loc0_FT = True #else: Loc0_FT = False print('%s %7.4f:%7.4f:%7.4f:%7.4f:%7.4f:%7.4f' % ('Loc0-2', curr_time, tau, u, w, v, s)) #set a Maximum value for delta du = 9999999 if abs(u - 0.006) > Loc0_ode_u.vtol: du = min( Loc0_ode_u.delta(vals, quanta=(0.006 - u), other_odes=[ Loc0_ode_tau, Loc0_ode_w, Loc0_ode_v, Loc0_ode_s ]), du) else: u = 0.006 du = 0 Return_Delta = min(99999, du) return 0, Return_Delta, tau, u, w, v, s, Loc0_FT, Loc1_FT, Loc2_FT, loc3_FT, curr_time else: raise RuntimeError('Reached unreachable branch' ' in Loc0') # The computations in Loc1 # Returning state, delta, value, loc1_FT, loc2_FT def Loc1(tau, u, w, v, s, Loc0_FT, Loc1_FT, Loc2_FT, loc3_FT, prev_time): curr_time = env.now vals = { S.sympify('tau(t)'): tau, S.sympify('u(t)'): u, S.sympify('w(t)'): w, S.sympify('v(t)'): v, S.sympify('s(t)'): s } # the edge guard take preference if u >= 0.013: print('%s %7.4f:%7.4f:%7.4f:%7.4f:%7.4f:%7.4f' % ('Loc1-1', curr_time, tau, u, w, v, s)) Loc2_FT = True Loc1_FT = None return 2, 0, tau, u, w, v, s, Loc0_FT, Loc1_FT, Loc2_FT, loc3_FT, curr_time elif u <= 0.013: if not Loc1_FT: tau = Loc1_ode_tau.compute(vals, curr_time - prev_time) u = Loc1_ode_u.compute(vals, curr_time - prev_time) w = Loc1_ode_w.compute(vals, curr_time - prev_time) v = Loc1_ode_v.compute(vals, curr_time - prev_time) s = Loc1_ode_s.compute(vals, curr_time - prev_time) Loc1_FT = True #else: Loc1_FT = False print('%s %7.4f:%7.4f:%7.4f:%7.4f:%7.4f:%7.4f' % ('Loc1-2', curr_time, tau, u, w, v, s)) #set a Maximum value for delta du = 9999999 if abs(u - 0.013) > Loc1_ode_u.vtol: du = min( Loc1_ode_u.delta(vals, quanta=(0.013 - u), other_odes=[ Loc1_ode_tau, Loc1_ode_w, Loc1_ode_v, Loc1_ode_s ]), du) else: u = 0.013 du = 0 Return_Delta = min(99999, du) return 1, Return_Delta, tau, u, w, v, s, Loc0_FT, Loc1_FT, Loc2_FT, loc3_FT, curr_time else: raise RuntimeError('Reached unreachable branch' ' in Loc1') # The computations in Loc2 # Returning state, delta, value, loc1_FT, loc2_FT def Loc2(tau, u, w, v, s, Loc0_FT, Loc1_FT, Loc2_FT, loc3_FT, prev_time): curr_time = env.now vals = { S.sympify('tau(t)'): tau, S.sympify('u(t)'): u, S.sympify('w(t)'): w, S.sympify('v(t)'): v, S.sympify('s(t)'): s } # the edge guard take preference if u >= 0.3: print('%s %7.4f:%7.4f:%7.4f:%7.4f:%7.4f:%7.4f' % ('Loc2-1', curr_time, tau, u, w, v, s)) loc3_FT = True Loc2_FT = None return 3, 0, tau, u, w, v, s, Loc0_FT, Loc1_FT, Loc2_FT, loc3_FT, curr_time elif u <= 0.3: if not Loc2_FT: tau = Loc2_ode_tau.compute(vals, curr_time - prev_time) u = Loc2_ode_u.compute(vals, curr_time - prev_time) w = Loc2_ode_w.compute(vals, curr_time - prev_time) v = Loc2_ode_v.compute(vals, curr_time - prev_time) s = Loc2_ode_s.compute(vals, curr_time - prev_time) Loc2_FT = True #else: Loc2_FT = False print('%s %7.4f:%7.4f:%7.4f:%7.4f:%7.4f:%7.4f' % ('Loc2-2', curr_time, tau, u, w, v, s)) #set a Maximum value for delta du = 9999999 if abs(u - 0.3) > Loc2_ode_u.vtol: du = min( Loc2_ode_u.delta(vals, quanta=(0.3 - u), other_odes=[ Loc2_ode_tau, Loc2_ode_w, Loc2_ode_v, Loc2_ode_s ]), du) else: u = 0.3 du = 0 Return_Delta = min(99999, du) return 2, Return_Delta, tau, u, w, v, s, Loc0_FT, Loc1_FT, Loc2_FT, loc3_FT, curr_time else: raise RuntimeError('Reached unreachable branch' ' in Loc2') # The computations in loc3 # Returning state, delta, value, loc1_FT, loc2_FT def loc3(tau, u, w, v, s, Loc0_FT, Loc1_FT, Loc2_FT, loc3_FT, prev_time): curr_time = env.now vals = { S.sympify('tau(t)'): tau, S.sympify('u(t)'): u, S.sympify('w(t)'): w, S.sympify('v(t)'): v, S.sympify('s(t)'): s } # the edge guard take preference if u >= 2.0: print('%s %7.4f:%7.4f:%7.4f:%7.4f:%7.4f:%7.4f' % ('loc3-1', curr_time, tau, u, w, v, s)) loc3_FT = True loc3_FT = None return 3, 0, tau, u, w, v, s, Loc0_FT, Loc1_FT, Loc2_FT, loc3_FT, curr_time elif u <= 2.0: if not loc3_FT: tau = loc3_ode_tau.compute(vals, curr_time - prev_time) u = loc3_ode_u.compute(vals, curr_time - prev_time) w = loc3_ode_w.compute(vals, curr_time - prev_time) v = loc3_ode_v.compute(vals, curr_time - prev_time) s = loc3_ode_s.compute(vals, curr_time - prev_time) loc3_FT = True #else: loc3_FT = False print('%s %7.4f:%7.4f:%7.4f:%7.4f:%7.4f:%7.4f' % ('loc3-2', curr_time, tau, u, w, v, s)) #set a Maximum value for delta du = 9999999 if abs(u - 2.0) > loc3_ode_u.vtol: du = min( loc3_ode_u.delta(vals, quanta=(2.0 - u), other_odes=[ loc3_ode_tau, loc3_ode_w, loc3_ode_v, loc3_ode_s ]), du) else: u = 2.0 du = 0 Return_Delta = min(99999, du) return 3, Return_Delta, tau, u, w, v, s, Loc0_FT, Loc1_FT, Loc2_FT, loc3_FT, curr_time else: raise RuntimeError('Reached unreachable branch' ' in loc3') # The dictionary for the switch statement. switch_case = {0: Loc0, 1: Loc1, 2: Loc2, 3: loc3} prev_time = env.now while (True): (cstate, delta, tau, u, w, v, s, Loc0_FT, Loc1_FT, Loc2_FT, loc3_FT, prev_time) = switch_case[cstate](tau, u, w, v, s, Loc0_FT, Loc1_FT, Loc2_FT, loc3_FT, prev_time) # This should always be the final statement in this function global step step += 1 yield env.timeout(delta)
def NoName(env, cstate=0): delta = None # None to cause failure #define constants le = 1 v1 = 30 v2 = -10 #define continuous variables used in this ha phi = 1 theta = 0 x = 0 y = 1 #define location equations L1_ode_x = ODE(env, lvalue=S.sympify('diff(x(t))'), rvalue=S.sympify(v1 * S.cos(S.sympify('theta(t)'))), ttol=0.01, iterations=1000, vtol=0) L1_ode_y = ODE(env, lvalue=S.sympify('diff(y(t))'), rvalue=S.sympify(v1 * S.sin(S.sympify('theta(t)'))), ttol=0.01, iterations=1000, vtol=0) L1_ode_theta = ODE(env, lvalue=S.sympify('diff(theta(t))'), rvalue=S.sympify(v1 * (S.tan(S.sympify('phi(t)')) / le)), ttol=0.01, iterations=1000, vtol=0) L1_ode_phi = ODE(env, lvalue=S.sympify('diff(phi(t))'), rvalue=S.sympify(v2), ttol=0.01, iterations=1000, vtol=0) #define location init value L1_FT = False L2_End_FT = False #define location function # The computations in L1 # Returning state, delta, value, loc1_FT, loc2_FT def L1(x, y, theta, phi, L1_FT, L2_End_FT, prev_time): curr_time = env.now vals = { S.sympify('x(t)'): x, S.sympify('y(t)'): y, S.sympify('theta(t)'): theta, S.sympify('phi(t)'): phi } # the edge guard take preference if ((y >= 1.8 and x <= 2.8) or (y <= 0.8 and x <= 2.8)): print('%s %7.4f:%7.4f:%7.4f:%7.4f:%7.4f' % ('L1-1', curr_time, x, y, theta, phi)) L2_End_FT = True L1_FT = None return 1, 0, x, y, theta, phi, L1_FT, L2_End_FT, curr_time elif not ((y >= 1.8 and x <= 2.8) or (y <= 0.8 and x <= 2.8)): if not L1_FT: x = L1_ode_x.compute(vals, curr_time - prev_time) y = L1_ode_y.compute(vals, curr_time - prev_time) theta = L1_ode_theta.compute(vals, curr_time - prev_time) phi = L1_ode_phi.compute(vals, curr_time - prev_time) L1_FT = True #else: L1_FT = False print('%s %7.4f:%7.4f:%7.4f:%7.4f:%7.4f' % ('L1-2', curr_time, x, y, theta, phi)) #set a Maximum value for delta dy, dx = 9999999, 9999999 if abs(x - 2.8) > L1_ode_x.vtol: dx = min( L1_ode_x.delta( vals, quanta=(2.8 - x), other_odes=[L1_ode_y, L1_ode_theta, L1_ode_phi]), dx) else: x = 2.8 dx = 0 if abs(y - 0.8) > L1_ode_y.vtol: dy = min( L1_ode_y.delta( vals, quanta=(0.8 - y), other_odes=[L1_ode_x, L1_ode_theta, L1_ode_phi]), dy) else: y = 0.8 dy = 0 if abs(y - 1.8) > L1_ode_y.vtol: dy = min( L1_ode_y.delta( vals, quanta=(1.8 - y), other_odes=[L1_ode_x, L1_ode_theta, L1_ode_phi]), dy) else: y = 1.8 dy = 0 Return_Delta = min(99999, dy, dx) return 0, Return_Delta, x, y, theta, phi, L1_FT, L2_End_FT, curr_time else: raise RuntimeError('Reached unreachable branch' ' in L1') # Location End is end state in this example. def L2_End(x, y, theta, phi, L1_FT, L2_End_FT, prev_time): global step print('total steps: ', step) # Done sys.exit(1) # The dictionary for the switch statement. switch_case = {0: L1, 1: L2_End} prev_time = env.now while (True): (cstate, delta, x, y, theta, phi, L1_FT, L2_End_FT, prev_time) = switch_case[cstate](x, y, theta, phi, L1_FT, L2_End_FT, prev_time) # This should always be the final statement in this function global step step += 1 yield env.timeout(delta)
def NoName(env, cstate=0): delta = None # None to cause failure #define constants #define continuous variables used in this ha x = 20 #define location equations LOC2_ode_x = ODE(env, lvalue=S.sympify('diff(x(t))'), rvalue=S.sympify(-0.25 * S.sympify('x(t)') + 125), ttol=10**-3, iterations=100, vtol=0) Loc1_ode_x = ODE(env, lvalue=S.sympify('diff(x(t))'), rvalue=S.sympify((-0.25) * S.sympify('x(t)')), ttol=10**-3, iterations=100, vtol=0) #define location init value Loc1_FT = False LOC2_FT = False #define location function # The computations in Loc1 # Returning state, delta, value, loc1_FT, loc2_FT def Loc1(x, Loc1_FT, LOC2_FT, prev_time): curr_time = env.now vals = {S.sympify('x(t)'): x} # the edge guard take preference if x <= 18.5: print('%s %7.4f:%7.4f' % ('Loc1-1', curr_time, x)) LOC2_FT = True Loc1_FT = None return 1, 0, x, Loc1_FT, LOC2_FT, curr_time elif x >= 18.5: if not Loc1_FT: x = Loc1_ode_x.compute(vals, curr_time - prev_time) Loc1_FT = True #else: Loc1_FT = False print('%s %7.4f:%7.4f' % ('Loc1-2', curr_time, x)) #set a Maximum value for delta dx = 9999999 if abs(x - 18.5) > Loc1_ode_x.vtol: dx = min( Loc1_ode_x.delta(vals, quanta=(18.5 - x), other_odes=[]), dx) else: x = 18.5 dx = 0 Return_Delta = min(99999, dx) return 0, Return_Delta, x, Loc1_FT, LOC2_FT, curr_time else: raise RuntimeError('Reached unreachable branch' ' in Loc1') # The computations in LOC2 # Returning state, delta, value, loc1_FT, loc2_FT def LOC2(x, Loc1_FT, LOC2_FT, prev_time): curr_time = env.now vals = {S.sympify('x(t)'): x} # the edge guard take preference if x >= 19.5: print('%s %7.4f:%7.4f' % ('LOC2-1', curr_time, x)) Loc1_FT = True LOC2_FT = None return 0, 0, x, Loc1_FT, LOC2_FT, curr_time elif x <= 19.5: if not LOC2_FT: x = LOC2_ode_x.compute(vals, curr_time - prev_time) LOC2_FT = True #else: LOC2_FT = False print('%s %7.4f:%7.4f' % ('LOC2-2', curr_time, x)) #set a Maximum value for delta dx = 9999999 if abs(x - 19.5) > LOC2_ode_x.vtol: dx = min( LOC2_ode_x.delta(vals, quanta=(19.5 - x), other_odes=[]), dx) else: x = 19.5 dx = 0 Return_Delta = min(99999, dx) return 1, Return_Delta, x, Loc1_FT, LOC2_FT, curr_time else: raise RuntimeError('Reached unreachable branch' ' in LOC2') # The dictionary for the switch statement. switch_case = {0: Loc1, 1: LOC2} prev_time = env.now while (True): (cstate, delta, x, Loc1_FT, LOC2_FT, prev_time) = switch_case[cstate](x, Loc1_FT, LOC2_FT, prev_time) # This should always be the final statement in this function global step step += 1 yield env.timeout(delta)
def ha(env, cstate=0): """This is the ha itself. This is very similar to the 'C' code that we generate from the haskell model, except that the whole thing is event drive. """ delta = None # None to cause failure # Some constants K1 = 0.1 K2 = -4 # The continous variables used in this ha th = 5*math.pi/2 # The initial value y = 0 loc1_ode_y = ODE(env, S.sympify('diff(y(t))'), rvalue=S.sympify(K1), iterations=1000) loc1_ode_th = ODE(env, S.sympify('diff(th(t))'), rvalue=S.sympify('exp(y(t))'), iterations=1000, vtol=10**-6) loc2_ode_th = ODE(env, S.sympify('diff(th(t))'), rvalue=S.sympify(K2), iterations=1000, vtol=10**-6) loc1_FT = False loc2_FT = False # XXX: DEBUG # print(loc1_ode, loc2_ode) # The computations in location1 # Returning state, delta, value, loc1_FT, loc2_FT def location1(th, y, loc1_FT, loc2_FT, prev_time): curr_time = env.now vals = {S.sympify('th(t)'): th, S.sympify('y(t)'): y} # TODO: Try to remove this later on # Currently, cos(th(t)) <= V, does not work gvals = {S.sympify('th'): S.sympify(th), S.sympify('y'): S.sympify(y)} # The edge guard takes preference g1 = S.sympify('cos(th) <= -0.99') gth = None # XXX: This should all be generated by the compiler if g1.is_Relational: if ((len(g1.args[0].args) == 1) and (g1.args[1].is_Number) and (g1.args[0].func in ODE.TRANSCEDENTAL_FUNCS)): gth = min(S.solve(g1.args[0]-g1.args[1])) # DEBUG # print(g1, ':', gth, 'normalize_theta: ', normalize_theta(th)) else: raise RuntimeError("Don't know how to handle this guard: ", g1) pass else: raise RuntimeError('Guards can only be relations: ', g1) if (g1.subs(gvals)): # print('%7.4f: %7.4f %7.4f' % (curr_time, th, y)) return 1, 0, th, y, None, True, curr_time # The location invariant elif (True): # Compute the th and y values and print them. if not loc1_FT: th = loc1_ode_th.compute(vals, curr_time-prev_time) y = loc1_ode_y.compute(vals, curr_time-prev_time) loc1_FT = True # print('%7.4f: %7.4f %7.4f' % (curr_time, th, y)) dth = 0, 0 # Here 3.2 should be obtained by solving the guard condition if abs(normalize_theta(th)-gth) > loc1_ode_th.vtol: dth = loc1_ode_th.delta(vals, quanta=(gth-normalize_theta(th)), other_odes=[loc1_ode_y]) else: # This means we have found the level crossing th = gth + (th - normalize_theta(th)) dth = 0 return 0, dth, th, y, False, None, curr_time else: raise RuntimeError('Reached unreachable branch' ' in location1') # Location 2 is end state in this example. def location2(th, y, loc1_FT, loc2_FT, prev_time): curr_time = env.now vals = {S.sympify('th(t)'): th} # TODO: Try to remove this later on # Currently, cos(th(t)) <= V, does not work gvals = {S.sympify('th'): S.sympify(th)} # The edge guard takes preference g1 = S.sympify('cos(th) >= 0.99') gth = None # XXX: This should all be generated by the compiler if g1.is_Relational: if ((len(g1.args[0].args) == 1) and (g1.args[1].is_Number) and (g1.args[0].func in ODE.TRANSCEDENTAL_FUNCS)): gth = min(S.solve(g1.args[0]-g1.args[1])) # DEBUG # print(g1, ':', gth, 'normalize_theta: ', normalize_theta(th)) else: raise RuntimeError("Don't know how to handle this guard: ", g1) pass else: raise RuntimeError('Guards can only be relations: ', g1) if (g1.subs(gvals)): # print('%7.4f: %7.4f' % (curr_time, th)) return 0, 0, th, 0, True, None, curr_time # The location invariant elif (True): # Compute the th value and print it. if not loc2_FT: th = loc2_ode_th.compute(vals, curr_time-prev_time) loc2_FT = True # print('%7.4f: %7.4f' % (curr_time, th)) # TODO: FIXTHIS dth = 0 if abs(normalize_theta(th)-gth) > loc2_ode_th.vtol: dth = loc2_ode_th.delta(vals, quanta=(gth-normalize_theta(th)), other_odes=[]) else: # This means we have found the level crossing # FIXME: This needs to be checked properly! th = gth + (th - normalize_theta(th)) dth = 0 return 1, dth, th, y, None, False, curr_time else: raise RuntimeError('Reached unreachable branch' ' in location2') # The dictionary for the switch statement. switch_case = { 0: location1, 1: location2 } prev_time = env.now while(True): (cstate, delta, th, y, loc1_FT, loc2_FT, prev_time) = switch_case[cstate](th, y, loc1_FT, loc2_FT, prev_time) # This should always be the final statement in this function global step step += 1 yield env.timeout(delta)
import math import numpy as np from src.ivp import IVP from src.ode import ODE from src.results import ResultsComparator from src.solver import ForwardEulerSolver from src.solver import BackwardEulerSolver g = lambda u, t: np.array([t**2 - 4*t - 1]) de = ODE(g) u_0 = np.array([0]) t_0 = 0 step = 0.0001 precision = 4 t_n = 10 problem = IVP(de, u_0, t_0) forward_slv = ForwardEulerSolver(problem, t_n, step, precision) forward_slv.solve() backward_slv = BackwardEulerSolver(problem, t_n, step, precision) backward_slv.solve()
def ha(env, cstate=0): """This is the ha itself. This is very similar to the 'C' code that we generate from the haskell model, except that the whole thing is event drive. """ delta = None # None to cause failure # The continous variables used in this ha x = 2 # The initial value loc1_ode = ODE(env, lvalue=S.sympify('diff(x(t))'), rvalue=S.sympify('sin(cos(x(t)))+2'), ttol=10**-3, iterations=100) loc2_ode = ODE(env, S.sympify('diff(x(t))'), S.sympify('-2*x(t)'), ttol=10**-3, iterations=100) loc1_FT = False loc2_FT = False # XXX: DEBUG # print(loc1_ode, loc2_ode) # The computations in location1 # Returning state, delta, value, loc1_FT, loc2_FT def location1(x, loc1_FT, loc2_FT, prev_time): curr_time = env.now # The edge guard takes preference if x >= 5: print('%7.4f %7.4f' % (curr_time, x)) # import sys # sys.exit(1) return 1, 0, x, None, True, curr_time # The invariant elif x <= 5: # Compute the x value and print it. if not loc1_FT: x = loc1_ode.compute({S.sympify('x(t)'): x}, curr_time-prev_time) loc1_FT = True print('%7.7f %7.7f' % (curr_time, x)) # XXX: Call the ODE class that will give the delta back iff # the calculated "x" is greater than the error. if abs(x-5) > loc1_ode.vtol: delta = loc1_ode.delta({S.sympify('x(t)'): x}, quanta=(5-x)) else: # If within the error bound just make it 10 x = 5 delta = 0 return 0, delta, x, False, None, curr_time else: raise RuntimeError('Reached unreachable branch' ' in location1') # The computations in location2 def location2(x, loc1_FT, loc2_FT, prev_time): curr_time = env.now if x <= 1: print('%7.7f %7.7f' % (curr_time, x)) return 0, 0, x, True, None, curr_time elif x >= 1: # TODO: Call the ODE class to get delta if not loc2_FT: x = loc2_ode.compute({S.sympify('x(t)'): x}, curr_time-prev_time) print('%7.7f %7.7f' % (curr_time, x)) # If the output is outside the error margin then bother # recomputing a new delta. if abs(x-1) > loc2_ode.vtol: delta = loc2_ode.delta({S.sympify('x(t)'): x}, quanta=(1 - x)) else: # If within error bound then just make it the level. x = 1 delta = 0 return 1, delta, x, None, False, curr_time else: raise RuntimeError('Reached unreachable branch' ' in location2') # The dictionary for the switch statement. switch_case = { 0: location1, 1: location2 } prev_time = env.now while(True): (cstate, delta, x, loc1_FT, loc2_FT, prev_time) = switch_case[cstate](x, loc1_FT, loc2_FT, prev_time) # This should always be the final statement in this function yield env.timeout(delta)
def ha(env, cstate=0): """This is the ha itself. This is very similar to the 'C' code that we generate from the haskell model, except that the whole thing is event drive. """ delta = None # None to cause failure # The constants EPI_TVP = 1.4506 EPI_TV1M = 60.0 EPI_TV2M = 1150.0 EPI_TWP = 200.0 EPI_TW1M = 60.0 EPI_TW2M = 15.0 EPI_TS1 = 2.7342 EPI_TS2 = 16.0 EPI_TFI = 0.11 EPI_TO2 = 6 EPI_TSO1 = 30.0181 EPI_TSO2 = 0.9957 EPI_TSI = 1.8875 EPI_TWINF = 0.07 EPI_THV = 0.3 # EPI_THVM = 0.006 # EPI_THVINF = 0.006 # EPI_THW = 0.13 # EPI_THWINF = 0.006 # EPI_THSO = 0.13 # EPI_THSI = 0.13 # EPI_THO = 0.006 EPI_KWM = 65.0 EPI_KS = 2.0994 EPI_KSO = 2.0458 EPI_UWM = 0.03 EPI_US = 0.9087 EPI_UU = 1.55 EPI_USO = 0.65 jfi1 = 0.0 jsi1 = 0.0 jfi2 = 0.0 jsi2 = 0.0 jfi3 = 0.0 stim = 1.0 # The continous variables used in this ha u = 0.0 v = 1.0 s = 0.0 w = 1.0 tau = 0.0 # This we are setting, but dReach searches in their case. EPI_TO1 = 0.007 ut = S.sympify('u(t)') vt = S.sympify('v(t)') wt = S.sympify('w(t)') st = S.sympify('s(t)') loc0_ode_tau = ODE(env, S.sympify('diff(tau(t))'), S.sympify('1.0'), ttol=10**-3, iterations=100) loc0_ode_u = ODE(env, S.sympify('diff(u(t))'), S.sympify((stim - jfi1) - ((ut / EPI_TO1) + jsi1)), ttol=10**-3, iterations=100) loc0_ode_w = ODE(env, S.sympify('diff(w(t))'), S.sympify(((1.0 - (ut / EPI_TWINF) - wt) / (EPI_TW1M + (EPI_TW2M - EPI_TW1M) * (1.0 / (1 + S.exp(-2 * EPI_KWM * (ut - EPI_UWM))))))), ttol=10**-3, iterations=100) loc0_ode_v = ODE(env, S.sympify('diff(v(t))'), S.sympify(((1.0 - vt) / EPI_TV1M)), ttol=10**-3, iterations=100) loc0_ode_s = ODE(env, S.sympify('diff(s(t))'), S.sympify( (((1 / (1 + S.exp(-2 * EPI_KS * (ut - EPI_US)))) - st) / EPI_TS1)), ttol=10**-3, iterations=100) loc0_FT = False loc1_ode_tau = ODE(env, S.sympify('diff(tau(t))'), S.sympify('1.0'), ttol=10**-3, iterations=100) loc1_ode_u = ODE(env, S.sympify('diff(u(t))'), S.sympify((stim - jfi2) - ((ut / EPI_TO2) + jsi2)), ttol=10**-3, iterations=100) loc1_ode_w = ODE(env, S.sympify('diff(w(t))'), S.sympify(((0.94 - wt) / (EPI_TW1M + (EPI_TW2M - EPI_TW1M) * (1.0 / (1 + S.exp(-2 * EPI_KWM * (ut - EPI_UWM))))))), ttol=10**-3, iterations=100) loc1_ode_v = ODE(env, S.sympify('diff(v(t))'), S.sympify((-vt / EPI_TV2M)), ttol=10**-3, iterations=100) loc1_ode_s = ODE(env, S.sympify('diff(s(t))'), S.sympify( (((1 / (1 + S.exp(-2 * EPI_KS * (ut - EPI_US)))) - st) / EPI_TS1)), ttol=10**-3, iterations=100) loc1_FT = False loc2_ode_tau = ODE(env, S.sympify('diff(tau(t))'), S.sympify('1.0'), ttol=10**-3, iterations=100) loc2_ode_u = ODE(env, S.sympify('diff(u(t))'), S.sympify((stim - jfi3) - ((1.0 / (EPI_TSO1 + ((EPI_TSO2 - EPI_TSO1) * (1 / (1 + S.exp(-2 * EPI_KSO * (ut - EPI_USO))))))) + (0 - (wt * st) / EPI_TSI))), ttol=10**-3, iterations=100, simplify_poly=True) loc2_ode_w = ODE(env, S.sympify('diff(w(t))'), S.sympify((-wt / EPI_TWP)), ttol=10**-3, iterations=100, simplify_poly=True) loc2_ode_v = ODE(env, S.sympify('diff(v(t))'), S.sympify((-vt / EPI_TV2M)), ttol=10**-3, iterations=100) loc2_ode_s = ODE(env, S.sympify('diff(s(t))'), S.sympify( (((1 / (1 + S.exp(-2 * EPI_KS * (ut - EPI_US)))) - st) / EPI_TS2)), ttol=10**-3, iterations=100, simplify_poly=True) loc2_FT = False loc3_ode_tau = ODE(env, S.sympify('diff(tau(t))'), S.sympify('1.0'), ttol=10**-3, iterations=100) loc3_ode_u = ODE(env, S.sympify('diff(u(t))'), S.sympify((stim - (0 - vt * (ut - EPI_THV) * (EPI_UU - ut) / EPI_TFI)) - ((1.0 / (EPI_TSO1 + ((EPI_TSO2 - EPI_TSO1) * (1 / (1 + S.exp(-2 * EPI_KSO * (ut - EPI_USO))))))) + (0 - (wt * st) / EPI_TSI))), ttol=10**-3, iterations=100, simplify_poly=True) loc3_ode_w = ODE(env, S.sympify('diff(w(t))'), S.sympify((-wt / EPI_TWP)), ttol=10**-3, iterations=100) loc3_ode_v = ODE(env, S.sympify('diff(v(t))'), S.sympify((-vt / EPI_TVP)), ttol=10**-3, iterations=100) loc3_ode_s = ODE(env, S.sympify('diff(s(t))'), S.sympify( (((1 / (1 + S.exp(-2 * EPI_KS * (ut - EPI_US)))) - st) / EPI_TS2)), ttol=10**-3, iterations=100, simplify_poly=True) loc3_FT = False # Location 0 def location0(u, v, w, s, tau, loc0_FT, loc1_FT, loc2_FT, loc3_FT, prev_time): curr_time = env.now vals = { S.sympify('u(t)'): u, S.sympify('v(t)'): v, S.sympify('w(t)'): w, S.sympify('s(t)'): s, S.sympify('tau(t)'): tau } # The edge guard takes preference if u >= 0.006: print('%7.4f: %7.4f %7.4f %7.4f %7.4f %7.4f' % (curr_time, u, v, w, s, tau)) return 1, 0, u, v, w, s, tau, None, True, None, None, curr_time # The invariant elif u <= 0.006: if not loc0_FT: u = loc0_ode_u.compute(vals, curr_time - prev_time) v = loc0_ode_v.compute(vals, curr_time - prev_time) w = loc0_ode_w.compute(vals, curr_time - prev_time) s = loc0_ode_s.compute(vals, curr_time - prev_time) tau = loc0_ode_tau.compute(vals, curr_time - prev_time) loc0_FT = True print('%7.4f: %7.4f %7.4f %7.4f %7.4f %7.4f' % (curr_time, u, v, w, s, tau)) if abs(u - 0.006) > loc0_ode_u.vtol: delta = loc0_ode_u.delta(vals, quanta=(0.006 - u), other_odes=[ loc0_ode_s, loc0_ode_v, loc0_ode_w, loc0_ode_tau ]) else: u = 0.006 delta = 0 return (0, delta, u, v, w, s, tau, False, None, None, None, curr_time) else: raise RuntimeError('Reached unreachable branch' ' in location 0') def location1(u, v, w, s, tau, loc0_FT, loc1_FT, loc2_FT, loc3_FT, prev_time): curr_time = env.now vals = { S.sympify('u(t)'): u, S.sympify('v(t)'): v, S.sympify('w(t)'): w, S.sympify('s(t)'): s, S.sympify('tau(t)'): tau } # The edge guard takes preference if u >= 0.013: print('%7.4f: %7.4f %7.4f %7.4f %7.4f %7.4f' % (curr_time, u, v, w, s, tau)) return 2, 0, u, v, w, s, tau, None, True, None, None, curr_time # The invariant elif u <= 0.013: if not loc1_FT: u = loc1_ode_u.compute(vals, curr_time - prev_time) v = loc1_ode_v.compute(vals, curr_time - prev_time) w = loc1_ode_w.compute(vals, curr_time - prev_time) s = loc1_ode_s.compute(vals, curr_time - prev_time) tau = loc1_ode_tau.compute(vals, curr_time - prev_time) loc1_FT = True print('%7.4f: %7.4f %7.4f %7.4f %7.4f %7.4f' % (curr_time, u, v, w, s, tau)) if abs(u - 0.013) > loc1_ode_u.vtol: delta = loc1_ode_u.delta(vals, quanta=(0.013 - u), other_odes=[ loc1_ode_s, loc1_ode_v, loc1_ode_w, loc1_ode_tau ]) else: u = 0.013 delta = 0 return (1, delta, u, v, w, s, tau, False, None, None, None, curr_time) else: raise RuntimeError('Reached unreachable branch' ' in location 1') def location2(u, v, w, s, tau, loc0_FT, loc1_FT, loc2_FT, loc3_FT, prev_time): curr_time = env.now vals = { S.sympify('u(t)'): u, S.sympify('v(t)'): v, S.sympify('w(t)'): w, S.sympify('s(t)'): s, S.sympify('tau(t)'): tau } # The edge guard takes preference if u >= 0.3: print('%7.4f: %7.4f %7.4f %7.4f %7.4f %7.4f' % (curr_time, u, v, w, s, tau)) return 3, 0, u, v, w, s, tau, None, True, None, None, curr_time # The invariant elif u <= 0.3: if not loc2_FT: u = loc2_ode_u.compute(vals, curr_time - prev_time) v = loc2_ode_v.compute(vals, curr_time - prev_time) w = loc2_ode_w.compute(vals, curr_time - prev_time) s = loc2_ode_s.compute(vals, curr_time - prev_time) tau = loc2_ode_tau.compute(vals, curr_time - prev_time) loc2_FT = True print('%7.4f: %7.4f %7.4f %7.4f %7.4f %7.4f' % (curr_time, u, v, w, s, tau)) if abs(u - 0.3) > loc2_ode_u.vtol: delta = loc2_ode_u.delta(vals, quanta=(0.3 - u), other_odes=[ loc2_ode_s, loc2_ode_v, loc2_ode_w, loc2_ode_tau ]) else: u = 0.3 delta = 0 return (2, delta, u, v, w, s, tau, False, None, None, None, curr_time) else: raise RuntimeError('Reached unreachable branch' ' in location 2') def location3(u, v, w, s, tau, loc0_FT, loc1_FT, loc2_FT, loc3_FT, prev_time): curr_time = env.now vals = { S.sympify('u(t)'): u, S.sympify('v(t)'): v, S.sympify('w(t)'): w, S.sympify('s(t)'): s, S.sympify('tau(t)'): tau } # The edge guard takes preference if u >= 2.0: print('%7.4f: %7.4f %7.4f %7.4f %7.4f %7.4f' % (curr_time, u, v, w, s, tau)) return 3, 0, u, v, w, s, tau, None, True, None, None, curr_time # The invariant elif u <= 2.0: if not loc3_FT: u = loc3_ode_u.compute(vals, curr_time - prev_time) v = loc3_ode_v.compute(vals, curr_time - prev_time) w = loc3_ode_w.compute(vals, curr_time - prev_time) s = loc3_ode_s.compute(vals, curr_time - prev_time) tau = loc3_ode_tau.compute(vals, curr_time - prev_time) loc3_FT = True print('%7.4f: %7.4f %7.4f %7.4f %7.4f %7.4f' % (curr_time, u, v, w, s, tau)) if abs(u - 2.0) > loc3_ode_u.vtol: delta = loc3_ode_u.delta(vals, quanta=(2.0 - u), other_odes=[ loc3_ode_s, loc3_ode_v, loc3_ode_w, loc3_ode_tau ]) else: u = 2.0 delta = 0 return (3, delta, u, v, w, s, tau, False, None, None, None, curr_time) else: raise RuntimeError('Reached unreachable branch' ' in location 3') # The dictionary for the switch statement. switch_case = {0: location0, 1: location1, 2: location2, 3: location3} prev_time = env.now while (True): (cstate, delta, u, v, w, s, tau, loc0_FT, loc1_FT, loc2_FT, loc3_FT, prev_time) = switch_case[cstate](u, v, w, s, tau, loc0_FT, loc1_FT, loc2_FT, loc3_FT, prev_time) # This should always be the final statement in this function global step step += 1 yield env.timeout(delta)
def NoName(env, cstate=0): delta = None # None to cause failure #define constants T1 = 10 T2 = 10 thM = 20 thm = 5 v1 = -1.3 v2 = -2.7 vr = 10.5 #define continuous variables used in this ha theta = 11.5 x = T1 y = T2 #define location equations Loc0_ode_x = ODE(env, lvalue=S.sympify('diff(x(t))'), rvalue=S.sympify('1.00000000000000'), ttol=10**-3, iterations=100, vtol=10**-10) Loc0_ode_y = ODE(env, lvalue=S.sympify('diff(y(t))'), rvalue=S.sympify('1.00000000000000'), ttol=10**-3, iterations=100, vtol=10**-10) Loc0_ode_theta = ODE(env, lvalue=S.sympify('diff(theta(t))'), rvalue=S.sympify(vr), ttol=10**-3, iterations=100, vtol=10**-10) Loc1_ode_x = ODE(env, lvalue=S.sympify('diff(x(t))'), rvalue=S.sympify('1.00000000000000'), ttol=10**-3, iterations=100, vtol=10**-10) Loc1_ode_y = ODE(env, lvalue=S.sympify('diff(y(t))'), rvalue=S.sympify('1.00000000000000'), ttol=10**-3, iterations=100, vtol=10**-10) Loc1_ode_theta = ODE(env, lvalue=S.sympify('diff(theta(t))'), rvalue=S.sympify(v1), ttol=10**-3, iterations=100, vtol=10**-10) Loc2_ode_x = ODE(env, lvalue=S.sympify('diff(x(t))'), rvalue=S.sympify('1.00000000000000'), ttol=10**-3, iterations=100, vtol=10**-10) Loc2_ode_y = ODE(env, lvalue=S.sympify('diff(y(t))'), rvalue=S.sympify('1.00000000000000'), ttol=10**-3, iterations=100, vtol=10**-10) Loc2_ode_theta = ODE(env, lvalue=S.sympify('diff(theta(t))'), rvalue=S.sympify(v2), ttol=10**-3, iterations=100, vtol=10**-10) #define location init value Loc0_FT = False Loc1_FT = False Loc2_FT = False Loc3_FT = False #define location function # The computations in Loc0 # Returning state, delta, value, loc1_FT, loc2_FT def Loc0(x, y, theta, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, prev_time): curr_time = env.now vals = { S.sympify('x(t)'): x, S.sympify('y(t)'): y, S.sympify('theta(t)'): theta } # the edge guard take preference if theta == thM and x < T1 and y < T2: print('%s %7.4f:%7.4f:%7.4f:%7.4f' % ('Loc0-1', curr_time, x, y, theta)) Loc3_FT = True Loc0_FT = None return 3, 0, x, y, theta, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, curr_time elif theta == thM and x >= T1: print('%s %7.4f:%7.4f:%7.4f:%7.4f' % ('Loc0-1', curr_time, x, y, theta)) Loc1_FT = True Loc0_FT = None return 1, 0, x, y, theta, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, curr_time elif theta == thM and y >= T2: print('%s %7.4f:%7.4f:%7.4f:%7.4f' % ('Loc0-1', curr_time, x, y, theta)) Loc2_FT = True Loc0_FT = None return 2, 0, x, y, theta, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, curr_time elif theta <= thM: if not Loc0_FT: x = Loc0_ode_x.compute(vals, curr_time - prev_time) y = Loc0_ode_y.compute(vals, curr_time - prev_time) theta = Loc0_ode_theta.compute(vals, curr_time - prev_time) Loc0_FT = True #else: Loc0_FT = False print('%s %7.4f:%7.4f:%7.4f:%7.4f' % ('Loc0-2', curr_time, x, y, theta)) #set a Maximum value for delta dtheta = 9999999 if abs(theta - thM) > Loc0_ode_theta.vtol: dtheta = min( Loc0_ode_theta.delta(vals, quanta=(thM - theta), other_odes=[Loc0_ode_x, Loc0_ode_y]), dtheta) else: theta = thM dtheta = 0 Return_Delta = min(99999, dtheta) return 0, Return_Delta, x, y, theta, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, curr_time else: raise RuntimeError('Reached unreachable branch' ' in Loc0') # The computations in Loc1 # Returning state, delta, value, loc1_FT, loc2_FT def Loc1(x, y, theta, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, prev_time): curr_time = env.now vals = { S.sympify('x(t)'): x, S.sympify('y(t)'): y, S.sympify('theta(t)'): theta } # the edge guard take preference if theta == thm: x = 0 print('%s %7.4f:%7.4f:%7.4f:%7.4f' % ('Loc1-1', curr_time, x, y, theta)) Loc0_FT = True Loc1_FT = None return 0, 0, x, y, theta, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, curr_time elif theta >= thm: if not Loc1_FT: x = Loc1_ode_x.compute(vals, curr_time - prev_time) y = Loc1_ode_y.compute(vals, curr_time - prev_time) theta = Loc1_ode_theta.compute(vals, curr_time - prev_time) Loc1_FT = True #else: Loc1_FT = False print('%s %7.4f:%7.4f:%7.4f:%7.4f' % ('Loc1-2', curr_time, x, y, theta)) #set a Maximum value for delta dtheta = 9999999 if abs(theta - thm) > Loc1_ode_theta.vtol: dtheta = min( Loc1_ode_theta.delta(vals, quanta=(thm - theta), other_odes=[Loc1_ode_x, Loc1_ode_y]), dtheta) else: theta = thm dtheta = 0 Return_Delta = min(99999, dtheta) return 1, Return_Delta, x, y, theta, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, curr_time else: raise RuntimeError('Reached unreachable branch' ' in Loc1') # The computations in Loc2 # Returning state, delta, value, loc1_FT, loc2_FT def Loc2(x, y, theta, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, prev_time): curr_time = env.now vals = { S.sympify('x(t)'): x, S.sympify('y(t)'): y, S.sympify('theta(t)'): theta } # the edge guard take preference if theta == thm: y = 0 print('%s %7.4f:%7.4f:%7.4f:%7.4f' % ('Loc2-1', curr_time, x, y, theta)) Loc0_FT = True Loc2_FT = None return 0, 0, x, y, theta, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, curr_time elif theta >= thm: if not Loc2_FT: x = Loc2_ode_x.compute(vals, curr_time - prev_time) y = Loc2_ode_y.compute(vals, curr_time - prev_time) theta = Loc2_ode_theta.compute(vals, curr_time - prev_time) Loc2_FT = True #else: Loc2_FT = False print('%s %7.4f:%7.4f:%7.4f:%7.4f' % ('Loc2-2', curr_time, x, y, theta)) #set a Maximum value for delta dtheta = 9999999 if abs(theta - thm) > Loc2_ode_theta.vtol: dtheta = min( Loc2_ode_theta.delta(vals, quanta=(thm - theta), other_odes=[Loc2_ode_x, Loc2_ode_y]), dtheta) else: theta = thm dtheta = 0 Return_Delta = min(99999, dtheta) return 2, Return_Delta, x, y, theta, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, curr_time else: raise RuntimeError('Reached unreachable branch' ' in Loc2') # Location End is end state in this example. def Loc3(x, y, theta, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, prev_time): global step print('total steps: ', step) # Done sys.exit(1) # The dictionary for the switch statement. switch_case = {0: Loc0, 1: Loc1, 2: Loc2, 3: Loc3} prev_time = env.now while (True): (cstate, delta, x, y, theta, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, prev_time) = switch_case[cstate](x, y, theta, Loc0_FT, Loc1_FT, Loc2_FT, Loc3_FT, prev_time) # This should always be the final statement in this function global step step += 1 yield env.timeout(delta)
def ha(env, cstate=0): """This is the ha itself. This is very similar to the 'C' code that we generate from the haskell model, except that the whole thing is event drive. """ T1 = 10 T2 = 10 thM = 20 thm = 5 vr = 10.5 v1 = -1.3 v2 = -2.7 assert(T1 == T2) delta = None # None to cause failure # The continous variables used in this ha x = T1 # clock1 variable y = T2 # clock2 variable th = 11.5 # The reactor temperature # You need vtol here, because of floating point error. loc0_ode_x = ODE(env, S.sympify('diff(x(t))'), S.sympify('1.0'), ttol=10**-3, iterations=100) loc0_ode_y = ODE(env, S.sympify('diff(y(t))'), S.sympify('1.0'), ttol=10**-3, iterations=100) loc0_ode_th = ODE(env, S.sympify('diff(th(t))'), S.sympify(vr), ttol=10**-3, iterations=100, vtol=10**-10) loc0_FT = False loc1_ode_x = ODE(env, S.sympify('diff(x(t))'), S.sympify('1.0'), ttol=10**-3, iterations=100) loc1_ode_y = ODE(env, S.sympify('diff(y(t))'), S.sympify('1.0'), ttol=10**-3, iterations=100) loc1_ode_th = ODE(env, S.sympify('diff(th(t))'), S.sympify(v1), ttol=10**-3, iterations=100, vtol=10**-10) loc1_FT = False loc2_ode_x = ODE(env, S.sympify('diff(x(t))'), S.sympify('1.0'), ttol=10**-3, iterations=100) loc2_ode_y = ODE(env, S.sympify('diff(y(t))'), S.sympify('1.0'), ttol=10**-3, iterations=100) loc2_ode_th = ODE(env, S.sympify('diff(th(t))'), S.sympify(v2), ttol=10**-3, iterations=100, vtol=10**-10) loc2_FT = False # Location 3 is reactor shutdown loc3_FT = False # Location 0 def location0(x, y, th, loc0_FT, loc1_FT, loc2_FT, loc3_FT, prev_time): vals = {S.sympify('x(t)'): x, S.sympify('y(t)'): y, S.sympify('th(t)'): th} curr_time = env.now # The edge guard takes preference if th == thM and x >= T1: # print('%7.4f %7.4f %7.4f %7.4f' % (curr_time, x, y, th)) return 1, 0, x, y, th, None, True, None, None, curr_time elif th == thM and y >= T2: # print('%7.4f %7.4f %7.4f %7.4f' % (curr_time, x, y, th)) return 2, 0, x, y, th, None, None, True, None, curr_time elif th == thM and x < T1 and y < T2: # print('%7.4f %7.4f %7.4f %7.4f' % (curr_time, x, y, th)) return 3, 0, x, y, th, None, None, None, True, curr_time # The invariant elif th <= thM: if not loc0_FT: x = loc0_ode_x.compute(vals, curr_time-prev_time) y = loc0_ode_y.compute(vals, curr_time-prev_time) th = loc0_ode_th.compute(vals, curr_time-prev_time) loc0_FT = True # print('%7.4f %7.4f %7.4f %7.4f' % (curr_time, x, y, th)) if abs(th-thM) > loc0_ode_th.vtol: deltath = loc0_ode_th.delta(vals, quanta=(thM-th)) else: th = thM deltath = 0 return 0, deltath, x, y, th, False, None, None, None, curr_time else: # print('th:', th) raise RuntimeError('Reached unreachable branch' ' in location 0') def location1(x, y, th, loc0_FT, loc1_FT, loc2_FT, loc3_FT, prev_time): vals = {S.sympify('x(t)'): x, S.sympify('y(t)'): y, S.sympify('th(t)'): th} curr_time = env.now # The edge guard takes preference if th == thm: x = 0 # Reset # print('%7.4f %7.4f %7.4f %7.4f' % (curr_time, x, y, th)) return 0, 0, x, y, th, True, None, None, None, curr_time # The invariant elif th >= thm: if not loc1_FT: x = loc1_ode_x.compute(vals, curr_time-prev_time) y = loc1_ode_y.compute(vals, curr_time-prev_time) th = loc1_ode_th.compute(vals, curr_time-prev_time) loc1_FT = True # print('%7.4f %7.4f %7.4f %7.4f' % (curr_time, x, y, th)) if abs(th-thm) > loc1_ode_th.vtol: deltath = loc1_ode_th.delta(vals, quanta=(thm-th)) else: th = thm deltath = 0 return 1, deltath, x, y, th, False, None, None, None, curr_time else: raise RuntimeError('Reached unreachable branch' ' in location 1') def location2(x, y, th, loc0_FT, loc1_FT, loc2_FT, loc3_FT, prev_time): vals = {S.sympify('x(t)'): x, S.sympify('y(t)'): y, S.sympify('th(t)'): th} curr_time = env.now # The edge guard takes preference if th == thm: y = 0 # Reset # print('%7.4f %7.4f %7.4f %7.4f' % (curr_time, x, y, th)) return 0, 0, x, y, th, True, None, None, None, curr_time # The invariant elif th >= thm: if not loc2_FT: x = loc2_ode_x.compute(vals, curr_time-prev_time) y = loc2_ode_y.compute(vals, curr_time-prev_time) th = loc2_ode_th.compute(vals, curr_time-prev_time) loc2_FT = True # print('%7.4f %7.4f %7.4f %7.4f' % (curr_time, x, y, th)) if abs(th-thm) > loc2_ode_th.vtol: deltath = loc2_ode_th.delta(vals, quanta=(thm-th)) else: th = thm deltath = 0 return 2, deltath, x, y, th, False, None, None, None, curr_time else: raise RuntimeError('Reached unreachable branch' ' in location 2') def location3(x, y, th, loc0_FT, loc1_FT, loc2_FT, loc3_FT, prev_time): global step # print('total steps: ', step) # Done print(time.time()-start) sys.exit(1) # The dictionary for the switch statement. switch_case = { 0: location0, 1: location1, 2: location2, 3: location3 } prev_time = env.now while(True): (cstate, delta, x, y, th, loc0_FT, loc1_FT, loc2_FT, loc3_FT, prev_time) = switch_case[cstate](x, y, th, loc0_FT, loc1_FT, loc2_FT, loc3_FT, prev_time) # This should always be the final statement in this function global step step += 1 yield env.timeout(delta)
def HA1(env, cstate=0): delta = None # None to cause failure #define constants v2 = -10 v3 = 10 le = 1 v1 = 30 v4 = 5 #define continuous variables used in this ha y = 1 x = 0 theta = 0 phi = 1 #define location equations L2_ode_x = ODE(env, lvalue=S.sympify('diff(x(t))'), rvalue=S.sympify(v3 * S.sympify('cos(theta(t))')), ttol=0.01, iterations=1000) L2_ode_y = ODE(env, lvalue=S.sympify('diff(y(t))'), rvalue=S.sympify(v3 * S.sympify('sin(theta(t))')), ttol=0.01, iterations=1000) L2_ode_theta = ODE(env, lvalue=S.sympify('diff(theta(t))'), rvalue=S.sympify(v3 * S.sympify( (S.sympify('tan(phi(t))') / le))), ttol=0.01, iterations=1000) L2_ode_phi = ODE(env, lvalue=S.sympify('diff(phi(t))'), rvalue=S.sympify('v4'), ttol=0.01, iterations=1000) Initial0_ode_x = ODE(env, lvalue=S.sympify('diff(x(t))'), rvalue=S.sympify(v1 * S.sympify('cos(theta(t))')), ttol=0.01, iterations=1000) Initial0_ode_y = ODE(env, lvalue=S.sympify('diff(y(t))'), rvalue=S.sympify(v1 * S.sympify('sin(theta(t))')), ttol=0.01, iterations=1000) Initial0_ode_theta = ODE(env, lvalue=S.sympify('diff(theta(t))'), rvalue=S.sympify(v1 * S.sympify( (S.sympify('tan(phi(t))') / le))), ttol=0.01, iterations=1000) Initial0_ode_phi = ODE(env, lvalue=S.sympify('diff(phi(t))'), rvalue=S.sympify('v2'), ttol=0.01, iterations=1000) #define location init value L2_FT = False LocationEnd_FT = False Initial0_FT = True #define location function # The computations in Initial0 # Returning state, delta, value, loc1_FT, loc2_FT def Initial0(y, x, theta, phi, L2_FT, LocationEnd_FT, Initial0_FT, prev_time): curr_time = env.now vals = { S.sympify('y(t)'): y, S.sympify('x(t)'): x, S.sympify('theta(t)'): theta, S.sympify('phi(t)'): phi } # the edge guard take preference if (((y >= 0.8) and (x >= 3.2)) or ((y <= -0.4) and (x <= 2.8))): print('%7.4f:%7.4f:%7.4f:%7.4f:%7.4f' % (curr_time, y, x, theta, phi)) L2_FT = True Initial0_FT = None return 1, 0, y, x, theta, phi, L2_FT, LocationEnd_FT, Initial0_FT, curr_time if x > 3: print('%7.4f:%7.4f:%7.4f:%7.4f:%7.4f' % (curr_time, y, x, theta, phi)) LocationEnd_FT = True Initial0_FT = None return 2, 0, y, x, theta, phi, L2_FT, LocationEnd_FT, Initial0_FT, curr_time elif not (((y >= 0.8) and (x >= 3.2)) or ((y <= -0.4) and (x <= 2.8))): if not Initial0_FT: y = Initial0_ode_y.compute(vals, curr_time - prev_time) x = Initial0_ode_x.compute(vals, curr_time - prev_time) theta = Initial0_ode_theta.compute(vals, curr_time - prev_time) phi = Initial0_ode_phi.compute(vals, curr_time - prev_time) Initial0_FT = True print('%7.4f:%7.4f:%7.4f:%7.4f:%7.4f' % (curr_time, y, x, theta, phi)) #set a Maximum value for delta dx, dy = 9999999, 9999999 if abs(x - 2.8) > Initial0_ode_x.vtol: dx = min( Initial0_ode_x.delta(vals, quanta=(2.8 - x), other_odes=[ Initial0_ode_y, Initial0_ode_theta, Initial0_ode_phi ]), dx) else: x = 2.8 dx = 0 if abs(y - 0.8) > Initial0_ode_y.vtol: dy = min( Initial0_ode_y.delta(vals, quanta=(0.8 - y), other_odes=[ Initial0_ode_x, Initial0_ode_theta, Initial0_ode_phi ]), dy) else: y = 0.8 dy = 0 if abs(y - 1.8) > Initial0_ode_y.vtol: dy = min( Initial0_ode_y.delta(vals, quanta=(1.8 - y), other_odes=[ Initial0_ode_x, Initial0_ode_theta, Initial0_ode_phi ]), dy) else: y = 1.8 dy = 0 Return_Delta = min(99999, dx, dy) return 0, Return_Delta, y, x, theta, phi, L2_FT, LocationEnd_FT, Initial0_FT, curr_time else: raise RuntimeError('Reached unreachable branch' ' in Initial0') # The computations in L2 # Returning state, delta, value, loc1_FT, loc2_FT def L2(y, x, theta, phi, L2_FT, LocationEnd_FT, Initial0_FT, prev_time): curr_time = env.now vals = { S.sympify('y(t)'): y, S.sympify('x(t)'): x, S.sympify('theta(t)'): theta, S.sympify('phi(t)'): phi } # the edge guard take preference if not (((y >= 0.8) and (x >= 3.2)) or ((y <= -0.4) and (x <= 2.8))): print('%7.4f:%7.4f:%7.4f:%7.4f:%7.4f' % (curr_time, y, x, theta, phi)) Initial0_FT = True L2_FT = None return 0, 0, y, x, theta, phi, L2_FT, LocationEnd_FT, Initial0_FT, curr_time if x > 3: print('%7.4f:%7.4f:%7.4f:%7.4f:%7.4f' % (curr_time, y, x, theta, phi)) LocationEnd_FT = True L2_FT = None return 2, 0, y, x, theta, phi, L2_FT, LocationEnd_FT, Initial0_FT, curr_time elif (((y >= 0.8) and (x >= 3.2)) or ((y <= -0.4) and (x <= 2.8))): if not L2_FT: y = L2_ode_y.compute(vals, curr_time - prev_time) x = L2_ode_x.compute(vals, curr_time - prev_time) theta = L2_ode_theta.compute(vals, curr_time - prev_time) phi = L2_ode_phi.compute(vals, curr_time - prev_time) L2_FT = True print('%7.4f:%7.4f:%7.4f:%7.4f:%7.4f' % (curr_time, y, x, theta, phi)) #set a Maximum value for delta Return_Delta = min(99999, 0) return 1, Return_Delta, y, x, theta, phi, L2_FT, LocationEnd_FT, Initial0_FT, curr_time else: raise RuntimeError('Reached unreachable branch' ' in L2') # Location End is end state in this example. def LocationEnd(y, x, theta, phi, L2_FT, LocationEnd_FT, Initial0_FT, prev_time): global step print('total steps: ', step) # Done sys.exit(1) # The dictionary for the switch statement. switch_case = {1: L2, 2: LocationEnd, 0: Initial0} prev_time = env.now while (True): (cstate, delta, y, x, theta, phi, L2_FT, LocationEnd_FT, Initial0_FT, prev_time) = switch_case[cstate](y, x, theta, phi, L2_FT, LocationEnd_FT, Initial0_FT, prev_time) # This should always be the final statement in this function global step step += 1 yield env.timeout(delta)