import cirq
import random
import matplotlib.pyplot as plt
import numpy as np

def set_measure_x(circuit, qubits, n):
    for num in range(n):
        circuit.append(cirq.H(qubits[num]))

def set_measure_y(circuit, qubits, n):
    for num in range(n):
        circuit.append((cirq.Z**(-1/2))(qubits[num]))
        circuit.append(cirq.H(qubits[num]))

def qft_rotations_cirq(circuit, qubits, n):
    if n == 0:
        #print(circuit)
        set_measure_x(circuit, qubits, 4)
        circuit.append(cirq.measure(*qubits, key='this'))
        return circuit
    n -= 1
    circuit.append(cirq.H(qubits[n]))
    for qubit in range(n):
        circuit.append((cirq.CZ**(1/2**(n-qubit)))(qubits[qubit],qubits[n]))
    return qft_rotations_cirq(circuit, qubits, n) 

qubits = cirq.LineQubit.range(4)
circuit = cirq.Circuit()
circuit.append(cirq.X(qubits[0]))
qft_rotations_cirq(circuit, qubits, 4)
##set it to measure Y axis
#set_measure_x(circuit, qubits, 4)
#circuit.append(cirq.measure(*qubits, key='this'))
simulator = cirq.Simulator()
results = simulator.run(circuit , repetitions =100000)
#results = simulator.run(circuit)
print(circuit)
print(results.histogram(key="this"))

def qft_rotations_cirq(circuit, qubits, n):
    #this implementation is taken from https://qiskit.org/textbook/ch-algorithms/quantum-fourier-transform.html
    #if qubit amount is 0, then do nothing and return
    #print("loop n# %s"%n)
    if n == 0:
        #print(circuit)
        return circuit
    n -= 1
    circuit.append(cirq.H(qubits[n]))
    for qubit in range(n):
        circuit.append((cirq.CZ**(1/2**(n-qubit)))(qubits[qubit],qubits[n]))
        #print(n)
        #print(qubit)
    return qft_rotations_cirq(circuit, qubits, n)     

qubits = cirq.LineQubit.range(4)
circuit = cirq.Circuit()
circuit.append(cirq.X(qubits[0]))
qft_rotations_cirq(circuit, qubits, 4)
##set it to measure Y axis
set_measure_x(circuit, qubits, 4)
##measure the first qubit ---------V
circuit.append(cirq.measure(qubits[0], key='this'))
simulator = cirq.Simulator()
results = simulator.run(circuit , repetitions =1000000)
#results = simulator.run(circuit)
print(circuit)
print(results.histogram(key="this"))