[PYTHON] Increase the speed of the Monte Carlo method of Cython cut-out implementation.

Today is Cython

I wrote before Rapidly implement the Monte Carlo method in Python.

The implementation using Cython was too omission, so I will supplement it.

This is the original Python code

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()

This is Cython

#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.

Improved Cython

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

Increase the speed of the Monte Carlo method of Cython cut-out implementation.
Calculation of the shortest path using the Monte Carlo method
Speed comparison of each language by Monte Carlo method
Understand the metropolitan hasting method (one of the methods in Markov chain Monte Carlo method) with implementation
Find the ratio of the area of Lake Biwa by the Monte Carlo method
Monte Carlo method
Try implementing the Monte Carlo method in Python
The first Markov chain Monte Carlo method by PyStan
Introduction to Monte Carlo Method
How to increase the processing speed of vertex position acquisition
A simple Python implementation of the k-nearest neighbor method (k-NN)
Sprinkle rice grains to find the circumference (Monte Carlo method)
[Statistics] Visualize and understand the Hamiltonian Monte Carlo method with animation.
I tried to summarize the frequently used implementation method of pytest-mock
Einsum implementation of value iterative method
Simulate Monte Carlo method in Python
Estimating π by Monte Carlo method
Increase the UI size of MyPaint
I couldn't install pypy3.6-7.3.1 on macOS + pyenv, but I could install pypy3.6-7.3.0. I felt the wind of pypy by the Monte Carlo method.
Implementation of the treatise of "Parameter estimation method for human flow simulation" (unofficial)
Implementation and experiment of convex clustering method
Count / verify the number of method calls.
Othello-From the tic-tac-toe of "Implementation Deep Learning" (3)
I read the implementation of golang channel
Read the implementation of ARM global timer
Othello-From the tic-tac-toe of "Implementation Deep Learning" (2)