我参与sympy包的全部目标是获取所提供的d个变量的函数f
,评估其梯度,然后给出一个新的等式,其中1个未知变量lambda
替换为我的初始函数f
只使用单个变量lambda
得到一个等式。我的进步很有希望,但让我想要:
import simpy
# starting position
x0=(0,0)
# quadratic function provided; return sympy object
# f(x,y) = 3*x**2+x*y+y**2+x+2
f=3*x**2+x*y+y**2+x+2
# gradient of the function; return list
fgradient=[sympy.diff(f,var) for var in vars]
>> [6*x + y + 1, x + 2*y]
# stepping into algorithm
xk=x0
# evaluate the gradient at our initial point; return list
direction=[i.evalf(subs={'x':xk[0],’y’:xk[1]}) for i in fgradient]
>> [1.00000000000000, 0]
# substitute lambda in to get our next stepping direction; return list
# xk = x0 - lambda*direction
direction_lambda = [Symbol('lambda')*val for val in direction]
xk = [direction[i]-direction_lambda[i] for i in range(len(direction))]
>> [1.0*lambda, 0]
# substitute lambda into initial function component-wise; return updated sympy function
flambda = f.subs({x:xk[0], y:xk[1]})
>> -1.0*lambda + 3*(-1.0*lambda + 1.0)**2 + 3.0
因此,如果你一直遵循这一点的代码,你会看到我的flambda正好在我想要它做的地方......一个单一变量的表达式。然而,现在是事情变得时髦的地方。我想替换/评估它为lambda(作为我的自变量),并且所有标准解决方案都失败了。
flambda.evalf(subs={lambda:5})
>>TypeError: 'set' object has no attribute '__getitem__'
dflambda = flambda.diff() # works, but why cant i substitute a value?
>> 6.0*lambda - 7.0
In [285]: dflambda.evalf(subs={'lambda':5})
SympifyError: SympifyError: "could not parse u'lambda'"
答案 0 :(得分:2)
lambda
是Python中的保留字。不要将它用作变量。如果需要引用希腊字母,则通常使用lamda
。
我建议的其他变化:
subs={'x':xk[0], 'y':xk[1]}
依赖于将字符串转换为符号,不推荐使用。使用
subs={x: xk[0], y: xk[1]}
第二,
xk = [direction[i]-direction_lambda[i] for i in range(len(direction))]
在数学上看起来并不合适。你可能想在这里减去旧的xk值。
第三,evalf步骤太多了。理想情况下,最后只需要一个。保持符号化是最好的,直到它们必须成为一个数字。所以这就是我得到的。
import sympy
x0 = (0,0)
x, y, lamda = sympy.symbols('x y lamda')
f = 3*x**2+x*y+y**2+x+2
fgradient = [f.diff(var) for var in (x, y)] # calling diff as a method is convenient
xk = x0
direction = [i.subs({x: xk[0], y: xk[1]}) for i in fgradient]
xk = [xk[i] - lamda*direction[i] for i in range(len(direction))]
flamda = f.evalf(subs={x: xk[0], y: xk[1]})
但我怀疑你最终想要的是一个Python可调用计算flamda。那将是
flamda = sympy.lambdify(lamda, f.subs({x: xk[0], y: xk[1]}))
所以你可以使用flamda(0.3)
。请参阅lambdify。