Esempio n. 1
0
def plot_convergence(filename):
    with h5py.File('afqmc.h5', 'r') as fh5:
        hcore = fh5['Hamiltonian/hcore'][:].view(numpy.complex128)[:, :, 0]
    energies = []
    errs = []
    tau_bps = []
    sym_md = get_metadata(filename)
    bp_md = get_metadata(filename, 'Observables/BackPropagated/')
    taus = bp_md['BackPropSteps']
    for i, t in enumerate(taus):
        # skip the first block for equilibration
        skip = 1
        nelec = sym_md['NAEA'] + sym_md['NAEB']
        # We can extract the averaged 1RDM.
        rdm_av, rdm_errs = average_one_rdm(filename, eqlb=skip, ix=i)
        nelec_rdm = (rdm_av[0].trace()).real
        assert (nelec_rdm - nelec < 1e-12)
        # Often it is simpler to compute error bars if we first contract the 1RDM.
        # For example, we can compute the one-body energy from the averaged RDM as.
        e1b = numpy.einsum('ij,sij->', hcore, rdm_av).real
        # Or we can instead compute the average of the one-body energies.
        e1b_series, err = compute_one_body(filename, hcore, skip, i)
        energies.append(e1b_series)
        errs.append(err)
        # get back propagation time
        tau_bps.append(t * sym_md['Timestep'])
        assert (e1b - e1b_series < 1e-12)

    # Finally plot the one-body energy and check the estimator is converged with
    # respect to back propagation time.
    if have_mpl:
        plt.errorbar(tau_bps, energies, yerr=errs, fmt='o')
        plt.xlabel(r'$\tau_{BP}$')
        plt.ylabel(r'$E_{1B}$ (Ha)')
        plt.savefig('h1e_conv.pdf', bbox_inches='tight')
Esempio n. 2
0
def average_on_top_pdm(filename, estimator='back_propagated', eqlb=1, skip=1, ix=None):
    """Average on-top pair density matrix.

    Returns n2(r,r) for a given real space grid.

    Parameters
    ----------
    filename : string
        QMCPACK output containing density matrix (*.h5 file).
    estimator : string
        Estimator type to analyse. Options: back_propagated or mixed.
        Default: back_propagated.
    eqlb : int
        Number of blocks for equilibration. Default 1.
    skip : int
        Number of blocks to skip in between measurements equilibration.
        Default 1 (use all data).
    ix : int
        Back propagation path length to average. Optional.
        Default: None (chooses longest path).

    Returns
    -------
    opdm : :class:`numpy.ndarray`
        Averaged diagonal on-top pair density matrix.
    opdm_err : :class:`numpy.ndarray`
        Error bars for diagonal on-top pair density matrix elements.
    """
    md = get_metadata(filename)
    mean, err = average_observable(filename, 'on_top_pdm', eqlb=eqlb, skip=skip,
                                   estimator=estimator, ix=ix)
    # TODO: Update appropriately.
    return mean, err
Esempio n. 3
0
def average_one_rdm(filename,
                    estimator='back_propagated',
                    eqlb=1,
                    skip=1,
                    ix=None):
    """Average AFQMC 1RDM.

    Returns P_{sij} = <c_{is}^+ c_{js}^> as a (nspin, M, M) dimensional array.

    Parameters
    ----------
    filename : string
        QMCPACK output containing density matrix (*.h5 file).
    estimator : string
        Estimator type to analyse. Options: back_propagated or mixed.
        Default: back_propagated.
    eqlb : int
        Number of blocks for equilibration. Default 1.
    skip : int
        Number of blocks to skip in between measurements equilibration.
        Default 1 (use all data).
    ix : int
        Back propagation path length to average. Optional.
        Default: None (chooses longest path).

    Returns
    -------
    one_rdm : :class:`numpy.ndarray`
        Averaged 1RDM.
    one_rdm_err : :class:`numpy.ndarray`
        Error bars for 1RDM elements.
    """
    md = get_metadata(filename)
    mean, err = average_observable(filename,
                                   'one_rdm',
                                   eqlb=eqlb,
                                   skip=skip,
                                   estimator=estimator,
                                   ix=ix)
    nbasis = md['NMO']
    wt = md['WalkerType']
    try:
        walker = WALKER_TYPE[wt]
    except IndexError:
        print('Unknown walker type {}'.format(wt))

    if walker == 'closed':
        return 2 * mean.reshape(1, nbasis, nbasis), err.reshape(
            1, nbasis, nbasis)
    elif walker == 'collinear':
        return mean.reshape((2, nbasis, nbasis)), err.reshape(
            (2, nbasis, nbasis))
    elif walker == 'non_collinear':
        return mean.reshape((1, 2 * nbasis, 2 * nbasis)), err.reshape(
            (1, 2 * nbasis, 2 * nbasis))
    else:
        print('Unknown walker type.')
        return None
