Statistiques
| Révision :

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

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
}