Example #1
0
def test_kron_factor_special_unitaries(f1, f2):
    p = linalg.kron(f1, f2)
    g, g1, g2 = linalg.kron_factor_4x4_to_2x2s(p)
    assert np.allclose(linalg.kron(g1, g2), p)
    assert abs(g - 1) < 0.000001
    assert linalg.is_special_unitary(g1)
    assert linalg.is_special_unitary(g2)
Example #2
0
def recompose_so4(a: np.ndarray, b: np.ndarray) -> np.ndarray:
    assert a.shape == (2, 2)
    assert b.shape == (2, 2)
    assert linalg.is_special_unitary(a)
    assert linalg.is_special_unitary(b)

    magic = np.array([[1, 0, 0, 1j], [0, 1j, 1, 0], [0, 1j, -1, 0],
                      [1, 0, 0, -1j]]) * np.sqrt(0.5)
    result = np.real(
        combinators.dot(np.conj(magic.T), linalg.kron(a, b), magic))
    assert linalg.is_orthogonal(result)
    return result
Example #3
0
def test_kak_canonicalize_vector(x, y, z):
    i = np.eye(2)
    m = recompose_kak(1, (i, i), (x, y, z), (i, i))

    g, (a1, a0), (x2, y2, z2), (b1,
                                b0) = linalg.kak_canonicalize_vector(x, y, z)
    m2 = recompose_kak(g, (a1, a0), (x2, y2, z2), (b1, b0))

    assert 0.0 <= x2 <= np.pi / 4
    assert 0.0 <= y2 <= np.pi / 4
    assert -np.pi / 4 <= z2 <= np.pi / 4
    assert abs(x2) >= abs(y2) >= abs(z2)
    assert linalg.is_special_unitary(a1)
    assert linalg.is_special_unitary(a0)
    assert linalg.is_special_unitary(b1)
    assert linalg.is_special_unitary(b0)
    assert np.allclose(m, m2)
def _decompose_su(matrix: np.ndarray, controls: List['cirq.Qid'],
                  target: 'cirq.Qid') -> List['cirq.Operation']:
    """Decomposes controlled special unitary gate into elementary gates.

    Result has O(len(controls)) operations.
    See [1], lemma 7.9.
    """
    assert matrix.shape == (2, 2)
    assert is_special_unitary(matrix)
    assert len(controls) >= 1

    a, b, c, _ = _decompose_abc(matrix)

    cnots = decompose_multi_controlled_x(controls[:-1], target, [controls[-1]])
    return [
        *_decompose_single_ctrl(c, controls[-1], target), *cnots,
        *_decompose_single_ctrl(b, controls[-1], target), *cnots,
        *_decompose_single_ctrl(a, controls[-1], target)
    ]
Example #5
0
def decompose_multi_controlled_rotation(
        matrix: np.ndarray, controls: List['cirq.Qid'],
        target: 'cirq.Qid') -> List['cirq.Operation']:
    """Implements action of multi-controlled unitary gate.

    Returns a sequence of operations, which is equivalent to applying
    single-qubit gate with matrix `matrix` on `target`, controlled by
    `controls`.

    Result is guaranteed to consist exclusively of 1-qubit, CNOT and CCNOT
    gates.

    If matrix is special unitary, result has length `O(len(controls))`.
    Otherwise result has length `O(len(controls)**2)`.

    References:
        [1] Barenco, Bennett et al.
            Elementary gates for quantum computation. 1995.
            https://arxiv.org/pdf/quant-ph/9503016.pdf

    Args:
        matrix - 2x2 numpy unitary matrix (of real or complex dtype).
        controls - control qubits.
        targets - target qubits.

    Returns:
        A list of operations which, applied in a sequence, are equivalent to
        applying `MatrixGate(matrix).on(target).controlled_by(*controls)`.
    """
    assert is_unitary(matrix)
    assert matrix.shape == (2, 2)

    if len(controls) == 0:
        return [ops.MatrixGate(matrix).on(target)]
    elif len(controls) == 1:
        return _decompose_single_ctrl(matrix, controls[0], target)
    elif is_special_unitary(matrix):
        return _decompose_su(matrix, controls, target)
    else:
        return _decompose_recursive(matrix, 1.0, controls, target, [])
Example #6
0
def test_random_special_unitary():
    u1 = random_special_unitary(2)
    u2 = random_special_unitary(2)
    assert is_special_unitary(u1)
    assert is_special_unitary(u2)
    assert not np.allclose(u1, u2)