跳转至

StateVectorSimulator

QuICT.simulation.state_vector.StateVectorSimulator

StateVectorSimulator(device: str = 'CPU', precision: str = 'double', gpu_device_id: int = 0, sync: bool = True, hidden_empty_qubits: bool = False, ignore_last_measure: bool = True)

The simulator for qubits' vector state.

Parameters:

  • device (str, default: 'CPU' ) –

    The device type, one of [CPU, GPU]. Defaults to "CPU".

  • precision (str, default: 'double' ) –

    The precision for the state vector, one of [single, double]. Defaults to "double".

  • gpu_device_id (int, default: 0 ) –

    The GPU device ID. Defaults to 0.

  • sync (bool, default: True ) –

    Sync mode or Async mode. Defaults to True.

  • hidden_empty_qubits (bool, default: False ) –

    Whether ignore the empty qubits or not, default to False.

Source code in QuICT/simulation/state_vector/statevector_simulator.py
def __init__(
    self,
    device: str = "CPU",
    precision: str = "double",
    gpu_device_id: int = 0,
    sync: bool = True,
    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 state vector, one of [single, double].
            Defaults to "double".
        gpu_device_id (int, optional): The GPU device ID. Defaults to 0.
        sync (bool, optional): Sync mode or Async mode. Defaults to True.
        hidden_empty_qubits (bool, optional): Whether ignore the empty qubits or not, default to False.
    """
    self._gate_calculator = GateSimulator(device, precision, gpu_device_id, sync)
    self._quantum_machine = None
    self._hidden_empty_qubits = hidden_empty_qubits
    self._ignore_last_measure = ignore_last_measure

apply_specialgate

apply_specialgate(index: int, type: GateType, prob: float = None)

Apply Measure/Reset gate in to simulator

Parameters:

  • index (int) –

    The given qubit index

  • type (GateType) –

    the gate type of special gate

  • prob (float, default: None ) –

    The given probability of measured the target qubit into 1

Returns:

  • [float]: The target qubit's measured value or reset value, <0 or <1

Source code in QuICT/simulation/state_vector/statevector_simulator.py
def apply_specialgate(self, index: int, type: GateType, prob: float = None):
    """ Apply Measure/Reset gate in to simulator

    Args:
        index (int): The given qubit index
        type (GateType): the gate type of special gate
        prob (float): The given probability of measured the target qubit into 1

    Returns:
        [float]: The target qubit's measured value or reset value, <0 or <1
    """
    from QuICT.ops.gate_kernel.gpu import apply_measuregate, apply_resetgate
    if type == GateType.measure:
        result = int(apply_measuregate(
            index,
            self._vector,
            self._qubits,
            prob,
            self._gate_calculator._sync
        ))
        self._circuit.qubits[self._qubits - 1 - index].measured = result
    elif type == GateType.reset:
        result = apply_resetgate(
            index,
            self._vector,
            self._qubits,
            prob,
            self._gate_calculator._sync
        )

    return result

apply_zeros

apply_zeros()

Set state vector to be zero.

Source code in QuICT/simulation/state_vector/statevector_simulator.py
def apply_zeros(self):
    """ Set state vector to be zero. """
    self._vector = self._gate_calculator._array_helper.zeros_like(self.vector)

get_expectations

get_expectations(circuit, hamiltonians, quantum_state: ndarray = None)

Run the simulator to get expectations.

Parameters:

  • circuit (Circuit) –

    The quantum circuits.

  • hamiltonians (Hamiltonian) –

    The hamiltonians for calculating expectations.

  • quantum_state (ndarray, default: None ) –

    The initial quantum state vector. Defaults to None.

Returns:

  • Union[float, np.ndarray]: The expectations.

  • Union[cp.array, np.array]: The state vector.

Source code in QuICT/simulation/state_vector/statevector_simulator.py
def get_expectations(self, circuit, hamiltonians, quantum_state: np.ndarray = None):
    """ Run the simulator to get expectations.

    Args:
        circuit (Circuit): The quantum circuits.
        hamiltonians (Hamiltonian): The hamiltonians for calculating expectations.
        quantum_state (ndarray, optional): The initial quantum state vector. Defaults to None.

    Returns:
        Union[float, np.ndarray]: The expectations.
        Union[cp.array, np.array]: The state vector.
    """
    hamiltonians = self._check_hamiltonians(hamiltonians)
    expectations = []
    state_vector = self.run(circuit, quantum_state)
    for hamiltonian in hamiltonians:
        ham_circuit_list = hamiltonian.construct_hamilton_circuit(circuit.width())
        coefficients = hamiltonian.coefficients
        grad_vector = self._gate_calculator.get_empty_state_vector(circuit.width())
        for coeff, ham_circuit in zip(coefficients, ham_circuit_list):
            grad_vec = self.run(ham_circuit, state_vector)
            grad_vector += coeff * grad_vec
        expectation = (
            (state_vector.conj() @ grad_vector).real
            if self.device == "CPU"
            else (state_vector.conj() @ grad_vector).real.get()
        )
        expectations.append(expectation)

    return np.array(expectations)

get_measured_prob

get_measured_prob(index: int, all_measured: bool = False)

Return the probability of measured qubit with given index to be 1

Parameters:

  • index (int) –

    The given qubit index

  • all_measured (bool, default: False ) –

    Calculate measured probability with all state vector, only using with Multi-Node Simulation.

Source code in QuICT/simulation/state_vector/statevector_simulator.py
def get_measured_prob(self, index: int, all_measured: bool = False):
    """ Return the probability of measured qubit with given index to be 1

    Args:
        index (int): The given qubit index
        all_measured (bool): Calculate measured probability with all state vector,
            only using with Multi-Node Simulation.
    """
    from QuICT.ops.gate_kernel.gpu import measured_prob_calculate

    return measured_prob_calculate(
        index,
        self._vector,
        self._qubits,
        all_measured=all_measured,
        sync=self._gate_calculator._sync
    )

initial_circuit

initial_circuit(circuit: Circuit)

Initial the qubits, quantum gates and state vector by given quantum circuit.

Source code in QuICT/simulation/state_vector/statevector_simulator.py
def initial_circuit(self, circuit: Circuit):
    """ Initial the qubits, quantum gates and state vector by given quantum circuit. """
    self._origin_circuit = circuit
    self._circuit = circuit if self._quantum_machine is None else self._quantum_machine.transpile(circuit)
    self._qubits = int(circuit.width()) if isinstance(circuit, Circuit) else max(circuit.qubits) + 1
    self._used_qubits = circuit._gates.qubits
    if self._hidden_empty_qubits and self._qubits != len(self._used_qubits):
        self._qubits = len(circuit._gates.qubits)
        if isinstance(circuit, Circuit):
            circuit = circuit.to_compositegate() & list(range(self._qubits))
        else:
            circuit = circuit.copy() & list(range(self._qubits))

    if not self._ignore_last_measure:
        self._pipeline, self._measured_q_order = circuit.gates, None
    else:
        self._pipeline, self._measured_q_order = circuit.gates_without_last_measure()

    self._gate_calculator.gate_matrix_combined(self._circuit)

initial_state_vector

initial_state_vector(all_zeros: bool = False)

Initial qubits' vector states.

Source code in QuICT/simulation/state_vector/statevector_simulator.py
def initial_state_vector(self, all_zeros: bool = False):
    """ Initial qubits' vector states. """
    if not all_zeros:
        self._vector = self._gate_calculator.get_allzero_state_vector(self._qubits)
    else:
        self._vector = self._gate_calculator.get_empty_state_vector(self._qubits)

run

run(circuit: Circuit, quantum_state: ndarray = None, quantum_machine_model: Union[NoiseModel, VirtualQuantumMachine] = None, use_previous: bool = False) -> np.ndarray

start simulator with given circuit

Parameters:

  • circuit (Circuit) –

    The quantum circuits.

  • quantum_state (ndarray, default: None ) –

    The initial quantum state vector.

  • quantum_machine_model (Union[NoiseModel, VirtualQuantumMachine], default: None ) –

    The model of quantum machine

  • use_previous (bool, default: False ) –

    Using the previous state vector. Defaults to False.

Returns:

  • ndarray

    Union[cp.array, np.array]: The state vector.

Source code in QuICT/simulation/state_vector/statevector_simulator.py
def run(
    self,
    circuit: Circuit,
    quantum_state: np.ndarray = None,
    quantum_machine_model: Union[NoiseModel, VirtualQuantumMachine] = None,
    use_previous: bool = False
) -> np.ndarray:
    """ start simulator with given circuit

    Args:
        circuit (Circuit): The quantum circuits.
        quantum_state (ndarray): The initial quantum state vector.
        quantum_machine_model (Union[NoiseModel, VirtualQuantumMachine]): The model of quantum machine
        use_previous (bool, optional): Using the previous state vector. Defaults to False.

    Returns:
        Union[cp.array, np.array]: The state vector.
    """
    # Deal with the Physical Machine Model
    self._quantum_machine = None
    if quantum_machine_model is not None:
        noise_model = quantum_machine_model if isinstance(quantum_machine_model, NoiseModel) else \
            NoiseModel(quantum_machine_info=quantum_machine_model)
        if not noise_model.is_ideal_model():
            self._quantum_machine = noise_model

    # Initial Quantum Circuit and State Vector
    self.initial_circuit(circuit)
    self._original_state_vector = None
    if quantum_state is not None:
        self._vector = self._gate_calculator.normalized_state_vector(quantum_state.copy(), self._qubits)
        if self._quantum_machine is not None:
            self._original_state_vector = quantum_state.copy()
    elif not use_previous:
        self.initial_state_vector()

    # Apply gates one by one
    self._run()
    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/state_vector/statevector_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._circuit is not None), \
        SampleBeforeRunError("StateVectorSimulation sample without run any circuit.")
    target_qubits = self._regularized_target_qubits(target_qubits)
    if self._quantum_machine is not None:
        state_dict, sample_result = self._sample_with_noise(shots, target_qubits, extra_output, seed)
    else:
        state_dict = defaultdict(int)
        sample_result = self._gate_calculator.sample_for_statevector_cdf(
            shots, self._qubits, 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