Example #1
0
def so4_to_magic_su2s(
    mat: np.ndarray, *, rtol: float = 1e-5, atol: float = 1e-8, check_preconditions: bool = True
) -> Tuple[np.ndarray, np.ndarray]:
    """Finds 2x2 special-unitaries A, B where mat = Mag.H @ kron(A, B) @ Mag.

    Mag is the magic basis matrix:

        1  0  0  i
        0  i  1  0
        0  i -1  0     (times sqrt(0.5) to normalize)
        1  0  0 -i

    Args:
        mat: A real 4x4 orthogonal matrix.
        rtol: Per-matrix-entry relative tolerance on equality.
        atol: Per-matrix-entry absolute tolerance on equality.
        check_preconditions: When set, the code verifies that the given
            matrix is from SO(4). Defaults to set.

    Returns:
        A pair (A, B) of matrices in SU(2) such that Mag.H @ kron(A, B) @ Mag
        is approximately equal to the given matrix.

    Raises:
        ValueError: Bad matrix.
    """
    if check_preconditions:
        if mat.shape != (4, 4) or not predicates.is_special_orthogonal(mat, atol=atol, rtol=rtol):
            raise ValueError('mat must be 4x4 special orthogonal.')

    ab = combinators.dot(MAGIC, mat, MAGIC_CONJ_T)
    _, a, b = kron_factor_4x4_to_2x2s(ab)

    return a, b
Example #2
0
def so4_to_magic_su2s(
        mat: np.ndarray,
        tolerance: Tolerance = Tolerance.DEFAULT
) -> Tuple[np.ndarray, np.ndarray]:
    """Finds 2x2 special-unitaries A, B where mat = Mag.H @ kron(A, B) @ Mag.

    Mag is the magic basis matrix:

        1  0  0  i
        0  i  1  0
        0  i -1  0     (times sqrt(0.5) to normalize)
        1  0  0 -i

    Args:
        mat: A real 4x4 orthogonal matrix.
        tolerance: Per-matrix-entry tolerance on equality.

    Returns:
        A pair (A, B) of matrices in SU(2) such that Mag.H @ kron(A, B) @ Mag
        is approximately equal to the given matrix.

    Raises:
        ValueError: Bad matrix.
        """
    if mat.shape != (4, 4) or not predicates.is_special_orthogonal(
            mat, tolerance):
        raise ValueError('mat must be 4x4 special orthogonal.')

    ab = combinators.dot(MAGIC, mat, MAGIC_CONJ_T)
    _, a, b = kron_factor_4x4_to_2x2s(ab, tolerance)

    return a, b
Example #3
0
def test_is_special_orthogonal_tolerance():
    tol = Tolerance(atol=0.5)

    # Pays attention to specified tolerance.
    assert predicates.is_special_orthogonal(
        np.array([[1, 0], [-0.5, 1]]), tol)
    assert not predicates.is_special_orthogonal(
        np.array([[1, 0], [-0.6, 1]]), tol)

    # Error isn't accumulated across entries, except for determinant factors.
    assert predicates.is_special_orthogonal(
        np.array([[1.2, 0, 0], [0, 1.2, 0], [0, 0, 1 / 1.2]]), tol)
    assert not predicates.is_special_orthogonal(
        np.array([[1.2, 0, 0], [0, 1.2, 0], [0, 0, 1.2]]), tol)
    assert not predicates.is_special_orthogonal(
        np.array([[1.2, 0, 0], [0, 1.3, 0], [0, 0, 1 / 1.2]]), tol)
Example #4
0
def so4_to_magic_su2s(
        mat: np.ndarray,
        tolerance: Tolerance = Tolerance.DEFAULT
) -> Tuple[np.ndarray, np.ndarray]:
    """Finds 2x2 special-unitaries A, B where mat = Mag.H @ kron(A, B) @ Mag.

    Mag is the magic basis matrix:

        1  0  0  i
        0  i  1  0
        0  i -1  0     (times sqrt(0.5) to normalize)
        1  0  0 -i

    Args:
        mat: A real 4x4 orthogonal matrix.
        tolerance: Per-matrix-entry tolerance on equality.

    Returns:
        A pair (A, B) of matrices in SU(2) such that Mag.H @ kron(A, B) @ Mag
        is approximately equal to the given matrix.

    Raises:
        ValueError: Bad matrix.
        ArithmeticError: Failed to perform the decomposition to desired
            tolerance.
        """
    if mat.shape != (4, 4) or not predicates.is_special_orthogonal(mat,
                                                                   tolerance):
        raise ValueError('mat must be 4x4 special orthogonal.')

    magic = np.array([[1, 0, 0, 1j],
                    [0, 1j, 1, 0],
                    [0, 1j, -1, 0],
                    [1, 0, 0, -1j]]) * np.sqrt(0.5)
    ab = combinators.dot(magic, mat, np.conj(magic.T))
    _, a, b = kron_factor_4x4_to_2x2s(ab, tolerance)

    # Check decomposition against desired tolerance.
    reconstructed = combinators.dot(np.conj(magic.T),
                                    combinators.kron(a, b),
                                    magic)
    if not tolerance.all_close(reconstructed, mat):
        raise ArithmeticError('Failed to decompose to desired tolerance.')

    return a, b
