%run qlatvia.py

draw_qubit_grover()

draw_quantum_state((5/8)**0.5,(3/8)**0.5,"|u>")


def query(elements=[1],marked_elements=[0]):
    for i in marked_elements:
        elements[i] = -1 * elements[i]    
    return elements
def inversion (elements=[1]):
    # summation of all values
    summation = 0
    for i in range(len(elements)):
        summation += elements[i]

    # mean of all values
    mean = summation / len(elements)

    # reflection over mean
    for i in range(len(elements)):
        value = elements[i]
        new_value = mean - (elements[i]-mean)
        elements[i] = new_value   
    return elements

from math import asin, pi

# initial values
iteration = 5
N = 16
marked_elements = [0]
k = len(marked_elements)
elements = []
states_on_unit_circle= []

# initial quantum state
for i in range(N):
    elements.append(1/N**0.5)

x = elements[N-1] * ((N-k)**0.5)
y = elements[0] * (k**0.5)
states_on_unit_circle.append([x,y,"0"])

# Execute Grover's search algorithm for $iteration steps
for step in range(iteration):
    # query
    elements = query(elements,marked_elements)
    x = elements[N-1] * ((N-k)**0.5)
    y = elements[0] * (k**0.5)
    states_on_unit_circle.append([x,y,str(step)+"''"])
    # inversion
    elements = inversion(elements)
    x = elements[N-1] * ((N-k)**0.5)
    y = elements[0] * (k**0.5)
    states_on_unit_circle.append([x,y,str(step+1)])

# draw all states
%run qlatvia.py
draw_qubit_grover()
for state in states_on_unit_circle:
    draw_quantum_state(state[0],state[1],state[2])

# print the angles
print("angles in degree")
for state in states_on_unit_circle:
    print(asin(state[1])/pi*180)

def query(elements=[1],marked_elements=[0]):
    for i in marked_elements:
        elements[i] = -1 * elements[i]    
    return elements

def inversion (elements=[1]):
    # summation of all values
    summation = 0
    for i in range(len(elements)):
        summation += elements[i]

    # mean of all values
    mean = summation / len(elements)

    # reflection over mean
    for i in range(len(elements)):
        value = elements[i]
        new_value = mean - (elements[i]-mean)
        elements[i] = new_value   
    return elements

from math import asin, pi

# initial values
iteration = 10
N = 128

# try each case one by one
marked_elements = [0]
#marked_elements = [0,1]
#marked_elements = [0,1,2,3]
#marked_elements = [0,1,2,3,4,5,6,7]

k = len(marked_elements)
elements = []
states_on_unit_circle= []

# initial quantum state
for i in range(N):
    elements.append(1/N**0.5)


x = elements[N-1] * ((N-k)**0.5)
y = elements[0] * (k**0.5)
states_on_unit_circle.append([x,y,"0"])

# Execute Grover's search algorithm for $iteration steps
for step in range(iteration):
    # query
    elements = query(elements,marked_elements)
    x = elements[N-1] * ((N-k)**0.5)
    y = elements[0] * (k**0.5)
    states_on_unit_circle.append([x,y,str(step)+"''"])
    # inversion
    elements = inversion(elements)
    x = elements[N-1] * ((N-k)**0.5)
    y = elements[0] * (k**0.5)
    states_on_unit_circle.append([x,y,str(step+1)])

# draw all states
%run qlatvia.py
draw_qubit_grover()
for state in states_on_unit_circle:
    draw_quantum_state(state[0],state[1],state[2])

# print the angles
print("angles in degree")
for state in states_on_unit_circle:
    print(asin(state[1])/pi*180)

def query(elements=[1],marked_elements=[0]):
    for i in marked_elements:
        elements[i] = -1 * elements[i]    
    return elements

def inversion (elements=[1]):
    # summation of all values
    summation = 0
    for i in range(len(elements)):
        summation += elements[i]

    # mean of all values
    mean = summation / len(elements)

    # reflection over mean
    for i in range(len(elements)):
        value = elements[i]
        new_value = mean - (elements[i]-mean)
        elements[i] = new_value   
    return elements

from math import asin, pi

# initial values
iteration = 20
#iteration = 10
N = 256

# try each case one by one
marked_elements = [0]
#marked_elements = [0,1]
#marked_elements = [0,1,2,3]
#marked_elements = [0,1,2,3,4,5,6,7]

k = len(marked_elements)
elements = []
states_on_unit_circle= []

# initial quantum state
for i in range(N):
    elements.append(1/N**0.5)


x = elements[N-1] * ((N-k)**0.5)
y = elements[0] * (k**0.5)
states_on_unit_circle.append([x,y,"0"])

# Execute Grover's search algorithm for $iteration steps
for step in range(iteration):
    # query
    elements = query(elements,marked_elements)
    x = elements[N-1] * ((N-k)**0.5)
    y = elements[0] * (k**0.5)
    states_on_unit_circle.append([x,y,str(step)+"''"])
    # inversion
    elements = inversion(elements)
    x = elements[N-1] * ((N-k)**0.5)
    y = elements[0] * (k**0.5)
    states_on_unit_circle.append([x,y,str(step+1)])

# draw all states
%run qlatvia.py
draw_qubit_grover()
for state in states_on_unit_circle:
    draw_quantum_state(state[0],state[1],state[2])

# print the angles
print("angles in degree")
for state in states_on_unit_circle:
    print(asin(state[1])/pi*180)