Skip to content

Commit

Permalink
Add OnEach bloq (#346)
Browse files Browse the repository at this point in the history
* Add on each meta bloq.

* Format.

* Address review comments.

---------

Co-authored-by: Matthew Harrigan <[email protected]>
  • Loading branch information
fdmalone and mpharrigan authored Aug 16, 2023
1 parent 19c150b commit 9c2bb7b
Show file tree
Hide file tree
Showing 6 changed files with 101 additions and 0 deletions.
3 changes: 3 additions & 0 deletions qualtran/bloqs/basic_gates/hadamard.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ def add_my_tensors(
)
)

def short_name(self) -> 'str':
return 'H'

def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', q: 'CirqQuregT'
) -> Tuple['cirq.Operation', Dict[str, 'CirqQuregT']]:
Expand Down
3 changes: 3 additions & 0 deletions qualtran/bloqs/basic_gates/t_gate.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ def signature(self) -> 'Signature':
def t_complexity(self) -> 'TComplexity':
return TComplexity(t=1)

def short_name(self) -> str:
return 'T'

def as_cirq_op(
self, qubit_manager: 'cirq.QubitManager', q: 'CirqQuregT'
) -> Tuple['cirq.Operation', Dict[str, 'CirqQuregT']]:
Expand Down
3 changes: 3 additions & 0 deletions qualtran/bloqs/basic_gates/x_basis.py
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,9 @@ def add_my_tensors(
)
)

def short_name(self) -> str:
return 'X'

def on_classical_vals(self, q: int) -> Dict[str, 'ClassicalValT']:
return {'q': (q + 1) % 2}

Expand Down
3 changes: 3 additions & 0 deletions qualtran/bloqs/basic_gates/z_basis.py
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,9 @@ class ZGate(Bloq):
def signature(self) -> 'Signature':
return Signature.build(q=1)

def short_name(self) -> 'str':
return 'Z'

def add_my_tensors(
self,
tn: qtn.TensorNetwork,
Expand Down
57 changes: 57 additions & 0 deletions qualtran/bloqs/on_each.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Copyright 2023 Google LLC
#
# 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
#
# https://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.

"""Classes to apply single qubit bloq to multiple qubits."""
from functools import cached_property
from typing import Dict

import attrs

from qualtran import Bloq, BloqBuilder, Register, Signature, SoquetT


@attrs.frozen
class OnEach(Bloq):
"""Add a single-qubit (unparameterized) bloq on each of n qubits.
Args:
n: the number of qubits to add the bloq to.
gate: A single qubit gate. The single qubit register must be named q.
Registers:
- q: an n-qubit register.
"""

n: int
gate: Bloq

def __attrs_post_init__(self):
assert len(self.gate.signature) == 1, "Gate must only have a single register."
assert self.gate.signature[0].bitsize == 1, "Must be single qubit gate."
assert self.gate.signature[0].name == 'q', "Register must be named q."

@cached_property
def signature(self) -> Signature:
reg = Register('q', bitsize=self.n)
return Signature([reg])

def short_name(self) -> str:
return rf'{self.gate.short_name()}{self.n}'

def build_composite_bloq(self, bb: BloqBuilder, *, q: SoquetT) -> Dict[str, SoquetT]:

qs = bb.split(q)
for i in range(self.n):
qs[i] = bb.add(self.gate, q=qs[i])
return {'q': bb.join(qs)}
32 changes: 32 additions & 0 deletions qualtran/bloqs/on_each_test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# Copyright 2023 Google LLC
#
# 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
#
# https://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 functools import reduce

import numpy as np

import qualtran.testing as qlt_testing
from qualtran.bloqs.basic_gates import Hadamard, XGate
from qualtran.bloqs.on_each import OnEach


def test_valid_bloq():
on_each = OnEach(10, XGate())
qlt_testing.assert_valid_bloq_decomposition(on_each)


def test_tensor_contract():
bloq = OnEach(5, Hadamard())
tensor = bloq.tensor_contract()
single_had = Hadamard().tensor_contract()
np.testing.assert_allclose(tensor, reduce(np.kron, (single_had,) * 5))

0 comments on commit 9c2bb7b

Please sign in to comment.