示例#1
0
def test_run_empty_circuit(dtype):
    circuit = cirq.Circuit()
    simulator = cirq.KnowledgeCompilationSimulator(circuit, dtype=dtype)
    with pytest.raises(ValueError, match="no measurements"):
        simulator.run(circuit)
示例#2
0
def trial(n=6, p=2, repetitions=1000, maxiter=2):

    # Generate a random 3-regular graph on n nodes
    graph = networkx.random_regular_graph(3, n)

    # Make qubits
    qubits = cirq.LineQubit.range(n)

    # Print an example circuit
    cirq_circuit = qaoa_max_cut_circuit_no_meas(qubits, p, graph)
    print('Example QAOA circuit:')
    print(cirq_circuit.to_text_diagram(transpose=True))

    # noise = cirq.ConstantQubitNoiseModel(cirq.asymmetric_depolarize(0.005,0.005,0.005)) # mixture: size four noise not implemented
    noise = cirq.ConstantQubitNoiseModel(
        cirq.depolarize(0.005))  # mixture: size four noise not implemented
    # noise = cirq.ConstantQubitNoiseModel(cirq.phase_flip(0.01)) # mixture: works well
    # noise = cirq.ConstantQubitNoiseModel(cirq.bit_flip(0.01)) # mixture: works well

    cirq_circuit = cirq.Circuit(
        cirq.NoiseModel.from_noise_model_like(noise).noisy_moments(
            cirq_circuit, sorted(cirq_circuit.all_qubits())))
    meas_circuit = cirq.Circuit(cirq_circuit, cirq.measure(*qubits, key='m'))

    # Initialize simulators
    dm_sim = cirq.DensityMatrixSimulator()
    # kc_sim = cirq.KnowledgeCompilationSimulator(cirq_circuit, initial_state=0)
    kc_smp = cirq.KnowledgeCompilationSimulator(meas_circuit, initial_state=0)

    # Create variables to store the largest cut and cut value found
    dm_largest_cut_found = None
    dm_largest_cut_value_found = 0
    kc_largest_cut_found = None
    kc_largest_cut_value_found = 0

    # Define objective function (we'll use the negative expected cut value)
    iter = 0

    def f(x):
        # Create circuit
        betas = x[:p]
        betas_dict = {'beta' + str(index): betas[index] for index in range(p)}
        gammas = x[p:]
        gammas_dict = {
            'gamma' + str(index): gammas[index]
            for index in range(p)
        }
        param_resolver = cirq.ParamResolver({**betas_dict, **gammas_dict})

        # VALIDATE DENSITY MATRIX SIMULATION

        # dm_sim_start = time.time()
        # dm_sim_result = dm_sim.simulate(cirq_circuit, param_resolver=param_resolver)
        # dm_sim_time = time.time() - dm_sim_start

        # kc_sim_start = time.time()
        # kc_sim_result = kc_sim.simulate(cirq_circuit, param_resolver=param_resolver)
        # kc_sim_time = time.time() - kc_sim_start

        # print("dm_sim_result.final_density_matrix=")
        # print(dm_sim_result.final_density_matrix)
        # print("kc_sim_result.final_density_matrix=")
        # print(kc_sim_result.final_density_matrix)
        #
        # np.testing.assert_almost_equal(
        #     dm_sim_result.final_density_matrix,
        #     kc_sim_result.final_density_matrix,
        #     decimal=6
        # )

        # VALIDATE SAMPLING HISTOGRAMS

        # Sample bitstrings from circuit
        if n <= cirq_max:
            dm_smp_start = time.time()
            dm_smp_result = dm_sim.run(meas_circuit,
                                       param_resolver=param_resolver,
                                       repetitions=repetitions)
            dm_smp_time = time.time() - dm_smp_start
            dm_smp_time_dict[n].append(dm_smp_time)

            # Process histogram
            dm_bitstrings = dm_smp_result.measurements['m']
            dm_histogram = defaultdict(int)
            for bitstring in dm_bitstrings:
                integer = 0
                for pos, bit in enumerate(reversed(bitstring)):
                    integer += bit << pos
                dm_histogram[integer] += 1

            # Process bitstrings
            nonlocal dm_largest_cut_found
            nonlocal dm_largest_cut_value_found
            dm_values = cut_values(dm_bitstrings, graph)
            dm_max_value_index = np.argmax(dm_values)
            dm_max_value = dm_values[dm_max_value_index]
            if dm_max_value > dm_largest_cut_value_found:
                dm_largest_cut_value_found = dm_max_value
                dm_largest_cut_found = dm_bitstrings[dm_max_value_index]
            dm_mean = np.mean(dm_values)

        # Sample bitstrings from circuit
        kc_smp_start = time.time()
        kc_smp_result = kc_smp.run(meas_circuit,
                                   param_resolver=param_resolver,
                                   repetitions=repetitions)
        kc_smp_time = time.time() - kc_smp_start
        kc_smp_time_dict[n].append(kc_smp_time)

        # Process histogram
        kc_bitstrings = kc_smp_result.measurements['m']
        kc_histogram = defaultdict(int)
        for bitstring in kc_bitstrings:
            integer = 0
            for pos, bit in enumerate(reversed(bitstring)):
                integer += bit << pos
            kc_histogram[integer] += 1

        # Process bitstrings
        nonlocal kc_largest_cut_found
        nonlocal kc_largest_cut_value_found
        kc_values = cut_values(kc_bitstrings, graph)
        kc_max_value_index = np.argmax(kc_values)
        kc_max_value = kc_values[kc_max_value_index]
        if kc_max_value > kc_largest_cut_value_found:
            kc_largest_cut_value_found = kc_max_value
            kc_largest_cut_found = kc_bitstrings[kc_max_value_index]
        kc_mean = np.mean(kc_values)

        nonlocal iter
        # PRINT HISTOGRAMS
        # print ('iter,index,bitstring,bitstring_bin,dm_probability,dm_samples,kc_samples')
        # probabilities = np.zeros(1<<n)
        # for bitstring, probability in enumerate(cirq.sim.density_matrix_utils._probs(
        #     dm_sim_result.final_density_matrix,
        #     [index for index in range(n)],
        #     cirq.protocols.qid_shape(qubits)
        # )):
        #     probabilities[bitstring]=probability
        # sorted_bitstrings = np.argsort(probabilities)
        # for index, bitstring in enumerate(sorted_bitstrings):
        #     print (str(iter)+','+str(index)+','+str(bitstring)+','+format(bitstring,'b').zfill(n)+','+str(probabilities[bitstring])+','+"{:.6e}".format(dm_histogram[bitstring]/repetitions)+','+"{:.6e}".format(kc_histogram[bitstring]/repetitions))

        if n <= cirq_max:
            print('dm_mean=' + str(dm_mean) + ' kc_mean=' + str(kc_mean))
            # print ( 'dm_sim_time='+str(dm_sim_time)+' kc_sim_time='+str(kc_sim_time) )
            print('dm_smp_time=' + str(dm_smp_time) + ' kc_smp_time=' +
                  str(kc_smp_time))
        print(
            '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
        iter += 1
        return -kc_mean

    # Pick an initial guess
    x0 = np.random.uniform(-np.pi, np.pi, size=2 * p)

    # Optimize f
    print('Optimizing objective function ...')
    scipy.optimize.minimize(f,
                            x0,
                            method='Nelder-Mead',
                            options={'maxiter': maxiter})

    # Compute best possible cut value via brute force search
    all_bitstrings = np.array(list(itertools.product(range(2), repeat=n)))
    all_values = cut_values(all_bitstrings, graph)
    max_cut_value = np.max(all_values)

    # Print the results
    print('The largest cut value found was {}.'.format(
        dm_largest_cut_value_found))
    print('The largest possible cut has size {}.'.format(max_cut_value))
    print('The approximation ratio achieved is {}.'.format(
        dm_largest_cut_value_found / max_cut_value))
示例#3
0
def test_run_repetitions_terminal_measurement_stochastic():
    q = cirq.LineQubit(0)
    c = cirq.Circuit(cirq.H(q), cirq.measure(q, key='q'))
    results = cirq.KnowledgeCompilationSimulator(c).run(c, repetitions=10000)
    assert 1000 <= sum(v[0] for v in results.measurements['q']) < 9000
示例#4
0
def test_invalid_dtype():
    with pytest.raises(ValueError, match='complex'):
        cirq.KnowledgeCompilationSimulator(cirq.Circuit(), dtype=np.int32)
def experiment_multiplier(n=2):

    qubits = cirq.LineQubit.range(5 * n)
    # c = qubits[0:n*3:3]
    # a = qubits[1:n*3:3]
    b = qubits[2:n * 3:3]
    y = qubits[n * 3:n * 4]
    x = qubits[n * 4:]

    kc_circuit = cirq.Circuit(
        init_qubits_sym(
            [sympy.Symbol('x_bin' + str(index)) for index in range(n)], *x),
        init_qubits_sym(
            [sympy.Symbol('y_bin' + str(index)) for index in range(n)], *y),
        cirq.decompose(Multiplier(5 * n).on(*qubits)),
        cirq.measure(*b, key='result'))
    cirq.optimizers.SynchronizeTerminalMeasurements().optimize_circuit(
        kc_circuit)
    kc_simulator = cirq.KnowledgeCompilationSimulator(kc_circuit,
                                                      initial_state=0,
                                                      intermediate=False)

    for p in range(2**n):
        for q in range(2**n):
            y_bin = '{:08b}'.format(p)[-n:]
            x_bin = '{:08b}'.format(q)[-n:]

            x_bin_dict = {
                'x_bin' + str(index): x_bin[index]
                for index in range(n)
            }
            y_bin_dict = {
                'y_bin' + str(index): y_bin[index]
                for index in range(n)
            }
            param_resolver = cirq.ParamResolver({**x_bin_dict, **y_bin_dict})

            dm_circuit = cirq.Circuit(
                init_qubits(x_bin, *x),
                init_qubits(y_bin, *y),
                Multiplier(5 * n).on(*qubits),
            )
            np.testing.assert_almost_equal(
                cirq.Simulator().simulate(dm_circuit).state_vector(),
                kc_simulator.simulate(
                    kc_circuit, param_resolver=param_resolver).state_vector())

            sv_circuit = cirq.Circuit(init_qubits(x_bin, *x),
                                      init_qubits(y_bin, *y),
                                      Multiplier(5 * n).on(*qubits),
                                      cirq.measure(*b, key='result'))
            sv_result = cirq.Simulator().run(
                sv_circuit, repetitions=1).measurements['result']
            sv_sum_bin = ''.join(sv_result[0][::-1].astype(int).astype(str))

            kc_result = kc_simulator.run(kc_circuit,
                                         param_resolver=param_resolver,
                                         repetitions=1).measurements['result']
            kc_sum_bin = ''.join(kc_result[0][::-1].astype(int).astype(str))

            print('{} * {} = {}'.format(y_bin, x_bin, sv_sum_bin))
            print('{} * {} = {}'.format(y_bin, x_bin, kc_sum_bin))
            assert sv_sum_bin == kc_sum_bin
ansatz = openfermioncirq.SwapNetworkTrotterAnsatz(hamiltonian,
                                                  iterations=iterations)

print('Created a variational ansatz with the following circuit:')
print(ansatz.circuit.to_text_diagram(transpose=True))

# Use preparation circuit for mean-field state
import cirq
preparation_circuit = cirq.Circuit(
    openfermioncirq.prepare_gaussian_state(
        ansatz.qubits,
        openfermion.QuadraticHamiltonian(hamiltonian.one_body),
        occupied_orbitals=range(n_electrons)))

kc_simulator = cirq.KnowledgeCompilationSimulator(preparation_circuit +
                                                  ansatz.circuit,
                                                  initial_state=0)

# Create a Hamiltonian variational study
study = openfermioncirq.VariationalStudy(
    'jellium_study',
    ansatz,
    objective,
    preparation_circuit=preparation_circuit)

print("Created a variational study with {} qubits and {} parameters".format(
    len(study.ansatz.qubits), study.num_params))

print(
    "The value of the objective with default initial parameters is {}".format(
        study.value_of(kc_simulator, ansatz.default_initial_params())))
示例#7
0
def main(num_qubits=8):
    # Setup non-eavesdropped protocol
    print('Simulating non-eavesdropped protocol')
    alice_basis = [np.random.randint(0, 2) for _ in range(num_qubits)]
    alice_state = [np.random.randint(0, 2) for _ in range(num_qubits)]
    bob_basis = [np.random.randint(0, 2) for _ in range(num_qubits)]

    expected_key = bitstring([
        alice_state[i] for i in range(num_qubits)
        if alice_basis[i] == bob_basis[i]
    ])

    circuit = make_bb84_circ(num_qubits, alice_basis, bob_basis, alice_state)

    # Run simulations.
    repetitions = 1

    result = cirq.KnowledgeCompilationSimulator(
        circuit, intermediate=True).run(program=circuit,
                                        repetitions=repetitions)
    print("result=")
    print(result)
    result_bitstring = bitstring(
        [int(result.measurements[str(i)]) for i in range(num_qubits)])

    # Take only qubits where bases match
    obtained_key = ''.join([
        result_bitstring[i] for i in range(num_qubits)
        if alice_basis[i] == bob_basis[i]
    ])

    assert expected_key == obtained_key, "Keys don't match"
    print(circuit)
    print_results(alice_basis, bob_basis, alice_state, expected_key,
                  obtained_key)

    # Setup eavesdropped protocol
    print('Simulating eavesdropped protocol')
    np.random.seed(200)  # Seed random generator for consistent results
    alice_basis = [np.random.randint(0, 2) for _ in range(num_qubits)]
    alice_state = [np.random.randint(0, 2) for _ in range(num_qubits)]
    bob_basis = [np.random.randint(0, 2) for _ in range(num_qubits)]
    eve_basis = [np.random.randint(0, 2) for _ in range(num_qubits)]

    expected_key = bitstring([
        alice_state[i] for i in range(num_qubits)
        if alice_basis[i] == bob_basis[i]
    ])

    # Eve intercepts the qubits

    alice_eve_circuit = make_bb84_circ(num_qubits, alice_basis, eve_basis,
                                       alice_state)

    # Run simulations.
    repetitions = 1
    result = cirq.KnowledgeCompilationSimulator(alice_eve_circuit,
                                                intermediate=True).run(
                                                    program=alice_eve_circuit,
                                                    repetitions=repetitions)
    eve_state = [int(result.measurements[str(i)]) for i in range(num_qubits)]

    eve_bob_circuit = make_bb84_circ(num_qubits, eve_basis, bob_basis,
                                     eve_state)

    # Run simulations.
    repetitions = 1
    result = cirq.KnowledgeCompilationSimulator(eve_bob_circuit,
                                                intermediate=True).run(
                                                    program=eve_bob_circuit,
                                                    repetitions=repetitions)
    result_bitstring = bitstring(
        [int(result.measurements[str(i)]) for i in range(num_qubits)])

    # Take only qubits where bases match
    obtained_key = ''.join([
        result_bitstring[i] for i in range(num_qubits)
        if alice_basis[i] == bob_basis[i]
    ])

    assert expected_key != obtained_key, "Keys shouldn't match"

    circuit = alice_eve_circuit + eve_bob_circuit
    print(circuit)
    print_results(alice_basis, bob_basis, alice_state, expected_key,
                  obtained_key)
def main(
    repetitions=256,
    maxiter=1
    ):
    # Set problem parameters
    kc_kl_divs={}
    qs_kl_divs={}
    for length in range (2,6,1):

        kc_kl_divs[length]=[]
        qs_kl_divs[length]=[]

        for print_length in range(2,length,1):
            for kc_kl_div, qs_kl_div in zip(kc_kl_divs[print_length],qs_kl_divs[print_length]):
                print("print_length="+str(print_length)+" kc_kl_div="+str(kc_kl_div)+" qs_kl_div="+str(qs_kl_div))

        for _ in range(16):

            steps = 1

            h, jr, jc = random_instance(length)
            print('transverse fields: {}'.format(h))
            print('row j fields: {}'.format(jr))
            print('column j fields: {}'.format(jc))
            # prints something like
            # transverse fields: [[-1, 1, -1], [1, -1, -1], [-1, 1, -1]]
            # row j fields: [[1, 1, -1], [1, -1, 1]]
            # column j fields: [[1, -1], [-1, 1], [-1, 1]]

            # define qubits on the grid.
            # [cirq.GridQubit(i, j) for i in range(length) for j in range(length)]
            qubits = cirq.LineQubit.range(length*length)
            print(qubits)
            # prints
            # [cirq.GridQubit(0, 0), cirq.GridQubit(0, 1), cirq.GridQubit(0, 2), cirq.GridQubit(1, 0), cirq.GridQubit(1, 1), cirq.GridQubit(1, 2), cirq.GridQubit(2, 0), cirq.GridQubit(2, 1), cirq.GridQubit(2, 2)]

            cirq_circuit = cirq.Circuit()
            alpha = sympy.Symbol('alpha')
            beta = sympy.Symbol('beta')
            gamma = sympy.Symbol('gamma')
            for _ in range(steps):
                cirq_circuit.append(one_step(h, jr, jc, alpha, beta, gamma))
            meas_circuit = cirq.Circuit( cirq_circuit, cirq.measure(*qubits, key='x') )
            print(meas_circuit)

            # Initialize simulators
            qs_sim_16 = qsimcirq.QSimSimulator( qsim_options={'t':16, 'v': 0} )
            kc_sim = cirq.KnowledgeCompilationSimulator(cirq_circuit, initial_state=0)
            kc_smp = cirq.KnowledgeCompilationSimulator(meas_circuit, initial_state=0)

            iter = 0
            def f(x):
                param_resolver = cirq.ParamResolver({ 'alpha':x[0], 'beta':x[1], 'gamma':x[2] })

                # VALIDATE STATE VECTOR SIMULATION
                solved_circuit = cirq.resolve_parameters(meas_circuit, param_resolver)
                cirq.ConvertToCzAndSingleGates().optimize_circuit(solved_circuit) # cannot work with params
                cirq.ExpandComposite().optimize_circuit(solved_circuit)
                qsim_circuit = qsimcirq.QSimCircuit(solved_circuit)

                qs_sim_start = time.time()
                qs_sim_result = qs_sim_16.simulate(qsim_circuit)
                qs_sim_time = time.time() - qs_sim_start

                # kc_sim_start = time.time()
                # kc_sim_result = kc_sim.simulate(cirq_circuit, param_resolver=param_resolver)
                # kc_sim_time = time.time() - kc_sim_start

                # print("kc_sim_result.state_vector()=")
                # print(kc_sim_result.state_vector())
                # print("qs_sim_result.state_vector()=")
                # print(qs_sim_result.state_vector())

                # assert qs_sim_result.state_vector().shape == (1<<(length*length),)
                # assert cirq.linalg.allclose_up_to_global_phase(
                #     qs_sim_result.state_vector(),
                #     kc_sim_result.state_vector(),
                #     rtol = 1.e-4,
                #     atol = 1.e-6,
                # )

                # VALIDATE SAMPLING HISTOGRAMS

                # Sample bitstrings from circuit
                qs_smp_16_start = time.time()
                qs_smp_16_result = qs_sim_16.run(qsim_circuit, repetitions=repetitions)
                qs_smp_16_time = time.time() - qs_smp_16_start

                qs_bitstrings = qs_smp_16_result.measurements['x']

                # Process histogram
                qs_histogram = defaultdict(int)
                for bitstring in qs_bitstrings:
                    integer = 0
                    for pos, bit in enumerate(bitstring):
                        integer += bit<<pos
                    qs_histogram[integer] += 1

                # Process bitstrings
                qs_value = obj_func(qs_smp_16_result, h, jr, jc)
                print('Objective value is {}.'.format(qs_value))

                # Sample bitstrings from circuit
                kc_smp_start = time.time()
                kc_smp_result = kc_smp.run(meas_circuit, param_resolver=param_resolver, repetitions=repetitions)
                kc_smp_time = time.time() - kc_smp_start

                # Process histogram
                kc_bitstrings = kc_smp_result.measurements['x']
                kc_histogram = defaultdict(int)
                for bitstring in kc_bitstrings:
                    integer = 0
                    for pos, bit in enumerate(reversed(bitstring)):
                        integer += bit<<pos
                    kc_histogram[integer] += 1

                # Process bitstrings
                kc_value = obj_func(kc_smp_result, h, jr, jc)
                print('Objective value is {}.'.format(kc_value))

                nonlocal iter
                # PRINT HISTOGRAMS
                kc_kl_div = 0
                qs_kl_div = 0
                print ('iter,index,bitstring,bitstring_bin,qs_probability,qs_samples,kc_samples')
                probabilities = np.zeros(1<<(length*length))
                for bitstring, amplitude in enumerate(qs_sim_result.state_vector()):
                    probability = abs(amplitude) * abs(amplitude)
                    kc_samples = kc_histogram[bitstring]/repetitions
                    qs_samples = qs_histogram[bitstring]/repetitions
                    kc_kl_div += 0 if kc_samples==0 else kc_samples*math.log(kc_samples/probability)
                    qs_kl_div += 0 if qs_samples==0 else qs_samples*math.log(qs_samples/probability)
                    probabilities[bitstring]=probability
                kc_kl_divs[length].append(kc_kl_div)
                qs_kl_divs[length].append(qs_kl_div)
                sorted_bitstrings = np.argsort(probabilities)
                # for index, bitstring in enumerate(sorted_bitstrings):
                #     print (str(iter)+','+str(index)+','+str(bitstring)+','+format(bitstring,'b').zfill(length*length)+','+str(probabilities[bitstring])+','+"{:.6e}".format(qs_histogram[bitstring]/repetitions)+','+"{:.6e}".format(kc_histogram[bitstring]/repetitions))

                print ('qs_value='+str(qs_value)+' kc_value='+str(kc_value))
                # print ( 'qs_sim_time='+str(qs_sim_time)+' kc_sim_time='+str(kc_sim_time) )
                print ( 'qs_smp_16_time='+str(qs_smp_16_time)+' kc_smp_time='+str(kc_smp_time) )
                print ('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
                iter += 1
                return qs_value

            # Pick an initial guess
            x0 = np.random.uniform(0.0, 1.0, size=3)

            # Optimize f
            print('Optimizing objective function ...')
            scipy.optimize.minimize(f,
                                    x0,
                                    method='Nelder-Mead',
                                    options={'maxiter': maxiter})
示例#9
0
def main():

    q0, q1, q2 = cirq.LineQubit.range(3)
    for iteration in range(1):
        random_circuit = cirq.testing.random_circuit(qubits=[q0, q1, q2],
                                                     n_moments=32,
                                                     op_density=0.99)

        cirq.ConvertToCzAndSingleGates().optimize_circuit(
            random_circuit)  # cannot work with params
        cirq.ExpandComposite().optimize_circuit(random_circuit)
        qs_circuit = qsimcirq.QSimCircuit(random_circuit)
        random_circuit._to_quil_output().save_to_file('kc_qtorch.quil')

        qs_simulator = qsimcirq.QSimSimulator(qsim_options={'t': 16, 'v': 2})
        qs_result = qs_simulator.simulate(qs_circuit)
        assert qs_result.state_vector().shape == (8, )
        kc_simulator = cirq.KnowledgeCompilationSimulator(random_circuit)
        kc_result = kc_simulator.simulate(random_circuit)
        print("qs_result.state_vector()")
        print(qs_result.state_vector())
        print("kc_result.state_vector()")
        print(kc_result.state_vector())
        assert cirq.linalg.allclose_up_to_global_phase(
            qs_result.state_vector(),
            kc_result.state_vector(),
            rtol=1.e-4,
            atol=1.e-6,
        )

        path_to_qtorch = '/common/home/yh804/research/qtorch/bin/qtorch'
        with open('kc_qtorch.inp', 'w') as inp_file:
            inp_file.write('''# Line graph decomposition method for contraction
>string qasm kc_qtorch.quil
# >string contractmethod simple-stoch
>string contractmethod linegraph-qbb
>int quickbbseconds 65536
# >string measurement kc_qtorch.meas
# >string outputpath kc_qtorch.out
>bool qbbonly true
# >bool readqbbresonly true
# >int threads 8
''')
        stdout = os.system(path_to_qtorch + ' kc_qtorch.inp')

        probs = np.zeros(1 << 3)
        for bitstring in range(1 << 3):
            with open('kc_qtorch.inp', 'w') as inp_file:
                inp_file.write(
                    '''# Line graph decomposition method for contraction
>string qasm kc_qtorch.quil
# >string contractmethod simple-stoch
>string contractmethod linegraph-qbb
# >int quickbbseconds 65536
>string measurement kc_qtorch.meas
>string outputpath kc_qtorch.out
# >bool qbbonly true
>bool readqbbresonly true
>int threads 8
''')
            with open('kc_qtorch.meas', 'w') as meas_file:
                meas_file.write("{:03b}".format(bitstring))
            stdout = os.system(path_to_qtorch + ' kc_qtorch.inp')
            with open('kc_qtorch.out', 'r') as out_file:
                for line in out_file.readlines():
                    words = re.split(r'\(|,', line)
                    if words[0] == 'Result of Contraction: ':
                        probs[bitstring] = float(words[1])

        print(
            "np.diag(np.outer(qs_result.state_vector(),np.conj(qs_result.state_vector())))"
        )
        print(
            np.diag(
                np.outer(qs_result.state_vector(),
                         np.conj(qs_result.state_vector()))))
        print("probs")
        print(probs)
        assert cirq.linalg.allclose_up_to_global_phase(
            np.diag(
                np.outer(qs_result.state_vector(),
                         np.conj(qs_result.state_vector()))),
            probs,
            rtol=1.e-4,
            atol=1.e-6,
        )

        circuit_unitary = []
        for x in range(8):
            result = kc_simulator.simulate(random_circuit, initial_state=x)
            circuit_unitary.append(result.final_state_vector)

        print("np.transpose(circuit_unitary) = ")
        print(np.transpose(circuit_unitary))
        print("random_circuit.unitary() = ")
        print(random_circuit.unitary())
        np.testing.assert_almost_equal(np.transpose(circuit_unitary),
                                       random_circuit.unitary(),
                                       decimal=4)
def main(
    # repetitions=16384,
    maxiter=8
    ):
    # Set problem parameters
    n = 8
    p = 1

    # Generate a random 3-regular graph on n nodes
    graph = networkx.random_regular_graph(3, n)

    # Make qubits
    qubits = cirq.LineQubit.range(n)

    # Print an example circuit
    betas = np.random.uniform(-np.pi, np.pi, size=p)
    gammas = np.random.uniform(-np.pi, np.pi, size=p)
    circuit_no_meas = qaoa_max_cut_circuit_no_meas(qubits, p, graph)
    print('Example QAOA circuit:')
    print(circuit_no_meas.to_text_diagram(transpose=True))

    # noise = cirq.ConstantQubitNoiseModel(cirq.generalized_amplitude_damp(0.05,0.05))
    # noise = cirq.ConstantQubitNoiseModel(cirq.amplitude_damp(0.25))
    # noise = cirq.ConstantQubitNoiseModel(cirq.phase_damp(0.25))

    # noise = cirq.ConstantQubitNoiseModel(cirq.asymmetric_depolarize(0.05,0.05,0.05)) # asymmetric depolarizing
    noise = cirq.ConstantQubitNoiseModel(cirq.depolarize(0.005)) # symmetric depolarizing
    # noise = cirq.ConstantQubitNoiseModel(cirq.phase_flip(0.25)) # mixture
    # noise = cirq.ConstantQubitNoiseModel(cirq.bit_flip(0.03125)) # mixture

    circuit_no_meas = cirq.Circuit(cirq.NoiseModel.from_noise_model_like(noise).noisy_moments(circuit_no_meas, sorted(circuit_no_meas.all_qubits())))
    circuit = cirq.Circuit( circuit_no_meas, cirq.measure(*qubits, key='m') )
    cirq.optimizers.ExpandComposite().optimize_circuit(circuit) # seems to actually increase BN size

    # Initialize simulator
    kc_simulator = cirq.KnowledgeCompilationSimulator( circuit, initial_state=0, intermediate=False )
    dm_simulator = cirq.Simulator()

    # Create variables to store the largest cut and cut value found
    kc_largest_cut_found = None
    kc_largest_cut_value_found = 0
    dm_largest_cut_found = None
    dm_largest_cut_value_found = 0

    # Define objective function (we'll use the negative expected cut value)
    iter = 0
    def f(x):
        # Create circuit
        betas = x[:p]
        betas_dict = { 'beta'+str(index):betas[index] for index in range(p) }
        gammas = x[p:]
        gammas_dict = { 'gamma'+str(index):gammas[index] for index in range(p) }
        param_resolver = cirq.ParamResolver({**betas_dict,**gammas_dict})

        # kc_chisqs = {}
        # dm_chisqs = {}
        kc_power_divergences = {}
        dm_power_divergences = {}
        ks_2samps = {}

        for rep_pow in range(12):
            repetitions = 1<<rep_pow

            # VALIDATE STATE VECTOR SIMULATION
            # kc_sim_result = kc_simulator.simulate(circuit_no_meas, param_resolver=param_resolver)
            dm_sim_result = dm_simulator.simulate(circuit_no_meas, param_resolver=param_resolver)
            # print("kc_sim_result.final_density_matrix")
            # print(kc_sim_result.final_density_matrix)
            # print("dm_sim_result.final_density_matrix")
            # print(dm_sim_result.final_density_matrix)
            # np.testing.assert_almost_equal(
            #     kc_sim_result.final_density_matrix,
            #     dm_sim_result.final_density_matrix,
            #     decimal=5
            # )

            # VALIDATE SAMPLING HISTOGRAMS

            # Sample bitstrings from circuit
            kc_smp_start = time.time()
            kc_smp_result = kc_simulator.run(circuit, param_resolver=param_resolver, repetitions=repetitions)
            kc_smp_time = time.time() - kc_smp_start
            kc_bitstrings = kc_smp_result.measurements['m']

            # Process histogram
            kc_histogram = np.zeros(1<<n)
            kc_integers = []
            for bitstring in kc_bitstrings:
                integer = 0
                for pos, bit in enumerate(bitstring):
                    integer += bit<<pos
                kc_histogram[integer] += 1
                kc_integers.append(integer)

            # Process bitstrings
            nonlocal kc_largest_cut_found
            nonlocal kc_largest_cut_value_found
            kc_values = cut_values(kc_bitstrings, graph)
            kc_max_value_index = np.argmax(kc_values)
            kc_max_value = kc_values[kc_max_value_index]
            if kc_max_value > kc_largest_cut_value_found:
                kc_largest_cut_value_found = kc_max_value
                kc_largest_cut_found = kc_bitstrings[kc_max_value_index]
            kc_mean = np.mean(kc_values)

            # Sample bitstrings from circuit
            dm_smp_start = time.time()
            dm_smp_result = dm_simulator.run(circuit, param_resolver=param_resolver, repetitions=repetitions)
            dm_smp_time = time.time() - dm_smp_start
            dm_bitstrings = dm_smp_result.measurements['m']

            # Process histogram
            dm_histogram = np.zeros(1<<n)
            dm_integers = []
            for bitstring in dm_bitstrings:
                integer = 0
                for pos, bit in enumerate(bitstring):
                    integer += bit<<pos
                dm_histogram[integer] += 1
                dm_integers.append(integer)

            # Process bitstrings
            nonlocal dm_largest_cut_found
            nonlocal dm_largest_cut_value_found
            dm_values = cut_values(dm_bitstrings, graph)
            dm_max_value_index = np.argmax(dm_values)
            dm_max_value = dm_values[dm_max_value_index]
            if dm_max_value > dm_largest_cut_value_found:
                dm_largest_cut_value_found = dm_max_value
                dm_largest_cut_found = dm_bitstrings[dm_max_value_index]
            dm_mean = np.mean(dm_values)

            nonlocal iter
            # PRINT HISTOGRAMS

            exact_histogram = np.zeros(1<<n)
            for index, amplitude in enumerate(dm_sim_result.state_vector()):
                probability = abs(amplitude) * abs(amplitude)
                exact_histogram[index] = probability * repetitions
                # print ('iter='+str(iter)+' bitstring='+str(index)+' kc_probability='+str(kc_histogram[index]/repetitions)+' dm_probability='+str(dm_histogram[index]/repetitions)+' probability='+str(probability))
            # exact_probabilities = cirq.sim.density_matrix_utils._probs(
            #     dm_sim_result.final_density_matrix,
            #     [index for index in range(n)],
            #     cirq.protocols.qid_shape(qubits)
            #     )
            # for index, probability in enumerate(exact_probabilities):
            #     exact_histogram[index] = probability * repetitions
            #     print ('iter='+str(iter)+' bitstring='+str(index)+' kc_probability='+str(kc_histogram[index]/repetitions)+' dm_probability='+str(dm_histogram[index]/repetitions)+' probability='+str(probability))
            
            # kc_chisq, _ = scipy.stats.chisquare( f_obs=kc_histogram, f_exp=exact_histogram )
            # dm_chisq, _ = scipy.stats.chisquare( f_obs=dm_histogram, f_exp=exact_histogram )
            # kc_power_divergence, _ = scipy.stats.power_divergence( f_obs=kc_histogram, f_exp=exact_histogram, lambda_="pearson" )
            # dm_power_divergence, _ = scipy.stats.power_divergence( f_obs=dm_histogram, f_exp=exact_histogram, lambda_="pearson" )
            kc_power_divergence, _ = scipy.stats.power_divergence( f_obs=kc_histogram, f_exp=exact_histogram, lambda_="log-likelihood" )
            dm_power_divergence, _ = scipy.stats.power_divergence( f_obs=dm_histogram, f_exp=exact_histogram, lambda_="log-likelihood" )
            ks_2samp, _ = scipy.stats.ks_2samp( data1=kc_integers, data2=dm_integers )

            # kc_chisqs[repetitions]=kc_chisq
            # dm_chisqs[repetitions]=dm_chisq
            # kc_power_divergences[repetitions]=kc_power_divergence
            # dm_power_divergences[repetitions]=dm_power_divergence
            kc_power_divergences[repetitions]=kc_power_divergence / 2 / repetitions
            dm_power_divergences[repetitions]=dm_power_divergence / 2 / repetitions
            ks_2samps[repetitions]=ks_2samp

            print (
                'repetitions='+str(repetitions)+
                # ' kc_chisq='+str(kc_chisq)+
                # ' dm_chisq='+str(dm_chisq)+
                # ' kc_power_divergence='+str(kc_power_divergence)+
                # ' dm_power_divergence='+str(dm_power_divergence)+
                ' kc_power_divergence='+str(kc_power_divergence / 2 / repetitions)+
                ' dm_power_divergence='+str(dm_power_divergence / 2 / repetitions)+
                ' ks_2samp='+str(ks_2samp)
            )

            # print ('kc_mean='+str(kc_mean)+' dm_mean='+str(dm_mean))
            # print ( 'kc_smp_time=' + str(kc_smp_time) + ' dm_smp_time=' + str(dm_smp_time) )
            # print ('~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')

        iter += 1
        return -dm_mean

    # Pick an initial guess
    x0 = np.random.uniform(-np.pi, np.pi, size=2 * p)

    # Optimize f
    print('Optimizing objective function ...')
    scipy.optimize.minimize(f,
                            x0,
                            method='Nelder-Mead',
                            options={'maxiter': maxiter})

    # Compute best possible cut value via brute force search
    all_bitstrings = np.array(list(itertools.product(range(2), repeat=n)))
    all_values = cut_values(all_bitstrings, graph)
    max_cut_value = np.max(all_values)

    # Print the results
    print('The largest cut value found was {}.'.format(dm_largest_cut_value_found))
    print('The largest possible cut has size {}.'.format(max_cut_value))
    print('The approximation ratio achieved is {}.'.format(
        dm_largest_cut_value_found / max_cut_value))
示例#11
0
def trial(length=2, steps=1, repetitions=1000, maxiter=2):

    h, jr, jc = random_instance(length)
    print('transverse fields: {}'.format(h))
    print('row j fields: {}'.format(jr))
    print('column j fields: {}'.format(jc))
    # prints something like
    # transverse fields: [[-1, 1, -1], [1, -1, -1], [-1, 1, -1]]
    # row j fields: [[1, 1, -1], [1, -1, 1]]
    # column j fields: [[1, -1], [-1, 1], [-1, 1]]

    # define qubits on the grid.
    # [cirq.GridQubit(i, j) for i in range(length) for j in range(length)]
    qubits = cirq.LineQubit.range(length * length)
    print(qubits)
    # prints
    # [cirq.GridQubit(0, 0), cirq.GridQubit(0, 1), cirq.GridQubit(0, 2), cirq.GridQubit(1, 0), cirq.GridQubit(1, 1), cirq.GridQubit(1, 2), cirq.GridQubit(2, 0), cirq.GridQubit(2, 1), cirq.GridQubit(2, 2)]

    cirq_circuit = cirq.Circuit()
    alpha = sympy.Symbol('alpha')
    beta = sympy.Symbol('beta')
    gamma = sympy.Symbol('gamma')
    for _ in range(steps):
        cirq_circuit.append(one_step(h, jr, jc, alpha, beta, gamma))

    # noise = cirq.ConstantQubitNoiseModel(cirq.asymmetric_depolarize(0.005,0.005,0.005)) # mixture: size four noise not implemented
    noise = cirq.ConstantQubitNoiseModel(
        cirq.depolarize(0.005))  # mixture: size four noise not implemented
    # noise = cirq.ConstantQubitNoiseModel(cirq.phase_flip(0.01)) # mixture: works well
    # noise = cirq.ConstantQubitNoiseModel(cirq.bit_flip(0.01)) # mixture: works well

    cirq_circuit = cirq.Circuit(
        cirq.NoiseModel.from_noise_model_like(noise).noisy_moments(
            cirq_circuit, sorted(cirq_circuit.all_qubits())))
    meas_circuit = cirq.Circuit(cirq_circuit, cirq.measure(*qubits, key='x'))
    print(meas_circuit)

    # Initialize simulators
    dm_sim = cirq.DensityMatrixSimulator()
    # kc_sim = cirq.KnowledgeCompilationSimulator(cirq_circuit, initial_state=0)
    kc_smp = cirq.KnowledgeCompilationSimulator(meas_circuit, initial_state=0)

    # eval_iter = 0
    def f(x):
        param_resolver = cirq.ParamResolver({
            'alpha': x[0],
            'beta': x[1],
            'gamma': x[2]
        })

        # VALIDATE DENSITY MATRIX SIMULATION

        # dm_sim_start = time.time()
        # dm_sim_result = dm_sim.simulate(cirq_circuit, param_resolver=param_resolver)
        # dm_sim_time = time.time() - dm_sim_start

        # kc_sim_start = time.time()
        # kc_sim_result = kc_sim.simulate(cirq_circuit, param_resolver=param_resolver)
        # kc_sim_time = time.time() - kc_sim_start

        # print("dm_sim_result.final_density_matrix=")
        # print(dm_sim_result.final_density_matrix)
        # print("kc_sim_result.final_density_matrix=")
        # print(kc_sim_result.final_density_matrix)

        # np.testing.assert_almost_equal(
        #     dm_sim_result.final_density_matrix,
        #     kc_sim_result.final_density_matrix,
        #     decimal=6
        # )

        # VALIDATE SAMPLING HISTOGRAMS

        # Sample bitstrings from circuit
        if length * length <= cirq_max:
            dm_smp_start = time.time()
            dm_smp_result = dm_sim.run(meas_circuit,
                                       param_resolver=param_resolver,
                                       repetitions=repetitions)
            dm_smp_time = time.time() - dm_smp_start
            dm_smp_time_dict[length * length].append(dm_smp_time)

            # Process histogram
            dm_bitstrings = dm_smp_result.measurements['x']
            dm_histogram = defaultdict(int)
            for bitstring in dm_bitstrings:
                integer = 0
                for pos, bit in enumerate(reversed(bitstring)):
                    integer += bit << pos
                dm_histogram[integer] += 1

            # Process bitstrings
            dm_value = obj_func(dm_smp_result, h, jr, jc)
            print('Objective value is {}.'.format(dm_value))

        # Sample bitstrings from circuit
        kc_smp_start = time.time()
        kc_smp_result = kc_smp.run(meas_circuit,
                                   param_resolver=param_resolver,
                                   repetitions=repetitions)
        kc_smp_time = time.time() - kc_smp_start
        kc_smp_time_dict[length * length].append(kc_smp_time)

        # Process histogram
        kc_bitstrings = kc_smp_result.measurements['x']
        kc_histogram = defaultdict(int)
        for bitstring in kc_bitstrings:
            integer = 0
            for pos, bit in enumerate(reversed(bitstring)):
                integer += bit << pos
            kc_histogram[integer] += 1

        # Process bitstrings
        kc_value = obj_func(kc_smp_result, h, jr, jc)
        print('Objective value is {}.'.format(kc_value))

        # nonlocal eval_iter
        # PRINT HISTOGRAMS
        # print ('eval_iter,index,bitstring,bitstring_bin,dm_probability,dm_samples,kc_samples')
        # probabilities = np.zeros(1<<(length*length))
        # for bitstring, probability in enumerate(cirq.sim.density_matrix_utils._probs(
        #     dm_sim_result.final_density_matrix,
        #     [index for index in range(length*length)],
        #     cirq.protocols.qid_shape(qubits)
        # )):
        #     probabilities[bitstring]=probability
        # sorted_bitstrings = np.argsort(probabilities)
        # for index, bitstring in enumerate(sorted_bitstrings):
        #     print (str(eval_iter)+','+str(index)+','+str(bitstring)+','+format(bitstring,'b').zfill(length*length)+','+str(probabilities[bitstring])+','+"{:.6e}".format(dm_histogram[bitstring]/repetitions)+','+"{:.6e}".format(kc_histogram[bitstring]/repetitions))

        if length * length <= cirq_max:
            print('dm_value=' + str(dm_value) + ' kc_value=' + str(kc_value))
            # print ( 'dm_sim_time='+str(dm_sim_time)+' kc_sim_time='+str(kc_sim_time) )
            print('dm_smp_time=' + str(dm_smp_time) + ' kc_smp_time=' +
                  str(kc_smp_time))
        print(
            '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
        # eval_iter += 1
        return kc_value

    # Pick an initial guess
    x0 = np.random.uniform(0.0, 1.0, size=3)

    # Optimize f
    print('Optimizing objective function ...')
    scipy.optimize.minimize(f,
                            x0,
                            method='Nelder-Mead',
                            options={'maxiter': maxiter})
示例#12
0
def main():

    q0, q1 = cirq.LineQubit.range(2)
    circuit_no_meas = cirq.Circuit(
        # cirq.H(q0),
        cirq.bit_flip(9/25)(q0),
        # cirq.bit_flip(9/25)(q1),
        cirq.CNOT(q0,q1),
    )

    kc_simulator = cirq.KnowledgeCompilationSimulator(circuit_no_meas, intermediate=True)
    dm_simulator = cirq.DensityMatrixSimulator()

    kc_sim_result = kc_simulator.simulate(circuit_no_meas)
    dm_sim_result = dm_simulator.simulate(circuit_no_meas)

    print("kc_sim_result.final_density_matrix")
    print(kc_sim_result.final_density_matrix)

    np.testing.assert_almost_equal(
        kc_sim_result.final_density_matrix,
        dm_sim_result.final_density_matrix,
        decimal=7
    )

    circuit = cirq.Circuit(
        circuit_no_meas,
        cirq.measure(q0,q1)
    )

    kc_simulator = cirq.KnowledgeCompilationSimulator(circuit, initial_state=0, intermediate=False)
    repetitions = 65536

    dm_run_result = dm_simulator.run(circuit, repetitions=repetitions)
    dm_histogram = np.zeros(1<<2)
    for bitstring in dm_run_result.measurements['0,1']:
        integer = 0
        for pos, bit in enumerate(bitstring):
            integer += bit<<pos
        dm_histogram[integer] += 1
    print ("DM")
    print (dm_histogram/repetitions)

    kc_run_result = kc_simulator.run(circuit, repetitions=repetitions)
    kc_histogram = np.zeros(1<<2)
    for bitstring in kc_run_result.measurements['0,1']:
        integer = 0
        for pos, bit in enumerate(bitstring):
            integer += bit<<pos
        kc_histogram[integer] += 1
    print ("KC")
    print (kc_histogram/repetitions)

    for _ in range (2):
        dm_run_result = dm_simulator.run(circuit, repetitions=repetitions)
        dm_histogram = np.zeros(1<<2)
        for bitstring in dm_run_result.measurements['0,1']:
            integer = 0
            for pos, bit in enumerate(bitstring):
                integer += bit<<pos
            dm_histogram[integer] += 1
        print ("DM")
        print (dm_histogram/repetitions)

    exit()
示例#13
0
def trial(n=6, p=2, repetitions=1000, maxiter=2):

    # Generate a random 3-regular graph on n nodes
    graph = networkx.random_regular_graph(3, n)

    # Make qubits
    qubits = cirq.LineQubit.range(n)

    # Print an example circuit
    cirq_circuit = qaoa_max_cut_circuit_no_meas(qubits, p, graph)
    print('Example QAOA circuit:')
    print(cirq_circuit.to_text_diagram(transpose=True))
    meas_circuit = cirq.Circuit(cirq_circuit, cirq.measure(*qubits, key='m'))

    # Initialize simulators
    # sv_sim = cirq.Simulator()
    # dm_simulator = cirq.DensityMatrixSimulator()
    qs_sim_01 = qsimcirq.QSimSimulator(qsim_options={'t': 1, 'v': 0})
    # qs_sim_02 = qsimcirq.QSimSimulator( qsim_options={'t': 2, 'v': 0} )
    qs_sim_04 = qsimcirq.QSimSimulator(qsim_options={'t': 4, 'v': 0})
    # qs_sim_08 = qsimcirq.QSimSimulator( qsim_options={'t': 8, 'v': 0} )
    qs_sim_16 = qsimcirq.QSimSimulator(qsim_options={'t': 16, 'v': 0})
    # qh_sim_16 = qsimcirq.QSimhSimulator( qsimh_options={
    #     't': 64,
    #     'v':  2,
    #     'k': [k for k in range(int(n/2))],
    #     'w':  0,
    #     'p': int(2*n/3),
    #     'r': int(2*n/3)
    # } )
    # kc_sim = cirq.KnowledgeCompilationSimulator(cirq_circuit, initial_state=0)
    kc_smp = cirq.KnowledgeCompilationSimulator(meas_circuit, initial_state=0)

    # Create variables to store the largest cut and cut value found
    # sv_largest_cut_found = None
    # sv_largest_cut_value_found = 0
    qs_largest_cut_found = None
    qs_largest_cut_value_found = 0
    kc_largest_cut_found = None
    kc_largest_cut_value_found = 0

    # Define objective function (we'll use the negative expected cut value)
    # iter = 0
    def f(x):
        # Create circuit
        betas = x[:p]
        betas_dict = {'beta' + str(index): betas[index] for index in range(p)}
        gammas = x[p:]
        gammas_dict = {
            'gamma' + str(index): gammas[index]
            for index in range(p)
        }
        param_resolver = cirq.ParamResolver({**betas_dict, **gammas_dict})

        # VALIDATE STATE VECTOR SIMULATION
        # qsim_circuit = cirq.resolve_parameters(cirq_circuit, param_resolver)
        # qsim_circuit_01 = qsimcirq.QSimCircuit(cirq.resolve_parameters(meas_circuit, param_resolver))
        # qsim_circuit_04 = qsimcirq.QSimCircuit(cirq.resolve_parameters(meas_circuit, param_resolver))
        # qsim_circuit_16 = qsimcirq.QSimCircuit(cirq.resolve_parameters(meas_circuit, param_resolver))

        # sv_sim_start = time.time()
        # sv_sim_result = sv_sim.simulate(cirq_circuit, param_resolver=param_resolver)
        # sv_sim_time = time.time() - sv_sim_start

        qs_sim_start = time.time()
        qs_sim_result = qs_sim_16.simulate(cirq_circuit,
                                           param_resolver=param_resolver)
        qs_sim_time = time.time() - qs_sim_start

        # kc_sim_start = time.time()
        # kc_sim_result = kc_sim.simulate(cirq_circuit, param_resolver=param_resolver)
        # kc_sim_time = time.time() - kc_sim_start

        # print("kc_sim_result.state_vector()=")
        # print(kc_sim_result.state_vector())
        # print("qs_sim_result.state_vector()=")
        # print(qs_sim_result.state_vector())

        # assert qs_sim_result.state_vector().shape == (1<<n,)
        # assert cirq.linalg.allclose_up_to_global_phase(
        #     sv_sim_result.state_vector(),
        #     qs_sim_result.state_vector(),
        #     rtol = 1.e-5,
        #     atol = 1.e-7,
        # )
        # assert cirq.linalg.allclose_up_to_global_phase(
        #     qs_sim_result.state_vector(),
        #     kc_sim_result.state_vector(),
        #     rtol = 1.e-4,
        #     atol = 1.e-6,
        # )

        # VALIDATE SAMPLING HISTOGRAMS

        # Sample bitstrings from circuit
        # sv_smp_start = time.time()
        # sv_smp_result = sv_sim.run(meas_circuit, param_resolver=param_resolver, repetitions=repetitions)
        # sv_smp_time = time.time() - sv_smp_start
        # sv_bitstrings = sv_smp_result.measurements['m']

        # Process histogram
        # sv_histogram = defaultdict(int)
        # for bitstring in sv_bitstrings:
        #     integer = 0
        #     for pos, bit in enumerate(reversed(bitstring)):
        #         integer += bit<<pos
        #     sv_histogram[integer] += 1

        # Process bitstrings
        # nonlocal sv_largest_cut_found
        # nonlocal sv_largest_cut_value_found
        # sv_values = cut_values(sv_bitstrings, graph)
        # sv_max_value_index = np.argmax(sv_values)
        # sv_max_value = sv_values[sv_max_value_index]
        # if sv_max_value > sv_largest_cut_value_found:
        #     sv_largest_cut_value_found = sv_max_value
        #     sv_largest_cut_found = sv_bitstrings[sv_max_value_index]
        # sv_mean = np.mean(sv_values)

        # Sample bitstrings from circuit
        qs_smp_01_start = time.time()
        qs_smp_01_result = qs_sim_01.run(meas_circuit,
                                         param_resolver=param_resolver,
                                         repetitions=repetitions)
        qs_smp_01_time = time.time() - qs_smp_01_start
        qs_smp_01_time_dict[n].append(qs_smp_01_time)

        # qs_smp_02_start = time.time()
        # qs_smp_02_result = qs_sim_02.run(qsim_circuit_02, repetitions=repetitions)
        # qs_smp_02_time = time.time() - qs_smp_02_start
        # qs_smp_02_time_dict[n].append(qs_smp_02_time)

        qs_smp_04_start = time.time()
        qs_smp_04_result = qs_sim_04.run(meas_circuit,
                                         param_resolver=param_resolver,
                                         repetitions=repetitions)
        qs_smp_04_time = time.time() - qs_smp_04_start
        qs_smp_04_time_dict[n].append(qs_smp_04_time)

        # qs_smp_08_start = time.time()
        # qs_smp_08_result = qs_sim_08.run(qsim_circuit_08, repetitions=repetitions)
        # qs_smp_08_time = time.time() - qs_smp_08_start
        # qs_smp_08_time_dict[n].append(qs_smp_08_time)

        qs_smp_16_start = time.time()
        qs_smp_16_result = qs_sim_16.run(meas_circuit,
                                         param_resolver=param_resolver,
                                         repetitions=repetitions)
        qs_smp_16_time = time.time() - qs_smp_16_start
        qs_smp_16_time_dict[n].append(qs_smp_16_time)

        qs_bitstrings = qs_smp_16_result.measurements['m']

        # Process histogram
        qs_histogram = defaultdict(int)
        # qs_bitstring_strs = []
        for bitstring in qs_bitstrings:
            integer = 0
            # string = ''
            for pos, bit in enumerate(bitstring):
                integer += bit << pos
                # string += str(bit)
            qs_histogram[integer] += 1
            # qs_bitstring_strs.append(string)

        # Process bitstrings
        nonlocal qs_largest_cut_found
        nonlocal qs_largest_cut_value_found
        qs_values = cut_values(
            np.array([np.flip(qs_bitstring)
                      for qs_bitstring in qs_bitstrings]), graph)
        qs_max_value_index = np.argmax(qs_values)
        qs_max_value = qs_values[qs_max_value_index]
        if qs_max_value > qs_largest_cut_value_found:
            qs_largest_cut_value_found = qs_max_value
            qs_largest_cut_found = qs_bitstrings[qs_max_value_index]
        qs_mean = np.mean(qs_values)

        # qh_smp_16_start = time.time()
        # qh_smp_16_result = qh_sim_16.compute_amplitudes(program=qsim_circuit, bitstrings=qs_bitstring_strs)
        # qh_smp_16_time = time.time() - qh_smp_16_start
        # qh_smp_16_time_dict[n].append(qh_smp_16_time)

        # Sample bitstrings from circuit
        kc_smp_start = time.time()
        kc_smp_result = kc_smp.run(meas_circuit,
                                   param_resolver=param_resolver,
                                   repetitions=repetitions)
        kc_smp_time = time.time() - kc_smp_start
        kc_smp_time_dict[n].append(kc_smp_time)

        # Process histogram
        kc_bitstrings = kc_smp_result.measurements['m']
        kc_histogram = defaultdict(int)
        for bitstring in kc_bitstrings:
            integer = 0
            for pos, bit in enumerate(reversed(bitstring)):
                integer += bit << pos
            kc_histogram[integer] += 1

        # Process bitstrings
        nonlocal kc_largest_cut_found
        nonlocal kc_largest_cut_value_found
        kc_values = cut_values(kc_bitstrings, graph)
        kc_max_value_index = np.argmax(kc_values)
        kc_max_value = kc_values[kc_max_value_index]
        if kc_max_value > kc_largest_cut_value_found:
            kc_largest_cut_value_found = kc_max_value
            kc_largest_cut_found = kc_bitstrings[kc_max_value_index]
        kc_mean = np.mean(kc_values)

        # nonlocal iter
        # PRINT HISTOGRAMS
        # print ('iter,index,bitstring,bitstring_bin,sv_probability,sv_samples,qs_samples,kc_samples')
        # probabilities = np.zeros(1<<n)
        # for bitstring, amplitude in enumerate(sv_sim_result.state_vector()):
        #     probability = abs(amplitude) * abs(amplitude)
        #     probabilities[bitstring]=probability
        # sorted_bitstrings = np.argsort(probabilities)
        # for index, bitstring in enumerate(sorted_bitstrings):
        #     print (str(iter)+','+str(index)+','+str(bitstring)+','+format(bitstring,'b').zfill(n)+','+str(probabilities[bitstring])+','+"{:.6e}".format(sv_histogram[bitstring]/repetitions)+','+"{:.6e}".format(qs_histogram[bitstring]/repetitions)+','+"{:.6e}".format(kc_histogram[bitstring]/repetitions))

        print('qs_mean=' + str(qs_mean) + ' kc_mean=' + str(kc_mean))
        # print ( 'sv_sim_time='+str(sv_sim_time)+' qs_sim_time='+str(qs_sim_time)+' kc_sim_time='+str(kc_sim_time) )
        print('qs_smp_01_time=' + str(qs_smp_01_time) + ' qs_smp_04_time=' +
              str(qs_smp_04_time) + ' qs_smp_16_time=' + str(qs_smp_16_time) +
              ' kc_smp_time=' + str(kc_smp_time))
        print(
            '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~')
        # iter += 1
        return -qs_mean

    # Pick an initial guess
    x0 = np.random.uniform(-np.pi, np.pi, size=2 * p)

    # Optimize f
    print('Optimizing objective function ...')
    scipy.optimize.minimize(f,
                            x0,
                            method='Nelder-Mead',
                            options={'maxiter': maxiter})

    # Compute best possible cut value via brute force search
    # all_bitstrings = np.array(list(itertools.product(range(2), repeat=n)))
    # all_values = cut_values(all_bitstrings, graph)
    # max_cut_value = np.max(all_values)

    # Print the results
    print('The largest cut value found was {}.'.format(
        qs_largest_cut_value_found))