Example #1
0
def create_icmr_uccsd_state_spinfree(n_qubits,
                                     v_n,
                                     a_n,
                                     c_n,
                                     rho,
                                     DS,
                                     theta_list,
                                     det,
                                     ndim1,
                                     act2act=False,
                                     SpinProj=False):
    """
    """
    state = QuantumState(n_qubits)
    state.set_computational_basis(det)

    theta_list_rho = theta_list / rho
    circuit = set_circuit_ic_mrucc_spinfree(n_qubits, v_n, a_n, c_n, DS,
                                            theta_list_rho, ndim1, act2act)
    for i in range(rho):
        circuit.update_quantum_state(state)

    if SpinProj:
        from .phflib import S2Proj
        state_P = S2Proj(state)
        return state_P
    else:
        return state
Example #2
0
def create_uccsd_state(n_qubits,
                       rho,
                       DS,
                       theta_list,
                       det,
                       ndim1,
                       SpinProj=False):
    """Function
    Prepare a UCC state based on theta_list.
    The initial determinant 'det' contains the base-10 integer
    specifying the bit string for occupied orbitals.

    Author(s):  Yuto Mori, Takashi Tsuchimochi
    """
    from .init import get_occvir_lists

    ### Form RHF bits
    state = QuantumState(n_qubits)
    state.set_computational_basis(det)
    occ_list, vir_list = get_occvir_lists(n_qubits, det)

    theta_list_rho = theta_list / rho
    circuit = set_circuit_uccsdX(n_qubits, DS, theta_list_rho, occ_list,
                                 vir_list, ndim1)
    for i in range(rho):
        circuit.update_quantum_state(state)

    if SpinProj:
        from .phflib import S2Proj
        state = S2Proj(Quket, state)
    return state
Example #3
0
def cost_upccgsd(Quket, print_level, kappa_list, theta_list, k):
    """Function:
    Energy functional of UpCCGSD

    Author(s): Takahiro Yoshikura
    """
    t1 = time.time()

    norbs = Quket.n_orbitals
    n_qubits = Quket.n_qubits
    det = Quket.det
    ndim1 = Quket.ndim1
    ndim2 = Quket.ndim2
    ndim = Quket.ndim

    state = QuantumState(n_qubits)
    state.set_computational_basis(det)
    if "epccgsd" in Quket.ansatz:
        circuit = set_circuit_epccgsd(n_qubits, norbs, theta_list, ndim1,
                                      ndim2, k)
    else:
        circuit = set_circuit_upccgsd(n_qubits, norbs, theta_list, ndim1,
                                      ndim2, k)
    circuit.update_quantum_state(state)
    if Quket.projection.SpinProj:
        from .phflib import S2Proj
        state_P = S2Proj(Quket, state)
        state = state_P.copy()

    Eupccgsd = Quket.qulacs.Hamiltonian.get_expectation_value(state)
    cost = Eupccgsd
    ### Project out the states contained in 'lower_states'
    cost += orthogonal_constraint(Quket, state)
    S2 = Quket.qulacs.S2.get_expectation_value(state)

    t2 = time.time()
    cpu1 = t2 - t1
    if print_level == 1:
        cput = t2 - cf.t_old
        cf.t_old = t2
        cf.icyc += 1
        prints(f"{cf.icyc:5d}: "
               f"E[{k}-UpCCGSD] = {Eupccgsd:.12f}  <S**2> = {S2:17.15f}  "
               f"CPU Time = {cput:5.2f}  ({cpu1:2.2f} / step)")
        SaveTheta(ndim, theta_list, cf.tmp)
    if print_level > 1:
        prints(f"Final: "
               f"E[{k}-UpCCGSD] = {Eupccgsd:.12f}  <S**2> = {S2:17.15f}")
        prints(f"\n({k}-UpCCGSD state)")
        print_state(state, threshold=Quket.print_amp_thres)

    # Store UpCCGSD wave function
    Quket.state = state
    return cost, S2
Example #4
0
def test_H() -> None:
    state = QuantumState(1)
    state.set_zero_state()
    circ = Circuit(1).H(0)
    qulacs_circ = tk_to_qulacs(circ)
    qulacs_circ.update_quantum_state(state)

    state0 = QuantumState(1)
    state0.set_computational_basis(0)
    probability = inner_product(state0, state)**2
    assert np.isclose(probability, 0.5)
