Source code for mimiqcircuits.complex

#
# Copyright © 2023-2025 QPerfect. All Rights Reserved.
#
# 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 mimiqcircuits import Operation
import warnings


# raises a z-variable to a given power (passwd as a parameter of the operation)
[docs] class Pow(Operation): """ Raises a z-variable to a given power (passed as a parameter of the operation). Examples: >>> from mimiqcircuits import * >>> Pow(-1) z[?] = z[?]^(-1) >>> c = Circuit() >>> c.push(Pow(2), 1) 2-zvar circuit with 1 instructions: └── z[1] = z[1]^2 <BLANKLINE> """ _name = "Pow" _num_bits = 0 _num_qubits = 0 _num_cregs = 0 _num_zvars = 1 _num_zregs = 1 _qregsizes = [] _cregsizes = [] _zregsizes = [1] _parnames = ("exponent",) def __init__(self, exponent): if exponent == 1: warnings.warn("Pow(1) will be equivalent to a no-op.", stacklevel=2) super().__init__() self.exponent = exponent
[docs] def inverse(self): return Pow(-self.exponent)
[docs] def iswrapper(self): return False
def __repr__(self): if self.exponent >= 0: return f"z[?] = z[?]^{self.exponent}" return f"z[?] = z[?]^({self.exponent})" def __str__(self): return f"{self._name}({self.exponent})"
[docs] def format_with_targets(self, qubits, bits, zvars): idx = zvars[0] if self.exponent >= 0: return f"z[{idx}] = z[{idx}]^{self.exponent}" else: return f"z[{idx}] = z[{idx}]^({self.exponent})"
[docs] class Add(Operation): """ Add several z-register variables between them and optionally a constant. The result is strored in the first z-register variable given. Examples: >>> from mimiqcircuits import * >>> Add(1) z[?0] += 0.0 >>> Add(1,c=1) z[?0] += 1 >>> Add(3,1) z[?0] += 1 + z[?1] + z[?2] >>> Add(4, c=3) z[?0] += 3 + z[?1] + z[?2] + z[?3] >>> c = Circuit() >>> c.push(Add(2), 1, 2) 3-zvar circuit with 1 instructions: └── z[1] += 0.0 + z[2] <BLANKLINE> """ _name = "Add" _num_bits = 0 _num_qubits = 0 _num_qregs = 0 _num_cregs = 0 _qregsizes = [] _cregsizes = [] _parnames = ("term",) def __init__(self, N=1, c=0.0): if N < 1: raise ValueError("Add requires at least one z-variable.") if N == 1 and c == 0.0: warnings.warn("Add(1; c=0.0) will be equivalent to a no-op.", stacklevel=2) super().__init__() self._num_zvars = N self._num_zregs = 1 self._zregsizes = [N] self.term = c
[docs] def iswrapper(self): return False
def __repr__(self): repr = "z[?0] +=" parts = [str(self.term)] for i in range(1, self._num_zvars): parts.append(f"z[?{i}]") repr += " " + " + ".join(parts) return repr def __str__(self): return f"{self._name}({self._num_zvars}, c={self.term})"
[docs] def format_with_targets(self, qubits, bits, zvars): head = f"z[{zvars[0]}] +=" terms = [str(self.term)] terms.extend(f"z[{z}]" for z in zvars[1:]) return f"{head} {' + '.join(terms)}"
[docs] class Multiply(Operation): """ Multiply several z-register variables between them and optionally a constant. The result is strored in the first z-register variable given. Examples: >>> from mimiqcircuits import * >>> Multiply(1) z[?0] *= 1.0 >>> Multiply(3) z[?0] *= 1.0 * z[?1] * z[?2] >>> Multiply(3, c=2) z[?0] *= 2 * z[?1] * z[?2] >>> Multiply(2,2) z[?0] *= 2 * z[?1] >>> c = Circuit() >>> c.push(Multiply(2), 1, 2) 3-zvar circuit with 1 instructions: └── z[1] *= 1.0 * z[2] <BLANKLINE> """ _name = "Multiply" _num_bits = 0 _num_qubits = 0 _num_qregs = 0 _num_cregs = 0 _qregsizes = [] _cregsizes = [] _parnames = ("factor",) def __init__(self, N=1, c=1.0): if N < 1: raise ValueError("Multiply requires at least one z-variable.") if N == 1 and c == 1.0: warnings.warn( "Multiply(1; c=1.0) will be equivalent to a no-op.", stacklevel=2 ) def __init__(self, N=1, c=1.0): if N < 1: raise ValueError("Multiply requires at least one z-variable.") if N == 1 and c == 1.0: warnings.warn( "Multiply(1; c=1.0) will be equivalent to a no-op.", stacklevel=2 ) super().__init__() self._num_zvars = N self._num_zregs = 1 self._zregsizes = [N] self.factor = c
[docs] def iswrapper(self): return False
def __repr__(self): repr = "z[?0] *=" parts = [str(self.factor)] for i in range(1, self._num_zvars): parts.append(f"z[?{i}]") repr += " " + " * ".join(parts) return repr def __str__(self): return f"{self._name}({self.num_zvars}, c={self.factor})"
[docs] def format_with_targets(self, qubits, bits, zvars): head = f"z[{zvars[0]}] *=" terms = [str(self.factor)] terms.extend(f"z[{z}]" for z in zvars[1:]) return f"{head} {' * '.join(terms)}"
__all__ = ["Pow", "Add", "Multiply"]