Ejemplo n.º 1
0
    def create_input_gate(self, x, uin_type):
        # Encode x into quantum state
        # x = 2-dim. variables, [-1,1]
        u = QuantumCircuit(self.nqubit)

        angle_y = np.arcsin(x)
        angle_z = np.arccos(x**2)

        if uin_type == 0:
            for i in range(self.nqubit):
                u.add_RY_gate(i, angle_y[i])
                u.add_RZ_gate(i, angle_z[i])

        elif uin_type == 1:
            #for d in range(2):
            for i in range(self.nqubit):
                u.add_H_gate(i)
                u.add_RY_gate(i, angle_y[i])
                u.add_RZ_gate(i, angle_z[i])
            # KT: add second order expansion
            for i in range(self.nqubit - 1):
                for j in range(i + 1, self.nqubit):
                    angle_z2 = np.arccos(x[i] * x[j])
                    u.add_CNOT_gate(i, j)
                    u.add_RZ_gate(j, angle_z2)
                    u.add_CNOT_gate(i, j)

        return u
Ejemplo n.º 2
0
    def suspend_test_phase_estimation_debug(self):
        theta = 5*np.pi/16
        n_qubits = 2
        a_idx = 1
        k = 2
        circuit = QuantumCircuit(n_qubits)
        psi = QuantumState(n_qubits) # |ancilla>|logical>
        phi = 1.25/2
        print('k={}, phi={} mod (np.pi)'.format(k, phi))
        # Apply H to ancilla bit to get |+> state
        circuit.add_H_gate(a_idx)
        # Apply kickback phase rotation to ancilla bit
        circuit.add_RZ_gate(a_idx, -np.pi * phi)
        # Apply C-U(Z0)
        theta_k = 2 ** (k-1) * theta
        print('phase:{} mod (np.pi)'.format(theta_k/np.pi))
        circuit.add_RZ_gate(0, -theta_k)
        circuit.add_CNOT_gate(a_idx, 0)
        circuit.add_RZ_gate(0, theta_k)
        circuit.add_CNOT_gate(a_idx, 0)
        # Apply H to ancilla bit to get |+> state
        circuit.add_H_gate(a_idx)

        # run circuit
        circuit.update_quantum_state(psi)
        print(psi.get_vector())

        # partial trace
        p0 = psi.get_marginal_probability([2, 0])
        p1 = psi.get_marginal_probability([2, 1])
        print(p0, p1)
def main():
    import numpy as np
    n_qubit = 2
    obs = Observable(n_qubit)
    initial_state = QuantumState(n_qubit)
    obs.add_operator(1, "Z 0 Z 1")
    circuit_list = []
    p_list = [0.02, 0.04, 0.06, 0.08]

    #prepare circuit list
    for p in p_list:
        circuit = QuantumCircuit(n_qubit)
        circuit.add_H_gate(0)
        circuit.add_RY_gate(1, np.pi / 6)
        circuit.add_CNOT_gate(0, 1)
        circuit.add_gate(
            Probabilistic([p / 4, p / 4, p / 4],
                          [X(0), Y(0), Z(0)]))  #depolarizing noise
        circuit.add_gate(
            Probabilistic([p / 4, p / 4, p / 4],
                          [X(1), Y(1), Z(1)]))  #depolarizing noise
        circuit_list.append(circuit)

    #get mitigated output
    mitigated, non_mitigated_array, fit_coefs = error_mitigation_extrapolate_linear(
        circuit_list,
        p_list,
        initial_state,
        obs,
        n_circuit_sample=100000,
        return_full=True)

    #plot the result
    p = np.linspace(0, max(p_list), 100)
    plt.plot(p,
             fit_coefs[0] * p + fit_coefs[1],
             linestyle="--",
             label="linear fit")
    plt.scatter(p_list, non_mitigated_array, label="un-mitigated")
    plt.scatter(0, mitigated, label="mitigated output")

    #prepare the clean result
    state = QuantumState(n_qubit)
    circuit = QuantumCircuit(n_qubit)
    circuit.add_H_gate(0)
    circuit.add_RY_gate(1, np.pi / 6)
    circuit.add_CNOT_gate(0, 1)
    circuit.update_quantum_state(state)
    plt.scatter(0, obs.get_expectation_value(state), label="True output")
    plt.xlabel("error rate")
    plt.ylabel("expectation value")
    plt.legend()
    plt.show()
Ejemplo n.º 4
0
    def test_CU_Y0Y1(self):
        n_qubits = 3
        a_idx = 2
        theta = np.pi/4
        state = QuantumState(n_qubits)
        input_states_bin = [0b001, 0b010, 0b101, 0b110]
        input_states = []
        output_states = []

        circuit = QuantumCircuit(n_qubits)
        # change basis from Z to Y
        circuit.add_S_gate(0)
        circuit.add_S_gate(1)
        circuit.add_H_gate(0)
        circuit.add_H_gate(1)
        circuit.add_CNOT_gate(1, 0)
        # RZ
        circuit.add_RZ_gate(0, -0.5*theta)
        circuit.add_CNOT_gate(a_idx, 0)
        circuit.add_RZ_gate(0, 0.5*theta)
        circuit.add_CNOT_gate(a_idx, 0)
        
        circuit.add_CNOT_gate(1, 0)
        # change basis from Z to Y
        circuit.add_H_gate(0)
        circuit.add_H_gate(1)
        circuit.add_Sdag_gate(0)
        circuit.add_Sdag_gate(1)

        for b in input_states_bin:
            psi = state.copy()
            psi.set_computational_basis(b) 
            input_states += [psi]
            psi_out = psi.copy()
            circuit.update_quantum_state(psi_out)
            output_states += [psi_out]

        p_list = []
        for in_state in input_states:
            for out_state in output_states:
                prod = inner_product(in_state, out_state)
                p_list += [prod]
        # |001>
        exp_list = [1.0, 0.0, 0.0, 0.0]
        # |010>
        exp_list += [0.0, 1.0, 0.0, 0.0]
        # |101>
        exp_list += [0.0, 0.0, np.cos(theta/2), complex(0, -np.sin(theta/2))]
        # |110> 
        exp_list += [0.0, 0.0, complex(0, -np.sin(theta/2)), np.cos(theta/2)]
        
        for result, expected in zip(p_list, exp_list):
            self.assertAlmostEqual(result, expected, places=6)
Ejemplo n.º 5
0
def sample_observable_noisy_circuit(circuit,
                                    initial_state,
                                    obs,
                                    n_circuit_sample=1000,
                                    n_sample_per_circuit=1):
    """
    Args:
        circuit (:class:`qulacs.QuantumCircuit`)
        initial_state (:class:`qulacs.QuantumState`)
        obs (:class:`qulacs.Observable`)
        n_circuit_sample (:class:`int`):  number of circuit samples
        n_sample (:class:`int`):  number of samples per one circuit samples
    Return:
        :float: sampled expectation value of the observable
    """
    n_term = obs.get_term_count()
    n_qubit = obs.get_qubit_count()

    pauli_terms = [obs.get_term(i) for i in range(n_term)]
    coefs = [p.get_coef() for p in pauli_terms]
    pauli_ids = [p.get_pauli_id_list() for p in pauli_terms]
    pauli_indices = [p.get_index_list() for p in pauli_terms]

    exp = 0
    state = initial_state.copy()
    for c in range(n_circuit_sample):
        state.load(initial_state)
        circuit.update_quantum_state(state)
        for i in range(n_term):
            measurement_circuit = QuantumCircuit(n_qubit)
            if len(pauli_ids[i]) == 0:  # means identity
                exp += coefs[i]
                continue
            mask = ''.join([
                '1' if n_qubit - 1 - k in pauli_indices[i] else '0'
                for k in range(n_qubit)
            ])
            for single_pauli, index in zip(pauli_ids[i], pauli_indices[i]):
                if single_pauli == 1:
                    measurement_circuit.add_H_gate(index)
                elif single_pauli == 2:
                    measurement_circuit.add_Sdag_gate(index)
                    uncompute_circuit.add_H_gate(index)
            measurement_circuit.update_quantum_state(state)
            samples = state.sampling(n_sample_per_circuit)
            mask = int(mask, 2)
            exp += coefs[i] * sum(
                list(map(lambda x: (-1)**(bin(x & mask).count('1')),
                         samples))) / n_sample_per_circuit
    exp /= n_circuit_sample
    return exp
Ejemplo n.º 6
0
def ansatz_circuit(n_qubit, depth, theta_list):
    circuit = QuantumCircuit(n_qubit)

    for i in range(n_qubit):
        circuit.add_gate(RY(i, theta_list[i]))
    for d in range(depth):
        for i in range(1, n_qubit):
            circuit.add_H_gate(i)
        for j in range(n_qubit - 1):
            circuit.add_CNOT_gate(j, j + 1)
            circuit.add_gate(RY(j, theta_list[n_qubit * (1 + d) + j]))
            circuit.add_H_gate(j + 1)
        circuit.add_gate(
            RY(n_qubit - 1, theta_list[n_qubit * (1 + d) + n_qubit - 1]))

    return circuit