Esempio n. 4
0
def average_atom_correlations(filename, estimator='back_propagated', eqlb=1, skip=1, ix=None):
    """Average atom centered correlations.

    Returns <C(I)>, <S(I)>, <C(I)C(J)> and <S(I)S(J)> for a given set of atomic sites.
    C = (nup + ndown), S = (nup - ndown)

    Parameters
    ----------
    filename : string
        QMCPACK output containing density matrix (*.h5 file).
    estimator : string
        Estimator type to analyse. Options: back_propagated or mixed.
        Default: back_propagated.
    eqlb : int
        Number of blocks for equilibration. Default 1.
    skip : int
        Number of blocks to skip in between measurements equilibration.
        Default 1 (use all data).
    ix : int
        Back propagation path length to average. Optional.
        Default: None (chooses longest path).

    Returns
    -------
    c_mean : :class:`numpy.ndarray`
        Averaged charge. 
    c_err : :class:`numpy.ndarray`
        Error bars for charge. 
    s_mean : :class:`numpy.ndarray`
        Averaged spin. 
    s_err : :class:`numpy.ndarray`
        Error bars for spin.  
    cc_mean : :class:`numpy.ndarray`
        Averaged charge-charge correlation function. 
    cc_err : :class:`numpy.ndarray`
        Error bars for charge-charge correlation function. 
    ss_mean : :class:`numpy.ndarray`
        Averaged spin-spin correlation function. 
    ss_err : :class:`numpy.ndarray`
        Error bars for spin-spin correlation function.  
    """
    md = get_metadata(filename)
    c_mean, c_err = average_observable(filename, 'c_atom_correlation', eqlb=eqlb, skip=skip,
                                   estimator=estimator, ix=ix)
    s_mean, s_err = average_observable(filename, 's_atom_correlation', eqlb=eqlb, skip=skip,
                                   estimator=estimator, ix=ix)
    m_mean, m_err = average_observable(filename, 'm_atom_correlation', eqlb=eqlb, skip=skip,
                                   estimator=estimator, ix=ix)
    cc_mean, cc_err = average_observable(filename, 'cc_atom_correlation', eqlb=eqlb, skip=skip,
                                   estimator=estimator, ix=ix)
    ss_mean, ss_err = average_observable(filename, 'ss_atom_correlation', eqlb=eqlb, skip=skip,
                                   estimator=estimator, ix=ix)
    # TODO: get npts from metadata local to cc_correlation
    npts = int(sqrt(cc_mean.shape[0]))
    return c_mean, c_err, s_mean, s_err, m_mean, m_err, cc_mean.reshape((npts,-1)), cc_err.reshape((npts,-1)), \
                ss_mean.reshape((npts,-1)), ss_err.reshape((npts,-1))
