Esempio n. 1
0
def calculate_pairing_matrix(u, v, norm):
    assert is_square_matrix(u)
    assert is_square_matrix(v)
    assert u.shape[0] == v.shape[0]

    # Warn if u is singular, but don't abort cuz sometimes this is OK..
    (signdet, logdet) = numpy.linalg.slogdet(u)
    logger.info('|det(u)| = %g', numpy.abs(numpy.exp(logdet)))  # actually, just log it for now..

    phiMat = numpy.dot( numpy.linalg.inv(u.conjugate().transpose()), v.conjugate().transpose() )

#    logger.debug('Pairing matrix = ...')
#    logger.debug(phiMat)
#    logger.debug("Pairing matrix's main diagonal = ...")
#    logger.debug(phiMat.diagonal())

    # Check that phiMat is symmetric:
    if numpy.max(numpy.abs(phiMat - phiMat.transpose())) > 1e-8:
        raise RuntimeError('"Symmetricness" of pairing matrix = %.9g', numpy.max(numpy.abs(phiMat - phiMat.transpose())))

    # Check against TI code (must first run *_Fourier.py with same parameters):
#    phiMat_TI = numpy.loadtxt('phiMat_TI.dat').view(complex)
#    logger.debug('max|phiMat - phiMat_TI| = %.9g ', numpy.max(numpy.abs(phiMat - phiMat_TI)))

    phiNorm = norm_of_pairing_matrix(phiMat)
    logger.info('Norm of pairing matrix before normalization = %f', phiNorm)

    if norm is not None:
        phiMat = norm * (phiMat / phiNorm)
        phiNorm = norm_of_pairing_matrix(phiMat)
        logger.info('Norm of pairing matrix after normalization = %f', phiNorm)

    return phiMat
Esempio n. 2
0
def calculate_free_fermion_pairing_matrix(evecs, evals, Nparticles, norm):
    assert is_square_matrix(evecs)

    Nsites = evecs.shape[0]
    assert Nsites == len(evals)

    M = Nparticles/2  # ( = N_up = N_down )
    assert M <= Nsites

    phiMat = numpy.zeros((Nsites, Nsites), dtype=complex)
    for ind_r in range(0, Nsites):
        for ind_rp in range(0, Nsites):
            phiMat[ind_r, ind_rp] = numpy.dot( evecs[ind_r, 0:M], evecs[ind_rp, 0:M] )

#    logger.debug('Pairing matrix = ...')
#    logger.debug(phiMat)
#    logger.debug("Pairing matrix's main diagonal = ...")
#    logger.debug(phiMat.diagonal())

    # Check that phiMat is symmetric:
    if numpy.max(numpy.abs(phiMat - phiMat.transpose())) > 1e-8:
        raise RuntimeError('"Symmetricness" of pairing matrix = %.9g', numpy.max(numpy.abs(phiMat - phiMat.transpose())))

    phiNorm = norm_of_pairing_matrix(phiMat)
    logger.info('Norm of pairing matrix before normalization = %f', phiNorm)

    if norm is not None:
        phiMat = norm * (phiMat / phiNorm)
        phiNorm = norm_of_pairing_matrix(phiMat)
        logger.info('Norm of pairing matrix after normalization = %f', phiNorm)

    return phiMat
Esempio n. 3
0
def add_noise_to_matrix_diagonal(mat, noiselevel=.001):
    # only adds noise to the diagonal
    assert 0 <= noiselevel < 1
    assert is_square_matrix(mat)
    assert numpy.max(numpy.abs(mat - mat.transpose())) < 1e-12
    mat = mat.copy()
    if noiselevel == 0:
        return mat
    for i in six.moves.xrange(mat.shape[0]):
        mat[i, i] *= 1 + random.uniform(-noiselevel, noiselevel)
    return mat
