from qiskit.algorithms import VQE
from qiskit.algorithms.optimizers import SLSQP, L_BFGS_B
from qiskit.circuit.library import TwoLocal

num_qubits = 2
ansatz = TwoLocal(num_qubits, 'ry', 'cz')
opt = SLSQP(maxiter=60)
bfgs_optimizer = L_BFGS_B(maxiter=60)
vqe = VQE(ansatz, optimizer=opt)

ansatz.draw()

from qiskit import Aer

backend = Aer.get_backend('aer_simulator_statevector')

from qiskit.utils import QuantumInstance

backend = Aer.get_backend('aer_simulator')
quantum_instance = QuantumInstance(backend=backend, shots=800, seed_simulator=99) 

from qiskit.opflow import X, Z, I
print(I.to_matrix())
print((Z^I).to_matrix())

H2_op = (-1.052373245772859 * I ^ I) + \
        (0.39793742484318045 * I ^ Z) + \
        (-0.39793742484318045 * Z ^ I) + \
        (-0.01128010425623538 * Z ^ Z) + \
        (0.18093119978423156 * X ^ X)

print(H2_op.to_matrix())

from qiskit.utils import algorithm_globals
seed = 50
algorithm_globals.random_seed = seed
qi = QuantumInstance(Aer.get_backend('statevector_simulator'), seed_transpiler=seed, seed_simulator=seed)

ansatz = TwoLocal(rotation_blocks='ry', entanglement_blocks='cz')
slsqp = SLSQP(maxiter=1000)
vqe = VQE(ansatz, optimizer=bfgs_optimizer, quantum_instance=qi)
result = vqe.compute_minimum_eigenvalue(H2_op)
print(result)

from qiskit.circuit.library import EfficientSU2
entanglements = ["linear", "full"]
for entanglement in entanglements:
    ansatz = EfficientSU2(num_qubits=4, entanglement=entanglement)
    if entanglement == "linear":
        print("=============Linear Entanglement:=============")
        vqe = VQE(ansatz, optimizer=bfgs_optimizer, quantum_instance=qi)
        result = vqe.compute_minimum_eigenvalue(H2_op)
        print(result)
        print()
    else:
        print("=============Full Entanglement:=============")
        vqe = VQE(ansatz, optimizer=bfgs_optimizer, quantum_instance=qi)
        result = vqe.compute_minimum_eigenvalue(H2_op)
        print(result)
        print()

