Along the Line and Across It

inner product · projection · orthogonality · unit vectors · complex numbers

Vectors here are Python lists of complex numbers (ints and floats are allowed too). The inner product of two vectors of the same length is

\langle u|v\rangle = \sum_i \overline{u_i}\, v_i

with the conjugate (z.conjugate()) on the first vector. Two vectors are orthogonal when their inner product is 0.

Given a vector v and a unit vector e (one with \langle e|e\rangle = 1), every v splits into a part along e and a part across it:

v = c\, e + r, \qquad c = \langle e|v\rangle, \qquad r = v - c\,e

The number c (complex in general) says how much of v lies along e, and the leftover r is orthogonal to e. In the simulator you are building, c will be the amplitude of a state along a measurement direction.

Write split_along(v, e) that returns the pair (c, r), with r as a list.

Examples

Input:  v = [3, 4j], e = [1, 0]
Output: (3, [0, 4j])

Input:  v = [2, 2j], e = [0.6, 0.8j]
Output: (2.8, [0.32, -0.24j])
Explanation: c = 0.6 * 2 + (-0.8j) * 2j = 1.2 + 1.6 = 2.8, and
r = [2 - 2.8 * 0.6, 2j - 2.8 * 0.8j] = [0.32, -0.24j].
Check: <e|r> = 0.6 * 0.32 + (-0.8j) * (-0.24j) = 0.192 - 0.192 = 0.

Input:  v = [0, 1], e = [0.7071067811865476, 0.7071067811865476j]
Output: (-0.7071067811865476j, [0.5j, 0.5])
Explanation: conjugating v instead of e would give c = 0.7071067811865476j and
r = [-0.5j, 1.5], which is not orthogonal to e.

Constraints

  • e has length 1 (within 1e-9)
  • answers are compared with a tolerance of 1e-6; a list [c, r] is accepted in place of the tuple

Goals

  • Find how much of a complex vector lies along a unit vector, with the inner product
  • Split a vector into a part along a direction and a part orthogonal to it
  • Put the conjugate on the right vector so the leftover part really is orthogonal
Starting Python…