import matplotlib.pyplot as plt
import numpy as np

# Define N values
N = np.arange(1, 1001)

# Calculate logarithm of N base 2
log2_N = np.log2(N)

# Generate plot
plt.figure(figsize=(8, 6))
plt.plot(N, log2_N, label="log2(N)")
plt.xlabel("N")
plt.ylabel("n = log2(N)") # number of qubits 
plt.title("Logarithm of N (base 2) for N = 1 to 1000")
plt.grid(True)
plt.legend()
plt.show()

from qiskit import QuantumCircuit, Aer, transpile, assemble
from qiskit.visualization import plot_histogram, plot_bloch_multivector
import numpy as np
import matplotlib.pyplot as plt


def state_preparation_circuit(x):
    """
    Create a state preparation circuit for encoding the classical data point x.
    """
    n = len(x)
    qc = QuantumCircuit(n)
    
    for i, xi in enumerate(x):
        angle = 2 * np.arctan(xi)  # Convert the feature xi to an angle for rotation
        qc.ry(angle, i)  # Apply Ry rotation to the i-th qubit
    
    return qc

# Example classical data point
x = [0.1, 0.5, 0.3]

# Create the state preparation circuit
qc = state_preparation_circuit(x)

# Visualize the circuit
qc.draw('mpl')



# Use the Aer simulator to simulate the quantum state
simulator = Aer.get_backend('statevector_simulator')

# Transpile and assemble the quantum circuit
transpiled_qc = transpile(qc, simulator)
qobj = assemble(transpiled_qc)

# Execute the circuit on the statevector simulator
result = simulator.run(qobj).result()

# Get the statevector representing the quantum state
statevector = result.get_statevector()

# Plot the Bloch sphere representation of the quantum state
plot_bloch_multivector(statevector)



# Print the statevector to see the quantum state
print("Statevector representing the quantum state:")
print(statevector)




# Define the dense angle encoding circuit for multiple features
def dense_angle_encoding_circuit(x):
    """
    Create a quantum circuit to encode a feature vector x
    using dense angle encoding.
    """
    num_qubits = len(x) // 2
    qc = QuantumCircuit(num_qubits)
    
    for i in range(0, len(x), 2):
        amplitude_angle = np.pi * x[i]
        phase_angle = 2 * np.pi * x[i+1]
        qc.ry(2 * amplitude_angle, i//2)
        qc.rz(phase_angle, i//2)
    
    return qc

# Example feature vector with 8 features
x = [0.3, 0.7, 0.5, 0.9, 0.2, 0.4, 0.8, 0.6]

# Create the dense angle encoding circuit
qc = dense_angle_encoding_circuit(x)

# Visualize the circuit
qc.draw('mpl')



# Use the Aer simulator to simulate the quantum state
simulator = Aer.get_backend('statevector_simulator')

# Transpile and assemble the quantum circuit
transpiled_qc = transpile(qc, simulator)
qobj = assemble(transpiled_qc)

# Execute the circuit on the statevector simulator
result = simulator.run(qobj).result()

# Get the statevector representing the quantum state
statevector = result.get_statevector()

# Plot the Bloch sphere representation of the quantum state
plot_bloch_multivector(statevector)