Esempio n. 5
0
def average_two_rdm(filename, estimator='back_propagated', eqlb=1, skip=1, ix=None):
    """Average AFQMC 2RDM.

    Returns a list of 2RDMS, where 
      2RDM[s1s2,i,k,j,l] = <c_{i}^+ c_{j}^+ c_{l} c_{k}>.
      For closed shell systems, returns [(a,a,a,a),(a,a,b,b)] 
      For collinear systems, returns [(a,a,a,a),(a,a,b,b),(b,b,b,b)] 

    Parameters
    ----------
    filename : string
        QMCPACK output containing density matrix (*.h5 file).
    estimator : string
        Estimator type to analyse. Options: back_propagated or mixed.
        Default: back_propagated.
    eqlb : int
        Number of blocks for equilibration. Default 1.
    skip : int
        Number of blocks to skip in between measurements equilibration.
        Default 1 (use all data).
    ix : int
        Back propagation path length to average. Optional.
        Default: None (chooses longest path).

    Returns
    -------
    two_rdm : :class:`numpy.ndarray`
        List of averaged 2RDM.
    two_rdm_err : :class:`numpy.ndarray`
        List of error bars for 2RDM elements.
    """
    md = get_metadata(filename)
    mean, err = average_observable(filename, 'two_rdm', eqlb=eqlb, skip=skip,
                                   estimator=estimator, ix=ix)
    nbasis = md['NMO']
    wt = md['WalkerType']
    try:
        walker = WALKER_TYPE[wt]
    except IndexError:
        print('Unknown walker type {}'.format(wt))

    if walker == 'closed':
        return mean.reshape(2,nbasis,nbasis,nbasis,nbasis), err.reshape(2,nbasis,nbasis,nbasis,nbasis)
    elif walker == 'collinear':
        return mean.reshape(3,nbasis,nbasis,nbasis,nbasis), err.reshape(3,nbasis,nbasis,nbasis,nbasis)
    elif walker == 'non_collinear':
        return mean.reshape(2*nbasis,2*nbasis,2*nbasis,2*nbasis), err.reshape(2*nbasis,2*nbasis,2*nbasis, 2*nbasis)
    else:
        print('Unknown walker type.')
        return None
Esempio n. 6
0
def average_gen_fock(filename, fock_type='plus', estimator='back_propagated',
                     eqlb=1, skip=1, ix=None):
    """Average AFQMC genralised Fock matrix.

    Parameters
    ----------
    filename : string
        QMCPACK output containing density matrix (*.h5 file).
    fock_type : string
        Which generalised Fock matrix to extract. Optional (plus/minus).
        Default: plus.
    estimator : string
        Estimator type to analyse. Options: back_propagated or mixed.
        Default: back_propagated.
    eqlb : int
        Number of blocks for equilibration. Default 1.
    skip : int
        Number of blocks to skip in between measurements equilibration.
        Default 1 (use all data).
    ix : int
        Back propagation path length to average. Optional.
        Default: None (chooses longest path).

    Returns
    -------
    gfock : :class:`numpy.ndarray`
        Averaged 1RDM.
    gfock_err : :class:`numpy.ndarray`
        Error bars for 1RDM elements.
    """
    md = get_metadata(filename)
    name = 'gen_fock_' + fock_type
    mean, err = average_observable(filename, name, eqlb=eqlb, skip=skip,
                                   estimator=estimator, ix=ix)
    nbasis = md['NMO']
    wt = md['WalkerType']
    try:
        walker = WALKER_TYPE[wt]
    except IndexError:
        print('Unknown walker type {}'.format(wt))

    if walker == 'closed':
        return mean.reshape(1,nbasis,nbasis), err.reshape(1,nbasis, nbasis)
    elif walker == 'collinear':
        return mean.reshape((2,nbasis,nbasis)), err.reshape((2, nbasis, nbasis))
    elif walker == 'non_collinear':
        return mean.reshape((1,2*nbasis,2*nbasis)), err.reshape((1,2*nbasis, 2*nbasis))
    else:
        print('Unknown walker type.')
        return None
