hqs_quantum_solver.helpers#

Helper functions for other routines.

Copyright © 2023-2024 HQS Quantum Simulations GmbH. All Rights Reserved.

Functions

check_dtype_is_float_or_complex_and_return_it(matrix)

Simple helper to sanitize dtype to float/complex and reject others.

check_if_two_dimensional_and_return_shape(matrix)

Simple function that checks if the array is two-dimensional.

check_input_and_output_shapes_for_dot(left, ...)

Helper routine to check that the output shape is compatible with the inputs.

check_input_and_output_shapes_for_dot_h(...)

Helper routine to check that the output shape is compatible with the inputs for dot_h.

check_input_and_output_shapes_for_rdot(left, ...)

Helper routine to check that the output shape is compatible with the inputs.

check_input_and_output_shapes_for_rdot_h(...)

Helper routine to check that the output shape is compatible with the inputs.

convert_sparse_matrix_to_csr_eigen(matrix)

Takes a standard sparse matrix from SciPy and converts it to an Eigen representation.

convert_triples_to_csr_eigen(row, col, data, ...)

Takes a set of triples converts them to an Eigen representation.

is_density_matrix(matrix[, tolerance])

Test whether a matrix is a valid density matrix by checking its ρ-representability.

is_positive_definite(matrix)

Test whether a matrix is positive-definite.

is_positive_semidefinite(matrix[, tolerance])

Test whether a matrix is positive-semidefinite to a tolerance.

random_density_matrix(dimension[, ...])

Generates a random real/complex density matrix following Hilbert-Schmidt or Bures metrics.

random_haar_states(length, ...)

Generates randomly distributed input states as columns (uniform over the Haar measure).

random_phasor_states(length, number_of_samples)

Generates (normalised) random phasor state(s) (vectors made up of e^ix where x is random).

random_signor_states(length, number_of_samples)

Generates random signor state(s) (vectors made up +/- 1 but normalized).

random_unitary_or_orthogonal_matrix(...)

Generates a random unitary (or orthogonal) matrix uniform over the Haar measure.

check_if_two_dimensional_and_return_shape(matrix: SupportsShape) Tuple[int, int]#

Simple function that checks if the array is two-dimensional.

Parameters:

matrix (SupportsShape) – the (possibly non-)square matrix to be checked.

Returns:

The shape of the matrix.

Return type:

Tuple[int, int]

Raises:

ValueError – If the array is not 2D.

check_input_and_output_shapes_for_dot(left: SupportsShape, right: SupportsShape, out: SupportsShape | None = None) Tuple[int, ...]#

Helper routine to check that the output shape is compatible with the inputs.

Parameters:
Returns:

the shape of the output (ellipsis as it can be 1d or 2d)

Return type:

Tuple[int, …]

Raises:
  • ValueError – If the right input array is not one or two-dimensional.

  • ValueError – If the output shape is incompatible with the inputs.

check_input_and_output_shapes_for_dot_h(left: SupportsShape, right: SupportsShape, out: SupportsShape | None = None) Tuple[int, ...]#

Helper routine to check that the output shape is compatible with the inputs for dot_h.

Parameters:
Returns:

the shape of the output (ellipsis as it can be 1d or 2d)

Return type:

Tuple[int, …]

Raises:
  • ValueError – If the right input array is not one or two-dimensional.

  • ValueError – If the output shape is incompatible with the inputs.

check_input_and_output_shapes_for_rdot(left: SupportsShape, right: SupportsShape) Tuple[int, ...]#

Helper routine to check that the output shape is compatible with the inputs.

Parameters:
Returns:

the shape of the output (ellipsis as it can be 1d or 2d)

Return type:

Tuple[int, …]

Raises:

ValueError – If the left input array is not one or two-dimensional.

check_input_and_output_shapes_for_rdot_h(left: SupportsShape, right: SupportsShape) Tuple[int, ...]#

Helper routine to check that the output shape is compatible with the inputs.

Parameters:
Returns:

the shape of the output (ellipsis as it can be 1d or 2d)

Return type:

Tuple[int, …]

Raises:

ValueError – If the left input array is not one or two-dimensional.

convert_sparse_matrix_to_csr_eigen(matrix: spmatrix) csr_matrix_eigen | csr_matrix_eigen_c#

Takes a standard sparse matrix from SciPy and converts it to an Eigen representation.

Internally, this will convert to a COO format so that its internal triples may be viewed. For speed, we recommend initializing COO, or at least CSR/CSC but any sparse matrix from SciPy will work as they all support to_coo().

Parameters:

matrix (sparse_matrix) – The sparse matrix we wish to convert.

Returns:

The matrix now in csr_matrix_eigen or csr_matrix_eigen_c.

Return type:

MatrixEigenType

convert_triples_to_csr_eigen(row: ndarray, col: ndarray, data: ndarray, shape: Tuple[int, int]) csr_matrix_eigen | csr_matrix_eigen_c#