Ejemplo n.º 7
0
def ctrl_RZ_circuit(theta_k, kickback_phase):
    n_qubits = 2
    a_idx = 1
    phi = kickback_phase / 2
    circuit = QuantumCircuit(n_qubits)
    # Apply H to ancilla bit to get |+> state
    circuit.add_H_gate(a_idx)
    # Apply kickback phase rotation to ancilla bit
    circuit.add_RZ_gate(a_idx, -np.pi * phi)
    # Apply C-U(Z0)
    # print('phase:{} mod (np.pi)'.format(theta_k/np.pi))
    circuit.add_RZ_gate(0, -theta_k)
    circuit.add_CNOT_gate(a_idx, 0)
    circuit.add_RZ_gate(0, theta_k)
    circuit.add_CNOT_gate(a_idx, 0)
    # Apply H to ancilla bit to get |+> state
    circuit.add_H_gate(a_idx)
    return circuit
Ejemplo n.º 8
0
def sample_observable(state, obs, n_sample):
    """Function
    Args:
        state (qulacs.QuantumState):
        obs (qulacs.Observable)
        n_sample (int):  number of samples for each observable
    Return:
        :float: sampled expectation value of the observable

    Author(s): Takashi Tsuchimochi
    """
    n_term = obs.get_term_count()
    n_qubits = obs.get_qubit_count()

    exp = 0
    buf_state = QuantumState(n_qubits)
    for i in range(n_term):
        pauli_term = obs.get_term(i)
        coef = pauli_term.get_coef()
        pauli_id = pauli_term.get_pauli_id_list()
        pauli_index = pauli_term.get_index_list()

        if len(pauli_id) == 0:  # means identity
            exp += coef
            continue

        buf_state.load(state)
        measurement_circuit = QuantumCircuit(n_qubits)
        mask = "".join(["1" if n_qubits - 1 - k in pauli_index else "0"
                        for k in range(n_qubits)])
        for single_pauli, index in zip(pauli_id, pauli_index):
            if single_pauli == 1:
                measurement_circuit.add_H_gate(index)
            elif single_pauli == 2:
                measurement_circuit.add_Sdag_gate(index)
                measurement_circuit.add_H_gate(index)
        measurement_circuit.update_quantum_state(buf_state)
        samples = buf_state.sampling(n_sample)
        mask = int(mask, 2)
        exp += (coef
                *sum(list(map(lambda x: (-1)**(bin(x & mask).count("1")),
                              samples)))
                /n_sample)
    return exp
Ejemplo n.º 9
0
    def test_CU_Z0(self):
        n_qubits = 2
        a_idx = 1
        theta = np.pi/8

        state = QuantumState(n_qubits)
        input_states_bin = [0b00, 0b10]
        input_states = []
        output_states = []

        circuit_H = QuantumCircuit(n_qubits)
        circuit_H.add_H_gate(0)
        # |0>|+> and |1>|+>
        for b in input_states_bin:
            psi = state.copy()
            psi.set_computational_basis(b) 
            input_states += [psi]
            circuit_H.update_quantum_state(psi)

        circuit = QuantumCircuit(n_qubits)
        circuit.add_RZ_gate(0, -0.5*theta)
        circuit.add_CNOT_gate(a_idx, 0)
        circuit.add_RZ_gate(0, 0.5*theta)
        circuit.add_CNOT_gate(a_idx, 0)
        
        for in_state in input_states:
            psi = in_state.copy()
            circuit.update_quantum_state(psi)
            output_states += [psi]

        p_list = []
        for in_state in input_states:
            for out_state in output_states:
                p_list += [inner_product(in_state, out_state)]
        
        # <0|<+|0>|+> = 1
        # <0|<+|1>|H> = 0
        # <1|<+|0>|+> = 0
        # <1|<+|1>|H> = cos(pi/16)
        exp_list = [1.0, 0.0, 0.0, np.cos(theta/2)]

        for result, expected in zip(p_list, exp_list):
            self.assertAlmostEqual(result, expected, places=6)
Ejemplo n.º 10
0
def sample_observable(state, obs, n_sample):
    """
    Args:
        state (qulacs.QuantumState):
        obs (qulacs.Observable)
        n_sample (int):  number of samples for each observable
    Return:
        :float: sampled expectation value of the observable
    """
    n_term = obs.get_term_count()
    n_qubit = obs.get_qubit_count()

    pauli_terms = [obs.get_term(i) for i in range(n_term)]
    coefs = [p.get_coef() for p in pauli_terms]
    pauli_ids = [p.get_pauli_id_list() for p in pauli_terms]
    pauli_indices = [p.get_index_list() for p in pauli_terms]

    exp = 0
    measured_state = state.copy()
    for i in range(n_term):
        state.load(measured_state)
        measurement_circuit = QuantumCircuit(n_qubit)
        if len(pauli_ids[i]) == 0:  # means identity
            exp += coefs[i]
            continue
        mask = ''.join([
            '1' if n_qubit - 1 - k in pauli_indices[i] else '0'
            for k in range(n_qubit)
        ])
        for single_pauli, index in zip(pauli_ids[i], pauli_indices[i]):
            if single_pauli == 1:
                measurement_circuit.add_H_gate(index)
            elif single_pauli == 2:
                measurement_circuit.add_Sdag_gate(index)
                measurement_circuit.add_H_gate(index)
        measurement_circuit.update_quantum_state(state)
        samples = state.sampling(n_sample)
        mask = int(mask, 2)
        exp += coefs[i] * sum(
            list(map(lambda x:
                     (-1)**(bin(x & mask).count('1')), samples))) / n_sample

    return exp
Ejemplo n.º 11
0
    def test_iterative_phase_estimation(self):
        theta = 5*np.pi/16
        # theta = np.pi/3 # -0.5235987755982988
        # print(-theta/2) 
        n_itter = 6
        n_qubits = 2
        a_idx = 1
        
        state = QuantumState(n_qubits) # |ancilla>|logical>
        kickback_phase = 0.0
        for k in reversed(range(1, n_itter)):
            psi = state.copy()
            phi = kickback_phase/2
            # print('k={}, phi={} mod (np.pi)'.format(k, phi))
            circuit = QuantumCircuit(n_qubits)
            # Apply H to ancilla bit to get |+> state
            circuit.add_H_gate(a_idx)
            # Apply kickback phase rotation to ancilla bit
            circuit.add_RZ_gate(a_idx, -np.pi * phi)
            # Apply C-U(Z0)
            theta_k = 2 ** (k-1) * theta
            # print('phase:{} mod (np.pi)'.format(theta_k/np.pi))
            circuit.add_RZ_gate(0, -theta_k)
            circuit.add_CNOT_gate(a_idx, 0)
            circuit.add_RZ_gate(0, theta_k)
            circuit.add_CNOT_gate(a_idx, 0)
            # Apply H to ancilla bit to get |+> state
            circuit.add_H_gate(a_idx)

            # run circuit
            circuit.update_quantum_state(psi)
            # print(psi.get_vector())
            # partial trace
            p0 = psi.get_marginal_probability([2, 0])
            p1 = psi.get_marginal_probability([2, 1])
            # print(p0, p1)
            # update kickback phase
            kth_digit = 1 if (p0 < p1) else 0
            kickback_phase = kickback_phase/2 + kth_digit
            # print(kickback_phase)
        # print(-np.pi * kickback_phase/2)
        self.assertAlmostEqual(-np.pi * kickback_phase/2, -theta/2)
