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 submatrix 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("Size %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 *= sizes[ii]
if not dodim and shape[ii] != sizes[ii]:
dodim = ii
# 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:
data.extend(self.size*[self.defaultValue])
# check value types
if [x for x in values if not isinstance(x,(float,int))]:
raise ApiError("Non-numeric values passed to setSubmatrixData: %s" % list(set(x for x in values if not isinstance(x,(float,int)))))
if dodim <= 0:
# set single stretch from 1D array
data[offset:offset+stretch] =values
else:
# do work for ndim array
# check length and type of values
import operator
subsize = reduce(operator.mul, shape)
if len(values) != subsize:
raise ApiError("Number of values %s do not fit submatrix shape %s" % (subsize, shape))
# set up multidimensional loop
vector = (dodim)*[0]
dim = dim0 = dodim - 1
target = 0
while dim >= 0:
# do actual work
next = target+stretch
data[offset:offset+stretch] = values[target:next]
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
|