Пример #1
0
def S2Proj(Quket, Q, threshold=1e-8):
    """Function
    Perform spin-projection to QuantumState |Q>
            |Q'>  =  Ps |Q>
    where Ps is a spin-projection operator (non-unitary).
            Ps = \sum_i^ng   wg[i] Ug[i]
    This function provides a shortcut to |Q'>, which is unreal.
    One actually needs to develop a quantum circuit for this
    (See PRR 2, 043142 (2020)).

    Author(s): Takashi Tsuchimochi
    """
    spin = Quket.projection.spin
    s = (spin - 1) / 2
    Ms = Quket.projection.Ms / 2

    n_qubits = Q.get_qubit_count()
    state_P = QuantumState(n_qubits)
    state_P.multiply_coef(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)
    for ialpha in range(nalpha):
        alpha = Quket.projection.sp_angle[0][ialpha]
        alpha_coef = Quket.projection.sp_weight[0][ialpha] * np.exp(
            1j * alpha * Ms)

        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] *
                              np.exp(1j * gamma * Ms))

                # Total Weight
                coef = (2 * s + 1) / (8 * np.pi) * (alpha_coef * beta_coef *
                                                    gamma_coef)

                state_g = QuantumState(n_qubits)
                state_g.load(Q)
                circuit_Rg = QuantumCircuit(n_qubits)
                set_circuit_Rg(circuit_Rg, n_qubits, alpha, beta, gamma)
                circuit_Rg.update_quantum_state(state_g)
                state_g.multiply_coef(coef)
                state_P.add_state(state_g)

    # Normalize
    norm2 = state_P.get_squared_norm()
    if norm2 < threshold:
        error(
            "Norm of spin-projected state is too small!\n",
            "This usually means the broken-symmetry state has NO component ",
            "of the target spin.")
    state_P.normalize(norm2)
    # print_state(state_P,name="P|Q>",threshold=1e-6)
    return state_P
Пример #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)
Пример #3
0
def __qulacs_measure_shots(qstate, qid, shots=1):

    # error check
    qubit_num = qstate.get_qubit_count()
    if max(qid) >= qubit_num:
        raise ValueError

    # list of binary vectors for len(qid) bit integers
    qid_sorted = sorted(qid)
    mbits_list = []
    for i in range(2**len(qid)):
        # ex)
        # qid = [5,0,2] -> qid_sorted = [0,2,5]
        # i = (0,1,2), idx = (2,0,1)
        # bits = [q0,q1,q2] -> mbits = [q1,q2,q0]
        bits = list(map(int, list(format(i, '0{}b'.format(len(qid))))))
        mbits = [0] * len(qid)
        for i, q in enumerate(qid):
            idx = qid_sorted.index(q)
            mbits[idx] = bits[i]
        mbits_list.append(mbits)

    # list of probabilities
    prob_list = []
    prob = 0.0
    for mbits in mbits_list:
        args = [2] * qubit_num
        for j, q in enumerate(qid):
            args[q] = mbits[j]
        prob += qstate.get_marginal_probability(args)
        prob_list.append(prob)
    if prob_list[-1] != 1.0:
        prob_list[-1] = 1.0

    # frequency
    mval_data = []
    if shots > 1:
        for i in range(shots - 1):
            rand = random.random()
            for mbits, prob in zip(mbits_list, prob_list):
                if rand <= prob:
                    mval = ''.join(map(str, mbits))
                    mval_data.append(mval)
                    break

    # last quantum state
    circ = QuantumCircuit(qubit_num)
    for i, q in enumerate(qid):
        circ.add_gate(Measurement(q, i))
    circ.update_quantum_state(qstate)

    last = ''.join(
        map(str, [qstate.get_classical_value(i) for i in range(len(qid))]))
    mval_data.append(last)

    frequency = Counter(mval_data)

    return frequency, qstate
