#  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.

Apply to Lth Target#

from qualtran import Bloq, CompositeBloq, BloqBuilder, Signature, Register
from qualtran import QBit, QInt, QUInt, QAny
from qualtran.drawing import show_bloq, show_call_graph, show_counts_sigma
from typing import *
import numpy as np
import sympy
import cirq

ApplyGateToLthQubit#

A controlled SELECT operation for single-qubit gates.

\[ \mathrm{SELECT} = \sum_{l}|l \rangle \langle l| \otimes [G(l)]_l \]

Where \(G\) is a function that maps an index to a single-qubit gate.

This gate uses the unary iteration scheme to apply nth_gate(selection) to the selection-th qubit of target all controlled by the control register.

Parameters#

  • selection_regs: Indexing select signature of type Tuple[Register, …]. It also contains information about the iteration length of each selection register.

  • nth_gate: A function mapping the composite selection index to a single-qubit gate.

  • control_regs: Control signature for constructing a controlled version of the gate.

References#

from qualtran.bloqs.multiplexers.apply_gate_to_lth_target import ApplyGateToLthQubit

Example Instances#

from qualtran import BQUInt, Register

def _z_to_odd(n: int):
    if n % 2 == 1:
        return cirq.Z
    return cirq.I

apply_z_to_odd = ApplyGateToLthQubit(
    Register('selection', BQUInt(3, 4)),
    nth_gate=_z_to_odd,
    control_regs=Signature.build(control=2),
)

Graphical Signature#

from qualtran.drawing import show_bloqs
show_bloqs([apply_z_to_odd],
           ['`apply_z_to_odd`'])

Decomposition#

import qualtran.cirq_interop.testing as cq_testing
from qualtran.cirq_interop.jupyter_tools import display_gate_and_compilation

g = cq_testing.GateHelper(
    apply_z_to_odd
)

display_gate_and_compilation(g)
/usr/local/google/home/mpharrigan/qualtran/conda-311/lib/python3.11/site-packages/cotengra/hyperoptimizers/hyper.py:57: UserWarning: Couldn't find `optuna`, `cmaes`, `baytune (btb)`, `chocolate`, or `nevergrad` so will use completely random sampling in place of hyper-optimization.
  warnings.warn(
/usr/local/google/home/mpharrigan/qualtran/conda-311/lib/python3.11/site-packages/cotengra/hyperoptimizers/hyper.py:76: UserWarning: Couldn't find `optuna`, `cmaes`, `baytune (btb)`, `chocolate`, or `nevergrad` so will use completely random sampling in place of hyper-optimization.
  warnings.warn(

Call Graph#

from qualtran.resource_counting.generalizers import ignore_split_join
apply_z_to_odd_g, apply_z_to_odd_sigma = apply_z_to_odd.call_graph(max_depth=1, generalizer=ignore_split_join)
show_call_graph(apply_z_to_odd_g)
show_counts_sigma(apply_z_to_odd_sigma)
../../_images/11b65d33deb84c5774d3ad5b828d063dc16a897d70af85d3a50f694d2f8a3a4e.svg

Counts totals:

  • And: 1

  • And: 3

  • And†: 4

  • CNOT: 3

  • CZ: 2

  • I: 2