Problem
Tensor without a real subscript story is effectively write-only: a user can build one, do arithmetic on it, and aggregate it, but the moment they want "the first three rows" or "channel 0 of every frame" they have to drop back to constructing a fresh tensor and copying by hand. Matrix already accepts a sensible subset of NumPy keys; Tensor needs the same vocabulary lifted from rank 2 to arbitrary rank.
Desired functionality
Tensor.__getitem__ and Tensor.__setitem__ accept the same key shapes Matrix accepts today — int, slice, and tuples of those whose length is at most the tensor's rank — and behave the same way per axis. __getitem__ returns a new contiguous tensor of the appropriate shape. __setitem__ accepts either a scalar (broadcast to every targeted element) or a tensor whose shape exactly matches the indexed region.
Constraints
- Results are copies. No views, no aliasing of the original storage.
- Supported keys exhaust to:
int, slice, tuple of (int | slice). Anything else raises TypeError naming the unsupported form.
- Negative integer indices wrap; out-of-range raises
IndexError.
__setitem__ does not invoke broadcasting on its right-hand side in v1: scalar broadcast yes, exact-shape Tensor yes, anything else TypeError.
Matrix is untouched by this work.
Out of scope
Ellipsis, None / np.newaxis, boolean masks, integer-array and list-of-indices fancy indexing, value-broadcast on __setitem__, views.
Open questions
- Rank reduction. NumPy-style —
tensor[i, :] on a rank-2 tensor returns rank 1 — versus Matrix-style — the same key returns rank 2 with an axis of size 1. The two are incompatible; one must be picked and documented. NumPy-style is the more conventional choice, but the project's existing rank-2 behaviour is the other one.
- Empty-result slices: raise
IndexError (current Matrix behaviour) or return a zero-size tensor.
- Whether a rank-0 tensor accepts
tensor[()] as identity.
Problem
Tensorwithout a real subscript story is effectively write-only: a user can build one, do arithmetic on it, and aggregate it, but the moment they want "the first three rows" or "channel 0 of every frame" they have to drop back to constructing a fresh tensor and copying by hand.Matrixalready accepts a sensible subset of NumPy keys;Tensorneeds the same vocabulary lifted from rank 2 to arbitrary rank.Desired functionality
Tensor.__getitem__andTensor.__setitem__accept the same key shapesMatrixaccepts today —int,slice, and tuples of those whose length is at most the tensor's rank — and behave the same way per axis.__getitem__returns a new contiguous tensor of the appropriate shape.__setitem__accepts either a scalar (broadcast to every targeted element) or a tensor whose shape exactly matches the indexed region.Constraints
int,slice, tuple of(int | slice). Anything else raisesTypeErrornaming the unsupported form.IndexError.__setitem__does not invoke broadcasting on its right-hand side in v1: scalar broadcast yes, exact-shapeTensoryes, anything elseTypeError.Matrixis untouched by this work.Out of scope
Ellipsis,
None/np.newaxis, boolean masks, integer-array and list-of-indices fancy indexing, value-broadcast on__setitem__, views.Open questions
tensor[i, :]on a rank-2 tensor returns rank 1 — versus Matrix-style — the same key returns rank 2 with an axis of size 1. The two are incompatible; one must be picked and documented. NumPy-style is the more conventional choice, but the project's existing rank-2 behaviour is the other one.IndexError(currentMatrixbehaviour) or return a zero-size tensor.tensor[()]as identity.