Пример #1
0
def set_circuit_bcs(ansatz, n_qubits, n_orbitals, ndim1, ndim, theta_list, k):
    circuit = QuantumCircuit(n_qubits)
    target_list = np.empty(2)
    pauli_index = np.empty(2)
    for i in range(k):
        ioff = i * ndim
        for p in range(n_orbitals):
            pa = 2 * p
            pb = 2 * p + 1
            target_list = pa, pb

            pauli_index = 1, 2
            gate = PauliRotation(target_list, pauli_index,
                                 -theta_list[p + ioff])
            circuit.add_gate(gate)

            pauli_index = 2, 1
            gate = PauliRotation(target_list, pauli_index,
                                 -theta_list[p + ioff])
            circuit.add_gate(gate)

            if "ebcs" in ansatz:
                if p < n_orbitals - 1:
                    circuit.add_CNOT_gate(pa, pa + 2)
                    circuit.add_CNOT_gate(pb, pb + 2)
        upcc_Gsingles(circuit, n_orbitals, theta_list, ndim1, n_orbitals, i)
    return circuit
Пример #2
0
 def test_pointer_del(self):
     from qulacs import QuantumCircuit
     from qulacs.gate import X
     qc = QuantumCircuit(1)
     gate = X(0)
     qc.add_gate(gate)
     del gate
     del qc
Пример #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 test_add_gate(self):
     from qulacs import QuantumCircuit
     from qulacs.gate import X
     circuit = QuantumCircuit(1)
     gate = X(0)
     circuit.add_gate(gate)
     del gate
     s = circuit.to_string()
     del circuit
Пример #5
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
Пример #6
0
def tk_to_qulacs(circuit: Circuit) -> QuantumCircuit:
    """ Convert a pytket circuit to a qulacs circuit object. """
    qulacs_circ = QuantumCircuit(circuit.n_qubits)
    for com in circuit:
        optype = com.op.type
        if optype in _IBM_GATES:
            qulacs_gate = _IBM_GATES[optype]
            index = com.qubits[0].index[0]

            if optype == OpType.U1:
                param = com.op.params[0]
                add_gate = qulacs_gate(index, param * np.pi)
            elif optype == OpType.U2:
                param0, param1 = com.op.params
                add_gate = qulacs_gate(index, param0 * np.pi, param1 * np.pi)
            elif optype == OpType.U3:
                param0, param1, param2 = com.op.params
                add_gate = qulacs_gate(index, param0 * np.pi, param1 * np.pi,
                                       param2 * np.pi)

        elif optype in _ONE_QUBIT_GATES:
            qulacs_gate = _ONE_QUBIT_GATES[optype]
            index = com.qubits[0].index[0]
            add_gate = qulacs_gate(index)

        elif optype in _ONE_QUBIT_ROTATIONS:
            qulacs_gate = _ONE_QUBIT_ROTATIONS[optype]
            index = com.qubits[0].index[0]
            param = com.op.params[0] * np.pi
            add_gate = qulacs_gate(index,
                                   -param)  # parameter negated for qulacs

        elif optype in _TWO_QUBIT_GATES:
            qulacs_gate = _TWO_QUBIT_GATES[optype]
            id1 = com.qubits[0].index[0]
            id2 = com.qubits[1].index[0]
            add_gate = qulacs_gate(id1, id2)

        elif optype in _MEASURE_GATES:
            continue
            # gate = _MEASURE_GATES[optype]
            # qubit = com.qubits[0].index[0]
            # bit = com.bits[0].index[0]
            # add_gate = (gate(qubit, bit))

        elif optype == OpType.Barrier:
            continue

        else:
            raise NotImplementedError(
                "Gate: {} Not Implemented in Qulacs!".format(optype))
        qulacs_circ.add_gate(add_gate)
    return qulacs_circ
Пример #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
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()
Пример #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 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
Пример #11
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)
Пример #12
0
def exp_iHt(H, t, n_qubits=None):
    """
    ハミルトニアンH = sum_i h[i] に対して、一次のTrotter近似
            Exp[-iHt] ~ Prod_i  Exp[-i h[i] t]
    を行う量子回路を生成する

    使われてない?
    """
    nterms = H.get_term_count()
    if n_qubits is None:
        n_qubits = H.get_qubit_count()

    circuit = QuantumCircuit(n_qubits)
    for i in nterms:
        h = H.get_term(i)
        circuit.add_gate(exp_iht(h, t))
    return circuit