Пример #4
0
def calc_psi_lessH(psi_dash, n, index, a, id_set):
    circuit = QuantumCircuit(n)
    for i, a_i in enumerate(a):
        if abs(a_i) > 0:
            pauli_id = id_set[i]
            gate = PauliRotation(index, pauli_id, a_i * (-2))
            circuit.add_gate(gate)
    circuit.update_quantum_state(psi_dash)
    norm = psi_dash.get_squared_norm()
    psi_dash.normalize(norm)
    return psi_dash
Пример #5
0
 def _simulate_on_qulacs(
     self,
     data: _StateAndBuffer,
     shape: tuple,
     qulacs_state: qulacs.QuantumState,
     qulacs_circuit: qulacs.QuantumCircuit,
 ) -> None:
     data.buffer = data.state
     cirq_state = np.array(data.state).flatten().astype(np.complex64)
     qulacs_state.load(cirq_state)
     qulacs_circuit.update_quantum_state(qulacs_state)
     data.state = qulacs_state.get_vector().reshape(shape)
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()
Пример #7
0
def __qulacs_measure(qstate, qubit_num, q):

    # error check
    if q >= qubit_num:
        raise ValueError("measurement qubit id is out of bound")

    circ = QuantumCircuit(qubit_num)
    circ.add_gate(Measurement(q, 0))
    circ.update_quantum_state(qstate)
    mval = qstate.get_classical_value(0)

    return mval
Пример #8
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)
Пример #9
0
def __qulacs_reset(qstate, qubit_num, q):

    # error check
    if q >= qubit_num:
        raise ValueError("reset qubit id is out of bound")

    circ = QuantumCircuit(qubit_num)
    circ.add_gate(Measurement(q, 0))
    circ.update_quantum_state(qstate)
    circ_flip = QuantumCircuit(qubit_num)
    if qstate.get_classical_value(0) == 1:
        circ_flip.add_gate(X(q))
        circ_flip.update_quantum_state(qstate)
Пример #10
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
Пример #11
0
 def test_add_same_gate_multiple_time(self):
     from qulacs import QuantumCircuit, QuantumState
     from qulacs.gate import X, DepolarizingNoise, DephasingNoise, Probabilistic, RX
     state = QuantumState(1)
     circuit = QuantumCircuit(1)
     noise = DepolarizingNoise(0, 0)
     circuit.add_gate(noise)
     circuit.add_gate(noise.copy())
     circuit.add_gate(DephasingNoise(0, 0))
     circuit.add_gate(Probabilistic([0.1], [RX(0, 0)]))
     gate = RX(0, 0)
     circuit.add_gate(gate)
     circuit.add_gate(gate)
     circuit.add_gate(gate)
     circuit.add_gate(gate)
     circuit.add_gate(gate)
     del gate
     circuit.update_quantum_state(state)
     circuit.update_quantum_state(state)
     circuit.update_quantum_state(state)
     circuit.update_quantum_state(state)
     circuit.update_quantum_state(state)
     circuit.update_quantum_state(state)
     circuit.update_quantum_state(state)
     circuit.to_string()
     del circuit
     del state
