Code:
|
# get starting offset and normalise point -
# padding with zero and converting to positive indices
offset = self.pointToIndex(point)
point = self.indexToPoint(offset)
# set up internal params
ndim = self.ndim
sizes = self.shape
# set widths and check
shape = list(shape)
if len(shape) > ndim:
raise ApiError("Number of dimensions %s exceeds ndim %s" % (shape,ndim))
for ii,width in enumerate(shape):
if not width:
shape[ii] = sizes[ii] - point[ii]
elif width < 0 or width > sizes[ii] - point[ii]:
raise ApiError("Width %s in dim %s out of permitted range" % (width,ii))
# Extend shape, padding to dimension sizes.
shape.extend(sizes[ii] - point[ii] for ii in range(len(shape),ndim))
# set up strides list and lowest dim with continuous data.
strides = ndim*[0]
factor = 1
dodim = 0
for ii in range(ndim-1,-1,-1):
strides[ii] = factor
factor *= shape[ii]
if not dodim and shape[ii] != sizes[ii]:
dodim = ii
size = factor
# length of contiguous stretch
stretch = strides[dodim] * shape[dodim]
# get hold of data (must bypass API for speed)
data = self.__dict__['data']
if not data:
# default-only matrix
result = size*(self.defaultValue,)
else:
if dodim <= 0:
# take single stretch from 1D array
result = data[offset:offset+stretch]
else:
# do work for ndim array
# set up result list (optimisation - could be done with extend instead)
import operator
subsize = reduce(operator.mul, shape)
result = subsize*[None]
# set up multidimensional loop
vector = (dodim)*[0]
dim = dim0 = dodim - 1
target = 0
while dim >= 0:
# do actual work
next = target+stretch
result[target:next] = data[offset:offset+stretch]
target = next
# update reading offset
vector[dim] += 1
if vector[dim] < shape[dim]:
offset += strides[dim]
if dim < dim0:
dim += 1
else:
vector[dim] = 0
dim -=1
#
result = tuple(result)
|