code: def blocks(prng, block, n_blocks=2, chain_blocks=True):
      
      n_block_features, _ = block.shape
      n_features = n_block_features * n_blocks
      adjacency = np.zeros((n_features, n_features))
  
      dep_groups = np.eye(n_blocks)
      if chain_blocks:
          chain_alpha = np.round(0.01 + 0.5 / n_blocks, 2)
          chain_groups = lattice(prng, n_blocks, chain_alpha, random_sign=False)
          chain_groups *= -0.1
          dep_groups += chain_groups
  
      adjacency = np.kron(dep_groups, block)
      adjacency[np.where(np.eye(n_features))] = 0
      return adjacency
docs: Replicates `block` matrix n_blocks times diagonally to create a
      square matrix of size n_features = block.size[0] * n_blocks and with zeros
      along the diagonal.
  
      The graph can be made fully connected using chaining assumption when
      chain_blocks=True (default).
  
      This utility can be used to generate cluster networks or banded lattice n
      networks, among others.
  
      Parameters
      -----------
      block : 2D array (n_block_features, n_block_features)
          Prototype block adjacency matrix.
  
      n_blocks : int (default=2)
          Number of blocks.  Returned matrix will be square with
          shape n_block_features * n_blocks.
  
      chain_blocks : bool (default=True)
          Apply random lattice structure to chain blocks together.