Пример #12
0
    def test_circuit_add_gate(self):
        from qulacs import QuantumCircuit, QuantumState
        from qulacs.gate import Identity, X, Y, Z, H, S, Sdag, T, Tdag, sqrtX, sqrtXdag, sqrtY, sqrtYdag
        from qulacs.gate import P0, P1, U1, U2, U3, RX, RY, RZ, CNOT, CZ, SWAP, TOFFOLI, FREDKIN, Pauli, PauliRotation
        from qulacs.gate import DenseMatrix, SparseMatrix, DiagonalMatrix, RandomUnitary, ReversibleBoolean, StateReflection
        from qulacs.gate import BitFlipNoise, DephasingNoise, IndependentXZNoise, DepolarizingNoise, TwoQubitDepolarizingNoise, AmplitudeDampingNoise, Measurement
        from qulacs.gate import merge, add, to_matrix_gate, Probabilistic, CPTP, Instrument, Adaptive
        from scipy.sparse import lil_matrix
        qc = QuantumCircuit(3)
        qs = QuantumState(3)
        ref = QuantumState(3)
        sparse_mat = lil_matrix((4, 4))
        sparse_mat[0, 0] = 1
        sparse_mat[1, 1] = 1

        def func(v, d):
            return (v + 1) % d

        def adap(v):
            return True

        gates = [
            Identity(0), X(0), Y(0), Z(0), H(0), S(0), Sdag(0), T(0), Tdag(0), sqrtX(0), sqrtXdag(0), sqrtY(0), sqrtYdag(0),
            Probabilistic([0.5, 0.5], [X(0), Y(0)]), CPTP([P0(0), P1(0)]), Instrument([P0(0), P1(0)], 1), Adaptive(X(0), adap),
            CNOT(0, 1), CZ(0, 1), SWAP(0, 1), TOFFOLI(0, 1, 2), FREDKIN(0, 1, 2), Pauli([0, 1], [1, 2]), PauliRotation([0, 1], [1, 2], 0.1),
            DenseMatrix(0, np.eye(2)), DenseMatrix([0, 1], np.eye(4)), SparseMatrix([0, 1], sparse_mat),
            DiagonalMatrix([0, 1], np.ones(4)), RandomUnitary([0, 1]), ReversibleBoolean([0, 1], func), StateReflection(ref),
            BitFlipNoise(0, 0.1), DephasingNoise(0, 0.1), IndependentXZNoise(0, 0.1), DepolarizingNoise(0, 0.1), TwoQubitDepolarizingNoise(0, 1, 0.1),
            AmplitudeDampingNoise(0, 0.1), Measurement(0, 1), merge(X(0), Y(1)), add(X(0), Y(1)), to_matrix_gate(X(0)),
            P0(0), P1(0), U1(0, 0.), U2(0, 0., 0.), U3(0, 0., 0., 0.), RX(0, 0.), RY(0, 0.), RZ(0, 0.),
        ]
        gates.append(merge(gates[0], gates[1]))
        gates.append(add(gates[0], gates[1]))

        ref = None
        for gate in gates:
            qc.add_gate(gate)

        for gate in gates:
            qc.add_gate(gate)

        qc.update_quantum_state(qs)
        qc = None
        qs = None
        for gate in gates:
            gate = None

        gates = None
        parametric_gates = None
Пример #13
0
def __qulacs_operate_qgate(qstate, qubit_num, kind, qid, phase, phase1,
                           phase2):

    if __is_supported_qgate(kind) is False:
        raise ValueError("not supported quantum gate")

    circ = QuantumCircuit(qubit_num)

    term_num = get_qgate_qubit_num(kind)
    para_num = get_qgate_param_num(kind)
    gate_function_name = GateFunctionName[kind]

    phase = phase * np.pi
    phase1 = phase1 * np.pi
    phase2 = phase2 * np.pi

    # the sign-definition of rotation gate on qulacs
    if (kind in (cfg.ROTATION_X, cfg.ROTATION_Y, cfg.ROTATION_Z,
                 cfg.CONTROLLED_RX, cfg.CONTROLLED_RY, cfg.CONTROLLED_RZ)):
        phase = -phase
    # the argument-order-definition of U2 gate on qulacs
    elif kind in (cfg.ROTATION_U2, cfg.CONTROLLED_U2):
        phase1, phase = phase, phase1
    # the argument-order-definition of U3 gate on qulacs
    elif kind in (cfg.ROTATION_U3, cfg.CONTROLLED_U3):
        phase2, phase = phase, phase2

    if term_num == 1 and para_num == 0:
        circ.add_gate(eval(gate_function_name)(qid[0]))
    elif term_num == 1 and para_num == 1:
        circ.add_gate(eval(gate_function_name)(qid[0], phase))
    elif term_num == 1 and para_num == 2:
        circ.add_gate(eval(gate_function_name)(qid[0], phase, phase1))
    elif term_num == 1 and para_num == 3:
        circ.add_gate(eval(gate_function_name)(qid[0], phase, phase1, phase2))
    elif term_num == 2 and para_num == 0:
        circ.add_gate(eval(gate_function_name)(qid[0], qid[1]))
    elif term_num == 2 and para_num == 1:
        circ.add_gate(eval(gate_function_name)(qid[0], qid[1], phase))
    elif term_num == 2 and para_num == 2:
        circ.add_gate(eval(gate_function_name)(qid[0], qid[1], phase, phase1))
    elif term_num == 2 and para_num == 3:
        circ.add_gate(
            eval(gate_function_name)(qid[0], qid[1], phase, phase1, phase2))
    else:
        raise ValueError("not supported terminal or parameter-number")

    circ.update_quantum_state(qstate)
