1.4 Randomized Measurement V1#

Entanglement Entropy#

This method is based on Probing Rényi entanglement entropy via randomized measurements with deplorizing error mitigation by Simple mitigation of global depolarizing errors in quantum simulations.

randomized_entangled_entropy_v1#

Here, we assume you already have the data from the calculation. You can call the function randomized_entangled_entropy_v1 from qurry.process.randomized_measure to calculate the entropy.

In this function, only shots, counts, and degree are required arguments. The others are optional.

The following is the arguments of the function:

def randomized_entangled_entropy_v1(
    shots: int,
    counts: list[dict[str, int]],
    degree: Optional[Union[tuple[int, int], int]],
    measure: Optional[tuple[int, int]] = None,
    backend: PostProcessingBackendLabel = DEFAULT_PROCESS_BACKEND,
    workers_num: Optional[int] = None,
    pbar: Optional[tqdm.tqdm] = None,
) -> RandomizedEntangledEntropyComplex:
    """Calculate entangled entropy.

    Args:
        shots (int):
            Shots of the counts.
        counts (list[dict[str, int]]):
            Counts from randomized measurement results.
        degree (Optional[Union[tuple[int, int], int]]):
            The range of partition.
        measure (Optional[tuple[int, int]], optional):
            The range that implemented the measuring gate.
            If not specified, then use all qubits.
            This will affect the range of partition
            when you not implement the measuring gate on all qubit.
            Defaults to None.
        backend (PostProcessingBackendLabel, optional):
            Backend for the post-processing.
            Defaults to DEFAULT_PROCESS_BACKEND.
        workers_num (Optional[int], optional):
            Number of multi-processing workers, it will be ignored if backend is Rust.
            if sets to 1, then disable to using multi-processing;
            if not specified, then use the number of all cpu counts by `os.cpu_count()`.
            This only works for Python and Cython backend.
            Defaults to None.
        pbar (Optional[tqdm.tqdm], optional):
            The progress bar API, you can use put a :cls:`tqdm` object here.
            This function will update the progress bar description.
            Defaults to None.

    Returns:
        RandomizedEntangledEntropyComplex:
            A dictionary contains purity, entropy,
            a list of each overlap, puritySD, degree,
            actual measure range, bitstring range and more.
    """

This function returns a dictionary that contains the entropy, purity, and other relevant information. The returned dict contains the following information:

class RandomizedEntangledEntropyComplex(TypedDict):
    """The result of the analysis."""

    purity: Union[np.float64, float]
    """The purity of the system."""
    entropy: Union[np.float64, float]
    """The entropy of the system."""
    purityCells: Union[dict[int, np.float64], dict[int, float]]
    """The purity of each cell."""
    puritySD: Union[np.float64, float]
    """The standard deviation of the purity."""
    entropySD: Union[np.float64, float]
    """The standard deviation of the entropy."""
    degree: Optional[Union[tuple[int, int], int]]
    """The range of partition."""
    measureActually: Union[tuple[int, int], tuple[()]]
    """The range of partition refer to all qubits."""
    bitStringRange: Union[tuple[int, int], tuple[()]]
    """The range of partition on the bitstring."""
    countsNum: int
    """The number of counts."""

Dummy Data#

from qurry.capsule import quickRead

easy_dummy: dict[str, dict[str, int]] = quickRead("../easy-dummy.json")
large_dummy_list = [easy_dummy["0"] for _ in range(100)]

Simple Example#

from qurry.process.randomized_measure import (
    randomized_entangled_entropy_v1,
    RandomizedEntangledEntropyComplex,
)

test_result_1_1_1 = randomized_entangled_entropy_v1(4096, large_dummy_list, 6)
from pprint import pprint

print("| result of randomized_entangled_entropy_v1 except for purityCells")
pprint({k: v for k, v in test_result_1_1_1.items() if k != "purityCells"})
# "purityCells" is too long we skip it here

print("| result of randomized_entangled_entropy_v1[purityCells]")
print(test_result_1_1_1["purityCells"][0])
print(test_result_1_1_1["purityCells"][1])
| result of randomized_entangled_entropy_v1 except for purityCells
{'bitStringRange': (2, 8),
 'countsNum': 100,
 'degree': 6,
 'entropy': np.float64(-0.08786065308638322),
 'entropySD': np.float64(0.0),
 'measureActually': (2, 8),
 'purity': np.float64(1.0627930164337158),
 'puritySD': np.float64(0.0),
 'takingTime': 0.002523279}
| result of randomized_entangled_entropy_v1[purityCells]
1.0627930164337158
1.0627930164337158

Integration with your own progress bar#

from tqdm import tqdm
import time

all_counts_progress_01 = tqdm(
    [
        (4096, large_dummy_list, 6),
        (4096, large_dummy_list, (2, 8)),
        (4096, large_dummy_list, 7),
        (4096, large_dummy_list, (0, 7)),
        (4096, large_dummy_list, (-2, 5)),
        (4096, large_dummy_list, (-5, -1)),
        (4096, large_dummy_list, (3, -2)),
    ],
    bar_format="| {desc} - {elapsed} < {remaining}",
)

