Äú¿ÉÒÔ¾èÖú£¬Ö§³ÖÎÒÃǵĹ«ÒæÊÂÒµ¡£

1Ôª 10Ôª 50Ôª





ÈÏÖ¤Â룺  ÑéÖ¤Âë,¿´²»Çå³þ?Çëµã»÷Ë¢ÐÂÑéÖ¤Âë ±ØÌî



  ÇóÖª ÎÄÕ ÎÄ¿â Lib ÊÓÆµ iPerson ¿Î³Ì ÈÏÖ¤ ×Éѯ ¹¤¾ß ½²×ù Modeler   Code  
»áÔ±   
 
   
 
 
     
   
 ¶©ÔÄ
  ¾èÖú
¸ßÐÔÄܵÄPythonÀ©Õ¹£ºµÚÒ»²¿·Ö
 
×÷Õß Õŵ¤£¬»ðÁú¹ûÈí¼þ    ·¢²¼ÓÚ 2014-11-18
  3032  次浏览      29
 

¼ò½é

ͨ³£À´Ëµ£¬Python²»ÊÇÒ»ÖÖ¸ßÐÔÄܵÄÓïÑÔ£¬ÔÚijÖÖÒâÒåÉÏ£¬ÕâÖÖ˵·¨ÊÇÕæµÄ¡£µ«ÊÇ£¬Ëæ×ÅÒÔNumpyΪÖÐÐĵÄÊýѧºÍ¿ÆÑ§Èí¼þ°üµÄÉú̬ȦµÄ·¢Õ¹£¬´ïµ½ºÏÀíµÄÐÔÄܲ»»áÌ«À§ÄÑ¡£

µ±ÐÔÄܳÉΪÎÊÌâʱ£¬ÔËÐÐʱ¼äͨ³£Óɼ¸¸öº¯Êý¾ö¶¨¡£ÓÃCÖØÐ´ÕâЩº¯Êý£¬Í¨³£Äܼ«´óµÄÌáÉýÐÔÄÜ¡£

ÔÚ±¾ÏµÁеĵÚÒ»²¿·ÖÖУ¬ÎÒÃÇÀ´¿´¿´ÈçºÎʹÓÃNumPyµÄC APIÀ´±àдCÓïÑÔµÄPythonÀ©Õ¹£¬ÒÔ¸ÄÉÆÄ£Ð͵ÄÐÔÄÜ¡£ÔÚÒÔºóµÄÎÄÕÂÖУ¬ÎÒÃǽ«ÔÚÕâÀïÌá³öÎÒÃǵĽâ¾ö·½°¸£¬ÒÔ½øÒ»²½ÌáÉýÆäÐÔÄÜ¡£

Îļþ

ÕâÆªÎÄÕÂÖÐËùÉæ¼°µÄÎļþ¿ÉÒÔÔÚGithubÉÏ»ñµÃ¡£

Ä£Äâ

×÷ΪÕâ¸öÁ·Ï°µÄÆðµã£¬ÎÒÃǽ«ÔÚÏñÖØÁ¦µÄÁ¦µÄ×÷ÓÃÏÂΪNÌåÀ´¿¼ÂǶþάNÌåµÄÄ£Äâ¡£

ÒÔÏÂÊǽ«ÓÃÓÚ´æ´¢ÎÒÃÇÊÀ½çµÄ״̬£¬ÒÔ¼°Ò»Ð©ÁÙʱ±äÁ¿µÄÀà¡£

# lib/sim.py

class World(object):
"""World is a structure that holds the state of N bodies and
additional variables.

threads : (int) The number of threads to use for multithreaded
implementations.

STATE OF THE WORLD:

N : (int) The number of bodies in the simulation.
m : (1D ndarray) The mass of each body.
r : (2D ndarray) The position of each body.
v : (2D ndarray) The velocity of each body.
F : (2D ndarray) The force on each body.

TEMPORARY VARIABLES:

Ft : (3D ndarray) A 2D force array for each thread's local storage.
s : (2D ndarray) The vectors from one body to all others.
s3 : (1D ndarray) The norm of each s vector.

NOTE: Ft is used by parallel algorithms for thread-local
storage. s and s3 are only used by the Python
implementation.
"""
def __init__(self, N, threads=1,
m_min=1, m_max=30.0, r_max=50.0, v_max=4.0, dt=1e-3):
self.threads = threads
self.N = N
self.m = np.random.uniform(m_min, m_max, N)
self.r = np.random.uniform(-r_max, r_max, (N, 2))
self.v = np.random.uniform(-v_max, v_max, (N, 2))
self.F = np.zeros_like(self.r)
self.Ft = np.zeros((threads, N, 2))
self.s = np.zeros_like(self.r)
self.s3 = np.zeros_like(self.m)
self.dt = dt

