Python C extension to compute the permanent.
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

permanent.c 3.2KB

il y a 9 ans
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106
  1. /* Computes the permanent, given a numpy array */
  2. #include <Python.h>
  3. #include <numpy/arrayobject.h>
  4. #include <math.h>
  5. // Forward function declaration.
  6. static PyObject *permanent(PyObject *self, PyObject *args);
  7. // Boilerplate: method list.
  8. static PyMethodDef methods[] = {
  9. { "permanent", permanent, METH_VARARGS, "Compute the permanent"},
  10. { NULL, NULL, 0, NULL } /* Sentinel */
  11. };
  12. // Boilerplate: Module initialization.
  13. PyMODINIT_FUNC initpermanent(void) {
  14. (void) Py_InitModule("permanent", methods);
  15. import_array();
  16. }
  17. /*****************************************************************************
  18. * Array access macros. *
  19. *****************************************************************************/
  20. #define m(x0) (*(npy_float64*)((PyArray_DATA(py_m) + \
  21. (x0) * PyArray_STRIDES(py_m)[0])))
  22. #define m_shape(i) (py_m->dimensions[(i)])
  23. #define r(x0, x1) (*(npy_float64*)((PyArray_DATA(py_r) + \
  24. (x0) * PyArray_STRIDES(py_r)[0] + \
  25. (x1) * PyArray_STRIDES(py_r)[1])))
  26. #define r_shape(i) (py_r->dimensions[(i)])
  27. #define v(x0, x1) (*(npy_float64*)((PyArray_DATA(py_v) + \
  28. (x0) * PyArray_STRIDES(py_v)[0] + \
  29. (x1) * PyArray_STRIDES(py_v)[1])))
  30. #define v_shape(i) (py_v->dimensions[(i)])
  31. #define F(x0, x1) (*(npy_float64*)((PyArray_DATA(py_F) + \
  32. (x0) * PyArray_STRIDES(py_F)[0] + \
  33. (x1) * PyArray_STRIDES(py_F)[1])))
  34. #define F_shape(i) (py_F->dimensions[(i)])
  35. /*****************************************************************************
  36. * compute_F *
  37. *****************************************************************************/
  38. static inline void compute_F(npy_int64 N,
  39. PyArrayObject *py_m,
  40. PyArrayObject *py_r,
  41. PyArrayObject *py_F) {
  42. npy_int64 i, j;
  43. npy_float64 sx, sy, Fx, Fy, s3, tmp;
  44. // Set all forces to zero.
  45. for(i = 0; i < N; ++i) {
  46. F(i, 0) = F(i, 1) = 0;
  47. }
  48. // Compute forces between pairs of bodies.
  49. for(i = 0; i < N; ++i) {
  50. for(j = i + 1; j < N; ++j) {
  51. sx = r(j, 0) - r(i, 0);
  52. sy = r(j, 1) - r(i, 1);
  53. s3 = sqrt(sx*sx + sy*sy);
  54. s3 *= s3 * s3;
  55. tmp = m(i) * m(j) / s3;
  56. Fx = tmp * sx;
  57. Fy = tmp * sy;
  58. F(i, 0) += Fx;
  59. F(i, 1) += Fy;
  60. F(j, 0) -= Fx;
  61. F(j, 1) -= Fy;
  62. }
  63. }
  64. }
  65. static PyObject *permanent(PyObject *self, PyObject *args) {
  66. // Declare variables.
  67. npy_int64 d, i, j;
  68. npy_float64 output;
  69. PyArrayObject *submatrix;
  70. // Parse variables.
  71. if (!PyArg_ParseTuple(args, "ldllO!O!O!O!",
  72. &threads,
  73. &dt,
  74. &steps,
  75. &N,
  76. &PyArray_Type, &submatrix)) {
  77. return NULL;
  78. }
  79. // Compute the permanent
  80. for(i = 0; i < d; ++i) {
  81. for(j = 0; j<d; ++j) {
  82. }
  83. }
  84. Py_RETURN_NONE;
  85. }