Ejemplo n.º 12
0
def test_transition_observable(state, obs, poststate0, poststate1, n_sample):
    """
    Args:
        state (qulacs.QuantumState): This includes entangled ancilla
                                     (n_qubits = n_qubit_system + 1)
        obs (qulacs.Observable): This does not include ancilla Z
                                 (n_qubit_system)
        poststate0 (qulacs.QuantumState): post-measurement state
                                          when ancilla = 0 (n_qubit_system)
        poststate1 (qulacs.QuantumState): post-measurement state
                                          when ancilla = 1 (n_qubit_system)
        n_sample (int):  number of samples for each observable

    Return:
        :float: sampled expectation value of the observable
    """
    n_term = obs.get_term_count()
    n_qubits = obs.get_qubit_count()
    p0 = state.get_zero_probability(n_qubits - 1)
    p1 = 1 - p0
    opt = f"0{n_qubits}b"

    prints(f"p0: {p0}  p1: {p1}")
    print_state(poststate0, name="post(0)")
    prints("post(1)")
    print_state(poststate1, name="post(1)")

    expH = 0
    exp = []
    coef = []
    buf_state = QuantumState(n_qubits)
    for i in range(n_term):
        pauli_term = obs.get_term(i)
        coef.append(pauli_term.get_coef().real)
        pauli_id = pauli_term.get_pauli_id_list()
        pauli_index = pauli_term.get_index_list()

        if len(pauli_id) == 0:  # means identity
            exp.extend(coef)
            continue

        buf_state.load(state)
        measurement_circuit = QuantumCircuit(n_qubits)
        mask = "".join(["1" if n_qubits - 1 - k in pauli_index else "0"
                        for k in range(n_qubits)])

        measure_observable = QubitOperator((), 1)
        #measure_observable = QubitOperator('Z%d' % n_qubits)
        for single_pauli, index in zip(pauli_id, pauli_index):
            if single_pauli == 1:
                ###  X
                measurement_circuit.add_H_gate(index)
                measure_observable *= QubitOperator(f"X{index}")
            elif single_pauli == 2:
                ###  Y
                measurement_circuit.add_Sdag_gate(index)
                measurement_circuit.add_H_gate(index)
                measure_observable *= QubitOperator(f"Y{index}")
            elif single_pauli == 3:
                ###  Z
                measure_observable *= QubitOperator(f"Z{index}")
        qulacs_measure_observable \
                = create_observable_from_openfermion_text(
                        str(measure_observable))
        ### p0 ###
        H0 = qulacs_measure_observable.get_expectation_value(poststate0)
        ### p1 ###
        H1 = qulacs_measure_observable.get_expectation_value(poststate1)
        prob = p0*H0 - p1*H1
        # print(prob, qulacs_measure_observable.get_expectation_value(state), obs.get_expectation_value(state))
        prob = qulacs_measure_observable.get_expectation_value(state)
        expH += coef[i]*prob

        # measurement_circuit.update_quantum_state(buf_state)
        # samples = buf_state.sampling(n_sample)
        # print('samples? ',format(samples[0],opt))
        # print("I = :",'%5d' % i, "  h_I ", '%10.5f' % coef[i], "    <P_I> ", '%10.5f' % exp[i])
        # mask = int(mask, 2)
        # print(sum(list(map(lambda x: (-1) **(bin(x & mask).count('1')), samples))))
        # print(coef*sum(list(map(lambda x: (-1) **
        #                             (bin(x & mask).count('1')), samples))))
        # expH += coef[i] * exp[i]
        # samples = buf_state.sampling(n_sample)

        # mask = int(mask, 2)
        # prob = sum(list(map(lambda x: (-1) **
        #                             (bin(x & mask).count('1')), samples)))/n_sample
        # measure_list = list(map(int,np.ones(n_qubits)*2))
        # for j in pauli_index:
        #    measure_list[j] = 1
        # print(qulacs_measure_observable.get_expectation_value(state))
        # expH += coef[i] * prob
        print(f"coef: {coef[i]:10.5f}  prob: {prob:10.5f}")
    return expH
Ejemplo n.º 13
0
def test_observable(state, obs, obsZ, n_sample):
    """Function

    Args:
        state (qulacs.QuantumState): This includes entangled ancilla
                                     (n_qubits = n_qubit_system + 1)
        obs (qulacs.Observable): This does not include ancilla Z
                                 (n_qubit_system)
        obsZ (qulacs.Observable): Single Pauli Z for ancilla (1)
        poststate0 (qulacs.QuantumState): post-measurement state
                                          when ancilla = 0 (n_qubit_system)
        poststate1 (qulacs.QuantumState): post-measurement state
                                          when ancilla = 1 (n_qubit_system)
        n_sample (int):  number of samples for each observable

    Return:
        :float: sampled expectation value of the observable

    Author(s): Takashi Tsuchimochi
    """
    n_term = obs.get_term_count()
    n_qubits = obs.get_qubit_count()
    p0 = state.get_zero_probability(n_qubits)
    p1 = 1 - p0
    opt = f"0{n_qubits}b"

    expH = 0
    exp = []
    coef = []
    buf_state = QuantumState(n_qubits)
    for i in range(n_term):
        pauli_term = obs.get_term(i)
        coef.append(pauli_term.get_coef().real)
        pauli_id = pauli_term.get_pauli_id_list()
        pauli_index = pauli_term.get_index_list()

        if len(pauli_id) == 0:  # means identity
            exp.extend(coef)
            continue

        buf_state.load(state)
        measurement_circuit = QuantumCircuit(n_qubits)
        mask = "".join(["1" if n_qubits - 1 - k in pauli_index else "0"
                        for k in range(n_qubits)])
        measure_observable = QubitOperator((), 1)
        for single_pauli, index in zip(pauli_id, pauli_index):
            if single_pauli == 1:
                ###  X
                measurement_circuit.add_H_gate(index)
                measure_observable *= QubitOperator(f"X{index}")
            elif single_pauli == 2:
                ###  Y
                measurement_circuit.add_Sdag_gate(index)
                measurement_circuit.add_H_gate(index)
                measure_observable *= QubitOperator(f"Y{index}")
            elif single_pauli == 3:
                ###  Z
                measure_observable *= QubitOperator(f"Z{index}")
        qulacs_measure_observable \
                = create_observable_from_openfermion_text(
                        str(measure_observable))
        measurement_circuit.update_quantum_state(buf_state)
        #exp.append(obsZ.get_expectation_value(buf_state).real)
        samples = buf_state.sampling(n_sample)
        #print(f"samples? {format(samples[0], opt)}")
        #print(f"I = {i:5d}  h_I = {coef[i]:10.5f}  <P_I> = {exp[i]:10.5f}")
        #mask = int(mask, 2)
        #print(sum(list(map(lambda x: (-1)**(bin(x & mask).count('1')),
        #                   samples))))
        #print(coef*sum(list(map(lambda x: (-1)**(bin(x & mask).count('1')),
        #                        samples))))
        expH += coef[i]*exp[i]
        samples = buf_state.sampling(n_sample)

        mask = int(mask, 2)
        prob = (sum(list(map(lambda x: (-1)**(bin(x & mask).count("1")),
                             samples)))
                /n_sample)
        measure_list = list(map(int, np.ones(n_qubits)*2))
        for j in pauli_index:
            measure_list[j] = 1
        #print(qulacs_measure_observable.get_expectation_value(state))
        expH += coef[i]*prob
        #print(f"coef: {coef[i]:10.5f}  prob: {prob:10.5f}")
    return expH
