Beispiel #1
0
def decompose_4x4_optimal(U):
    """Builds optimal decomposition of general 4x4 unitary matrix.

    This decomposition consists of at most 3 CNOT gates, 15 Rx/Ry gates and one
    R1 gate.

    Returns list of `Gate`s.
    """
    assert is_unitary(U)

    magic_decomp = decompose_to_magic_diagonal(U)

    result = []
    result += apply_on_qubit(su_to_gates(magic_decomp['VA']), 1)
    result += apply_on_qubit(su_to_gates(magic_decomp['VB']), 0)
    result += decompose_magic_N(magic_decomp['alpha'])
    result += apply_on_qubit(su_to_gates(magic_decomp['UA']), 1)
    result += apply_on_qubit(su_to_gates(magic_decomp['UB']), 0)

    # Adding global phase using Rz and R1.
    gl_phase = magic_decomp['global_phase'] + 0.25 * np.pi
    if np.abs(gl_phase) > 1e-9:
        result.append(GateSingle(Gate2('Rz', 2 * gl_phase), 0))
        result.append(GateSingle(Gate2('R1', 2 * gl_phase), 0))

    result = skip_identities(result)

    assert _allclose(U, gates_to_matrix(result, 2))

    return result
Beispiel #2
0
def test_GateSingle_to_matrix():
    assert np.allclose(
        GateSingle(Gate2('X'), 0, 2).to_matrix(),
        [[0, 1, 0, 0], [1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])

    assert np.allclose(
        GateSingle(Gate2('X'), 1, 2).to_matrix(),
        [[0, 0, 1, 0], [0, 0, 0, 1], [1, 0, 0, 0], [0, 1, 0, 0]])
Beispiel #3
0
def test_GateFC_to_matrix():
    assert np.allclose(
        GateFC(Gate2('X'), 0).to_matrix(2),
        [[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0]])

    assert np.allclose(
        GateFC(Gate2('X'), 1).to_matrix(2),
        [[1, 0, 0, 0], [0, 0, 0, 1], [0, 0, 1, 0], [0, 1, 0, 0]])
def unitary2x2_to_gates(A):
    """Decomposes 2x2 unitary to gates Ry, Rz, R1.

    R1(x) = diag(1, exp(i*x)).
    """
    assert is_unitary(A)
    phi = np.angle(np.linalg.det(A))
    if np.abs(phi) < 1e-9:
        return su_to_gates(A)
    elif np.allclose(A, PAULI_X):
        return [Gate2('X')]
    else:
        A = np.diag([1.0, np.exp(-1j * phi)]) @ A
        return su_to_gates(A) + [Gate2('R1', phi)]
def su_to_gates(A):
    """Decomposes 2x2 special unitary to gates Ry, Rz.

    R_k(x) = exp(0.5*i*x*sigma_k).
    """
    assert is_special_unitary(A)
    u00 = A[0, 0]
    u01 = A[0, 1]
    theta = np.arccos(np.abs(u00))
    lmbda = np.angle(u00)
    mu = np.angle(u01)

    result = []
    result.append(Gate2('Rz', lmbda - mu))
    result.append(Gate2('Ry', 2 * theta))
    result.append(Gate2('Rz', lmbda + mu))
    return result
Beispiel #6
0
def decompose_magic_N(a):
    """Decomposes "Magic N" matrix into 3 CNOTs, 4 Rz and 1 Ry gate.

    Result is missing global phase pi/4.
    Implements cirquit on fig. 7 from [1].
    """
    t1 = 2 * a[2] - 0.5 * np.pi
    t2 = 0.5 * np.pi - 2 * a[0]
    t3 = 2 * a[1] - 0.5 * np.pi
    result = []

    result.append(GateSingle(Gate2('Rz', 0.5 * np.pi), 1))
    result.append(GateFC(Gate2('X'), 0))
    result.append(GateSingle(Gate2('Rz', t1), 0))
    result.append(GateSingle(Gate2('Ry', t2), 1))
    result.append(GateFC(Gate2('X'), 1))
    result.append(GateSingle(Gate2('Ry', t3), 1))
    result.append(GateFC(Gate2('X'), 0))
    result.append(GateSingle(Gate2('Rz', -0.5 * np.pi), 0))

    N = magic_N(a)
    assert np.allclose(N, gates_to_matrix(result, 2) * np.exp(0.25j * np.pi))

    return result
Beispiel #7
0
 def dump_flips():
     global flip_mask
     for qubit_id in range(qubit_count):
         if (flip_mask & (2**qubit_id)) != 0:
             result.append(GateSingle(Gate2('X'), qubit_id, qubit_count))
     flip_mask = 0
Beispiel #8
0
 def merge_gates(g1, g2):
     assert can_merge(g1, g2)
     new_gate2 = Gate2(g1.gate2.name, arg=g1.gate2.arg + g2.gate2.arg)
     return GateSingle(new_gate2, g1.qubit_id, g1.qubit_count)