ashutosh1919's picture
Adding Perceptron and its simulation demo notebook
91d3e9c
import numpy as np
from typing import List, Dict
from qiskit import QuantumCircuit
from quantum_perceptron.utils.data_utils import (
get_possible_state_strings,
get_ones_counts_to_states
)
def append_hypergraph_state(
circuit: QuantumCircuit,
data_vector: np.ndarray,
states: np.ndarray,
ones_count: Dict[int, List[int]],
num_qubits: int) -> QuantumCircuit:
"""
Append the computed hypergraph state to the circuit.
Args:
circuit: `QuantumCircuit` object corresponding to the perceptron.
data_vector: `np.ndarray` containing the data vector containing -1s & 1s.
states: `list` of `str` containing the bit strings for states.
ones_count: `dict` containing mapping of the count of ones with
index of states
num_qubits: `int` denoting total number of qubits in the circuit.
Returns: `QuantumCircuit` object denoting the circuit containing
hypergraph states.
"""
is_sign_inverted = [1] * len(data_vector)
# Flipping all signs if all zero state has coef -1.
if data_vector[0] == -1:
for i in range(len(data_vector)):
data_vector[i] *= -1
for ct in range(1, num_qubits + 1):
for i in ones_count.get(ct, []):
if data_vector[i] == is_sign_inverted[i]:
state = states[i]
ones_idx = [j for j, x in enumerate(state) if x == '1']
if ct == 1:
circuit.z(ones_idx[0])
elif ct == 2:
circuit.cz(ones_idx[0], ones_idx[1])
else:
circuit.mcrz(
-np.pi,
[circuit.qubits[j] for j in ones_idx[1:]],
circuit.qubits[ones_idx[0]]
)
for j, state in enumerate(states):
is_one = np.array([bit == '1' for bit in state])
if np.all(is_one[ones_idx]):
is_sign_inverted[j] *= -1
return circuit
def create_hypergraph_state(circuit: QuantumCircuit,
data_vector: np.ndarray,
num_qubits: int) -> QuantumCircuit:
"""
Creating hypergraph state for specific data vector corresponding to
the provided data (input or weight value).
It is as per https://arxiv.org/abs/1811.02266.
Args:
circuit: `QuantumCircuit` object corresponding to the perceptron.
data_vector: `np.ndarray` containing the data vector containing -1s & 1s.
num_qubits: `int` denoting total number of qubits in the circuit.
Returns: `QuantumCircuit` object denoting the circuit containing
hypergraph states.
"""
states = get_possible_state_strings(num_qubits)
ones_count = get_ones_counts_to_states(states)
return append_hypergraph_state(
circuit,
data_vector,
states,
ones_count,
num_qubits
)