Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 42 additions & 26 deletions Standard/src/Arithmetic/Modular.qs
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,31 @@ namespace Microsoft.Quantum.Arithmetic {
/// # Summary
/// Performs a modular increment of a qubit register by an integer constant.
///
/// Let us denote `increment` by a, `modulus` by N and integer encoded in `target` by y
/// # Description
/// Let us denote `increment` by $a$, `modulus` by $N$ and integer encoded in `target` by $y$.
/// Then the operation performs the following transformation:
/// \begin{align}
/// \ket{y} \mapsto \ket{y + 1 \operatorname{mod} N}
/// \ket{y} \mapsto \ket{(y + a) \operatorname{mod} N}
/// \end{align}
/// Integers are encoded in little-endian format.
///
/// # Input
/// ## increment
/// Integer increment a to be added to y.
/// Integer increment $a$ to be added to $y$.
/// ## modulus
/// Integer N that mods y + a.
/// Integer $N$ that mods $y + a$.
/// ## target
/// Integer y in `LittleEndian` format that `increment` a is added to.
/// Integer $y$ in `LittleEndian` format that `increment` $a$ is added to.
///
/// # See Also
/// - IncrementPhaseByModularInteger
/// - Microsoft.Quantum.Arithmetic.IncrementPhaseByModularInteger
///
/// # Remarks
/// Assumes that the value of target is less than N. Note that
/// Assumes that the initial value of target is less than $N$
/// and that the increment $a$ is less than $N$.
/// Note that
/// <xref:microsoft.quantum.arithmetic.incrementphasebymodularinteger> implements
/// the same operation, but in the `PhaseLittleEndian` basis.
/// the same operation in the `PhaseLittleEndian` basis.
operation IncrementByModularInteger(increment : Int, modulus : Int, target : LittleEndian) : Unit {
body (...) {
let inner = IncrementPhaseByModularInteger(increment, modulus, _);
Expand All @@ -50,17 +53,20 @@ namespace Microsoft.Quantum.Arithmetic {
/// # Summary
/// Performs a modular increment of a qubit register by an integer constant.
///
/// Let us denote `increment` by a, `modulus` by N and integer encoded in `target` by y
/// # Description
/// Let us denote `increment` by $a$, `modulus` by $N$ and integer encoded in `target` by $y$.
/// Then the operation performs the following transformation:
/// |y⟩ ↦ |y+a (mod N)⟩
/// Integers are encoded in little-endian format in QFT basis
/// \begin{align}
/// \ket{y} \mapsto \ket{(y + a) \operatorname{mod} N}
/// \end{align}
/// Integers are encoded in little-endian format in QFT basis.
///
/// # See Also
/// - Microsoft.Quantum.Canon.ModularIncrementLE
/// - Microsoft.Quantum.Arithmetic.IncrementByModularInteger
///
/// # Remarks
/// Assumes that `target` has the highest bit set to 0.
/// Also assumes that the value of target is less than N.
/// Also assumes that the value of target is less than $N$.
///
/// For the circuit diagram and explanation see Figure 5 on [Page 5
/// of arXiv:quant-ph/0205095v3](https://arxiv.org/pdf/quant-ph/0205095v3.pdf#page=5).
Expand Down Expand Up @@ -113,10 +119,11 @@ namespace Microsoft.Quantum.Arithmetic {
/// # Summary
/// Performs a modular multiply-and-add by integer constants on a qubit register.
///
/// # Description
/// Implements the map
/// $$
/// \begin{align}
/// \ket{x} \ket{b} \mapsto \ket{x} \ket{b + a \cdot x \operatorname{mod} N}
/// \ket{x} \ket{b} \mapsto \ket{x} \ket{(b + a \cdot x) \operatorname{mod} N}
/// \end{align}
/// $$
/// for a given modulus $N$, constant multiplier $a$, and summand $y$.
Expand All @@ -133,6 +140,9 @@ namespace Microsoft.Quantum.Arithmetic {
/// A quantum register representing an unsigned integer to use as the target
/// for this operation.
///
/// # See Also
/// - Microsoft.Quantum.Arithmetic.MultiplyAndAddPhaseByModularInteger
///
/// # Remarks
/// - For the circuit diagram and explanation see Figure 6 on [Page 7
/// of arXiv:quant-ph/0205095v3](https://arxiv.org/pdf/quant-ph/0205095v3.pdf#page=7)
Expand All @@ -153,15 +163,15 @@ namespace Microsoft.Quantum.Arithmetic {
}

/// # Summary
/// The same as ModularAddProductLE, but assumes that summand encodes
/// integers in QFT basis
///
/// # See Also
/// - Microsoft.Quantum.Canon.ModularAddProductLE
/// The same as MultiplyAndAddByModularInteger, but assumes that the summand encodes
/// integers in QFT basis.
///
/// # Remarks
/// Assumes that `phaseSummand` has the highest bit set to 0.
/// Also assumes that the value of `phaseSummand` is less than N.
/// Also assumes that the value of `phaseSummand` is less than $N$.
///
/// # See Also
/// - Microsoft.Quantum.Arithmetic.MultiplyAndAddByModularInteger
operation MultiplyAndAddPhaseByModularInteger(constMultiplier : Int, modulus : Int, multiplier : LittleEndian, phaseSummand : PhaseLittleEndian) : Unit is Adj + Ctl {
EqualityFactB(modulus <= 2 ^ (Length(phaseSummand!) - 1), true, $"`multiplier` must be big enough to fit integers modulo `modulus`" + $"with highest bit set to 0");
EqualityFactB(constMultiplier >= 0 and constMultiplier < modulus, true, $"`constMultiplier` must be between 0 and `modulus`-1");
Expand All @@ -183,19 +193,25 @@ namespace Microsoft.Quantum.Arithmetic {
/// # Summary
/// Performs modular multiplication by an integer constant on a qubit register.
///
/// Let us denote modulus by N and constMultiplier by a
/// then this operation implements a unitary defined by the following map on
/// # Description
/// Let us denote `modulus` by $N$ and `constMultiplier` by $a$.
/// Then this operation implements a unitary operation defined by the following map on the
/// computational basis:
/// |y⟩ ↦ |a⋅y (mod N) ⟩, for all y between 0 and N - 1
/// $$
/// \begin{align}
/// \ket{y} \mapsto \ket{(a \cdot y) \operatorname{mod} N}
/// \end{align}
/// $$
/// for all $y$ between $0$ and $N - 1$.
///
/// # Input
/// ## constMultiplier
/// Constant by which multiplier is being multiplied. Must be co-prime to modulus.
/// ## modulus
/// The multiplication operation is performed modulo `modulus`
/// The multiplication operation is performed modulo `modulus`.
/// ## multiplier
/// The number being multiplied by a constant.
/// This is an array of qubits representing integer in little-endian bit order.
/// This is an array of qubits encoding an integer in little-endian format.
///
/// # Remarks
/// - For the circuit diagram and explanation see Figure 7 on [Page 8
Expand All @@ -204,7 +220,7 @@ namespace Microsoft.Quantum.Arithmetic {
/// [arXiv:quant-ph/0205095v3](https://arxiv.org/pdf/quant-ph/0205095v3.pdf)
operation MultiplyByModularInteger(constMultiplier : Int, modulus : Int, multiplier : LittleEndian) : Unit is Adj + Ctl {
// Check the preconditions using Microsoft.Quantum.Canon.EqualityFactB
EqualityFactB(constMultiplier >= 0 and constMultiplier < modulus, true, $"`constMultiplier` must be between 0 and `modulus`");
EqualityFactB(0 <= constMultiplier and constMultiplier < modulus, true, $"`constMultiplier` must be between 0 and `modulus`");
EqualityFactB(modulus <= 2 ^ Length(multiplier!), true, $"`multiplier` must be big enough to fit integers modulo `modulus`");
EqualityFactB(IsCoprimeI(constMultiplier, modulus), true, $"`constMultiplier` and `modulus` must be co-prime");

Expand Down