Beispiel #1
0
    def __init__ ( self, num_qubits, gate_size, location ):
        """
        FixedGate Constructor

        Args:
            num_qubits (int): The number of qubits in the entire circuit

            gate_size (int): The number of qubits this gate acts on

            location (tuple[int]): The qubits this gate acts on
        """

        super().__init__( num_qubits, gate_size )

        if not utils.is_valid_location( location, num_qubits ):
            raise TypeError( "Specified location is invalid." )

        if len( location ) != gate_size:
            raise ValueError( "Location does not match gate size." )

        self.location = location

        self.Hcoef  = -1j / ( 2 ** num_qubits )
        self.sigmav = pauli.get_pauli_n_qubit_projection( num_qubits, location )
        self.sigmav = self.Hcoef * self.sigmav
Beispiel #2
0
    def __init__ ( self, num_qubits, gate_size, location ):
        """
        FixedGate Constructor

        Args:
            num_qubits (int): The number of qubits in the entire circuit

            gate_size (int): The number of qubits this gate acts on

            location (tuple[int]): The qubits this gate acts on
        """

        super().__init__( num_qubits, gate_size )

        if not utils.is_valid_location( location, num_qubits ):
            raise TypeError( "Specified location is invalid." )

        if len( location ) != gate_size:
            raise ValueError( "Location does not match gate size." )

        self.location = location

        self.Hcoef = -1j / ( 2 ** self.num_qubits )
        self.paulis = pauli.get_norder_paulis( self.gate_size )
        self.sigmav = self.Hcoef * np.array( self.paulis )
        self.I = np.identity( 2 ** ( num_qubits - gate_size ) )
        self.perm_matrix = perm.calc_permutation_matrix( num_qubits, location )
Beispiel #3
0
    def __init__(self, utry, location):
        """
        Gate Class Constructor

        Args:
            utry (np.ndarray): The gate's unitary operation.

            location (tuple[int]): The set of qubits the gate acts on.

        Raises:
            TypeError: If unitary or location are invalid.
        """

        if not utils.is_unitary(utry, tol=1e-14):
            raise TypeError("Invalid unitary.")

        self.utry = utry
        self.num_qubits = utils.get_num_qubits(self.utry)

        if not utils.is_valid_location(location):
            raise TypeError("Invalid location.")

        if len(location) != self.num_qubits:
            raise ValueError("Invalid size of location.")

        self.location = location
Beispiel #4
0
 def test_is_valid_location_invalid1(self):
     self.assertFalse(is_valid_location("a"))
     self.assertFalse(is_valid_location(0))
     self.assertFalse(is_valid_location("a", 256))
     self.assertFalse(is_valid_location(0, 256))
Beispiel #5
0
 def test_is_valid_location_valid(self):
     self.assertTrue(is_valid_location((0, 1, 2)))
     self.assertTrue(is_valid_location((0, 1, 2), 3))
     self.assertTrue(is_valid_location((0, 1, 2, 17)))
     self.assertTrue(is_valid_location((0, 1, 2, 17), 18))
Beispiel #6
0
 def test_is_valid_location_empty(self):
     self.assertTrue(is_valid_location(tuple()))
     self.assertTrue(is_valid_location(tuple(), 0))
     self.assertTrue(is_valid_location(tuple(), 3))
Beispiel #7
0
 def test_is_valid_location_invalid4(self):
     self.assertFalse(is_valid_location((0, 1, 2), 1))
     self.assertFalse(is_valid_location((0, 1, 2), 0))
Beispiel #8
0
 def test_is_valid_location_invalid3(self):
     self.assertFalse(is_valid_location((0, 0)))
     self.assertFalse(is_valid_location((0, 0), 256))
Beispiel #9
0
 def test_is_valid_location_invalid2(self):
     self.assertFalse(is_valid_location((0, "a", 2)))
     self.assertFalse(is_valid_location((0, "a", 2), 256))
Beispiel #10
0
def calc_permutation_matrix(num_qubits, location):
    """
    Creates the permutation matrix specified by arguments.

    This is done by moving the first len( locations ) qubits 
    into positions defined by location.

    Args:
        num_qubits (int): Total number of qubits

        location (Tuple[int]): The desired locations to swap
                                the starting qubits to.

    Returns:
        (np.ndarray): The permutation matrix

    Examples:
        calc_permutation_matrix( 2, (0, 1) ) =
            [ [ 1, 0, 0, 0 ],
              [ 0, 1, 0, 0 ],
              [ 0, 0, 1, 0 ],
              [ 0, 0, 0, 1 ] ]

        Here the 4x4 identity is returned because their are 2 total
        qubits, specified by the first parameter, and the desired
        permutation is [0, 1] -> [0, 1].

        calc_permutation_matrix( 2, (1,) ) =
        calc_permutation_matrix( 2, (1, 0) ) =
            [ [ 1, 0, 0, 0 ],
              [ 0, 0, 1, 0 ],
              [ 0, 1, 0, 0 ],
              [ 0, 0, 0, 1 ] ]

        This is a more interesting example. The swap gate is returned
        here since we are working with 2 qubits and want the permutation
        that swaps the two qubits, giving by the permutation [0] -> [1]
        or in the second case [0, 1] -> [1, 0]. Both calls produce
        identical permutations.
    """

    if not utils.is_valid_location(location, num_qubits):
        raise TypeError("Invalid location.")

    max_qubit = np.max(location)
    num_core_qubits = max_qubit + 1
    num_gate_qubits = len(location)

    perm = cb.Permutation(2**num_core_qubits)
    temp_pos = list(range(num_gate_qubits))

    for q in range(num_gate_qubits):
        perm *= swap(temp_pos[q], location[q], num_core_qubits)

        if location[q] < num_gate_qubits:
            temp_pos[location[q]] = temp_pos[q]

    matrix = np.identity(2**num_core_qubits)

    for transpos in reversed(perm.transpositions()):
        matrix[list(transpos), :] = matrix[list(reversed(transpos)), :]

    if num_qubits - num_core_qubits > 0:
        matrix = np.kron(matrix,
                         np.identity(2**(num_qubits - num_core_qubits)))

    return np.array(matrix)