Esempio n. 4
0
def add_noise_to_symmetric_matrix(mat, noiselevel=.01):
    # currently does not add noise to the diagonal
    assert 0 < noiselevel < 1
    assert is_square_matrix(mat)
    assert numpy.max(numpy.abs(mat - mat.transpose())) < 1e-12
    mat = mat.copy()
    for i in six.moves.xrange(mat.shape[0]):
        for j in six.moves.xrange(i + 1, mat.shape[1]):
            z = random.uniform(1 - noiselevel, 1 + noiselevel)
            mat[(i, j)] *= z
            mat[(j, i)] *= z
    return mat
Esempio n. 5
0
def bcs_stats(u, v):
    assert is_square_matrix(u)
    assert is_square_matrix(v)
    assert u.shape[0] == v.shape[0]

    Nsites = u.shape[0]

    fdagf = numpy.zeros((Nsites), dtype=float)
    fdownfup = numpy.zeros((Nsites), dtype=complex)
    Tvec = numpy.zeros((Nsites, 3), dtype=float)
    Ttot = numpy.zeros((Nsites), dtype=float)

    for ind_r in range(0, Nsites):
        fdagf[ind_r] = 2.0 * numpy.dot( v[ind_r, :], v[ind_r, :].conjugate() ).real
        fdownfup[ind_r] = -numpy.dot( u[ind_r, :], v[ind_r, :].conjugate() )

    for ind_r in range(0, Nsites):
        Tvec[ind_r, 0] = fdownfup[ind_r].real
        Tvec[ind_r, 1] = -fdownfup[ind_r].imag
        Tvec[ind_r, 2] = 0.5 * (fdagf[ind_r] - 1.0)
        Tvec[ind_r, :] = 2.0 * Tvec[ind_r, :]  # 2.0 to be consistent with Lesik.
        Ttot[ind_r] = numpy.sqrt( numpy.dot( Tvec[ind_r, :], Tvec[ind_r, :].conjugate() ) ).real

    return {'fdagf':fdagf, 'fdownfup':fdownfup, 'Tvec':Tvec, 'Ttot':Ttot}
Esempio n. 6
0
def add_onsite_terms(offsite, onsite):
    assert is_square_matrix(offsite)

    check_offsite_for_onsite(offsite)  # since we're singling out the on-site terms with this function

    Nsites = offsite.shape[0]

    # total_{ij} = offsite_{ij} + onsite_i * krondelta_{ij}
    if isinstance(onsite, numpy.ndarray):
        assert onsite.ndim == 1
        assert onsite.shape[0] == 1 or onsite.shape[0] == Nsites
        if onsite.shape[0] == 1:
            total = offsite + onsite * numpy.identity(Nsites)
        elif onsite.shape[0] == Nsites:
            total = offsite + numpy.diag(onsite)
    else:
        total = offsite + onsite * numpy.identity(Nsites)

    return total
Esempio n. 7
0
def free_fermion_soln(t):
    assert is_square_matrix(t)

    Nsites = t.shape[0]

    # t_{ij} = ttilde_{ij} = t_{ij} + mu_i * krondelta_{ij} from notes (FIXME: take t and mu as separate parameters?)
    H = -t

    assert numpy.max(numpy.abs(H - H.conjugate().transpose())) < 1e-12

    eigsys = numpy.linalg.eigh(H)

    idx = eigsys[0].argsort()
    evals = eigsys[0][idx]
    evecs = eigsys[1][:,idx]

    logger.debug('Eigenvalues = ...')
    logger.debug(evals)

    return {'evecs':evecs, 'evals':evals}
Esempio n. 8
0
def plot_pairing_matrix(phiMat, callshow=True):
    assert is_square_matrix(phiMat)

    from mpl_toolkits.mplot3d import Axes3D
    from matplotlib import cm
    from matplotlib.ticker import LinearLocator, FormatStrFormatter

    fig = plt.figure()
    ax = fig.gca(projection='3d')
    X = numpy.arange(0, phiMat.shape[0], 1)
    Y = numpy.arange(0, phiMat.shape[0], 1)
    X, Y = numpy.meshgrid(X, Y)
    surf = ax.plot_surface(X, Y, numpy.abs(phiMat), rstride=1, cstride=1, cmap=cm.coolwarm, linewidth=0, antialiased=False)

    #ax.zaxis.set_major_locator(LinearLocator(10))
    ax.zaxis.set_major_formatter(FormatStrFormatter('%.02f'))

    fig.colorbar(surf, shrink=0.5, aspect=5)

    if callshow:
        plt.show()
