I've set up a model to fit some data with a substraction in the exponent. It works fine for fits, but when I explicitly evaluate the model I get strange results and an AttributeError: 'Mul' object has no attribute 'exp'.
The problem seems to stem from the way lambdify works and occurs when evaluating a model containing a non-trivial function such as potentiation or exponentiation.
import symfit as sf
a = sf.Parameter('a',1,0,2) #name, initial value, minimum, maximum
b = sf.Parameter('b',1,0,2)
c=sf.Parameter('c',1,0,2)
x, y = sf.variables('x, y')
model=sf.Model({y: a * (c - sf.exp((x) / b))})
model(1,a,b,c)
Out: Ans(y=a*(c + 1))
model=sf.Model({y: a * (1 - sf.exp((x-c) / b))})
model(1,a,b,c)
Traceback (most recent call last):
File "<ipython-input-9-faba3b52b923>", line 1, in <module>
model(1,a,b,c)
File "C:\PortablePrograms\Python\WPy-3670\python-3.6.7.amd64\lib\site-packages\symfit\core\fit.py", line 334, in __call__
return Ans(*self.eval_components(**bound_arguments.arguments))
File "C:\PortablePrograms\Python\WPy-3670\python-3.6.7.amd64\lib\site-packages\symfit\core\fit.py", line 296, in eval_components
return [expr(*args, **kwargs) for expr in self.numerical_components]
File "C:\PortablePrograms\Python\WPy-3670\python-3.6.7.amd64\lib\site-packages\symfit\core\fit.py", line 296, in <listcomp>
return [expr(*args, **kwargs) for expr in self.numerical_components]
File "C:\PortablePrograms\Python\WPy-3670\python-3.6.7.amd64\lib\site-packages\sympy\utilities\lambdify.py", line 444, in wrapper
return funcarg(*newargs, **kwargsx)
File "<string>", line 1, in <lambda>
AttributeError: 'Mul' object has no attribute 'exp'
I would expect either the initial value of the parameters to be used or to get a symbolic answer, but get neither.
For the first model the result is therefore both wrong and inconsistant, I would expect
Ans(y=a*(c-exp(1/b))
or
Ans(y=a*(c-1))
or just simply
Ans(y=0)
For the second model lambdify seems to be unable to parse the expression.
This is also the case when using sf.sqrt(), or sympy.exp(). I'm working in python 3.6.7 and IPython 7.1.1, using Symfit 0.4.6 and Sympy 1.1.1 (as Symfit doesn't work with higher versions accoring to pip).
I can use either model to fit data and evaluate the model with the best-fit parameters as shown in the example here (https://pypi.org/project/symfit/). The line
yfit = model(x=xdata, **fit_result.params)[y]
doesn't work either (tried on python 2.7, 3.5 and 3.6) unless changed to
yfit = [model(x=x, **fit_result.params) for x in xdata]