Ejemplo n.º 14
0
def cost_proj(Quket,
              print_level,
              qulacs_hamiltonianZ,
              qulacs_s2Z,
              coef0_H,
              coef0_S2,
              kappa_list,
              theta_list=0,
              threshold=0.01):
    """Function:
    Energy functional for projected methods (phf, puccsd, puccd, opt_puccd)

    Author(s): Takashi Tsuchimochi
    """
    t1 = time.time()

    noa = Quket.noa
    nob = Quket.nob
    nva = Quket.nva
    nvb = Quket.nvb
    n_electrons = Quket.n_electrons
    rho = Quket.rho
    DS = Quket.DS
    anc = Quket.anc
    n_qubit_system = Quket.n_qubits
    n_qubits = n_qubit_system + 1
    # opt_psauccdとかはndimの計算が異なるけどこっちを使う?
    #ndim1 = noa * nva + nob * nvb
    #ndim2aa = int(noa * (noa - 1) * nva * (nva - 1) / 4)
    #ndim2ab = int(noa * nob * nva * nvb)
    #ndim2bb = int(nob * (nob - 1) * nvb * (nvb - 1) / 4)
    #ndim2 = ndim2aa + ndim2ab + ndim2bb
    ndim1 = Quket.ndim1
    ndim2 = Quket.ndim2
    ndim = Quket.ndim
    ref = Quket.ansatz

    state = QuantumState(n_qubits)
    if noa == nob:
        circuit_rhf = set_circuit_rhfZ(n_qubits, n_electrons)
    else:
        circuit_rhf = set_circuit_rohfZ(n_qubits, noa, nob)
    circuit_rhf.update_quantum_state(state)

    if ref == "phf":
        circuit_uhf = set_circuit_uhfZ(n_qubits, noa, nob, nva, nvb,
                                       kappa_list)
        circuit_uhf.update_quantum_state(state)
    elif ref == "sghf":
        circuit_ghf = set_circuit_ghfZ(n_qubits, noa + nob, nva + nvb,
                                       kappa_list)
        circuit_ghf.update_quantum_state(state)
    elif ref == "puccsd":
        # First prepare UHF determinant
        circuit_uhf = set_circuit_uhfZ(n_qubits, noa, nob, nva, nvb,
                                       kappa_list)
        circuit_uhf.update_quantum_state(state)
        # Then prepare UCCSD
        theta_list_rho = theta_list / rho
        circuit = set_circuit_uccsd(n_qubits, noa, nob, nva, nvb, 0,
                                    theta_list_rho, ndim1)
        for i in range(rho):
            circuit.update_quantum_state(state)
    elif ref == "puccd":
        # First prepare UHF determinant
        circuit_uhf = set_circuit_uhfZ(n_qubits, noa, nob, nva, nvb,
                                       kappa_list)
        circuit_uhf.update_quantum_state(state)
        # Then prepare UCCD
        theta_list_rho = theta_list / rho
        circuit = set_circuit_uccd(n_qubits, noa, nob, nva, nvb,
                                   theta_list_rho)
        for i in range(rho):
            circuit.update_quantum_state(state)
    elif ref == "opt_puccd":
        if DS:
            # First prepare UHF determinant
            circuit_uhf = set_circuit_uhfZ(n_qubits, noa, nob, nva, nvb,
                                           theta_list)
            circuit_uhf.update_quantum_state(state)
            # Then prepare UCCD
            theta_list_rho = theta_list[ndim1:] / rho
            circuit = set_circuit_uccd(n_qubits, noa, nob, nva, nvb,
                                       theta_list_rho)
            for i in range(rho):
                circuit.update_quantum_state(state)
        else:
            # First prepare UCCD
            theta_list_rho = theta_list[ndim1:] / rho
            circuit = set_circuit_uccd(n_qubits, noa, nob, nva, nvb,
                                       theta_list_rho)
            for i in range(rho):
                circuit.update_quantum_state(state)
            # then rotate
            circuit_uhf = set_circuit_uhfZ(n_qubits, noa, nob, nva, nvb,
                                           theta_list)
            circuit_uhf.update_quantum_state(state)
    elif ref == "opt_psauccd":
        # ここが問題
        # ndim2が他と異なる
        #theta_list_rho = theta_list[ndim1 : ndim1+ndim2]/rho
        theta_list_rho = theta_list[ndim1:] / rho
        circuit = set_circuit_sauccd(n_qubits, noa, nva, theta_list_rho)
        for i in range(rho):
            circuit.update_quantum_state(state)
        circuit_uhf = set_circuit_uhfZ(n_qubits, noa, nob, nva, nvb,
                                       theta_list)
        circuit_uhf.update_quantum_state(state)

    if print_level > 0:
        if ref in ("uhf", "phf", "suhf", "sghf"):
            SaveTheta(ndim, kappa_list, cf.tmp)
        else:
            SaveTheta(ndim, theta_list, cf.tmp)
    if print_level > 1:
        prints("State before projection")
        print_state(state, n_qubits=n_qubit_system)
        if ref in ("puccsd", "opt_puccd"):
            print_amplitudes(theta_list, noa, nob, nva, nvb, threshold)

    ### grid loop ###
    ### a list to compute the probability to observe 0 in ancilla qubit
    ### Array for <HUg>, <S2Ug>, <Ug>
    Ep = S2 = Norm = 0
    nalpha = max(Quket.projection.euler_ngrids[0], 1)
    nbeta = max(Quket.projection.euler_ngrids[1], 1)
    ngamma = max(Quket.projection.euler_ngrids[2], 1)
    HUg = np.empty(nalpha * nbeta * ngamma)
    S2Ug = np.empty(nalpha * nbeta * ngamma)
    Ug = np.empty(nalpha * nbeta * ngamma)
    ig = 0
    for ialpha in range(nalpha):
        alpha = Quket.projection.sp_angle[0][ialpha]
        alpha_coef = Quket.projection.sp_weight[0][ialpha]

        for ibeta in range(nbeta):
            beta = Quket.projection.sp_angle[1][ibeta]
            beta_coef = (Quket.projection.sp_weight[1][ibeta] *
                         Quket.projection.dmm[ibeta])

            for igamma in range(ngamma):
                gamma = Quket.projection.sp_angle[2][igamma]
                gamma_coef = Quket.projection.sp_weight[2][igamma]

                ### Copy quantum state of UHF (cannot be done in real device) ###
                state_g = QuantumState(n_qubits)
                state_g.load(state)
                ### Construct Ug test
                circuit_ug = QuantumCircuit(n_qubits)
                ### Hadamard on anc
                circuit_ug.add_H_gate(anc)
                #circuit_ug.add_X_gate(anc)
                #controlled_Ug(circuit_ug, n_qubits, anc, beta)
                controlled_Ug_gen(circuit_ug, n_qubits, anc, alpha, beta,
                                  gamma)
                #circuit_ug.add_X_gate(anc)
                circuit_ug.add_H_gate(anc)
                circuit_ug.update_quantum_state(state_g)

                ### Compute expectation value <HUg> ###
                HUg[ig] = qulacs_hamiltonianZ.get_expectation_value(state_g)
                ### <S2Ug> ###
                # print_state(state_g)
                S2Ug[ig] = qulacs_s2Z.get_expectation_value(state_g)
                ### <Ug> ###
                p0 = state_g.get_zero_probability(anc)
                p1 = 1 - p0
                Ug[ig] = p0 - p1

                ### Norm accumulation ###
                Norm += alpha_coef * beta_coef * gamma_coef * Ug[ig]
                Ep += alpha_coef * beta_coef * gamma_coef * HUg[ig]
                S2 += alpha_coef * beta_coef * gamma_coef * S2Ug[ig]
                ig += 1
    #        print('p0 : ',p0,'  p1 : ',p1,  '  p0 - p1 : ',p0-p1)
    #    print("Time: ",t2-t1)
    ### Energy calculation <HP>/<P> and <S**2P>/<P> ###
    Ep /= Norm
    S2 /= Norm
    Ep += coef0_H
    S2 += coef0_S2

    t2 = time.time()
    cpu1 = t2 - t1
    if print_level == -1:
        prints(f"Initial E[{ref}] = {Ep:.12f}  <S**2> = {S2:17.15f}  "
               f"rho = {rho}")
    elif print_level == 1:
        cput = t2 - cf.t_old
        cf.t_old = t2
        cf.icyc += 1
        prints(f"{cf.icyc:5d}: E[{ref}] = {Ep:.12f}  <S**2> = {S2:17.15f}  "
               f"CPU Time = {cput:5.2f}  ({cpu1:2.2f} / step)")
    elif print_level > 1:
        prints(f"Final: E[{ref}] = {Ep:.12f}  <S**2> = {S2:17.15f}  "
               f"rho = {rho}")
        print_state(state, n_qubits=n_qubits - 1)
        if ref in ("puccsd", "opt_puccd"):
            print_amplitudes(theta_list, noa, nob, nva, nvb)
        prints("HUg", HUg)
        prints("Ug", Ug)

    # Store wave function
    Quket.state = state
    return Ep, S2
