import cmath
import math

def normalize(amplitudes):
    norm = math.sqrt(sum(abs(value) ** 2 for value in amplitudes))
    if norm < 1e-15:
        raise ValueError("the zero vector cannot be normalized")
    return tuple(value / norm for value in amplitudes)

def probabilities(amplitudes):
    return tuple(abs(value) ** 2 for value in amplitudes)

pairs = ((3 + 4j, -2 + 0.5j),
         (cmath.rect(2.5, 0.7), cmath.rect(0.4, -1.2)),
         (-1j, 1 + 1j))
max_polar_error = 0.0
for left, right in pairs:
    product = left * right
    polar_product = cmath.rect(abs(left) * abs(right), cmath.phase(left) + cmath.phase(right))
    max_polar_error = max(max_polar_error, abs(product - polar_product))
    assert abs(product.conjugate() - left.conjugate() * right.conjugate()) < 1e-12
    assert abs(abs(left) ** 2 - left.real ** 2 - left.imag ** 2) < 1e-12
assert max_polar_error < 1e-12

raw_states = ((3 + 4j, 0j), (1 + 2j, -2 + 1j), (0.25j, -3, 4 - 2j))
states = tuple(normalize(state) for state in raw_states)
for state in states:
    assert abs(sum(probabilities(state)) - 1.0) < 1e-12

phase = cmath.exp(1j * 1.234)
max_probability_shift = 0.0
for state in states:
    shifted = tuple(phase * value for value in state)
    shift = max(abs(a - b) for a, b in zip(probabilities(state), probabilities(shifted)))
    max_probability_shift = max(max_probability_shift, shift)
assert max_probability_shift < 1e-12

wrong_rule_total = sum(abs(value) for value in normalize((3, 4)))
assert abs(wrong_rule_total - 1.0) > 0.1
zero_rejected = False
try:
    normalize((0j, 0j))
except ValueError:
    zero_rejected = True
assert zero_rejected
print(f"PASS: 08 complex amplitudes verify {len(pairs)} polar products and {len(states)} normalized states; max polar error={max_polar_error:.2e}, global-phase probability shift={max_probability_shift:.2e}")
