1+ import numpy as np
2+ from multiprocessing import Pool
3+
4+
5+ def remove_i (x , i ):
6+ """Drops the ith element of an array."""
7+ shape = (x .shape [0 ]- 1 ,) + x .shape [1 :]
8+ y = np .empty (shape , dtype = float )
9+ y [:i ] = x [:i ]
10+ y [i :] = x [i + 1 :]
11+ return y
12+
13+
14+ def a (i , x , G , m ):
15+ """The acceleration of the ith mass."""
16+ x_i = x [i ]
17+ x_j = remove_i (x , i ) # don't compute on itself
18+ m_j = remove_i (m , i )
19+ diff = x_j - x_i
20+ mag3 = np .sum (diff ** 2 , axis = 1 )** 1.5
21+ # compute acceleration on ith mass
22+ result = G * np .sum (diff * (m_j / mag3 )[:,np .newaxis ], axis = 0 )
23+ return result
24+
25+
26+ # function needs one argument
27+ def timestep_i (args ):
28+ """Worker function that computes the next position and velocity for the ith mass."""
29+ i , x0 , v0 , G , m , dt = args # unpack arguments to original function
30+ a_i0 = a (i , x0 , G , m ) # body of original timestep()
31+ v_i1 = a_i0 * dt + v0 [i ]
32+ x_i1 = a_i0 * dt ** 2 + v0 [i ] * dt + x0 [i ]
33+ return i , x_i1 , v_i1
34+
35+
36+ def timestep (x0 , v0 , G , m , dt , pool ):
37+ """Computes the next position and velocity for all masses given
38+ initial conditions and a time step size.
39+ """
40+ N = len (x0 )
41+ tasks = [(i , x0 , v0 , G , m , dt ) for i in range (N )]
42+ results = pool .map (timestep_i , tasks ) # replace old do() with Pool.map()
43+ x1 = np .empty (x0 .shape , dtype = float )
44+ v1 = np .empty (v0 .shape , dtype = float )
45+ for i , x_i1 , v_i1 in results :
46+ x1 [i ] = x_i1
47+ v1 [i ] = v_i1
48+ return x1 , v1
49+
50+
51+ def initial_cond (N , D ):
52+ """Generates initial conditions for N unity masses at rest
53+ starting at random positions in D-dimensional space.
54+ """
55+ x0 = np .random .rand (N , D ) # use random initial locations
56+ v0 = np .zeros ((N , D ), dtype = float )
57+ m = np .ones (N , dtype = float )
58+ return x0 , v0 , m
59+
60+
61+ def simulate (P , N , D , S , G , dt ):
62+ x0 , v0 , m = initial_cond (N , D )
63+ pool = Pool (P )
64+ for s in range (S ):
65+ x1 , v1 = timestep (x0 , v0 , G , m , dt , pool )
66+ x0 , v0 = x1 , v1
0 commit comments