1.5 Randomized Measurement V1 with Error Mitigation#
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_mitigated_v1
#
Similar to randomized_entangled_entropy
introduced in section 3.1.3 a, this function is used to calculate the entropy of a quantum state, but additionally, mitigate the depolarizing error. You can call the function randomized_entangled_entropy_mitigated_v1
from qurry.process.randomized_measure
. In order to perform the error mitigation, this function requires the measurement outcomes of the all system as the baseline. If you already have data at hand, you can prepare a dict
like following:
class ExistingAllSystemSource(TypedDict):
"""Existing all system source."""
purityCellsAllSys: dict[int, float]
"""The purity of each cell of all system."""
bitStringRange: tuple[int, int]
"""The range of partition on the bitstring."""
measureActually: tuple[int, int]
"""The range of partition refer to all qubits."""
source: str
"""The source of all system."""
And assign it into the argument existed_all_system
of the function randomized_entangled_entropy_mitigated_v1
to save a lot of time on mitigating purities of all partitions.
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_mitigated_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,
existed_all_system: Optional[ExistingAllSystemSource] = None,
pbar: Optional[tqdm.tqdm] = None,
) -> RandomizedEntangledEntropyMitigatedComplex:
"""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.
existed_all_system (Optional[ExistingAllSystemSource], optional):
Existing all system source.
If there is known all system result,
then you can put it here to save a lot of time on calculating all system
for not matter what partition you are using,
their all system result is the same.
All system source should contain
`purityCellsAllSys`, `bitStringRange`, `measureActually`, `source` for its name.
This can save a lot of time
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:
RandomizedEntangledEntropyMitigatedComplex:
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 return dict
contains the following variables:
class RandomizedEntangledEntropyMitigatedComplex(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."""
puritySD: Union[np.float64, float]
"""The standard deviation of the purity."""
entropySD: Union[np.float64, float]
"""The standard deviation of the entropy."""
purityCells: Union[dict[int, np.float64], dict[int, float]]
"""The purity of each cell."""
bitStringRange: Union[tuple[int, int], tuple[()]]
"""The range of partition on the bitstring."""
allSystemSource: Union[str, Literal["independent"]]
"""The source of all system."""
purityAllSys: Union[np.float64, float]
"""The purity of all system."""
entropyAllSys: Union[np.float64, float]
"""The entropy of all system."""
puritySDAllSys: Union[np.float64, float]
"""The standard deviation of the purity of all system."""
entropySDAllSys: Union[np.float64, float]
"""The standard deviation of the entropy of all system."""
purityCellsAllSys: Union[dict[int, np.float64], dict[int, float]]
"""The purity of each cell of all system."""
bitsStringRangeAllSys: Union[tuple[int, int], tuple[()], None]
"""The range of partition on the bitstring of all system."""
errorRate: Union[np.float64, float]
"""The error rate of the measurement from depolarizing error migigation calculated."""
mitigatedPurity: Union[np.float64, float]
"""The mitigated purity."""
mitigatedEntropy: Union[np.float64, float]
"""The mitigated entropy."""
degree: Optional[Union[tuple[int, int], int]]
"""The range of partition."""
num_qubits: int
"""The number of qubits of this syystem."""
measure: tuple[str, Union[list[int], tuple[int, int]]]
"""The qubit range of the measurement and text description.
- The first element is the text description.
- The second element is the qubit range of the measurement.
---
- When the measurement is specified, it will be:
>>> ("measure range:", (0, 3))
- When the measurement is not specified, it will be:
>>> ("not specified, use all qubits", (0, 3))
- When null counts exist, it will be:
>>> ("The following is the index of null counts.", [0, 1, 2, 3])
"""
measureActually: Union[tuple[int, int], tuple[()]]
"""The range of partition refer to all qubits."""
measureActuallyAllSys: Union[tuple[int, int], tuple[()], None]
"""The range of partition refer to all qubits of all system."""
countsNum: int
"""The number of counts."""
takingTime: Union[np.float64, float]
"""The time of taking during specific partition."""
takingTimeAllSys: Union[np.float64, float]
"""The taking time of the all system if it is calculated,
it will be 0 when use the all system from other analysis.
"""
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_mitigated_v1,
RandomizedEntangledEntropyMitigatedComplex,
ExistingAllSystemSource,
)
test_result_1_2_1 = randomized_entangled_entropy_mitigated_v1(4096, large_dummy_list, 6)
from pprint import pprint
print("| result of randomized_entangled_entropy except for purityCells")
pprint({k: v for k, v in test_result_1_2_1.items() if "purityCells" not in k})
# "purityCells" is too long we skip it here
print()
print("| result of randomized_entangled_entropy[purityCells]")
print(test_result_1_2_1["purityCells"][0])
print(test_result_1_2_1["purityCells"][1])
print()
print("| result of randomized_entangled_entropy[purityCellsAllSys]")
print(test_result_1_2_1["purityCellsAllSys"][0])
print(test_result_1_2_1["purityCellsAllSys"][1])
| result of randomized_entangled_entropy except for purityCells
{'allSystemSource': 'independent',
'bitStringRange': (2, 8),
'bitsStringRangeAllSys': (0, 8),
'countsNum': 100,
'degree': 6,
'entropy': np.float64(-0.08786065308638322),
'entropyAllSys': np.float64(0.9461940705953849),
'entropySD': np.float64(0.0),
'entropySDAllSys': np.float64(0.0),
'errorRate': np.float64(0.2808939301105586),
'measure': ('not specified, use all qubits', (2, 8)),
'measureActually': (2, 8),
'measureActuallyAllSys': (0, 8),
'mitigatedEntropy': np.float64(-1.0290289944568636),
'mitigatedPurity': np.float64(2.0406503299038543),
'num_qubits': 8,
'purity': np.float64(1.0627930164337158),
'purityAllSys': np.float64(0.5189998149871826),
'puritySD': np.float64(0.0),
'puritySDAllSys': np.float64(0.0),
'takingTime': 0.002717059,
'takingTimeAllSys': 0.008686682}
| result of randomized_entangled_entropy[purityCells]
1.0627930164337158
1.0627930164337158
| result of randomized_entangled_entropy[purityCellsAllSys]
0.5189998149871826
0.5189998149871826
With Existing All System Data#
test_result_1_2_2 = randomized_entangled_entropy_mitigated_v1(
4096,
large_dummy_list,
6,
existed_all_system={
"purityCellsAllSys": test_result_1_2_1["purityCellsAllSys"],
"bitStringRange": test_result_1_2_1["bitStringRange"],
"measureActually": test_result_1_2_1["measureActually"],
"source": "from_previous_result:test_result_1_2_1",
},
)
from pprint import pprint
print("| result of randomized_entangled_entropy except for purityCells")
pprint({k: v for k, v in test_result_1_2_2.items() if "purityCells" not in k})
# "purityCells" is too long we skip it here
print()
print("| result of randomized_entangled_entropy[purityCells]")
print(test_result_1_2_2["purityCells"][0])
print(test_result_1_2_2["purityCells"][1])
print()
print("| result of randomized_entangled_entropy[purityCellsAllSys]")
print(test_result_1_2_2["purityCellsAllSys"][0])
print(test_result_1_2_2["purityCellsAllSys"][1])
print()
print("| You can see takingTimeAllSys is 0 for we use existed_all_system")
print(test_result_1_2_2["takingTimeAllSys"])
| result of randomized_entangled_entropy except for purityCells
{'allSystemSource': 'from_previous_result:test_result_1_2_1',
'bitStringRange': (2, 8),
'bitsStringRangeAllSys': (2, 8),
'countsNum': 100,
'degree': 6,
'entropy': np.float64(-0.08786065308638322),
'entropyAllSys': np.float64(0.9461940705953849),
'entropySD': np.float64(0.0),
'entropySDAllSys': np.float64(0.0),
'errorRate': np.float64(0.2808939301105586),
'measure': ('not specified, use all qubits', (2, 8)),
'measureActually': (2, 8),
'measureActuallyAllSys': (2, 8),
'mitigatedEntropy': np.float64(-1.0290289944568636),
'mitigatedPurity': np.float64(2.0406503299038543),
'num_qubits': 8,
'purity': np.float64(1.0627930164337158),
'purityAllSys': np.float64(0.5189998149871826),
'puritySD': np.float64(0.0),
'puritySDAllSys': np.float64(0.0),
'takingTime': 0.002146689,
'takingTimeAllSys': 0}
| result of randomized_entangled_entropy[purityCells]
1.0627930164337158
1.0627930164337158
| result of randomized_entangled_entropy[purityCellsAllSys]
0.5189998149871826
0.5189998149871826
| You can see takingTimeAllSys is 0 for we use existed_all_system
0
Integration wit your own progress bar#
from tqdm import tqdm
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_2_3 = []
for tmp_shot, tmp_counts, tmp_partition in all_counts_progress_01:
test_result_1_2_3.append(
randomized_entangled_entropy_mitigated_v1(
tmp_shot,
tmp_counts,
tmp_partition,
existed_all_system=(
None
if len(test_result_1_2_3) == 0
else {
"purityCellsAllSys": test_result_1_2_3[-1]["purityCellsAllSys"],
"bitStringRange": test_result_1_2_3[-1]["bitStringRange"],
"measureActually": test_result_1_2_3[-1]["measureActually"],
"source": "from_previous_result:test_result_1_2_1",
}
),
pbar=all_counts_progress_01,
)
)
print(f"| partition: {tmp_partition}")
print("| - takingTime:", test_result_1_2_3[-1]["takingTime"])
print("| - takingTimeAllSys:", test_result_1_2_3[-1]["takingTimeAllSys"])
| - 00:00 < ?
| Calculate specific degree 6 by Rust. - 00:00 < ?
| Preparing error mitigation of (2, 8) on None - 00:00 < ?
| with mitigation. - 00:00 < ?
| Calculate specific degree (2, 8) by Rust. - 00:00 < ?
| Preparing error mitigation of (2, 8) on None - 00:00 < ?
| with mitigation. - 00:00 < ?
| Calculate specific degree 7 by Rust. - 00:00 < ?
| Preparing error mitigation of (1, 8) on None - 00:00 < ?
| with mitigation. - 00:00 < ?
| Calculate specific degree (0, 7) by Rust. - 00:00 < ?
| Preparing error mitigation of (0, 7) on None - 00:00 < ?
| with mitigation. - 00:00 < ?
| Calculate specific degree (-2, 5) by Rust. - 00:00 < ?
| Preparing error mitigation of (-2, 5) on None - 00:00 < ?
| with mitigation. - 00:00 < ?
| Calculate specific degree (-5, -1) by Rust. - 00:00 < ?
| Preparing error mitigation of (3, 7) on None - 00:00 < ?
| with mitigation. - 00:00 < ?
| Calculate specific degree (3, -2) by Rust. - 00:00 < ?
| Preparing error mitigation of (3, 6) on None - 00:00 < ?
| with mitigation. - 00:00 < ?
| with mitigation. - 00:00 < 00:00
| partition: 6
| - takingTime: 0.002107948
| - takingTimeAllSys: 0.009134133
| partition: (2, 8)
| - takingTime: 0.002256208
| - takingTimeAllSys: 0
| partition: 7
| - takingTime: 0.004148485
| - takingTimeAllSys: 0
| partition: (0, 7)
| - takingTime: 0.003592065
| - takingTimeAllSys: 0
| partition: (-2, 5)
| - takingTime: 0.004112764
| - takingTimeAllSys: 0
| partition: (-5, -1)
| - takingTime: 0.00089297
| - takingTimeAllSys: 0
| partition: (3, -2)
| - takingTime: 0.00075446
| - takingTimeAllSys: 0
Using Python backend#
It will be slow. Yoy 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_2_4 = []
for tmp_shot, tmp_counts, tmp_partition in all_counts_progress_02:
test_result_1_2_4.append(
randomized_entangled_entropy_mitigated_v1(
tmp_shot,
tmp_counts,
tmp_partition,
existed_all_system=(
None
if len(test_result_1_2_4) == 0
else {
"purityCellsAllSys": test_result_1_2_4[-1]["purityCellsAllSys"],
"bitStringRange": test_result_1_2_4[-1]["bitStringRange"],
"measureActually": test_result_1_2_4[-1]["measureActually"],
"source": "from_previous_result:test_result_1_2_4",
}
),
pbar=all_counts_progress_02,
backend="Python",
)
)
| - 00:00 < ?
| Calculate specific degree 6 by Python. - 00:00 < ?
| Preparing error mitigation of (2, 8) on None - 00:07 < ?
| Partition: (2, 8), Measure: (0, 8), backend: Python, 16 workers, 100 overlaps with mitigation. - 00:07 < ?
| Partition: (2, 8), Measure: (0, 8), backend: Python, 16 workers, 100 overlaps with mitigation. - 00:07 < 00:44
| Calculate specific degree (2, 8) by Python. - 00:07 < 00:44
| Preparing error mitigation of (2, 8) on None - 00:10 < 00:44
| Partition: (2, 8), Measure: (0, 8), backend: Python, 16 workers, 100 overlaps with mitigation. - 00:10 < 00:44
| Partition: (2, 8), Measure: (0, 8), backend: Python, 16 workers, 100 overlaps with mitigation. - 00:10 < 00:24
| Calculate specific degree 7 by Python. - 00:10 < 00:24
| Preparing error mitigation of (1, 8) on None - 00:13 < 00:24
| Partition: (1, 8), Measure: (0, 8), backend: Python, 16 workers, 100 overlaps with mitigation. - 00:13 < 00:24
| Partition: (1, 8), Measure: (0, 8), backend: Python, 16 workers, 100 overlaps with mitigation. - 00:13 < 00:16
| Calculate specific degree (0, 7) by Python. - 00:13 < 00:16
| Preparing error mitigation of (0, 7) on None - 00:17 < 00:16
| Partition: (0, 7), Measure: (0, 8), backend: Python, 16 workers, 100 overlaps with mitigation. - 00:17 < 00:16
| Partition: (0, 7), Measure: (0, 8), backend: Python, 16 workers, 100 overlaps with mitigation. - 00:17 < 00:11
| Calculate specific degree (-2, 5) by Python. - 00:17 < 00:11
| Preparing error mitigation of (-2, 5) on None - 00:21 < 00:11
| Partition: cycling-(-2, 5), Measure: (0, 8), backend: Python, 16 workers, 100 overlaps with mitigation. - 00:21 < 00:11
| Partition: cycling-(-2, 5), Measure: (0, 8), backend: Python, 16 workers, 100 overlaps with mitigation. - 00:21 < 00:07
| Calculate specific degree (-5, -1) by Python. - 00:21 < 00:07
| Preparing error mitigation of (3, 7) on None - 00:23 < 00:07
| Partition: (3, 7), Measure: (0, 8), backend: Python, 16 workers, 100 overlaps with mitigation. - 00:23 < 00:07
| Partition: (3, 7), Measure: (0, 8), backend: Python, 16 workers, 100 overlaps with mitigation. - 00:23 < 00:03
| Calculate specific degree (3, -2) by Python. - 00:23 < 00:03
| Preparing error mitigation of (3, 6) on None - 00:26 < 00:03
| Partition: (3, 6), Measure: (0, 8), backend: Python, 16 workers, 100 overlaps with mitigation. - 00:26 < 00:03
| Partition: (3, 6), Measure: (0, 8), backend: Python, 16 workers, 100 overlaps with mitigation. - 00:26 < 00:00
| Partition: (3, 6), Measure: (0, 8), backend: Python, 16 workers, 100 overlaps with mitigation. - 00:26 < 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>