Если я правильно понимаю, у вас есть
def g(a,b,c):
c1 = (1.0 - c)
cx = 1/c1
c2 = 2*c1
g = a*a*b*gamma(2+cx)*gamma(cx)/gamma(1+3/c2)-b*b/(1+b**c2)**(1/c2)
return g
Если это так, и если вы правильно понимаете математику, это может быть представлено как
a = sqrt((g+b*b/(1+b**c2)**(1/c2))*gamma(1+3/c2)/(b*gamma(2+cx)*gamma(cx)))
То есть вы может думать о вашей проблеме как о переменной g
, которая> 0, и значении a
, полученном из b
, c
и g
с помощью Выражение выше.
И что вы можете сделать с lmfit
и его механизмом ограничения на основе выражений. Вам нужно будет добавить функцию gamma
, как с
from lmfit import Parameters
from scipy.special import gamma
params = Parameters()
params._asteval.symtable['gamma'] = gamma
, а затем установить параметры с границами и ограничениями. Я бы, вероятно, следовал приведенной выше математике, чтобы улучшить отладку и использовать что-то вроде:
params.add('b', 1.5, min=1)
params.add('c', 0.4, min=0, max=1)
params.add('g', 0.2, min=0)
params.add('c1', expr='1-c')
params.add('cx', expr='1.0/c1')
params.add('c2', expr='2*c1')
params.add('gprod', expr='b*gamma(2+cx)*gamma(cx)/gamma(1+3/c2)')
params.add('bfact', expr='(1+b**c2)**(1/c2)')
params.add('a', expr='sqrt(g+b*b/(bfact*gprod))')
Обратите внимание, что это дает 3 фактические переменные (теперь g
, b
и c
) с большим количеством производные значения рассчитаны из них, в том числе a
. Я бы обязательно проверил всю эту математику. Похоже, вы в безопасности от negative**fractional_power
, sqrt(negitive)
и gamma(-1)
, но помните об этих возможностях, которые убьют подгонку.
Вы можете встроить все это в свою функцию подгонки, но использование выражений ограничений дает возможность ограничивать значения параметров независимо от того, как определена функция подгонки или модели.
Надеюсь, это поможет. Опять же, если это не соответствует тому, что вы пытаетесь сделать, опубликуйте более подробную информацию об ограничении, которое вы пытаетесь навязать.