Implementing numerical integration in Python
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
5
down vote
favorite
I have this Python code that implements a rectangular numerical integration. It evaluates the (K-1)-dimensional integral for arbitrary integer $K geq 1$
$$int_u_K = 0^gammaint_u_K-1 = 0^gamma-u_Kcdotsint_u_2^gamma-u_K-cdots-u_3F_U(gamma-sum_k=2^Ku_k)f_U(u_2)cdots f_U(u_K),du_2cdots du_K$$
where $F_U$ corresponds to the cdf function in the code, and $f_U$ to the pdf. I implemented it using recursion as follows:
#************************** Import necessary libraries******************************************
import numpy as np
import matplotlib.pyplot as plt
import time
#******************************Set the constant scalars and vectors***************************
start_time = time.time()
KU = 3
eta_dB = 3
eta = 10**(eta_dB/10)
ExpanF = 50
tdB = np.arange(-5,11,4)
tVec = 10**(tdB/10)
thVec = (tVec/eta)*(ExpanF-eta*(KU-1))
N = 10000 # For simulation
du = 0.01
#******************************Define functions to be used***************************************
#Define the CDF of U
def CDF(u):
return 1-1/(u+1)
#Define the PDF of U
def pdf(u):
return 1/((1+u))**2
def FK(h, k):
#print(f'h is h, and k is k')
if k == 1:
res = CDF(h)
else:
#n_iter = int(h/du)
res = 0
u = 0
while u < h:
res += FK(h-u, k-1)*pdf(u)*du
u += du
return res
#*******************Find the numerical and simulation values of the integral******************
ResultNum =
ResultSim =
if (ExpanF-eta*(KU-1)) > 0:
for t in thVec:
# Numerical
ResultNum.append(1-FK(t, KU))
# Simulation
count = 0
for n in range(0, N):
if np.sum(np.random.exponential(1, (1, KU))/np.random.exponential(1, (1, KU))) <= t:
count += 1
ResultSim.append(1-count/N)
The parameter du
is the resolution of the numerical integral, and the smaller, the more accurate the numerical approximation is. However, decreasing du
comes at the expense of more computational time using the above code. For example I tried to run the above code on my machine Intel i5 @2.5 GH with 6 GB of RAM for du=0.0001
, and it took 15 hours and didn't finish, at which case I had to abort it.
Is there anyway the above code can be optimized to run significantly faster? I tried C++, and I got a 30x speed factor using the same code and algorithm, but I was wondering if I can get a similar or better speed up factor in Python.
python performance python-3.x numpy numerical-methods
 |Â
show 4 more comments
up vote
5
down vote
favorite
I have this Python code that implements a rectangular numerical integration. It evaluates the (K-1)-dimensional integral for arbitrary integer $K geq 1$
$$int_u_K = 0^gammaint_u_K-1 = 0^gamma-u_Kcdotsint_u_2^gamma-u_K-cdots-u_3F_U(gamma-sum_k=2^Ku_k)f_U(u_2)cdots f_U(u_K),du_2cdots du_K$$
where $F_U$ corresponds to the cdf function in the code, and $f_U$ to the pdf. I implemented it using recursion as follows:
#************************** Import necessary libraries******************************************
import numpy as np
import matplotlib.pyplot as plt
import time
#******************************Set the constant scalars and vectors***************************
start_time = time.time()
KU = 3
eta_dB = 3
eta = 10**(eta_dB/10)
ExpanF = 50
tdB = np.arange(-5,11,4)
tVec = 10**(tdB/10)
thVec = (tVec/eta)*(ExpanF-eta*(KU-1))
N = 10000 # For simulation
du = 0.01
#******************************Define functions to be used***************************************
#Define the CDF of U
def CDF(u):
return 1-1/(u+1)
#Define the PDF of U
def pdf(u):
return 1/((1+u))**2
def FK(h, k):
#print(f'h is h, and k is k')
if k == 1:
res = CDF(h)
else:
#n_iter = int(h/du)
res = 0
u = 0
while u < h:
res += FK(h-u, k-1)*pdf(u)*du
u += du
return res
#*******************Find the numerical and simulation values of the integral******************
ResultNum =
ResultSim =
if (ExpanF-eta*(KU-1)) > 0:
for t in thVec:
# Numerical
ResultNum.append(1-FK(t, KU))
# Simulation
count = 0
for n in range(0, N):
if np.sum(np.random.exponential(1, (1, KU))/np.random.exponential(1, (1, KU))) <= t:
count += 1
ResultSim.append(1-count/N)
The parameter du
is the resolution of the numerical integral, and the smaller, the more accurate the numerical approximation is. However, decreasing du
comes at the expense of more computational time using the above code. For example I tried to run the above code on my machine Intel i5 @2.5 GH with 6 GB of RAM for du=0.0001
, and it took 15 hours and didn't finish, at which case I had to abort it.
Is there anyway the above code can be optimized to run significantly faster? I tried C++, and I got a 30x speed factor using the same code and algorithm, but I was wondering if I can get a similar or better speed up factor in Python.
python performance python-3.x numpy numerical-methods
Please fix your indentation. The easiest way to post code is to paste it into the question editor, highlight it, and press Ctrl-K to mark it as a code block.
â 200_success
Jul 29 at 17:56
@200_success Done. Thanks
â BlackMath
Jul 29 at 18:56
Did you tryscipy.integrate.nquad
?
â Gareth Rees
Jul 30 at 8:05
@GarethRees Not really. Can it be used for an arbitrary number of nested integrals?
â BlackMath
Jul 30 at 14:37
See the documentation: "Function signature should befunc(x0, x1, ..., xn, t0, t1, ..., tm)
. Integration is carried out in order. That is, integration overx0
is the innermost integral, andxn
is the outermost."
â Gareth Rees
Jul 30 at 15:15
 |Â
