Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
3.2 kB
3
Indexable
def make_Majorana(N):

    # Make 'N' Majorana fermions. Set of N Hermitian matrices psi_i, i=1,..N
    # obeying anti-commutation relations {psi_i,psi_j} = δ_{ij}
    
    X = np.array([[0, 1], [1, 0]])
    Y = np.array([[0, -1j], [1j, 0]])
    Z = np.array([[1, 0], [0, -1]])
    I = np.array([[1, 0], [0, 1]])

    psi = dict()

    if simpl == 0: 
        for i in range(1, N+1):

            if (i % 2) == 1:
            # For ex: On odd numbered Majorana with N = 8, we have --> XIII, ZXII, ZZXI, ZZZX
                matlist = [Z] * int((i-1)/2)
                matlist.append(X)
                matlist = matlist + [I] * int((N/2 - (i+1)/2))
                psi[i] = 1/np.sqrt(2)*reduce(np.kron, matlist)
            else:
            # On even numbered with N = 8 --> YIII, ZYII, ZZYI, ZZZY
                matlist = [Z] * int((i - 2) / 2)
                matlist.append(Y)
                matlist = matlist + [I] * int((N/2 - i/2))
                psi[i] = 1/np.sqrt(2)*reduce(np.kron, matlist)

    if simpl == 1: 
        for i in range(1, N+1):

            if (i % 2) == 1:
            # For ex: On odd numbered Majorana with N = 8, we have --> XIII, IXII, IIXI, IIIX
                matlist = [I] * int((i-1)/2)
                matlist.append(X)
                matlist = matlist + [I] * int((N/2 - (i+1)/2))
                psi[i] = 1/np.sqrt(2)*reduce(np.kron, matlist)
            else:
            # On even numbered with N = 8 --> YIII, IYII, IIYI, IIIY
                matlist = [I] * int((i - 2) / 2)
                matlist.append(Y)
                matlist = matlist + [I] * int((N/2 - i/2))
                psi[i] = 1/np.sqrt(2)*reduce(np.kron, matlist)


    for i in range(1, N+1):
        for j in range(1, N+1):

            if simpl == 0:
            # Not checking this for simplified H yet.  

                if i != j:
                    if np.allclose(psi[i] @ psi[j], -psi[j] @ psi[i]) == False:
                        print ("Does not satisfy algebra")

                if i == j:
                    if np.allclose(psi[i] @ psi[j] + psi[j] @ psi[i], np.eye(int(2**(N/2)))) == False:
                        print ("Does not satisfy algebra for i=j")

    return psi


def make_Hamiltonian(psi, N, instances, J_squared):
    
    # Creates multiple realisations of the SYK Hamiltonian
    # Variance of couplings is given by 'J_squared * 3!/N^3'.

    H = 0
    J = dict()
    sigma_sq = 6.*J_squared/(N**3)
    sigma = math.sqrt(sigma_sq)

    for i in range(1, N+1):
        for j in range(i+1, N+1):
            for k in range(j+1, N+1):
                for l in range(k+1, N+1):
                    J[i, j, k, l] = np.random.normal(loc=0, scale=sigma,size=instances)
                    #print (J[i, j, k, l])
                    M = psi[i] @ psi[j] @ psi[k] @ psi[l]

                    if np.allclose(M, M.conj().T) == True: 
                        H = H + np.array([element * M for element in J[i, j, k, l]])

                    else:
                        if np.allclose(M, -M.conj().T) == True: 
                            M *= complex(0,1.)
                            H = H + np.array([element * M for element in J[i, j, k, l]])
                    

    return H