Skip to content

Commit

Permalink
Merge pull request #4 from SaashaJoshi/doc-strings
Browse files Browse the repository at this point in the history
Edit and create appropriate class and module doc strings. This commit partially fulfills the linting requirements. Early merge made to update work in a parallel PR.
  • Loading branch information
SaashaJoshi authored Nov 17, 2023
2 parents 16fcdaa + b6de7fb commit eb4ed0b
Show file tree
Hide file tree
Showing 21 changed files with 383 additions and 131 deletions.
1 change: 1 addition & 0 deletions .github/workflows/pylint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ jobs:
run: |
python -m pip install --upgrade pip
pip install pylint
pip install -r requirements.txt
- name: Analysing the code with pylint
run: |
pylint $(git ls-files '*.py')
9 changes: 9 additions & 0 deletions quantum_image_processing/data_encoder/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""
Data Encoders (module: quantum_image_processing.data_encoder)
"""

from .angle_encoder import angle_encoding

__all__ = [
"angle_encoding",
]
2 changes: 0 additions & 2 deletions quantum_image_processing/data_encoder/amplitude_encoder.py
Original file line number Diff line number Diff line change
@@ -1,2 +0,0 @@
def amplitude_encoding():
pass
1 change: 1 addition & 0 deletions quantum_image_processing/data_encoder/angle_encoder.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Angle Encoder"""
from qiskit.circuit import QuantumCircuit, ParameterVector


Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
"""
Quantum Image Representations (module: quantum_image_processing.data_encoder.image_representations)
"""

from .frqi import FRQI
from .neqr import NEQR

Expand Down
70 changes: 34 additions & 36 deletions quantum_image_processing/data_encoder/image_representations/frqi.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from __future__ import annotations
import math
import numpy as np
from qiskit import Aer, execute
from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit.visualization import plot_histogram
from qiskit.circuit import QuantumCircuit, QuantumRegister


class FRQI:
Expand Down Expand Up @@ -51,20 +49,20 @@ def _color_info(self, pixel_pos: int) -> QuantumCircuit:

return circ

# TODO: Delete this function from here. Make a separate file.
def _measure_circ(self, circ: QuantumCircuit) -> QuantumCircuit:
# Append measurement gates to the circuit
qr = QuantumRegister(self.feature_dim + 1)
cr = ClassicalRegister(self.feature_dim + 1)

meas_circ = QuantumCircuit(qr, cr)
meas_circ.measure(
list(range(self.feature_dim + 1)),
list(range(self.feature_dim + 1)),
)
meas_circ = meas_circ.compose(circ, range(self.feature_dim + 1), front=True)

return meas_circ
# # TODO: Delete this function from here. Make a separate file.
# def _measure_circ(self, circ: QuantumCircuit) -> QuantumCircuit:
# # Append measurement gates to the circuit
# qr = QuantumRegister(self.feature_dim + 1)
# cr = ClassicalRegister(self.feature_dim + 1)
#
# meas_circ = QuantumCircuit(qr, cr)
# meas_circ.measure(
# list(range(self.feature_dim + 1)),
# list(range(self.feature_dim + 1)),
# )
# meas_circ = meas_circ.compose(circ, range(self.feature_dim + 1), front=True)
#
# return meas_circ

def frqi(self, measure=True) -> QuantumCircuit:
"""Builds the FRQI image representation on a circuit.
Expand Down Expand Up @@ -103,28 +101,28 @@ def frqi(self, measure=True) -> QuantumCircuit:
)
circ.barrier()

if measure:
circ = self._measure_circ(circ)
# if measure:
# circ = self._measure_circ(circ)

return circ

# TODO: Remove the following function from this file.
@staticmethod
def get_simulator_result(
circ: QuantumCircuit,
backend: str = "qasm_simulator",
shots: int = 1024,
plot_counts=True,
):
backend = Aer.get_backend(backend)
job = execute(circ, backend=backend, shots=shots)
results = job.result()
counts = results.get_counts()

if plot_counts:
plot_histogram(counts)

return counts
# # TODO: Remove the following function from this file.
# @staticmethod
# def get_simulator_result(
# circ: QuantumCircuit,
# backend: str = "qasm_simulator",
# shots: int = 1024,
# plot_counts=True,
# ):
# backend = Aer.get_backend(backend)
# job = execute(circ, backend=backend, shots=shots)
# results = job.result()
# counts = results.get_counts()
#
# if plot_counts:
# plot_histogram(counts)
#
# return counts

def qic(self):
pass
Expand Down
70 changes: 34 additions & 36 deletions quantum_image_processing/data_encoder/image_representations/neqr.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
from __future__ import annotations
import math
import numpy as np
from qiskit import Aer, execute
from qiskit.circuit import QuantumCircuit, QuantumRegister, ClassicalRegister
from qiskit.visualization import plot_histogram
from qiskit.circuit import QuantumCircuit, QuantumRegister


class NEQR:
Expand Down Expand Up @@ -46,21 +44,21 @@ def _color_info(self, pixel_pos: int) -> QuantumCircuit:

return circ

def _measure_circ(self, circ: QuantumCircuit) -> QuantumCircuit:
# Append measurement gates to the circuit
qr = QuantumRegister(self.feature_dim + self.q)
cr = ClassicalRegister(self.feature_dim + self.q)

meas_circ = QuantumCircuit(qr, cr)
meas_circ.measure(
list(range(self.feature_dim + self.q)),
list(range(self.feature_dim + self.q)),
)
meas_circ = meas_circ.compose(
circ, range(self.feature_dim + self.q), front=True
)

return meas_circ
# def _measure_circ(self, circ: QuantumCircuit) -> QuantumCircuit:
# # Append measurement gates to the circuit
# qr = QuantumRegister(self.feature_dim + self.q)
# cr = ClassicalRegister(self.feature_dim + self.q)
#
# meas_circ = QuantumCircuit(qr, cr)
# meas_circ.measure(
# list(range(self.feature_dim + self.q)),
# list(range(self.feature_dim + self.q)),
# )
# meas_circ = meas_circ.compose(
# circ, range(self.feature_dim + self.q), front=True
# )
#
# return meas_circ

def image_encoding(self, measure=True) -> QuantumCircuit:
qr = QuantumRegister(self.feature_dim + self.q)
Expand Down Expand Up @@ -91,27 +89,27 @@ def image_encoding(self, measure=True) -> QuantumCircuit:
range(self.feature_dim),
)

if measure:
circ = self._measure_circ(circ)
# if measure:
# circ = self._measure_circ(circ)

return circ

@staticmethod
def get_simulator_result(
circ: QuantumCircuit,
backend: str = "qasm_simulator",
shots: int = 1024,
plot_counts=True,
) -> list:
backend = Aer.get_backend(backend)
job = execute(circ, backend=backend, shots=shots)
results = job.result()
counts = results.get_counts()

if plot_counts:
plot_histogram(counts)

return counts
# @staticmethod
# def get_simulator_result(
# circ: QuantumCircuit,
# backend: str = "qasm_simulator",
# shots: int = 1024,
# plot_counts=True,
# ) -> list:
# backend = Aer.get_backend(backend)
# job = execute(circ, backend=backend, shots=shots)
# results = job.result()
# counts = results.get_counts()
#
# if plot_counts:
# plot_histogram(counts)
#
# return counts

def qic(self):
pass
Expand Down
9 changes: 9 additions & 0 deletions quantum_image_processing/data_loader/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"""
Data Loader (module: quantum_image_processing.data_loader)
"""

from .mnist_data_loader import load_mnist_data

__all__ = [
"load_mnist_data",
]
2 changes: 1 addition & 1 deletion quantum_image_processing/gates/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""
Gate implementations, including unitary gates and their alternative parameterization.
(mod: quantum_image_processing.gates)
(module: quantum_image_processing.gates)
"""

