Skip to content

← Shapes and Strides step 5 of 9

Easy Primitives

Scale every row by its own weight

Jump to the task

To multiply each row by its own weight, the weight axis must line up with the row axis. Broadcasting aligns dimensions from the right:

x:           (rows, cols)
w:                 (rows)

Here the length of w is compared with the column count, even though its values represent row weights. Matching sizes alone cannot express that meaning.

Insert an axis for the columns

w.unsqueeze(1) changes shape (rows,) to (rows, 1). Each weight then broadcasts across the columns of its own row:

import torch

x = torch.tensor([[1., 2.], [3., 4.]])
w = torch.tensor([10., 100.])
print((x * w).tolist())  # [[10.0, 200.0], [30.0, 400.0]]
print((x * w.unsqueeze(1)).tolist())  # [[10.0, 20.0], [300.0, 400.0]]

Both outputs have the same shape. The first scales columns, while the second performs the required row scaling.

x:                (rows, cols)
w.unsqueeze(1):   (rows,    1)
result:           (rows, cols)

When the wrong expression still runs

With unequal row and column counts greater than one, x * w raises a broadcasting error. Singleton dimensions are exceptions: with one column and several rows it broadcasts to (rows, rows), the wrong output shape. With a single row, its single weight happens to scale that row correctly.

Checking a rectangular example, a square example and singleton cases helps expose these different behaviors. Also check values: the wrong expression can have the expected shape.

Equivalent ways to align this vector

For the nonempty 1-D weights used here, these expressions all produce a storage-sharing column view:

w.unsqueeze(1)
w[:, None]
w.reshape(-1, 1)

unsqueeze names the axis insertion explicitly. It does not copy the weights; the multiplication produces the scaled output.

Your task

def scale_rows(x: torch.Tensor, w: torch.Tensor) -> torch.Tensor

Given x of shape (rows, cols) and w of shape (rows,), with positive dimensions, return shape (rows, cols) satisfying result[i, j] = x[i, j] * w[i]. The starter leaves the weight vector aligned with the last axis instead.