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

QUBITS_NUM = 3

def create_pauli_string_with_pauli_op_on_index_i(pauli_op, i, qubits_num):
    if i == 1:
        pauli_string = pauli_op
        for qubit in range(qubits_num - 1):
            pauli_string = pauli_string ^ I
        return pauli_string
    
    pauli_string = I
    for qubit in range(2, qubits_num + 1):
        if qubit == i:
            pauli_string = pauli_string ^ pauli_op
        else:
            pauli_string = pauli_string ^ I
            
    return pauli_string

def create_pauli_string_with_pauli_ops_on_index_i_and_j(pauli_op_second, i, pauli_op_first, j, qubits_num):
    if j == 1:
        pauli_string = pauli_op_first
        for qubit in range(2, qubits_num + 1):
            if qubit == i:
                pauli_string = pauli_string ^ pauli_op_second
            else:
                pauli_string = pauli_string ^ I
        return pauli_string
    
    pauli_string = I
    for qubit in range(2, qubits_num + 1):
        if qubit == j:
            pauli_string = pauli_string ^ pauli_op_first
        elif qubit == i:
            pauli_string = pauli_string ^ pauli_op_second
        else:
            pauli_string = pauli_string ^ I
            
    return pauli_string


def get_Ising_model_hamiltonian():
    hamiltonian = I
    for qubit in range(QUBITS_NUM - 1):
        hamiltonian = hamiltonian^I
    hamiltonian = 0 * hamiltonian
    
    for i in range(1, QUBITS_NUM + 1):
        a_i = np.random.random_sample()
        x_i = create_pauli_string_with_pauli_op_on_index_i(X, i, QUBITS_NUM)
        hamiltonian = hamiltonian + a_i * x_i
        for j in range(1, i):
            J_ij = np.random.random_sample()
            z_ij = create_pauli_string_with_pauli_ops_on_index_i_and_j(Z, i, Z, j, QUBITS_NUM)
            hamiltonian = hamiltonian + J_ij * z_ij
    
    return hamiltonian

transverse_ising_3_qubits = get_Ising_model_hamiltonian()
print(transverse_ising_3_qubits)

from qiskit.opflow import X, Z, I

H2_molecule_hamiltonian = 0.0 * (I^I^I)
                    + 0.012764169333459807 * (X^I^I)
                    + 0.7691573729160869 * (I^X^I)
                    + 0.398094746026449 * (Z^Z^I)
                    + 0.15250261906586637 * (I^I^X)
                    + 0.2094051920882264 * (Z^I^Z)
                    + 0.5131291860752999 * (I^Z^Z)