UnitarySimulator(device: str = 'CPU', precision: str = 'double', hidden_empty_qubits: bool = False, ignore_last_measure: bool = True)
Algorithms to calculate the unitary matrix of a quantum circuit, and simulate.
Parameters:
-
device
(str, default:
'CPU'
)
–
The device type, one of [CPU, GPU]. Defaults to "CPU".
-
precision
(str, default:
'double'
)
–
The precision for the unitary matrix. Defaults to "double".
-
hidden_empty_qubits
(bool, default:
False
)
–
Whether ignore the empty qubits or not, default to False.
Source code in QuICT/simulation/unitary/unitary_simulator.py
| def __init__(
self,
device: str = "CPU",
precision: str = "double",
hidden_empty_qubits: bool = False,
ignore_last_measure: bool = True,
):
"""
Args:
device (str, optional): The device type, one of [CPU, GPU]. Defaults to "CPU".
precision (str, optional): The precision for the unitary matrix. Defaults to "double".
hidden_empty_qubits (bool, optional): Whether ignore the empty qubits or not, default to False.
"""
assert device in ["CPU", "GPU"], ValueError("UnitarySimulation.device", "[CPU, GPU]", device)
self._device = device
assert precision in ["single", "double"], \
ValueError("UnitarySimulation.precision", "[single, double]", precision)
self._precision = precision
self._gate_calculator = GateSimulator(self._device, self._precision)
self._vector = None
self._hidden_empty_qubits = hidden_empty_qubits
self._ignore_last_measure = ignore_last_measure
|
run
run(circuit: Union[ndarray, Circuit], quantum_state: ndarray = None, use_previous: bool = False) -> np.ndarray
Simulation by given unitary matrix or circuit
Parameters:
-
circuit
(Union[ndarray, Circuit])
–
The unitary matrix or the circuit for simulation
-
quantum_state
(ndarray, default:
None
)
–
The initial quantum state vector.
-
use_previous
(bool, default:
False
)
–
whether using previous state vector. Defaults to False.
Returns:
-
ndarray
–
np.ndarray: The state vector after simulation
Source code in QuICT/simulation/unitary/unitary_simulator.py
| def run(
self,
circuit: Union[np.ndarray, Circuit],
quantum_state: np.ndarray = None,
use_previous: bool = False
) -> np.ndarray:
""" Simulation by given unitary matrix or circuit
Args:
circuit (Union[np.ndarray, Circuit]): The unitary matrix or the circuit for simulation
quantum_state (ndarray): The initial quantum state vector.
use_previous (bool, optional): whether using previous state vector. Defaults to False.
Returns:
np.ndarray: The state vector after simulation
"""
# Step 1: Generate the unitary matrix of the given circuit
if isinstance(circuit, (Circuit, CompositeGate)):
self._qubits_num = circuit.width()
self._used_qubits = circuit._gates.qubits
circuit.precision = self._precision
if self._hidden_empty_qubits and self._qubits_num != len(circuit._gates.qubits):
self._qubits_num = len(circuit._gates.qubits)
if isinstance(circuit, Circuit):
circuit = circuit.to_compositegate() & list(range(self._qubits_num))
else:
circuit & list(range(self._qubits_num))
self._unitary_matrix = circuit.matrix(self._device)
else:
row = circuit.shape[0]
self._qubits_num = int(np.log2(row))
self._unitary_matrix = self._gate_calculator.normalized_matrix(circuit, self._qubits_num)
self._ignore_last_measure = False
self._hidden_empty_qubits = False
if self._ignore_last_measure:
_, self._measured_q_order = circuit.gates_without_last_measure()
# Step 2: Prepare the state vector
self._original_state_vector = None
if quantum_state is not None:
self._vector = self._gate_calculator.dot(
self._unitary_matrix,
self._gate_calculator.normalized_state_vector(quantum_state, self._qubits_num)
)
elif not use_previous:
self._vector = self._unitary_matrix[:, 0]
return self._vector
|
sample
sample(shots: int = 1, target_qubits: list = None, extra_output: bool = False, seed: int = -1) -> dict
Sample the measured result from current state vector, please first run simulator.run().
Parameters:
-
shots
(int, default:
1
)
–
The sample times for current state vector.
-
target_qubits
(list, default:
None
)
–
The List of target sample qubits.
-
extra_output
(bool, default:
False
)
–
Output with extra info: measured qubits (list), and samples (list)
Returns:
-
dict
–
List[int]: The measured result list with length equal to 2 ** self._qubits
Source code in QuICT/simulation/unitary/unitary_simulator.py
| def sample(self, shots: int = 1, target_qubits: list = None, extra_output: bool = False, seed: int = -1) -> dict:
""" Sample the measured result from current state vector, please first run simulator.run().
Args:
shots (int): The sample times for current state vector.
target_qubits (list): The List of target sample qubits.
extra_output (bool): Output with extra info: measured qubits (list), and samples (list)
Returns:
List[int]: The measured result list with length equal to 2 ** self._qubits
"""
assert (self._vector is not None), \
SampleBeforeRunError("StateVectorSimulation sample without run any circuit.")
state_dict = defaultdict(int)
target_qubits = self._regularized_target_qubits(target_qubits)
sample_result = self._gate_calculator.sample_for_statevector_cdf(
shots, self._qubits_num, self._vector, target_qubits, seed=seed
)
for res in sample_result:
state_dict[res] += 1
if not extra_output:
return state_dict
else:
normalize_res, normalize_qorder, normalize_sample = self._sample_normalize(
state_dict, sample_result, target_qubits
)
return normalize_res, normalize_qorder, normalize_sample
|