Пример #14
0
def qtest(angle):
    state = QuantumState(3)
    state.set_Haar_random_state()
    circuit = QuantumCircuit(3)
    circuit.add_X_gate(0)
    merged_gate = merge(CNOT(0, 1), Y(1))
    circuit.add_gate(merged_gate)
    circuit.add_RX_gate(1, angle)
    circuit.update_quantum_state(state)
    observable = Observable(3)
    observable.add_operator(2.0, "X 2 Y 1 Z 0")
    observable.add_operator(-3.0, "Z 2")
    result = observable.get_expectation_value(state)

    output = {'energy': result}
    return (output)
Пример #15
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
Пример #16
0
def test_ibm_gateset() -> None:
    state = QuantumState(3)
    state.set_zero_state()
    circ = Circuit(3)
    circ.add_gate(OpType.U1, 0.19, [0])
    circ.add_gate(OpType.U2, [0.19, 0.24], [1])
    circ.add_gate(OpType.U3, [0.19, 0.24, 0.32], [2])
    qulacs_circ = tk_to_qulacs(circ)
    qulacs_circ.update_quantum_state(state)

    state1 = QuantumState(3)
    state1.set_zero_state()
    qulacs_circ1 = QuantumCircuit(3)
    qulacs_circ1.add_U1_gate(0, 0.19 * np.pi)
    qulacs_circ1.add_U2_gate(1, 0.19 * np.pi, 0.24 * np.pi)
    qulacs_circ1.add_U3_gate(2, 0.19 * np.pi, 0.24 * np.pi, 0.32 * np.pi)
    qulacs_circ1.update_quantum_state(state1)
    overlap = inner_product(state1, state)
    assert np.isclose(1, overlap)
Пример #17
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
Пример #18
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)
Пример #19
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)
Пример #20
0
def NProj(Quket, Q, threshold=1e-8):
    """Function
    Perform number-projection to QuantumState |Q>
            |Q'>  =  PN |Q>
    where PN is a number-projection operator (non-unitary).
            PN = \sum_i^ng   wg[i] Ug[i]
    This function provides a shortcut to |Q'>, which is unreal.
    One actually needs to develop a quantum circuit for this
    (See QST 6, 014004 (2021)).

    Author(s): Takashi Tsuchimochi
    """
    n_qubits = Q.get_qubit_count()
    state_P = QuantumState(n_qubits)
    state_P.multiply_coef(0)
    state_g = QuantumState(n_qubits)
    nphi = max(Quket.projection.number_ngrids, 1)
    #print_state(Q)
    for iphi in range(nphi):
        coef = (Quket.projection.np_weight[iphi] *
                np.exp(1j * Quket.projection.np_angle[iphi] *
                       (Quket.projection.n_active_electrons -
                        Quket.projection.n_active_orbitals)))

        state_g = Q.copy()
        circuit = QuantumCircuit(n_qubits)
        set_circuit_ExpNa(circuit, n_qubits, Quket.projection.np_angle[iphi])
        set_circuit_ExpNb(circuit, n_qubits, Quket.projection.np_angle[iphi])
        circuit.update_quantum_state(state_g)
        state_g.multiply_coef(coef)
        state_P.add_state(state_g)

    norm2 = state_P.get_squared_norm()
    if norm2 < threshold:
        error(
            "Norm of number-projected state is too small!\n",
            "This usually means the broken-symmetry state has NO component ",
            "of the target number.")
    state_P.normalize(norm2)
    return state_P