ÔÚ¿ªÊ¼Ä£Äâʱ£¬NÌå±»Ëæ»ú·ÖÅäÖÊÁ¿m£¬Î»ÖÃrºÍËÙ¶Èv¡£¶ÔÓÚÿ¸öʱ¼ä²½³¤£¬½ÓÏÂÀ´µÄ¼ÆËãÓУº

ºÏÁ¦F£¬Ã¿¸öÌåÉϵĺÏÁ¦¸ù¾ÝËùÓÐÆäËûÌåµÄ¼ÆËã¡£

ËÙ¶Èv£¬ÓÉÓÚÁ¦µÄ×÷ÓÃÿ¸öÌåµÄËٶȱ»¸Ä±ä¡£

λÖÃR£¬ÓÉÓÚËÙ¶Èÿ¸öÌåµÄλÖñ»¸Ä±ä¡£

µÚÒ»²½ÊǼÆËãºÏÁ¦F£¬Õ⽫ÊÇÎÒÃÇµÄÆ¿¾±¡£ÓÉÓÚÊÀ½çÉÏ´æÔ򵀮äËûÎïÌ壬µ¥Ò»ÎïÌåÉϵÄÁ¦ÊÇËùÓÐ×÷ÓÃÁ¦µÄ×ܺ͡£Õâµ¼Ö¸´ÔÓ¶ÈΪO£¨N^2£©¡£ËÙ¶ÈvºÍλÖÃr¸üеĸ´ÔӶȶ¼ÊÇO£¨N£©¡£

Èç¹ûÄãÓÐÐËȤ£¬ÕâÆªÎ¬»ù°Ù¿ÆµÄÎÄÕ½éÉÜÁËһЩ¿ÉÒÔ¼Ó¿ìÁ¦µÄ¼ÆËãµÄ½üËÆ·½·¨¡£

´¿Python

ÔÚ´¿PythonÖУ¬Ê¹ÓÃNumPyÊý×éÊÇʱ¼äÑݱ亯ÊýµÄÒ»ÖÖʵÏÖ·½Ê½£¬ËüΪÓÅ»¯ÌṩÁËÒ»¸öÆðµã£¬²¢Éæ¼°²âÊÔÆäËûʵÏÖ·½Ê½¡£

# lib/sim.py

def compute_F(w):
"""Compute the force on each body in the world, w."""
for i in xrange(w.N):
w.s[:] = w.r - w.r[i]
w.s3[:] = (w.s[:,0]**2 + w.s[:,1]**2)**1.5
w.s3[i] = 1.0 # This makes the self-force zero.
w.F[i] = (w.m[i] * w.m[:,None] * w.s / w.s3[:,None]).sum(0)

def evolve(w, steps):
"""Evolve the world, w, through the given number of steps."""
for _ in xrange(steps):
compute_F(w)
w.v += w.F * w.dt / w.m[:,None]
w.r += w.v * w.dt

ºÏÁ¦¼ÆËãµÄ¸´ÔÓ¶ÈΪO£¨N^2£©µÄÏÖÏó±»NumPyµÄÊý×é·ûºÅËùÑڸǡ£Ã¿¸öÊý×é²Ù×÷±éÀúÊý×éÔªËØ¡£

¿ÉÊÓ»¯

ÕâÀïÊÇ7¸öÎïÌå´ÓËæ»ú³õʼ״̬¿ªÊ¼ÑÝ»¯µÄ·¾¶Í¼£º

ÐÔÄÜ

ΪÁËʵÏÖÕâ¸ö»ù×¼£¬ÎÒÃÇÔÚÏîĿĿ¼Ï´´½¨ÁËÒ»¸ö½Å±¾£¬°üº¬ÈçÏÂÄÚÈÝ£º

import lib
w = lib.World(101)
lib.evolve(w, 4096)

ÎÒÃÇʹÓÃcProfileÄ£¿éÀ´²âÊÔºâÁ¿Õâ¸ö½Å±¾¡£

python -m cProfile -scum bench.py

ǰ¼¸ÐиæËßÎÒÃÇ£¬compute_FȷʵÊÇÎÒÃÇµÄÆ¿¾±£¬ËüÕ¼Á˳¬¹ý99£¥µÄÔËÐÐʱ¼ä¡£

