import math

def inner(left, right):
    if len(left) != len(right):
        raise ValueError("vectors must have equal dimension")
    return sum(a.conjugate() * b for a, b in zip(left, right))

def coordinates(vector, basis):
    if len(basis) != len(vector) or any(len(column) != len(vector) for column in basis):
        raise ValueError("basis dimension mismatch")
    return tuple(inner(column, vector) for column in basis)

def reconstruct(values, basis):
    return tuple(sum(values[column] * basis[column][row] for column in range(len(values)))
                 for row in range(len(values)))

def reverse_bits(index, qubits):
    output = 0
    for _ in range(qubits):
        output = (output << 1) | (index & 1)
        index >>= 1
    return output

def change_endianness(vector):
    size = len(vector)
    qubits = size.bit_length() - 1
    if 1 << qubits != size:
        raise ValueError("state dimension must be a power of two")
    output = [0j] * size
    for index, amplitude in enumerate(vector):
        output[reverse_bits(index, qubits)] = amplitude
    return tuple(output)

scale = math.sqrt(0.5)
x_basis = ((scale, scale), (scale, -scale))
states = ((1, 0), (0, 1), (scale, 1j * scale), (0.6, -0.8j))
max_roundtrip_error = 0.0
for state in states:
    values = coordinates(state, x_basis)
    recovered = reconstruct(values, x_basis)
    max_roundtrip_error = max(max_roundtrip_error, *(abs(a - b) for a, b in zip(state, recovered)))
    assert abs(inner(state, state) - inner(values, values)) < 1e-12
assert max_roundtrip_error < 1e-12

for left, right in zip(states, reversed(states)):
    converted_left = coordinates(left, x_basis)
    converted_right = coordinates(right, x_basis)
    assert abs(inner(left, right) - inner(converted_left, converted_right)) < 1e-12

ordered_states = ((0, 1, 0, 0),
                  (0, 0, scale, 1j * scale),
                  tuple(complex(index, -index) for index in range(8)))
for state in ordered_states:
    assert change_endianness(change_endianness(state)) == state
    changed = change_endianness(state)
    assert abs(inner(state, state) - inner(changed, changed)) < 1e-12

ket_01_msb = (0, 1, 0, 0)
ket_01_lsb = change_endianness(ket_01_msb)
assert ket_01_msb != ket_01_lsb and ket_01_lsb == (0, 0, 1, 0)
bad_dimension_rejected = False
try:
    change_endianness((1, 0, 0))
except ValueError:
    bad_dimension_rejected = True
assert bad_dimension_rejected
print(f"PASS: 09 basis/endianness harness round-trips {len(states) + len(ordered_states)} states; max coordinate error={max_roundtrip_error:.2e}, swapped |01> coordinate vector={ket_01_lsb}")
