2011-10-28 51 views
2

我正在做一些數據擬合使用pyminuit Python綁定的minuit最小化代碼(http://code.google.com/p/pyminuit/)。最小化器接受一個函數並使用內省來提取要最小化的參數。一般來說,我想將給定特定函數的數據集的卡方值最小化以描述數據集。如何爲任意函數定義chi2值函數?

我的問題:有沒有一種方法來定義一個卡方函數,給出的參數不同數量的任意函數,返回一個函數,它給出了卡方值,該功能只包含的參數是在函數參數說明中最小化?

例子:

from scipy import * 
import minuit 
# Generate some data to fit 
data_x = arange(50) 
noise = 0.3 
data_y = data_x**3 + normal(0.0, noise) 
# Fit function, e.g. a cubic 
fit_func = lambda x, a1, a2, a3, a4: a1 + a2*x + a3*x**2 + a4*x**3 

# Minimisation function e.g. chi squared 
# Note this has only the parameters to be minimised in the definition (eg not data_x) 
min_func = lambda a1, a2, a3, a4: sum((fit_func(data_x, a1, a2, a3, a4) - data_y)**2/noise**2) 

這是我想寫點東西像min_func = make_chi2(fit_func)。我不知道該怎麼辦,因爲data_xdata_y只在函數的外部定義。爲了完整性,其餘的最小化程序看起來像:

# Initialise minimiser object with initial values 
m = minuit.Minuit(min_func, {'a1': 1.0, 'a2': 1.0, 'a3': 1.0, 'a4': 1.0}) 
# Run minimiser 
m.migrad() 
# Print minimised values - example output 
print m.values 
>>> {'a1': 0.000, 'a2': 0.000, 'a3': 0.000, 'a4': 1.000} 

感謝您的幫助提前!

+0

我會打電話的事實,pyminuit只能通過內省提取參數和不允許明確地命名它們是pyminuit方面至少有問題的設計。他們是否允許明確給出這些參數,你的問題將是微不足道的解決。 –

回答

1

由於PyMinuit使用自省,所以也必須使用自省。 make_chi_squared()可以實現這樣的:

import inspect 

chi_squared_template = """ 
def chi_squared(%(params)s): 
    return (((f(data_x, %(params)s) - data_y)/errors) ** 2).sum() 
""" 

def make_chi_squared(f, data_x, data_y, errors): 
    params = ", ".join(inspect.getargspec(f).args[1:]) 
    exec chi_squared_template % {"params": params} 
    return chi_squared 

用法示例:

import numpy 

def f(x, a1, a2, a3, a4): 
    return a1 + a2*x + a3*x**2 + a4*x**3 

data_x = numpy.arange(50) 
errors = numpy.random.randn(50) * 0.3 
data_y = data_x**3 + errors 

chi_squared = make_chi_squared(f, data_x, data_y, errors) 
print inspect.getargspec(chi_squared).args 

印刷

['a1', 'a2', 'a3', 'a4'] 
+0

我寫過這樣的東西,但是這更簡潔明瞭。謝謝! – almailer