예제 #1
0
    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)
예제 #2
0
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()
예제 #3
0
    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)
예제 #4
0
 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)
예제 #5
0
    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
예제 #6
0
 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
예제 #7
0
        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))
예제 #8
0
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)
예제 #9
0
    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)
예제 #10
0
 def setUp(self):
     self.n = 4
     self.dim = 2**self.n
     self.state = qulacs.QuantumState(self.n)
     self.circuit = qulacs.QuantumCircuit(self.n)
예제 #11
0
 def setUp(self):
     self.n = 4
     self.dim = 2**self.n
     self.state = qulacs.QuantumState(self.n)
예제 #12
0
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)
예제 #13
0
    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)
예제 #14
0
 def _get_qulacs_state(self, num_qubits: int):
     return qulacs.QuantumState(num_qubits)
예제 #15
0
 def initialize_state(self, n_qubits=None):
     if n_qubits is None:
         n_qubits = self.n_qubits
     return qulacs.QuantumState(n_qubits)
예제 #16
0
 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
예제 #17
0
    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)