from qiskit import QuantumCircuit, QuantumRegister, ClassicalRegister, execute, Aer, IBMQ
import qiskit_tools as qt
import numpy as np
import matplotlib.pyplot as plt
import matplotlib

digit = 2
a = 1

phase = False

nint = qt.get_nint([digit,a])
npres = qt.get_npres([digit,a])
n = nint + npres

if phase:
    n+=1

print(n, nint, npres)

binary_x = qt.my_binary_repr(digit, n, nint=nint, phase=phase)
binary_a = qt.my_binary_repr(a, n, nint=nint, phase=phase)

print(binary_x,binary_a)

print('It is',digit>=a,'that',str(digit)+' >= '+str(a)+'.')

qx = QuantumRegister(n, 'x')
qtarg = QuantumRegister(1, 'targ')
qans = QuantumRegister(n-1, 'anc')
out_reg = ClassicalRegister(1,'out_reg')
circ = QuantumCircuit(qx, qtarg, qans, out_reg)

x_gate = qt.input_bits_to_qubits(binary_x, circ, reg=qx, wrap=True)
circ.append(x_gate, qx);

intcomp_gate = qt.integer_compare(circ, qx, qtarg, qans, a, geq=True, wrap=True)
circ.append(intcomp_gate, [*qx, *qtarg, *qans]);

circ.measure(qtarg, out_reg);

circ.draw('latex')

circ.decompose(reps=1).draw('latex')

shots=10
emulator = Aer.get_backend('qasm_simulator')
job = execute(circ, emulator, shots=shots )
hist = job.result().get_counts()

print('Target:')
print(digit,'>=',a,'=',digit>=a)

print('Result:')
for label in hist.keys():
    print(digit,'>=',a,'=',bool(qt.bin_to_dec(label, nint=nint, phase=False)),'->',label,'with probability',float(hist[label])/shots)

digit = 1.5
a = 2.25

phase = False

nint = qt.get_nint([digit,a])
npres = qt.get_npres([digit,a])
n = nint + npres

if phase:
    n+=1

print(n, nint, npres)

binary_x = qt.my_binary_repr(digit, n, nint=nint, phase=phase)
binary_a = qt.my_binary_repr(a, n, nint=nint, phase=phase)

int_x = qt.bin_to_dec(binary_x, nint=None, phase=False)
int_a = qt.bin_to_dec(binary_a, nint=None, phase=False)

print(digit,'->',binary_x,'->',int(int_x),',',a,'->',binary_a,'->',int(int_a))

print('It is',digit>=a,'that',str(digit)+' >= '+str(a)+', and it is',int_x>=int_a,'that',str(int_x)+' >= '+str(int_a))

qx = QuantumRegister(n, 'x')
qtarg = QuantumRegister(1, 'targ')
qans = QuantumRegister(n-1, 'anc')
out_reg = ClassicalRegister(1,'out_reg')
circ = QuantumCircuit(qx, qtarg, qans, out_reg)

x_gate = qt.input_bits_to_qubits(binary_x, circ, reg=qx, wrap=True)
circ.append(x_gate, qx);

intcomp_gate = qt.integer_compare(circ, qx, qtarg, qans, int_a, geq=True, wrap=True)
circ.append(intcomp_gate, [*qx, *qtarg, *qans]);

circ.measure(qtarg, out_reg);

shots=10
emulator = Aer.get_backend('qasm_simulator')
job = execute(circ, emulator, shots=shots )
hist = job.result().get_counts()

print('Target:')
print(digit,'>=',a,'=',digit>=a)

print('Result:')
for label in hist.keys():
    print(digit,'>=',a,'=',bool(qt.bin_to_dec(label, nint=nint, phase=False)),'->',label,'with probability',float(hist[label])/shots)

digit = -1.5
a = 2.25

phase = True

nint = qt.get_nint([digit,a])
npres = qt.get_npres([digit,a])
n = nint + npres

if phase:
    n+=1

print(n, nint, npres)

binary_x = qt.my_binary_repr(digit, n, nint=nint, phase=phase)
binary_a = qt.my_binary_repr(a, n, nint=nint, phase=phase)

binary_a_ = qt.my_binary_repr(a, n, nint=nint, phase=phase)

if binary_a[0]=='0':
    binary_a_ = '1'+binary_a[1:]
elif binary_a[0]=='1':
    binary_a_ = '0'+binary_a[1:]

binary_x_ = qt.my_binary_repr(digit, n, nint=nint, phase=phase)

if binary_x[0]=='0':
    binary_x_ = '1'+binary_x[1:]
elif binary_x[0]=='1':
    binary_x_ = '0'+binary_x[1:]

int_x = qt.bin_to_dec(binary_x_, nint=None, phase=False)
int_a = qt.bin_to_dec(binary_a_, nint=None, phase=False)

print(digit,'->',binary_x,'->',binary_x_,'->',int(int_x),',',a,'->',binary_a,'->',binary_a_,'->',int(int_a))