Пример #13
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
Пример #14
0
def main():
    ## Example1
    circuit = QuantumCircuit(3)
    circuit.add_X_gate(0)
    circuit.add_Y_gate(1)
    circuit.add_Z_gate(2)
    circuit.add_dense_matrix_gate([0,1], [[1,0,0,0],[0,1,0,0],[0,0,0,1],[0,0,1,0]])
    circuit.add_CNOT_gate(2,0)
    circuit.add_X_gate(2)
    draw_circuit(circuit, verbose=1)

    ## Example2
    circuit = QuantumCircuit(3)
    circuit.add_X_gate(0)
    circuit.add_Y_gate(1)
    circuit.add_dense_matrix_gate([0,1], [[1,0,0,0],[0,1,0,0],[0,0,0,1],[0,0,1,0]])
    circuit.add_Z_gate(2)
    circuit.add_CNOT_gate(2,0)
    circuit.add_X_gate(2)
    draw_circuit(circuit, verbose=1)

    ## Example3
    circuit = QuantumCircuit(3)
    circuit.add_X_gate(1)
    circuit.add_CZ_gate(0,2)
    circuit.add_X_gate(1)
    draw_circuit(circuit)

    ## Example4
    circuit = QuantumCircuit(4)
    ##CCX0,2, 3
    cx_gate = CNOT(2,3)
    cx_mat_gate = to_matrix_gate(cx_gate)
    control_index = 0
    control_with_value = 1
    cx_mat_gate.add_control_qubit(control_index, control_with_value)
    circuit.add_gate(cx_mat_gate)
    ##CCX1,2, 3
    ccx = TOFFOLI(1,2, 3)
    circuit.add_gate(ccx)
    ##CCX1,2, 0
    ccx = TOFFOLI(1,2, 0)
    circuit.add_gate(ccx)
    ##CCX1,3, 0
    ccx = TOFFOLI(1,3, 0)
    circuit.add_gate(ccx)
    ##CCX1,3, 2
    ccx = TOFFOLI(1,3, 2)
    circuit.add_gate(ccx)
    ##SWAP0,1
    circuit.add_SWAP_gate(0,1)
    ##SWAP0,2
    circuit.add_SWAP_gate(0,2)
    ##SWAP1,3
    circuit.add_SWAP_gate(1,3)
    draw_circuit(circuit, verbose=1)

    ## Example5
    circuit = QuantumCircuit(5)
    ## 3-qubit gate applied to [0,1,2]
    mat = np.identity(2**3)
    circuit.add_dense_matrix_gate([0,1,2], mat)
    ## 3-qubit gate applied to [0,3,4], and [1] qubit is control-qubit
    c_dense_gate = DenseMatrix([0,3,4], mat)
    control_index = 1
    control_with_value = 1
    c_dense_gate.add_control_qubit(control_index, control_with_value)
    circuit.add_gate(c_dense_gate)
    ## 3-qubit gate applied to [0,2,4]
    circuit.add_dense_matrix_gate([0,2,4], mat)
    ## SWAP gate aplied to [1,3], and [2] qubit is control-qubit
    swp_gate = to_matrix_gate(SWAP(1,3))
    control_index = 2
    control_with_value = 1
    swp_gate.add_control_qubit(control_index, control_with_value)
    circuit.add_gate(swp_gate)
    draw_circuit(circuit)
Пример #15
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
Пример #16
0
    for i in range(nqubit):
        U.add_RY_gate(i, angle_y)
        U.add_RZ_gate(i, angle_z)

    return U

circuit = QuantumCircuit(nqubit)
#circuit.add_H_gate(0)
#circuit.add_H_gate(1)
#circuit.add_H_gate(2)
circuit.add_RX_gate(0, 0.1)
circuit.add_RX_gate(1, 0.1)
#circuit.add_RX_gate(2, 0.1)
merged_gate = merge(CNOT(0,1),Y(1))
circuit.add_gate(merged_gate)
meas0 = Measurement(0, 0)
circuit.add_gate(meas0)
meas1 = Measurement(1, 1)
circuit.add_gate(meas1)
#meas2 = Measurement(2, 2)
#circuit.add_gate(meas2)
print(circuit)

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()
Пример #17
0
 def copy_circuit(c):
     ret = QuantumCircuit(2)
     for i in range(c.get_gate_count()):
         gate = c.get_gate(i)
         ret.add_gate(gate)
     return ret
