Создание более сложных составных моделей с помощью lmfit

Я хочу создавать более сложные/сложные модели из простых с помощью lmfit.

У меня есть две функции, например, например. гауссовский (норма к единице на пике) и лоренцев (норма к единице на пике) и хотите соответствовать, например. их линейная комбинация. Все еще добавляя к единству. Поэтому я мог бы написать новую функцию, например

def voigt(*all the parameters*, alpha)
   return alpha*gaussian(...) + (1-alpha)*lorentzian(...)

но это не очень адаптивно. Поэтому я теперь делаю вместо этого:

mod = ConstantModel(prefix = 'a1_') + Model(gauss) + ConstantModel(prefix='a2_') * Model(lorentz)
pars = Parameters()
pars.add('a1_c', value = 1, min = 0, max = 1)
pars.add('a2_c', expr = '1-a1_c')

Все еще чувствует себя немного неуклюжим. Есть ли более элегантный способ?


person Swift    schedule 21.06.2020    source источник


Ответы (1)


Я думаю, это в основном зависит от того, какую сложность и адаптируемость вы ищете. Если я понимаю вопрос (возможно, пример или упрощение вашей реальной цели), вы хотите ограничить две пиковые функции, чтобы они имели максимальную высоту, которая в сумме дает фиксированное значение (скажем, 1). Почему бы не определить базовые функции, которые масштабируются по вашему желанию?

 import numpy as np
 def gauss(x, amp, cen, wid):
      return amp * np.exp(-(x-cen)**2/wid)  # deliberately Gaussian-like

 def loren(x, amp, cen, wid): 
      return amp * wid / ( (x-cen)**2 + wid) # deliberately Lorentzian-like

а затем суммируйте их и ограничьте два параметра amp суммой до 1:

from lmfit import Model
mod = Model(gauss, prefix='g_') + Model(loren, prefix='l_')

pars = mod.make_params(g_cen=1, g_wid=1, l_cen=1, l_wid=1)
pars.add('g_amp', value=0.5, min=0, max=1)
pars.add('l_amp', expr='1 - g_amp', min=0, max=1)
person M Newville    schedule 22.06.2020