def __init__(self, n_qubit, remover): self.n_qubit = [] self.circuit_list = [] for isym in range(remover.rank): targetpauli = paulistr(remover.targetpauli_qop_list[isym]) gensym = paulistr(remover.gensym_qop_list[isym]) index_tgt, axis_tgt = targetpauli[0] indices_gensym = [index for index, axis in gensym] pauli_gensym = [axis for index, axis in gensym] assert axis_tgt == 'X' assert index_tgt in indices_gensym assert 'X' not in pauli_gensym assert 'Y' not in pauli_gensym indices_gensym_wo_tgt = [ index for index in indices_gensym if index != index_tgt ][::-1] ctrl_tgt_pair = [ pair for pair in zip(indices_gensym_wo_tgt[:-1], indices_gensym_wo_tgt[1:]) ] circuit = qulacs.QuantumCircuit(n_qubit) for ctrl, tgt in ctrl_tgt_pair: circuit.add_CNOT_gate(ctrl, tgt) circuit.add_CNOT_gate(indices_gensym_wo_tgt[-1], index_tgt) circuit.add_CZ_gate(indices_gensym_wo_tgt[-1], index_tgt) for ctrl, tgt in reversed(ctrl_tgt_pair): circuit.add_CNOT_gate(ctrl, tgt) circuit.add_H_gate(index_tgt) self.circuit_list.append(circuit)
def __init__(self, ats, hs: List[TIDHamiltonian]): super().__init__(hs[0].n_qubits) self.ats = ats self.hs = hs self.n_comb = len(hs) self.circuit = qulacs.QuantumCircuit(self.n_qubits) self.num_paras_list = [0] for h in self.hs: circuit = h.time_evolution_circuit(1.0) for i in range(circuit.get_gate_count()): gate = circuit.get_gate(i) self.circuit.add_gate(gate) n = circuit.get_gate_count() + self.num_paras_list[-1] self.num_paras_list.append(n) self.angles = [] for i in range(self.circuit.get_parameter_count()): self.angles.append(self.circuit.get_parameter(i))
def simulate_sweep( self, program: Union[circuits.Circuit, schedules.Schedule], params: study.Sweepable, qubit_order: ops.QubitOrderOrList = ops.QubitOrder.DEFAULT, initial_state: Any = None, ) -> List['SimulationTrialResult']: """Simulates the supplied Circuit or Schedule with Qulacs Args: program: The circuit or schedule to simulate. params: Parameters to run with the program. qubit_order: Determines the canonical ordering of the qubits. This is often used in specifying the initial state, i.e. the ordering of the computational basis states. initial_state: The initial state for the simulation. The form of this state depends on the simulation implementation. See documentation of the implementing class for details. Returns: List of SimulationTrialResults for this run, one for each possible parameter resolver. """ trial_results = [] # sweep for each parameters resolvers = study.to_resolvers(params) for resolver in resolvers: # result circuit cirq_circuit = protocols.resolve_parameters(program, resolver) qubits = ops.QubitOrder.as_qubit_order(qubit_order).order_for( cirq_circuit.all_qubits()) qubit_map = {q: i for i, q in enumerate(qubits)} num_qubits = len(qubits) # create state qulacs_state = self._get_qulacs_state(num_qubits) if initial_state is not None: cirq_state = wave_function.to_valid_state_vector( initial_state, num_qubits) qulacs_state.load(cirq_state) del cirq_state # create circuit qulacs_circuit = qulacs.QuantumCircuit(num_qubits) address_to_key = {} register_address = 0 for moment in cirq_circuit: operations = moment.operations for op in operations: indices = [ num_qubits - 1 - qubit_map[qubit] for qubit in op.qubits ] result = self._try_append_gate(op, qulacs_circuit, indices) if result: continue if isinstance(op.gate, ops.ResetChannel): qulacs_circuit.update_quantum_state(qulacs_state) qulacs_state.set_zero_state() qulacs_circuit = qulacs.QuantumCircuit(num_qubits) elif protocols.is_measurement(op): for index in indices: qulacs_circuit.add_gate( qulacs.gate.Measurement( index, register_address)) address_to_key[ register_address] = protocols.measurement_key( op.gate) register_address += 1 elif protocols.has_mixture(op): indices.reverse() qulacs_gates = [] gate = cast(ops.GateOperation, op).gate channel = protocols.channel(gate) for krauss in channel: krauss = krauss.astype(np.complex128) qulacs_gate = qulacs.gate.DenseMatrix( indices, krauss) qulacs_gates.append(qulacs_gate) qulacs_cptp_map = qulacs.gate.CPTP(qulacs_gates) qulacs.circuit.add_gate(qulacs_cptp_map) # perform simulation qulacs_circuit.update_quantum_state(qulacs_state) # fetch final state and measurement results final_state = qulacs_state.get_vector() measurements = collections.defaultdict(list) for register_index in range(register_address): key = address_to_key[register_index] value = qulacs_state.get_classical_value(register_index) measurements[key].append(value) # create result for this parameter result = SimulationTrialResult(params=resolver, measurements=measurements, final_simulator_state=final_state) trial_results.append(result) # release memory del qulacs_state del qulacs_circuit return trial_results
def setUp(self): self.n = 4 self.dim = 2**self.n self.state = qulacs.QuantumState(self.n) self.circuit = qulacs.QuantumCircuit(self.n)
def convert_circuit_to_qulacs(circuit): qulacs_circuit = qulacs.QuantumCircuit(len(circuit.qubits)) for gate in circuit.gates: qulacs_circuit = append_gate(gate, qulacs_circuit) return qulacs_circuit
#%% plot test xs = np.linspace(0, 1) ys = np.sin(np.pi*xs) plt.plot(xs, ys) plt.show() #%% define # state n = 2 zero_index = 0 psi_index_list = list(range(1, n)) state0 = qulacs.QuantumState(n) state0.set_computational_basis(0b011) state1 = state0.copy() # define Adamal test. # Hamiltonian = H x I + \Lambda(U) + H x I # \Lambda(U) = |0><0| x I + |1><1| x U circuit = qulacs.QuantumCircuit(n) lambda_U = qulacs.gate.to_matrix_gate(qulacs.gate.RZ(1, np.pi/2)) lambda_U.add_control_qubit(0, 1) circuit.add_H_gate(0) circuit.add_gate(lambda_U) circuit.add_H_gate(0) circuit.update_quantum_state(state0) print("<\psi|U|\psi>", qulacs.state.inner_product(state1, state0))
def convert_to_qulacs(circuit: circuits.Circuit): qulacs_circuit = qulacs.QuantumCircuit(circuit.n_qubits) for operation in circuit.operations: qulacs_circuit.add_gate(_qulacs_gate(operation)) return qulacs_circuit
def _base_iterator( self, circuit: circuits.Circuit, qubit_order: ops.QubitOrderOrList, initial_state: Union[int, np.ndarray], perform_measurements: bool = True, ) -> Iterator: qubits = ops.QubitOrder.as_qubit_order(qubit_order).order_for( circuit.all_qubits()) num_qubits = len(qubits) qubit_map = {q: i for i, q in enumerate(qubits)} state = wave_function.to_valid_state_vector(initial_state, num_qubits, self._dtype) if len(circuit) == 0: yield SparseSimulatorStep(state, {}, qubit_map, self._dtype) def on_stuck(bad_op: ops.Operation): return TypeError( "Can't simulate unknown operations that don't specify a " "_unitary_ method, a _decompose_ method, " "(_has_unitary_ + _apply_unitary_) methods," "(_has_mixture_ + _mixture_) methods, or are measurements." ": {!r}".format(bad_op)) def keep(potential_op: ops.Operation) -> bool: # The order of this is optimized to call has_xxx methods first. return (protocols.has_unitary(potential_op) or protocols.has_mixture(potential_op) or protocols.is_measurement(potential_op)) data = _StateAndBuffer(state=np.reshape(state, (2, ) * num_qubits), buffer=np.empty((2, ) * num_qubits, dtype=self._dtype)) shape = np.array(data.state).shape # Qulacs qulacs_flag = 0 qulacs_state = qulacs.QuantumStateGpu(int(num_qubits)) qulacs_circuit = qulacs.QuantumCircuit(int(num_qubits)) for moment in circuit: measurements = collections.defaultdict( list) # type: Dict[str, List[bool]] non_display_ops = (op for op in moment if not isinstance(op, ( ops.SamplesDisplay, ops.WaveFunctionDisplay, ops.DensityMatrixDisplay))) unitary_ops_and_measurements = protocols.decompose( non_display_ops, keep=keep, on_stuck_raise=on_stuck) for op in unitary_ops_and_measurements: indices = [ num_qubits - 1 - qubit_map[qubit] for qubit in op.qubits ] if protocols.has_unitary(op): # single qubit unitary gates if isinstance(op.gate, ops.pauli_gates._PauliX): qulacs_circuit.add_X_gate(indices[0]) elif isinstance(op.gate, ops.pauli_gates._PauliY): qulacs_circuit.add_Y_gate(indices[0]) elif isinstance(op.gate, ops.pauli_gates._PauliZ): qulacs_circuit.add_Z_gate(indices[0]) elif isinstance(op.gate, ops.common_gates.HPowGate): qulacs_circuit.add_H_gate(indices[0]) elif isinstance(op.gate, ops.common_gates.XPowGate): indices.reverse() qulacs_circuit.add_dense_matrix_gate( indices, op._unitary_()) elif isinstance(op.gate, ops.common_gates.YPowGate): indices.reverse() qulacs_circuit.add_dense_matrix_gate( indices, op._unitary_()) elif isinstance(op.gate, ops.common_gates.ZPowGate): indices.reverse() qulacs_circuit.add_dense_matrix_gate( indices, op._unitary_()) elif isinstance(op.gate, circuits.qasm_output.QasmUGate): indices.reverse() qulacs_circuit.add_dense_matrix_gate( indices, op._unitary_()) elif isinstance(op.gate, ops.matrix_gates.SingleQubitMatrixGate): qulacs_circuit.add_dense_matrix_gate( indices, op._unitary_()) # Two Qubit Unitary Gates elif isinstance(op.gate, ops.common_gates.CNotPowGate): qulacs_circuit.add_CNOT_gate(indices[0], indices[1]) elif isinstance(op.gate, ops.common_gates.CZPowGate): qulacs_circuit.add_CZ_gate(indices[0], indices[1]) elif isinstance(op.gate, ops.common_gates.SwapPowGate): qulacs_circuit.add_SWAP_gate(indices[0], indices[1]) elif isinstance(op.gate, ops.common_gates.ISwapPowGate): indices.reverse() qulacs_circuit.add_dense_matrix_gate( indices, op._unitary_()) elif isinstance(op.gate, ops.parity_gates.XXPowGate): indices.reverse() qulacs_circuit.add_dense_matrix_gate( indices, op._unitary_()) elif isinstance(op.gate, ops.parity_gates.YYPowGate): indices.reverse() qulacs_circuit.add_dense_matrix_gate( indices, op._unitary_()) elif isinstance(op.gate, ops.parity_gates.ZZPowGate): indices.reverse() qulacs_circuit.add_dense_matrix_gate( indices, op._unitary_()) elif isinstance(op.gate, ops.matrix_gates.TwoQubitMatrixGate): indices.reverse() qulacs_circuit.add_dense_matrix_gate( indices, op._unitary_()) # Three Qubit Unitary Gates elif isinstance(op.gate, ops.three_qubit_gates.CCXPowGate): indices.reverse() qulacs_circuit.add_dense_matrix_gate( indices, op._unitary_()) elif isinstance(op.gate, ops.three_qubit_gates.CCZPowGate): indices.reverse() qulacs_circuit.add_dense_matrix_gate( indices, op._unitary_()) elif isinstance(op.gate, ops.three_qubit_gates.CSwapGate): indices.reverse() qulacs_circuit.add_dense_matrix_gate( indices, op._unitary_()) qulacs_flag = 1 elif protocols.is_measurement(op): # Do measurements second, since there may be mixtures that # operate as measurements. # TODO: support measurement outside the computational basis. if perform_measurements: if qulacs_flag == 1: self._simulate_on_qulacs(data, shape, qulacs_state, qulacs_circuit) qulacs_flag = 0 self._simulate_measurement(op, data, indices, measurements, num_qubits) elif protocols.has_mixture(op): if qulacs_flag == 1: self._simulate_on_qulacs(data, shape, qulacs_state, qulacs_circuit) qulacs_flag = 0 qulacs_circuit = qulacs.QuantumCircuit(int(num_qubits)) self._simulate_mixture(op, data, indices) if qulacs_flag == 1: self._simulate_on_qulacs(data, shape, qulacs_state, qulacs_circuit) qulacs_flag = 0 del qulacs_state del qulacs_circuit yield SparseSimulatorStep(state_vector=data.state, measurements=measurements, qubit_map=qubit_map, dtype=self._dtype)
def test_trotterstep_circuit(self): from freqerica.op.symbol import WrappedExpr as Symbol from openfermion import FermionOperator, jordan_wigner, get_sparse_operator from sympy import Array import numpy as np np.random.seed(100) import scipy import qulacs n_orb = 2 const = Symbol('const') T1 = [[None for _ in range(n_orb)] for _ in range(n_orb)] for p in range(n_orb): for q in range(p, n_orb): t = Symbol('t{}{}'.format(p,q)) T1[p][q] = T1[q][p] = t T1 = Array(T1) print(T1) const_value = np.random.rand() T1_value = np.random.rand(n_orb,n_orb)*0.01 T1_value += T1_value.T print(const_value) print(T1_value) def op1e(const, Tmat): fop = FermionOperator('', const) for p in range(n_orb): for q in range(n_orb): fop += FermionOperator( ((2*p , 1),(2*q , 0)), Tmat[p,q] ) fop += FermionOperator( ((2*p+1, 1),(2*q+1, 0)), Tmat[p,q] ) return fop fop_symbol = op1e(const, T1) qop_symbol = jordan_wigner(fop_symbol) print(fop_symbol) print(qop_symbol) n_qubit = n_orb*2 # c1 : TrotterStep with symbolic qop c1 = freqerica.circuit.trotter.TrotterStep(n_qubit, (-1j)*qop_symbol) print(c1) symbol_number_pairs = [(const, const_value), (T1, T1_value)] c1.subs(symbol_number_pairs) print(c1) # c2 : TrotterStep with numerical qop fop_number = op1e(const_value, T1_value) qop_number = jordan_wigner(fop_number) c2 = freqerica.circuit.trotter.TrotterStep(n_qubit, (-1j)*qop_number) print(c2) # c3 : oldtype with numerical qop c3 = qulacs.QuantumCircuit(n_qubit) freqerica.circuit.trotter.trotter_step_2nd_order(c3, (-1j)*qop_number) s0 = qulacs.QuantumState(n_qubit) s0.set_Haar_random_state() s1 = s0.copy() s2 = s0.copy() s3 = s0.copy() from freqerica.util.qulacsnize import convert_state_vector sv = convert_state_vector( n_qubit, s0.get_vector() ) corr1 = [] corr2 = [] corr3 = [] corrv = [] for t in range(100): corr1.append( qulacs.state.inner_product(s0, s1) ) corr2.append( qulacs.state.inner_product(s0, s2) ) corr3.append( qulacs.state.inner_product(s0, s3)*np.exp(-1j*qop_number.terms[()]*t) ) corrv.append( np.dot(np.conjugate(convert_state_vector(n_qubit, s0.get_vector())), sv) ) c1._circuit.update_quantum_state(s1) c2._circuit.update_quantum_state(s2) c3.update_quantum_state(s3) sv = scipy.sparse.linalg.expm_multiply(-1j * get_sparse_operator(qop_number), sv)