2
\$\begingroup\$

The code below is my shot at trying to do monte carlo integration of the function sin(x) from 0 to pi in Python 3. I sample randomly 10000 times a floating number from 0 to pi and do the standard procedure of the monte carlo integration and also take the average of ten results for an even better approximation,i was wondering if there is anything i can do to optimize my code from a time or accuracy standpoint.

import random
import math
def func(n):
 return math.sin(n)
integralres=0
for t in range(10):
 resf=0
 for i in range(10000):
 u=random.uniform(0,math.pi)
 resf+=func(u)
 integralres+=(math.pi)*resf/10000
print(integralres/10)
asked Dec 22, 2020 at 14:14
\$\endgroup\$
0

1 Answer 1

1
\$\begingroup\$

Style

PEP8 is the Python style guide and is worth a read to keep your code clear and understandable.

Naming

You're not using your loop indicies, t and i, it's customary to replace them with _ to indicate this.

The name func for a function doesn't tell you what it does. Names should be as descriptive as possible, in this case sin seems sensible

def sin(x):
 return math.sin(x)

Functions

The function sin doesn't actually give you anything, as is now clearer, and I'd remove it altogether.

The calculation of you integration is discrete, and might be used separately. I would put that inside a function

def monte_carlo(n):
 resf = 0
 for _ in range(n):
 uniform_rand_no = random.uniform(0, math.pi)
 resf += math.sin(uniform_rand_no)
 return math.pi * resf / 10000

Note that I've:

  1. Allowed you to pick the number of iterations
  2. Added spaces around operators

I'm not really sure what resf means, otherwise I would have renamed that too.

Main

All your code will execute when you import your file. If you use the following you can gate execution solely to when the file is run:

if __name__ == "__main__":
 for _ in range(10):
 ...

Everything

Putting all this together you would get:

import random
import math
def monte_carlo(n):
 resf = 0
 for _ in range(n):
 uniform_rand_no = random.uniform(0, math.pi)
 resf += math.sin(uniform_rand_no)
 return math.pi * resf / 10000
if __name__ == "__main__":
 integral = 0
 n = 10000
 
 for _ in range(10):
 integral += math.pi * monte_carlo(n) / n
 print(integral / 10)
answered Dec 22, 2020 at 15:59
\$\endgroup\$
2
  • \$\begingroup\$ sin = math.sin is a lot better declaration than explicit function definition \$\endgroup\$ Commented Dec 22, 2020 at 16:00
  • \$\begingroup\$ Wouldn't you just from math import sin, pi rather than declaring that @hjpotter92? (I did forget the math. in front of sin; I've edited the answer to include it. \$\endgroup\$ Commented Dec 22, 2020 at 22:28

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.