Ejemplo n.º 15
0
    def _try_append_gate(self, op: ops.GateOperation,
                         qulacs_circuit: qulacs.QuantumCircuit,
                         indices: np.array):
        # One qubit gate
        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):
            qulacs_circuit.add_RX_gate(indices[0], -np.pi * op.gate._exponent)
        elif isinstance(op.gate, ops.common_gates.YPowGate):
            qulacs_circuit.add_RY_gate(indices[0], -np.pi * op.gate._exponent)
        elif isinstance(op.gate, ops.common_gates.ZPowGate):
            qulacs_circuit.add_RZ_gate(indices[0], -np.pi * op.gate._exponent)
        elif isinstance(op.gate, ops.SingleQubitMatrixGate):
            mat = op.gate._matrix
            qulacs_circuit.add_dense_matrix_gate(indices[0], mat)
        elif isinstance(op.gate, circuits.qasm_output.QasmUGate):
            lmda = op.gate.lmda
            theta = op.gate.theta
            phi = op.gate.phi
            gate = qulacs.gate.U3(indices[0], theta * np.pi, phi * np.pi,
                                  lmda * np.pi)
            qulacs_circuit.add_gate(gate)

        # Two qubit gate
        elif isinstance(op.gate, ops.common_gates.CNotPowGate):
            if op.gate._exponent == 1.0:
                qulacs_circuit.add_CNOT_gate(indices[0], indices[1])
            else:
                mat = _get_google_rotx(op.gate._exponent)
                gate = qulacs.gate.DenseMatrix(indices[1], mat)
                gate.add_control_qubit(indices[0], 1)
                qulacs_circuit.add_gate(gate)
        elif isinstance(op.gate, ops.common_gates.CZPowGate):
            if op.gate._exponent == 1.0:
                qulacs_circuit.add_CZ_gate(indices[0], indices[1])
            else:
                mat = _get_google_rotz(op.gate._exponent)
                gate = qulacs.gate.DenseMatrix(indices[1], mat)
                gate.add_control_qubit(indices[0], 1)
                qulacs_circuit.add_gate(gate)
        elif isinstance(op.gate, ops.common_gates.SwapPowGate):
            if op.gate._exponent == 1.0:
                qulacs_circuit.add_SWAP_gate(indices[0], indices[1])
            else:
                qulacs_circuit.add_dense_matrix_gate(indices, op._unitary_())
        elif isinstance(op.gate, ops.parity_gates.XXPowGate):
            qulacs_circuit.add_multi_Pauli_rotation_gate(
                indices, [1, 1], -np.pi * op.gate._exponent)
        elif isinstance(op.gate, ops.parity_gates.YYPowGate):
            qulacs_circuit.add_multi_Pauli_rotation_gate(
                indices, [2, 2], -np.pi * op.gate._exponent)
        elif isinstance(op.gate, ops.parity_gates.ZZPowGate):
            qulacs_circuit.add_multi_Pauli_rotation_gate(
                indices, [3, 3], -np.pi * op.gate._exponent)
        elif isinstance(op.gate, ops.TwoQubitMatrixGate):
            indices.reverse()
            mat = op.gate._matrix
            qulacs_circuit.add_dense_matrix_gate(indices, mat)

            # Three qubit gate
            """
            # deprecated because these functions cause errors in gpu
            elif isinstance(op.gate, ops.three_qubit_gates.CCXPowGate):
                mat = _get_google_rotx(op.gate._exponent)
                gate = qulacs.gate.DenseMatrix(indices[2], mat)
                gate.add_control_qubit(indices[0],1)
                gate.add_control_qubit(indices[1],1)
                qulacs_circuit.add_gate(gate)
            elif isinstance(op.gate, ops.three_qubit_gates.CCZPowGate):
                mat = _get_google_rotz(op.gate._exponent)
                gate = qulacs.gate.DenseMatrix(indices[2], mat)
                gate.add_control_qubit(indices[0],1)
                gate.add_control_qubit(indices[1],1)
                qulacs_circuit.add_gate(gate)
            """
        elif isinstance(op.gate, ops.three_qubit_gates.CSwapGate):
            mat = np.zeros(shape=(4, 4))
            mat[0, 0] = 1
            mat[1, 2] = 1
            mat[2, 1] = 1
            mat[3, 3] = 1
            gate = qulacs.gate.DenseMatrix(indices[1:], mat)
            gate.add_control_qubit(indices[0], 1)
            qulacs_circuit.add_gate(gate)

        # Misc
        elif protocols.has_unitary(op):
            indices.reverse()
            mat = op._unitary_()
            qulacs_circuit.add_dense_matrix_gate(indices, mat)

        # Not unitary
        else:
            return False

        return True
Ejemplo n.º 16
0
def cost_phf_sample_oneshot(print_level, qulacs_hamiltonianZ, qulacs_s2Z,
                            qulacs_ancZ, coef0_H, coef0_S2, kappa_list):
    """Function:
    Test function for sampling Hamiltonian and S** expectation values
    with PHF just for once.

    Author(s): Takashi Tsuchimochi

    使われてない?
    """
    t1 = time.time()

    noa = Quket.noa
    nob = Quket.nob
    nva = Quket.nva
    nvb = Quket.nvb
    n_electrons = Quket.n_electrons
    n_qubit_system = n_qubits
    n_qubits = Quket.n_qubits + 1
    anc = n_qubit_system

    state = QuantumState(n_qubits)
    circuit_rhf = set_circuit_rhfZ(n_qubits, n_electrons)
    circuit_rhf.update_quantum_state(state)
    circuit_uhf = set_circuit_uhfZ(n_qubits, noa, nob, nva, nvb, kappa_list)
    circuit_uhf.update_quantum_state(state)

    ### Set post-measurement states ####
    poststate0 = state.copy()
    poststate1 = state.copy()
    circuit0 = QuantumCircuit(n_qubits)
    circuit1 = QuantumCircuit(n_qubits)
    ### Projection to anc = 0 or anc = 1 ###
    circuit0.add_gate(P0(0))
    circuit1.add_gate(P1(0))
    circuit0.update_quantum_state(poststate0)
    circuit1.update_quantum_state(poststate1)
    ### Renormalize each state ###
    norm0 = poststate0.get_squared_norm()
    norm1 = poststate1.get_squared_norm()
    poststate0.normalize(norm0)
    poststate1.normalize(norm1)

    ### grid loop ###
    Ng = 4
    beta = [-0.861136311594053, -0.339981043584856,
             0.339981043584856,  0.861136311594053]
    wg = [0.173927422568724, 0.326072577431273,
          0.326072577431273, 0.173927422568724]
    ### a list to compute the probability to observe 0 in ancilla qubit
    p0_list = np.full(n_qubits, 2)
    p0_list[-1] = 0
    ### Array for <HUg>, <S2Ug>, <Ug>
    samplelist = [5, 50, 500, 5000, 50000, 500000, 5000000]
    Ng = 4
    ncyc = 10

    prints("", filepath="./log.txt", opentype="w")
    for i_sample in samplelist:
        sampleEn = []
        sampleS2 = []

        for icyc in range(ncyc):
            prints(f"n_sample : {i_sample}  ({icyc} / {ncyc})",
                   filepath="./log.txt")

            HUg = []
            S2Ug = []
            Ug = []
            Ephf = S2 = Norm = 0
            for i in range(Ng):
                ### Copy quantum state of UHF (cannot be done in real device) ###
                state_g = QuantumState(n_qubits)
                circuit_rhf.update_quantum_state(state_g)
                circuit_uhf.update_quantum_state(state_g)
                ### Construct Ug test
                circuit_ug = QuantumCircuit(n_qubits)
                ### Hadamard on anc
                circuit_ug.add_H_gate(anc)
                controlled_Ug(circuit_ug, n_qubits, anc, np.arccos(beta[i]))
                circuit_ug.add_H_gate(anc)
                circuit_ug.update_quantum_state(state_g)

                ### Probabilities for getting 0 and 1 in ancilla qubit ###
                p0 = state_g.get_marginal_probability(p0_list)
                p1 = 1 - p0

                ### Compute expectation value <HUg> ###
                HUg.append(sample_observable(state_g,
                                             qulacs_hamiltonianZ,
                                             i_sample).real)
                ### <S2Ug> ###
                S2Ug.append(sample_observable(state_g,
                                              qulacs_s2Z,
                                              i_sample).real)
                #S2Ug.append(qulacs_s2Z.get_expectation_value(state_g))

                #Ug.append(p0 - p1)
                Ug.append(sample_observable(state_g,
                                            qulacs_ancZ,
                                            i_sample).real)
                ### Norm accumulation ###
                Norm += wg[i]*g[i]
                sampleHUg[icyc, i] = HUg[i]
                sampleS2Ug[icyc, i] = S2Ug[i]
                sampleUg[icyc, i] = Ug[i]
            #print(f"{p0=}  {p1=}  {p0-p1=}")

            sampleHUg1.append(HUg[0])
            sampleHUg2.append(HUg[1])
            sampleHUg3.append(HUg[2])
            sampleHUg4.append(HUg[3])
            sampleS2Ug1.append(S2Ug[0])
            sampleS2Ug2.append(S2Ug[1])
            sampleS2Ug3.append(S2Ug[2])
            SAMpleS2Ug4.append(S2Ug[3])
            sampleUg1.append(Ug[0])
            sampleUg2.append(Ug[1])
            sampleUg3.append(Ug[2])
            sampleUg4.append(Ug[3])

            ### Energy calculation <HP>/<P> and <S**2P>/<P> ###
            Ephf = 0
            for i in range(Ng):
                Ephf += wg[i]*HUg[i]/Norm
                S2 += wg[i]*S2Ug[i]/Norm
            #print(f" E[PHF] = {Ephf}  <S**2> = {S2}  (Nsample = {i_sample})")
            Ephf += coef0_H
            S2 += coef0_S2
            sampleEn[icyc, 0] = Ephf
            sampleS2[icyc, 0] = S2
        #print(f"(n_sample = {i_sample}): sample HUg1\n", sampleHUg1)
        #print(f"(n_sample = {i_sample}): sample HUg2\n", sampleHUg2)
        #print(f"(n_sample = {i_sample}): sample HUg3\n", sampleHUg3)
        #print(f"(n_sample = {i_sample}): sample HUg4\n", sampleHUg4)
        #print(f"(n_sample = {i_sample}): sample S2Ug1\n", sampleS2Ug1)
        #print(f"(n_sample = {i_sample}): sample S2Ug2\n", sampleS2Ug2)
        #print(f"(n_sample = {i_sample}): sample S2Ug3\n", sampleS2Ug3)
        #print(f"(n_sample = {i_sample}): sample S2Ug4\n", sampleS2Ug4)
        #print(f"(n_sample = {i_sample}): sample Ug1\n", sampleUg1)
        #print(f"(n_sample = {i_sample}): sample Ug2\n", sampleUg2)
        #print(f"(n_sample = {i_sample}): sample Ug3\n", sampleUg3)
        #print(f"(n_sample = {i_sample}): sample Ug4\n", sampleUg4)
        #print(f"(n_sample = {i_sample}): sample HUg1\n", sampleHUg1)
        #print(f"(n_sample = {i_sample}): sample HUg2\n", sampleHUg2)
        #print(f"(n_sample = {i_sample}): sample HUg3\n", sampleHUg3)
        #print(f"(n_sample = {i_sample}): sample HUg4\n", sampleHUg4)
        #print(f"(n_sample = {i_sample}): sample En\n", sampleEn)
        #print(f"(n_sample = {i_sample}): sample S2\n", sampleS2)
        with open(f"./HUg_{i_sample}.csv", "w") as fHUg:
            writer = csv.writer(fHUg)
            writer.writerows(sampleHUg)
        with open(f"./S2Ug_{i_sample}.csv", "w") as fS2Ug:
            writer = csv.writer(fS2Ug)
            writer.writerows(sampleS2Ug)
        with open(f"./Ug_{i_sample}.csv", "w") as fUg:
            writer = csv.writer(fUg)
            writer.writerows(sampleUg)
        with open(f"./En_{i_sample}.csv", "w") as fEn:
            writer = csv.writer(fEn)
            writer.writerows(sampleEn)
        with open(f"./S2_{i_sample}.csv", "w") as fS2:
            writer = csv.writer(fS2)
            writer.writerows(sampleS2)
    return Ephf, S2