Example #5
0
def test_bellpair() -> None:
    state = QuantumState(2)
    circ = Circuit(2).H(0).CX(0, 1)
    qulacs_circ = tk_to_qulacs(circ)
    qulacs_circ.update_quantum_state(state)

    state0 = QuantumState(2)
    state0.set_computational_basis(0)
    probability = inner_product(state0, state)**2
    assert np.isclose(probability, 0.5)

    state1 = QuantumState(2)
    state1.set_computational_basis(1)
    probability = inner_product(state1, state)**2
    assert np.isclose(probability, 0)

    state2 = QuantumState(2)
    state2.set_computational_basis(2)
    probability = inner_product(state2, state)**2
    assert np.isclose(probability, 0)

    state3 = QuantumState(2)
    state3.set_computational_basis(3)
    probability = inner_product(state3, state)**2
    assert np.isclose(probability, 0.5)
Example #6
0
def create_sauccsd_state(n_qubit_system, noa, nva, rho, DS, theta_list, det,
                         ndim1):
    """Function
    Prepare a UCC state based on theta_list.
    The initial determinant 'det' contains the base-10 integer
    specifying the bit string for occupied orbitals.

    Author(s):  Yuto Mori, Takashi Tsuchimochi
    """
    ### Form RHF bits

    state = QuantumState(n_qubit_system)
    state.set_computational_basis(det)
    theta_list_rho = theta_list / rho
    circuit = set_circuit_sauccsd(n_qubit_system, noa, nva, DS, theta_list_rho,
                                  ndim1)
    for i in range(rho):
        circuit.update_quantum_state(state)
    return state
Example #7
0
def create_icmr_uccsd_state(n_qubit_system, nv, na, nc, rho, DS, theta_list,
                            det, ndim1):
    """ Function
    Author(s): Yuto Mori
    """
    state = QuantumState(n_qubit_system)
    state.set_computational_basis(det)

    theta_list_rho = theta_list / rho
    circuit = set_circuit_ic_mrucc(n_qubit_system, nv, na, nc, DS,
                                   theta_list_rho, ndim1)
    for i in range(rho):
        circuit.update_quantum_state(state)

    if cf.SpinProj:
        from .phflib import S2Proj
        state_P = S2Proj(state)
        return state_P
    else:
        return state