Takes a set of triples converts them to an Eigen representation.

Parameters:
  • row (np.ndarray) – The row data (int).

  • col (np.ndarray) – The column data (int).

  • data (np.ndarray) – The numerical data (with float or complex type).

  • shape (Tuple[int, int]) – The shape of the output matrix, must be 2d.

Returns:

The matrix now in Eigen representation.

Return type:

Union[csr_matrix_eigen, csr_matrix_eigen_c]

Raises:
  • ValueError – If the row, column and data inputs have incompatible shapes.

  • ValueError – If the output shape is not 2D.

is_density_matrix(matrix: ndarray, tolerance: float = 1e-11) bool#

Test whether a matrix is a valid density matrix by checking its ρ-representability.

Parameters:
  • matrix (np.ndarray) – Matrix under consideration

  • tolerance (float) – Tolerance for the trace deviation

Returns:

True if a valid density matrix, else False.

Return type:

bool

is_positive_definite(matrix: ndarray) bool#

Test whether a matrix is positive-definite.

This function effectively wraps the semidefinite check but with a tolerance set to zero. Though it is true an eigenvalue of a definite matrix may be arbitrarily close to zero, if it is so small that it is affected by noise then it is an ill-conditioned matrix and should be considered effectively semidefinite anyway.

Parameters:

matrix (np.ndarray) – Matrix under consideration.

Returns:

True if positive-definite, else False.

Return type:

bool

is_positive_semidefinite(matrix: ndarray, tolerance: float = 1e-11) bool#

Test whether a matrix is positive-semidefinite to a tolerance.

Due to numerical error, small amounts of negativity might be observed in eigenvalues that are otherwise zero. To account for this we add an infinitesimal shift to the cholesky check given by tolerance.

Parameters:
  • matrix (np.ndarray) – Matrix under consideration

  • tolerance (float) – The level of “negativity” allowed in the eigenvalues

Returns:

True if positive semi-definite, else False.

Return type:

bool

random_density_matrix(dimension: int, is_complex: bool = False, metric: Literal['bures', 'hilbert-schmidt'] = 'hilbert-schmidt') ndarray#

Generates a random real/complex density matrix following Hilbert-Schmidt or Bures metrics.

Valid metrics are “hilbert-schmidt” or “bures” (case-sensitive). We note that most use cases likely don’t need anything more than the Hilbert-Schmidt metric, we added Bures as it required very little extra development.

Reference: K. Życzkowski, et al. “Generating random density matrices.”

Journal of Mathematical Physics 52.6 (2011): 062201. arXiv:1010.3570v2

Parameters:
  • dimension (int) – The size of the matrix (n × n).

  • is_complex (bool) – Whether to generate a complex (True) or real (False) matrix.

  • metric (Metric) – The metric to generate the density matrix over.

Returns:

The density matrix satisfying the specified dtype and metric.

Return type:

np.ndarray

Raises:

NameError – If the metric requested is not supported.

random_haar_states(length: int, number_of_samples: int, is_complex: bool) ndarray#

Generates randomly distributed input states as columns (uniform over the Haar measure).

This is a simple routine to generate uniformly distributed states on the Haar measure. If the number of samples is set to one, a 1d vector will be returned, else a 2d array.

Parameters:
  • length (int) – The linear dimension of the state(s).

  • number_of_samples (int) – The number of samples taken.

  • is_complex (bool) – Whether you want complex (True) or real (False) state vectors.

Returns:

The random state(s).

Return type:

np.ndarray

random_phasor_states(length: int, number_of_samples: int) ndarray#

Generates (normalised) random phasor state(s) (vectors made up of e^ix where x is random).

Always complex so is_complex is not an option.

Parameters:
  • length (int) – The linear dimension of the state(s).

  • number_of_samples (int) – The number of samples taken

Returns:

The (normalized) phasor state(s).

Return type:

np.ndarray

random_signor_states(length: int, number_of_samples: int) ndarray#

Generates random signor state(s) (vectors made up +/- 1 but normalized).

Always real so is_complex is not an option.

Parameters:
  • length (int) – The linear dimension of the state(s).

  • number_of_samples (int) – The number of samples taken

Returns:

The (normalized) signor state(s).

Return type:

np.ndarray

random_unitary_or_orthogonal_matrix(dimension: int, is_complex: bool) ndarray#

Generates a random unitary (or orthogonal) matrix uniform over the Haar measure.

Reference:

F. Mezzadri, “How to generate random matrices from the classical compact groups.”, arXiv math-ph/0609050 (2006). arXiv:math-ph/0609050

Parameters:
  • dimension (int) – The size of the matrix (n × n).

  • is_complex (bool) – If True, return unitary matrix, else orthogonal.

Returns:

The random unitary or orthogonal matrix.

Return type:

np.ndarray