[PYTHON] Qiskit: j'ai implémenté VQE

J'ai implémenté VQE avec Qiskit.

Cette fois, nous allons implémenter VQE (Variational Quantum Eigen Solver) en utilisant le framework open source pour les ordinateurs quantiques fourni par IBM. Cet algorithme devrait être appliqué à la chimie quantique. Veuillez consulter Quantum Native Dojo pour une explication théorique. Je pense qu'il existe plusieurs articles d'implémentation VQE, mais la plupart des articles japonais sont écrits en utilisant Qulacs et Blueqat, j'ai donc essayé de les implémenter avec Qiskit cette fois. J'ai écrit des articles sur QAOA et QCL dans le passé, alors jetez un œil. Implémentation de QAOA sans Qiskit Aqua Mise en œuvre de l'apprentissage des circuits quantiques

la mise en oeuvre

Importation de bibliothèque

python


from qiskit import Aer, execute
from qiskit import QuantumCircuit
from qiskit.aqua.utils import tensorproduct
from qiskit.quantum_info.analysis import average_data

from scipy.optimize import minimize
import numpy as np

Initialiser

python


class VQE:

    def __init__(self, n_qubits, observable, layer, backend):
        self.n_qubits = n_qubits
        self.OBS = observable
        self.Layer = layer
        self.backend = backend

Cette fois, l'hamiltonien est également traité comme une entrée.

Créer un circuit

python


    def make_circuit(self, Params):

        def make_U_circuit(circ, params):
            for n in range(self.n_qubits):
                param = params[3*n:3*(n+1)]
                circ.rz(param[0], n)
                circ.rx(param[1], n)
                circ.rz(param[2], n)
            return circ

        def make_Ent(circ):
            for n in range(self.n_qubits-1):
                circ.cx(n, n+1)
            return circ

        #Mettre en place le circuit
        circ = QuantumCircuit(self.n_qubits, self.n_qubits)

        for l in range(self.Layer):
            #Créer un circuit de paramètres
            params = Params[3*self.n_qubits*l:3*self.n_qubits*(l+1)]
            #Créer un enchevêtrement
            make_U_circuit(circ, params)
            #Nombre de couches-Parce que ça doit être 1
            if l != self.Layer-1:
                make_Ent(circ)

        #La mesure
        circ.measure(circ.qregs[0], circ.cregs[0])

        return circ

Phase d'exécution VQE

python


    def outputlayer(self, params):
        circ = self.make_circuit(params)
        counts = execute(circ, backend=self.backend, shots=8192).result().get_counts()
        return average_data(counts, self.OBS)

    def initial_params(self):
        #Création des paramètres initiaux
        init = [0.1 for _ in range(3 * self.Layer * self.n_qubits)]
        return np.array(init)

    def minimize(self):
        initial_params = self.initial_params()
        #Effectuer l'optimisation
        opt_params, opt_cost = classica_minimize(self.outputlayer, initial_params, options={'maxiter':500})
        circ = self.make_circuit(opt_params)
        counts = execute(circ, backend=self.backend, shots=8192).result().get_counts()
        ans = sorted(counts.items(), key=lambda x: x[1], reverse=True)
        print(ans)
        return opt_cost

De plus, contrairement à d'autres articles, une couche est utilisée. C'est dans la référence [1]. Je vais vous expliquer brièvement. Lorsque $ \ theta = (\ theta_1, \ theta_2, \ cdots, \ theta_d) $ est un ensemble de paramètres, le circuit

python


U(\theta) = U_d(\theta_d)U_{ENT} \cdots U_1(\theta_1)U_{ENT}U_0(\theta_0)

Peut être écrit. À ce stade, $ d $ est le nombre de couches. En mettant $ d = 2 $, il est possible de créer le même circuit que les autres articles.

Courir

Cette fois, j'utiliserai la formule qui est également traitée dans d'autres articles comme hamiltonien. Supplementary Information

python


def sample_hamiltonian():
    '''
    https://dojo.qulacs.org/ja/latest/notebooks/5.1_variational_quantum_eigensolver.html
Hamiltonian est utilisé.
    '''
    I_mat = np.array([[1, 0], [0, 1]])
    X_mat = np.array([[0, 1], [1, 0]])
    Z_mat = np.array([[1, 0], [0, -1]])
    obs = np.zeros((4, 4))
    obs += -3.8505 * tensorproduct(I_mat, I_mat)
    obs += -0.2288 * tensorproduct(I_mat, X_mat)
    obs += -1.0466 * tensorproduct(I_mat, Z_mat)
    obs += 0.2613 * tensorproduct(X_mat, X_mat)
    obs += 0.2288 * tensorproduct(X_mat, Z_mat)
    obs += -1.0466 * tensorproduct(Z_mat, I_mat)
    obs += 0.2288 * tensorproduct(Z_mat, X_mat)
    obs += 0.2356 * tensorproduct(Z_mat, Z_mat)
    return obs / 2

J'utilise également les fonctions que j'utilise dans d'autres articles que j'écris pour l'optimisation classique.

python


def classica_minimize(cost_func, initial_params, options, method='powell'):
    print('classical minimize is starting now... ')
    result = minimize(cost_func, initial_params, options=options, method=method)
    print('opt_cost: {}'.format(result.fun))
    print('opt_params: {}'.format(result.x))
    return result.x, result.fun

C'est l'exécution.

python


if __name__ == '__main__':
    backend = Aer.get_backend('qasm_simulator')
    obs = sample_hamiltonian()
    vqe = VQE(2, obs, 2, backend)
    vqe.minimize()

Résultat d'exécution

-2.85405 #résultat vqe
-2.8626207640766816 #Valeur propre minimale

Par rapport à d'autres articles, la précision est moindre, mais est-ce un succès ...?

Sommaire

J'ai essayé d'implémenter VQE en utilisant Qiskit. Pour être honnête, je préfère QAOA, qui convient aux problèmes classiques, à VQE, j'ai donc écrit cet article dans le but d'une implémentation complète. Veuillez faire votre propre théorie ...

Références

[1] Hardware-efficient variational quantum eigensolver for small molecules and quantum magnets [2] Quantum Native Dojo

Recommended Posts

Qiskit: j'ai implémenté VQE
J'ai essayé d'implémenter VQE avec Blueqat
J'ai implémenté CycleGAN (1)
J'ai implémenté ResNet!
J'ai essayé d'implémenter Extreme Learning Machine
J'ai essayé d'implémenter Deep VQE
[Python] J'ai essayé d'implémenter un échantillonnage de Gibbs marginalisé
J'ai essayé d'implémenter Attention Seq2Seq avec PyTorch
J'ai comparé Qiskit et Blueqat (débutant)
J'ai essayé de mettre en œuvre un réseau de neurones à deux couches
J'ai essayé d'implémenter la régularisation Shake-Shake (ShakeNet) avec PyTorch
[Renforcer l'apprentissage] J'ai implémenté / expliqué R2D3 (Keras-RL)
J'ai essayé d'implémenter la régression logistique de Cousera en Python
CheckIO (Python)> Éléments non uniques> J'ai essayé de mettre en œuvre
Implémentation de DQN avec TensorFlow (je voulais ...)