Skip to content

← Orientation and the Grade step 3 of 3

Easy Primitives

Subtract each row's mean with correct broadcasting

Jump to the task

Implement centre_rows(x) for a two-dimensional floating-point tensor. Subtract each row's mean from every value in that row. Return a tensor with the same shape as x.

For example:

input:   [[1., 3.], [10., 20.]]
means:   [2., 15.]
output:  [[-1., 1.], [-5., 5.]]

The broadcasting trap

The starter uses:

x - x.mean(dim=1)

For an input shaped (rows, cols), the mean has shape (rows,). Broadcasting aligns dimensions from the right, so that one-dimensional result aligns with the column axis of x.

On a square tensor, the sizes match and the subtraction runs. It subtracts mean number j from column j, instead of subtracting each row's own mean. For torch.arange(16).reshape(4, 4).float(), the first row shows the difference:

required row 0: [-1.5, -0.5,  0.5,   1.5]
starter row 0:  [-1.5, -4.5, -7.5, -10.5]

Compatible shapes do not guarantee correct values. A square case with equal row means can even hide this bug. On shape (3, 4), the starter raises a shape error; on (3, 1), it broadcasts to the wrong output shape (3, 3).

Keep the reduced axis

Using keepdim=True gives the means shape (rows, 1):

x:         (rows, cols)
row means: (rows,    1)

The trailing axis then broadcasts across each row's columns. This preserves the intended pairing for square and rectangular inputs, including a single row or a single column.

Your task

def centre_rows(x: torch.Tensor) -> torch.Tensor