[Numpy-discussion] problem with view() and strided arrays?
Zachary Pincus
zachary.pincus@yale....
Fri Apr 25 08:36:39 CDT 2008
Hi all,
> Actually -- it seems like view() doesn't work with strided arrays at
> all. (?)
>
> In : a = numpy.ones((4,32), dtype=numpy.uint8)
>
> In : a.view(numpy.uint16).shape
> Out: (4, 16)
>
> In : a[:,:16].view(numpy.uint16)
> ValueError: new type not compatible with array.
>
> I think this might be a recent regression, because before I updated my
> numpy installation to the latest SVN version (to check if the bug was
> fixed!), I'm pretty sure this kind of operation worked.
The problem starts out in arrayobject.c:6392, in array_descr_set(),
where the following test is performed:
if ((newtype->elsize != self->descr->elsize) && \
(self->nd == 0 || !PyArray_ISONESEGMENT(self) || \
newtype->subarray)) goto fail;
I *think* I could fix it by relaxing the restrictions to only require
that the array have at least one dimension where self->strides[dim] ==
self->descr->elsize, and then adjust the size of that dimension.
Here's my perhaps-fix. The old code is:
if ((newtype->elsize != self->descr->elsize) && \
(self->nd == 0 || !PyArray_ISONESEGMENT(self) || \
newtype->subarray)) goto fail;
if (PyArray_ISCONTIGUOUS(self)) index = self->nd - 1;
else index = 0;
My suggested fix is:
if ((newtype->elsize != self->descr->elsize) && \
(self->nd == 0 || newtype->subarray)) goto fail;
if (PyArray_ISCONTIGUOUS(self)) index = self->nd - 1;
else if (PyArray_ISFORTRAN(self)) index = 0;
else {
int index_found = FALSE;
for (index = 0; index < self->nd; index++) {
if (self->strides[index] == self->descr->elsize) {
index_found = TRUE;
break;
}
}
if (!index_found) goto fail;
}
Could someone look this over? If it looks basically right, I'll make
this a proper patch and post it to trac.
Thanks,
Zach
More information about the Numpy-discussion
mailing list