Beispiel #1
0
    def _throwExceptionIfObservableMeasurementIsNotValid(self, observable):
        if self.__is_dereferenced:
            raise IllegalRegisterReference("Measurement attempted on "
                                           "dereferenced register.")

        if not isinstance(observable, qOp):
            raise TypeError("Argument of measure_observable() must be a qOp.")

        if len(self) < observable.size():
            raise WrongShapeError("Observable larger than qReg.")
Beispiel #2
0
    def _throwExceptionIfRequestedMeasurementIsNotValid(self, target):
        if self.__is_dereferenced:
            raise IllegalRegisterReference('Measurement attempted on '
                                           'dereferenced register.')

        isTargetQubitIndexValid = (isinstance(target, int) and target >= 0
                                   and target < len(self))
        if not isTargetQubitIndexValid:
            raise IndexError('Quantum register address must be nonnegative '
                             'integer less than size of register.')
Beispiel #3
0
    def __imul__(self, some_reg):
        '''
        Concatentates the register with some_reg (|a_reg> *= |some_reg> stores
        |a_reg>|some_reg> into ``a_reg``).
        '''

        if not isinstance(some_reg, qReg):
            raise TypeError("Cannot concatentate a non-qReg to a qReg.")

        if self.__is_dereferenced or some_reg.__is_dereferenced:
            raise IllegalRegisterReference(
                'Concatentation attempted on dereferenced register.')

        self.__q_reg = self.__q_reg.qubit_product(some_reg._qReg__q_reg)
        some_reg._qReg__is_dereferenced = True

        return self
Beispiel #4
0
    def __mul__(self, another_reg):
        '''
        For concatenating the register with another_reg
        (|new> = |reg> * |another_reg> stores the product into ``new``).
        '''

        if self.__is_dereferenced or another_reg.__is_dereferenced:
            raise IllegalRegisterReference(
                'Concatenation attempted on dereferenced register.')

        product_register = qReg()
        product_qubits = self.__q_reg.qubit_product(another_reg._qReg__q_reg)
        product_register._qReg__q_reg.change_state(product_qubits.state())

        self.__is_dereferenced = True
        another_reg._qReg__is_dereferenced = True

        return product_register
Beispiel #5
0
    def dump_state(self):
        '''
        Returns a copy of the state of a ``qReg`` as a numpy array. Would have
        no effect on a hardware implementation of the backend. If the register
        has been dereferenced, raises an exception.

        Returns
        -------
        numpy.ndarray
            The state of ``qReg`` as a vector in the computational basis. Has
            no side effects.

        Examples
        --------
        Here we get a vector corresponding to the Hadamard state:

        >>> from pypsqueak.api import qReg
        >>> from pypsqueak.gates import H
        >>> a = qReg(3)
        >>> H.on(a, 0)
        >>> a.dump_state()
        array([0.70710678, 0.70710678, 0.        , 0.        , 0.        ,
               0.        , 0.        , 0.        ])

        Now we dereference the ``qReg`` and run into an exception when we try
        to dump its state again:

        >>> a * qReg()
        qReg(4)
        >>> a.dump_state()
        Traceback (most recent call last):
            File "<stdin>", line 1, in <module>
            File "pypsqueak/api.py", line 342, in dump_state
            exception.
        pypsqueak.errors.IllegalRegisterReference: Dereferenced register
        encountered.

        '''

        if self.__is_dereferenced:
            raise IllegalRegisterReference('Dereferenced register '
                                           'encountered.')

        return self.__q_reg.state()
Beispiel #6
0
    def __iadd__(self, n_new_qubits):
        '''
        Prepends ``n_new_qubits`` qubits to the register in the |0> state.
        Leaves register unchanged if n_new_qubits is zero.
        '''

        if self.__is_dereferenced:
            raise IllegalRegisterReference('Attempt to add Qubits to '
                                           'dereferenced register.')

        if not isinstance(n_new_qubits, int) or n_new_qubits < 0:
            raise ValueError("Can only add a nonnegative integer number of "
                             "qubits to qReg.")

        n_qubits_in_zero_state = Qubit(
            [1 if i == 0 else 0 for i in range(2**n_new_qubits)])

        self.__q_reg = n_qubits_in_zero_state.qubit_product(self.__q_reg)
        return self
Beispiel #7
0
    def peek(self):
        '''
        Returns a ket description of the state of a ``qReg``. Would have no
        effect on hardware implementations of the backend. If the register has
        been dereferenced, raises an exception.

        Returns
        -------
        str
            Description of ``qReg`` state. Has no side effects.

        Examples
        --------
        Here we peek at a register in the Hadamard state:

        >>> from pypsqueak.api import qReg
        >>> from pypsqueak.gates import H
        >>> a = qReg(3)
        >>> H.on(a, 0)
        >>> a.peek()
        '(7.07e-01)|000> + (7.07e-01)|001>'

        After dereferencing the register via a multiplication, calling
        ``peek()`` raises an exception:

        >>> a * qReg()
        qReg(4)
        >>> a.peek()
        Traceback (most recent call last):
            File "<stdin>", line 1, in <module>
            File "pypsqueak/api.py", line 309, in peek
                raise IllegalRegisterReference('Dereferenced register '
                                                     'encountered.')
        pypsqueak.errors.IllegalRegisterReference: Dereferenced register
        encountered.

        '''

        if self.__is_dereferenced:
            raise IllegalRegisterReference('Dereferenced register '
                                           'encountered.')

        return str(self.__q_reg)
Beispiel #8
0
    def __len__(self):
        if self.__is_dereferenced:
            raise IllegalRegisterReference(
                'Dereferenced register encountered.')

        return len(self.__q_reg)