show 4 more comments
up vote
5
down vote
favorite
up vote
5
down vote
favorite
I have this Python code that implements a rectangular numerical integration. It evaluates the (K-1)-dimensional integral for arbitrary integer $K geq 1$
$$int_u_K = 0^gammaint_u_K-1 = 0^gamma-u_Kcdotsint_u_2^gamma-u_K-cdots-u_3F_U(gamma-sum_k=2^Ku_k)f_U(u_2)cdots f_U(u_K),du_2cdots du_K$$
where $F_U$ corresponds to the cdf function in the code, and $f_U$ to the pdf. I implemented it using recursion as follows:
#************************** Import necessary libraries******************************************
import numpy as np
import matplotlib.pyplot as plt
import time
#******************************Set the constant scalars and vectors***************************
start_time = time.time()
KU = 3
eta_dB = 3
eta = 10**(eta_dB/10)
ExpanF = 50
tdB = np.arange(-5,11,4)
tVec = 10**(tdB/10)
thVec = (tVec/eta)*(ExpanF-eta*(KU-1))
N = 10000 # For simulation
du = 0.01
#******************************Define functions to be used***************************************
#Define the CDF of U
def CDF(u):
return 1-1/(u+1)
#Define the PDF of U
def pdf(u):
return 1/((1+u))**2
def FK(h, k):
#print(f'h is h, and k is k')
if k == 1:
res = CDF(h)
else:
#n_iter = int(h/du)
res = 0
u = 0
while u < h:
res += FK(h-u, k-1)*pdf(u)*du
u += du
return res
#*******************Find the numerical and simulation values of the integral******************
ResultNum =
ResultSim =
if (ExpanF-eta*(KU-1)) > 0:
for t in thVec:
# Numerical
ResultNum.append(1-FK(t, KU))
# Simulation
count = 0
for n in range(0, N):
if np.sum(np.random.exponential(1, (1, KU))/np.random.exponential(1, (1, KU))) <= t:
count += 1
ResultSim.append(1-count/N)
The parameter du
is the resolution of the numerical integral, and the smaller, the more accurate the numerical approximation is. However, decreasing du
comes at the expense of more computational time using the above code. For example I tried to run the above code on my machine Intel i5 @2.5 GH with 6 GB of RAM for du=0.0001
, and it took 15 hours and didn't finish, at which case I had to abort it.
Is there anyway the above code can be optimized to run significantly faster? I tried C++, and I got a 30x speed factor using the same code and algorithm, but I was wondering if I can get a similar or better speed up factor in Python.
python performance python-3.x numpy numerical-methods
I have this Python code that implements a rectangular numerical integration. It evaluates the (K-1)-dimensional integral for arbitrary integer $K geq 1$
$$int_u_K = 0^gammaint_u_K-1 = 0^gamma-u_Kcdotsint_u_2^gamma-u_K-cdots-u_3F_U(gamma-sum_k=2^Ku_k)f_U(u_2)cdots f_U(u_K),du_2cdots du_K$$
where $F_U$ corresponds to the cdf function in the code, and $f_U$ to the pdf. I implemented it using recursion as follows:
#************************** Import necessary libraries******************************************
import numpy as np
import matplotlib.pyplot as plt
import time
#******************************Set the constant scalars and vectors***************************
start_time = time.time()
KU = 3
eta_dB = 3
eta = 10**(eta_dB/10)
ExpanF = 50
tdB = np.arange(-5,11,4)
tVec = 10**(tdB/10)
thVec = (tVec/eta)*(ExpanF-eta*(KU-1))
N = 10000 # For simulation
du = 0.01
#******************************Define functions to be used***************************************
#Define the CDF of U
def CDF(u):
return 1-1/(u+1)
#Define the PDF of U
def pdf(u):
return 1/((1+u))**2
def FK(h, k):
#print(f'h is h, and k is k')
if k == 1:
res = CDF(h)
else:
#n_iter = int(h/du)
res = 0
u = 0
while u < h:
res += FK(h-u, k-1)*pdf(u)*du
u += du
return res
#*******************Find the numerical and simulation values of the integral******************
ResultNum =
ResultSim =
if (ExpanF-eta*(KU-1)) > 0:
for t in thVec:
# Numerical
ResultNum.append(1-FK(t, KU))
# Simulation
count = 0
for n in range(0, N):
if np.sum(np.random.exponential(1, (1, KU))/np.random.exponential(1, (1, KU))) <= t:
count += 1
ResultSim.append(1-count/N)
The parameter du
is the resolution of the numerical integral, and the smaller, the more accurate the numerical approximation is. However, decreasing du
comes at the expense of more computational time using the above code. For example I tried to run the above code on my machine Intel i5 @2.5 GH with 6 GB of RAM for du=0.0001
, and it took 15 hours and didn't finish, at which case I had to abort it.
Is there anyway the above code can be optimized to run significantly faster? I tried C++, and I got a 30x speed factor using the same code and algorithm, but I was wondering if I can get a similar or better speed up factor in Python.
python performance python-3.x numpy numerical-methods
edited Jul 29 at 19:06
asked Jul 29 at 15:40
BlackMath
614
614
Please fix your indentation. The easiest way to post code is to paste it into the question editor, highlight it, and press Ctrl-K to mark it as a code block.
â 200_success
Jul 29 at 17:56
@200_success Done. Thanks
â BlackMath
Jul 29 at 18:56
Did you tryscipy.integrate.nquad
?
â Gareth Rees
Jul 30 at 8:05
@GarethRees Not really. Can it be used for an arbitrary number of nested integrals?
â BlackMath
Jul 30 at 14:37
See the documentation: "Function signature should befunc(x0, x1, ..., xn, t0, t1, ..., tm)
. Integration is carried out in order. That is, integration overx0
is the innermost integral, andxn
is the outermost."
â Gareth Rees
Jul 30 at 15:15
 |Â
