cerv21
cerv21

Reputation: 433

Model and parameters in symfit package via loop

I would like to add more and more model equation and thus also parameters via a loop. I tried it, but so far it only led to errors.

x, y_1, y_2 = variables('x, y_1, y_2')
a = Parameter('a', min=0.0)
b = Parameter('b')
d = Parameter('d')

c_1, c_2 = parameters('c_1, c_2')
#a, b, c_1, c_2, d = parameters('a, b, c_1, c_2, d')

if 1: 
    model = Model({
        y_1: a * exp(-x) + c_1 + b * x/(x**2 + d**2),
        y_2: a * exp(-x) + c_2 + b * x/(x**2 + (d - 1)**2),
    })

Ideally, I would like to have something like this, but so far I only got errors:

for i in range(1, 6): 
    equations[f'y_{i+2}'] = a * exp(-x) + parameters(f'c_{i+2}') + b * x / (x**2 + (d - i)**2)

model = Model(equations)

Any ideas? Or is there another python package which supports a loop on a Model?

Edit:

# Create variables
x = variables('x')
ys = variables(','.join(f'y_{i}' for i in range(1, 3)))

# Create parameters
a = Parameter('a', min=0.0)
b, d = parameters('b, d')
cs = parameters(','.join(f'c_{i}' for i in range(1, 3)))

# Create model dictionary
model_dict = {
    y: a * exp(-2 * 0.3 * x) + c + b * x/(x**2 + d**2)
    for y, c in zip(ys, cs)
}

This code for example gives the following error:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[41], line 18
     15 cs = parameters(','.join(f'c_{i}' for i in range(1, 3)))
     17 # Create model dictionary
---> 18 model_dict = {
     19     y: a * exp(-2 * 0.3 * x) + c + b * x/(x**2 + d**2)
     20     for y, c in zip(ys, cs)
     21 }
     23 xdata = np.arange(0,1256,pixel_size_nm)
     25 ydata = [ima0_avg.data[i, :] for i in range(2, len(ima0_avg.data))]

Cell In[41], line 19, in <dictcomp>(.0)
     15 cs = parameters(','.join(f'c_{i}' for i in range(1, 3)))
     17 # Create model dictionary
     18 model_dict = {
---> 19     y: a * exp(-2* 0.3 * x) + c + b * x/(x**2 + d**2)
     20     for y, c in zip(ys, cs)
     21 }
     23 xdata = np.arange(0,1256,pixel_size_nm)
     25 ydata = [ima0_avg.data[i, :] for i in range(2, len(ima0_avg.data))]

TypeError: can't multiply sequence by non-int of type 'float'

Upvotes: 0

Views: 54

Answers (1)

Tarik
Tarik

Reputation: 11209

x is defined as a tuple. Unpacking the tuple fixes the problem:

from symfit import parameters, variables, Parameter, exp

# Create variables
(x,) = variables('x')
ys = variables(' '.join(f'y_{i}' for i in range(1, 3)))

# Create parameters
a = Parameter('a', min=0.0)
b, d = parameters('b, d')
cs = parameters(','.join(f'c_{i}' for i in range(1, 3)))

# Create model dictionary
model_dict = {
    y: a * exp(-2 * 0.3 * x) + c + b * x/(x**2 + d**2)
    for y, c in zip(ys, cs)
}

Upvotes: 0

Related Questions