def sample(self, variables, samples, *args, **kwargs) -> numpy.array: # todo: generalize in baseclass. Do Hamiltonian mapping on initialization self.update_variables(variables) state = qulacs.QuantumState(self.U.n_qubits) self.U.circuit.update_quantum_state(state) result = [] for H in self._abstract_hamiltonians: E = 0.0 for ps in H.paulistrings: # change basis, measurement is destructive so copy the state # to avoid recomputation bc = QCircuit() zero_string = False for idx, p in ps.items(): if idx not in self.U.qubit_map: # circuit does not act on the qubit # case1: paulimatrix is 'Z' -> unit factor: ignore that part # case2: zero factor -> continue with next ps if p.upper() != "Z": zero_string = True else: bc += change_basis(target=idx, axis=p) if zero_string: continue qbc = self.U.create_circuit(abstract_circuit=bc, variables=None) Esamples = [] for sample in range(samples): if self.U.has_noise: state = qulacs.QuantumState(self.U.n_qubits) self.U.circuit.update_quantum_state(state) state_tmp = state else: state_tmp = state.copy() if len(bc.gates) > 0: # otherwise there is no basis change (empty qulacs circuit does not work out) qbc.update_quantum_state(state_tmp) ps_measure = 1.0 for idx in ps.keys(): if idx not in self.U.qubit_map: continue # means its 1 or Z and <0|Z|0> = 1 anyway else: M = qulacs.gate.Measurement(self.U.qubit_map[idx], self.U.qubit_map[idx]) M.update_quantum_state(state_tmp) measured = state_tmp.get_classical_value(self.U.qubit_map[idx]) ps_measure *= (-2.0 * measured + 1.0) # 0 becomes 1 and 1 becomes -1 Esamples.append(ps_measure) E += ps.coeff * sum(Esamples) / len(Esamples) result.append(E) return numpy.asarray(result)
def run1(): t = 3.0 M = 100 delta = t / M h = 3.0 n_qubits = 6 coefs = ([(1.0, [("Z", i), ("Z", (i + 1) % n_qubits)]) for i in range(n_qubits)] + [(h, [("X", i)]) for i in range(n_qubits)]) hamiltonian = Hamiltonian(n_qubits, coefs) circuit = hamiltonian.time_evolution_circuit(delta) # target observable z_obs = qulacs.Observable(n_qubits) for i in range(n_qubits): z_obs.add_operator(qulacs.PauliOperator("Z " + str(i), 1.0 / n_qubits)) # target observable z_obs = qulacs.Observable(n_qubits) for i in range(n_qubits): z_obs.add_operator(qulacs.PauliOperator("Z " + str(i), 1.0 / n_qubits)) # initial state state = qulacs.QuantumState(n_qubits) state.set_zero_state() # time evolution t = [i * delta for i in range(M + 1)] y = list() y.append(z_obs.get_expectation_value(state)) for i in range(M): circuit.update_quantum_state(state) y.append(z_obs.get_expectation_value(state)) plt.plot(t, y) plt.show()
def do_sample(self, samples, circuit, noise_model=None, initial_state=0, *args, **kwargs) -> QubitWaveFunction: assert (noise_model is None) state = qulacs.QuantumState(self.n_qubits) lsb = BitStringLSB.from_int(initial_state, nbits=self.n_qubits) state.set_computational_basis( BitString.from_binary(lsb.binary).integer) self.circuit.update_quantum_state(state) if hasattr(self, "measurements"): result = {} for sample in range(samples): sample_result = {} for t, m in self.measurements.items(): m.update_quantum_state(state) sample_result[t] = state.get_classical_value(t) sample_result = dict( sorted(sample_result.items(), key=lambda x: x[0])) binary = BitString.from_array(sample_result.values()) if binary in result: result[binary] += 1 else: result[binary] = 1 return QubitWaveFunction(state=result) else: # sample from the whole wavefunction (all-Z measurement) result = state.sampling(samples) return self.convert_measurements(backend_result=result)
def __init__(self, hamiltonian: Hamiltonian, t: float, nt: int, target_obs): self.hamiltonian = hamiltonian self.t = t self.nt = nt self.delta = self.t / self.nt self.target_obs = target_obs self.state = qulacs.QuantumState(hamiltonian.n_qubits)
def do_simulate(self, variables, initial_state, *args, **kwargs): state = qulacs.QuantumState(self.n_qubits) lsb = BitStringLSB.from_int(initial_state, nbits=self.n_qubits) state.set_computational_basis(BitString.from_binary(lsb.binary).integer) self.circuit.update_quantum_state(state) wfn = QubitWaveFunction.from_array(arr=state.get_vector(), numbering=self.numbering) return wfn
def get_qulacs_state_from_circuit(self, circuit: Circuit): qulacs_state = qulacs.QuantumState(circuit.n_qubits) for executable, operations_group in itertools.groupby( circuit.operations, self.can_be_executed_natively): if executable: qulacs_circuit = convert_to_qulacs( Circuit(operations_group, circuit.n_qubits)) qulacs_circuit.update_quantum_state(qulacs_state) else: wavefunction = qulacs_state.get_vector() for operation in operations_group: wavefunction = operation.apply(wavefunction) qulacs_state.load(wavefunction) return qulacs_state
def single_test(i): N = 8 #k = np.random.rand(N,N) #k -= (k+k.T)/2 # random real antisymmetric matrix k = get_random_antihermite_mat(N) umat = scipy.linalg.expm(k) #print(umat) c1 = freqerica.circuit.rotorb.OrbitalRotation(umat) from openfermion import FermionOperator, jordan_wigner, get_sparse_operator fop = FermionOperator() for p in range(N): for q in range(N): fop += FermionOperator(((p, 1), (q, 0)), k[p, q]) qop = jordan_wigner(fop) #print(qop) #from freqerica.circuit.trotter import TrotterStep from freqerica.util.qulacsnize import convert_state_vector import qulacs #M = 100 #c2 = TrotterStep(N, qop/M) s1 = qulacs.QuantumState(N) s1.set_Haar_random_state() #s2 = s1.copy() s3 = convert_state_vector(N, s1.get_vector()) c1._circuit.update_quantum_state(s1) #for i in range(M): c2._circuit.update_quantum_state(s2) s3 = scipy.sparse.linalg.expm_multiply(get_sparse_operator(qop), s3) #ip12 = qulacs.state.inner_product(s1, s2) ip13 = np.conjugate(convert_state_vector(N, s1.get_vector())).dot(s3) #ip23 = np.conjugate(convert_state_vector(N, s2.get_vector())).dot(s3) #print('dot(s1,s2)', abs(ip12), ip12) #print('dot(s1,s3)', abs(ip13), ip13) #print('dot(s2,s3)', abs(ip23), ip23) print('[trial{:02d}] fidelity-1 : {:+.1e} dot=({:+.5f})'.format( i, abs(ip13) - 1, ip13))
def test_rotorb_circuit(): import scipy.linalg np.set_printoptions(linewidth=300) N = 8 #k = np.random.rand(N,N) #k -= (k+k.T)/2 # random real antisymmetric matrix k = get_random_antihermite_mat(N) umat = scipy.linalg.expm(k) print(umat) c1 = OrbitalRotation(umat) from openfermion import FermionOperator, jordan_wigner, get_sparse_operator fop = FermionOperator() for p in range(N): for q in range(N): fop += FermionOperator(((p, 1), (q, 0)), k[p, q]) qop = jordan_wigner(fop) #print(qop) from trotter_qulacs import TrotterStep from util_qulacs import convert_state_vector M = 100 c2 = TrotterStep(N, qop / M) s1 = qulacs.QuantumState(N) s1.set_Haar_random_state() s2 = s1.copy() s3 = convert_state_vector(N, s1.get_vector()) c1._circuit.update_quantum_state(s1) for i in range(M): c2._circuit.update_quantum_state(s2) s3 = scipy.sparse.linalg.expm_multiply(get_sparse_operator(qop), s3) ip12 = qulacs.state.inner_product(s1, s2) ip13 = np.conjugate(convert_state_vector(N, s1.get_vector())).dot(s3) ip23 = np.conjugate(convert_state_vector(N, s2.get_vector())).dot(s3) print('dot(s1,s2)', abs(ip12), ip12) print('dot(s1,s3)', abs(ip13), ip13) print('dot(s2,s3)', abs(ip23), ip23)
def simulate(self, variables, *args, **kwargs) -> numpy.array: # fast return if possible if self.H is None: return numpy.asarray([0.0]) elif len(self.H) == 0: return numpy.asarray([0.0]) elif isinstance(self.H, numbers.Number): return numpy.asarray[self.H] self.U.update_variables(variables) state = qulacs.QuantumState(self.U.n_qubits) self.U.circuit.update_quantum_state(state) result = [] for H in self.H: if isinstance(H, numbers.Number): result.append(H) # those are accumulated unit strings, e.g 0.1*X(3) in wfn on qubits 0,1 else: result.append(H.get_expectation_value(state)) return numpy.asarray(result)
def setUp(self): self.n = 4 self.dim = 2**self.n self.state = qulacs.QuantumState(self.n) self.circuit = qulacs.QuantumCircuit(self.n)
def setUp(self): self.n = 4 self.dim = 2**self.n self.state = qulacs.QuantumState(self.n)
import qulacs import matplotlib.pyplot as plt #%% 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)
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.QuantumState(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 _get_qulacs_state(self, num_qubits: int): return qulacs.QuantumState(num_qubits)
def initialize_state(self, n_qubits=None): if n_qubits is None: n_qubits = self.n_qubits return qulacs.QuantumState(n_qubits)
def get_qulacs_state_from_circuit(self, circuit): qulacs_circuit = convert_circuit_to_qulacs(circuit) num_qubits = len(circuit.qubits) qulacs_state = qulacs.QuantumState(num_qubits) qulacs_circuit.update_quantum_state(qulacs_state) return qulacs_state
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)