2016-11-01 2 views
0

Я хотел бы сохранить синтаксис в самом общем виде, давая iminuit его параметры с помощью *:питон ошибка атрибут iminuit

import iminuit 
import numpy as np 

x_data = np.array([0,1,2,3,4,5,6,7,8,9]) 
y_data = np.array([0,1,2,3,4,5,4,3,2,1]) 

def fit_function(x, *p): 
    return p[0]*np.exp(-((x-p[1])**2/(2*p[2]**2))) 

def minimize_me(*p): 
    return sum((fit_function(x, *p) - y)**2 for x, y in zip(x_data, y_data)) 

p=[4.5, 5, 0.4] 
print(minimize_me(*p)) # works! --> gives: 57.1645229329 

m = iminuit.Minuit(minimize_me, *p) 
m.migrad() # fails! 

с ошибкой:

AttributeError: 'float' object has no attribute 'print_banner' 

Любые идеи, что Я делать не так? Благодарю.

p.s. этот экзамен основан на этой должности СО: https://stackoverflow.com/a/22540079/5177935

ответ

1

В чем проблема?

Вы вызываете Minuit Инициализатора так:

p = [4.5, 5, 0.4] 
Minuit(minimize_me, *p) 

, которое эквивалентно следующему:

Minuit(minimize_me, 4.5, 5, 0.4) 

т.е. в Python звездные результаты в argument list unpacking, в этом случае прохождения поплавков в качестве позиционных аргументов для параметров, которые не должны плавать:

Minuit(fcn=minimize_me, throw_nan=4.5, pedantic=5, frontend=0.4) 

Неверное неправильное обращение к Minuit() и сообщение об ошибке. В настоящее время это не так, потому что в инициализаторе нет входной проверки. Благодарим за сообщение об этом https://github.com/iminuit/iminuit/issues/189.

Как это сделать?

В вашем случае вам не нужны имена параметров. Но Minuit должен иметь имя для каждого параметра. Это часть внутренней структуры данных и используется, например, для представления результатов подгонки.

Вот общий способ справиться с этим:

p_vals = [4.5, 5, 0.4] 
p_names = ['par_{}'.format(_) for _ in range(len(p_vals))] 

m = iminuit.Minuit(
    fcn=minimize_me, 
    forced_parameters=p_names, 
    **dict(zip(p_names, p_vals)) 
) 
print(m.parameters) 
m.migrad() # works! 
Смежные вопросы