428710 function calls (428521 primitive calls) in 16.836 seconds
Ordered by: cumulative time
ncalls tottime percall cumtime percall filename:lineno(function)
1 0.000 0.000 16.837 16.837 bench.py:2(<module>)
1 0.062 0.062 16.756 16.756 sim.py:60(evolve)
4096 15.551 0.004 16.693 0.004 sim.py:51(compute_F)
413696 1.142 0.000 1.142 0.000 {method 'sum' ...
3 0.002 0.001 0.115 0.038 __init__.py:1(<module>)
...

ÔÚIntel i5̨ʽ»úÉÏÓÐ101Ì壬ÕâÖÖʵÏÖÄܹ»Í¨¹ýÿÃë257¸öʱ¼ä²½³¤ÑÝ»¯ÊÀ½ç¡£

¼òµ¥µÄCÀ©Õ¹ 1

ÔÚ±¾½ÚÖУ¬ÎÒÃǽ«¿´µ½Ò»¸öCÀ©Õ¹Ä£¿éʵÏÖÑÝ»¯µÄ¹¦ÄÜ¡£µ±¿´ÍêÕâÒ»½Úʱ£¬Õâ¿ÉÄܰïÖúÎÒÃÇ»ñµÃÒ»¸öCÎļþµÄ¸±±¾¡£Îļþsrc/simple1.c£¬¿ÉÒÔÔÚGitHubÉÏ»ñµÃ¡£

¹ØÓÚNumPyµÄC APIµÄÆäËûÎĵµ£¬Çë²ÎÔÄNumPyµÄ²Î¿¼¡£PythonµÄC APIµÄÏêϸÎĵµÔÚÕâÀï¡£

Ñù°å

ÎļþÖеĵÚÒ»¼þÊÂÇéÊÇÏÈÉùÃ÷ÑÝ»¯º¯Êý¡£Õ⽫ֱ½ÓÓÃÓÚÏÂÃæµÄ·½·¨ÁÐ±í¡£

static PyObject *evolve(PyObject *self, PyObject *args);

½ÓÏÂÀ´ÊÇ·½·¨ÁÐ±í¡£

static PyMethodDef methods[] = {
{ "evolve", evolve, METH_VARARGS, "Doc string."},
{ NULL, NULL, 0, NULL } /* Sentinel */
};

ÕâÊÇΪÀ©Õ¹Ä£¿éµÄÒ»¸öµ¼³ö·½·¨ÁÐ±í¡£ÕâÖ»ÓÐÒ»¸öÃûΪevolve·½·¨¡£

Ñù°åµÄ×îºóÒ»²¿·ÖÊÇÄ£¿éµÄ³õʼ»¯¡£

PyMODINIT_FUNC initsimple1(void) {
(void) Py_InitModule("simple1", methods);
import_array();
}

ÁíÍ⣬ÕýÈçÕâÀïÏÔʾ£¬initsimple1ÖеÄÃû³Æ±ØÐëÓëPy_InitModuleÖеĵÚÒ»¸ö²ÎÊýÆ¥Åä¡£¶Ôÿ¸öʹÓÃNumPy APIµÄÀ©Õ¹¶øÑÔ£¬µ÷ÓÃimport_arrayÊÇÓбØÒªµÄ¡£

Êý×é·ÃÎʺê

Êý×é·ÃÎʵĺê¿ÉÒÔÔÚÊý×éÖб»ÓÃÀ´ÕýÈ·µØË÷Òý£¬ÎÞÂÛÊý×é±»ÈçºÎÖØËÜ»ò·ÖƬ¡£ÕâЩºêҲʹÓÃÈçϵĴúÂëʹËüÃÇÓиü¸ßµÄ¿É¶ÁÐÔ¡£

#define m(x0) (*(npy_float64*)((PyArray_DATA(py_m) + \
(x0) * PyArray_STRIDES(py_m)[0])))
#define m_shape(i) (py_m->dimensions[(i)])

#define r(x0, x1) (*(npy_float64*)((PyArray_DATA(py_r) + \
(x0) * PyArray_STRIDES(py_r)[0] + \
(x1) * PyArray_STRIDES(py_r)[1])))
#define r_shape(i) (py_r->dimensions[(i)])

ÔÚÕâÀÎÒÃÇ¿´µ½·ÃÎʺêµÄһάºÍ¶þάÊý×é¡£¾ßÓиü¸ßά¶ÈµÄÊý×é¿ÉÒÔÒÔÀàËÆµÄ·½Ê½±»·ÃÎÊ¡£

ÔÚÕâЩºêµÄ°ïÖúÏ£¬ÎÒÃÇ¿ÉÒÔʹÓÃÏÂÃæµÄ´úÂëÑ­»·r:

for(i = 0; i < r_shape(0); ++i) {
for(j = 0; j < r_shape(1); ++j) {
r(i, j) = 0; // Zero all elements.
}
}

