def test_generate_dnf_hamiltonian_content(self):
        clauses = [
            dnf_lib.Clause(2, 4, True, False),
            dnf_lib.Clause(5, 4, True, True)
        ]
        dnf = dnf_lib.DNF(10, clauses)

        circuit = cirq.Circuit()
        circuit.append(dnf_circuit_lib.generate_dnf_hamiltonian_exponential(
            dnf, 0.25),
                       strategy=insert_strategy.InsertStrategy.NEW_THEN_INLINE)

        operations = list(circuit.all_operations())
        self.assertCountEqual(operations, [
            cirq.ZPowGate(exponent=-0.5 / math.pi, global_shift=-0.5).on(
                cirq.LineQubit(4)),
            cirq.ZPowGate(exponent=0.5 / math.pi, global_shift=-0.5).on(
                cirq.LineQubit(2)),
            cirq.ZZPowGate(exponent=0.5 / math.pi, global_shift=-0.5).on(
                cirq.LineQubit(2), cirq.LineQubit(4)),
            cirq.ZPowGate(exponent=0.5 / math.pi, global_shift=-0.5).on(
                cirq.LineQubit(4)),
            cirq.ZPowGate(exponent=0.5 / math.pi, global_shift=-0.5).on(
                cirq.LineQubit(5)),
            cirq.ZZPowGate(exponent=-0.5 / math.pi, global_shift=-0.5).on(
                cirq.LineQubit(4), cirq.LineQubit(5)),
        ])
    def test_generate_dnf_hamiltonian_order(self):
        circuit = cirq.Circuit()
        dnf = dnf_lib.DNF(10, [dnf_lib.Clause(5, 7, False, False)])
        circuit.append(dnf_circuit_lib.generate_dnf_hamiltonian_exponential(
            dnf, 0.5),
                       strategy=insert_strategy.InsertStrategy.NEW_THEN_INLINE)

        generator = circuit.all_operations()

        operation = next(generator)
        self.assertEqual(
            operation,
            cirq.ZPowGate(exponent=-1.0 / math.pi,
                          global_shift=-0.5).on(cirq.LineQubit(5)))

        operation = next(generator)
        self.assertEqual(
            operation,
            cirq.ZPowGate(exponent=-1.0 / math.pi,
                          global_shift=-0.5).on(cirq.LineQubit(7)))

        operation = next(generator)
        self.assertEqual(
            operation,
            cirq.ZZPowGate(exponent=-1.0 / math.pi,
                           global_shift=-0.5).on(cirq.LineQubit(5),
                                                 cirq.LineQubit(7)))

        with self.assertRaises(StopIteration):
            next(generator)
Пример #3
0
 def test_eval(self, literals, expected_evaluation):
     # (x_0 OR x_2) AND (x_1 OR not(x_2))
     clauses = [
         dnf_lib.Clause(0, 2, False, False),
         dnf_lib.Clause(1, 2, False, True)
     ]
     dnf = dnf_lib.DNF(3, clauses)
     self.assertEqual(dnf.eval(literals), expected_evaluation)
 def test_get_probabilities_wrong_shape(self):
     dnf = dnf_lib.DNF(2, [dnf_lib.Clause(0, 1, True, False)])
     # time is chosen so that ZPowGate = sqrt(Z) and Rx = sqrt(X) up to phase.
     circuit = dnf_circuit_lib.BangBangProtocolCircuit(math.pi / 4, dnf)
     with self.assertRaisesRegex(
             ValueError,
             r'The shape of wavefunction should be \(4\,\) but got \(3\,\)'
     ):
         circuit.get_probabilities(wavefunction=np.array([1., 0., 0.]))
Пример #5
0
 def test_get_num_clauses_satisfied(self, literals,
                                    expected_clauses_satisfied):
     # (x_0 OR x_2) AND (x_1 OR not(x_2))
     clauses = [
         dnf_lib.Clause(0, 2, False, False),
         dnf_lib.Clause(1, 2, False, True)
     ]
     dnf = dnf_lib.DNF(3, clauses)
     self.assertEqual(dnf.get_num_clauses_satisfied(literals),
                      expected_clauses_satisfied)
 def test_constraint_evaluation(self, measurement, expected_value):
     dnf = dnf_lib.DNF(4, [
         dnf_lib.Clause(0, 1, False, False),
         dnf_lib.Clause(0, 1, True, True),
         dnf_lib.Clause(0, 1, False, True),
         dnf_lib.Clause(0, 1, True, False),
         dnf_lib.Clause(2, 3, False, False)
     ])
     self.assertEqual(dnf.optimal_num_satisfied, 4)
     circuit = dnf_circuit_lib.BangBangProtocolCircuit(1, dnf)
     self.assertEqual(circuit.constraint_evaluation(measurement),
                      expected_value)
 def test_get_constraint_expectation(self):
     dnf = dnf_lib.DNF(2, [dnf_lib.Clause(0, 1, True, False)])
     # time is chosen so that ZPowGate = sqrt(Z) and Rx = sqrt(X) up to phase.
     circuit = dnf_circuit_lib.BangBangProtocolCircuit(math.pi / 4, dnf)
     bangbang_protocol = [
         circuit_lib.HamiltonianType.CONSTRAINT,
         circuit_lib.HamiltonianType.X,
     ]
     self.assertAlmostEqual(circuit.get_constraint_expectation(
         circuit.get_wavefunction(bangbang_protocol)),
                            0.5,
                            places=5)
