# import functionality from qiskit for building and running circuits
from qiskit import QuantumCircuit, BasicAer, transpile
import numpy as np

# define a quantum circuit with a single "X" gate
circuit = QuantumCircuit(1)
circuit.x(0)
circuit.measure_all()

circuit.draw()

# select a quantum backend and run the circuit
backend = BasicAer.get_backend('qasm_simulator')
shots = 2**13

job = backend.run(circuit, shots=shots)
result = job.result()

# get the measurement counts from the circuit
counts = result.get_counts()
print(counts)
print('probability to measure state 0: {}%'.format(counts.get('0', 0) / shots * 100))
print('probability to measure state 1: {}%'.format(counts.get('1', 0) / shots * 100))

# define a quantum circuit with a single Hadamard gate
circuit = QuantumCircuit(1)
circuit.h(0)
circuit.measure_all()

circuit.draw()

job = backend.run(transpile(circuit, backend), shots=shots)
result = job.result()

counts = result.get_counts()
print(counts)
print('probability to measure state 0: {}%'.format(counts.get('0', 0) / shots * 100))
print('probability to measure state 1: {}%'.format(counts.get('1', 0) / shots * 100))

# define the state |1>
a = 0
b = 1
state = np.array([a,b])
norm = np.linalg.norm(state)
normalized_state_ONE = state/norm

print(normalized_state_ONE)

# then, initialize this state as a quantum circuit and measure in computational (Z) basis
circuit = QuantumCircuit(1)
circuit.initialize(normalized_state_ONE)
circuit.measure_all()
print(circuit)

# run the circuit and then subtract the two probabilities p(0)-p(1)
job = backend.run(transpile(circuit, backend), shots=shots)
result = job.result()

counts = result.get_counts()
print(counts)

expval = (counts.get('0',0)-counts.get('1',0)) / shots
print('expectation value: {}'.format(expval))

# define the state |+>
a = 0.70710678 # 1/sqrt(2)
b = 0.70710678
state = np.array([a,b])
norm = np.linalg.norm(state)
normalized_state_PLUS = state/norm

print(normalized_state_PLUS)

# initialize as a quantum circuit and measure
circuit = QuantumCircuit(1)
circuit.initialize(normalized_state_PLUS)
circuit.measure_all()
print(circuit)

# run the circuit and then subtract the two probabilities p(0)-p(1)
job = backend.run(transpile(circuit, backend), shots=shots)
result = job.result()

counts = result.get_counts()
print(counts)

expval = (counts.get('0',0)-counts.get('1',0)) / shots
print('expectation value: {}'.format(expval))

# define the Pauli Z operator
z = np.array([[1,  0],
             [0, -1]])

# what are the eigenvectors of this operator?
from qiskit.visualization import plot_state_city, plot_bloch_multivector
z_eigenvals, z_eigenvecs = np.linalg.eigh(z)

print('Eigensystem of Z:')
print(z_eigenvals)
print(z_eigenvecs)

plot_bloch_multivector(z_eigenvecs[:,0])

import qiskit.tools.jupyter
%qiskit_version_table
%qiskit_copyright