Functional plane
parent
863d974281
commit
dd6d4936fb
47
src/plane.py
47
src/plane.py
|
@ -24,27 +24,22 @@ class Plane:
|
||||||
numpy grid, without the same bloat as a straightforward N-dimensional grid of booleans for instance.
|
numpy grid, without the same bloat as a straightforward N-dimensional grid of booleans for instance.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, size, N):
|
def __init__(self, shape):
|
||||||
"""
|
"""
|
||||||
Construction of a plane. There are three cases:
|
Construction of a plane. There are three cases:
|
||||||
|
|
||||||
If N == 0: We have an undefined plane. Nothing is in it.
|
If shape is the empty tuple, we have an undefined plane. Nothing is in it.
|
||||||
If N == 1: We have a 1D plane. This is represented by a single number.
|
If shape is length 1, we have a 1D plane. This is represented by a single number.
|
||||||
Otherwise: We have an N-D plane. Everything operates as expected.
|
Otherwise, we have an N-D plane. Everything operates as expected.
|
||||||
|
|
||||||
If N happens to be negative, an exception is thrown.
|
|
||||||
"""
|
"""
|
||||||
if N < 0:
|
self.shape = tuple(shape)
|
||||||
raise ValueError('Negative dimension nonsensical')
|
|
||||||
elif N == 0:
|
if len(shape) == 0:
|
||||||
self.shape = ()
|
self.grid = None
|
||||||
self.grid = np.array([], dtype=np.object)
|
elif len(shape) == 1:
|
||||||
elif N == 1:
|
self.grid = 0
|
||||||
self.shape = (size,)
|
|
||||||
self.grid = np.array([0], dtype=np.object)
|
|
||||||
else:
|
else:
|
||||||
self.shape = (size,) * N
|
self.grid = np.zeros((np.prod(shape[:-1]),), dtype=np.object)
|
||||||
self.grid = np.zeros((size**(N-1),), dtype=np.object)
|
|
||||||
|
|
||||||
def __getitem__(self, idx):
|
def __getitem__(self, idx):
|
||||||
"""
|
"""
|
||||||
|
@ -57,7 +52,7 @@ class Plane:
|
||||||
|
|
||||||
# Passed in coordinates, access incrementally
|
# Passed in coordinates, access incrementally
|
||||||
# Note this could be a tuple of slices or numbers
|
# Note this could be a tuple of slices or numbers
|
||||||
if type(idx) in [tuple]:
|
if type(idx) is tuple:
|
||||||
tmp = self
|
tmp = self
|
||||||
for i in idx:
|
for i in idx:
|
||||||
tmp = tmp[i]
|
tmp = tmp[i]
|
||||||
|
@ -65,23 +60,27 @@ class Plane:
|
||||||
|
|
||||||
# Reached last dimension, return bits instead
|
# Reached last dimension, return bits instead
|
||||||
elif len(self.shape) == 1:
|
elif len(self.shape) == 1:
|
||||||
bits = bm.bits_of(self.grid[0], self.shape[0])[idx]
|
bits = bm.bits_of(self.grid, self.shape[0])[idx]
|
||||||
if isinstance(idx, slice):
|
if isinstance(idx, slice):
|
||||||
return list(map(int, bits))
|
return list(map(int, bits))
|
||||||
else:
|
else:
|
||||||
return int(bits)
|
return int(bits)
|
||||||
|
|
||||||
# Simply relay to numpy methods
|
# Simply relay to numpy methods
|
||||||
# Note this doesn't necessarily return a grid in the same notion but
|
# We check if we reach an actual number as opposed to a tuple
|
||||||
# does still allow further indexing if desired. In addition, we can
|
# does still allow further indexing if desired. In addition, we can
|
||||||
# be confident idx is either a list or a number so the final dimension
|
# be confident idx is either a list or a number so the final dimension
|
||||||
# cannot be accessed from here
|
# cannot be accessed from here
|
||||||
# TODO: Reconsider this...
|
|
||||||
else:
|
else:
|
||||||
full = np.reshape(self.grid, self.shape[:-1])[idx]
|
tmp = np.reshape(self.grid, self.shape[:-1])[idx]
|
||||||
tmp = cls(1, len(self.shape) - 1)
|
try:
|
||||||
tmp.grid = full.flat
|
plane = Plane(tmp.shape + self.shape[-1:])
|
||||||
return tmp
|
plane.grid = tmp.flat
|
||||||
|
except AttributeError:
|
||||||
|
plane = Plane(self.shape[-1:])
|
||||||
|
plane.grid = tmp
|
||||||
|
|
||||||
|
return plane
|
||||||
|
|
||||||
def _flatten(coordinates):
|
def _flatten(coordinates):
|
||||||
"""
|
"""
|
||||||
|
|
Loading…
Reference in New Issue