I am trying to integrate an exponential function using a Lambda function first time.
There are two versions of codes that should work the same, but the one with Lambda function is giving an error saying:
The code giving the error is
import numpy as np
import sympy as sym
# Predetermined parameter values
s, t, T= 0.2 ,0, 0.25
a1, a2= 1.2, 2.3
X1, X2, X3=0.5,-2.0,0.3
# Symbolic variable for integration
u = sym.symbols('u')
# Version 1 giving the above error
fx= lambda X1,X2,X3,a1,a2,T,u: (X1*sym.exp(-a1*(T-u)) + X2*sym.exp(-a2*(T-u))+X3)**2
Fx=sym.integrate(sym.expand(fx), (u,t,s))
Fx=float(Fx)
On the other hand, I can obtain the output Fx using the following version without the Lambda function.
# Version 2 works fine
def expFun3fsq(X1,X2,X3,a1,a2,T,u):
# Squared single line exponential function
# It returns a symbolic function where u is the only symbol in the function
fx= (X1*sym.exp(-a1*(T-u))+X2*sym.exp(-a2*(T-u))+X3) **2
return fx
Fx=sym.integrate(sym.expand(expFun3fsq(X1,X2,X3,a1,a2,T,u)), (u,t,s))
Fx=float(Fx)
What are the causes of the error and how can I fix the problem?
When you write f = lambda x: 1 + x
you are telling python that you will provide a single argument to f
(like f(1)
) and that argument should be referenced as x
in the formula. You only need a lambda if you want to be able to change an argument of an expression easily (in my example the f
will add 1 to whatever you pass to it).
When you write f = lambda: 1 + x
this would mean that you aren't going to pass any parameters and you just want the function to use the local value of x
and add 1.
>>> f = lambda: x + 1
>>> g = lambda x: x + 1
>>> x = 1
>>> f()
2
>>> g(1)
2
>>> x = 3
>>> f()
4
>>> g(1)
2
It's important to make sure you understand the above outputs. The lambda behave the same way as a defined function -- and you showed that you know how to use the defined function.
Since you fix all but u
and you want to integrate an expression that is a function of u
you have to define that expression in some way: you can either pass the parameters to a function/lambda (properly) to get that expression or just write the expression. So change fx= lambda X1,X2,X3,a1,a2,T,u:
to fx =
and your code will work. OR, pass all the variables to the lambda just like you did in the case of using the function.
>>> s, t, T= 0.2 ,0, 0.25
>>> a1, a2= 1.2, 2.3
>>> X1, X2, X3=0.5,-2.0,0.3
>>> u = sym.symbols('u')
Here, fx
is the expression
>>> fx= (X1*sym.exp(-a1*(T-u)) + X2*sym.exp(-a2*(T-u))+X3)**2
>>> fx.subs(u, 0) # less convenient than using a lambda as shown last below
0.207025570818871
>>> Fx1=sym.integrate(sym.expand(fx), (u,t,s))
Here, fx
is a function to which we must pass all parameters
>>> fx = lambda X1,X2,X3,a1,a2,T,u:(X1*sym.exp(-a1*(T-u)) + X2*sym.exp(-a2*(T-u))+X3)**2
>>> Fx2=sym.integrate(sym.expand(fx(X1,X2,X3,a1,a2,T,u)), (u,t,s))
Here, fx
is a function of u
and we use the local values of the variables
>>> fx = lambda u:(X1*sym.exp(-a1*(T-u)) + X2*sym.exp(-a2*(T-u))+X3)**2
>>> fx(0)
0.207025570818871
>>> fx(u).n(2)
1.3*(0.33*exp(1.2*u) - exp(2.3*u) + 0.27)**2
>>> Fx3=sym.integrate(sym.expand(fx(u)), (u,t,s))
All methods give the same answer:
>>> Fx1,Fx2, Fx3
(0.106060402899230, 0.106060402899230, 0.106060402899230)