Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Vectorization and unvectorization for Hermitian matrix #243

Open
vprusso opened this issue Nov 15, 2023 · 2 comments
Open

Feature: Vectorization and unvectorization for Hermitian matrix #243

vprusso opened this issue Nov 15, 2023 · 2 comments
Labels
Milestone

Comments

@vprusso
Copy link
Owner

vprusso commented Nov 15, 2023

The ability to vectorize and unvectorize a Hermitian matrix will be useful when generating random PPT states.

Something like this following:

Vectorize:

def vectorize_hermitian_matrix(X):
    """
    Vectorize a Hermitian matrix by scaling the off-diagonal elements.
    
    Args:
    X (numpy.ndarray): A Hermitian matrix (square, symmetric, complex).

    Returns:
    numpy.ndarray: A vectorized form of the Hermitian matrix.
    """
    n = X.shape[0]
    sX = np.diag(np.diag(X)) + np.sqrt(2) * (np.real(np.triu(X, k=1)) + np.imag(np.tril(X, k=-1)))
    return sX.reshape(n**2, 1)

Unvectorize:

def unvectorize_hermitian_matrix(symX):
    """
    Unvectorize a vectorized Hermitian matrix to its original form.

    Args:
    symX (numpy.ndarray): A vectorized Hermitian matrix.

    Returns:
    numpy.ndarray: The original Hermitian matrix.
    """
    n = int(np.round(np.sqrt(len(symX))))
    tmpX = np.reshape(symX, (n, n))
    triX = (np.triu(tmpX, k=1) + 1j * np.tril(tmpX, k=-1)) / np.sqrt(2)
    return np.diag(np.diag(tmpX)) + triX + triX.conj().T

The unvectorize function is the inverse of the vectorize one, so a set of tests that capture that, like the following, would be helpful:

def test_hermitian_vectorization():
    # Test case 1: 2x2 Hermitian matrix
    X1 = np.array([[1+1j, 2+2j], [2-2j, 3+3j]])
    sv1 = vectorize_hermitian_matrix(X1)
    X1_reconstructed = unvectorize_hermitian_matrix(sv1)
    assert np.allclose(X1, X1_reconstructed), "Test case 1 failed"

    # Test case 2: 3x3 Hermitian matrix
    X2 = np.array([[1+0j, 2-1j, 3+4j], [2+1j, 5+0j, 6-2j], [3-4j, 6+2j, 7+0j]])
    sv2 = vectorize_hermitian_matrix(X2)
    X2_reconstructed = unvectorize_hermitian_matrix(sv2)
    assert np.allclose(X2, X2_reconstructed), "Test case 2 failed"

    print("All test cases passed!")

# Run the tests
test_hermitian_vectorization()

This would most likely live in matrix_ops/ with the corresponding tests in test_matrix_ops/.

@vprusso vprusso added the good first issue Good for newcomers label Nov 15, 2023
@purva-thakre
Copy link
Collaborator

When attempting to fix this issue, it might also be better to use the function's docstrings to distinguish between the functions described in the issue's description vs. the vec and unvec functions already in matrix_ops/.

"""Unvec operation."""

"""Vec operation."""

@vprusso
Copy link
Owner Author

vprusso commented Nov 18, 2023

Good point. I'll make sure to accentuate that vectorize_hermitian_matrix is specialized for Hermitian matrices and includes scaling to account for the complex structure of such matrices. In contrast, the vec operation is a general matrix-to-vector transformation without any modifications to the matrix elements.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants