def _define(self): definition = [] qr = QuantumRegister(self.num_qubits) oracle_qr = [qr[i] for i in self.oracle_qubits] # Prepare the auxiliary qubit into the Hadamard minus state. definition.append((HGate(), [qr[-1]], [])) definition.append((ZGate(), [qr[-1]], [])) # Add the boolean oracle whose behavior is # determined by the auxiliary qubit. definition.append((BooleanOracleGate(self.classical_boolean_oracle), oracle_qr + [qr[-1]], [])) # Add the inverse of the quantum algorithm. definition.append((self.quantum_algorithm.inverse(), qr[:-1], [])) # Add the 'inversion around the mean' operator as a # special boolean oracle that behaves as a phase oracle # because of how was set the auxiliary qubit. definition.append( (BooleanOracleGate([1] + [0] * (2**(self.num_qubits - 1) - 1)), qr[:], [])) # Add the quantum algorithm. definition.append((self.quantum_algorithm, qr[:-1], [])) # Revert the auxiliary qubit to zero. definition.append((ZGate(), [qr[-1]], [])) definition.append((HGate(), [qr[-1]], [])) self.definition = definition
def build_correction(self): # Build Correction Circuit circ = QuantumCircuit(self.code, self.syndrm) circ.append(XGate().control(4, ctrl_state='0010'), [self.syndrm[i] for i in range(4)] + [self.code[0]]) circ.append(YGate().control(4, ctrl_state='1110'), [self.syndrm[i] for i in range(4)] + [self.code[0]]) circ.append(ZGate().control(4, ctrl_state='1100'), [self.syndrm[i] for i in range(4)] + [self.code[0]]) circ.append(XGate().control(4, ctrl_state='0101'), [self.syndrm[i] for i in range(4)] + [self.code[1]]) circ.append(YGate().control(4, ctrl_state='1101'), [self.syndrm[i] for i in range(4)] + [self.code[1]]) circ.append(ZGate().control(4, ctrl_state='1000'), [self.syndrm[i] for i in range(4)] + [self.code[1]]) circ.append(XGate().control(4, ctrl_state='1010'), [self.syndrm[i] for i in range(4)] + [self.code[2]]) circ.append(YGate().control(4, ctrl_state='1011'), [self.syndrm[i] for i in range(4)] + [self.code[2]]) circ.append(ZGate().control(4, ctrl_state='0001'), [self.syndrm[i] for i in range(4)] + [self.code[2]]) circ.append(XGate().control(4, ctrl_state='0100'), [self.syndrm[i] for i in range(4)] + [self.code[3]]) circ.append(YGate().control(4, ctrl_state='0111'), [self.syndrm[i] for i in range(4)] + [self.code[3]]) circ.append(ZGate().control(4, ctrl_state='0011'), [self.syndrm[i] for i in range(4)] + [self.code[3]]) circ.append(XGate().control(4, ctrl_state='1001'), [self.syndrm[i] for i in range(4)] + [self.code[4]]) circ.append(YGate().control(4, ctrl_state='1111'), [self.syndrm[i] for i in range(4)] + [self.code[4]]) circ.append(ZGate().control(4, ctrl_state='0110'), [self.syndrm[i] for i in range(4)] + [self.code[4]]) return circ
def to_instruction(self): """Convert to Pauli circuit instruction.""" from math import pi pauli, phase = self._to_label(self.z, self.x, self._phase[0], full_group=False, return_phase=True) if len(pauli) == 1: gate = { "I": IGate(), "X": XGate(), "Y": YGate(), "Z": ZGate() }[pauli] else: gate = PauliGate(pauli) if not phase: return gate # Add global phase circuit = QuantumCircuit(self.num_qubits, name=str(self)) circuit.global_phase = -phase * pi / 2 circuit.append(gate, range(self.num_qubits)) return circuit.to_instruction()
def setUp(self): super().setUp() self.ops = { 'X': XGate(), 'Y': YGate(), 'Z': ZGate(), 'H': HGate(), 'S': SGate() }
def from_label(cls, label): """Return a tensor product of single-qubit operators. Args: label (string): single-qubit operator string. Returns: Operator: The N-qubit operator. Raises: QiskitError: if the label contains invalid characters, or the length of the label is larger than an explicitly specified num_qubits. Additional Information: The labels correspond to the single-qubit matrices: 'I': [[1, 0], [0, 1]] 'X': [[0, 1], [1, 0]] 'Y': [[0, -1j], [1j, 0]] 'Z': [[1, 0], [0, -1]] 'H': [[1, 1], [1, -1]] / sqrt(2) 'S': [[1, 0], [0 , 1j]] 'T': [[1, 0], [0, (1+1j) / sqrt(2)]] '0': [[1, 0], [0, 0]] '1': [[0, 0], [0, 1]] '+': [[0.5, 0.5], [0.5 , 0.5]] '-': [[0.5, -0.5], [-0.5 , 0.5]] 'r': [[0.5, -0.5j], [0.5j , 0.5]] 'l': [[0.5, 0.5j], [-0.5j , 0.5]] """ # Check label is valid label_mats = { 'I': IGate().to_matrix(), 'X': XGate().to_matrix(), 'Y': YGate().to_matrix(), 'Z': ZGate().to_matrix(), 'H': HGate().to_matrix(), 'S': SGate().to_matrix(), 'T': TGate().to_matrix(), '0': np.array([[1, 0], [0, 0]], dtype=complex), '1': np.array([[0, 0], [0, 1]], dtype=complex), '+': np.array([[0.5, 0.5], [0.5, 0.5]], dtype=complex), '-': np.array([[0.5, -0.5], [-0.5, 0.5]], dtype=complex), 'r': np.array([[0.5, -0.5j], [0.5j, 0.5]], dtype=complex), 'l': np.array([[0.5, 0.5j], [-0.5j, 0.5]], dtype=complex), } if re.match(r'^[IXYZHST01rl\-+]+$', label) is None: raise QiskitError('Label contains invalid characters.') # Initialize an identity matrix and apply each gate num_qubits = len(label) op = Operator(np.eye(2 ** num_qubits, dtype=complex)) for qubit, char in enumerate(reversed(label)): if char != 'I': op = op.compose(label_mats[char], qargs=[qubit]) return op
def from_label(label): """Return a tensor product of single-qubit Clifford gates. Args: label (string): single-qubit operator string. Returns: Clifford: The N-qubit Clifford operator. Raises: QiskitError: if the label contains invalid characters. Additional Information: The labels correspond to the single-qubit Cliffords are * - Label - Stabilizer - Destabilizer * - ``"I"`` - +Z - +X * - ``"X"`` - -Z - +X * - ``"Y"`` - -Z - -X * - ``"Z"`` - +Z - -X * - ``"H"`` - +X - +Z * - ``"S"`` - +Z - +Y """ # Check label is valid label_gates = { 'I': IGate(), 'X': XGate(), 'Y': YGate(), 'Z': ZGate(), 'H': HGate(), 'S': SGate() } if re.match(r'^[IXYZHS\-+]+$', label) is None: raise QiskitError('Label contains invalid characters.') # Initialize an identity matrix and apply each gate num_qubits = len(label) op = Clifford(np.eye(2 * num_qubits, dtype=np.bool)) for qubit, char in enumerate(reversed(label)): _append_circuit(op, label_gates[char], qargs=[qubit]) return op
def to_instruction(self): """Convert to Pauli circuit instruction.""" from qiskit.circuit import QuantumCircuit, QuantumRegister from qiskit.circuit.library.standard_gates import IGate, XGate, YGate, ZGate gates = {'I': IGate(), 'X': XGate(), 'Y': YGate(), 'Z': ZGate()} label = self.to_label() num_qubits = self.num_qubits qreg = QuantumRegister(num_qubits) circuit = QuantumCircuit(qreg, name='Pauli:{}'.format(label)) for i, pauli in enumerate(reversed(label)): circuit.append(gates[pauli], [qreg[i]]) return circuit.to_instruction()
def test_pauli_error_1q_gate_from_string(self): """Test single-qubit pauli error as gate qobj from string label""" paulis = ['I', 'X', 'Y', 'Z'] probs = [0.4, 0.3, 0.2, 0.1] actual = pauli_error(zip(paulis, probs)) expected = QuantumError([(IGate(), 0.4), (XGate(), 0.3), (YGate(), 0.2), (ZGate(), 0.1)]) for i in range(actual.size): circ, prob = actual.error_term(i) expected_circ, expected_prob = expected.error_term(i) self.assertEqual(circ, expected_circ, msg=f"Incorrect {i}-th circuit") self.assertAlmostEqual(prob, expected_prob, msg=f"Incorrect {i}-th probability")
def test_depolarizing_error_1q_gate(self): """Test 1-qubit depolarizing error as gate qobj""" p_depol = 0.3 actual = depolarizing_error(p_depol, 1) expected = QuantumError([ (IGate(), 1 - p_depol*3/4), (XGate(), p_depol/4), (YGate(), p_depol/4), (ZGate(), p_depol/4) ]) for i in range(actual.size): circ, prob = actual.error_term(i) expected_circ, expected_prob = expected.error_term(i) self.assertEqual(circ, expected_circ, msg=f"Incorrect {i}-th circuit") self.assertAlmostEqual(prob, expected_prob, msg=f"Incorrect {i}-th probability")
def test_thermal_relaxation_error_gate(self): """Test qobj instructions return for t2 < t1""" t1, t2, time, p1 = (2, 1, 1, 0.3) actual = thermal_relaxation_error(t1, t2, time, p1) p_z = 0.5 * np.exp(-1 / t1) * (1 - np.exp(-(1 / t2 - 1 / t1) * time)) p_reset0 = (1 - p1) * (1 - np.exp(-1 / t1)) p_reset1 = p1 * (1 - np.exp(-1 / t1)) expected = QuantumError([ (IGate(), 1 - p_z - p_reset0 - p_reset1), (ZGate(), p_z), (Reset(), p_reset0), ([(Reset(), [0]), (XGate(), [0])], p_reset1), ]) for i in range(actual.size): circ, prob = actual.error_term(i) expected_circ, expected_prob = expected.error_term(i) self.assertEqual(circ, expected_circ, msg=f"Incorrect {i}-th circuit") self.assertAlmostEqual(prob, expected_prob, msg=f"Incorrect {i}-th probability")
def oraculo_trivial(n, k): qc = qiskit.QuantumCircuit(n) list_qu = list(range(n)) bin_k = ('{0:0' + str(n) + 'b}').format(k) print(bin_k) bin_k = bin_k[::-1] for qu in range(n): qc.h(qu) qc.append(ZGate("zgate").control(num_ctrl_qubits=n - 1), list_qu) for i in range(n): if bin_k[i] == '0': qc.x(i) backend = qiskit.Aer.get_backend('statevector_simulator') job = qiskit.execute(qc, backend) result = job.result() print('Estado gerado pelo circuito: ', result.get_statevector()) print(qc.draw()) return qc
The ``string`` supports only 1- or 2-qubit errors and its possible values are ``'pauli'``, ``'reset'``, ``'clifford'``. The ``'clifford'`` does not support 2-qubit errors. """ def approximate(noise): return approximate_quantum_error(noise, operator_string=operator_string, operator_dict=operator_dict, operator_list=operator_list) return transform_noise_model(model, approximate) # pauli operators _PAULIS_Q0 = [[(IGate(), [0])], [(XGate(), [0])], [(YGate(), [0])], [(ZGate(), [0])]] _PAULIS_Q1 = [[(IGate(), [1])], [(XGate(), [1])], [(YGate(), [1])], [(ZGate(), [1])]] _PAULIS_Q0Q1 = [op_q0 + op_q1 for op_q0 in _PAULIS_Q0 for op_q1 in _PAULIS_Q1] # reset operators _RESET_Q0_TO_0 = [(Reset(), [0])] _RESET_Q0_TO_1 = [(Reset(), [0]), (XGate(), [0])] _RESET_Q0 = [[(IGate(), [0])], _RESET_Q0_TO_0, _RESET_Q0_TO_1] _RESET_Q1_TO_0 = [(Reset(), [1])] _RESET_Q1_TO_1 = [(Reset(), [1]), (XGate(), [1])] _RESET_Q1 = [[(IGate(), [1])], _RESET_Q1_TO_0, _RESET_Q1_TO_1] _RESET_Q0Q1 = [op_q0 + op_q1 for op_q0 in _RESET_Q0 for op_q1 in _RESET_Q1] # preset operator table _PRESET_OPERATOR_TABLE = { "pauli": { 1: _PAULIS_Q0[1:],
def _gate_gradient_dict( gate: Gate) -> List[Tuple[List[complex], List[Instruction]]]: r"""Given a parameterized gate U(theta) with derivative dU(theta)/dtheta = sum_ia_iU(theta)V_i. This function returns a:=[a_0, ...] and V=[V_0, ...] Suppose U takes multiple parameters, i.e., U(theta^0, ... theta^k). The returned coefficients and gates are ordered accordingly. Only parameterized Qiskit gates are supported. Args: gate: The gate for which the derivative is being computed. Returns: The coefficients and the gates used for the metric computation for each parameter of the respective gates. [([a^0], [V^0]) ..., ([a^k], [V^k])] Raises: AquaError: If the input gate is controlled by another state but '|1>^{\otimes k}' TypeError: If the input gate is not a supported parametrized gate. """ # pylint: disable=too-many-return-statements if isinstance(gate, PhaseGate): # theta return [([0.5j, -0.5j], [IGate(), CZGate()])] if isinstance(gate, UGate): # theta, lambda, phi return [([-0.5j], [CZGate()]), ([-0.5j], [CZGate()]), ([-0.5j], [CZGate()])] if isinstance(gate, RXGate): # theta return [([-0.5j], [CXGate()])] if isinstance(gate, RYGate): # theta return [([-0.5j], [CYGate()])] if isinstance(gate, RZGate): # theta return [([-0.5j], [CZGate()])] if isinstance(gate, RXXGate): # theta cxx_circ = QuantumCircuit(3) cxx_circ.cx(0, 1) cxx_circ.cx(0, 2) cxx = cxx_circ.to_instruction() return [([-0.5j], [cxx])] if isinstance(gate, RYYGate): # theta cyy_circ = QuantumCircuit(3) cyy_circ.cy(0, 1) cyy_circ.cy(0, 2) cyy = cyy_circ.to_instruction() return [([-0.5j], [cyy])] if isinstance(gate, RZZGate): # theta czz_circ = QuantumCircuit(3) czz_circ.cz(0, 1) czz_circ.cz(0, 2) czz = czz_circ.to_instruction() return [([-0.5j], [czz])] if isinstance(gate, RZXGate): # theta czx_circ = QuantumCircuit(3) czx_circ.cx(0, 2) czx_circ.cz(0, 1) czx = czx_circ.to_instruction() return [([-0.5j], [czx])] if isinstance(gate, ControlledGate): # TODO support arbitrary control states if gate.ctrl_state != 2**gate.num_ctrl_qubits - 1: raise AquaError( 'Function only support controlled gates with control state `1` on all control ' 'qubits.') base_coeffs_gates = LinComb._gate_gradient_dict(gate.base_gate) coeffs_gates = [] # The projectors needed for the gradient of a controlled gate are integrated by a sum # of gates. # The following line generates the decomposition gates. proj_gates_controlled = [[ (-1)**p.count(ZGate()), p ] for p in product([IGate(), ZGate()], repeat=gate.num_ctrl_qubits) ] for base_coeffs, base_gates in base_coeffs_gates: # loop over parameters coeffs = [] gates = [] for phase, proj_gates in proj_gates_controlled: coeffs.extend([ phase * c / (2**gate.num_ctrl_qubits) for c in base_coeffs ]) for base_gate in base_gates: controlled_circ = QuantumCircuit(gate.num_ctrl_qubits + gate.num_qubits) for i, proj_gate in enumerate(proj_gates): if isinstance(proj_gate, ZGate): controlled_circ.cz(0, i + 1) if not isinstance(base_gate, IGate): controlled_circ.append(base_gate, [ 0, range(gate.num_ctrl_qubits + 1, gate.num_ctrl_qubits + gate.num_qubits) ]) gates.append(controlled_circ.to_instruction()) c_g = (coeffs, gates) coeffs_gates.append(c_g) return coeffs_gates raise TypeError('Unrecognized parametrized gate, {}'.format(gate))
def thermal_relaxation_error(t1, t2, time, excited_state_population=0): r""" Return a single-qubit thermal relaxation quantum error channel. Args: t1 (double): the :math:`T_1` relaxation time constant. t2 (double): the :math:`T_2` relaxation time constant. time (double): the gate time for relaxation error. excited_state_population (double): the population of :math:`|1\rangle` state at equilibrium (default: 0). Returns: QuantumError: a quantum error object for a noise model. Raises: NoiseError: If noise parameters are invalid. Additional information: * For parameters to be valid :math:`T_1` and :math:`T_2` must satisfy :math:`T_2 \le 2 T_1`. * If :math:`T_2 \le T_1` the error can be expressed as a mixed reset and unitary error channel. * If :math:`T_1 < T_2 \le 2 T_1` the error must be expressed as a general non-unitary Kraus error channel. """ if excited_state_population < 0: raise NoiseError("Invalid excited state population " "({} < 0).".format(excited_state_population)) if excited_state_population > 1: raise NoiseError("Invalid excited state population " "({} > 1).".format(excited_state_population)) if time < 0: raise NoiseError("Invalid gate_time ({} < 0)".format(time)) if t1 <= 0: raise NoiseError("Invalid T_1 relaxation time parameter: T_1 <= 0.") if t2 <= 0: raise NoiseError("Invalid T_2 relaxation time parameter: T_2 <= 0.") if t2 - 2 * t1 > 0: raise NoiseError( "Invalid T_2 relaxation time parameter: T_2 greater than 2 * T_1.") # T1 relaxation rate if t1 == np.inf: rate1 = 0 p_reset = 0 else: rate1 = 1 / t1 p_reset = 1 - np.exp(-time * rate1) # T2 dephasing rate if t2 == np.inf: rate2 = 0 exp_t2 = 1 else: rate2 = 1 / t2 exp_t2 = np.exp(-time * rate2) # Qubit state equilibrium probabilities p0 = 1 - excited_state_population p1 = excited_state_population if t2 > t1: # If T_2 > T_1 we must express this as a Kraus channel # We start with the Choi-matrix representation: chan = Choi( np.array([[1 - p1 * p_reset, 0, 0, exp_t2], [0, p1 * p_reset, 0, 0], [0, 0, p0 * p_reset, 0], [exp_t2, 0, 0, 1 - p0 * p_reset]])) return QuantumError(Kraus(chan)) else: # If T_2 < T_1 we can express this channel as a probabilistic # mixture of reset operations and unitary errors: circuits = [[(IGate(), [0])], [(ZGate(), [0])], [(Reset(), [0])], [(Reset(), [0]), (XGate(), [0])]] # Probability p_reset0 = p_reset * p0 p_reset1 = p_reset * p1 p_z = (1 - p_reset) * (1 - np.exp(-time * (rate2 - rate1))) / 2 p_identity = 1 - p_z - p_reset0 - p_reset1 probabilities = [p_identity, p_z, p_reset0, p_reset1] return QuantumError(zip(circuits, probabilities))
def _gradient_states( self, state_op: StateFn, meas_op: Optional[OperatorBase] = None, target_params: Optional[Union[ParameterExpression, ParameterVector, List[ParameterExpression]]] = None ) -> ListOp: """Generate the gradient states. Args: state_op: The operator representing the quantum state for which we compute the gradient. meas_op: The operator representing the observable for which we compute the gradient. target_params: The parameters we are taking the gradient wrt: ω Returns: ListOp of StateFns as quantum circuits which are the states w.r.t. which we compute the gradient. If a parameter appears multiple times, one circuit is created per parameterized gates to compute the product rule. Raises: AquaError: If one of the circuits could not be constructed. TypeError: If the operators is of unsupported type. """ state_qc = deepcopy(state_op.primitive) # Define the working qubit to realize the linear combination of unitaries qr_work = QuantumRegister(1, 'work_qubit_lin_comb_grad') work_q = qr_work[0] if not isinstance(target_params, (list, np.ndarray)): target_params = [target_params] if len(target_params) > 1: states = None additional_qubits: Tuple[List[Qubit], List[Qubit]] = ([work_q], []) for param in target_params: if param not in state_qc._parameter_table.get_keys(): op = ~Zero @ One else: param_gates = state_qc._parameter_table[param] for m, param_occurence in enumerate(param_gates): coeffs, gates = self._gate_gradient_dict( param_occurence[0])[param_occurence[1]] # construct the states for k, gate_to_insert in enumerate(gates): grad_state = QuantumCircuit(*state_qc.qregs, qr_work) grad_state.compose(state_qc, inplace=True) # apply Hadamard on work_q self.insert_gate(grad_state, param_occurence[0], HGate(), qubits=[work_q]) # Fix work_q phase coeff_i = coeffs[k] sign = np.sign(coeff_i) is_complex = np.iscomplex(coeff_i) if sign == -1: if is_complex: self.insert_gate(grad_state, param_occurence[0], SdgGate(), qubits=[work_q]) else: self.insert_gate(grad_state, param_occurence[0], ZGate(), qubits=[work_q]) else: if is_complex: self.insert_gate(grad_state, param_occurence[0], SGate(), qubits=[work_q]) # Insert controlled, intercepting gate - controlled by |0> if isinstance(param_occurence[0], UGate): if param_occurence[1] == 0: self.insert_gate( grad_state, param_occurence[0], RZGate(param_occurence[0].params[2])) self.insert_gate(grad_state, param_occurence[0], RXGate(np.pi / 2)) self.insert_gate( grad_state, param_occurence[0], gate_to_insert, additional_qubits=additional_qubits) self.insert_gate(grad_state, param_occurence[0], RXGate(-np.pi / 2)) self.insert_gate( grad_state, param_occurence[0], RZGate(-param_occurence[0].params[2])) elif param_occurence[1] == 1: self.insert_gate( grad_state, param_occurence[0], gate_to_insert, after=True, additional_qubits=additional_qubits) else: self.insert_gate( grad_state, param_occurence[0], gate_to_insert, additional_qubits=additional_qubits) else: self.insert_gate( grad_state, param_occurence[0], gate_to_insert, additional_qubits=additional_qubits) grad_state.h(work_q) state = np.sqrt( np.abs(coeff_i)) * state_op.coeff * CircuitStateFn( grad_state) # Chain Rule parameter expressions gate_param = param_occurence[0].params[ param_occurence[1]] if meas_op: if gate_param == param: state = meas_op @ state else: if isinstance(gate_param, ParameterExpression): expr_grad = DerivativeBase.parameter_expression_grad( gate_param, param) state = (expr_grad * meas_op) @ state else: state = ~Zero @ One else: if gate_param == param: state = ListOp([state], combo_fn=partial( self._grad_combo_fn, state_op=state_op)) else: if isinstance(gate_param, ParameterExpression): expr_grad = DerivativeBase.parameter_expression_grad( gate_param, param) state = expr_grad * ListOp( [state], combo_fn=partial(self._grad_combo_fn, state_op=state_op)) else: state = ~Zero @ One if m == 0 and k == 0: op = state else: # Product Rule op += state if len(target_params) > 1: if not states: states = [op] else: states += [op] else: return op if len(target_params) > 1: return ListOp(states) else: return op
def _hessian_states( self, state_op: StateFn, meas_op: Optional[OperatorBase] = None, target_params: Optional[Union[Tuple[ParameterExpression, ParameterExpression], List[Tuple[ParameterExpression, ParameterExpression]]]] = None ) -> OperatorBase: """Generate the operator states whose evaluation returns the Hessian (items). Args: state_op: The operator representing the quantum state for which we compute the Hessian. meas_op: The operator representing the observable for which we compute the gradient. target_params: The parameters we are computing the Hessian wrt: ω Returns: Operators which give the Hessian. If a parameter appears multiple times, one circuit is created per parameterized gates to compute the product rule. Raises: AquaError: If one of the circuits could not be constructed. TypeError: If ``operator`` is of unsupported type. """ state_qc = deepcopy(state_op.primitive) if isinstance(target_params, list) and isinstance( target_params[0], tuple): tuples_list = deepcopy(target_params) target_params = [] for tuples in tuples_list: if all([ param in state_qc._parameter_table.get_keys() for param in tuples ]): for param in tuples: if param not in target_params: target_params.append(param) elif isinstance(target_params, tuple): tuples_list = deepcopy([target_params]) target_params = [] for tuples in tuples_list: if all([ param in state_qc._parameter_table.get_keys() for param in tuples ]): for param in tuples: if param not in target_params: target_params.append(param) else: raise TypeError( 'Please define in the parameters for which the Hessian is evaluated either ' 'as parameter tuple or a list of parameter tuples') qr_add0 = QuantumRegister(1, 'work_qubit0') work_q0 = qr_add0[0] qr_add1 = QuantumRegister(1, 'work_qubit1') work_q1 = qr_add1[0] # create a copy of the original circuit with an additional working qubit register circuit = state_qc.copy() circuit.add_register(qr_add0, qr_add1) # Get the circuits needed to compute the Hessian hessian_ops = None for param_a, param_b in tuples_list: if param_a not in state_qc._parameter_table.get_keys() or param_b \ not in state_qc._parameter_table.get_keys(): hessian_op = ~Zero @ One else: param_gates_a = state_qc._parameter_table[param_a] param_gates_b = state_qc._parameter_table[param_b] for i, param_occurence_a in enumerate(param_gates_a): coeffs_a, gates_a = self._gate_gradient_dict( param_occurence_a[0])[param_occurence_a[1]] # apply Hadamard on working qubit self.insert_gate(circuit, param_occurence_a[0], HGate(), qubits=[work_q0]) self.insert_gate(circuit, param_occurence_a[0], HGate(), qubits=[work_q1]) for j, gate_to_insert_a in enumerate(gates_a): coeff_a = coeffs_a[j] hessian_circuit_temp = QuantumCircuit(*circuit.qregs) hessian_circuit_temp.data = circuit.data # Fix working qubit 0 phase sign = np.sign(coeff_a) is_complex = np.iscomplex(coeff_a) if sign == -1: if is_complex: self.insert_gate(hessian_circuit_temp, param_occurence_a[0], SdgGate(), qubits=[work_q0]) else: self.insert_gate(hessian_circuit_temp, param_occurence_a[0], ZGate(), qubits=[work_q0]) else: if is_complex: self.insert_gate(hessian_circuit_temp, param_occurence_a[0], SGate(), qubits=[work_q0]) # Insert controlled, intercepting gate - controlled by |1> if isinstance(param_occurence_a[0], UGate): if param_occurence_a[1] == 0: self.insert_gate( hessian_circuit_temp, param_occurence_a[0], RZGate(param_occurence_a[0].params[2])) self.insert_gate(hessian_circuit_temp, param_occurence_a[0], RXGate(np.pi / 2)) self.insert_gate(hessian_circuit_temp, param_occurence_a[0], gate_to_insert_a, additional_qubits=([work_q0], [])) self.insert_gate(hessian_circuit_temp, param_occurence_a[0], RXGate(-np.pi / 2)) self.insert_gate( hessian_circuit_temp, param_occurence_a[0], RZGate(-param_occurence_a[0].params[2])) elif param_occurence_a[1] == 1: self.insert_gate(hessian_circuit_temp, param_occurence_a[0], gate_to_insert_a, after=True, additional_qubits=([work_q0], [])) else: self.insert_gate(hessian_circuit_temp, param_occurence_a[0], gate_to_insert_a, additional_qubits=([work_q0], [])) else: self.insert_gate(hessian_circuit_temp, param_occurence_a[0], gate_to_insert_a, additional_qubits=([work_q0], [])) for m, param_occurence_b in enumerate(param_gates_b): coeffs_b, gates_b = self._gate_gradient_dict( param_occurence_b[0])[param_occurence_b[1]] for n, gate_to_insert_b in enumerate(gates_b): coeff_b = coeffs_b[n] # create a copy of the original circuit with the same registers hessian_circuit = QuantumCircuit( *hessian_circuit_temp.qregs) hessian_circuit.data = hessian_circuit_temp.data # Fix working qubit 1 phase sign = np.sign(coeff_b) is_complex = np.iscomplex(coeff_b) if sign == -1: if is_complex: self.insert_gate(hessian_circuit, param_occurence_b[0], SdgGate(), qubits=[work_q1]) else: self.insert_gate(hessian_circuit, param_occurence_b[0], ZGate(), qubits=[work_q1]) else: if is_complex: self.insert_gate(hessian_circuit, param_occurence_b[0], SGate(), qubits=[work_q1]) # Insert controlled, intercepting gate - controlled by |1> if isinstance(param_occurence_b[0], UGate): if param_occurence_b[1] == 0: self.insert_gate( hessian_circuit, param_occurence_b[0], RZGate(param_occurence_b[0]. params[2])) self.insert_gate( hessian_circuit, param_occurence_b[0], RXGate(np.pi / 2)) self.insert_gate( hessian_circuit, param_occurence_b[0], gate_to_insert_b, additional_qubits=([work_q1], [])) self.insert_gate( hessian_circuit, param_occurence_b[0], RXGate(-np.pi / 2)) self.insert_gate( hessian_circuit, param_occurence_b[0], RZGate(-param_occurence_b[0]. params[2])) elif param_occurence_b[1] == 1: self.insert_gate( hessian_circuit, param_occurence_b[0], gate_to_insert_b, after=True, additional_qubits=([work_q1], [])) else: self.insert_gate( hessian_circuit, param_occurence_b[0], gate_to_insert_b, additional_qubits=([work_q1], [])) else: self.insert_gate( hessian_circuit, param_occurence_b[0], gate_to_insert_b, additional_qubits=([work_q1], [])) hessian_circuit.h(work_q0) hessian_circuit.cz(work_q1, work_q0) hessian_circuit.h(work_q1) term = state_op.coeff * np.sqrt(np.abs(coeff_a) * np.abs(coeff_b)) \ * CircuitStateFn(hessian_circuit) # Chain Rule Parameter Expression gate_param_a = param_occurence_a[0].params[ param_occurence_a[1]] gate_param_b = param_occurence_b[0].params[ param_occurence_b[1]] if meas_op: meas = deepcopy(meas_op) if isinstance(gate_param_a, ParameterExpression): expr_grad = DerivativeBase.parameter_expression_grad( gate_param_a, param_a) meas *= expr_grad if isinstance(gate_param_b, ParameterExpression): expr_grad = DerivativeBase.parameter_expression_grad( gate_param_a, param_a) meas *= expr_grad term = meas @ term else: term = ListOp([term], combo_fn=partial( self._hess_combo_fn, state_op=state_op)) if isinstance(gate_param_a, ParameterExpression): expr_grad = DerivativeBase.parameter_expression_grad( gate_param_a, param_a) term *= expr_grad if isinstance(gate_param_b, ParameterExpression): expr_grad = DerivativeBase.parameter_expression_grad( gate_param_a, param_a) term *= expr_grad if i == 0 and j == 0 and m == 0 and n == 0: hessian_op = term else: # Product Rule hessian_op += term # Create a list of Hessian elements w.r.t. the given parameter tuples if len(tuples_list) == 1: return hessian_op else: if not hessian_ops: hessian_ops = [hessian_op] else: hessian_ops += [hessian_op] return ListOp(hessian_ops)
('z', 'h', 'z'), # u3 gates ( 'x', ), ('y', ), ('s', 'x'), ('sdg', 'x') ] return labels[j] _CLIFFORD_GATES = [ (IGate(), ), (SGate(), ), (SdgGate(), ), (ZGate(), ), # u2 gates (HGate(), ), (HGate(), ZGate()), (ZGate(), HGate()), (HGate(), SGate()), (SGate(), HGate()), (HGate(), SdgGate()), (SdgGate(), HGate()), (SGate(), HGate(), SGate()), (SdgGate(), HGate(), SGate()), (ZGate(), HGate(), SGate()), (SGate(), HGate(), SdgGate()), (SdgGate(), HGate(), SdgGate()), (ZGate(), HGate(), SdgGate()), (SGate(), HGate(), ZGate()),
#b = QuantumRegister(2) #cq = QuantumRegister(4) #anc = QuantumRegister(1) c = ClassicalRegister(4) qc = QuantumCircuit(a, c) qc.h(a) # qc.append(mult(2, 2), a[:] + b[:] + cq[:] + [anc]) # Oracle oq = QuantumRegister(4) O = QuantumCircuit(oq, name="Oracle") O.x(oq[0]) O.x(oq[3]) O.append(ZGate().control(3), oq[:]) O.x(oq[0]) O.x(oq[3]) # Diffusor d = QuantumRegister(4) Dif = QuantumCircuit(d, name="Diffusor") Dif.x(d) Dif.h(d) Dif.append(ZGate().control(3), d[:]) Dif.x(d) Dif.h(d) #oracle = CustomCircuitOracle(variable_register=oq, output_register=ancq, circuit=O) g = Grover(4, O)
def _standard_gate_instruction(instruction, ignore_phase=True): """Temporary function to create Instruction objects from a json string, which is necessary for creating a new QuantumError object from deprecated json-based input. Note that the type of returned object is different from the deprecated standard_gate_instruction. TODO: to be removed after deprecation period. Args: instruction (dict): A qobj instruction. ignore_phase (bool): Ignore global phase on unitary matrix in comparison to canonical unitary. Returns: list: a list of (instructions, qubits) equivalent to in input instruction. """ gate = { "id": IGate(), "x": XGate(), "y": YGate(), "z": ZGate(), "h": HGate(), "s": SGate(), "sdg": SdgGate(), "t": TGate(), "tdg": TdgGate(), "cx": CXGate(), "cz": CZGate(), "swap": SwapGate() } name = instruction.get("name", None) qubits = instruction["qubits"] if name in gate: return [(gate[name], qubits)] if name not in ["mat", "unitary", "kraus"]: return [instruction] params = instruction["params"] with warnings.catch_warnings(): warnings.filterwarnings("ignore", category=DeprecationWarning, module="qiskit.providers.aer.noise.errors.errorutils") # Check for single-qubit reset Kraus if name == "kraus": if len(qubits) == 1: superop = SuperOp(Kraus(params)) # Check if reset to |0> reset0 = reset_superop(1) if superop == reset0: return [(Reset(), [0])] # Check if reset to |1> reset1 = reset0.compose(Operator(standard_gate_unitary('x'))) if superop == reset1: return [(Reset(), [0]), (XGate(), [0])] return [instruction] # Check single qubit gates mat = params[0] if len(qubits) == 1: # Check clifford gates for j in range(24): if matrix_equal( mat, single_qubit_clifford_matrix(j), ignore_phase=ignore_phase): return [(gate, [0]) for gate in _CLIFFORD_GATES[j]] # Check t gates for name in ["t", "tdg"]: if matrix_equal( mat, standard_gate_unitary(name), ignore_phase=ignore_phase): return [(gate[name], qubits)] # TODO: u1,u2,u3 decomposition # Check two qubit gates if len(qubits) == 2: for name in ["cx", "cz", "swap"]: if matrix_equal( mat, standard_gate_unitary(name), ignore_phase=ignore_phase): return [(gate[name], qubits)] # Check reversed CX if matrix_equal( mat, standard_gate_unitary("cx_10"), ignore_phase=ignore_phase): return [(CXGate(), [qubits[1], qubits[0]])] # Check 2-qubit Pauli's paulis = ["id", "x", "y", "z"] for pauli0 in paulis: for pauli1 in paulis: pmat = np.kron( standard_gate_unitary(pauli1), standard_gate_unitary(pauli0)) if matrix_equal(mat, pmat, ignore_phase=ignore_phase): if pauli0 == "id": return [(gate[pauli1], [qubits[1]])] elif pauli1 == "id": return [(gate[pauli0], [qubits[0]])] else: return [(gate[pauli0], [qubits[0]]), (gate[pauli1], [qubits[1]])] # Check three qubit toffoli if len(qubits) == 3: if matrix_equal( mat, standard_gate_unitary("ccx_012"), ignore_phase=ignore_phase): return [(CCXGate(), qubits)] if matrix_equal( mat, standard_gate_unitary("ccx_021"), ignore_phase=ignore_phase): return [(CCXGate(), [qubits[0], qubits[2], qubits[1]])] if matrix_equal( mat, standard_gate_unitary("ccx_120"), ignore_phase=ignore_phase): return [(CCXGate(), [qubits[1], qubits[2], qubits[0]])] # Else return input in return [instruction]
def apply_grad_gate(circuit, gate, param_index, grad_gate, grad_coeff, qr_superpos, open_ctrl=False, trim_after_grad_gate=False): """Util function to apply a gradient gate for the linear combination of unitaries method. Replaces the ``gate`` instance in ``circuit`` with ``grad_gate`` using ``qr_superpos`` as superposition qubit. Also adds the appropriate sign-fix gates on the superposition qubit. Args: circuit (QuantumCircuit): The circuit in which to do the replacements. gate (Gate): The gate instance to replace. param_index (int): The index of the parameter in ``gate``. grad_gate (Gate): A controlled gate encoding the gradient of ``gate``. grad_coeff (float): A coefficient to the gradient component. Might not be one if the gradient contains multiple summed terms. qr_superpos (QuantumRegister): A ``QuantumRegister`` of size 1 contained in ``circuit`` that is used as control for ``grad_gate``. open_ctrl (bool): If True use an open control for ``grad_gate`` instead of closed. trim_after_grad_gate (bool): If True remove all gates after the ``grad_gate``. Can be used to reduce the circuit depth in e.g. computing an overlap of gradients. Returns: QuantumCircuit: A copy of the original circuit with the gradient gate added. Raises: RuntimeError: If ``gate`` is not in ``circuit``. """ # copy the input circuit taking the gates by reference out = QuantumCircuit(*circuit.qregs) out._data = circuit._data.copy() out._parameter_table = ParameterTable({ param: values.copy() for param, values in circuit._parameter_table.items() }) # get the data index and qubits of the target gate TODO use built-in gate_idx, gate_qubits = None, None for i, (op, qarg, _) in enumerate(out._data): if op is gate: gate_idx, gate_qubits = i, qarg break if gate_idx is None: raise RuntimeError('The specified gate could not be found in the circuit data.') # initialize replacement instructions replacement = [] # insert the phase fix before the target gate better documentation sign = np.sign(grad_coeff) is_complex = np.iscomplex(grad_coeff) if sign < 0 and is_complex: replacement.append((SdgGate(), qr_superpos[:], [])) elif sign < 0: replacement.append((ZGate(), qr_superpos[:], [])) elif is_complex: replacement.append((SGate(), qr_superpos[:], [])) # else no additional gate required # open control if specified if open_ctrl: replacement += [(XGate(), qr_superpos[:], [])] # compute the replacement if isinstance(gate, UGate) and param_index == 0: theta = gate.params[2] rz_plus, rz_minus = RZGate(theta), RZGate(-theta) replacement += [(rz_plus, [qubit], []) for qubit in gate_qubits] replacement += [(RXGate(np.pi / 2), [qubit], []) for qubit in gate_qubits] replacement.append((grad_gate, qr_superpos[:] + gate_qubits, [])) replacement += [(RXGate(-np.pi / 2), [qubit], []) for qubit in gate_qubits] replacement += [(rz_minus, [qubit], []) for qubit in gate_qubits] # update parametertable if necessary if isinstance(theta, ParameterExpression): out._update_parameter_table(rz_plus) out._update_parameter_table(rz_minus) if open_ctrl: replacement += [(XGate(), qr_superpos[:], [])] if not trim_after_grad_gate: replacement.append((gate, gate_qubits, [])) elif isinstance(gate, UGate) and param_index == 1: # gradient gate is applied after the original gate in this case replacement.append((gate, gate_qubits, [])) replacement.append((grad_gate, qr_superpos[:] + gate_qubits, [])) if open_ctrl: replacement += [(XGate(), qr_superpos[:], [])] else: replacement.append((grad_gate, qr_superpos[:] + gate_qubits, [])) if open_ctrl: replacement += [(XGate(), qr_superpos[:], [])] if not trim_after_grad_gate: replacement.append((gate, gate_qubits, [])) # replace the parameter we compute the derivative of with the replacement # TODO can this be done more efficiently? if trim_after_grad_gate: # remove everything after the gradient gate out._data[gate_idx:] = replacement # reset parameter table table = ParameterTable() for op, _, _ in out._data: for idx, param_expression in enumerate(op.params): if isinstance(param_expression, ParameterExpression): for param in param_expression.parameters: if param not in table.keys(): table[param] = [(op, idx)] else: table[param].append((op, idx)) out._parameter_table = table else: out._data[gate_idx:gate_idx + 1] = replacement return out
def phase_oracle(list_values: list, circuit_type: str): n = len(list_values[0]) # Number of elements in one string. assert n >= 2, 'Length of input should be greater or equal to 2.' assert len(set(map(len, list_values)) ) == 1, 'The values on your list should have the same length.' if (circuit_type == 'noancilla' or n == 2): q1 = QuantumRegister(n, "q") a1 = QuantumCircuit(q1) #a1.barrier() for element in list_values: ############ If an element in string equal 0 then apply X Gate on the left of the control dot. for i in range(n): if element[::-1][i] == '0': a1.x(q1[i]) ############ # Apply n-1 qubits control Toffoli gate. gate = ZGate().control(n - 1) a1.append(gate, q1) ############ If an element in string equal 0 then apply X Gate on the right of the control dot. for i in range(n): if element[::-1][i] == '0': a1.x(q1[i]) ############ #a1.barrier() elif circuit_type == 'ancilla': if n == 3: q1 = QuantumRegister(4, "q") a1 = QuantumCircuit(q1) for element in list_values: ############ for i in range(n): if element[::-1][i] == '0': a1.x(q1[i]) ############ a1.ccx(0, 1, 3) a1.cz(3, 2) a1.ccx(0, 1, 3) ############ for i in range(n): if element[::-1][i] == '0': a1.x(q1[i]) ############ else: pn, jn, kn = 2, 0, 1 q1 = QuantumRegister(n + (n - 3), "q") a1 = QuantumCircuit(q1) #a1.barrier() for element in list_values: ############ for i in range(n): if element[::-1][i] == '0': a1.x(q1[i]) ############ # Apply n-1 qubits control Toffoli gate using 2-qubits control Toffoli gates. a1.ccx(q1[0], q1[1], q1[n]) for i in range(n - 4): a1.ccx(q1[pn], q1[n + jn], q1[n + kn]) if i < n - 5: pn += 1 jn += 1 kn += 1 #a1.barrier() a1.h(q1[n - 1]) a1.ccx(q1[(n - 2)], q1[n + (n - 4)], q1[n - 1]) a1.h(q1[n - 1]) #a1.barrier() for i in range(n - 4): a1.ccx(q1[pn], q1[n + jn], q1[n + kn]) if i < n - 5: pn += -1 jn += -1 kn += -1 a1.ccx(q1[0], q1[1], q1[n]) ############ for i in range(n): if element[::-1][i] == '0': a1.x(q1[i]) ############ #a1.barrier() return a1
import qiskit import numpy as np from qiskit.circuit.library.standard_gates import ZGate n = int(input("Digite o número do qubits: ")) k = int(input("Digite o target do qubits: ")) qc = qiskit.QuantumCircuit(n) list_qu = list(range(n)) bin_k = ('{0:0' + str(n) + 'b}').format(k) print(bin_k) bin_k = bin_k[::-1] for qu in range(n): qc.h(qu) qc.append(ZGate("zgate").control(num_ctrl_qubits=n - 1), list_qu) for i in range(n): if bin_k[i] == '0': qc.x(i) backend = qiskit.Aer.get_backend('statevector_simulator') job = qiskit.execute(qc, backend) result = job.result() print('Estado gerado pelo circuito: ', result.get_statevector()) print(qc.draw())
def apply_grad_gate( circuit, gate, param_index, grad_gate, grad_coeff, qr_superpos, open_ctrl=False, trim_after_grad_gate=False, ): """Util function to apply a gradient gate for the linear combination of unitaries method. Replaces the ``gate`` instance in ``circuit`` with ``grad_gate`` using ``qr_superpos`` as superposition qubit. Also adds the appropriate sign-fix gates on the superposition qubit. Args: circuit (QuantumCircuit): The circuit in which to do the replacements. gate (Gate): The gate instance to replace. param_index (int): The index of the parameter in ``gate``. grad_gate (Gate): A controlled gate encoding the gradient of ``gate``. grad_coeff (float): A coefficient to the gradient component. Might not be one if the gradient contains multiple summed terms. qr_superpos (QuantumRegister): A ``QuantumRegister`` of size 1 contained in ``circuit`` that is used as control for ``grad_gate``. open_ctrl (bool): If True use an open control for ``grad_gate`` instead of closed. trim_after_grad_gate (bool): If True remove all gates after the ``grad_gate``. Can be used to reduce the circuit depth in e.g. computing an overlap of gradients. Returns: QuantumCircuit: A copy of the original circuit with the gradient gate added. Raises: RuntimeError: If ``gate`` is not in ``circuit``. """ qr_superpos_qubits = tuple(qr_superpos) # copy the input circuit taking the gates by reference out = QuantumCircuit(*circuit.qregs) out._data = circuit._data.copy() out._parameter_table = ParameterTable({ param: values.copy() for param, values in circuit._parameter_table.items() }) # get the data index and qubits of the target gate TODO use built-in gate_idx, gate_qubits = None, None for i, instruction in enumerate(out._data): if instruction.operation is gate: gate_idx, gate_qubits = i, instruction.qubits break if gate_idx is None: raise RuntimeError( "The specified gate could not be found in the circuit data.") # initialize replacement instructions replacement = [] # insert the phase fix before the target gate better documentation sign = np.sign(grad_coeff) is_complex = np.iscomplex(grad_coeff) if sign < 0 and is_complex: replacement.append( CircuitInstruction(SdgGate(), qr_superpos_qubits, ())) elif sign < 0: replacement.append( CircuitInstruction(ZGate(), qr_superpos_qubits, ())) elif is_complex: replacement.append( CircuitInstruction(SGate(), qr_superpos_qubits, ())) # else no additional gate required # open control if specified if open_ctrl: replacement += [ CircuitInstruction(XGate(), qr_superpos_qubits, []) ] # compute the replacement if isinstance(gate, UGate) and param_index == 0: theta = gate.params[2] rz_plus, rz_minus = RZGate(theta), RZGate(-theta) replacement += [ CircuitInstruction(rz_plus, (qubit, ), ()) for qubit in gate_qubits ] replacement += [ CircuitInstruction(RXGate(np.pi / 2), (qubit, ), ()) for qubit in gate_qubits ] replacement.append( CircuitInstruction(grad_gate, qr_superpos_qubits + gate_qubits, [])) replacement += [ CircuitInstruction(RXGate(-np.pi / 2), (qubit, ), ()) for qubit in gate_qubits ] replacement += [ CircuitInstruction(rz_minus, (qubit, ), ()) for qubit in gate_qubits ] # update parametertable if necessary if isinstance(theta, ParameterExpression): # This dangerously subverts ParameterTable by abusing the fact that binding will # mutate the exact instruction instance, and relies on all instances of `rz_plus` # that were added before being the same in memory, which QuantumCircuit usually # ensures is not the case. I'm leaving this as close to its previous form as # possible, to avoid introducing further complications, but this whole method # accesses internal attributes of `QuantumCircuit` and needs rewriting. # - Jake Lishman, 2022-03-02. out._update_parameter_table( CircuitInstruction(rz_plus, (gate_qubits[0], ), ())) out._update_parameter_table( CircuitInstruction(rz_minus, (gate_qubits[0], ), ())) if open_ctrl: replacement.append( CircuitInstruction(XGate(), qr_superpos_qubits, ())) if not trim_after_grad_gate: replacement.append(CircuitInstruction(gate, gate_qubits, ())) elif isinstance(gate, UGate) and param_index == 1: # gradient gate is applied after the original gate in this case replacement.append(CircuitInstruction(gate, gate_qubits, ())) replacement.append( CircuitInstruction(grad_gate, qr_superpos_qubits + gate_qubits, ())) if open_ctrl: replacement.append( CircuitInstruction(XGate(), qr_superpos_qubits, ())) else: replacement.append( CircuitInstruction(grad_gate, qr_superpos_qubits + gate_qubits, ())) if open_ctrl: replacement.append( CircuitInstruction(XGate(), qr_superpos_qubits, ())) if not trim_after_grad_gate: replacement.append(CircuitInstruction(gate, gate_qubits, ())) # replace the parameter we compute the derivative of with the replacement # TODO can this be done more efficiently? if trim_after_grad_gate: # remove everything after the gradient gate out._data[gate_idx:] = replacement # reset parameter table table = ParameterTable() for instruction in out._data: for idx, param_expression in enumerate( instruction.operation.params): if isinstance(param_expression, ParameterExpression): for param in param_expression.parameters: if param not in table.keys(): table[param] = ParameterReferences( ((instruction.operation, idx), )) else: table[param].add((instruction.operation, idx)) out._parameter_table = table else: out._data[gate_idx:gate_idx + 1] = replacement return out
def depolarizing_error(param, num_qubits, standard_gates=None): r""" Return a depolarizing quantum error channel. The depolarizing channel is defined as: .. math:: E(ρ) = (1 - λ) ρ + λ \text{Tr}[ρ] \frac{I}{2^n} with :math:`0 \le λ \le 4^n / (4^n - 1)` where :math:`λ` is the depolarizing error param and :math`n` is the number of qubits. * If :math:`λ = 0` this is the identity channel :math:`E(ρ) = ρ` * If :math:`λ = 1` this is a completely depolarizing channel :math:`E(ρ) = I / 2^n` * If :math:`λ = 4^n / (4^n - 1)` this is a uniform Pauli error channel: :math:`E(ρ) = \sum_j P_j ρ P_j / (4^n - 1)` for all :math:`P_j != I`. Args: param (double): depolarizing error parameter. num_qubits (int): the number of qubits for the error channel. standard_gates (bool): DEPRECATED, if True return the operators as Pauli gates. If false return as unitary gates. (Default: None) Returns: QuantumError: The quantum error object. Raises: NoiseError: If noise parameters are invalid. """ if not isinstance(num_qubits, int) or num_qubits < 1: raise NoiseError("num_qubits must be a positive integer.") # Check that the depolarizing parameter gives a valid CPTP num_terms = 4**num_qubits max_param = num_terms / (num_terms - 1) if param < 0 or param > max_param: raise NoiseError("Depolarizing parameter must be in between 0 " "and {}.".format(max_param)) # Rescale completely depolarizing channel error probs # with the identity component removed prob_iden = 1 - param / max_param prob_pauli = param / num_terms probs = [prob_iden] + (num_terms - 1) * [prob_pauli] if standard_gates is not None: warnings.warn( '"standard_gates" option has been deprecated as of qiskit-aer 0.10.0' ' and will be removed no earlier than 3 months from that release date.', DeprecationWarning, stacklevel=2) circs = [] for pauli_list in it.product( [IGate(), XGate(), YGate(), ZGate()], repeat=num_qubits): qc = QuantumCircuit(num_qubits) for q, pauli in enumerate(pauli_list): if not standard_gates: pauli = UnitaryGate(pauli.to_matrix()) qc.append(pauli, qargs=[q]) circs.append(qc) return QuantumError(zip(circs, probs)) # Generate pauli strings. The order doesn't matter as long # as the all identity string is first. paulis = [ Pauli("".join(tup)) for tup in it.product(['I', 'X', 'Y', 'Z'], repeat=num_qubits) ] return QuantumError(zip(paulis, probs))
from qiskit.circuit.library.standard_gates import ZGate, HGate # import basic plot tools from qiskit.visualization import plot_histogram n = 4 grover_circuit = QuantumCircuit(n) for qubit in range(n): grover_circuit.h(qubit) grover_circuit.barrier() grover_circuit.x(1) grover_circuit.x(3) c3z_gate = ZGate().control(3) grover_circuit.append(c3z_gate, [3, 2, 1, 0]) grover_circuit.x(1) grover_circuit.x(3) grover_circuit.barrier() for qubit in range(n): grover_circuit.h(qubit) grover_circuit.draw( 'mpl', 1, 'C:/Users/Familie/Documents/QuantumComputers/grover_circuit_4qubits_oracle_0101.png' ) plt.show(grover_circuit)