Ограничения lmfit Python: a ‹ b ‹ c

Я использую lmfit в Python для подгонки некоторых данных, включая подгонку переменных a, b и c. Мне нужно убедиться, что a ‹ b ‹ c. Я нашел http://cars9.uchicago.edu/software/python/lmfit_MinimizerResult/constraints.html, в котором говорится об ограничениях, которые необходимо определить как неравенства, и о настройке фиктивных переменных. Например, если бы я хотел, чтобы a + b ‹= 10, я мог бы сделать:

pars.add('a',     value = 5, vary=True)
pars.add('delta', value = 5, max=10, vary=True)
pars.add('b',     expr='delta-a')

И это гарантировало бы, что a + b ‹= 10.

Я предполагаю, что мне понадобится c - b > 0 и b - a > 0 (или, альтернативно, a - b ‹ 0 и b - c ‹ 0), но я не уверен, как это закодировать.


person ChemPaul    schedule 19.04.2018    source источник
comment
на самом деле, что вы хотите получить в результате или вам нужно строго использовать этот LMFIT?   -  person Virbhadrasinh    schedule 20.04.2018
comment
Мне не обязательно использовать lmfit, но мне нужно использовать метод наименьших квадратов, чтобы подогнать функцию к моим данным.   -  person ChemPaul    schedule 20.04.2018


Ответы (1)


Следуя подсказке из документа, на который вы ссылаетесь, ограничение неравенства x > y должно быть переведено в x = y + something, где something имеет нижнюю границу 0.

Итак, применяя этот подход дважды, я думаю, что это должно делать то, что вы хотите:

from lmfit import Parameters
params = Parameters()
params.add('a', value=5, vary=True)
params.add('b_minus_a', value=1,  vary=True, min=0)
params.add('c_minus_b', value=1,  vary=True, min=0)
params.add('b', expr='a + b_minus_a')
params.add('c', expr='b + c_minus_b')

Это по-прежнему использует три переменные (a, b_minus_a и c_minus_b) и накладывает ограничения неравенства, с оговоркой, что различия могут фактически быть равны 0. С числами с плавающей запятой этого обычно достаточно, но в зависимости от масштаба переменных вы можете изменить 0 на что-то вроде 1.e-12.

person M Newville    schedule 20.04.2018
comment
Ах, да, это имеет смысл. Я попробую это завтра утром, когда вернусь к своему обычному компьютеру. - person ChemPaul; 20.04.2018
comment
У меня похожая ситуация, за исключением того, что нужно только связать 1 параметр как меньший, чем другой, так что b ‹ 0,2 * a, но в противном случае b должен иметь возможность свободно варьироваться, но кажется, что он заблокирован ровно на 0,2 * a , где я установил params.add(name="b", expr='0.2*a + b_minus_a'), просто ли мой фитинг просто хочет, чтобы b было выше, чтобы он как бы упирался в потолок, или он действительно застрял на этом значении? Кажется, это так, независимо от множителя, поэтому я подозреваю, что это привело к упомянутой вами оговорке. Могу ли я заставить его исследовать больше? - person ch4rl1e97; 25.08.2020