Esempio n. 7
0
def average_observable(filename,
                       name,
                       eqlb=1,
                       estimator='back_propagated',
                       ix=None,
                       skip=1):
    """Compute mean and error bar for AFQMC HDF5 observable.

    Parameters
    ----------
    filename : string
        QMCPACK output containing density matrix (*.h5 file).
    name : string
        Name of observable (see estimates.py for list).
    eqlb : int
        Number of blocks for equilibration. Default 1.
    estimator : string
        Estimator type to analyse. Options: back_propagated or mixed.
        Default: back_propagated.
    skip : int
        Number of blocks to skip in between measurements equilibration.
        Default 1 (use all data).
    ix : int
        Back propagation path length to average. Optional.
        Default: None (chooses longest path).

    Returns
    -------
    mean : :class:`numpy.ndarray`
        Averaged quantity.
    err : :class:`numpy.ndarray`
        Error bars for quantity.
    """
    md = get_metadata(filename)
    free_proj = md['FreeProjection']
    if free_proj:
        mean = None
        err = None
        print("# Error analysis for free projection not implemented.")
    else:
        data = extract_observable(filename,
                                  name=name,
                                  estimator=estimator,
                                  ix=ix)
        mean = numpy.mean(data[eqlb:len(data):skip], axis=0)
        err = scipy.stats.sem(data[eqlb:len(data):skip].real, axis=0)
    return mean, err
Esempio n. 8
0
def average_diag_two_rdm(filename, estimator='back_propagated', eqlb=1, skip=1, ix=None):
    """Average diagonal part of 2RDM.

    Returns <c_{is}^+ c_{jt}^+ c_{jt} c_{is}> as a (2M,2M) dimensional array.

    Parameters
    ----------
    filename : string
        QMCPACK output containing density matrix (*.h5 file).
    estimator : string
        Estimator type to analyse. Options: back_propagated or mixed.
        Default: back_propagated.
    eqlb : int
        Number of blocks for equilibration. Default 1.
    skip : int
        Number of blocks to skip in between measurements equilibration.
        Default 1 (use all data).
    ix : int
        Back propagation path length to average. Optional.
        Default: None (chooses longest path).

    Returns
    -------
    two_rdm : :class:`numpy.ndarray`
        Averaged diagonal 2RDM.
    two_rdm_err : :class:`numpy.ndarray`
        Error bars for diagonal 2RDM elements.
    """
    md = get_metadata(filename)
    mean, err = average_observable(filename, 'diag_two_rdm', eqlb=eqlb, skip=skip,
                                   estimator=estimator, ix=ix)
    nbasis = md['NMO']
    wt = md['WalkerType']
    try:
        walker = WALKER_TYPE[wt]
    except IndexError:
        print('Unknown walker type {}'.format(wt))

    if walker == 'closed':
        dm_size = nbasis*(2*nbasis-1) - nbasis*(nbasis-1) // 2
        assert mean.shape == dm_size
        two_rdm = numpy.zeros((2*nbasis, 2*nbasis), dtype=mean.dtype)
        two_rdm_err = numpy.zeros((2*nbasis, 2*nbasis), dtype=mean.dtype)
        ij = 0
        for i in range(nbasis):
            for j in range(i+1, 2*nbasis):
                two_rdm[i,j] = mean[ij]
                two_rdm_err[i,j] = err[ij]
                two_rdm[j,i] = mean[ij].conj()
                two_rdm_err[j,i] = err[ij].conj()
                ij += 1
        two_rdm[nbasis:,nbasis:] = two_rdm[:nbasis,:nbasis].copy()
    elif walker == 'collinear':
        dm_size = nbasis*(2*nbasis-1)
        assert mean.shape == dm_size
        two_rdm = numpy.zeros((2*nbasis, 2*nbasis), dtype=mean.dtype)
        two_rdm_err = numpy.zeros((2*nbasis, 2*nbasis), dtype=mean.dtype)
        ij = 0
        for i in range(2*nbasis):
            for j in range(i+1, 2*nbasis):
                two_rdm[i,j] = mean[ij]
                two_rdm_err[i,j] = err[ij]
                two_rdm[j,i] = mean[ij].conj()
                two_rdm_err[j,i] = err[ij].conj()
                ij += 1
    elif walker == 'non_collinear':
        print("Non-collinear wavefunction not supported.")
        return None
    else:
        print('Unknown walker type.')
        return None
    # Diagonal is zero
    return two_rdm, two_rdm_err