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