QAOA - pyqtorch

Skip to content

# QAOA

In [23]:
Copied!

    import torch
    import torch.nn as nn
    import torch.nn.functional as F
    import torch.nn.init as init

    import numpy as np
    import matplotlib.pyplot as plt
    import networkx as nx

    from pyqtorch.core.circuit import QuantumCircuit
    from pyqtorch.ansatz import AlternateLayerAnsatz
    from pyqtorch.embedding import SingleLayerEncoding
    from pyqtorch.core.operation import Z, RX

import torch import torch.nn as nn import torch.nn.functional as F import torch.nn.init as init import numpy as np import matplotlib.pyplot as plt import networkx as nx from pyqtorch.core.circuit import QuantumCircuit from pyqtorch.ansatz import AlternateLayerAnsatz from pyqtorch.embedding import SingleLayerEncoding from pyqtorch.core.operation import Z, RX

## Solve MIS for QAOA¶

In [24]:
Copied!

    np.random.seed(0)
    n_nodes = 5

    graph = nx.gnp_random_graph(n_nodes, .25, seed=42)
    nx.draw(graph, with_labels=True)

np.random.seed(0) n_nodes = 5 graph = nx.gnp_random_graph(n_nodes, .25, seed=42) nx.draw(graph, with_labels=True)
In [32]:
Copied!

    from pyqtorch.matrices import generate_ising_from_graph, sum_N
    ising_matrix = generate_ising_from_graph(graph, type_ising='N')
    ising_cost = 1.2*ising_matrix - sum_N(n_nodes)

    ising_matrix = ising_matrix.reshape([2] * n_nodes + [1])
    ising_cost = ising_cost.reshape([2] * n_nodes + [1])

    class MIS(QuantumCircuit):
        def __init__(self, n_qubits, n_layers):
            super().__init__(n_qubits)
            self.beta = nn.Parameter(torch.empty(n_layers,))
            self.gamma = nn.Parameter(torch.empty(n_layers,))
            self.reset_parameters()

        def reset_parameters(self):
            init.uniform_(self.beta, -2 * np.pi, 2 * np.pi)
            init.uniform_(self.gamma, -2 * np.pi, 2 * np.pi)

        def forward(self, return_cost=False):
            state = self.uniform_state()
            for b, g in zip(self.beta, self.gamma):
                state = state * torch.exp(-1j * g * ising_matrix)
                for i in range(self.n_qubits):
                    state = RX(b, state, [i], self.n_qubits)
            if return_cost:
                return torch.real(torch.sum(torch.abs(state)**2 * ising_cost))
            else:
                state = state.reshape((2**self.n_qubits,))
                return torch.abs(state)**2

from pyqtorch.matrices import generate_ising_from_graph, sum_N ising_matrix = generate_ising_from_graph(graph, type_ising='N') ising_cost = 1.2*ising_matrix - sum_N(n_nodes) ising_matrix = ising_matrix.reshape([2] * n_nodes + [1]) ising_cost = ising_cost.reshape([2] * n_nodes + [1]) class MIS(QuantumCircuit): def __init__(self, n_qubits, n_layers): super().__init__(n_qubits) self.beta = nn.Parameter(torch.empty(n_layers,)) self.gamma = nn.Parameter(torch.empty(n_layers,)) self.reset_parameters() def reset_parameters(self): init.uniform_(self.beta, -2 * np.pi, 2 * np.pi) init.uniform_(self.gamma, -2 * np.pi, 2 * np.pi) def forward(self, return_cost=False): state = self.uniform_state() for b, g in zip(self.beta, self.gamma): state = state * torch.exp(-1j * g * ising_matrix) for i in range(self.n_qubits): state = RX(b, state, [i], self.n_qubits) if return_cost: return torch.real(torch.sum(torch.abs(state)**2 * ising_cost)) else: state = state.reshape((2**self.n_qubits,)) return torch.abs(state)**2
In [33]:
Copied!

    model = MIS(n_nodes, 20)

    optimizer = torch.optim.Adam(model.parameters(), lr=.02)
    epochs = 100

    for epoch in range(epochs):
        optimizer.zero_grad()
        loss = model(True)
        loss.backward()
        optimizer.step()
        if epoch%50 == 0:
            print(f"Epoch {epoch} | Loss {loss}")

model = MIS(n_nodes, 20) optimizer = torch.optim.Adam(model.parameters(), lr=.02) epochs = 100 for epoch in range(epochs): optimizer.zero_grad() loss = model(True) loss.backward() optimizer.step() if epoch%50 == 0: print(f"Epoch {epoch} | Loss {loss}")

    Epoch 0 | Loss -0.5000000000000002
    Epoch 50 | Loss -0.5000000000000002

In [27]:
Copied!

    prob = model()
    mis = torch.argmax(prob)
    format(mis, '010b')

prob = model() mis = torch.argmax(prob) format(mis, '010b')
Out[27]:

    '0011111001'

In [28]:
Copied!

    mis

mis
Out[28]:

    tensor(249)

In [29]:
Copied!

    "{0:b}".format(1)

"{0:b}".format(1)
Out[29]:

    '1'

In [30]:
Copied!

    sum_N(n_nodes)[mis]

sum_N(n_nodes)[mis]
Out[30]:

    tensor(6.+0.j, dtype=torch.complex128)

In [ ]:
Copied!