Exemple #1
0
    def test_n_equals_9(self):
        n = 9
        # Obtain a random antisymmetric matrix
        rand_mat = numpy.random.randn(2 * n, 2 * n)
        antisymmetric_matrix = rand_mat - rand_mat.T

        # Get the diagonalizing fermionic unitary
        ferm_unitary = diagonalizing_fermionic_unitary(antisymmetric_matrix)
        lower_unitary = ferm_unitary[n:]

        # Get fermionic Gaussian decomposition of lower_unitary
        left_unitary, decomposition, diagonal = (
            fermionic_gaussian_decomposition(lower_unitary))

        # Check that left_unitary zeroes out the correct entries of
        # lower_unitary
        product = left_unitary.dot(lower_unitary)
        for i in range(n - 1):
            for j in range(n - 1 - i):
                self.assertAlmostEqual(product[i, j], 0.)

        # Compute right_unitary
        right_unitary = numpy.eye(2 * n, dtype=complex)
        for parallel_set in decomposition:
            combined_op = numpy.eye(2 * n, dtype=complex)
            for op in parallel_set:
                if op == 'pht':
                    swap_rows(combined_op, n - 1, 2 * n - 1)
                else:
                    i, j, theta, phi = op
                    c = numpy.cos(theta)
                    s = numpy.sin(theta)
                    phase = numpy.exp(1.j * phi)
                    givens_rotation = numpy.array(
                        [[c, -phase * s], [s, phase * c]], dtype=complex)
                    double_givens_rotate(combined_op, givens_rotation, i, j)
            right_unitary = combined_op.dot(right_unitary)

        # Compute left_unitary * lower_unitary * right_unitary^\dagger
        product = left_unitary.dot(lower_unitary.dot(right_unitary.T.conj()))

        # Construct the diagonal matrix
        diag = numpy.zeros((n, 2 * n), dtype=complex)
        diag[range(n), range(n, 2 * n)] = diagonal

        # Assert that W and D are the same
        for i in numpy.ndindex((n, 2 * n)):
            self.assertAlmostEqual(diag[i], product[i])
Exemple #2
0
    def test_n_equals_3(self):
        n = 3
        # Obtain a random antisymmetric matrix
        rand_mat = numpy.random.randn(2 * n, 2 * n)
        antisymmetric_matrix = rand_mat - rand_mat.T

        # Get the diagonalizing fermionic unitary
        ferm_unitary = diagonalizing_fermionic_unitary(antisymmetric_matrix)
        lower_unitary = ferm_unitary[n:]
        lower_left = lower_unitary[:, :n]
        lower_right = lower_unitary[:, n:]

        # Check that lower_left and lower_right satisfy the constraints
        # necessary for the transformed fermionic operators to satisfy
        # the fermionic anticommutation relations
        constraint_matrix_1 = (lower_left.dot(lower_left.T.conj()) +
                               lower_right.dot(lower_right.T.conj()))
        constraint_matrix_2 = (lower_left.dot(lower_right.T) +
                               lower_right.dot(lower_left.T))

        identity = numpy.eye(n, dtype=complex)
        for i in numpy.ndindex((n, n)):
            self.assertAlmostEqual(identity[i], constraint_matrix_1[i])
            self.assertAlmostEqual(0., constraint_matrix_2[i])
Exemple #3
0
 def test_not_antisymmetric(self):
     n = 4
     ones_mat = numpy.ones((n, n))
     with self.assertRaises(ValueError):
         ferm_unitary = diagonalizing_fermionic_unitary(ones_mat)
Exemple #4
0
 def test_bad_dimensions(self):
     n, p = (3, 4)
     ones_mat = numpy.ones((n, p))
     with self.assertRaises(ValueError):
         ferm_unitary = diagonalizing_fermionic_unitary(ones_mat)