def temporal_louvain(tnet, resolution=1, intersliceweight=1, n_iter=100, negativeedge='ignore', randomseed=None, consensus_threshold=0.5, temporal_consensus=True, njobs=1):
    r"""
    Louvain clustering for a temporal network.

    Parameters
    -----------
    tnet : array, dict, TemporalNetwork
        Input network
    resolution : int
        resolution of Louvain clustering ($\gamma$)
    intersliceweight : int
        interslice weight of multilayer clustering ($\omega$). Must be positive.
    n_iter : int
        Number of iterations to run louvain for
    randomseed : int
        Set for reproduceability
    negativeedge : str
        If there are negative edges, what should be done with them.
        Options: 'ignore' (i.e. set to 0). More options to be added.
    consensus : float (0.5 default)
        When creating consensus matrix to average over number of iterations, keep values when the consensus is this amount.

    Returns
    -------
    communities : array (node,time)
        node,time array of community assignment

    Notes
    -------

    References
    ----------
    """

    tnet = process_input(tnet, ['C', 'G', 'TN'], 'TN')
    # Divide resolution by the number of timepoints
    resolution = resolution / tnet.T
    supranet = create_supraadjacency_matrix(
        tnet, intersliceweight=intersliceweight)
    if negativeedge == 'ignore':
        supranet = supranet[supranet['weight'] > 0]
    nxsupra = tnet_to_nx(supranet)
    np.random.seed(randomseed)
    while True:
        comtmp = []
        with ProcessPoolExecutor(max_workers=njobs) as executor:
            job = {executor.submit(_run_louvain, nxsupra, resolution, tnet.N, tnet.T) for n in range(n_iter)}
            for j in as_completed(job):
                comtmp.append(j.result())
        comtmp = np.stack(comtmp)
        comtmp = comtmp.transpose()
        comtmp = np.reshape(comtmp, [tnet.N, tnet.T, n_iter], order='F')
        if n_iter == 1: 
            break        
        nxsupra_old = nxsupra
        nxsupra = make_consensus_matrix(comtmp, consensus_threshold)
        # If there was no consensus, there are no communities possible, return
        if nxsupra is None:
            break
        if (nx.to_numpy_array(nxsupra, nodelist=np.arange(tnet.N*tnet.T)) == nx.to_numpy_array(nxsupra_old, nodelist=np.arange(tnet.N*tnet.T))).all():
            break
    communities = comtmp[:, :, 0]
    if temporal_consensus == True:
        communities = make_temporal_consensus(communities)
    return communities
def temporal_louvain ( tnet , resolution = 1 , intersliceweight = 1 , n_iter = 100 , negativeedge = 'ignore' , randomseed = None , consensus_threshold = 0.5 , temporal_consensus = True , njobs = 1 ) : tnet = process_input ( tnet , [ 'C' , 'G' , 'TN' ] , 'TN' ) resolution = resolution / tnet . T supranet = create_supraadjacency_matrix ( tnet , intersliceweight = intersliceweight ) if negativeedge == 'ignore' : supranet = supranet [ supranet [ 'weight' ] > 0 ] nxsupra = tnet_to_nx ( supranet ) np . random . seed ( randomseed ) while True : comtmp = [ ] with ProcessPoolExecutor ( max_workers = njobs ) as executor : job = { executor . submit ( _run_louvain , nxsupra , resolution , tnet . N , tnet . T ) for n in range ( n_iter ) } for j in as_completed ( job ) : comtmp . append ( j . result ( ) ) comtmp = np . stack ( comtmp ) comtmp = comtmp . transpose ( ) comtmp = np . reshape ( comtmp , [ tnet . N , tnet . T , n_iter ] , order = 'F' ) if n_iter == 1 : break nxsupra_old = nxsupra nxsupra = make_consensus_matrix ( comtmp , consensus_threshold ) if nxsupra is None : break if ( nx . to_numpy_array ( nxsupra , nodelist = np . arange ( tnet . N * tnet . T ) ) == nx . to_numpy_array ( nxsupra_old , nodelist = np . arange ( tnet . N * tnet . T ) ) ) . all ( ) : break communities = comtmp [ : , : , 0 ] if temporal_consensus == True : communities = make_temporal_consensus ( communities ) return communities
r"""
    Louvain clustering for a temporal network.

    Parameters
    -----------
    tnet : array, dict, TemporalNetwork
        Input network
    resolution : int
        resolution of Louvain clustering ($\gamma$)
    intersliceweight : int
        interslice weight of multilayer clustering ($\omega$). Must be positive.
    n_iter : int
        Number of iterations to run louvain for
    randomseed : int
        Set for reproduceability
    negativeedge : str
        If there are negative edges, what should be done with them.
        Options: 'ignore' (i.e. set to 0). More options to be added.
    consensus : float (0.5 default)
        When creating consensus matrix to average over number of iterations, keep values when the consensus is this amount.

    Returns
    -------
    communities : array (node,time)
        node,time array of community assignment

    Notes
    -------

    References
    ----------