Statistiques
| Révision :

root / Ising / Numpy-C / array_module_np.c @ 96

Historique | Voir | Annoter | Télécharger (5,28 ko)

1 18 equemene
/*  Example of change values in array in the Numpy-C-API. */
2 18 equemene
/* http://scipy-lectures.github.io/advanced/interfacing_with_c/interfacing_with_c.html */
3 18 equemene
/* http://dsnra.jpl.nasa.gov/software/Python/numpydoc/numpy-13.html */
4 18 equemene
/* http://enzo.googlecode.com/.../Grid_ConvertToNumpy.C */
5 18 equemene
/* http://docs.scipy.org/doc/numpy/reference/c-api.array.html#data-access */
6 18 equemene
7 18 equemene
/*
8 18 equemene
   What is absolutely necessary to know:
9 18 equemene
   -
10 18 equemene
*/
11 18 equemene
12 18 equemene
#include <Python.h>
13 18 equemene
#include <numpy/arrayobject.h>
14 18 equemene
#include <math.h>
15 18 equemene
#include <stdio.h>
16 18 equemene
#include <sys/time.h>
17 18 equemene
18 18 equemene
/* All RNG numbers of Marsaglia are Unsigned int32 ! */
19 18 equemene
#define znew  ((z=36969*(z&65535)+(z>>16))<<16)
20 18 equemene
#define wnew  ((w=18000*(w&65535)+(w>>16))&65535)
21 18 equemene
#define MWC   (znew+wnew)
22 18 equemene
#define SHR3  (jsr=(jsr=(jsr=jsr^(jsr<<17))^(jsr>>13))^(jsr<<5))
23 18 equemene
#define CONG  (jcong=69069*jcong+1234567)
24 18 equemene
#define KISS  ((MWC^CONG)+SHR3)
25 18 equemene
#define LFIB4 (t[c]=t[c]+t[c+58]+t[c+119]+t[++c+178])
26 18 equemene
#define SWB   (t[c+237]=(x=t[c+15])-(y=t[++c]+(x<y)))
27 18 equemene
#define UNI   (KISS*2.328306e-10)
28 18 equemene
#define VNI   ((long) KISS)*4.656613e-10
29 18 equemene
30 18 equemene
#define MWCfp (float)MWC * 2.328306435454494e-10f
31 18 equemene
#define KISSfp (float)KISS * 2.328306435454494e-10f
32 18 equemene
#define SHR3fp (float)SHR3 * 2.328306435454494e-10f
33 18 equemene
34 18 equemene
// static PyObject* array_metropolis_np(PyObject* self, PyObject *args)
35 18 equemene
static PyObject* array_metropolis_np(PyObject* self, PyObject *args)
36 18 equemene
{
37 18 equemene
38 18 equemene
  PyObject *in_array;
39 18 equemene
  PyArrayObject *local;
40 18 equemene
  unsigned int z,w;
41 18 equemene
  long iterations=1;
42 18 equemene
  int seed_w=521288629,seed_z=362436069,jcong=380116160,jsr=123456789;
43 18 equemene
  int factor;
44 18 equemene
  float B=0,J=0,T=0;
45 18 equemene
  double elapsed=0;
46 18 equemene
  unsigned long i;
47 18 equemene
  struct timeval tv1,tv2;
48 18 equemene
  struct timezone tz;
49 18 equemene
50 18 equemene
  /*  parse single numpy array argument */
51 18 equemene
  /* http://docs.python.org/release/1.5.2p2/ext/parseTuple.html */
52 18 equemene
  /* O for in_array */
53 18 equemene
  /* fff  for 3 float values (Coupling, Magnetic Field, Temperature)*/
54 18 equemene
  /* l for 1 long int value (iterations) */
55 18 equemene
  /* ii for 2 int values (2 seeds) */
56 18 equemene
  if (!PyArg_ParseTuple(args, "Offflii", &in_array,
57 18 equemene
                        &J,&B,&T,&iterations,&seed_w,&seed_z))
58 18 equemene
    {
59 18 equemene
      printf("Not null argument provided !\n");
60 18 equemene
      return NULL;
61 18 equemene
    }
62 18 equemene
63 18 equemene
  /* display the extra parameters */
64 18 equemene
  printf("Parameters for physics: J=%f\nB=%f\nT=%f\n",J,B,T);
65 18 equemene
  printf("Parameters for simulation: iterations=%ld\nseed_w=%i\nseed_z=%i\n",
66 18 equemene
         iterations,seed_w,seed_z);
67 18 equemene
68 18 equemene
  local = (PyArrayObject *) PyArray_ContiguousFromAny(in_array, NPY_INT32, 2, 2);
69 18 equemene
70 18 equemene
71 18 equemene
  if (PyArray_NDIM(local)!=2) {
72 18 equemene
    printf("This simulation is only for 2D arrays !\n");
73 18 equemene
    return NULL;
74 18 equemene
  }
75 18 equemene
76 18 equemene
  npy_intp size_x=*(npy_intp *)(PyArray_DIMS(local));
77 18 equemene
  npy_intp size_y=*(npy_intp *)(PyArray_DIMS(local)+1);
78 18 equemene
  /* Cast necessary, PyArg_ParseTuple() does not support any unsigned type ! */
79 18 equemene
  w=(unsigned int)seed_w;
80 18 equemene
  z=(unsigned int)seed_z;
81 18 equemene
82 18 equemene
  gettimeofday(&tv1, &tz);
83 18 equemene
  printf("Simulation started: ...");
84 18 equemene
85 18 equemene
  for (i=0;i<(unsigned long)iterations;i++) {
86 18 equemene
87 18 equemene
    npy_intp x=MWC%size_x ;
88 18 equemene
    npy_intp y=MWC%size_y ;
89 18 equemene
90 18 equemene
    int p=*(int *)PyArray_GETPTR2(local,x,y);
91 18 equemene
92 18 equemene
    int d=*(int *)PyArray_GETPTR2(local,x,(y+1)%size_y);
93 18 equemene
    int u=*(int *)PyArray_GETPTR2(local,x,(y-1)%size_y);
94 18 equemene
    int l=*(int *)PyArray_GETPTR2(local,(x-1)%size_x,y);
95 18 equemene
    int r=*(int *)PyArray_GETPTR2(local,(x+1)%size_x,y);
96 18 equemene
97 18 equemene
    float DeltaE=J*(float)p*(2.*(float)(u+d+l+r)+B);
98 18 equemene
99 18 equemene
    factor=((DeltaE < 0.0f) || (MWCfp < exp(-DeltaE/T))) ? -1:1;
100 18 equemene
101 18 equemene
    *(int *)PyArray_GETPTR2(local,x,y)=(factor*p);
102 18 equemene
  }
103 18 equemene
  gettimeofday(&tv2, &tz);
104 18 equemene
  elapsed=(double)((tv2.tv_sec-tv1.tv_sec) * 1000000L +        \
105 18 equemene
                   (tv2.tv_usec-tv1.tv_usec))/1000000.;
106 18 equemene
  printf("done in %.2f seconds !\n",elapsed);
107 18 equemene
108 18 equemene
  return PyArray_Return(local);
109 18 equemene
110 18 equemene
}
111 18 equemene
112 18 equemene
static PyObject* array_display_np(PyObject* self, PyObject *args)
113 18 equemene
{
114 18 equemene
115 18 equemene
  PyObject *in_array;
116 18 equemene
  PyArrayObject      *local;
117 18 equemene
  unsigned int i,x,y;
118 18 equemene
119 18 equemene
  /*  parse single numpy array argument */
120 18 equemene
  /* http://docs.python.org/release/1.5.2p2/ext/parseTuple.html */
121 18 equemene
  /* O for in_array */
122 18 equemene
  if (!PyArg_ParseTuple(args, "O", &in_array)) {
123 18 equemene
    printf("Not null argument provided !\n");
124 18 equemene
    return NULL;
125 18 equemene
  }
126 18 equemene
127 18 equemene
  local = (PyArrayObject *) PyArray_ContiguousFromObject(in_array, PyArray_NOTYPE, 2, 2);
128 18 equemene
129 18 equemene
  /* display the size of array */
130 18 equemene
  printf("Array has %i dimension(s) : size of ",PyArray_NDIM(local));
131 18 equemene
  if (PyArray_NDIM(local)==1) {
132 18 equemene
      printf("%i\n",(int)*(PyArray_DIMS(local)));
133 18 equemene
  }
134 18 equemene
  else {
135 18 equemene
    for (i=0;i<PyArray_NDIM(local)-1;i++) {
136 18 equemene
      printf("%ix",(int)*(PyArray_DIMS(local)+i));
137 18 equemene
    }
138 18 equemene
    printf("%i\n",(int)*(PyArray_DIMS(local)+PyArray_NDIM(local)-1));
139 18 equemene
  }
140 18 equemene
141 18 equemene
  /* display the array */
142 18 equemene
  printf("[");
143 18 equemene
  for (x=0;x<(unsigned int)(int)*(PyArray_DIMS(local));x++) {
144 18 equemene
    printf("[");
145 18 equemene
    for (y=0;y<(unsigned int)(int)*(PyArray_DIMS(local)+1);y++)
146 18 equemene
      printf("%2i ",* (int *)PyArray_GETPTR2(local,x,y));
147 18 equemene
    printf("]\n ");
148 18 equemene
  }
149 18 equemene
  printf("]\n");
150 18 equemene
151 18 equemene
  // Py_INCREF(local);
152 18 equemene
153 18 equemene
  /*  construct the output array, like the input array */
154 18 equemene
  return PyArray_Return(local);
155 18 equemene
156 18 equemene
}
157 18 equemene
158 18 equemene
159 18 equemene
/*  define functions in module */
160 18 equemene
static PyMethodDef ArrayMethods[] =
161 18 equemene
{
162 18 equemene
     {"array_metropolis_np", array_metropolis_np, METH_VARARGS,
163 18 equemene
         "evaluate a metropolis simulation on a numpy array"},
164 18 equemene
     {"array_display_np", array_display_np, METH_VARARGS,
165 18 equemene
         "evaluate a metropolis simulation on a numpy array"},
166 18 equemene
     {NULL, NULL, 0, NULL}
167 18 equemene
};
168 18 equemene
169 18 equemene
/* module initialization */
170 18 equemene
PyMODINIT_FUNC
171 18 equemene
172 18 equemene
initarray_module_np(void)
173 18 equemene
{
174 18 equemene
     (void) Py_InitModule("array_module_np", ArrayMethods);
175 18 equemene
     /* IMPORTANT: this must be called */
176 18 equemene
     import_array();
177 18 equemene
}