ÃüÃû±ê¼Ç

ÉÏÃæ¶¨ÒåµÄºê£¬Ö»ÔÚÆ¥ÅäNumPyµÄÊý×é¶ÔÏó¶¨ÒåÁËÕýÈ·µÄÃû³ÆÊ±²ÅÓÐЧ¡£ÔÚÉÏÃæµÄ´úÂëÖУ¬Êý×é±»ÃüÃûΪpy_mºÍpy_r¡£ÎªÁËÔÚ²»Í¬µÄ·½·¨ÖÐʹÓÃÏàͬµÄºê£¬NumPyÊý×éµÄÃû³ÆÐèÒª±£³ÖÒ»Ö¡£

¼ÆËãÁ¦

ÌØ±ðÊÇÓëÉÏÃæÎåÐеÄPython´úÂëÏà±È£¬¼ÆËãÁ¦Êý×éµÄ·½·¨ÏÔµÃÆÄΪ·±Ëö¡£

static inline void compute_F(npy_int64 N,
                             PyArrayObject *py_m,
                             PyArrayObject *py_r,
                             PyArrayObject *py_F) {
  npy_int64 i, j;
  npy_float64 sx, sy, Fx, Fy, s3, tmp;
 
  // Set all forces to zero. 
  for(i = 0; i < N; ++i) {
    F(i, 0) = F(i, 1) = 0;
  }
 
  // Compute forces between pairs of bodies.
  for(i = 0; i < N; ++i) {
    for(j = i + 1; j < N; ++j) {
      sx = r(j, 0) - r(i, 0);
      sy = r(j, 1) - r(i, 1);
 
      s3 = sqrt(sx*sx + sy*sy);
      s3 *= s3 * s3;
 
      tmp = m(i) * m(j) / s3;
      Fx = tmp * sx;
      Fy = tmp * sy;
 
      F(i, 0) += Fx;
      F(i, 1) += Fy;
 
      F(j, 0) -= Fx;
      F(j, 1) -= Fy;
    }
  }
}

Çë×¢Ò⣬ÎÒÃÇʹÓÃÅ£¶ÙµÚÈý¶¨ÂÉ£¨³É¶Ô³öÏÖµÄÁ¦´óСÏàµÈÇÒ·½ÏòÏà·´£©À´½µµÍÄÚ»··¶Î§¡£²»ÐÒµÄÊÇ£¬ËüµÄ¸´ÔÓ¶ÈÈÔȻΪO£¨N^2£©¡£

ÑÝ»¯º¯Êý

¸ÃÎļþÖеÄ×îºóÒ»¸öº¯ÊýÊǵ¼³öµÄÑÝ»¯·½·¨¡£

static PyObject *evolve(PyObject *self, PyObject *args) {
 
  // Declare variables. 
  npy_int64 N, threads, steps, step, i;
  npy_float64 dt;
  PyArrayObject *py_m, *py_r, *py_v, *py_F;
 
  // Parse arguments. 
  if (!PyArg_ParseTuple(args, "ldllO!O!O!O!",
                        &threads,
                        &dt,
                        &steps,
                        &N,
                        &PyArray_Type, &py_m,
                        &PyArray_Type, &py_r,
                        &PyArray_Type, &py_v,
                        &PyArray_Type, &py_F)) {
    return NULL;
  }
 
  // Evolve the world. 
  for(step = 0;  step< steps; ++step) {
    compute_F(N, py_m, py_r, py_F);
 
    for(i = 0; i < N; ++i) {
      v(i, 0) += F(i, 0) * dt / m(i);
      v(i, 1) += F(i, 1) * dt / m(i);
 
      r(i, 0) += v(i, 0) * dt;
      r(i, 1) += v(i, 1) * dt;
    }
  }
 
  Py_RETURN_NONE;
}

ÔÚÕâÀÎÒÃÇ¿´µ½ÁËPython²ÎÊýÈçºÎ±»½âÎö¡£Ôڸú¯Êýµ×²¿µÄʱ¼ä²½³¤Ñ­»·ÖУ¬ÎÒÃÇ¿´µ½µÄËٶȺÍλÖÃÏòÁ¿µÄxºÍy·ÖÁ¿µÄÏÔʽ¼ÆËã¡£

ÐÔÄÜ

C°æ±¾µÄÑÝ»¯·½·¨±ÈPython°æ±¾¸ü¿ì£¬ÕâÓ¦¸Ã²»×ãÎªÆæ¡£ÔÚÉÏÃæÌáµ½µÄÏàͬµÄi5̨ʽ»úÖУ¬CʵÏÖµÄÑÝ»¯·½·¨Äܹ»ÊµÏÖÿÃë17972¸öʱ¼ä²½³¤¡£Ïà±ÈPythonʵÏÖ£¬Õâ·½ÃæÓÐ70±¶µÄÌáÉý¡£