test_result_1_1_2 = []
for tmp_shot, tmp_counts, tmp_partition in all_counts_progress_01:
    test_result_1_1_2.append(
        randomized_entangled_entropy_v1(
            tmp_shot, tmp_counts, tmp_partition, pbar=all_counts_progress_01
        )
    )
    time.sleep(0.5)
|  - 00:00 < ?
| Calculate specific degree 6. - 00:00 < ?
| Calculate specific degree 6. - 00:00 < 00:03
| Calculate specific degree (2, 8). - 00:00 < 00:03
| Calculate specific degree (2, 8). - 00:01 < 00:02
| Calculate specific degree 7. - 00:01 < 00:02     
| Calculate specific degree 7. - 00:01 < 00:02
| Calculate specific degree (0, 7). - 00:01 < 00:02
| Calculate specific degree (0, 7). - 00:02 < 00:01
| Calculate specific degree (-2, 5). - 00:02 < 00:01
| Calculate specific degree (-2, 5). - 00:02 < 00:01
| Calculate specific degree (-5, -1). - 00:02 < 00:01
| Calculate specific degree (-5, -1). - 00:03 < 00:00
| Calculate specific degree (3, -2). - 00:03 < 00:00 
| Calculate specific degree (3, -2). - 00:03 < 00:00
| Calculate specific degree (3, -2). - 00:03 < 00:00

Using Python backend#

It will be slow. You’d better think twice before using it.

all_counts_progress_02 = tqdm(
    [
        (4096, large_dummy_list, 6),
        (4096, large_dummy_list, (2, 8)),
        (4096, large_dummy_list, 7),
        (4096, large_dummy_list, (0, 7)),
        (4096, large_dummy_list, (-2, 5)),
        (4096, large_dummy_list, (-5, -1)),
        (4096, large_dummy_list, (3, -2)),
    ],
    bar_format="| {desc} - {elapsed} < {remaining}",
)


test_result_1_1_2 = []
for tmp_shot, tmp_counts, tmp_partition in all_counts_progress_02:
    test_result_1_1_2.append(
        randomized_entangled_entropy_v1(
            tmp_shot,
            tmp_counts,
            tmp_partition,
            pbar=all_counts_progress_02,
            backend="Python",
        )
    )
    time.sleep(0.5)
|  - 00:00 < ?
| Calculate specific degree 6. - 00:00 < ?
| Calculate specific degree 6. - 00:03 < 00:22
| Calculate specific degree (2, 8). - 00:03 < 00:22
| Calculate specific degree (2, 8). - 00:07 < 00:17
| Calculate specific degree 7. - 00:07 < 00:17     
| Calculate specific degree 7. - 00:11 < 00:14
| Calculate specific degree (0, 7). - 00:11 < 00:14
| Calculate specific degree (0, 7). - 00:14 < 00:11
| Calculate specific degree (-2, 5). - 00:14 < 00:11
| Calculate specific degree (-2, 5). - 00:18 < 00:07
| Calculate specific degree (-5, -1). - 00:18 < 00:07
| Calculate specific degree (-5, -1). - 00:22 < 00:03
| Calculate specific degree (3, -2). - 00:22 < 00:03 
| Calculate specific degree (3, -2). - 00:25 < 00:00
| Calculate specific degree (3, -2). - 00:25 < 00:00

Post-Process Availablities and Version Info#

from qurry.process.status import AVAIBILITY_STATESHEET

AVAIBILITY_STATESHEET
 | Qurrium version: 0.13.0
---------------------------------------------------------------------------
 ### Qurrium Post-Processing
   - Backend Availability ................... Python Cython Rust   JAX   
 - randomized_measure
   - entangled_entropy.entropy_core_2 ....... Yes    Depr.  Yes    No    
   - entangle_entropy.purity_cell_2 ......... Yes    Depr.  Yes    No    
   - entangled_entropy_v1.entropy_core ...... Yes    Depr.  Yes    No    
   - entangle_entropy_v1.purity_cell ........ Yes    Depr.  Yes    No    
   - wavefunction_overlap.echo_core_2 ....... Yes    Depr.  Yes    No    
   - wavefunction_overlap.echo_cell_2 ....... Yes    Depr.  Yes    No    
   - wavefunction_overlap_v1.echo_core ...... Yes    Depr.  Yes    No    
   - wavefunction_overlap_v1.echo_cell ...... Yes    Depr.  Yes    No    
 - hadamard_test
   - purity_echo_core ....................... Yes    No     Yes    No    
 - magnet_square
   - magnsq_core ............................ Yes    No     Yes    No    
 - string_operator
   - strop_core ............................. Yes    No     Yes    No    
 - classical_shadow
   - rho_m_core ............................. Yes    No     No     Yes   
 - utils
   - randomized ............................. Yes    Depr.  Yes    No    
   - counts_process ......................... Yes    No     Yes    No    
   - bit_slice .............................. Yes    No     Yes    No    
   - dummy .................................. Yes    No     Yes    No    
   - test ................................... Yes    No     Yes    No    
---------------------------------------------------------------------------
   + Yes ...... Working normally.
   + Error .... Exception occurred.
   + No ....... Not supported.
   + Depr. .... Deprecated.
---------------------------------------------------------------------------
by <Hoshi>