title: How to implement multiprocessing in Monte Carlo integration
body: <p>I created a Python program that integrates a given function over a given interval using Monte Carlo simulation. It works well, except for the fact that it runs painfully slow when you want higher levels of accuracy (larger N value). I figured I'd give multiprocessing a try in order to speed it up, but then I realized I have no clue how to implement it. Here's what I have right now:</p>
  <pre><code>from scipy import random
  import numpy as np
  import matplotlib.pyplot as plt
  from multiprocessing import Process
  import os
  
  # GOAL: Approximate the integral of a function f(x) from lower bound a to upper bound b using Monte Carlo simulation
  
  # bounds of integration
  a = 0
  b = np.pi
  
  # function to integrate
  def f(x):
      return np.sin(x)
  
  N = 10000
  areas = []
  
  
  def mcIntegrate():
      
      for i in range(N):
          
          # array filled with random numbers between limits
          xrand = random.uniform(a, b, N)
          
          # sum the return values of the function of each random number
          integral = 0.0
          for i in range(N):
              integral += f(xrand[i])
          
          # scale integral by difference of bounds divided by amount of random values
          ans = integral * ((b - a) / float(N))
          
          # add approximation to list of other approximations
          areas.append(ans)
  
  
  if __name__ == &quot;__main__&quot;:
  
      processes = []
      numProcesses = os.cpu_count()
  
      for i in range(numProcesses):
          process = Process(target=mcIntegrate)
          processes.append(process)
  
      for process in processes:
          process.start()
  
      for process in processes:
          process.start()
  
      # graph approximation distribution
      plt.title(&quot;Distribution of Approximated Integrals&quot;)
      plt.hist(areas, bins=30, ec='black')
      plt.xlabel(&quot;Areas&quot;)
      plt.show()
  
  </code></pre>
  <p>Can I get some help with this implementation?</p>
  <hr />
  <p>Took advice from the comments and used multiprocessor.Pool, and also cut down on some operations by using NumPy instead. Went from taking about 5min to run to now about 6sec (for N = 10000). Here's my implementation:</p>
  <pre><code>import scipy
  import numpy as np
  import matplotlib.pyplot as plt
  import multiprocessing
  import os
  
  # GOAL: Approximate the integral of function f from lower bound a to upper bound b using Monte Carlo simulation
  
  a = 0       # lower bound of integration
  b = np.pi   # upper bound of integration
  f = np.sin  # function to integrate
  N = 10000   # sample size
  
  def mcIntegrate(p):
      xrand = scipy.random.uniform(a, b, N)       # create array filled with random numbers within bounds
      integral = np.sum(f(xrand))                 # sum return values of function of each random number
      approx = integral * ((b - a) / float(N))    # scale integral by difference of bounds divided by sample size
      return approx
  
  
  if __name__ == &quot;__main__&quot;:
      
      # run simulation N times in parallel and store results in array
      with multiprocessing.Pool(os.cpu_count()) as pool:
          areas = pool.map(mcIntegrate, range(N))
  
      # graph approximation distribution
      plt.title(&quot;Distribution of Approximated Integrals&quot;)
      plt.hist(areas, bins=30, ec='black')
      plt.xlabel(&quot;Areas&quot;)
      plt.show()
  
  </code></pre>