|
3 | 3 | from typing import Union
|
4 | 4 |
|
5 | 5 | import numpy as np
|
6 |
| -from scipy.linalg import fractional_matrix_power |
7 | 6 |
|
8 | 7 | from qibo.backends import _check_backend
|
9 |
| -from qibo.backends.pytorch import PyTorchBackend |
10 | 8 | from qibo.config import PRECISION_TOL, raise_error
|
11 |
| -from qibo.quantum_info.linalg_operations import partial_trace |
| 9 | +from qibo.quantum_info.linalg_operations import matrix_power, partial_trace |
12 | 10 | from qibo.quantum_info.metrics import _check_hermitian, purity
|
13 | 11 |
|
14 | 12 |
|
@@ -724,7 +722,7 @@ def renyi_entropy(state, alpha: Union[float, int], base: float = 2, backend=None
|
724 | 722 | / np.log2(base)
|
725 | 723 | )
|
726 | 724 |
|
727 |
| - log = backend.np.log2(backend.np.trace(_matrix_power(state, alpha, backend))) |
| 725 | + log = backend.np.log2(backend.np.trace(matrix_power(state, alpha, backend))) |
728 | 726 |
|
729 | 727 | return (1 / (1 - alpha)) * log / np.log2(base)
|
730 | 728 |
|
@@ -823,17 +821,17 @@ def relative_renyi_entropy(
|
823 | 821 | return relative_von_neumann_entropy(state, target, base, backend=backend)
|
824 | 822 |
|
825 | 823 | if alpha == np.inf:
|
826 |
| - new_state = _matrix_power(state, 0.5, backend) |
827 |
| - new_target = _matrix_power(target, 0.5, backend) |
| 824 | + new_state = matrix_power(state, 0.5, backend) |
| 825 | + new_target = matrix_power(target, 0.5, backend) |
828 | 826 |
|
829 | 827 | log = backend.np.log2(
|
830 | 828 | backend.calculate_norm_density_matrix(new_state @ new_target, order=1)
|
831 | 829 | )
|
832 | 830 |
|
833 | 831 | return -2 * log / np.log2(base)
|
834 | 832 |
|
835 |
| - log = _matrix_power(state, alpha, backend) |
836 |
| - log = log @ _matrix_power(target, 1 - alpha, backend) |
| 833 | + log = matrix_power(state, alpha, backend) |
| 834 | + log = log @ matrix_power(target, 1 - alpha, backend) |
837 | 835 | log = backend.np.log2(backend.np.trace(log))
|
838 | 836 |
|
839 | 837 | return (1 / (alpha - 1)) * log / np.log2(base)
|
@@ -891,7 +889,7 @@ def tsallis_entropy(state, alpha: float, base: float = 2, backend=None):
|
891 | 889 | return von_neumann_entropy(state, base=base, backend=backend)
|
892 | 890 |
|
893 | 891 | return (1 / (1 - alpha)) * (
|
894 |
| - backend.np.trace(_matrix_power(state, alpha, backend)) - 1 |
| 892 | + backend.np.trace(matrix_power(state, alpha, backend)) - 1 |
895 | 893 | )
|
896 | 894 |
|
897 | 895 |
|
@@ -953,19 +951,3 @@ def entanglement_entropy(
|
953 | 951 | )
|
954 | 952 |
|
955 | 953 | return entropy_entanglement
|
956 |
| - |
957 |
| - |
958 |
| -def _matrix_power(matrix, alpha, backend): |
959 |
| - """Calculates ``matrix ** alpha`` according to backend.""" |
960 |
| - if backend.__class__.__name__ in [ |
961 |
| - "CupyBackend", |
962 |
| - "CuQuantumBackend", |
963 |
| - ]: # pragma: no cover |
964 |
| - new_matrix = backend.to_numpy(matrix) |
965 |
| - else: |
966 |
| - new_matrix = backend.np.copy(matrix) |
967 |
| - |
968 |
| - if len(new_matrix.shape) == 1: |
969 |
| - new_matrix = backend.np.outer(new_matrix, backend.np.conj(new_matrix)) |
970 |
| - |
971 |
| - return backend.cast(fractional_matrix_power(backend.to_numpy(new_matrix), alpha)) |
0 commit comments