Пример #21
0
    def apply_circuit(self, x, theta):
        """
        Apply unitary gates U(x) and U(theta) to |0>
        
        Argument:
        x: dx1 numpy array (vector), the sample vector to be encoded.
        theta: n_qubitsx(3*D) numpy array, the decision variables.
        
        Return:
        circuit: quantum state after applying the circuit with the given theta.
        """

        state = QuantumState(self.n_qubits)
        state.set_zero_state()

        # Construct a circuit
        circuit = QuantumCircuit(self.n_qubits)
        circuit = self.unitary_x(circuit, x)
        circuit = self.unitary_theta(circuit, theta)

        # apply the circuit to the zero state
        circuit.update_quantum_state(state)
        return state
Пример #22
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
Пример #23
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
Пример #24
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
Пример #25
0
observable = Observable(nqubit)
observable.add_operator(1, "Z 0")
observable.add_operator(2, "Z 1")
#observable.add_operator(4, "Z 2")

data = list()
x_value = list()
y_value = list()

for i in range(n_data):
    #state.set_Haar_random_state()
    x = random.random()
    state.set_zero_state() # U_in|000>
    U_in(x).update_quantum_state(state)
    state_vec = state.get_vector()
    circuit.update_quantum_state(state)
    value = observable.get_expectation_value(state)
    #print(value)
#    data.append((state_vec, value))
    data.append((x, value))
    x_value.append(x)
    y_value.append(value)

with open('Training.data', 'wb') as f:
    pickle.dump(data, f)

plt.plot(x_value, y_value, 'o', color='black')
plt.show()
plt.savefig('qcl_training.png')
Пример #26
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
Пример #27
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
Пример #28
0
import matplotlib.pyplot as plt

obs = Observable(1)
obs.add_operator(1, "Z 0")
state = QuantumState(1)
circuit = QuantumCircuit(1)
p = 0.1  # probability of bit flip
n_circuit_sample = 10000
n_depth = 20  # the number of probabilistic gate

probabilistic_pauli_gate = Probabilistic([p],
                                         [X(0)])  #define probabilistic gate

circuit.add_gate(probabilistic_pauli_gate)  # add the prob. gate to the circuit

exp_array = []
for depth in range(n_depth):
    exp = 0
    for i in [0] * n_circuit_sample:
        state.set_zero_state()
        for _ in range(depth):
            circuit.update_quantum_state(state)  # apply the prob. gate
        exp += obs.get_expectation_value(
            state)  # get expectation value for one sample of circuit
    exp /= n_circuit_sample  # get overall average
    exp_array.append(exp)