from .unitary_block import Unitary
Expand Down
60 changes: 60 additions & 0 deletions quantum_image_processing/gates/two_qubit_unitary.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"""Two-Qubit Unitary Gate class"""
from __future__ import annotations

import numpy as np
Expand All @@ -9,6 +10,7 @@ class TwoQubitUnitary(Unitary):
"""
Implements two qubit unitary with alternative parameterizations.
"""

def simple_parameterization(
self,
circuit: QuantumCircuit,
Expand Down Expand Up @@ -48,6 +50,26 @@ def auxiliary_parameterization(
def _real_simple_block(
circuit: QuantumCircuit, qubits: list, parameter_vector: ParameterVector
) -> tuple[QuantumCircuit, ParameterVector]:
"""
Builds a two-qubit unitary gate with simple parameterization,
consisting of real two single-unitary gates followed by a CNOT
gate as given in the following paper.
References:
[1] E. Grant et al., “Hierarchical quantum classifiers,”
npj Quantum Information, vol. 4, no. 1, Dec. 2018,
doi: https://doi.org/10.1038/s41534-018-0116-9.
Args:
circuit (QuantumCircuit): Circuit on which two-qubit
unitary gate needs to be applied.
qubits (list): list of qubits on which the gates need to
be applied.
parameter_vector (ParameterVector): list of parameters
of the unitary gates.
"""
block = circuit
block.ry(parameter_vector[0], qubits[0])
block.ry(parameter_vector[1], qubits[1])
Expand All @@ -61,6 +83,25 @@ def _real_simple_block(
def _real_general_block(
circuit: QuantumCircuit, qubits: list, parameter_vector: ParameterVector
) -> tuple[QuantumCircuit, ParameterVector]:
"""
Builds a two-qubit unitary gate with a general parameterization,
consisting of real gates only, as given in the following reference paper.
Reference:
[1] F. Vatan and C. Williams, “Optimal quantum circuits for
general two-qubit gates,” Physical Review A, vol. 69, no. 3,
Mar. 2004, doi: https://doi.org/10.1103/physreva.69.032315.
Args:
circuit (QuantumCircuit): Circuit on which two-qubit
unitary gate needs to be applied.
qubits (list): list of qubits on which the gates need to
be applied.
parameter_vector (ParameterVector): list of parameters
of the unitary gates.
"""
block = circuit

block.rz(np.pi / 2, qubits[0])
Expand Down Expand Up @@ -89,6 +130,25 @@ def _real_general_block(
def _complex_general_block(
circuit: QuantumCircuit, qubits: list, parameter_vector: ParameterVector
) -> tuple[QuantumCircuit, ParameterVector]:
"""
Builds a two-qubit unitary gate with a general parameterization,
consisting of complex gates, as given in the following reference paper.
Reference:
[1] F. Vatan and C. Williams, “Optimal quantum circuits for
general two-qubit gates,” Physical Review A, vol. 69, no. 3,
Mar. 2004, doi: https://doi.org/10.1103/physreva.69.032315.
Args:
circuit (QuantumCircuit): Circuit on which two-qubit
unitary gate needs to be applied.
qubits (list): list of qubits on which the gates need to
be applied.
parameter_vector (ParameterVector): list of parameters
of the unitary gates.
"""
block = circuit
block.rz(parameter_vector[0], qubits[0])
block.ry(parameter_vector[1], qubits[0])
Expand Down
Loading

0 comments on commit eb4ed0b

Please sign in to comment.