M
Maarten van Reeuwijk
I am constructing a "placeholder array" to mimick Numeric arrays. I have a
3D regular structured domain, so I can describe the axis with 3 1D arrays
x[], y[] and z[]. All the variables defined on this field (temperature,
velocity) are 3D-fields, and to treat everything the same, I want to have
x,y and z also as a 3d-array. However, as one field is typically 100 Mb, I
do not want to create these arrays, but instead define a class that mimicks
this.
I have succeeded in doing this (see code below), but now I want to transfer
any unknown class methods to the in-line created variable, something like:
def process_unknownmethod(self, method, args)
exec(self[:].method(args))
How do I do this in python?
TIA, Maarten
Here's the class (sorry for the long class)
from Numeric import *
class PlaceHolder:
def __init__(self, axis, dims, arr):
self.axis = axis
self.arr = arr
self.dims = dims
def __interpretkey(self, axis, key):
if type(key) == int:
sl = slice(key, key+1,1)
else:
# interpret the slice object
start = key.start
if (start == None):
if not (key.stop == None):
start = key.stop
else:
start == 0
if start < 0:
if start > - self.dims[axis]:
start = self.dims[axis] + start
else:
start = 0
stop = key.stop
if stop == None or stop == sys.maxint:
stop = self.dims[axis]
if stop < 0:
if stop > - self.dims[axis]:
stop = self.dims[axis] + stop
else:
stop = 0
step = key.step
if not step: step = 1
sl = slice(start, stop, step)
return sl
def __getitem__(self, key):
sl = []
# if it's only one argument, make it into a tuple
if not ((type(key) == tuple) or (type(key) == list)):
key = (key,)
# determine ranges
for i, rng in enumerate(key):
sl.append(self.__interpretkey(i, rng))
# extend for missing dimensions
for i in range(len(key), len(self.dims)):
sl.append(slice(0, self.dims, 1))
# swap values for indices
sl[0], sl[self.axis] = sl[self.axis], sl[0]
base = self.arr[sl[0]]
# create an array
for n, i in enumerate(sl):
l = int(abs(float(i.stop - i.start)) / abs(i.step)+0.5)
if n > 0:
base = add.outer(base, zeros(l))
base = swapaxes(base, 0, self.axis)
# remove the dimensions of length 1
rdims = []
for i in range(rank(base)):
if base.shape <= 1:
rdims.append(i)
rdims.sort()
rdims.reverse()
for i in rdims:
base = add.reduce(base, i)
return base
# example starts here
a = arange(10.)
y = PlaceHolder(1, [10, 10, 10], a)
print y[1, :, 10]
print y[1, 3]
3D regular structured domain, so I can describe the axis with 3 1D arrays
x[], y[] and z[]. All the variables defined on this field (temperature,
velocity) are 3D-fields, and to treat everything the same, I want to have
x,y and z also as a 3d-array. However, as one field is typically 100 Mb, I
do not want to create these arrays, but instead define a class that mimicks
this.
I have succeeded in doing this (see code below), but now I want to transfer
any unknown class methods to the in-line created variable, something like:
def process_unknownmethod(self, method, args)
exec(self[:].method(args))
How do I do this in python?
TIA, Maarten
Here's the class (sorry for the long class)
from Numeric import *
class PlaceHolder:
def __init__(self, axis, dims, arr):
self.axis = axis
self.arr = arr
self.dims = dims
def __interpretkey(self, axis, key):
if type(key) == int:
sl = slice(key, key+1,1)
else:
# interpret the slice object
start = key.start
if (start == None):
if not (key.stop == None):
start = key.stop
else:
start == 0
if start < 0:
if start > - self.dims[axis]:
start = self.dims[axis] + start
else:
start = 0
stop = key.stop
if stop == None or stop == sys.maxint:
stop = self.dims[axis]
if stop < 0:
if stop > - self.dims[axis]:
stop = self.dims[axis] + stop
else:
stop = 0
step = key.step
if not step: step = 1
sl = slice(start, stop, step)
return sl
def __getitem__(self, key):
sl = []
# if it's only one argument, make it into a tuple
if not ((type(key) == tuple) or (type(key) == list)):
key = (key,)
# determine ranges
for i, rng in enumerate(key):
sl.append(self.__interpretkey(i, rng))
# extend for missing dimensions
for i in range(len(key), len(self.dims)):
sl.append(slice(0, self.dims, 1))
# swap values for indices
sl[0], sl[self.axis] = sl[self.axis], sl[0]
base = self.arr[sl[0]]
# create an array
for n, i in enumerate(sl):
l = int(abs(float(i.stop - i.start)) / abs(i.step)+0.5)
if n > 0:
base = add.outer(base, zeros(l))
base = swapaxes(base, 0, self.axis)
# remove the dimensions of length 1
rdims = []
for i in range(rank(base)):
if base.shape <= 1:
rdims.append(i)
rdims.sort()
rdims.reverse()
for i in rdims:
base = add.reduce(base, i)
return base
# example starts here
a = arange(10.)
y = PlaceHolder(1, [10, 10, 10], a)
print y[1, :, 10]
print y[1, 3]