防止symfit模型共享参数对象

时间:2019-03-04 17:23:16

标签: python sympy symfit

多个symfit模型实例共享具有相同名称的参数对象。我想了解这种行为的来源,目的是什么以及是否有可能停用它。

为了说明我的意思,下面是一个简单的示例:

import symfit as sf
# Create Parameters and Variables
a = sf.Parameter('a',value=0)
b = sf.Parameter('b',value=1,fixed=True)
x, y = sf.variables('x, y')

# Instanciate two models
model1=sf.Model({y:a*x+b})
model2=sf.Model({y:a*x+b})

# They are indeed not the same
id(model1) == id(model2)
>>False

# There are two parameters
print(model1.params)
>>[a,b]
print(model1.params[1].name, model1.params[1].value)
>>b 1
print(model2.params[1].name, model2.params[1].value)
>>b 1
#They are initially identical

# We want to manually modify the fixed one in only one model
model1.params[1].value = 3
# Both have changed
print(model1.params[1].name, model1.params[1].value)
>>b 3
print(model2.params[1].name, model2.params[1].value)
>>b 3
id(model1.params[1]) == id(model2.params[1])
>>True
# The parameter is the same object

我想使用不同的模型来适应多个数据流,但是要根据数据流使用不同的固定参数值。重命名模型的每个实例中的参数都可以,但是由于参数表示相同的数量,因此很难看。可以顺序处理它们并在它们之间修改参数,但是我担心步骤之间的意外交互。

PS:声誉良好的人可以创建symfit标签

吗?

1 个答案:

答案 0 :(得分:1)

很好的问题。原则上,这是因为Parameter对象是sympy.Symbol的子类,并且是其文档字符串中的子类:

Symbols are identified by name and assumptions:

>>> from sympy import Symbol
>>> Symbol("x") == Symbol("x")
True
>>> Symbol("x", real=True) == Symbol("x", real=False)
False

这是sympy内部工作的基础,因此我们在symfit中也使用了某些东西。但是,值和固定参数不被视为假设,因此不能用于区分参数。

现在,请问您有关这将如何影响拟合的问题。就像您说的那样,按顺序工作是一个很好的解决方案,并且不会产生任何副作用:

model = sf.Model({y:a*x+b})
b.fixed = True
fit_results = []

for b_value, xdata, ydata in datastream:
    b.value = b_value
    fit = Fit(model, x=xdata, y=ydata)
    fit_results.append(fit.execute())

因此,无需每次迭代都定义一个新的Parameter,每个循环内的b.value属性将是相同的,因此这不会出错。我能想象出这是错误的唯一方法是,如果您使用threading,则可能会创建一些竞争条件。但是无论如何threading对于受CPU限制的任务都是不理想的,multiprocessing是可行的方法。在那种情况下,将产生单独的过程,创建单独的缩影,因此那里也应该没有问题。

我希望这能回答您的问题,如果不让我知道。

p.s。我慢慢地回答了直到1500的问题,但如果有人击败我,我当然会更高兴的;)