def gen_XdX(atom_list,operator_table,operator_table_dagger,Hcomm,N_atoms_uc):
    """Operate commutation relations to put all the 2nd order term as ckd**ck, cmk**cmkd, cmk**ck and ckd**cmkd form"""
    print "gen_XdX"
    
    operator_table = N.array(operator_table)
    operator_table_dagger = N.array(operator_table_dagger)

    bins = (operator_table_dagger[:,None].T*operator_table[:,None]).flatten().tolist()
    retbins = N.zeros(len(bins),dtype=object)
    expr_list = sympy.make_list(Hcomm, sympy.Add)
    
    for subexpr in expr_list:
        for i in range(len(bins)):
            curr_coeff = subexpr.as_coefficient(bins[i])
            if curr_coeff:
                retbins[i] += curr_coeff
    XdX = retbins.reshape((2*N_atoms_uc,2*N_atoms_uc))
    XdX = sympy.matrices.Matrix(XdX)
    
    def g_func(i,j,num):
        if i!=j: return 0
        elif i<num: return 1
        else: return -1   
    
    g = sympy.matrices.Matrix(2*N_atoms_uc,2*N_atoms_uc,lambda i,j:g_func(i,j,N_atoms_uc))
    
    return XdX,g
def coeff_bins(expr,bins):
    # get rid of None expressions
    if not expr:
        return 0
    # chop up expr at '+'
    expr_list = sympy.make_list(expr, sympy.Add)
    retbins = N.zeros(len(bins),dtype=object)
    #scan through expr
    for subexpr in expr_list:
        #see if it contains a bin element
        for i in range(len(bins)):
            curr_coeff = subexpr.as_coefficient(bins[i])
            if curr_coeff:
                retbins[i] += curr_coeff
    return retbins