print('It is',digit>=a,'that',str(digit)+' >= '+str(a)+', and it is',int_x>=int_a,'that',str(int_x)+' >= '+str(int_a))

qx = QuantumRegister(n, 'x')
qtarg = QuantumRegister(1, 'targ')
qans = QuantumRegister(n-1, 'anc')
out_reg = ClassicalRegister(1,'out_reg')
circ = QuantumCircuit(qx, qtarg, qans, out_reg)

x_gate = qt.input_bits_to_qubits(binary_x, circ, reg=qx, wrap=True)
circ.append(x_gate, qx);

circ.x(qx[-1]);

intcomp_gate = qt.integer_compare(circ, qx, qtarg, qans, int_a, geq=True, wrap=True)
circ.append(intcomp_gate, [*qx, *qtarg, *qans]);

circ.x(qx[-1]);

circ.measure(qtarg, out_reg);

circ.draw('latex')

shots=10
emulator = Aer.get_backend('qasm_simulator')
job = execute(circ, emulator, shots=shots )
hist = job.result().get_counts()

print('Target:')
print(digit,'>=',a,'=',digit>=a)

print('Result:')
for label in hist.keys():
    print(digit,'>=',a,'=',bool(qt.bin_to_dec(label, nint=nint, phase=False)),'->',label,'with probability',float(hist[label])/shots)

digit = -1.5
a = 2.25

phase = True

nint = qt.get_nint([digit,a])
npres = qt.get_npres([digit,a])
n = nint + npres

if phase:
    n+=1
    
binary_x = qt.my_binary_repr(digit, n, nint=nint, phase=phase)
binary_a = qt.my_binary_repr(a, n, nint=nint, phase=phase)

binary_x_ = qt.my_binary_repr(digit, n, nint=nint, phase=phase)

if binary_x[0]=='0':
    binary_x_ = '1'+binary_x[1:]
elif binary_x[0]=='1':
    binary_x_ = '0'+binary_x[1:]
    
binary_a_ = qt.my_binary_repr(a, n, nint=nint, phase=phase)

if binary_a[0]=='0':
    binary_a_ = '1'+binary_a[1:]
elif binary_a[0]=='1':
    binary_a_ = '0'+binary_a[1:]
    
int_x = qt.bin_to_dec(binary_x_, nint=None, phase=False)
int_a = qt.bin_to_dec(binary_a_, nint=None, phase=False)

qx = QuantumRegister(n, 'x')
qtarg = QuantumRegister(1, 'targ')
qans = QuantumRegister(n-1, 'anc')
out_reg = ClassicalRegister(1,'out_reg')
circ = QuantumCircuit(qx, qtarg, qans, out_reg)

x_gate = qt.input_bits_to_qubits(binary_x, circ, reg=qx, wrap=True)
circ.append(x_gate, qx);

circ.x(qx[-1]);
intcomp_gate = qt.integer_compare(circ, qx, qtarg, qans, int_a, geq=False, wrap=True)
circ.append(intcomp_gate, [*qx, *qtarg, *qans]);
circ.x(qx[-1]);

circ.measure(qtarg, out_reg);

shots=10
emulator = Aer.get_backend('qasm_simulator')
job = execute(circ, emulator, shots=shots )
hist = job.result().get_counts()

print('Target:')
print(digit,'<=',a,'=',digit<=a)

print('Result:')
for label in hist.keys():
    print(digit,'<=',a,'=',bool(qt.bin_to_dec(label, nint=nint, phase=False)),'->',label,'with probability',float(hist[label])/shots)

digit = 3.5
a = 2.25

phase = True

nint = qt.get_nint([digit,a])
npres = qt.get_npres([digit,a])
n = nint + npres

if phase:
    n+=1
    
binary_x = qt.my_binary_repr(digit, n, nint=nint, phase=phase)

qx = QuantumRegister(n, 'x')
qtarg = QuantumRegister(1, 'targ')
qans = QuantumRegister(n-1, 'anc')
out_reg = ClassicalRegister(1,'out_reg')
circ = QuantumCircuit(qx, qtarg, qans, out_reg)

x_gate = qt.input_bits_to_qubits(binary_x, circ, reg=qx, wrap=True)
circ.append(x_gate, qx);

comp_gate = qt.inequal_cond(circ, qx, qtarg, qans, a, nint=nint, phase=phase, geq=False, wrap=True)
circ.append(comp_gate, [*qx, *qtarg, *qans]);

circ.measure(qtarg, out_reg);

shots=10
emulator = Aer.get_backend('qasm_simulator')
job = execute(circ, emulator, shots=shots )
hist = job.result().get_counts()

print('Target:')
print(digit,'<=',a,'=',digit<=a)

print('Result:')
for label in hist.keys():
    print(digit,'<=',a,'=',bool(qt.bin_to_dec(label, nint=nint, phase=False)),'->',label,'with probability',float(hist[label])/shots)