Ejemplo n.º 17
0
def cost_phf_sample(Quket, print_level,
                    qulacs_hamiltonian, qulacs_hamiltonianZ, qulacs_s2Z,
                    qulacs_ancZ, coef0_H, coef0_S2, ref, theta_list,
                    samplelist):
    """Function:
    Sample Hamiltonian and S**2 expectation values with PHF and PUCCSD.
    Write out the statistics in csv files.

    Author(s): Takashi Tsuchimochi
    """
    t1 = time.time()

    noa = Quket.noa
    nob = Quket.nob
    nva = Quket.nva
    nvb = Quket.nvb
    n_electrons = Quket.n_electrons
    n_qubit_system = n_qubits
    n_qubits = Quket.n_qubits + 1
    anc = n_qubit_system
    ndim1 = Quket.ndim1

    state = QuantumState(n_qubits)
    circuit_rhf = set_circuit_rhfZ(n_qubits, n_electrons)
    circuit_rhf.update_quantum_state(state)

    if ref == "phf":
        circuit_uhf = set_circuit_uhfZ(n_qubits, noa, nob, nva, nvb, theta_list)
        circuit_uhf.update_quantum_state(state)
        print("pHF")
    elif ref == "puccsd":
        circuit = set_circuit_uccsd(n_qubits, noa, nob, nva, nvb, theta_list,
                                    ndim1)
        for i in range(rho):
            circuit.update_quantum_state(state)
        print("UCCSD")

    if print_level > -1:
        print("State before projection")
        utils.print_state(state, n_qubit_system)
    #### Set post-measurement states ####
    #poststate0 = state.copy()
    #poststate1 = state.copy()
    #circuit0 = QuantumCircuit(n_qubits)
    #circuit1 = QuantumCircuit(n_qubits)
    #### Projection to anc = 0 or anc = 1 ###
    #circuit0.add_gate(P0(0))
    #circuit1.add_gate(P1(0))
    #circuit0.update_quantum_state(poststate0)
    #circuit1.update_quantum_state(poststate1)
    #### Renormalize each state ###
    #norm0 = poststate0.get_squared_norm()
    #norm1 = poststate1.get_squared_norm()
    #poststate0.normalize(norm0)
    #poststate1.normalize(norm1)

    ### grid loop ###
    Ng = 4
    beta = [-0.861136311594053, -0.339981043584856,
             0.339981043584856,  0.861136311594053]
    wg = [0.173927422568724, 0.326072577431273,
          0.326072577431273, 0.173927422568724]

    Ng = 2
    beta = [0.577350269189626, -0.577350269189626]
    wg = [0.5, 0.5]

    ### a list to compute the probability to observe 0 in ancilla qubit
    p0_list = np.full(n_qubits, 2)
    p0_list[-1] = 0

    ### Array for <HUg>, <S2Ug>, <Ug>
    # samplelist = [10,100,1000,10000,100000,1000000,10000000]
    ncyc = 4
    prints("", filepath="./log2.txt")
    for i_sample in samplelist:
        i_sample_x = i_sample
        if i_sample == 10000000:
            print("OK")
            ncyc = ncyc*10
            i_sample_x = 1000000
        sampleHUg1 = []
        sampleHUg2 = []
        sampleHUg3 = []
        sampleHUg4 = []
        sampleS2Ug1 = []
        sampleS2Ug2 = []
        sampleS2Ug3 = []
        sampleS2Ug4 = []
        sampleUg1 = []
        sampleUg2 = []
        sampleUg3 = []
        sampleUg4 = []
        # sampleEn = []
        # sampleS2 = []
        sampleHUg = np.zeros((ncyc, Ng))
        sampleS2Ug = np.zeros((ncyc, Ng))
        sampleUg = np.zeros((ncyc, Ng))
        sampleEn = np.zeros((ncyc, 1))
        sampleS2 = np.zeros((ncyc, 1))

        for icyc in range(ncyc):
            prints(f"n_sample = {i_sample_x}  ({icyc} / {ncyc})",
                   filepath="./log2.txt")
            HUg = []
            S2Ug = []
            Ug = []
            Ephf = S2 = Norm = 0
            for i in range(Ng):
                ### Copy quantum state of UHF (cannot be done in real device) ###
                state_g = QuantumState(n_qubits)
                state_g.load(state)
                ### Construct Ug test
                circuit_ug = QuantumCircuit(n_qubits)
                ### Hadamard on anc
                circuit_ug.add_H_gate(anc)
                controlled_Ug(circuit_ug, n_qubits, anc, np.arccos(beta[i]))
                circuit_ug.add_H_gate(anc)
                circuit_ug.update_quantum_state(state_g)

                ### Set post-measurement states ####
                poststate0 = state_g.copy()
                poststate1 = state_g.copy()
                circuit0 = QuantumCircuit(n_qubits)
                circuit1 = QuantumCircuit(n_qubits)
                ### Projection to anc = 0 or anc = 1 ###
                circuit0.add_gate(P0(anc))
                circuit1.add_gate(P1(anc))
                circuit0.update_quantum_state(poststate0)
                circuit1.update_quantum_state(poststate1)
                ### Renormalize each state ###
                norm0 = poststate0.get_squared_norm()
                norm1 = poststate1.get_squared_norm()
                poststate0.normalize(norm0)
                poststate1.normalize(norm1)
                ### Set ancilla qubit of poststate1 to zero (so that it won't be used) ###
                circuit_anc = QuantumCircuit(n_qubits)
                circuit_anc.add_X_gate(anc)
                circuit_anc.update_quantum_state(poststate1)
                print(
                        test_transition_observable(
                            state_g, qulacs_hamiltonianZ,
                            poststate0, poststate1, 100000))
                # exit()

                ### Probabilities for getting 0 and 1 in ancilla qubit ###
                p0 = state_g.get_marginal_probability(p0_list)
                p1 = 1 - p0

                ### Compute expectation value <HUg> ###
                HUg.append(sample_observable(state_g,
                                             qulacs_hamiltonianZ,
                                             i_sample_x).real)
                #HUg.append(adaptive_sample_observable(state_g,
                #                                      qulacs_hamiltonianZ,
                #                                      i_sample_x).real)
                ### <S2Ug> ###
                S2Ug.append(sample_observable(state_g,
                                              qulacs_s2Z,
                                              i_sample_x).real)
                #S2Ug.append(adaptive_sample_observable(state_g,
                #                                       qulacs_s2Z,
                #                                       i_sample_x).real)
                #S2Ug.append(qulacs_s2Z.get_expectation_value(state_g))
                #HUg.append(0)
                #S2Ug.append(0)

                #Ug.append(p0 - p1)
                n_term = qulacs_hamiltonianZ.get_term_count()
                n_sample_total = i_sample_x * n_term
                # in the worst-case scenario,
                # Ug is measured as many times as n_sample_total
                #(required to evaluate HUg)
                Ug.append(sample_observable(state_g,
                                            qulacs_ancZ,
                                            i_sample_x*n_term).real)
                #p0_sample = 0
                #for j_sample in range(n_sample_total):
                #   if(p0 > np.random.rand()):
                #      p0_sample += 1
                #Ug.append(2*p0_sample/n_sample_total - 1)
                ### Norm accumulation ###
                Norm += wg[i]*Ug[i]
                sampleHUg[icyc, i] = HUg[i]
                sampleS2Ug[icyc, i] = S2Ug[i]
                sampleUg[icyc, i] = Ug[i]
            #print('p0 : ',p0,'  p1 : ',p1,  '  p0 - p1 : ',p0-p1)

            sampleHUg1.append(HUg[0])
            sampleHUg2.append(HUg[1])
            #sampleHUg3.append(HUg[2])
            #sampleHUg4.append(HUg[3])
            sampleS2Ug1.append(S2Ug[0])
            sampleS2Ug2.append(S2Ug[1])
            #sampleS2Ug3.append(S2Ug[2])
            #sampleS2Ug4.append(S2Ug[3])
            sampleUg1.append(Ug[0])
            sampleUg2.append(Ug[1])
            #sampleUg3.append(Ug[2])
            #sampleUg4.append(Ug[3])

            ### Energy calculation <HP>/<P> and <S**2P>/<P> ###
            Ephf = 0
            for i in range(Ng):
                Ephf += wg[i]*HUg[i]/Norm
                S2 += wg[i]*S2Ug[i]/Norm
            # print(" <S**2> = ", S2, '\n')
            Ephf += coef0_H
            S2 += coef0_S2
            sampleEn[icyc, 0] = Ephf
            sampleS2[icyc, 0] = S2
            # print(" <E[PHF]> (Nsample = ",i_sample,") = ", Ephf)
        #print(f"(n_sample = {i_sample}):  sample HUg1\n",sampleHUg1)
        #print(f"(n_sample = {i_sample}):  sample HUg2\n",sampleHUg2)
        #print(f"(n_sample = {i_sample}):  sample HUg3\n",sampleHUg3)
        #print(f"(n_sample = {i_sample}):  sample HUg4\n",sampleHUg4)
        #print(f"(n_sample = {i_sample}):  sample S2Ug1\n",sampleS2Ug1)
        #print(f"(n_sample = {i_sample}):  sample S2Ug2\n",sampleS2Ug2)
        #print(f"(n_sample = {i_sample}):  sample S2Ug3\n",sampleS2Ug3)
        #print(f"(n_sample = {i_sample}):  sample S2Ug4\n",sampleS2Ug4)
        #print(f"(n_sample = {i_sample}):  sample Ug1\n",sampleUg1)
        #print(f"(n_sample = {i_sample}):  sample Ug2\n",sampleUg2)
        #print(f"(n_sample = {i_sample}):  sample Ug3\n",sampleUg3)
        #print(f"(n_sample = {i_sample}):  sample Ug4\n",sampleUg4)
        #print(f"(n_sample = {i_sample}):  sample HUg1\n",sampleHUg1)
        #print(f"(n_sample = {i_sample}):  sample HUg2\n",sampleHUg2)
        #print(f"(n_sample = {i_sample}):  sample HUg3\n",sampleHUg3)
        #print(f"(n_sample = {i_sample}):  sample HUg4\n",sampleHUg4)
        #print(f"(n_sample = {i_sample}):  sample En\n",sampleEn)
        #print(f"(n_sample = {i_sample}):  sample S2\n",sampleS2)
        with open(f"./Ug_{i_sample}.csv", "w") as fUg:
            writer = csv.writer(fUg)
            writer.writerows(sampleUg)
        with open(f"./HUg_{i_sample}.csv", "w") as fHUg:
            writer = csv.writer(fHUg)
            writer.writerows(sampleHUg)
        with open(f"./S2Ug_{i_sample}.csv", "w") as fS2Ug:
            writer = csv.writer(fS2Ug)
            writer.writerows(sampleS2Ug)
        with open(f"./En_{i_sample}.csv", "w") as fEn:
            writer = csv.writer(fEn)
            writer.writerows(sampleEn)
        with open(f"./S2_{i_smaple}.csv", "w") as fS2:
            writer = csv.writer(fS2)
            writer.writerows(sampleS2)
    return Ephf, S2
