コード例 #1
0
ファイル: block_gf.py プロジェクト: vegaandagev/triqs
    def __init__(self, **kwargs):
        """
   * There are several possible constructors, which accept only keyword arguments.

            * BlockGf(name_list = list of names, block_list = list of blocks, make_copies = False, name = '')

                   * ``name_list``: list of the names of the blocks, e.g. ["up","down"].
                   * ``block_list``: list of blocks of Green's functions.
                   * ``make_copies``: If True, it makes a copy of the blocks and build the Green's function from these copies.

            * BlockGf(mesh = mesh, gf_struct = block structure, target_rank = rank of target space, name = '')

                   * ``mesh``: The mesh used to construct each block
                   * ``target_rank``: The rank of the target space of each block (default: 2)
                   * ``gf_struct``: List of pairs [ [str, [str,...]], ... ] providing the block name and indices, e.g. [ ['up', ['0']], ['dn', ['0']] ]

            * BlockGf(name_block_generator, make_copies = False, name = '')

                   * ``name_block_generator``: a generator of (name, block)
                   * ``make_copies``: If True, it makes a copy of the blocks and build the Green's function from these copies.

          """
        # first extract the optional name argument
        self.name = kwargs.pop('name','G')
        self.note = kwargs.pop('note','')
        self._rename_gf = kwargs.pop('rename_gf',True)

        # Default arguments
        if set(kwargs.keys()) == set(['mesh','gf_struct']):
            kwargs['target_rank'] = 2
        if 'block_list' in kwargs.keys() and 'make_copies' not in kwargs.keys():
            kwargs['make_copies'] = False
        if set(kwargs.keys()) == set(['block_list','make_copies']):
            kwargs['name_list'] = [str(i) for i in range(len(kwargs['block_list']))]

        if set(kwargs.keys()) == set(['name_list','block_list','make_copies']):
            BlockNameList, GFlist = kwargs['name_list'],kwargs['block_list']
            assert all([isinstance(name,str) for name in BlockNameList]), "Error in BlockGf Construction: Block-Names must be Strings"
        elif set(kwargs.keys()) == set(['mesh','gf_struct','target_rank']):
            BlockNameList = []
            GFlist = []
            for bl, idx_lst in kwargs['gf_struct']:
                BlockNameList.append(bl)
                if len(idx_lst) > 0 and kwargs['target_rank'] > 0:
                    GFlist.append(Gf(mesh=kwargs['mesh'], target_shape=[len(idx_lst)]*kwargs['target_rank'], name='G_%s'%bl, indices=[idx_lst]*kwargs['target_rank']))
                else:
                    GFlist.append(Gf(mesh=kwargs['mesh'], target_shape=[], name='G_%s'%bl))
        elif set(kwargs.keys()) == set(['name_block_generator','make_copies']):
            BlockNameList,GFlist = zip(* kwargs['name_block_generator'])
        else:
            raise RuntimeError, "BlockGf construction: error in parameters, see the documentation"

        if kwargs.get('make_copies', False): GFlist = [g.copy() for g in GFlist]

        # First a few checks
        assert GFlist !=[], "Empty list of blocks !"
        for ind in BlockNameList: assert str(ind)[0:2] !='__', "indices should not start with __"
        assert len(set(BlockNameList)) == len(BlockNameList),"Block indices of the Green Function are not unique"
        assert len(BlockNameList) == len(GFlist), "Number of indices and of Green Function Blocks differ"
        assert 'block_names' not in BlockNameList, "'block_names' is a reserved keyword. It is not authorized as a block name ! "

        # All blocks are compatible for binary operation
        # --> correction: All blocks have the same type
        #if not reduce (operator.and_,[ GFlist[0]._is_compatible_for_ops(x) for x in GFlist[1:] ] , True):
        #    raise RuntimeError, "The blocks are not compatible for binary operations: not the same type, same temperature, etc..."
        if len(set([ type(g) for g in GFlist])) != 1:
            raise RuntimeError, "BlockGf: All block must have the same type %s"%GFlist

        # init
        self.__indices,self.__GFlist = BlockNameList,GFlist
        try:
            self.__me_as_dict = dict(self)
        except TypeError:
            raise TypeError, "indices are not of the correct type"
        self.__BlockIndexNumberTable = dict( (i,n) for n,i in enumerate(self.__indices) ) # a dict: index -> number of its order

        # Add the name to the G
        self.note = ''
        if self._rename_gf:
            for i,g in self: g.name = "%s_%s"%(str(self.name),i) if self.name else '%s'%(i,)
        del self._rename_gf
コード例 #2
0
def fit_legendre(g_t, order=10):
    """ General fit of a noisy imaginary time Green's function
    to a low order Legendre expansion in imaginary time.

    Only Hermiticity is imposed on the fit, so discontinuities has
    to be fixed separately (see the method enforce_discontinuity)

    Author: Hugo U.R. Strand 

    Parameters
    ----------

    g_t : TRIQS imaginary time Green's function (matrix valued)
          Imaginary time Green's function to fit (possibly noisy binned data)

    order : int
            Maximal order of the fitted Legendre expansion

    Returns
    -------

    g_l : TRIQS Legendre polynomial Green's function (matrix valued)
          Fitted Legendre Green's function with order `order`
    """

    import numpy.polynomial.legendre as leg

    if isinstance(g_t, BlockGf):
        return map_block(lambda g_bl: fit_legendre(g_bl, order), g_t)

    assert isinstance(g_t, Gf) and isinstance(g_t.mesh, MeshImTime), "fit_legendre expects imaginary-time Green function objects"
    assert len(g_t.target_shape) == 2, "fit_legendre currently only implemented for matrix_valued Green functions"

    # -- flatten the data to 2D N_tau x (N_orb * N_orb)

    shape = g_t.data.shape
    fshape = [shape[0], np.prod(shape[1:])]

    # -- extend data accounting for hermiticity

    mesh = g_t.mesh
    tau = np.array([ t.value for t in mesh ])
    # Rescale to the interval (-1,1)
    x = 2. * tau / mesh.beta - 1.

    data = g_t.data.reshape(fshape)
    data_herm = np.transpose(g_t.data, axes=(0, 2, 1)).conjugate().reshape(fshape)

    # -- Separated real valued linear system, with twice the number of RHS terms

    data_re = 0.5 * (data + data_herm).real
    data_im = 0.5 * (data + data_herm).imag
    data_ext = np.hstack((data_re, data_im))

    c_l_ext = leg.legfit(x, data_ext, order - 1)
    c_l_re, c_l_im = np.split(c_l_ext, 2, axis=-1)
    c_l = c_l_re + 1.j * c_l_im

    # -- make Legendre Green's function of the fitted coeffs

    lmesh = MeshLegendre(mesh.beta, mesh.statistic, order)

    # Nb! We have to scale the actual Legendre coeffs to the Triqs "scaled" Legendre coeffs
    # see Boehnke et al. PRB (2011)
    l = np.arange(len(lmesh))
    scale = np.sqrt(2.*l + 1) / mesh.beta
    scale = scale.reshape([len(lmesh)] + [1]*len(g_t.target_shape))
    
    g_l = Gf(mesh=lmesh, target_shape=g_t.target_shape)
    g_l.data[:] = c_l.reshape(g_l.data.shape) / scale

    return g_l