The same set of numbers can be organized into many different shapes — 12 elements can be viewed as a flat vector of 12, a 3x4 grid, or a 2x2x3 block — without changing which numbers exist, only how they're grouped into dimensions. Every layer in a real network reshapes and reorders its tensors constantly (flattening before a Linear layer, moving a "channels" dimension around for a convolution), so these three operations are the vocabulary everything else in this curriculum is built out of.
Implement reshape(a, shape), transpose(a, dim0, dim1), and permute(a, dims). transpose and permute look similar but are genuinely different operations, not a generalization with a default — implement each exactly, not one in terms of the other.
a: any NumPy array. shape may contain a single -1, meaning "infer this dimension from the total element count."transpose(a, dim0, dim1) swaps exactly the two named dimensions; every other dimension stays exactly where it is.permute(a, dims) reorders every dimension at once according to dims — a full reordering, not a two-axis swap.reshape preserves element order (the same flat sequence of values, regrouped).a.Open one at a time. Each gives away a little more than the last.
reshape needs no manual -1 handling — NumPy's own .reshape() already supports a single inferred dimension, the same convention torch.reshape uses.
transpose and permute are two different NumPy functions, not the same function called two ways: one swaps a pair of axes, the other takes a full axis ordering.
Click "Run Tests" to test your implementation