def main(argv): if len(argv) > 1: raise app.UsageError('Too many command-line arguments.') logging.info('Generate a random DNF') dnf = dnf_lib.get_random_dnf(FLAGS.num_literals, FLAGS.num_clauses) logging.info(dnf) logging.info('initialization_method: %s', FLAGS.initialization_method) if FLAGS.initialization_method == 'random': get_initial_protocol = stochastic_descent_lib.get_random_protocol elif FLAGS.initialization_method == 'adiabatic': get_initial_protocol = functools.partial( stochastic_descent_lib.get_random_adiabatic_protocol, ascending=True) elif FLAGS.initialization_method == 'anti_adiabatic': get_initial_protocol = functools.partial( stochastic_descent_lib.get_random_adiabatic_protocol, ascending=False) logging.info('Stochastic descent') for i in range(FLAGS.num_samples): logging.info('Trial index: %d', i) bangbang_protocol, protocol_eval, num_epoch = ( stochastic_descent_lib.stochastic_descent( circuit=dnf_circuit_lib.BangBangProtocolCircuit( chunk_time=FLAGS.total_time / FLAGS.num_chunks, dnf=dnf), max_num_flips=FLAGS.max_num_flips, initial_protocol=get_initial_protocol(FLAGS.num_chunks), minimize=False, skip_search=FLAGS.skip_search)) logging.info( 'Optimal protocol: %s', circuit_lib.protocol_to_string(bangbang_protocol)) logging.info('Protocol eval: %f', protocol_eval) logging.info('Number of epoch: %d', num_epoch)
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.]))
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)
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_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)
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, []))
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(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)