"""Ideal unipolar ADC and aliasing demonstration."""
from math import floor, isclose, pi, sin


def quantize(voltage, bits=12, reference=3.3):
    bins = 1 << bits
    code = min(bins - 1, max(0, floor(voltage / reference * bins)))
    return code, (code + 0.5) * reference / bins


def main():
    step = 3.3 / 4096
    largest = 0.0
    for i in range(10_001):
        voltage = 3.3 * i / 10_000
        _, reconstructed = quantize(voltage)
        largest = max(largest, abs(voltage - reconstructed))
    assert largest <= step / 2 + 1e-12
    assert quantize(-1)[0] == 0
    assert quantize(4)[0] == 4095
    fs = 1000
    for n in range(100):
        high = sin(2 * pi * 900 * n / fs)
        aliased = -sin(2 * pi * 100 * n / fs)
        assert isclose(high, aliased, abs_tol=1e-12)
    print(f"lsb={step * 1000:.6f} mV max_error={largest * 1000:.6f} mV")
    print("900 Hz sampled at 1000 Hz aliases to phase-inverted 100 Hz")
    print("PASS")


if __name__ == "__main__":
    main()
