Ejemplo n.º 1
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.º 2
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.º 3
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