Ejemplo n.º 18
0
def time_evolution_circuit_improved(g_list,
                                    t,
                                    kickback_phase,
                                    k,
                                    n_trotter_step=1):
    n_qubits = 3
    a_idx = 2
    phi = -(t / n_trotter_step) * g_list
    # print(phi)
    circuit = QuantumCircuit(n_qubits)
    circuit.add_H_gate(a_idx)
    # Apply kickback phase rotation to ancilla bit
    circuit.add_RZ_gate(a_idx, -np.pi * kickback_phase / 2)
    for _ in range(n_trotter_step):
        for _ in range(2**k):
            # CU(Z0)
            circuit.add_RZ_gate(0, -phi[0])
            circuit.add_CNOT_gate(a_idx, 0)
            circuit.add_RZ_gate(0, phi[0])
            circuit.add_CNOT_gate(a_idx, 0)

            # CU(Y0 Y1)
            circuit.add_S_gate(0)
            circuit.add_S_gate(1)
            circuit.add_H_gate(0)
            circuit.add_H_gate(1)
            circuit.add_CNOT_gate(1, 0)
            circuit.add_RZ_gate(0, -phi[1])
            circuit.add_CNOT_gate(a_idx, 0)
            circuit.add_RZ_gate(0, phi[1])
            circuit.add_CNOT_gate(a_idx, 0)
            circuit.add_CNOT_gate(1, 0)
            circuit.add_H_gate(0)
            circuit.add_H_gate(1)
            circuit.add_Sdag_gate(0)
            circuit.add_Sdag_gate(1)

            # CU(Z1)
            circuit.add_RZ_gate(1, -phi[2])
            circuit.add_CNOT_gate(a_idx, 1)
            circuit.add_RZ_gate(1, phi[2])
            circuit.add_CNOT_gate(a_idx, 1)

            # CU(X0 X1)
            circuit.add_H_gate(0)
            circuit.add_H_gate(1)
            circuit.add_CNOT_gate(1, 0)
            circuit.add_RZ_gate(0, -phi[3])
            circuit.add_CNOT_gate(a_idx, 0)
            circuit.add_RZ_gate(0, phi[3])
            circuit.add_CNOT_gate(a_idx, 0)
            circuit.add_CNOT_gate(1, 0)
            circuit.add_H_gate(0)
            circuit.add_H_gate(1)

    circuit.add_H_gate(a_idx)
    return circuit
Ejemplo n.º 19
0
def adaptive_sample_observable(state, obs, n_sample):
    """
    Args:
        state (qulacs.QuantumState):
        obs (qulacs.Observable)
        n_sample (int):  number of samples for each observable
    Return:
        :float: sampled expectation value of the observable
    """
    n_term = obs.get_term_count()
    n_qubits = obs.get_qubit_count()

    exp = 0
    buf_state = QuantumState(n_qubits)

    ### check the coefficients for each term...
    coef_list = np.array([abs(obs.get_term(i).get_coef())
                          for i in range(n_term)])
    sum_coef = np.sum(coef_list)

    ### sort
    sorted_indices = np.argsort(-coef_list)
    coef_list.sort()
    #sorted_coef_list = [coef_list[i] for i in sorted_indices]
    ### determine sampling wight
    n_sample_total = n_sample*n_term
    n_sample_list = n_sample_total*coef_list//sum_coef
    n_count = np.sum(n_sample_list)
    n_rest = n_sample_total - n_count
    n_sample_list[sorted_indices[:n_rest]] += 1

    j = 0
    for i in range(n_term):
        if n_sample_list[i] == 0:
            continue
        j += n_sample_list[i]

        pauli_term = obs.get_term(i)
        coef = pauli_term.get_coef()
        pauli_id = pauli_term.get_pauli_id_list()
        pauli_index = pauli_term.get_index_list()

        if len(pauli_id) == 0:  # means identity
            exp += coef
            continue

        buf_state.load(state)
        measurement_circuit = QuantumCircuit(n_qubits)
        mask = "".join(["1" if n_qubits - 1 - k in pauli_index else "0"
                        for k in range(n_qubits)])
        for single_pauli, index in zip(pauli_id, pauli_index):
            if single_pauli == 1:
                measurement_circuit.add_H_gate(index)
            elif single_pauli == 2:
                measurement_circuit.add_Sdag_gate(index)
                measurement_circuit.add_H_gate(index)
        measurement_circuit.update_quantum_state(buf_state)
        samples = buf_state.sampling(n_sample_list[i])
        mask = int(mask, 2)
        exp += (coef
                *sum(list(map(lambda x: (-1)**(bin(x & mask).count("1")),
                              samples)))
                /n_sample_list[i])
    return exp
