from qiskit.algorithms import VQE

from qiskit import Aer
from qiskit.utils import QuantumInstance, algorithm_globals

seed = 50
algorithm_globals.random_seed = seed

backend = Aer.get_backend('qasm_simulator')
quantum_instance = QuantumInstance(backend=backend, shots=800,  seed_transpiler=seed, seed_simulator=seed)

from qiskit.algorithms.optimizers import L_BFGS_B

bfgs_optimizer = L_BFGS_B(maxiter=60)

import numpy as np
from qiskit.opflow import X, Z, I

a_1 = np.random.random_sample()
a_2 = np.random.random_sample()
J_21 = np.random.random_sample()

H_transverse_ising = a_1*(I^X) + a_2*(X^I) + J_21*(Z^Z)
print("========== Transverse Ising Model Hamiltonian for Two Qubits ==========\n")
print(H_transverse_ising.to_matrix())
print()

H2_molecule_Hamiltonian = -0.5053051899926562*(I^I) + \
                            -0.3277380754984016*(Z^I) + \
                            0.15567463610622564*(Z^Z) + \
                            -0.3277380754984016*(I^Z)
print("========== H2 Molecule Hamiltonian for Two Qubits ==========\n")
print(H2_molecule_Hamiltonian.to_matrix())
print()

from qiskit.circuit.library import EfficientSU2

def minimum_eigenvalue_by_vqe(num_qubits, ansatz_entanglement, optimizer, quantum_instance, hamiltonian):
    ansatz = EfficientSU2(num_qubits=num_qubits, entanglement=entanglement)
    vqe = VQE(ansatz, optimizer, quantum_instance=quantum_instance)
    result = vqe.compute_minimum_eigenvalue(hamiltonian)
    print(result)

num_qubits = 2
entanglement = "linear"

minimum_eigenvalue_by_vqe(num_qubits, entanglement, bfgs_optimizer, quantum_instance, H_transverse_ising)

num_qubits = 2
entanglement = "full"

minimum_eigenvalue_by_vqe(num_qubits, entanglement, bfgs_optimizer, quantum_instance, H_transverse_ising)

num_qubits = 2
entanglement = "linear"

minimum_eigenvalue_by_vqe(num_qubits, entanglement, bfgs_optimizer, quantum_instance, H2_molecule_Hamiltonian)

num_qubits = 2
entanglement = "full"

minimum_eigenvalue_by_vqe(num_qubits, entanglement, bfgs_optimizer, quantum_instance, H2_molecule_Hamiltonian)