Socks Before Shoes

matrices · matrix multiplication · complex numbers · nested loops · non-commutativity

A matrix here is a list of rows: a[i][j] is the entry in row i, column j, and entries are complex numbers (ints and floats are allowed too). If a has r rows of k entries and b has k rows of c entries, their product AB has r rows of c entries:

(AB)_{ij} = \sum_{t} A_{it}\, B_{tj}

Entry (i, j) combines row i of a with column j of b; there is no conjugate. Applying B to a vector and then A is the same as applying the single matrix AB (the one applied first stands on the right). Like putting on socks and shoes, the order matters: AB and BA are usually different, and the simulator you are building must multiply its gates in the right order.

Write mat_mul(a, b) that returns AB as a list of rows.

Examples

Input:  a = [[0, 1], [1, 0]], b = [[1, 0], [0, -1]]
Output: [[0, -1], [1, 0]]

Input:  a = [[1, 0], [0, -1]], b = [[0, 1], [1, 0]]
Output: [[0, 1], [-1, 0]]
Explanation: the same two matrices in the other order give a different product.

Input:  a = [[1, 1j, 2]], b = [[1], [1j], [3]]
Output: [[6]]
Explanation: 1 * 1 + 1j * 1j + 2 * 3 = 1 - 1 + 6 = 6. One row of three times three rows
of one is a 1 x 1 matrix.

Constraints

  • answers are compared with a tolerance of 1e-6; a complex answer with imaginary part 0 counts as the real number

Goals

  • Multiply two matrices stored as lists of rows
  • See that A B and B A are usually different matrices
  • Get the shape of a product of non-square matrices right
Starting Python…