Example #8
0
def qite_anti(Quket, id_set, size):
    ### Parameter setting
    ansatz = Quket.ansatz
    n = Quket.n_qubits
    db = Quket.dt
    qbit = Quket.det
    ntime = Quket.maxiter
    observable = Quket.qulacs.Hamiltonian
    S2_observable = Quket.qulacs.S2
    threshold = Quket.ftol
    S2 = 0

    prints(f"QITE: Pauli operator group size = {size}")
    if ansatz != "cite":
        sigma_list, sigma_ij_index, sigma_ij_coef = qite_s_operators(id_set, n)
        len_list = len(sigma_list)
        prints(f"    Unique sigma list = {len_list}")

    index = np.arange(n)
    delta = QuantumState(n)
    first_state = QuantumState(n)
    first_state.set_computational_basis(qbit)

    energy = []
    psi_dash = first_state.copy()

    t1 = time.time()
    cf.t_old = t1

    En = observable.get_expectation_value(psi_dash)
    energy.append(En)
    if S2_observable is not None:
        S2 = S2_observable.get_expectation_value(psi_dash)

    dE = 100
    for t in range(ntime):
        t2 = time.time()
        cput = t2 - cf.t_old
        cf.t_old = t2
        if cf.debug:
            print_state(psi_dash)
        prints(f"{t*db:6.2f}: E = {En:.12f}  <S**2> = {S2:17.15f}  "
               f"CPU Time = {cput: 5.2f}")

        if abs(dE) < threshold:
            break
        if t == 0:
            xv = np.zeros(size)

        T0 = time.time()
        delta = calc_delta(psi_dash, observable, n, db)
        T1 = time.time()

        if ansatz == "cite":
            delta.add_state(psi_dash)
            psi_dash = delta.copy()
        else:
            #for i in range(size):
            #   pauli_id = id_set[i]
            #   circuit_i = make_gate(n, index, pauli_id)
            #   state_i = psi_dash.copy()
            #   circuit_i.update_quantum_state(state_i)
            #   print(i)
            #   for j in range(i+1):
            #       pauli_id = id_set[j]
            #       circuit_j = make_gate(n, index, pauli_id)
            #       state_j = psi_dash.copy()
            #       circuit_j.update_quantum_state(state_j)
            #       s = inner_product(state_j, state_i)
            #       S[i][j] = s
            #       S[j][i] = s

            ###  Compute Sij as expectation values of sigma_list
            Sij_list = np.zeros(len_list)
            Sij_my_list = np.zeros(len_list)
            ipos, my_ndim = mpi.myrange(len_list)
            T2 = time.time()
            for iope in range(ipos, ipos + my_ndim):
                val = sigma_list[iope].get_expectation_value(psi_dash)
                Sij_my_list[iope] = val
            T3 = time.time()
            mpi.comm.Allreduce(Sij_my_list, Sij_list, mpi.MPI.SUM)
            T4 = time.time()

            ### Distribute Sij
            ij = 0
            sizeT = size * (size - 1) // 2
            ipos, my_ndim = mpi.myrange(sizeT)
            S = np.zeros((size, size), dtype=complex)
            my_S = np.zeros((size, size), dtype=complex)
            for i in range(size):
                for j in range(i):
                    if ij in range(ipos, ipos + my_ndim):
                        ind = sigma_ij_index[ij]
                        coef = sigma_ij_coef[ij]
                        my_S[i, j] = coef * Sij_list[ind]
                        my_S[j, i] = my_S[i, j].conjugate()
                    ij += 1
            mpi.comm.Allreduce(my_S, S, mpi.MPI.SUM)
            for i in range(size):
                S[i, i] = 1

            T5 = time.time()
            sigma = []
            for i in range(size):
                pauli_id = id_set[i]
                circuit_i = make_gate(n, index, pauli_id)
                state_i = psi_dash.copy()
                circuit_i.update_quantum_state(state_i)
                sigma.append(state_i)
            T6 = time.time()

            b_l = np.empty(size)
            for i in range(size):
                b_i = inner_product(sigma[i], delta)
                b_i = -2 * b_i.imag
                b_l[i] = b_i
            Amat = 2 * np.real(S)
            T7 = time.time()

            zct = b_l @ Amat

            def cost_fun(vct):
                return LA.norm(Amat @ vct - b_l)**2

            def J_cost_fun(vct):
                wct = Amat.T @ Amat @ vct
                return 2.0 * (wct - zct)

            #x = sp.optimize.minimize(cost_fun, x0=xv, method='Newton-CG',
            #                         jac=J_cost_fun, tol=1e-8).x
            #xv = x.copy()
            #x = sp.optimize.least_squares(cost_fun, x0=xv, ftol=1e-8).x
            #xv = x.copy()
            x, res, rnk, s = lstsq(Amat, b_l, cond=1e-8)
            a = x.copy()
            ### Just in case, broadcast a...
            mpi.comm.Bcast(a, root=0)

            T8 = time.time()
            psi_dash = calc_psi_lessH(psi_dash, n, index, a, id_set)
            T9 = time.time()

            if cf.debug:
                prints(f"T0 -> T1  {T1-T0}")
                prints(f"T1 -> T2  {T2-T1}")
                prints(f"T2 -> T3  {T3-T2}")
                prints(f"T3 -> T4  {T4-T3}")
                prints(f"T4 -> T5  {T5-T4}")
                prints(f"T5 -> T6  {T6-T5}")
                prints(f"T6 -> T7  {T7-T6}")
                prints(f"T7 -> T8  {T8-T7}")
                prints(f"T8 -> T9  {T9-T8}")

        En = observable.get_expectation_value(psi_dash)
        if S2_observable is not None:
            S2 = S2_observable.get_expectation_value(psi_dash)
        energy.append(En)
        dE = energy[t + 1] - energy[t]

    print_state(psi_dash, name="QITE")
Example #9
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)
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)

method = "COBYLA"
options = {"disp": False, "maxiter": arg_maxiter}
opt = minimize(cost, init_theta_list, method=method, options=options)

print("opt.x =", opt.x)
print(opt.success, opt.status, opt.message, opt.fun)

circ = ansatz_circuit(n_qubit, depth, opt.x)
for i in range(n_qubit):
    circ.add_gate(Measurement(i, i))

input_state = QuantumState(n_qubit)
#input_state.set_zero_state()
input_state.set_computational_basis(
    int('0b' + '1' * (n_qubit / 2) + '0' * (n_qubit / 2), 2))
circ.update_quantum_state(input_state)
print("Energy =", qulacs_hamiltonian.get_expectation_value(input_state))

exec_time = time.time() - start_time
print('')
print('QUBO of size ' + str(len(Q)) + ' sampled in ' + str(exec_time) + ' s')

