包含关键字/lambda 函数的动态字典
Dynamic dictionary including keywords/ lambda function
我有一组约束,我必须在 scipy 的优化中以特定方式输入这些约束。格式如下所示
cons = ({'type' : 'eq', 'fun': lambda x: sum(x) - 1.},
{'type' : 'ineq', 'fun': lambda x: bounds(x)},
{'type' : 'ineq', 'fun': lambda x: -1*bounds(x) + 0.1})
bounds 是一个计算点积的函数。无需过多介绍,我必须在运行时手动创建字典的 cons 元组。我现在的问题是,如果它包含关键字,我如何连接/连接键和值,例如 "lambda"?
我知道如何通过字符串调用函数
def install():
print "In install"
methods = {'install': install}
method_name = 'install'
if method_name in methods:
methods[method_name]()
但是我无法理解如何让 condict 工作。
谢谢
使用您当前的结构,您可以使用此代码:
for c in cons:
if c['type'] == type:
fun = c['fun']
fun(x)
其中 type
和 x
是您的参数。
你需要写一个函数,returns一个函数。例如:
def constraint_maker(delta):
def _(x):
return -1*bounds(x) + delta
return _
cons = ({'type' : 'ineq', 'fun': constraint_maker(0.1)},
{'type' : 'ineq', 'fun': constraint_maker(0.2)},
{'type' : 'ineq', 'fun': constraint_maker(0.3)})
名为_
的函数(名字随意,可以是任何名字)是一个闭包; delta
在其主体中的值由您传递给 constraint_maker
.
的参数确定
注意不能写成
cons = []
for d in [0.1, 0.2, 0.3]:
cons += {'type': 'ineq', 'fun': lambda x: -1*bounds(x) + d}
因为您的 lambda
表达式没有创建闭包;名称 d
只是一个自由变量,其值在最终调用时查找,与计算 lambda
表达式时 d
的值无关。当您在另一个函数中定义一个函数时,就会创建闭包。你可以把它写成
cons = []
for d in [0.1, 0.2, 0.3]:
cons += {'type': 'ineq', 'fun': lambda x, d=d: -1*bounds(x) + d}
因为现在 lambda
正文中的 d
不是自由变量;它是一个局部变量(具体来说,一个参数),其默认值取自循环中同名的变量。这有点丑陋,即使不考虑两个具有相同名称(但不同范围)的变量的混淆,因为现在你的函数有 2 个参数,尽管第二个参数永远不会被显式使用。
如果我没有正确理解你的问题,你想将两个函数合二为一,例如如果你这样做:
{'type': 'eq', 'fun': lambda x: x + 1} + {'type': 'ineq', 'fun': lambda x: x + 2}
您想获得:
{'type': 'eqineq', 'fun': lambda x: x + 1 + x + 2}
如果是这种情况,请尝试以下操作:
class FunctionSum(object):
def __init__(self, f1, f2):
self.f1 = f1
self.f2 = f2
def __call__(self, x):
return self.f1(x) + self.f2(x)
class ConstDict(dict):
def __add__(self, other):
_ = {}
for k, v in self.items():
if hasattr(v, '__call__'):
_[k] = FunctionSum(self[k], other[k])
else:
_[k] = self[k] + other[k]
return _
const = [ConstDict({'type': 'eq', 'fun': lambda x: x + 1}),
ConstDict({'type': 'ineq', 'fun': lambda x: x + 2})]
print (const[0] + const[1])['fun'](1)
我有一组约束,我必须在 scipy 的优化中以特定方式输入这些约束。格式如下所示
cons = ({'type' : 'eq', 'fun': lambda x: sum(x) - 1.},
{'type' : 'ineq', 'fun': lambda x: bounds(x)},
{'type' : 'ineq', 'fun': lambda x: -1*bounds(x) + 0.1})
bounds 是一个计算点积的函数。无需过多介绍,我必须在运行时手动创建字典的 cons 元组。我现在的问题是,如果它包含关键字,我如何连接/连接键和值,例如 "lambda"?
我知道如何通过字符串调用函数
def install():
print "In install"
methods = {'install': install}
method_name = 'install'
if method_name in methods:
methods[method_name]()
但是我无法理解如何让 condict 工作。 谢谢
使用您当前的结构,您可以使用此代码:
for c in cons:
if c['type'] == type:
fun = c['fun']
fun(x)
其中 type
和 x
是您的参数。
你需要写一个函数,returns一个函数。例如:
def constraint_maker(delta):
def _(x):
return -1*bounds(x) + delta
return _
cons = ({'type' : 'ineq', 'fun': constraint_maker(0.1)},
{'type' : 'ineq', 'fun': constraint_maker(0.2)},
{'type' : 'ineq', 'fun': constraint_maker(0.3)})
名为_
的函数(名字随意,可以是任何名字)是一个闭包; delta
在其主体中的值由您传递给 constraint_maker
.
注意不能写成
cons = []
for d in [0.1, 0.2, 0.3]:
cons += {'type': 'ineq', 'fun': lambda x: -1*bounds(x) + d}
因为您的 lambda
表达式没有创建闭包;名称 d
只是一个自由变量,其值在最终调用时查找,与计算 lambda
表达式时 d
的值无关。当您在另一个函数中定义一个函数时,就会创建闭包。你可以把它写成
cons = []
for d in [0.1, 0.2, 0.3]:
cons += {'type': 'ineq', 'fun': lambda x, d=d: -1*bounds(x) + d}
因为现在 lambda
正文中的 d
不是自由变量;它是一个局部变量(具体来说,一个参数),其默认值取自循环中同名的变量。这有点丑陋,即使不考虑两个具有相同名称(但不同范围)的变量的混淆,因为现在你的函数有 2 个参数,尽管第二个参数永远不会被显式使用。
如果我没有正确理解你的问题,你想将两个函数合二为一,例如如果你这样做:
{'type': 'eq', 'fun': lambda x: x + 1} + {'type': 'ineq', 'fun': lambda x: x + 2}
您想获得:
{'type': 'eqineq', 'fun': lambda x: x + 1 + x + 2}
如果是这种情况,请尝试以下操作:
class FunctionSum(object):
def __init__(self, f1, f2):
self.f1 = f1
self.f2 = f2
def __call__(self, x):
return self.f1(x) + self.f2(x)
class ConstDict(dict):
def __add__(self, other):
_ = {}
for k, v in self.items():
if hasattr(v, '__call__'):
_[k] = FunctionSum(self[k], other[k])
else:
_[k] = self[k] + other[k]
return _
const = [ConstDict({'type': 'eq', 'fun': lambda x: x + 1}),
ConstDict({'type': 'ineq', 'fun': lambda x: x + 2})]
print (const[0] + const[1])['fun'](1)