This repository has been archived by the owner on Jul 5, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
/
endianness.py
161 lines (131 loc) · 6.06 KB
/
endianness.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# ======================================================================
# Copyright CERFACS (February 2018)
# Contributor: Adrien Suau ([email protected])
#
# This software is governed by the CeCILL-B license under French law and
# abiding by the rules of distribution of free software. You can use,
# modify and/or redistribute the software under the terms of the
# CeCILL-B license as circulated by CEA, CNRS and INRIA at the following
# URL "http://www.cecill.info".
#
# As a counterpart to the access to the source code and rights to copy,
# modify and redistribute granted by the license, users are provided
# only with a limited warranty and the software's author, the holder of
# the economic rights, and the successive licensors have only limited
# liability.
#
# In this respect, the user's attention is drawn to the risks associated
# with loading, using, modifying and/or developing or reproducing the
# software by the user in light of its specific status of free software,
# that may mean that it is complicated to manipulate, and that also
# therefore means that it is reserved for developers and experienced
# professionals having in-depth computer knowledge. Users are therefore
# encouraged to load and test the software's suitability as regards
# their requirements in conditions enabling the security of their
# systems and/or data to be ensured and, more generally, to use and
# operate it in the same conditions as regards security.
#
# The fact that you are presently reading this means that you have had
# knowledge of the CeCILL-B license and that you accept its terms.
# ======================================================================
"""This module define some useful functions and types to deal with endianness.
Requires:
- qiskit module
"""
from typing import Union
from qiskit import QuantumRegister, ClassicalRegister, QuantumCircuit, \
CompositeGate, QuantumProgram
from utils.register import QRegisterBase
# Type alias definition
GateContainer = Union[QuantumCircuit, CompositeGate]
class QRegisterLE(QRegisterBase):
"""Quantum Register Little Endian."""
pass
class QRegisterBE(QRegisterBase):
"""Quantum Register Big Endian."""
pass
class QRegisterPhaseLE(QRegisterBase):
"""Quantum Register Little Endian in Quantum Fourier Transform state."""
pass
class QRegisterPhaseBE(QRegisterBase):
"""Quantum Register Big Endian in Quantum Fourier Transform state."""
pass
class CRegisterBase(ClassicalRegister):
"""Classical Register."""
def __init__(self, *args, **kwargs):
# Copy constructor
if len(args) == 1 and isinstance(args[0], ClassicalRegister):
classical_register = args[0]
self.name = classical_register.name
self.size = classical_register.size
# (name, qubit_number) constructor with QuantumProgram
elif len(args) > 1 and isinstance(args[0], QuantumProgram):
quantum_program = args[0]
args = args[1:]
classical_register = quantum_program.create_classical_register(*args, **kwargs)
self.name = classical_register.name
self.size = classical_register.size
# Delegate the constructor to the super class.
else:
super().__init__(*args, **kwargs)
class CRegister(CRegisterBase):
"""Classical Register."""
pass
def apply_LE_operation(container: GateContainer,
little_endian_operation,
qreg: QuantumRegister):
"""Apply a little endian operation to a quantum register.
This function will change the endianness of the given register if
it is not already in little endian, apply the operation, and recover
the initial endianness.
Warning: if the type of the given register does not give any
information on its endianness (inheriting from
QRegisterLE or QRegisterBE) then the operation will be
applied on the register without any endianness
consideration.
"""
if isinstance(qreg, QRegisterBE):
qreg._reverse_access_endian()
# Here we may have an instance of QRegisterBE which is
# in little endian when we access it. This should be
# avoided, that is why the method _reverse_access_endian
# is "private".
little_endian_operation(container, qreg)
# As written above, we may have a strange register (labeled
# as big endian but effectively in little endian). Don't
# forget to fix this register by changing again it's
# endianness.
if isinstance(qreg, QRegisterBE):
qreg._reverse_access_endian()
def apply_BE_operation(container: GateContainer,
big_endian_operation,
qreg: QuantumRegister):
"""Apply a big endian operation to a quantum register.
This function will change the endianness of the given register if
it is not already in big endian, apply the operation, and recover
the initial endianness.
Warning: if the type of the given register does not give any
information on its endianness (inheriting from
QRegisterLE or QRegisterBE) then the operation will be
applied on the register without any endianness
consideration.
"""
if isinstance(qreg, QRegisterLE):
qreg._reverse_access_endian()
# Here we may have an instance of QRegisterLE which is
# in big endian when we access it. This should be
# avoided, that is why the method _reverse_access_endian
# is "private".
big_endian_operation(container, qreg)
# As written above, we may have a strange register (labeled
# as little endian but effectively in big endian). Don't
# forget to fix this register by changing again it's
# endianness.
if isinstance(qreg, QRegisterLE):
qreg._reverse_access_endian()
def swap_endianness(self: GateContainer,
qreg: Union[QRegisterBE, QRegisterLE]):
"""Swaps the endianness of qreg."""
qubit_number = len(qreg)
for i in range(qubit_number//2):
self.swap(qreg[i], qreg[qubit_number-1-i])