1
fp.append(np.polyfit(train_x, train_y, 2))
f.append(np.poly1d(fp))
print(np.poly1d(fp))
threshold = fsolve(f, 50)

The above code finds x values for y=50 successfully. But when I try to do the same for the fitted exponential function, I can't understand how to do that.

def f_exp(x, a, b, c):
    y = a * np.exp(-b * x) + c
    return y
popt, pcov = curve_fit(f_exp, train_x, train_y)
print(popt)
threshold = fsolve(f_exp, 50) fails with  :TypeError: f_exp() missing 3 required positional arguments: 'a', 'b', and 'c'

if I add *popt then I get

threshold = fsolve(f_exp(*popt), 50) fails with: TypeError: f_exp() missing 1 required positional argument: 'c'

I assume that I need to add x value, but it's the value I'm trying to find... Anyway, adding some value instead of x, leads to another error:

threshold = fsolve(f_exp(1, *popt), 50) fails with: TypeError: 'numpy.float64' object is not callable

1 Answers1

1

I guess you need to pass f_exp function with optimized parameters to fsolve (i.e. with a, b and c args set to values obtained from curve_fit). In order to do so you can use functools.partial function:

popt, pcov = curve_fit(f_exp, train_x, train_y)
print(popt)
import functools
# preparing arguments
kwargs = dict(zip(['a', 'b', 'c'], popt))
optimized_f_exp = functools.partial(f_exp, **kwargs)
threshold = fsolve(optimized_f_exp, 50)

What we did here is basically made a new function optimized_f_exp by partially fixing a, b and c args of your original function to be popt (what's exactly why it called partial).

9dogs
  • 1,446
  • 10
  • 18