¹Û²ì

×¢Ò⣬C´úÂëÒ»Ö±±£³Ö¾¡¿ÉÄܵļòµ¥¡£ÊäÈë²ÎÊýºÍÊä³ö¾ØÕó¿ÉÒÔ½øÐÐÀàÐͼì²é£¬²¢·ÖÅäÒ»¸öPython×°ÊÎÆ÷º¯Êý¡£É¾³ý·ÖÅ䣬²»½öÄܼӿ촦Àí£¬¶øÇÒÏû³ýÁËÓÉPython¶ÔÏó²»ÕýÈ·µÄÒýÓüÆÊýÔì³ÉµÄÄÚ´æÐ¹Â¶£¨»ò¸üÔ㣩¡£

 

   
3032 ´Îä¯ÀÀ       29
Ïà¹ØÎÄÕÂ

Éî¶È½âÎö£ºÇåÀíÀôúÂë
ÈçºÎ±àд³öÓµ±§±ä»¯µÄ´úÂë
ÖØ¹¹-ʹ´úÂë¸ü¼ò½àÓÅÃÀ
ÍŶÓÏîÄ¿¿ª·¢"±àÂë¹æ·¶"ϵÁÐÎÄÕÂ
Ïà¹ØÎĵµ

ÖØ¹¹-¸ÄÉÆ¼ÈÓдúÂëµÄÉè¼Æ
Èí¼þÖØ¹¹v2
´úÂëÕû½àÖ®µÀ
¸ßÖÊÁ¿±à³Ì¹æ·¶
Ïà¹Ø¿Î³Ì

»ùÓÚHTML5¿Í»§¶Ë¡¢Web¶ËµÄÓ¦Óÿª·¢
HTML 5+CSS ¿ª·¢
ǶÈëʽC¸ßÖÊÁ¿±à³Ì
C++¸ß¼¶±à³Ì
×îл¼Æ»®
DeepSeekÔÚÈí¼þ²âÊÔÓ¦ÓÃʵ¼ù 4-12[ÔÚÏß]
DeepSeek´óÄ£ÐÍÓ¦Óÿª·¢Êµ¼ù 4-19[ÔÚÏß]
UAF¼Ü¹¹ÌåϵÓëʵ¼ù 4-11[±±¾©]
AIÖÇÄÜ»¯Èí¼þ²âÊÔ·½·¨Óëʵ¼ù 5-23[ÉϺ£]
»ùÓÚ UML ºÍEA½øÐзÖÎöÉè¼Æ 4-26[±±¾©]
ÒµÎñ¼Ü¹¹Éè¼ÆÓ뽨ģ 4-18[±±¾©]

WEBÓ¦ÓóÌÐòUIÄ£°æ´úÂë±àд
C# ±àÂë¹æ·¶ºÍ±à³ÌºÃϰ¹ß
ʲôÊÇ·ÀÓùÐÔ±à³Ì
ÉÆÓÚ·ÀÊØ-½¡×³´úÂëµÄ·ÀÓùÐÔ
Visual C++±à³ÌÃüÃû¹æÔò
JavaScript³ÌÐò±àÂë¹æ·¶


Éè¼ÆÄ£Ê½Ô­ÀíÓëÓ¦ÓÃ
´ÓÐèÇó¹ý¶Éµ½Éè¼Æ
Èí¼þÉè¼ÆÔ­ÀíÓëʵ¼ù
ÈçºÎ±àд¸ßÖÊÁ¿´úÂë
µ¥Ôª²âÊÔ¡¢Öع¹¼°³ÖÐø¼¯³É
Èí¼þ¿ª·¢¹ý³ÌÖ¸ÄÏ


ijȫÇòÖªÃûͨÐŹ«Ë¾ ´úÂëÕû½à
ºáºÓµç»ú ÈçºÎ±àд¸ßÖÊÁ¿´úÂë
ij֪Ãû½ðÈÚÈí¼þ·þÎñÉÌ ´úÂëÆÀÉó
¶«Èí¼¯ÍÅ ´úÂëÖØ¹¹
ij½ðÈÚÈí¼þ·þÎñÉÌ ¼¼ÊõÎĵµ
Öдïµçͨ Éè¼ÆÄ£Ê½Ô­ÀíÓëʵ¼ù
·¨¹úµçÐÅ ¼¼ÊõÎĵµ±àдÓë¹ÜÀí