Integration using Lambda function gives an error

197 views Asked by At

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: enter image description here

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?

1

There are 1 answers

3
smichr On BEST ANSWER

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)