Создание более сложных составных моделей с помощью lmfit - PullRequest
0 голосов
/ 21 июня 2020

Я хочу создавать более сложные / сложные модели из простых с 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')

По-прежнему кажется немного неуклюжим. Есть ли способ более элегантный?

1 Ответ

1 голос
/ 22 июня 2020

Я думаю, это в основном зависит от того, какую сложность и адаптивность вы ищете. Если я понимаю вопрос (возможно, пример или упрощение вашей реальной цели), вы хотите ограничить две функции пика максимальными высотами, которые в сумме равны фиксированному значению (скажем, 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)
...