-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #111 from qtzhuang/zqt
Add some pre-build circuit templates and tests
- Loading branch information
Showing
5 changed files
with
217 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
# (C) Copyright 2023 Beijing Academy of Quantum Information Sciences | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
"""Angel Embedding in Quantum Data embedding""" | ||
from quafu.circuits import QuantumCircuit | ||
import quafu.elements.element_gates as qeg | ||
import numpy as np | ||
|
||
ROT = {"X": qeg.RXGate, "Y": qeg.RYGate, "Z": qeg.RZGate} | ||
|
||
class AngleEmbedding: | ||
def __init__(self, features, num_qubits: int, rotation="X"): | ||
""" | ||
Args: | ||
features(np.array): The data to be embedded | ||
num_qubits(int): the number of qubit | ||
rotation(str): type of rotations used | ||
""" | ||
if rotation not in ROT: | ||
raise ValueError(f"Rotation option {rotation} not recognized.") | ||
|
||
shape = np.shape(features)[-1:] | ||
n_features = shape[0] | ||
if n_features != num_qubits: | ||
raise ValueError( | ||
"The length of Features must match num_qubits" | ||
) | ||
self.features = features | ||
self.num_qubits = num_qubits | ||
self.op = ROT[rotation] | ||
|
||
"""Build the embedding circuit and get the gate_list""" | ||
self.gate_list = self._build() | ||
|
||
def _build(self): | ||
gate_list = [] | ||
for i in range(self.num_qubits): | ||
gate = self.op(pos=i, paras=self.features[i]) | ||
gate_list.append(gate) | ||
return gate_list | ||
|
||
def __iter__(self): | ||
return iter(self.gate_list) | ||
|
||
def __getitem__(self, index): | ||
return self.gate_list[index] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
# (C) Copyright 2023 Beijing Academy of Quantum Information Sciences | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
"""Layers consisting of one-parameter single-qubit rotations on each qubit, followed by a closed chain or ring of CNOT gates""" | ||
from quafu.circuits import QuantumCircuit | ||
import quafu.elements.element_gates as qeg | ||
import numpy as np | ||
|
||
ROT = {"X": qeg.RXGate, "Y": qeg.RYGate, "Z": qeg.RZGate} | ||
|
||
class BasicEntangleLayers: | ||
def __init__(self, weights, num_qubits, rotation="X"): | ||
""" | ||
Args: | ||
weights(array): Each weight is used as a parameter for the rotation | ||
num_qubits(int): the number of qubit | ||
rotation(str): one-parameter single-qubit gate to use | ||
""" | ||
weights = np.asarray(weights) | ||
"""convert weights to numpy array if weights is list otherwise keep unchanged""" | ||
shape = np.shape(weights) | ||
|
||
##TODO(qtzhuang): If weights are batched, i.e. dim>3, additional processing is required | ||
if weights.ndim > 2: | ||
raise ValueError( | ||
f"Weights tensor must be 2-dimensional " | ||
) | ||
|
||
if not (len(shape) == 3 or len(shape) == 2): # 3 is when batching, 2 is no batching | ||
raise ValueError( | ||
f"Weights tensor must be 2-dimensional " | ||
f"or 3-dimensional if batching; got shape {shape}" | ||
) | ||
|
||
if shape[-1] != num_qubits: | ||
# index with -1 since we may or may not have batching in first dimension | ||
raise ValueError( | ||
f"Weights tensor must have last dimension of length {num_qubits}; got {shape[-1]}" | ||
) | ||
self.weights = weights | ||
self.num_qubits = num_qubits | ||
self.op = ROT[rotation] | ||
|
||
"""Build the quantum basic_entangle layer and get the gate_list""" | ||
self.gate_list = self._build() | ||
|
||
def _build(self): | ||
repeat = np.shape(self.weights)[-2] | ||
gate_list = [] | ||
for layer in range(repeat): | ||
for i in range(self.num_qubits): | ||
gate = self.op(pos=i, paras=self.weights[layer][i]) | ||
gate_list.append(gate) | ||
|
||
# if num_qubits equals two, it just need to apply CNOT one time | ||
if self.num_qubits == 2: | ||
gate_list.append(qeg.CXGate(0,1)) | ||
|
||
elif self.num_qubits > 2: | ||
for i in range(self.num_qubits): | ||
gate_list.append(qeg.CXGate(i,(i+1)%self.num_qubits)) | ||
|
||
return gate_list | ||
|
||
def __iter__(self): | ||
return iter(self.gate_list) | ||
|
||
def __getitem__(self, index): | ||
return self.gate_list[index] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# (C) Copyright 2023 Beijing Academy of Quantum Information Sciences | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
from quafu.circuits import QuantumCircuit | ||
import quafu.elements.element_gates as qeg | ||
from quafu.algorithms.embedding.angle import AngleEmbedding | ||
import numpy as np | ||
|
||
|
||
class TestAngleEmbedding: | ||
"""Example of angle embedding""" | ||
|
||
def test_build(self): | ||
num_qubits = 4 | ||
qc = QuantumCircuit(num_qubits) | ||
feature = np.array([[6,-12.5,11.15,7],[8,9.5,-11,-5],[5,0.5,8,-7]]) | ||
for i in range(4): | ||
qc.add_gate(qeg.HGate(pos=i)) | ||
for i in range(len(feature)): | ||
qc.add_gates(AngleEmbedding(features=feature[i], num_qubits=num_qubits,rotation='Y')) | ||
qc.draw_circuit(width=num_qubits) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# (C) Copyright 2023 Beijing Academy of Quantum Information Sciences | ||
# | ||
# Licensed under the Apache License, Version 2.0 (the "License"); | ||
# you may not use this file except in compliance with the License. | ||
# You may obtain a copy of the License at | ||
# | ||
# http://www.apache.org/licenses/LICENSE-2.0 | ||
# | ||
# Unless required by applicable law or agreed to in writing, software | ||
# distributed under the License is distributed on an "AS IS" BASIS, | ||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
# See the License for the specific language governing permissions and | ||
# limitations under the License. | ||
|
||
from quafu.circuits import QuantumCircuit | ||
import quafu.elements.element_gates as qeg | ||
from quafu.algorithms.layers.basic_entangle import BasicEntangleLayers | ||
import numpy as np | ||
|
||
class TestBasicEntangleLayers: | ||
"""Example of building basic_entangle layer""" | ||
def test_build(self): | ||
num_qubits = 3 | ||
qc = QuantumCircuit(num_qubits) | ||
weights = np.array([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6], [0.7, 0.8, 0.9]]) | ||
# weights = np.array([[0.1, 0.2, 0.3], [0.4, 0.5, 0.6]]) | ||
# weights = np.array([[0.1, 0.2], [0.3, 0.4]]) | ||
qc.add_gates(BasicEntangleLayers(weights=weights, num_qubits=num_qubits,rotation='Y')) | ||
qc.draw_circuit(width=num_qubits) | ||
|
||
##TODO(): if weights are as follows, it need additional processing. | ||
# weights = np.array([ | ||
# [ | ||
# [1, 2, 3, 4], | ||
# [5, 6, 7, 8], | ||
# [9, 10, 11, 12] | ||
# ], | ||
# [ | ||
# [13, 14, 15, 16], | ||
# [17, 18, 19, 20], | ||
# [21, 22, 23, 24] | ||
# ] | ||
# ]) |