Implementing numerical integration in Python

The name of the pictureThe name of the pictureThe name of the pictureClash 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.







share|improve this question





















  • 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 over x0 is the innermost integral, and xn is the outermost."
    – Gareth Rees
    Jul 30 at 15:15

















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.







share|improve this question





















  • 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 over x0 is the innermost integral, and xn is the outermost."
    – Gareth Rees
    Jul 30 at 15:15













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.







share|improve this question













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.









share|improve this question












share|improve this question




share|improve this question








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 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 over x0 is the innermost integral, and xn 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










  • @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 over x0 is the innermost integral, and xn 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
















active

oldest

votes











Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















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



































active

oldest

votes













active

oldest

votes









active

oldest

votes






active

oldest

votes










 

draft saved


draft discarded


























 


draft saved


draft discarded














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













































































Popular posts from this blog

Greedy Best First Search implementation in Rust

Function to Return a JSON Like Objects Using VBA Collections and Arrays

C++11 CLH Lock Implementation