samples = {}
sys.stdout.write("Value=")
for i in range(n_qubit):
    value = input_state.get_classical_value(i)
    samples[key_i[i]] = int(value)
    sys.stdout.write(str(value))
    sys.stdout.write(" ")
Example #12
0
        p0 = psi.get_marginal_probability(
            [lambda i: 0 if i == a_idx else 2 for i in range(n_qubits)])
        p1 = psi.get_marginal_probability(
            [lambda i: 1 if i == a_idx else 2 for i in range(n_qubits)])
        # update kickback phase
        kth_digit = 1 if (p0 < p1) else 0
        kickback_phase = kickback_phase / 2 + kth_digit
    return -0.5 * np.pi * kickback_phase


if __name__ == "__main__":
    n_qubits = 3  # 2 for electron configurations and 1 for ancilla
    g_list = [0.3593, 0.0896, -0.4826, 0.0896]
    pauli_strings = ['Z 0', 'Y 0 Y 1', 'Z 1', 'X 0 X 1']
    hf_state = QuantumState(n_qubits)
    hf_state.set_computational_basis(0b001)  # |0>|01>
    t = 0.640
    n_itter = 16  # determine precission

    # validity check
    _, eigs = reduced_term_hamiltonian()
    e_exact = eigs[0]
    print('e_exact:{}'.format(e_exact))
    print('n, e_matrix, e_iqpe, |e_matrix-e_iqpe|, |e_exact-e_iqpe|')
    for n in range(1, 10, 2):
        iqpe_phase = iterative_phase_estimation(g_list,
                                                t,
                                                n_itter,
                                                hf_state,
                                                n_trotter_step=n,
                                                kickback_phase=0.0)
Example #13
0
def qite_exact(Quket):
    nspin = Quket.n_qubits
    db = Quket.dt
    ntime = Quket.maxiter
    qbit = Quket.det
    observable = Quket.qulacs.Hamiltonian
    threshold = Quket.ftol

    active_qubit = [x for x in range(nspin)]
    n = nspin
    size = 4**nspin
    index = np.arange(n)
    delta = QuantumState(n)
    first_state = QuantumState(n)
    first_state.set_computational_basis(qbit)

    prints(f"Exact QITE: Pauli operator group size = {size}")

    energy = []
    psi_dash = first_state.copy()
    value = observable.get_expectation_value(psi_dash)
    energy.append(value)

    t1 = time.time()
    cf.t_old = t1
    dE = 100
    for t in range(ntime):
        t2 = time.time()
        cput = t2 - cf.t_old
        cf.t_old = t2
        if cf.debug:
            print_state(psi_dash)
        prints(f"{t*db:6.2f}: E = {value:.12f}  CPU Time = {cput:5.2f}")

        if abs(dE) < threshold:
            break
        #if t == 0:
        #    xv = np.zeros(size)
        psi_dash_copy = psi_dash.copy()

        #mpi.comm.bcast(size, root=0)
        #S_part = np.zeros((size, size), dtype=complex)
        #S = np.zeros((size, size), dtype=complex)
        #sizeT = size*(size+1)//2
        #nblock = sizeT//mpi.nprocs

        #ij = mpi.rank*nblock
        #start = int(np.sqrt(2*ij + 1/4) - 1/2)
        #end = int(np.sqrt(2*(ij+nblock) + 1/4) - 1/2)
        #for i in range(start, end):
        #    for j in range(i+1):
        #        S_part[i, j] = calc_inner1(i, j, n, active_qubit,
        #                                   index, psi_dash)
        #        ij += 1
        #    S[:i, i] = S[i, :i]
        #mpi.comm.Allreduce(S_part, S, mpi.MPI.SUM)

        S_part = np.zeros((size, size), dtype=complex)
        S = np.zeros((size, size), dtype=complex)
        sizeT = size * (size - 1) // 2
        ipos, my_ndim = mpi.myrange(sizeT)
        ij = 0
        for i in range(size):
            for j in range(i):
                if ij in range(ipos, ipos + my_ndim):
                    S_part[i, j] = calc_inner1(i, j, n, active_qubit, index,
                                               psi_dash)
                    S_part[j, i] = S_part[i, j].conjugate()
                ij += 1
        mpi.comm.Allreduce(S_part, S, mpi.MPI.SUM)
        for i in range(size):
            S[i, i] = 1

        sigma = []
        for i in range(size):
            state_i = make_state1(i, n, active_qubit, index, psi_dash)
            sigma.append(state_i)

        delta = calc_delta(psi_dash, observable, n, db)
        b_l = []
        b_l = np.empty(size)
        for i in range(size):
            b_i = inner_product(sigma[i], delta)
            b_i = -2 * b_i.imag
            b_l[i] = b_i

        Amat = 2 * np.real(S)
        zct = b_l @ Amat

        #def cost_fun(vct):
        #    return LA.norm(Amat@vct - b_l)**2

        #def J_cost_fun(vct):
        #    wct = Amat.T@Amat@vct
        #    return 2.0*(wct-zct)

        #x = sp.optimize.minimize(cost_fun, x0=xv, method="Newton-CG",
        #                         jac=J_cost_fun, tol=1e-8).x
        #xv = x.copy()
        x, res, rnk, s = lstsq(Amat, b_l, cond=1.0e-8)
        a = x.copy()
        ### Just in case, broadcast a...
        mpi.comm.Bcast(a, root=0)
        psi_dash = calc_psi(psi_dash_copy, n, index, a, active_qubit)

        value = observable.get_expectation_value(psi_dash)
        energy.append(value)
        dE = energy[t + 1] - energy[t]
