# [Numpy-discussion] PyArray_ContiguousFromObject & PyDECREF

Michiel Jan Laurens de Hoon mdehoon at ims.u-tokyo.ac.jp
Sun Nov 30 22:13:05 CST 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?

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

```