gpt4 book ai didi

python - Lambda 函数不返回正确的值

转载 作者:行者123 更新时间:2023-11-28 16:21:20 25 4
gpt4 key购买 nike

我正在尝试制作 Gillespie 算法的变体,并确定 react 倾向 我正在尝试使用 lambda 表达式自动生成倾向向量。但是,在创建 SSA.P 时,一切都出错了。代码块中的最后一个循环 PROPLOOP 返回两种倾向,其中使用 P_alternative 生成​​的倾向是正确的。问题是:如何为 SSA.P 获得与 SSA.P_alternative 相同的值?

import numpy as np
from numpy.random import uniform
class Markov:
def __init__(self,z0,t0,tf,rates,stoich):
self.S=stoich

self.z0=z0
self.rates=rates

self.P=self.propensities()
self.P_alternative=[
lambda z,rate:(0.5*rate[0]*z[0]*(z[0]-1)),
lambda z,rate:rate[1]*np.prod(z[0]),
lambda z,rate:rate[2]*np.prod(z[1]),
lambda z,rate:rate[3]*np.prod(z[1]),
lambda z,rate:rate[4]*np.prod(z[np.array([0,1])]),
lambda z,rate:rate[5]]

self.t0=t0
self.tf=tf


def propensities(self):
prop=[]
for i,reac in enumerate(self.S.T):
if all(z>=0 for z in reac):
prop.append(lambda z,rate:rate[i])

if any(z==-1 for z in reac):
j=np.where(reac==-1)[0]
prop.append(lambda z,rate:rate[i]*np.prod(z[j]))

if any(z==-2 for z in reac):
j=np.where(reac==-2)[0][0]
prop.append(lambda z,rate:(0.5*rate[i]*z[j]*(z[j]-1))[0])

return prop


stoich=np.array([
[-2, -1, 2, 0, -1, 0],
[ 1, 0, -1, -1, -1, 1],
[ 0, 0, 0, 1, 1, 0]])

rates=np.array([1.0,0.02,200.0,0.0004,0.9,0.9])

z0=np.array([540,730,0])

SSA=Markov(z0=z0,t0=0,tf=100,rates=rates,stoich=stoich)

#PROPLOOP; the values should be equal for both SSA.P and SSA.P_alternative, where SSA.P_alternative is the correct one
for i in xrange(len(SSA.P)):
print "Inexplicably wrong",SSA.P[i](z0,rates)
print "Correct answer",SSA.P_alternative[i](z0,rates), "\n"

输出是:

Inexplicably wrong 130977.0
Correct answer 145530.0

Inexplicably wrong 354780.0
Correct answer 10.8

Inexplicably wrong 354780.0
Correct answer 146000.0

Inexplicably wrong 354780.0
Correct answer 0.292

Correct answer 354780.0
Correct answer 354780.0

Inexplicably wrong 0.9
Correct answer 0.9

最佳答案

问题是您在循环中创建 lambda 函数,它们引用变量 ij 可能随着循环的进行而改变。

lambda 在创建时不会复制 ij 的值,它只是保留对定义它们的 namespace 的引用。当它稍后调用时使用变量,它会在该命名空间中查找它们。由于您的 lambda 在循环(实际上是整个函数)结束后被调用,它们都看到了变量被赋予的最终值,这不是您想要的。这解释了为什么您的代码的两个版本在最后一次迭代中给出相同的输出。 ij 的最终值是最后一个 lambda 函数的预期值。

您可以通过让 lambda 在定义时保留 ij 的当前值的副本来解决这个问题。最简单的方法是使用默认参数:

for i,reac in enumerate(self.S.T):
if all(z>=0 for z in reac):
prop.append(lambda z, rate, i=i: rate[i]) # add i=i here and further down

if any(z==-1 for z in reac):
j=np.where(reac==-1)[0]
prop.append(lambda z, rate, i=i, j=j: rate[i]*np.prod(z[j]))

if any(z==-2 for z in reac):
j=np.where(reac==-2)[0][0]
prop.append(lambda z, rate, i=i, j=j: (0.5*rate[i]*z[j]*(z[j]-1))[0])

lambda 定义中的 i=i(和必要时的 j=j)使 lambda 函数的变量参数具有默认值,即当前值外部命名空间中的 i(和 j)。由于调用 lambda 函数时只传递两个参数,因此将使用保存的默认值。

关于python - Lambda 函数不返回正确的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40096323/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com