【发布时间】:2020-05-31 17:19:07
【问题描述】:
我有以下功能来模拟生化系统随着时间的推移。代码背后的想法是对时间步进行采样,然后将它们添加到当前时间。
我有一个全局定义的开始时间:tao = 0.0
以及以下功能:
def gillespie_tau_leaping(propensity_calc, popul_num, popul_num_all, tao_all, rxn_vector, tao, epsi):
t = simulation_timer()
t.start()
while tao < tmax:
evaluate_propensity = propensity_calc(LHS, popul_num, stoch_rate)
a0 = (sum(propensity)) # a0 is a numpy.float64
if a0 == 0.0:
break
if popul_num.any() < 0: # This isnt working
print("Number of molecules {} is too small for reaction to fire".format(popul_num))
break
# code equation 26 here!
for x in range(len(popul_num)):
# equation 22:
expctd_net_change = a0*state_change_array[x]
# equation 24:
part_diff = derivative(evaluate_propensity, popul_num[x])
# find the partial derivative of propensity with respect to popul_num (number of discrete molecules)
# need to find a a way to SELECT delta_t before I can code it!
# equation 26:
t_step = epsi*a0 / sum(expctd_net_change*part_diff)
delta_t = optimize.fmin(t_step, 0.00012)
print (delta_t)
lam = (evaluate_propensity*delta_t)
rxn_vector = np.random.poisson(lam) # probability of a reaction firing in the given time period
if tao + delta_t > tmax:
break
tao = tao + delta_t
leap_counter = tao / delta_t
if tao >= 2/a0: # if tao is big enough
for j in range(len(rxn_vector)):
state_change_lambda = np.squeeze(np.asarray(state_change_array[j])*rxn_vector[j])
#new_propensity = evaluate_propensity
propensity_check = evaluate_propensity.copy()
propensity_check[0] += state_change_lambda[0]
propensity_check[1:] += state_change_lambda
for n in range(len(propensity_check)):
if propensity_check[n] - evaluate_propensity[n] >= epsi*a0:
print("The value of delta_t {} choosen is too large".format(delta_t))
break
else:
popul_num = popul_num + state_change_lambda
popul_num_all.append(popul_num)
tao_all.append(tao)
else:
t = np.random.exponential(1/a0)
rxn_probability = evaluate_propensity / a0
num_rxn = np.arange(rxn_probability.size)
if tao + t > tmax:
tao = tmax
break
j = stats.rv_discrete(values=(num_rxn, rxn_probability)).rvs()
tao = tao + t
popul_num = popul_num + np.squeeze(np.asarray(state_change_array[j]))
popul_num_all.append(popul_num)
tao_all.append(tao)
print("tao:\n", tao)
print("Molecule numbers:\n", popul_num)
print("Number of leaps taken:\n", leap_counter)
t.stop()
return popul_num_all.append(popul_num), tao_all.append(tao)
print(gillespie_tau_leaping(propensity_calc, popul_num, popul_num_all, tao_all, rxn_vector, tao, epsi))
只有我得到错误:UnboundLocalError: local variable 'leap_counter' referenced before assignment
尝试打印或返回模拟期间所用的时间步数时,保存在变量 jump_counter 中,我不知道为什么。我试图稍微改变缩进,但这不起作用。发生了什么事,我该如何解决?
编辑:以下代码指定全局环境中 delta_t 的值。我试图在上面更新它,所以我在每次迭代中计算 delta_t 的值。但后来我遇到了跳跃计数器的问题。
def gillespie_tau_leaping(propensity_calc, popul_num, popul_num_all, tao_all, rxn_vector, tao, delta_t, epsi):
t = simulation_timer()
t.start()
while tao < tmax:
propensity = propensity_calc(LHS, popul_num, stoch_rate)
print("propensity:\n", type(propensity))
a0 = (sum(propensity))
if a0 == 0.0:
break
# if reaction cannot fire corresponding element in rxn_vector should be zero --> tau leaping method
if popul_num.any() < 0:
print("Number of molecules {} is too small for reaction to fire".format(popul_num))
break
lam = (propensity_calc(LHS, popul_num, stoch_rate)*delta_t)
rxn_vector = np.random.poisson(lam)
if tao + delta_t > tmax:
break
tao += delta_t
print("tao:\n", tao)
print("Molecule numbers:\n", popul_num)
# divide tao by delta_t to calculate number of leaps
leap_counter = tao / delta_t
if tao >= 2/a0:
for j in range(len(rxn_vector)):
state_change_lambda = np.squeeze(np.asarray(state_change_array[j])*rxn_vector[j])
popul_num = popul_num + state_change_lambda
new_propensity = propensity_calc(LHS, popul_num, stoch_rate)
for n in range(len(new_propensity)):
propensity_check = propensity + state_change_lambda
if propensity_check[n] - new_propensity[n] >= epsi*a0:
print("The value of delta_t {} choosen is too large".format(delta_t))
break
else:
popul_num = popul_num + state_change_lambda
popul_num_all.append(popul_num)
tao_all.append(tao)
else:
next_t = np.random.exponential(1/a0)
rxn_probability = propensity / a0
num_rxn = np.arange(rxn_probability.size)
if tao + next_t > tmax:
tao = tmax
break
j = stats.rv_discrete(values=(num_rxn, rxn_probability)).rvs()
tao = tao + next_t
popul_num = popul_num + np.squeeze(np.asarray(state_change_array[j]))
t.stop()
return popul_num_all.append(popul_num), tao_all.append(tao), leap_counter
这段代码完全按照我的意愿工作,我无法理解的是第一个函数突然不了
干杯
【问题讨论】:
-
请修正您的代码缩进。
-
leap_counter = tao / delta_t之前的任何行都可能中止您的循环,如果您的循环甚至进入了?你确定tao < tmax? -
是 tmax = 5.0 和 tao = 到 0.0,都全局设置
-
您没有考虑所有路径和错误情况。执行 0 次的
while或for怎么样?还是提前退出循环的中断?例如if popul_num.any() < 0: break... 然后你就不用处理了。 -
请提供一个最小的、可重现的例子。有多个提前中断条件,我们不能排除您的函数被输入来触发这些条件。有关详细信息,请参阅How to Ask 页面。请注意,与描述相反,
tao是一个局部变量。您是否有理由尝试访问leap_counter,即使它可能尚未设置?
标签: python scope variable-declaration