[Numpy-discussion] PyArray_ContiguousFromObject & PyDECREF

Michiel Jan Laurens de Hoon mdehoon at ims.u-tokyo.ac.jp
Sun Nov 30 22:13:05 EST 2003


Dear pythoneers,

In Chapter 12 ("Writing a C extension") in the Numerical Python manual, in the 
first example PyArray_ContiguousFromObject is used together with PyDECREF, while 
in the last example PyArray_ContiguousFromObject is used but the arrays are not 
PyDECREF'ed before the function returns. From Chapter 13 ("C API Reference") it 
seems that a PyDECREF is needed in both cases. Or am I missing something here? 
Is PyDECREF not needed for some reason in the last example?

Thanks in advance,

Michiel de Hoon
U Tokyo

First example:
==============
static PyObject *
trace(PyObject *self, PyObject *args)
{
   PyObject *input;
   PyArrayObject *array;
   double sum;
   int i, n;
   if (!PyArg_ParseTuple(args, "O", &input))
     return NULL;
   array = (PyArrayObject *)
           PyArray_ContiguousFromObject(input, PyArray_DOUBLE, 2, 2);
   if (array == NULL)
     return NULL;
   n = array->dimensions[0];
   if (n > array->dimensions[1])
     n = array->dimensions[1];
   sum = 0.;
   for (i = 0; i < n; i++)
     sum += *(double *)(array->data + i*array->strides[0] + i*array->strides[1]);
   Py_DECREF(array);
   return PyFloat_FromDouble(sum);
}


Last example:
=============
static PyObject *
matrix_vector(PyObject *self, PyObject *args)
{
   PyObject *input1, *input2;
   PyArrayObject *matrix, *vector, *result;
   int dimensions[1];
   double factor[1];
   double real_zero[1] = {0.};
   long int_one[1] = {1};
   long dim0[1], dim1[1];
   extern dgemv_(char *trans, long *m, long *n,
                 double *alpha, double *a, long *lda,
                 double *x, long *incx,
                 double *beta, double *Y, long *incy);
   if (!PyArg_ParseTuple(args, "dOO", factor, &input1, &input2))
     return NULL;
   matrix = (PyArrayObject *)
     PyArray_ContiguousFromObject(input1, PyArray_DOUBLE, 2, 2);
   if (matrix == NULL)
     return NULL;
   vector = (PyArrayObject *)
             PyArray_ContiguousFromObject(input2, PyArray_DOUBLE, 1, 1);
   if (vector == NULL)
     return NULL;
   if (matrix->dimensions[1] != vector->dimensions[0]) {
     PyErr_SetString(PyExc_ValueError,
                     "array dimensions are not compatible");
     return NULL;
   }
   dimensions[0] = matrix->dimensions[0];
   result = (PyArrayObject *)PyArray_FromDims(1, dimensions, PyArray_DOUBLE);
   if (result == NULL)
     return NULL;
   dim0[0] = (long)matrix->dimensions[0];
   dim1[0] = (long)matrix->dimensions[1];
   dgemv_("T", dim1, dim0, factor, (double *)matrix->data, dim1,
          (double *)vector->data, int_one,
          real_zero, (double *)result->data, int_one);
   return PyArray_Return(result);
}


-- 
Michiel de Hoon, Assistant Professor
University of Tokyo, Institute of Medical Science
Human Genome Center
4-6-1 Shirokane-dai, Minato-ku
Tokyo 108-8639
Japan
http://bonsai.ims.u-tokyo.ac.jp/~mdehoon






More information about the NumPy-Discussion mailing list