Aller au contenu

Éditeur de code quantique

Un petit simulateur à vecteur d'état est préchargé : Circuit(n) avec les portes h x y z s t cx cz, puis probabilities(), state_str() et measure(shots).

Modifiez le code puis exécutez-le. Python s'exécute dans votre navigateur (Pyodide), rien n'est envoyé à un serveur.

Voir le code du simulateur
import math, cmath, random

class Circuit:
    """Simulateur à vecteur d'état. Le qubit 0 est le bit de poids fort."""
    def __init__(self, n):
        self.n = n
        self.amp = [0j] * (2 ** n)
        self.amp[0] = 1 + 0j

    def _one(self, q, m):
        bit = 1 << (self.n - 1 - q)
        a = self.amp[:]
        for i in range(len(a)):
            if i & bit:
                continue
            x, y = self.amp[i], self.amp[i | bit]
            a[i] = m[0][0] * x + m[0][1] * y
            a[i | bit] = m[1][0] * x + m[1][1] * y
        self.amp = a
        return self

    def h(self, q):
        s = 1 / math.sqrt(2)
        return self._one(q, [[s, s], [s, -s]])
    def x(self, q): return self._one(q, [[0, 1], [1, 0]])
    def y(self, q): return self._one(q, [[0, -1j], [1j, 0]])
    def z(self, q): return self._one(q, [[1, 0], [0, -1]])
    def s(self, q): return self._one(q, [[1, 0], [0, 1j]])
    def t(self, q): return self._one(q, [[1, 0], [0, cmath.exp(1j * math.pi / 4)]])

    def cx(self, c, t):
        cb, tb = 1 << (self.n - 1 - c), 1 << (self.n - 1 - t)
        a = self.amp[:]
        for i in range(len(a)):
            if i & cb and not i & tb:
                a[i], a[i | tb] = self.amp[i | tb], self.amp[i]
        self.amp = a
        return self

    def cz(self, c, t):
        cb, tb = 1 << (self.n - 1 - c), 1 << (self.n - 1 - t)
        self.amp = [-v if (i & cb and i & tb) else v for i, v in enumerate(self.amp)]
        return self

    def probabilities(self):
        return {format(i, "0%db" % self.n): round(abs(v) ** 2, 4) for i, v in enumerate(self.amp) if abs(v) > 1e-12}

    def state_str(self):
        parts = []
        for i, v in enumerate(self.amp):
            if abs(v) > 1e-9:
                parts.append("(%.3f%+.3fi)|%s>" % (v.real, v.imag, format(i, "0%db" % self.n)))
        return " + ".join(parts)

    def measure(self, shots=1024):
        keys = [format(i, "0%db" % self.n) for i in range(len(self.amp))]
        w = [abs(v) ** 2 for v in self.amp]
        out = {}
        for k in random.choices(keys, weights=w, k=shots):
            out[k] = out.get(k, 0) + 1
        return dict(sorted(out.items()))