J'ai écrit avant Implémentez rapidement la méthode Monte Carlo en Python.
L'implémentation utilisant Cython était trop omise, je vais donc la compléter.
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)
C'est bien qu'il soit passé d'environ 100 secondes à 17 secondes (mesuré avec un MacBook 12 pouces), mais je devrais pouvoir faire de mon mieux. Puisque la partie aléatoire est du code Python, il semble bon d'utiliser l'implémentation C ici.
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)
Écrivons également setup.py
.
#setup.py
from setuptools import setup, Extension
ext_modules = [
Extension(
name='monte',
sources=['monte.pyx']
)
]
setup(
name = 'cymonte',
ext_modules = ext_modules
)
Vous pouvez créer un module en exécutant ce qui suit dans le terminal. Je pense que cela peut être fait sous Windows.
$ python setup.py build_ext --inplace
Après cela, écrivez le script principal pour l'exécuter.
#main.py
import monte
monte.monte()
Déplaçons-le.
$ time python main.py
real 0m2.081s
user 0m1.935s
sys 0m0.070s
Je l'ai réglé et c'est beaucoup plus rapide! Nous avons pu nous rapprocher le plus possible de l'implémentation de Numba et de l'implémentation de C ++.
Reference:
Monte Carlo Simulation with Cython
Recommended Posts