मैं अजगर (एनाकोंडा) पर LMFIT का उपयोग करके एक वक्र फिटिंग प्रोग्राम बनाने की कोशिश कर रहा हूं, लेकिन मुझे एक ही त्रुटि संदेश प्राप्त होता रहता है: TypeError: केवल size-1 सरणियों को पायथन स्केलर्स में बदला जा सकता है। मैं केवल एक फ़ंक्शन का उपयोग करके एक अनुकूलन करने में सक्षम था, लेकिन जब मैं किसी ऐसे फ़ंक्शन को अनुकूलित करने का प्रयास करता हूं जो अन्य उपयोगकर्ता-परिभाषित कार्यों को कॉल करता है, तो मुझे यह त्रुटि मिलती है।

import numpy as np
from matplotlib import pyplot
import scipy.special as sp
from scipy import integrate
import lmfit as lm


#Defining the first function.
def function1(alpha,q,s,l):

    Intensity = alpha**2 + q -s*alpha / (5*l)
    return Intensity

#Defining a second function that will perform a integration over the first function.
def integrate_function(q,s,l):
    func_parameters = {
        'q':q,
        's':s,
        'l':l,
    }
    to_be_integrated = lambda alpha: function1(alpha, **func_parameters)
    result, error = integrate.quad(to_be_integrated, 0, 10)
    return result

#Setting up the LMFIT model. Here I also provide the initial guess for the parameters.
integrate_function_model = lm.Model(integrate_function, independent_vars=['q'])
integrate_function_model.set_param_hint('s', value=2, min=-10.0, max=20.0, vary=True)
integrate_function_model.set_param_hint('l', value=3, min=1.0, max=10.0, vary=True)
initial_params = integrate_function_model.make_params()

#Creating data to be fitted (I also add some noise)
#Here I set s=1.5 and l=5.0 and I want the optimization routine to be able to find out these numbers.
x_data = np.linspace(0, 10, 100)
y_data = np.zeros(len(x_data))
for i in range(len(x_data)):
    y_data[i] = integrate_function(x_data[i],1.5,5.0)  + 5.0*np.random.random()


#Fitting the data.
fitting = integrate_function_model.fit(y_data, initial_params, q=x_data, method='leastsq')

#Printing original data and fitted model.
pyplot.plot(x_data, y_data, color='green', lw=2)
pyplot.plot(x_data, fitting.best_fit, color='blue', lw=2)
pyplot.show()
3
Rafael Freire 2 अक्टूबर 2018, 16:22

1 उत्तर

सबसे बढ़िया उत्तर

त्रुटि तब होती है जब आपके फ़ंक्शन integrate_function को np.array के साथ q के तर्क के रूप में कॉल किया जाता है:

>>> integrate_function(1,1,1)
333.33333333333337
>>> integrate_function(np.array([1,2]),1,1)
TypeError: only size-1 arrays can be converted to Python scalars

यह output.fit के दौरान होता है जहां integrate.quad कहा जाता है। quad वेक्टरकृत इनपुट को संभालने में सक्षम नहीं है, जो आपके मामले में हो रहा है।

इसे ठीक करने का एक विकल्प integrate_function को उस मामले को संभालने के लिए बदलना होगा जहां q तदनुसार एक सरणी है, उदाहरण के लिए q में सभी मानों पर मैन्युअल रूप से लूप शामिल करना:

def integrate_function(q,s,l):
    # Make q iterable if it is only a float/int
    if not hasattr(q, '__iter__'):
        q = np.array([q])

    result = []
    for q0 in q: 
        func_parameters = {
        'q':q0,
        's':s,
        'l':l,
    }
        to_be_integrated = lambda alpha: function1(alpha, **func_parameters)
        result.append(integrate.quad(to_be_integrated, 0, 10)[0])
    return np.array(result)

अपने कोड को संशोधित integrate_function के साथ निष्पादित करने पर निम्नलिखित प्लॉट प्राप्त होता है:

enter image description here

3
jdamp 2 अक्टूबर 2018, 14:39