1

I am struggling right now with Lorentzian curve fit. I'll try to explain my problem. I need to write my own code for Lorentzian curve fit so I can add some stuff to the equations. I've implemented Lorentzian fit with model and def, I've written similary, but it doesn't work. Check out my code:

So here are my data:

for dataset in [Bxfft]:
    dataset = np.asarray(dataset)
    freqs, psd = signal.welch(dataset, fs=266336/300, window='hamming', nperseg=16192, scaling='density')
    plt.semilogy(freqs[30:-7000], psd[30:-7000]/dataset.size**0, color='r', label='Bx')
    x = freqs[100:-7900]
    y = psd[100:-7900]

Here is Lorentzian curve fit defined by me:

def lorentzian(x, amp, cen, sig):
    return (amp/np.pi) * (sig/(x-cen)**2 + sig**2)

model = Model(lorentzian)
pars = model.make_params(amp=6, cen=5, sig=1)
pars['amp'].max = 6
result = model.fit(y, pars, x=x)
final_fit = result.best_fit
print(result.fit_report(min_correl=0.25))
plt.plot(x, final_fit, 'k--', linewidth=3)

And here done by model function:

model2 = LorentzianModel()
params2 = model2.make_params(amplitude=6, center=5, sigma=1)
params2['amplitude'].value = 6
result2 = model2.fit(y, params2, x=x)
final_fit2 = result2.best_fit
print(result2.fit_report(min_correl=0.25))
plt.plot(x, final_fit2, 'k--', linewidth=3)

The upper plot goes for def Lorentzian, and the lower plot goes for model Lorentzian.

And that's a result:enter image description here

Christian K.
  • 2,785
  • 18
  • 40
Hiddenguy
  • 547
  • 13
  • 33

1 Answers1

2

Look like a parenthesis problem. This:

(amp/np.pi) * (sig/(x-cen)**2 + sig**2)

is not a Lorentzian. This:

(amp/np.pi) * (sig/((x-cen)**2 + sig**2))

is. In addition you may have a slight integer problem in the rare event cen,x,sig are all integers. You can use math.pow to solve this, or what they do in lmfit and multiply x by a float: 1.0*x-cen.

As a side note, lmfit for some reason writes this function equivalently but a bit differently (find on page lorentzian). I don't see a reason for this though.

kabanus
  • 24,623
  • 6
  • 41
  • 74
  • 1
    It still amaze me that, parenthesis can change the whole thing :) Thank You for your advice. – Hiddenguy May 29 '18 at 10:47
  • @kabanus - If I am not mistaken, the definition of Lorentzian used by lmfit is equivalent to the one here (with correct parentheses, of course) for an Amplitude times a unit-normalized Lorentzian. – M Newville May 29 '18 at 17:49
  • @MNewville you are correct. I didn't mean it wasn't, just that the actual expression calculating the same thing differs. I think it's even worse (more division) from a programming view point. Anyway I'll clarify my meaning, thanks. – kabanus May 29 '18 at 17:51