xplodnow
xplodnow

Reputation: 257

Scipy Curve_fit. Separate bounds for multiple parameters

I am using Scipy to fit my data to a function. The function give me values for 2 parameters, in this case a and b. I want to use the bound argument to limit the values these parameters can take, each have their own range of acceptable values.

Acceptable values: 15< a <50 and 0.05< b <0.2

I want to know how to implement them. The official documentation only shows how to do them for 1 parameter. This question is similiar to: Python curve fit library that allows me to assign bounds to parameters. Which also only tackles boundaries for 1 parameter.

Here is what i tried:

def Ebfit(x,a,b):
    Eb_mean = a*(0.0256/kt)                         # Eb at bake temperature
    Eb_sigma = b*Eb_mean
    Foursigma =  4*Eb_sigma
    Eb_a = np.linspace(Eb_mean-Foursigma,Eb_mean+Foursigma,N_Device)
    dEb = Eb_a[1] - Eb_a[0]
    pdfEb_a = spys.norm.pdf(Eb_a,Eb_mean,Eb_sigma)

    ## Retention Time

    DMom = np.zeros(len(x),float)
    tau = (1/f0)*np.exp(Eb_a)
    for bb in range(len(x)):
        DMom[bb]= (1 - 2*(sum(pdfEb_a*(1 - np.exp(np.divide(-x[bb],tau))))*dEb))
    return DMom

time = datafile['time'][0:501]
Moment = datafile['25Oe'][0:501]

params,extras = curve_fit(Ebfit,time,Moment, p0=[20,0.1], bounds=[(15,50),(0.05,0.2)])

I have also tried the following variations to see if the parenthesis was the issue:

 params,extras = curve_fit(Ebfit,time,Moment, p0=[20,0.1], bounds=[[15,50],[0.02,0.2]])
 params,extras = curve_fit(Ebfit,time,Moment, p0=[20,0.1], bounds=((15,50),(0.02,0.2)))

But I get the same error for all of these variations

ValueError: Each lower bound mush be strictly less than each upper bound.

It only works with a single bound such as:

params,extras = curve_fit(Ebfit,time,Moment, p0=[20,0.1], bounds=[0,50])

Any help is appreciated. Thank you!

Upvotes: 5

Views: 9118

Answers (2)

xplodnow
xplodnow

Reputation: 257

As per @ev-br suggestion. I tried the following changes for the bounds argument and it worked out great.

bounds=[[15,0.02],[50,0.2]]

So in the end, the argument give should be as follows:

 bounds=[[a1,b1],[a2,b2]]

Where a1 is the lower limit for a and a2 the upper limit for a. Sames goes for b.

Upvotes: 3

ev-br
ev-br

Reputation: 26050

bounds=[[0,50],[0,0.3]]) means the second parameter is greater than 50 but smaller then 0.3. Also the first parameter is fixed at zero.

The format is bounds=(lower, upper).

Upvotes: 8

Related Questions