Пример #8
0
 def test_str(self):
     clauses = [
         dnf_lib.Clause(0, 2, False, False),
         dnf_lib.Clause(1, 2, False, True)
     ]
     dnf = dnf_lib.DNF(3, clauses)
     expected_regex = (r'^Number of Literals: 3, '
                       r'DNF: \(\!?x_\d \|\| \!?x_\d\) && '
                       r'\(\!?x_\d \|\| \!?x_\d\)$')
     self.assertRegex(str(dnf), expected_regex)
     self.assertIn('(x_0 || x_2)', str(dnf))
     self.assertIn('(x_1 || !x_2)', str(dnf))
 def test_get_probabilities(self):
     dnf = dnf_lib.DNF(2, [dnf_lib.Clause(0, 1, True, False)])
     # time is chosen so that ZPowGate = sqrt(Z) and Rx = sqrt(X) up to phase.
     circuit = dnf_circuit_lib.BangBangProtocolCircuit(math.pi / 4, dnf)
     bangbang_protocol = [
         circuit_lib.HamiltonianType.CONSTRAINT,
         circuit_lib.HamiltonianType.X,
     ]
     probabilities = circuit.get_probabilities(
         circuit.get_wavefunction(bangbang_protocol))
     np.testing.assert_allclose(probabilities, [0, 0.5, 0.5, 0],
                                atol=0.00001)
 def test_get_wavefunction(self):
     dnf = dnf_lib.DNF(2, [dnf_lib.Clause(0, 1, True, False)])
     # time is chosen so that ZPowGate = sqrt(Z) and Rx = sqrt(X) up to phase.
     circuit = dnf_circuit_lib.BangBangProtocolCircuit(math.pi / 4, dnf)
     bangbang_protocol = [
         circuit_lib.HamiltonianType.CONSTRAINT,
         circuit_lib.HamiltonianType.X,
     ]
     cirq.testing.assert_allclose_up_to_global_phase(
         circuit.get_wavefunction(bangbang_protocol),
         np.array([0, (1 + 1j) / 2, (-1 + 1j) / 2, 0]),
         atol=0.000001)
 def test_stochastic_descent_neg_max_num_flips(self):
     # Every 2-SAT with just one clause will not be satisfied by 1/4 of all
     # possible literal assignments.
     # With only one bang, the only way to do better than random guessing is to
     # apply the DNF hamiltonian.
     dnf = dnf_lib.DNF(3, [dnf_lib.Clause(0, 1, False, True)])
     circuit = dnf_circuit_lib.BangBangProtocolCircuit(1, dnf)
     with self.assertRaisesRegex(
             ValueError, 'max_num_flips should be positive, not -10'):
         stochastic_descent_lib.stochastic_descent(
             circuit=circuit,
             max_num_flips=-10,
             initial_protocol=stochastic_descent_lib.get_random_protocol(5),
             minimize=False)
 def test_stochastic_descent_epoch_neg_max_num_flips(self):
     dnf = dnf_lib.DNF(3, [dnf_lib.Clause(0, 1, False, True)])
     circuit = dnf_circuit_lib.BangBangProtocolCircuit(1, dnf)
     with self.assertRaisesRegex(ValueError,
                                 'max_num_flips should be positive, not 0'):
         stochastic_descent_lib._stochastic_descent_epoch(
             circuit=circuit,
             bangbang_protocol=[
                 circuit_lib.HamiltonianType.X,
                 circuit_lib.HamiltonianType.X,
                 circuit_lib.HamiltonianType.CONSTRAINT
             ],
             max_num_flips=0,
             previous_eval=0.75,
             minimize=False)
 def test_stochastic_descent_skip_search(self):
     dnf = dnf_lib.DNF(2, [dnf_lib.Clause(0, 1, True, True)])
     circuit = dnf_circuit_lib.BangBangProtocolCircuit(1, dnf)
     random_protocol = stochastic_descent_lib.get_random_protocol(2)
     random_eval = circuit.get_constraint_expectation(
         circuit.get_wavefunction(random_protocol))
     protocol, evaluation, num_epoch = stochastic_descent_lib.stochastic_descent(
         circuit=circuit,
         max_num_flips=1,
         initial_protocol=random_protocol,
         minimize=False,
         skip_search=True)
     self.assertListEqual(protocol, random_protocol)
     self.assertIsInstance(evaluation, float)
     self.assertAlmostEqual(evaluation, random_eval)
     # Zero epoch of stochastic descent.
     self.assertEqual(num_epoch, 0)
 def test_stochastic_descent_epoch_minimize(self):
     # Every 2-SAT with just one clause will not be satisfied by 1/4 of all
     # possible literal assignments.
     dnf = dnf_lib.DNF(3, [dnf_lib.Clause(0, 1, False, True)])
     circuit = dnf_circuit_lib.BangBangProtocolCircuit(1, dnf)
     protocol, evaluation = stochastic_descent_lib._stochastic_descent_epoch(
         circuit=circuit,
         bangbang_protocol=[
             circuit_lib.HamiltonianType.X, circuit_lib.HamiltonianType.X,
             circuit_lib.HamiltonianType.CONSTRAINT
         ],
         max_num_flips=2,
         previous_eval=0.75,
         minimize=True)
     self.assertLen(protocol, 3)
     self.assertIsInstance(evaluation, float)
     self.assertLessEqual(evaluation, 0.75)
 def test_generate_qaoa_circuit(self):
     dnf = dnf_lib.DNF(5, [dnf_lib.Clause(1, 2, False, False)])
     circuit = dnf_circuit_lib.BangBangProtocolCircuit(0.2, dnf)
     qaoa_circuit = circuit.qaoa_circuit([
         circuit_lib.HamiltonianType.CONSTRAINT,
         circuit_lib.HamiltonianType.CONSTRAINT,
         circuit_lib.HamiltonianType.CONSTRAINT,
         circuit_lib.HamiltonianType.X,
         circuit_lib.HamiltonianType.CONSTRAINT,
         circuit_lib.HamiltonianType.X,
         circuit_lib.HamiltonianType.X,
     ])
     # Should 21 contain gates
     # 5 gates from Hadamard Layer
     # 2 layers of X Hamiltonian, which has 5 gates each
     # 2 layers of DNF Hamiltonian, which has 3 gates each
     # 5 + 2*5 + 2*3  = 21
     self.assertLen(list(qaoa_circuit.all_operations()), 21)
 def test_stochastic_descent_maximize(self):
     # Every 2-SAT with just one clause will not be satisfied by 1/4 of all
     # possible literal assignments.
     # With only one bang, the only way to do better than random guessing is to
     # apply the DNF hamiltonian.
     dnf = dnf_lib.DNF(2, [dnf_lib.Clause(0, 1, True, True)])
     circuit = dnf_circuit_lib.BangBangProtocolCircuit(1, dnf)
     random_protocol = stochastic_descent_lib.get_random_protocol(2)
     random_eval = circuit.get_constraint_expectation(
         circuit.get_wavefunction(random_protocol))
     protocol, evaluation, num_epoch = stochastic_descent_lib.stochastic_descent(
         circuit=circuit,
         max_num_flips=2,
         initial_protocol=stochastic_descent_lib.get_random_protocol(5),
         minimize=False)
     self.assertLen(protocol, 5)
     self.assertIsInstance(evaluation, float)
     self.assertGreaterEqual(evaluation, random_eval)
     # Contain at least 1 epoch of stochastic descent.
     self.assertGreaterEqual(num_epoch, 1)