Esempio n. 9
0
def bcs_soln(t, delta):
    # both t and delta should include on-site terms, e.g., t_{ij} = ttilde_{ij} = t_{ij} + mu_i * krondelta_{ij} from notes
    assert is_square_matrix(t)
    assert is_square_matrix(delta)
    assert t.shape[0] == delta.shape[0]

    Nsites = t.shape[0]

    H = numpy.zeros((Nsites, Nsites, 2, 2), dtype=complex)
    for ind_r in range(0, Nsites):
        for ind_rp in range(0, Nsites):
            H[ind_r, ind_rp] = -numpy.array([[t[ind_r, ind_rp], delta[ind_r, ind_rp]],
                                             [delta[ind_r, ind_rp].conjugate(), -t[ind_r, ind_rp].conjugate()]])

    Hflat = numpy.zeros((2*Nsites, 2*Nsites), dtype=complex)
    for i in range(0, 2*Nsites):
        for j in range(0, 2*Nsites):
            Hflat[i,j] = H[i//2, j//2, numpy.mod(i,2), numpy.mod(j,2)]

    assert numpy.max(numpy.abs(Hflat - Hflat.conjugate().transpose())) < 1e-12

    eigsys = numpy.linalg.eigh(Hflat)

    idx = eigsys[0].argsort()
    evals = eigsys[0][idx]
    evecs = eigsys[1][:,idx]

    # Check that eigenvectors are orthonormal:
    Icheck = numpy.dot( evecs.conjugate().transpose(), evecs )
    assert numpy.max(numpy.abs(Icheck - numpy.identity(Icheck.shape[0], dtype=complex))) < 1e-12

    evalsNeg = evals[0:Nsites]
    evecsNeg = evecs[:, 0:Nsites]
    evalsPos = evals[Nsites:2*Nsites]
    evecsPos = evecs[:, Nsites:2*Nsites]

    logger.debug('Positive eigenvalues = ...')
    logger.debug(evalsPos)
#    logger.debug('Negative eigenvalues = ...')
#    logger.debug(evalsNeg[::-1])

    # Check that positive eigenvalues are positive and that eigenvalues have come in plus-minus pairs:
    # FIXME:  probably shouldn't be so strict, since this gets called when trying to tune the ansatz,
    # and we could potentially run into degenerate mean field solutions (i.e., those with zero modes) in that process;
    # if we don't assert evalsPos > 0, then we treat zero modes as positive and don't populate them in the the BCS solution,
    # which I think is OK; for now, we'll just warn instead of assert
#    assert numpy.min(evalsPos) > 1e-12
    if not numpy.min(evalsPos) > 1e-12:
        logger.warning('Some of evalsPos are not greater than 1e-12')
    assert numpy.max(numpy.abs(evalsNeg[::-1] + evalsPos)) < 1e-12

    u = evecsPos[0:evecsPos.shape[0]:2, :]
    v = evecsPos[1:evecsPos.shape[0]:2, :]

    # Check that (v, -u)^* from evecsPos are indeed negative eigenvectors:
    errr = []
    for n in range(0, Nsites):
        evecTest = numpy.zeros(2*Nsites, dtype=complex)
        for i in range(0, Nsites):
            evecTest[2*i] = v[i,n].conjugate()
            evecTest[2*i+1] = -u[i,n].conjugate()
        errr.append(numpy.max(numpy.abs( numpy.dot( Hflat, evecTest ) - (-evalsPos[n] * evecTest ))))
    assert numpy.max(errr) < 1e-12

    return {'u':u, 'v':v, 'evalsPos':evalsPos}