Modular Subtraction#

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

ModNeg#

Performs modular negation.

Applies the operation \(\ket{x} \rightarrow \ket{-x \% p}\)

Note: This implements the decomposition from Fig 6 in but doesn’t match table 8 since we don’t use measurement based uncompution because that introduces random phase flips.

Parameters#

  • dtype: Datatype of the register.

  • p: The modulus for the negation.

Registers#

  • x: The register contraining the integer we negate.

References#

from qualtran.bloqs.mod_arithmetic import ModNeg

Example Instances#

n = 32
prime = sympy.Symbol('p')
mod_neg = ModNeg(QUInt(n), mod=prime)

Graphical Signature#

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

Call Graph#

from qualtran.resource_counting.generalizers import ignore_split_join
mod_neg_g, mod_neg_sigma = mod_neg.call_graph(max_depth=1, generalizer=ignore_split_join)
show_call_graph(mod_neg_g)
show_counts_sigma(mod_neg_sigma)
../../_images/49433003d6ae9207a7bca7c27a049f2c02b2d1eba066c1aaf3f6fa8dcaae8e39.svg

Counts totals:

  • AddK: 1

  • C[32][XGate]: 2

  • MultiTargetCNOT: 1

  • XGate: 2

CModNeg#

Performs controlled modular negation.

Applies the operation \(\ket{c}\ket{x} \rightarrow \ket{c}\ket{(-1)^c x\%p}\)

Note: while this matches the count from Fig 8, it’s a different decomposition that controls only the Add operation instead of turning the CNOTs into toffolis.

Parameters#

  • dtype: Datatype of the register.

  • p: The modulus for the negation.

  • cv: value at which the gate is active.

Registers#

  • ctrl: Control bit.

  • x: The register contraining the integer we negate.

References#

from qualtran.bloqs.mod_arithmetic import CModNeg

Example Instances#

n = 32
prime = sympy.Symbol('p')
cmod_neg = CModNeg(QUInt(n), mod=prime)

Graphical Signature#

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

Call Graph#

from qualtran.resource_counting.generalizers import ignore_split_join
cmod_neg_g, cmod_neg_sigma = cmod_neg.call_graph(max_depth=1, generalizer=ignore_split_join)
show_call_graph(cmod_neg_g)
show_counts_sigma(cmod_neg_sigma)
../../_images/90834da224a47d6bfff58d7c03bb55f0d8f3c923ec3b355e14b0058b6ffb5cf2.svg

Counts totals:

  • AddK: 1

  • And: 1

  • And†: 1

  • C^32XGate: 2

  • MultiTargetCNOT: 1

  • XGate: 2

ModSub#

Performs modular subtraction.

Applies the operation \(\ket{x} \ket{y} \rightarrow \ket{x} \ket{y-x \% p}\)

Parameters#

  • dtype: Datatype of the register.

  • p: The modulus for the negation.

Registers#

  • x: The register contraining the first integer.

  • y: The register contraining the second integer.

References#

from qualtran.bloqs.mod_arithmetic import ModSub

Example Instances#

n, p = sympy.symbols('n p')
modsub_symb = ModSub(QUInt(n), p)

Graphical Signature#

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

Call Graph#

from qualtran.resource_counting.generalizers import ignore_split_join
modsub_symb_g, modsub_symb_sigma = modsub_symb.call_graph(max_depth=1, generalizer=ignore_split_join)
show_call_graph(modsub_symb_g)
show_counts_sigma(modsub_symb_sigma)
../../_images/b2e000e3b4307bd649598e8c55e19d5c6a9ce260540a98e39b30a6fab2b52612.svg

Counts totals:

  • AddK: 1

  • AddK†: 1

  • BitwiseNot: 2

  • ModAdd: 1

CModSub#

Performs controlled modular subtraction.

Applies the operation \(\ket{c}\ket{x} \ket{y} \rightarrow \ket{c}\ket{x} \ket{y-cx \% p}\)

Parameters#

  • dtype: Datatype of the register.

  • p: The modulus for the negation.

  • cv: value at which the bloq is active.

Registers#

  • ctrl: control register.

  • x: The register contraining the first integer.

  • y: The register contraining the second integer.

References#

from qualtran.bloqs.mod_arithmetic import CModSub

Example Instances#

n, p = sympy.symbols('n p')
cmodsub_symb = CModSub(QUInt(n), p)

Graphical Signature#

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

Call Graph#

from qualtran.resource_counting.generalizers import ignore_split_join
cmodsub_symb_g, cmodsub_symb_sigma = cmodsub_symb.call_graph(max_depth=1, generalizer=ignore_split_join)
show_call_graph(cmodsub_symb_g)
show_counts_sigma(cmodsub_symb_sigma)
../../_images/043831ee90e1d64676e6f84538579cf45c1548b45ff2317e96eae75864d61d35.svg

Counts totals:

  • AddK: 1

  • AddK†: 1

  • BitwiseNot: 2

  • CModAdd: 1