# [Numpy-discussion] Striding on NumArray objects

Todd Miller jmiller at stsci.edu
Tue Dec 21 12:22:03 CST 2004

```> > This is a difficult question for me,  but I think the answer is that
the
> > use of _bytestride is very limited.  _bytestride is used to compute
the
> > "natural" strides of an almost contiguous array, e.g. a field of a
> > recarray.   That is,  given a bytestride and a shape,  the strides
of a
> > field of a contiguous RecArray are implied.
>
> Yes, I was trying to use _bytestride mainly in RecArray contexts. It
just
> happens that I've used a NumArray object to check the _bytestride
behaviour.
>
> > However,  once we start slicing (say in more than one dimension),
> > _strides contains more and more information and is no longer implied
by
> > just the shape and bytestride but also by the history of slicing.
From
> > that perspective,  it's not clear what _bytestride can be relied
upon
> > for in general or that it needs to be (or can be) kept up to date
during
> > slicing.
>
> Well, for the time being it seems that RecArray does not support
> multidimensionalty, so I can just use _bytestride as a shortcut of
> _strides[0] here.

I wouldn't.

I had a veritable stroke of genius and talked to JC Hsu...  He suggested
doing concrete examples and also indicated that full multi-dimensional
RecArray support is almost all (except for repr'ing) there.

To be clear,  in general,  _bytestride != _itemsize.    For a RecArray
field (of a contiguous RecArray) where each row contains just one
element,  generally _strides[-1] == _bytestride != _itemsize:

>>> r = rec.array(buffer=None, formats="i2,(3,4)f4,a3", shape=10)
>>> r.field(0).info()
class: <class 'numarray.numarraycore.NumArray'>
shape: (10,)
strides: (53,)
byteoffset: 0
bytestride: 53
itemsize: 2
aligned: 0
contiguous: 0
data: <memory at 0x08256c10 with size:0x00000212 held by object 0x40764db8 aliasing object 0x00000000>
byteorder: little
byteswap: 0
type: Int16

For a RecArray field where each row contains more than one element,
_strides[-1] == itemsize:

>>> r.field(1).info()
class: <class 'numarray.numarraycore.NumArray'>
shape: (10, 3, 4)
strides: (53, 16, 4)
byteoffset: 2
bytestride: 53
itemsize: 4
aligned: 0
contiguous: 0
data: <memory at 0x08256978 with size:0x00000212 held by object 0x407613a8 aliasing object 0x00000000>
byteorder: little
byteswap: 0
type: Float32

The situation gets more complicated still when someone starts slicing
the field or RecArray:

>>> x[::3].info()
class: <class 'numarray.numarraycore.NumArray'>
shape: (4, 3, 4)
strides: (159, 16, 4)
byteoffset: 2
bytestride: 53
itemsize: 4
aligned: 0
contiguous: 0
data: <memory at 0x08256c10 with size:0x00000212 held by object
0x40764db8 aliasing object 0x00000000>
byteorder: little
byteswap: 0
type: Float32

Multi-dimensional RecArrays add their own twist:

>>> r = rec.array(buffer=None, formats="i2,(3,4)f4,a3",shape=(10,10,10))
>>> r.field(1).info()
class: <class 'numarray.numarraycore.NumArray'>
shape: (10, 10, 10, 3, 4)
strides: (5300, 480, 48, 16, 4)
byteoffset: 2
bytestride: 53
itemsize: 4
aligned: 0
contiguous: 0
data: <memory at 0x08257dd0 with size:0x0000cf08 held by object 0x40763a70 aliasing object 0x00000000>
byteorder: little
byteswap: 0
type: Float32

HTH,
Todd

```