Skip to content

Commit 44ccd65

Browse files
authored
Add clarifying examples to note concerning tuple usage in multi-axis indexing (#280)
* Add examples to note * Remove sentence * Add note * Add note regarding providing an empty tuple to a rank 0 array * Add note * Update note * Remove empty lines * Fix note * Add note
1 parent b9baefc commit 44ccd65

File tree

1 file changed

+17
-5
lines changed

1 file changed

+17
-5
lines changed

spec/API_specification/indexing.md

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,28 +17,29 @@ To index a single array axis, an array must support standard Python indexing rul
1717
- **Valid** nonnegative indices must reside on the half-open interval `[0, n)`.
1818

1919
```{note}
20-
2120
This specification does not require bounds checking. The behavior for out-of-bounds integer indices is left unspecified.
2221
```
2322
2423
- Negative indices must count backward from the last array index, starting from `-1` (i.e., negative-one-based indexing, where `-1` refers to the last array index).
2524
2625
```{note}
27-
2826
A negative index `j` is equivalent to `n-j`; the former is syntactic sugar for the latter, providing a shorthand for indexing elements that would otherwise need to be specified in terms of the axis (dimension) size.
2927
```
3028
3129
- **Valid** negative indices must reside on the closed interval `[-n, -1]`.
3230
3331
```{note}
34-
3532
This specification does not require bounds checking. The behavior for out-of-bounds integer indices is left unspecified.
3633
```
3734
3835
- A negative index `j` is related to a zero-based nonnegative index `i` via `i = n+j`.
3936
4037
- Colons `:` must be used for [slices](https://docs.python.org/3/library/functions.html#slice): `start:stop:step`, where `start` is inclusive and `stop` is exclusive.
4138
39+
```{note}
40+
The specification does not support returning scalar (i.e., non-array) values from operations, including indexing. In contrast to standard Python indexing rules, for any index, or combination of indices, which select a single value, the result must be a zero-dimensional array containing the selected value.
41+
```
42+
4243
### Slice Syntax
4344

4445
The basic slice syntax is `i:j:k` where `i` is the starting index, `j` is the stopping index, and `k` is the step (`k != 0`). A slice may contain either one or two colons, with either an integer value or nothing on either side of each colon. The following are valid slices.
@@ -60,7 +61,6 @@ A[i:j:k]
6061
```
6162

6263
```{note}
63-
6464
Slice syntax can be equivalently achieved using the Python built-in [`slice()`](https://docs.python.org/3/library/functions.html#slice) API. From the perspective of `A`, the behavior of `A[i:j:k]` and `A[slice(i, j, k)]` is indistinguishable (i.e., both retrieve the same set of items from `__getitem__`).
6565
```
6666

@@ -134,7 +134,9 @@ Multi-dimensional arrays must extend the concept of single-axis indexing to mult
134134
- Each axis may be independently indexed via single-axis indexing by providing a comma-separated sequence ("selection tuple") of single-axis indexing expressions (e.g., `A[:, 2:10, :, 5]`).
135135

136136
```{note}
137-
In Python, `x[(exp1, exp2, ..., expN)]` is equivalent to `x[exp1, exp2, ..., expN]`; the latter is syntactic sugar for the former.
137+
In Python, `A[(exp1, exp2, ..., expN)]` is equivalent to `A[exp1, exp2, ..., expN]`; the latter is syntactic sugar for the former.
138+
139+
Accordingly, if `A` has rank `1`, then `A[(2:10,)]` must be equivalent to `A[2:10]`. If `A` has rank `2`, then `A[(2:10, :)]` must be equivalent to `A[2:10, :]`. And so on and so forth.
138140
```
139141
140142
- Providing a single nonnegative integer `i` as a single-axis index must index the same elements as the slice `i:i+1`.
@@ -143,10 +145,20 @@ Multi-dimensional arrays must extend the concept of single-axis indexing to mult
143145
144146
- Providing a single integer as a single-axis index must reduce the number of array dimensions by `1` (i.e., the array rank should decrease by one; if `A` has rank `2`, `rank(A)-1 == rank(A[0, :])`). In particular, a selection tuple with the `m`th element an integer (and all other entries `:`) indexes a sub-array with rank `N-1`.
145147
148+
```{note}
149+
When providing a single integer as a single-axis index to an array of rank `1`, the result should be an array of rank `0`, not a NumPy scalar. Note that this behavior differs from NumPy.
150+
```
151+
146152
- Providing a slice must retain array dimensions (i.e., the array rank must remain the same; `rank(A) == rank(A[:])`).
147153
148154
- Providing [ellipsis](https://docs.python.org/3/library/constants.html#Ellipsis) must apply `:` to each dimension necessary to index all dimensions (e.g., if `A` has rank `4`, `A[1:, ..., 2:5] == A[1:, :, :, 2:5]`). Only a single ellipsis must be allowed. An `IndexError` exception must be raised if more than one ellipsis is provided.
149155
156+
- Providing an empty tuple or an ellipsis to an array of rank `0` must result in an array of the same rank (i.e., if `A` has rank `0`, `A == A[()]` and `A == A[...]`).
157+
158+
```{note}
159+
This behavior differs from NumPy where providing an empty tuple to an array of rank `0` returns a NumPy scalar.
160+
```
161+
150162
- Except in the case of providing a single ellipsis (e.g., `A[2:10, ...]` or `A[1:, ..., 2:5]`), the number of provided single-axis indexing expressions should equal `N`. For example, if `A` has rank `2`, a single-axis indexing expression should be explicitly provided for both axes (e.g., `A[2:10, :]`). An `IndexError` exception should be raised if the number of provided single-axis indexing expressions is less than `N`.
151163
152164
```{note}

0 commit comments

Comments
 (0)