Example #5
0
def so4_to_magic_su2s(
        mat: np.ndarray,
        tolerance: Tolerance = Tolerance.DEFAULT
) -> Tuple[np.ndarray, np.ndarray]:
    """Finds 2x2 special-unitaries A, B where mat = Mag.H @ kron(A, B) @ Mag.

    Mag is the magic basis matrix:

        1  0  0  i
        0  i  1  0
        0  i -1  0     (times sqrt(0.5) to normalize)
        1  0  0 -i

    Args:
        mat: A real 4x4 orthogonal matrix.
        tolerance: Per-matrix-entry tolerance on equality.

    Returns:
        A pair (A, B) of matrices in SU(2) such that Mag.H @ kron(A, B) @ Mag
        is approximately equal to the given matrix.

    Raises:
        ValueError: Bad matrix.
        ArithmeticError: Failed to perform the decomposition to desired
            tolerance.
        """
    if mat.shape != (4, 4) or not predicates.is_special_orthogonal(mat,
                                                                   tolerance):
        raise ValueError('mat must be 4x4 special orthogonal.')

    magic = np.array([[1, 0, 0, 1j],
                      [0, 1j, 1, 0],
                      [0, 1j, -1, 0],
                      [1, 0, 0, -1j]]) * np.sqrt(0.5)
    ab = combinators.dot(magic, mat, np.conj(magic.T))
    _, a, b = kron_factor_4x4_to_2x2s(ab, tolerance)

    # Check decomposition against desired tolerance.
    reconstructed = combinators.dot(np.conj(magic.T),
                                    combinators.kron(a, b),
                                    magic)
    if not tolerance.all_close(reconstructed, mat):
        raise ArithmeticError('Failed to decompose to desired tolerance.')

    return a, b
    np.linalg.inv(U)
except np.linalg.LinAlgError:
    print("Not a valid unitary operation")

# check if it is all real. This lets us use 2 CNOTS
real = True
for row in U:
    for element in row:
        if np.imag(element) != 0:
            real = False
            print("Nonreal matrix")

# print("U\n")
# print(U)

print(is_special_orthogonal(U))

print("Determinant = ", np.around(np.linalg.det(U), 2))

mUm = magic_basis @ U @ magic_basis.conjugate().transpose() @ np.kron(
    I2, pauli_Z) @ CNOT1 @ CNOT2 @ CNOT1

tuple = kron_factor_4x4_to_2x2s(mUm)

# print(tuple[1])
# print(tuple[2])

print()
print(U)
# print()
# print(np.around(magic_basis.conjugate().transpose() @ U @ magic_basis, 2))
Example #7
0
def test_bidiagonalize_unitary_with_special_orthogonals(mat):
    p, d, q = diagonalize.bidiagonalize_unitary_with_special_orthogonals(mat)
    assert predicates.is_special_orthogonal(p)
    assert predicates.is_special_orthogonal(q)
    assert np.allclose(p.dot(mat).dot(q), np.diag(d))
    assert_bidiagonalized_by(mat, p, q)
Example #8
0
def test_is_special_orthogonal():
    assert predicates.is_special_orthogonal(np.empty((0, 0)))
    assert not predicates.is_special_orthogonal(np.empty((1, 0)))
    assert not predicates.is_special_orthogonal(np.empty((0, 1)))

    assert predicates.is_special_orthogonal(np.array([[1]]))
    assert not predicates.is_special_orthogonal(np.array([[-1]]))
    assert not predicates.is_special_orthogonal(np.array([[1j]]))
    assert not predicates.is_special_orthogonal(np.array([[5]]))
    assert not predicates.is_special_orthogonal(np.array([[3j]]))

    assert not predicates.is_special_orthogonal(np.array([[1, 0]]))
    assert not predicates.is_special_orthogonal(np.array([[1], [0]]))

    assert not predicates.is_special_orthogonal(np.array([[1, 0], [0, -2]]))
    assert not predicates.is_special_orthogonal(np.array([[1, 0], [0, -1]]))
    assert predicates.is_special_orthogonal(np.array([[-1, 0], [0, -1]]))
    assert not predicates.is_special_orthogonal(np.array([[1j, 0], [0, 1]]))
    assert not predicates.is_special_orthogonal(np.array([[1, 0], [1, 1]]))
    assert not predicates.is_special_orthogonal(np.array([[1, 1], [0, 1]]))
    assert not predicates.is_special_orthogonal(np.array([[1, 1], [1, 1]]))
    assert not predicates.is_special_orthogonal(np.array([[1, -1], [1, 1]]))
    assert predicates.is_special_orthogonal(
        np.array([[1, -1], [1, 1]]) * np.sqrt(0.5))
    assert not predicates.is_special_orthogonal(
        np.array([[1, 1], [1, -1]]) * np.sqrt(0.5))
    assert not predicates.is_special_orthogonal(
        np.array([[1, 1j], [1j, 1]]) * np.sqrt(0.5))
    assert not predicates.is_special_orthogonal(
        np.array([[1, -1j], [1j, 1]]) * np.sqrt(0.5))

    assert predicates.is_special_orthogonal(
        np.array([[1, 1e-11], [0, 1 + 1e-11]]))