#plot
plt.plot(range(n_depth), exp_array)
plt.show()
Пример #29
0
class QulacsDevice(Device):
    """Qulacs device"""
    name = 'Qulacs device'
    short_name = 'qulacs.simulator'
    pennylane_requires = '>=0.5.0'
    version = __version__
    author = 'Steven Oud'

    _capabilities = {'model': 'qubit', 'tensor_observables': True}

    _operations_map = {
        'QubitStateVector': None,
        'BasisState': None,
        'QubitUnitary': None,
        'Toffoli': toffoli,
        'CSWAP': CSWAP,
        'CRZ': crz,
        'Rot': None,
        'SWAP': gate.SWAP,
        'CNOT': gate.CNOT,
        'CZ': gate.CZ,
        'S': gate.S,
        'Sdg': gate.Sdag,
        'T': gate.T,
        'Tdg': gate.Tdag,
        'RX': gate.RX,
        'RY': gate.RY,
        'RZ': gate.RZ,
        'PauliX': gate.X,
        'PauliY': gate.Y,
        'PauliZ': gate.Z,
        'Hadamard': gate.H
    }
    _observable_map = {
        'PauliX': X,
        'PauliY': Y,
        'PauliZ': Z,
        'Hadamard': H,
        'Identity': I,
        'Hermitian': hermitian
    }

    operations = _operations_map.keys()
    observables = _observable_map.keys()

    def __init__(self, wires, gpu=False, **kwargs):
        super().__init__(wires=wires)

        if gpu:
            if not GPU_SUPPORTED:
                raise DeviceError(
                    'GPU not supported with installed version of qulacs. '
                    'Please install "qulacs-gpu" to use GPU simulation.')

            self._state = QuantumStateGpu(wires)
        else:
            self._state = QuantumState(wires)

        self._circuit = QuantumCircuit(wires)
        self._first_operation = True

    def apply(self, operation, wires, par):
        par = np.negative(par)
        if operation == 'BasisState' and not self._first_operation:
            raise DeviceError(
                'Operation {} cannot be used after other Operations have already been applied '
                'on a {} device.'.format(operation, self.short_name))

        self._first_operation = False

        if operation == 'QubitStateVector':
            if len(par[0]) != 2**len(wires):
                raise ValueError('State vector must be of length 2**wires.')

            self._state.load(par[0])
        elif operation == 'BasisState':
            if len(par[0]) != len(wires):
                raise ValueError('Basis state must prepare all qubits.')

            basis_state = 0
            for bit in reversed(par[0]):
                basis_state = (basis_state << 1) | bit

            self._state.set_computational_basis(basis_state)
        elif operation == 'QubitUnitary':
            if len(par[0]) != 2**len(wires):
                raise ValueError(
                    'Unitary matrix must be of shape (2**wires, 2**wires).')

            unitary_gate = gate.DenseMatrix(wires, par[0])
            self._circuit.add_gate(unitary_gate)
        elif operation == 'Rot':
            self._circuit.add_gate(
                gate.merge([
                    gate.RZ(wires[0], par[0]),
                    gate.RY(wires[0], par[1]),
                    gate.RZ(wires[0], par[2])
                ]))
        elif operation in ('CRZ', 'Toffoli', 'CSWAP'):
            mapped_operation = self._operations_map[operation]
            if callable(mapped_operation):
                gate_matrix = mapped_operation(*par)
            else:
                gate_matrix = mapped_operation

            dense_gate = gate.DenseMatrix(wires, gate_matrix)
            self._circuit.add_gate(dense_gate)
        else:
            mapped_operation = self._operations_map[operation]
            self._circuit.add_gate(mapped_operation(*wires, *par))

    @property
    def state(self):
        return self._state.get_vector()

    def pre_measure(self):
        self._circuit.update_quantum_state(self._state)

    def expval(self, observable, wires, par):
        bra = self._state.copy()

        if isinstance(observable, list):
            A = self._get_tensor_operator_matrix(observable, par)
            wires = [item for sublist in wires for item in sublist]
        else:
            A = self._get_operator_matrix(observable, par)

        dense_gate = gate.DenseMatrix(wires, A)
        dense_gate.update_quantum_state(self._state)

        expectation = inner_product(bra, self._state)

        return expectation.real

    def probabilities(self):
        states = itertools.product(range(2), repeat=self.num_wires)
        probs = np.abs(self.state)**2

        return OrderedDict(zip(states, probs))

    def reset(self):
        self._state.set_zero_state()
        self._circuit = QuantumCircuit(self.num_wires)

    def _get_operator_matrix(self, operation, par):
        A = self._observable_map[operation]
        if not callable(A):
            return A

        return A(*par)

    def _get_tensor_operator_matrix(self, obs, par):
        ops = [self._get_operator_matrix(o, p) for o, p in zip(obs, par)]
        return functools.reduce(np.kron, ops)