Ejemplo n.º 20
0
    def create_input_gate(self, x, uin_type):
        # Encode x into quantum state
        # uin_type: unitary data-input type 0, 1, 20, 21, 30, 31, 40, 41, 50, 51, 60, 61
        # x = 1dim. variables, [-1,1]

        I_mat = np.eye(2, dtype=complex)
        X_mat = X(0).get_matrix()
        Y_mat = Y(0).get_matrix()
        Z_mat = Z(0).get_matrix()

        #make operators s.t. exp(i*theta * sigma^z_j@sigma^z_k)   @:tensor product
        def ZZ(u, theta, j, k):
            u.add_CNOT_gate(j, k)
            u.add_RZ_gate(k, -2 * theta * self.time_step)
            u.add_CNOT_gate(j, k)
            return u

        def XX(u, theta, j, k):
            u.add_H_gate(j)
            u.add_H_gate(k)
            ZZ(u, theta, j, k)
            u.add_H_gate(j)
            u.add_H_gate(k)
            return u

        def YY(u, theta, j, k):
            u.add_U1_gate(j, -np.pi / 2.)
            u.add_U1_gate(k, -np.pi / 2.)
            XX(u, theta, j, k)
            u.add_U1_gate(j, np.pi / 2.)
            u.add_U1_gate(k, np.pi / 2.)
            return u

        theta = x

        u = QuantumCircuit(self.nqubit)

        angle_y = np.arcsin(x)
        angle_z = np.arccos(x**2)

        if uin_type == 0:
            for i in range(self.nqubit):
                u.add_RY_gate(i, angle_y[i])
                u.add_RZ_gate(i, angle_z[i])

        elif uin_type == 1:
            #for d in range(2):
            for i in range(self.nqubit):
                u.add_H_gate(i)
                u.add_RY_gate(i, angle_y[i])
                u.add_RZ_gate(i, angle_z[i])
            # KT: add second order expansion
            for i in range(self.nqubit - 1):
                for j in range(i + 1, self.nqubit):
                    angle_z2 = np.arccos(x[i] * x[j])
                    u.add_CNOT_gate(i, j)
                    u.add_RZ_gate(j, angle_z2)
                    u.add_CNOT_gate(i, j)

        elif uin_type == 20:
            for i in range(self.nqubit):
                u.add_RX_gate(i, -2 * x[i] * self.time_step)

        elif uin_type == 21:
            ham = np.zeros((2**self.nqubit, 2**self.nqubit), dtype=complex)
            for i in range(self.nqubit):  # i runs 0 to nqubit-1
                J_x = x[i]
                print(x)
                ham += J_x * make_fullgate([[i, X_mat]], self.nqubit)

            ## Build time-evolution operator by diagonalizing the Ising hamiltonian H*P = P*D <-> H = P*D*P^dagger
            diag, eigen_vecs = np.linalg.eigh(ham)
            time_evol_op = np.dot(
                np.dot(eigen_vecs,
                       np.diag(np.exp(-1j * self.time_step * diag))),
                eigen_vecs.T.conj())  # e^-iHT

            # Convert to qulacs gate
            time_evol_gate = DenseMatrix([i for i in range(self.nqubit)],
                                         time_evol_op)
            u.add_gate(time_evol_gate)

        elif uin_type == 30:
            #Ising hamiltonian with input coefficient
            # nearest neighbor spin-conbination has interaction
            for i in range(self.nqubit):
                u.add_RX_gate(i, -2 * x[i] * self.time_step)
                ZZ(u, theta[i] * theta[(i + 1) % self.nqubit], i, i + 1)

        elif uin_type == 31:

            ham = np.zeros((2**self.nqubit, 2**self.nqubit), dtype=complex)
            for i in range(self.nqubit):
                J_x = x[i]
                ham += J_x * make_fullgate([[i, X_mat]], self.nqubit)
                J_zz = x[i] * x[(i + 1) % self.nqubit]
                ham += J_zz * make_fullgate(
                    [[i, Z_mat], [(i + 1) % self.nqubit, Z_mat]], self.nqubit)

            diag, eigen_vecs = np.linalg.eigh(ham)
            time_evol_op = np.dot(
                np.dot(eigen_vecs,
                       np.diag(np.exp(-1j * self.time_step * diag))),
                eigen_vecs.T.conj())

            time_evol_gate = DenseMatrix([i for i in range(self.nqubit)],
                                         time_evol_op)
            u.add_gate(time_evol_gate)

        elif uin_type == 40:
            #Ising hamiltonian with input coefficient
            # every two possible spin-conbination has interaction
            for i in range(self.nqubit):
                u.add_RX_gate(i, -2 * x[i] * self.time_step)
                for j in range(i + 1, self.nqubit):
                    ZZ(u, theta[i] * theta[j], i, j)

        elif uin_type == 41:

            ham = np.zeros((2**self.nqubit, 2**self.nqubit), dtype=complex)
            for i in range(self.nqubit):
                J_x = x[i]
                ham += J_x * make_fullgate([[i, X_mat]], self.nqubit)
                for j in range(i + 1, self.nqubit):
                    J_ij = x[i] * x[j]
                    ham += J_ij * make_fullgate([[i, Z_mat], [j, Z_mat]],
                                                self.nqubit)

            diag, eigen_vecs = np.linalg.eigh(ham)
            time_evol_op = np.dot(
                np.dot(eigen_vecs,
                       np.diag(np.exp(-1j * self.time_step * diag))),
                eigen_vecs.T.conj())

            time_evol_gate = DenseMatrix([i for i in range(self.nqubit)],
                                         time_evol_op)
            u.add_gate(time_evol_gate)

        elif uin_type == 50:
            #Heisenberg hamiltonian with input coefficient
            # nearest neighbor spin-conbination has interaction
            for i in range(self.nqubit):
                u.add_RX_gate(i, -2 * x[i] * self.time_step)
                XX(u, theta[i] * theta[(i + 1) % self.nqubit], i, i + 1)
                YY(u, theta[i] * theta[(i + 1) % self.nqubit], i, i + 1)
                ZZ(u, theta[i] * theta[(i + 1) % self.nqubit], i, i + 1)

        elif uin_type == 51:

            ham = np.zeros((2**self.nqubit, 2**self.nqubit), dtype=complex)
            for i in range(self.nqubit):
                J_x = x[i]
                ham += J_x * make_fullgate([[i, X_mat]], self.nqubit)

                J_xx = x[i] * x[(i + 1) % self.nqubit]
                J_yy = x[i] * x[(i + 1) % self.nqubit]
                J_zz = x[i] * x[(i + 1) % self.nqubit]
                ham += J_xx * make_fullgate(
                    [[i, X_mat], [(i + 1) % self.nqubit, X_mat]], self.nqubit)
                ham += J_yy * make_fullgate(
                    [[i, Y_mat], [(i + 1) % self.nqubit, Y_mat]], self.nqubit)
                ham += J_xx * make_fullgate(
                    [[i, Z_mat], [(i + 1) % self.nqubit, Z_mat]], self.nqubit)

            diag, eigen_vecs = np.linalg.eigh(ham)
            time_evol_op = np.dot(
                np.dot(eigen_vecs,
                       np.diag(np.exp(-1j * self.time_step * diag))),
                eigen_vecs.T.conj())

            time_evol_gate = DenseMatrix([i for i in range(self.nqubit)],
                                         time_evol_op)
            u.add_gate(time_evol_gate)

        elif uin_type == 60:
            #Heisenberg hamiltonian with input coefficient
            # every two possible spin-conbination has interaction
            for i in range(self.nqubit):
                u.add_RX_gate(i, -2 * x[i] * self.time_step)
                for j in range(i + 1, self.nqubit):
                    XX(u, theta[i] * theta[j], i, j)
                    YY(u, theta[i] * theta[j], i, j)
                    ZZ(u, theta[i] * theta[j], i, j)

        elif uin_type == 61:

            ham = np.zeros((2**self.nqubit, 2**self.nqubit), dtype=complex)
            for i in range(self.nqubit):
                J_x = x[i]
                ham += J_x * make_fullgate([[i, X_mat]], self.nqubit)

                for j in range(i + 1, self.nqubit):
                    J_xx = x[i] * x[j]
                    J_yy = x[i] * x[j]
                    J_zz = x[i] * x[j]
                    ham += J_xx * make_fullgate([[i, X_mat], [j, X_mat]],
                                                self.nqubit)
                    ham += J_yy * make_fullgate([[i, Y_mat], [j, Y_mat]],
                                                self.nqubit)
                    ham += J_xx * make_fullgate([[i, Z_mat], [j, Z_mat]],
                                                self.nqubit)

            diag, eigen_vecs = np.linalg.eigh(ham)
            time_evol_op = np.dot(
                np.dot(eigen_vecs,
                       np.diag(np.exp(-1j * self.time_step * diag))),
                eigen_vecs.T.conj())

            time_evol_gate = DenseMatrix([i for i in range(self.nqubit)],
                                         time_evol_op)
            u.add_gate(time_evol_gate)

        else:
            pass

        return u