Пример #17
0
class DNFTest(parameterized.TestCase):
    @parameterized.parameters(
        (dnf_lib.DNF(20, []), 20, set(), 0),
        (dnf_lib.DNF(5, [
            dnf_lib.Clause(0, 1, True, True),
            dnf_lib.Clause(3, 4, False, False)
        ]), 5,
         set([
             dnf_lib.Clause(0, 1, True, True),
             dnf_lib.Clause(3, 4, False, False)
         ]), 2),
        (dnf_lib.DNF(4, [
            dnf_lib.Clause(0, 1, False, False),
            dnf_lib.Clause(0, 1, True, True),
            dnf_lib.Clause(0, 1, False, True),
            dnf_lib.Clause(0, 1, True, False)
        ]), 4,
         set([
             dnf_lib.Clause(0, 1, False, False),
             dnf_lib.Clause(0, 1, True, True),
             dnf_lib.Clause(0, 1, False, True),
             dnf_lib.Clause(0, 1, True, False)
         ]), 3),
        # Duplicated clauses.
        (dnf_lib.DNF(5, [
            dnf_lib.Clause(0, 1, True, True),
            dnf_lib.Clause(0, 1, True, True)
        ]), 5, set([dnf_lib.Clause(0, 1, True, True)]), 1),
    )
    def test_init(self, dnf, expected_literals, expected_clauses,
                  expected_optimal):
        self.assertEqual(dnf.num_literals, expected_literals)
        self.assertSetEqual(dnf.clauses, expected_clauses)
        self.assertEqual(dnf.optimal_num_satisfied, expected_optimal)

    @parameterized.parameters(
        (dnf_lib.DNF(5, [
            dnf_lib.Clause(0, 1, True, True),
            dnf_lib.Clause(3, 4, False, False)
        ]), 2),
        (dnf_lib.DNF(4, [
            dnf_lib.Clause(0, 1, False, False),
            dnf_lib.Clause(0, 1, True, True),
            dnf_lib.Clause(0, 1, False, True),
            dnf_lib.Clause(0, 1, True, False)
        ]), 3),
    )
    def test_get_optimal_num_satisfied(self, dnf, expected_value):
        self.assertEqual(dnf._get_optimal_num_satisfied(), expected_value)

    @parameterized.parameters(
        (-5, 'num_literals must be at least 2, not -5'),
        (1, 'num_literals must be at least 2, not 1'),
    )
    def test_init_neg_num(self, num_literals, error_message):
        with self.assertRaisesRegex(ValueError, error_message):
            dnf_lib.DNF(num_literals, set())

    def test_str(self):
        clauses = [
            dnf_lib.Clause(0, 2, False, False),
            dnf_lib.Clause(1, 2, False, True)
        ]
        dnf = dnf_lib.DNF(3, clauses)
        expected_regex = (r'^Number of Literals: 3, '
                          r'DNF: \(\!?x_\d \|\| \!?x_\d\) && '
                          r'\(\!?x_\d \|\| \!?x_\d\)$')
        self.assertRegex(str(dnf), expected_regex)
        self.assertIn('(x_0 || x_2)', str(dnf))
        self.assertIn('(x_1 || !x_2)', str(dnf))

    @parameterized.parameters(
        ([True, True, True], True),
        ([True, True, False], True),
        ([True, False, True], False),
        ([True, False, False], True),
        ([False, True, True], True),
        ([False, True, False], False),
        ([False, False, True], False),
        ([False, False, False], False),
    )
    def test_eval(self, literals, expected_evaluation):
        # (x_0 OR x_2) AND (x_1 OR not(x_2))
        clauses = [
            dnf_lib.Clause(0, 2, False, False),
            dnf_lib.Clause(1, 2, False, True)
        ]
        dnf = dnf_lib.DNF(3, clauses)
        self.assertEqual(dnf.eval(literals), expected_evaluation)

    @parameterized.parameters(
        ([True, True, True], 2),
        ([True, True, False], 2),
        ([True, False, True], 1),
        ([True, False, False], 2),
        ([False, True, True], 2),
        ([False, True, False], 1),
        ([False, False, True], 1),
        ([False, False, False], 1),
    )
    def test_get_num_clauses_satisfied(self, literals,
                                       expected_clauses_satisfied):
        # (x_0 OR x_2) AND (x_1 OR not(x_2))
        clauses = [
            dnf_lib.Clause(0, 2, False, False),
            dnf_lib.Clause(1, 2, False, True)
        ]
        dnf = dnf_lib.DNF(3, clauses)
        self.assertEqual(dnf.get_num_clauses_satisfied(literals),
                         expected_clauses_satisfied)

    @parameterized.parameters((2, 4), (5, 40), (10, 180))
    def test_get_number_of_possible_clauses(
            self, num_literals, expected_number_of_possible_clauses):
        self.assertEqual(dnf_lib.get_number_of_possible_clauses(num_literals),
                         expected_number_of_possible_clauses)

    def test_get_random_dnf(self):
        with mock.patch.object(dnf_lib,
                               'get_random_clause') as mock_get_random_clause:
            mock_get_random_clause.side_effect = [
                dnf_lib.Clause(0, 1, True, True),
                dnf_lib.Clause(0, 1, True, True),  # Duplicaed clause.
                dnf_lib.Clause(0, 1, True, False),
                dnf_lib.Clause(1, 2, True, True),
                dnf_lib.Clause(3, 4, True, True),
                dnf_lib.Clause(5, 6, True, True),
                # Not used since we only need 5 unique clauses.
                dnf_lib.Clause(7, 8, True, True),
                dnf_lib.Clause(7, 8, False, True),
            ]
            dnf = dnf_lib.get_random_dnf(num_literals=10, num_clauses=5)
        self.assertEqual(dnf.num_literals, 10)
        self.assertSetEqual(
            dnf.clauses,
            set([
                dnf_lib.Clause(0, 1, True, True),
                dnf_lib.Clause(0, 1, True, False),
                dnf_lib.Clause(1, 2, True, True),
                dnf_lib.Clause(3, 4, True, True),
                dnf_lib.Clause(5, 6, True, True)
            ]))

    def test_get_random_dnf_num_clauses_too_large(self):
        with self.assertRaisesRegex(
                ValueError,
                'num_clauses 10 can not be greater than number of possible clauses 4'
        ):
            dnf_lib.get_random_dnf(num_literals=2, num_clauses=10)

    @parameterized.parameters(
        ('(x_32 || x_0)', dnf_lib.Clause(0, 32, False, False)),
        ('(x_2 || !x_39)', dnf_lib.Clause(2, 39, False, True)),
        ('(!x_11 || x_12)', dnf_lib.Clause(11, 12, True, False)),
        ('(!x_3 || !x_2)', dnf_lib.Clause(2, 3, True, True)))
    def test_clause_from_string(self, clause_string, expected_clause):
        self.assertEqual(dnf_lib.clause_from_string(clause_string),
                         expected_clause)

    @parameterized.parameters(('as;lkj;lkajsdf'), ('x_2'), ('x_-5'),
                              ('(x_0 | x_1)'), ('x_0 || x_1)'), ('x_0 || x_1'),
                              ('(!!x_3 || x_5)'), ('(!x_3 || x_4 || x_5)'))
    def test_clause_from_string_invalid(self, clause_string):
        with self.assertRaisesRegex(ValueError,
                                    'Not the output of a clause string'):
            dnf_lib.clause_from_string(clause_string)

    @parameterized.parameters(
        ('Number of Literals: 12, DNF:', dnf_lib.DNF(12, [])),
        ('Number of Literals: 4, DNF: ', dnf_lib.DNF(4, [])),
        ('Number of Literals: 24, DNF: (!x_0 || x_1)',
         dnf_lib.DNF(24, [dnf_lib.Clause(0, 1, True, False)])),
        ('Number of Literals: 5, DNF:(x_2 || x_4) && (x_3 || !x_1)',
         dnf_lib.DNF(5, [
             dnf_lib.Clause(2, 4, False, False),
             dnf_lib.Clause(1, 3, True, False)
         ])))
    def test_dnf_from_string(self, dnf_string, expected_dnf):
        dnf = dnf_lib.dnf_from_string(dnf_string)
        self.assertEqual(dnf.num_literals, expected_dnf.num_literals)
        self.assertEqual(dnf.clauses, expected_dnf.clauses)

    @parameterized.parameters(('Number of Literals: , DNF:'),
                              ('Number of Literals: 5, DNF: (x_0 || x_1) && '))
    def test_dnf_from_string_invalid(self, dnf_string):
        with self.assertRaisesRegex(ValueError,
                                    'Not the output of a dnf string'):
            dnf_lib.dnf_from_string(dnf_string)
 def test_bangbang_protocol_circuit_init(self):
     dnf = dnf_lib.DNF(4, [dnf_lib.Clause(0, 3, True, True)])
     circuit = dnf_circuit_lib.BangBangProtocolCircuit(5.3, dnf)
     self.assertEqual(circuit.dnf, dnf)
     self.assertEqual(circuit.chunk_time, 5.3)
     self.assertEqual(circuit.num_qubits, 4)
 def test_get_hamiltonian_diagonal(self):
     dnf = dnf_lib.DNF(4, [dnf_lib.Clause(0, 3, True, True)])
     circuit = dnf_circuit_lib.BangBangProtocolCircuit(5.3, dnf)
     np.testing.assert_allclose(
         circuit.get_hamiltonian_diagonal(),
         [1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0])
 def test_bangbang_protocol_circuit_init_neg_chunk_time(self):
     with self.assertRaisesRegex(ValueError,
                                 'chunk_time must be positive, not -1.2'):
         dnf_circuit_lib.BangBangProtocolCircuit(-1.2, dnf_lib.DNF(22, []))
Пример #21
0
 def test_init_neg_num(self, num_literals, error_message):
     with self.assertRaisesRegex(ValueError, error_message):
         dnf_lib.DNF(num_literals, set())