Пример #18
0
class QulacsDevice(QubitDevice):
    """Qulacs device"""

    name = "Qulacs device"
    short_name = "qulacs.simulator"
    pennylane_requires = ">=0.11.0"
    version = __version__
    author = "Steven Oud and Xanadu"
    gpu_supported = GPU_SUPPORTED

    _capabilities = {
        "model": "qubit",
        "tensor_observables": True,
        "inverse_operations": True
    }

    _operation_map = {
        "QubitStateVector": None,
        "BasisState": None,
        "QubitUnitary": None,
        "Toffoli": gate.TOFFOLI,
        "CSWAP": gate.FREDKIN,
        "CRZ": crz,
        "SWAP": gate.SWAP,
        "CNOT": gate.CNOT,
        "CZ": gate.CZ,
        "S": gate.S,
        "T": gate.T,
        "RX": gate.RX,
        "RY": gate.RY,
        "RZ": gate.RZ,
        "PauliX": gate.X,
        "PauliY": gate.Y,
        "PauliZ": gate.Z,
        "Hadamard": gate.H,
        "PhaseShift": phase_shift,
    }

    _observable_map = {
        "PauliX": "X",
        "PauliY": "Y",
        "PauliZ": "Z",
        "Identity": "I",
        "Hadamard": None,
        "Hermitian": None,
    }

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

    # Add inverse gates to _operation_map
    _operation_map.update({k + ".inv": v for k, v in _operation_map.items()})

    def __init__(self, wires, shots=1000, analytic=True, gpu=False, **kwargs):
        super().__init__(wires=wires, shots=shots, analytic=analytic)

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

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

        self._circuit = QuantumCircuit(self.num_wires)

        self._pre_rotated_state = self._state.copy()

    def apply(self, operations, **kwargs):
        rotations = kwargs.get("rotations", [])

        self.apply_operations(operations)
        self._pre_rotated_state = self._state.copy()

        # Rotating the state for measurement in the computational basis
        if rotations:
            self.apply_operations(rotations)

    def apply_operations(self, operations):
        """Apply the circuit operations to the state.

        This method serves as an auxiliary method to :meth:`~.QulacsDevice.apply`.

        Args:
            operations (List[pennylane.Operation]): operations to be applied
        """

        for i, op in enumerate(operations):
            if i > 0 and isinstance(op, (QubitStateVector, BasisState)):
                raise DeviceError(
                    "Operation {} cannot be used after other Operations have already been applied "
                    "on a {} device.".format(op.name, self.short_name))

            if isinstance(op, QubitStateVector):
                self._apply_qubit_state_vector(op)
            elif isinstance(op, BasisState):
                self._apply_basis_state(op)
            elif isinstance(op, QubitUnitary):
                self._apply_qubit_unitary(op)
            elif isinstance(op, (CRZ, PhaseShift)):
                self._apply_matrix(op)
            else:
                self._apply_gate(op)

    def _apply_qubit_state_vector(self, op):
        """Initialize state with a state vector"""
        wires = op.wires
        input_state = op.parameters[0]

        if len(input_state) != 2**len(wires):
            raise ValueError("State vector must be of length 2**wires.")
        if input_state.ndim != 1 or len(input_state) != 2**len(wires):
            raise ValueError("State vector must be of length 2**wires.")
        if not np.isclose(np.linalg.norm(input_state, 2), 1.0, atol=tolerance):
            raise ValueError("Sum of amplitudes-squared does not equal one.")

        input_state = _reverse_state(input_state)

        # call qulacs' state initialization
        self._state.load(input_state)

    def _apply_basis_state(self, op):
        """Initialize a basis state"""
        wires = op.wires
        par = op.parameters

        # translate from PennyLane to Qulacs wire order
        bits = par[0][::-1]
        n_basis_state = len(bits)

        if not set(bits).issubset({0, 1}):
            raise ValueError(
                "BasisState parameter must consist of 0 or 1 integers.")
        if n_basis_state != len(wires):
            raise ValueError(
                "BasisState parameter and wires must be of equal length.")

        basis_state = 0
        for bit in bits:
            basis_state = (basis_state << 1) | bit

        # call qulacs' basis state initialization
        self._state.set_computational_basis(basis_state)

    def _apply_qubit_unitary(self, op):
        """Apply unitary to state"""
        # translate op wire labels to consecutive wire labels used by the device
        device_wires = self.map_wires(op.wires)
        par = op.parameters

        if len(par[0]) != 2**len(device_wires):
            raise ValueError(
                "Unitary matrix must be of shape (2**wires, 2**wires).")

        if op.inverse:
            par[0] = par[0].conj().T

        # reverse wires (could also change par[0])
        reverse_wire_labels = device_wires.tolist()[::-1]
        unitary_gate = gate.DenseMatrix(reverse_wire_labels, par[0])
        self._circuit.add_gate(unitary_gate)
        unitary_gate.update_quantum_state(self._state)

    def _apply_matrix(self, op):
        """Apply predefined gate-matrix to state (must follow qulacs convention)"""
        # translate op wire labels to consecutive wire labels used by the device
        device_wires = self.map_wires(op.wires)
        par = op.parameters

        mapped_operation = self._operation_map[op.name]
        if op.inverse:
            mapped_operation = self._get_inverse_operation(
                mapped_operation, device_wires, par)

        if callable(mapped_operation):
            gate_matrix = mapped_operation(*par)
        else:
            gate_matrix = mapped_operation

        # gate_matrix is already in correct order => no wire-reversal needed
        dense_gate = gate.DenseMatrix(device_wires.labels, gate_matrix)
        self._circuit.add_gate(dense_gate)
        gate.DenseMatrix(device_wires.labels,
                         gate_matrix).update_quantum_state(self._state)

    def _apply_gate(self, op):
        """Apply native qulacs gate"""

        # translate op wire labels to consecutive wire labels used by the device
        device_wires = self.map_wires(op.wires)
        par = op.parameters

        mapped_operation = self._operation_map[op.name]
        if op.inverse:
            mapped_operation = self._get_inverse_operation(
                mapped_operation, device_wires, par)

        # Negating the parameters such that it adheres to qulacs
        par = np.negative(par)

        # mapped_operation is already in correct order => no wire-reversal needed
        self._circuit.add_gate(mapped_operation(*device_wires.labels, *par))
        mapped_operation(*device_wires.labels,
                         *par).update_quantum_state(self._state)

    @staticmethod
    def _get_inverse_operation(mapped_operation, device_wires, par):
        """Return the inverse of an operation"""

        if mapped_operation is None:
            return mapped_operation

        # if an inverse variant of the operation exists
        try:
            inverse_operation = getattr(gate,
                                        mapped_operation.get_name() + "dag")
        except AttributeError:
            # if the operation is hard-coded
            try:
                if callable(mapped_operation):
                    inverse_operation = np.conj(mapped_operation(*par)).T
                else:
                    inverse_operation = np.conj(mapped_operation).T

            # if mapped_operation is a qulacs.gate and np.conj is applied on it
            except TypeError:
                # else, redefine the operation as the inverse matrix
                def inverse_operation(*p):
                    # embed the gate in a unitary matrix with shape (2**wires, 2**wires)
                    g = mapped_operation(*p).get_matrix()
                    mat = reduce(np.kron, [np.eye(2)] *
                                 len(device_wires)).astype(complex)
                    mat[-len(g):, -len(g):] = g

                    # mat follows PL convention => reverse wire-order
                    reverse_wire_labels = device_wires.tolist()[::-1]
                    gate_mat = gate.DenseMatrix(reverse_wire_labels,
                                                np.conj(mat).T)
                    return gate_mat

        return inverse_operation

    def analytic_probability(self, wires=None):
        """Return the (marginal) analytic probability of each computational basis state."""
        if self._state is None:
            return None

        all_probs = self._abs(self.state)**2
        prob = self.marginal_prob(all_probs, wires)
        return prob

    def expval(self, observable):
        if self.analytic:
            qulacs_observable = Observable(self.num_wires)
            if isinstance(observable.name, list):
                observables = [
                    self._observable_map[obs] for obs in observable.name
                ]
            else:
                observables = [self._observable_map[observable.name]]

            if None not in observables:
                applied_wires = self.map_wires(observable.wires).tolist()
                opp = " ".join([
                    f"{obs} {applied_wires[i]}"
                    for i, obs in enumerate(observables)
                ])

                qulacs_observable.add_operator(1.0, opp)
                return qulacs_observable.get_expectation_value(
                    self._pre_rotated_state)

            # exact expectation value
            eigvals = self._asarray(observable.eigvals, dtype=self.R_DTYPE)
            prob = self.probability(wires=observable.wires)
            return self._dot(eigvals, prob)

        # estimate the ev
        return np.mean(self.sample(observable))

    @property
    def state(self):
        # returns the state after all operations are applied
        return _reverse_state(self._state.get_vector())

    def reset(self):
        self._state.set_zero_state()
        self._pre_rotated_state = self._state.copy()
        self._circuit = QuantumCircuit(self.num_wires)
Пример #19
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)
Пример #20
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
Пример #21
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)
Пример #22
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
Пример #23
0
from qulacs.gate import Probabilistic, X

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)
Пример #24
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
Пример #25
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