Hi Dr. Peixoto,

The attached is a complete example with the input simulated data and the python scripts. The main code is shown below as well, it's mainly one "load edges to graph" function and "minimize_nested_blockmodel_dl". Thank you!

import os
import numpy as np
import pandas as pd
import pickle
import warnings
from collections import defaultdict
import graph_tool.all as gt

def load_edges_to_graph(tidy_edges,verbose = True):
    # Grab lists of unique nodes for both types
    node_a_names = tidy_edges['node_a'].unique()
    n_node_a = len(node_a_names)

    node_b_names = tidy_edges['node_b'].unique()
    n_node_b = len(node_b_names)

    # create a graph-tool graph
    g = gt.Graph(directed=False)

    # Setup and pull out node property vectors for easy setting
    name = g.vp["name"] = g.new_vp("string")
    kind = g.vp["kind"] = g.new_vp("int")

    # Dictionaries for adding and grabbing nodes from either class
    node_a_add = defaultdict(lambda: g.add_vertex())
    node_b_add = defaultdict(lambda: g.add_vertex())

    num_edges, _ = tidy_edges.shape

    # Start by adding all unique node_a's to make sure nodes are not jumbled by type
    if(verbose): print(f'Adding all unique node As to model nodes')
    for node_a_name in node_a_names:
        node_a = node_a_add[node_a_name]
        name[node_a] = node_a_name
        kind[node_a] = 0

    # Next do node b's
    if(verbose): print(f'Adding all unique node Bs to model nodes')
    for node_b_name in node_b_names:
        node_b = node_b_add[node_b_name]
        name[node_b] = node_b_name
        kind[node_b] = 1

    # Now go edge by edge and add the model.
    five_percent = np.ceil(num_edges/20)
    for edge_num in range(num_edges):

        if((edge_num%five_percent == 0) and verbose):
            print(f'{np.round((edge_num/num_edges)*100, decimals=1)}% done | {edge_num}/{num_edges}')

        node_a_name, node_b_name = tidy_edges.iloc[edge_num,:]

        # Grab the nodes for each end of the edge.
        node_a = node_a_add[node_a_name]
        node_b = node_b_add[node_b_name]

        # Add the edge to the model
        edge = g.add_edge(node_a, node_b)

    return g

# Load network edges (aka phenome vectors)
tidy_edges = pd.read_csv("bisbm_sim_edge_complex.csv", dtype = 'str')
g = load_edges_to_graph(tidy_edges, verbose = True)
node_types = g.vp['kind']
niter = 1
beta = 1

# mcmc
state = gt.minimize_nested_blockmodel_dl(
        g,
        state_args = dict(deg_corr = True,clabel=node_types),
        multilevel_mcmc_args = dict(niter=niter,beta=beta))

Best,
Siwei

From: Tiago de Paula Peixoto <tiago@skewed.de>
Sent: Friday, July 22, 2022 7:18
To: graph-tool@skewed.de <graph-tool@skewed.de>
Subject: [graph-tool] Re: bipartite minimize_nested_blockmodel_dl() error: cannot move vertex across clabel barriers
 
Am 20.07.22 um 08:02 schrieb Siwei Zhang:
> Hi Dr. Peixoto,
>
> I am using graph-tool version 2.45 and I have two questions.
>
>  1. I am trying to reproduce the script in the document
>  2. g = gt.collection.data["celegansneural"]
>     state = gt.minimize_nested_blockmodel_dl(g,
>     state_args=dict(overlap=True))
>
>            and have the error:
> /usr/lib/python3/dist-packages/graph_tool/inference/blockmodel.py:390:
> UserWarning: unrecognized keyword arguments: ['overlap']
> warnings.warn("unrecognized keyword arguments: " +
>
>            It seems the argument of "overlap" is removed.

The proper way to use an overlapping model is to pass the option:

     state_args=dict(base_type=OverlapBlockState)

>          2. Regardless of the question1, I am trying to do a bipartite
> version stochastic block model and I define "clabel" to constraint
> labels on the vertices so that vertices with different label values will
> not be clustered in the same group. But I always have the error of
> "ValueError: cannot move vertex across clabel barriers". The below is
> the code:
> node_types = g.vp['kind']
> node_types.get_array()
> Output: PropertyArray([1, 1, 1, ..., 2, 2, 2], dtype=int32)
>
> state = gt.minimize_nested_blockmodel_dl(
> g,
> state_args=dict(clabel=node_types,pclabel=node_types,deg_corr=True),
> multilevel_mcmc_args = dict(niter=niter,beta=beta))
> Could you please help me with these questions? Thanks!
In order to understand what is happening you would need to send us a
minimal but complete working example that shows the problem.

Best,
Tiago


--
Tiago de Paula Peixoto <tiago@skewed.de>