I wrote before Rapidly implement the Monte Carlo method in Python.
The implementation using Cython was too omission, so I will supplement it.
import random
NUM=100000000
def monte():
counter = 0
for i in range(NUM):
x = random.random()
y = random.random()
if x*x+y*y < 1.0:
counter += 1
pi = 4.0*counter/NUM
print(pi)
def main():
monte()
if __name__ == '__main__':
main()
#monte.pyx
import random
cdef int NUM = 100000000
cdef cmonte():
cdef :
int counter = 0
int i=0
double x
double y
for i in range(NUM):
x = random.random()
y = random.random()
if x*x + y*y < 1.0:
counter += 1
cdef double pi = 4.0*counter/NUM
return pi
def monte():
pi=cmonte()
print(pi)
It's good that it shortened from about 100 seconds to 17 seconds (measured with a 12inch MacBook), but I should be able to do my best. Since the random part is Python code, it seems good to use the C implementation here.
from libc.stdlib cimport rand, RAND_MAX
cdef int NUM = 100000000
def monte():
cdef :
int counter = 0
int i=0
double x
double y
for i in range(NUM):
x = (rand()+1.0)/(RAND_MAX+2.0)
y = (rand()+1.0)/(RAND_MAX+2.0)
if x*x + y*y < 1.0:
counter += 1
pi = 4.0*counter/NUM
print(pi)
Let's also write setup.py
.
#setup.py
from setuptools import setup, Extension
ext_modules = [
Extension(
name='monte',
sources=['monte.pyx']
)
]
setup(
name = 'cymonte',
ext_modules = ext_modules
)
You can create a module by executing the following in the terminal. I think it can be done on Windows.
$ python setup.py build_ext --inplace
After that, write the main script to run it.
#main.py
import monte
monte.monte()
Let's move it.
$ time python main.py
real 0m2.081s
user 0m1.935s
sys 0m0.070s
I tuned it and it's much faster! You were able to get close enough to the implementation of Numba and the implementation of C ++.
Reference:
Monte Carlo Simulation with Cython
Recommended Posts