#initialization
import sys
import matplotlib.pyplot as plt
%matplotlib inline
import numpy as np

# importing the QISKit
from qiskit import QuantumProgram
try:
    sys.path.append("../../") # go to parent dir
    import Qconfig
    qx_config = {
        "APItoken": Qconfig.APItoken,
        "url": Qconfig.config['url']}
except:
    qx_config = {
        "APItoken":"YOUR_TOKEN_HERE",
        "url":"https://quantumexperience.ng.bluemix.net/api"}
    
# import basic plot tools
from qiskit.tools.visualization import plot_histogram

#set api
from IBMQuantumExperience import IBMQuantumExperience
api = IBMQuantumExperience(token=qx_config['APItoken'], config={'url': qx_config['url']})

#prepare backends
from qiskit.backends import discover_local_backends, discover_remote_backends, get_backend_instance
remote_backends = discover_remote_backends(api) #we have to call this to connect to remote backends
local_backends = discover_local_backends()


# Quantum program setup
Q_program = QuantumProgram()

#for plot with 16qubit
import numpy as np
from functools import reduce
from scipy import linalg as la
from collections import Counter
import matplotlib.pyplot as plt

def plot_histogram5(data, number_to_keep=False):
    """Plot a histogram of data.
    data is a dictionary of  {'000': 5, '010': 113, ...}
    number_to_keep is the number of terms to plot and rest is made into a
    single bar called other values
    """
    if number_to_keep is not False:
        data_temp = dict(Counter(data).most_common(number_to_keep))
        data_temp["rest"] = sum(data.values()) - sum(data_temp.values())
        data = data_temp

    labels = sorted(data)
    values = np.array([data[key] for key in labels], dtype=float)
    pvalues = values / sum(values)
    numelem = len(values)
    ind = np.arange(numelem)  # the x locations for the groups
    width = 0.35  # the width of the bars
    fig, ax = plt.subplots()
    rects = ax.bar(ind, pvalues, width, color='seagreen')
    # add some text for labels, title, and axes ticks
    ax.set_ylabel('Probabilities', fontsize=12)
    ax.set_xticks(ind)
    ax.set_xticklabels(labels, fontsize=12, rotation=70)
    ax.set_ylim([0., min([1.2, max([1.2 * val for val in pvalues])])])
    # attach some text labels
    for rect in rects:
        height = rect.get_height()
        ax.text(rect.get_x() + rect.get_width() / 2., 1.05 * height,
                '%f' % float(height),
                ha='center', va='bottom', fontsize=8)
    plt.show()

q1_2 = Q_program.create_quantum_register("q1_2", 3)
c1_2 = Q_program.create_classical_register("c1_2", 3)
qw1_2 = Q_program.create_circuit("qw1_2", [q1_2], [c1_2])

t=8 #time
qw1_2.x(q1_2[2])
qw1_2.u3(t, 0, 0, q1_2[1])
qw1_2.cx(q1_2[2], q1_2[1])
qw1_2.u3(t, 0, 0, q1_2[1])
qw1_2.cx(q1_2[2], q1_2[1])
qw1_2.measure(q1_2[0], c1_2[0])
qw1_2.measure(q1_2[1], c1_2[2])
qw1_2.measure(q1_2[2], c1_2[1])
print(qw1_2.qasm())

result = Q_program.execute(["qw1_2"], backend='local_qiskit_simulator', shots=1000)
plot_histogram5(result.get_counts("qw1_2"))

result = Q_program.execute(["qw1_2"], backend='ibmqx4', shots=1000, max_credits=3, wait=10, timeout=1024)
plot_histogram5(result.get_counts("qw1_2"))

q1 = Q_program.create_quantum_register("q1", 3)
c1 = Q_program.create_classical_register("c1", 3)
qw1 = Q_program.create_circuit("qw1", [q1], [c1])

t=8 #time
qw1.x(q1[1])
qw1.cx(q1[2], q1[1])
qw1.u3(t, 0, 0, q1[2])
qw1.cx(q1[2], q1[0])
qw1.u3(t, 0, 0, q1[2])
qw1.cx(q1[2], q1[0])
qw1.cx(q1[2], q1[1])
qw1.u3(2*t, 0, 0, q1[2])
qw1.measure(q1[0], c1[0])
qw1.measure(q1[1], c1[1])
qw1.measure(q1[2], c1[2])
print(qw1.qasm())

result = Q_program.execute(["qw1"], backend='local_qiskit_simulator')
plot_histogram5(result.get_counts("qw1"))

result = Q_program.execute(["qw1"], backend='ibmqx4', shots=1000, max_credits=3, wait=10, timeout=600)
plot_histogram5(result.get_counts("qw1"))