show 4 more comments
Please fix your indentation. The easiest way to post code is to paste it into the question editor, highlight it, and press Ctrl-K to mark it as a code block.
â 200_success
Jul 29 at 17:56
@200_success Done. Thanks
â BlackMath
Jul 29 at 18:56
Did you tryscipy.integrate.nquad
?
â Gareth Rees
Jul 30 at 8:05
@GarethRees Not really. Can it be used for an arbitrary number of nested integrals?
â BlackMath
Jul 30 at 14:37
See the documentation: "Function signature should befunc(x0, x1, ..., xn, t0, t1, ..., tm)
. Integration is carried out in order. That is, integration overx0
is the innermost integral, andxn
is the outermost."
â Gareth Rees
Jul 30 at 15:15
Please fix your indentation. The easiest way to post code is to paste it into the question editor, highlight it, and press Ctrl-K to mark it as a code block.
â 200_success
Jul 29 at 17:56
Please fix your indentation. The easiest way to post code is to paste it into the question editor, highlight it, and press Ctrl-K to mark it as a code block.
â 200_success
Jul 29 at 17:56
@200_success Done. Thanks
â BlackMath
Jul 29 at 18:56
@200_success Done. Thanks
â BlackMath
Jul 29 at 18:56
Did you try
scipy.integrate.nquad
?â Gareth Rees
Jul 30 at 8:05
Did you try
scipy.integrate.nquad
?â Gareth Rees
Jul 30 at 8:05
@GarethRees Not really. Can it be used for an arbitrary number of nested integrals?
â BlackMath
Jul 30 at 14:37
@GarethRees Not really. Can it be used for an arbitrary number of nested integrals?
â BlackMath
Jul 30 at 14:37
See the documentation: "Function signature should be
func(x0, x1, ..., xn, t0, t1, ..., tm)
. Integration is carried out in order. That is, integration over x0
is the innermost integral, and xn
is the outermost."â Gareth Rees
Jul 30 at 15:15
See the documentation: "Function signature should be
func(x0, x1, ..., xn, t0, t1, ..., tm)
. Integration is carried out in order. That is, integration over x0
is the innermost integral, and xn
is the outermost."â Gareth Rees
Jul 30 at 15:15
 |Â
show 4 more comments
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
active
oldest
votes
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f200525%2fimplementing-numerical-integration-in-python%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Please fix your indentation. The easiest way to post code is to paste it into the question editor, highlight it, and press Ctrl-K to mark it as a code block.
â 200_success
Jul 29 at 17:56
@200_success Done. Thanks
â BlackMath
Jul 29 at 18:56
Did you try
scipy.integrate.nquad
?â Gareth Rees
Jul 30 at 8:05
@GarethRees Not really. Can it be used for an arbitrary number of nested integrals?
â BlackMath
Jul 30 at 14:37
See the documentation: "Function signature should be
func(x0, x1, ..., xn, t0, t1, ..., tm)
. Integration is carried out in order. That is, integration overx0
is the innermost integral, andxn
is the outermost."â Gareth Rees
Jul 30 at 15:15