root / Ising / Numpy-C / array_module_np.c @ 97
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 | } |