Example #14
0
    fx_type = 'balanced'

cu_mat = np.zeros((2**(num_bits + 1), 2**(num_bits + 1)), np.int8)
for x in range(2**num_bits):
    crow = x * 2 + f(x)
    cu_mat[x * 2][crow] = 1
    cu_mat[x * 2 + 1][crow // 2 * 4 + 1 - crow] = 1

if num_bits < 6:
    print("CU Gate Matrix:")
    for i in range(2**(num_bits + 1)):
        print(''.join([str(b) for b in cu_mat[i]]))

state = QuantumState(num_bits + 1)
state.set_computational_basis(0)

print("\nInitial State:")
show_quantum_state(state)

for i in range(1, num_bits + 1):
    h_gate = H(i)
    h_gate.update_quantum_state(state)

print("\nAfter H Gate:")
show_quantum_state(state)

cu_gate = DenseMatrix(tuple(range(num_bits + 1)), cu_mat)
cu_gate.update_quantum_state(state)

print("\nAfter CU Gate:")
Example #15
0
def cost_bcs(Quket, print_level, theta_list, k):
    """Function:
    Energy functional of kBCS

    Author(s): Takahiro Yoshikura
    """
    t1 = time.time()

    noa = Quket.noa
    nob = Quket.nob
    nva = Quket.nva
    nvb = Quket.nvb
    n_qubits = Quket.n_qubits
    det = Quket.det
    ndim1 = Quket.ndim1
    ndim = Quket.ndim

    state = QuantumState(n_qubits)
    state.set_computational_basis(det)
    circuit = set_circuit_bcs(ansatz, n_qubits, n_orbitals, ndim1, ndim,
                              theta_list, k)
    circuit.update_quantum_state(state)

    if Quket.projection.SpinProj:
        from .phflib import S2Proj
        state_P = S2Proj(Quket, state)
        state = state_P.copy()
    if Quket.projection.NumberProj:
        from .phflib import NProj
        state_P = NProj(Quket, state)
        state = state_P.copy()
    #print_state(state, threshold=cf.print_amp_thres)

    Ebcs = Quket.qulacs.Hamiltonian.get_expectation_value(state)
    cost = Ebcs
    ### Project out the states contained in 'lower_states'
    cost += orthogonal_constraint(Quket, state)
    S2 = Quket.qulacs.S2.get_expectation_value(state)

    t2 = time.time()
    cpu1 = t2 - t1
    if print_level == 1:
        cput = t2 - cf.t_old
        cf.t_old = t2
        cf.icyc += 1
        prints(f"{cf.icyc:5d}: "
               f"E[{k}-kBCS] = {Ebcs:.12f}  "
               f"<S**2> = {S2:17.15f}  "
               f"CPU Time = {cput:5.2f}  "
               f"({cpu1:2.2f} / step)")
        SaveTheta(ndim, theta_list, cf.tmp)
    if print_level > 1:
        prints(f"Final: "
               f"E[{k}-kBCS] = {Ebcs:.12f}  "
               f"<S**2> = {S2:17.15f}")
        prints(f"\n({k}-kBCS state)")
        printmat(theta_list)
        print_state(state, threshold=Quket.print_amp_thres)

    # Store kBCS wave function
    Quket.state = state
    return cost, S2