class_docstr: A data generator for use with full-batch models on relational graphs e.g. RGCN.
  
  The supplied graph G should be a StellarGraph or StellarDiGraph object with node features.
  Use the :meth:`flow` method supplying the nodes and (optionally) targets
  to get an object that can be used as a Keras data generator.
  
  This generator will supply the features array and the adjacency matrix to a
  full-batch Keras graph ML model.  There is a choice to supply either a list of sparse
  adjacency matrices (the default) or a list of dense adjacency matrices, with the `sparse`
  argument.
  
  For these algorithms the adjacency matrices require preprocessing and the default option is to
  normalize each row of the adjacency matrix so that it sums to 1.
  For customization a transformation (callable) can be passed that
  operates on the node features and adjacency matrix.
  
  Example::
  
      G_generator = RelationalFullBatchNodeGenerator(G)
      train_data_gen = G_generator.flow(node_ids, node_targets)
  
      # Fetch the data from train_data_gen, and feed into a Keras model:
      # Alternatively, use the generator itself with model.fit:
      model.fit(train_gen, epochs=num_epochs, ...)
  
  .. seealso::
  
     Model using this generator: :class:`.RGCN`.
  
     Examples using this generator:
  
     - `node classification <https://stellargraph.readthedocs.io/en/stable/demos/node-classification/rgcn-node-classification.html>`__
     - `unsupervised representation learning with Deep Graph Infomax <https://stellargraph.readthedocs.io/en/stable/demos/embeddings/deep-graph-infomax-embeddings.html>`__
  
     Related generators:
  
     - :class:`.FullBatchNodeGenerator` for graphs with one edge type
     - :class:`.CorruptedGenerator` for unsupervised training with :class:`.DeepGraphInfomax`
  
  Args:
      G (StellarGraph): a machine-learning StellarGraph-type graph
      name (str): an optional name of the generator
      transform (callable): an optional function to apply on features and adjacency matrix
          the function takes ``(features, Aadj)`` as arguments.
      sparse (bool): If True (default) a list of sparse adjacency matrices is used,
          if False a list of dense adjacency matrices is used.
      weighted (bool, optional): if True, use the edge weights from ``G``; if False, treat the
          graph as unweighted.
class_docstr_tok: ["A","data","generator","for","use","with","full-batch","models","on","relational","graphs","e.g",".","RGCN",".","The","supplied","graph","G","should","be","a","StellarGraph","or","StellarDiGraph","object","with","node","features",".","Use","the",":","meth",":","`","flow","`","method","supplying","the","nodes","and","(","optionally",")","targets","to","get","an","object","that","can","be","used","as","a","Keras","data","generator",".","This","generator","will","supply","the","features","array","and","the","adjacency","matrix","to","a","full-batch","Keras","graph","ML","model",".","There","is","a","choice","to","supply","either","a","list","of","sparse","adjacency","matrices","(","the","default",")","or","a","list","of","dense","adjacency","matrices",",","with","the","`","sparse","`","argument",".","For","these","algorithms","the","adjacency","matrices","require","preprocessing","and","the","default","option","is","to","normalize","each","row","of","the","adjacency","matrix","so","that","it","sums","to","1",".","For","customization","a","transformation","(","callable",")","can","be","passed","that","operates","on","the","node","features","and","adjacency","matrix",".","Example",":",":","G_generator","=","RelationalFullBatchNodeGenerator","(","G",")","train_data_gen","=","G_generator.flow","(","node_ids",",","node_targets",")","#","Fetch","the","data","from","train_data_gen",",","and","feed","into","a","Keras","model",":","#","Alternatively",",","use","the","generator","itself","with","model.fit",":","model.fit","(","train_gen",",","epochs=num_epochs",",","...",")","..","seealso",":",":","Model","using","this","generator",":",":","class",":","`",".RGCN","`",".","Examples","using","this","generator",":","-","`","node","classification","<","https",":","\/\/stellargraph.readthedocs.io\/en\/stable\/demos\/node-classification\/rgcn-node-classification.html",">","`","__","-","`","unsupervised","representation","learning","with","Deep","Graph","Infomax","<","https",":","\/\/stellargraph.readthedocs.io\/en\/stable\/demos\/embeddings\/deep-graph-infomax-embeddings.html",">","`","__","Related","generators",":","-",":","class",":","`",".FullBatchNodeGenerator","`","for","graphs","with","one","edge","type","-",":","class",":","`",".CorruptedGenerator","`","for","unsupervised","training","with",":","class",":","`",".DeepGraphInfomax","`","Args",":","G","(","StellarGraph",")",":","a","machine-learning","StellarGraph-type","graph","name","(","str",")",":","an","optional","name","of","the","generator","transform","(","callable",")",":","an","optional","function","to","apply","on","features","and","adjacency","matrix","the","function","takes","``","(","features",",","Aadj",")","``","as","arguments",".","sparse","(","bool",")",":","If","True","(","default",")","a","list","of","sparse","adjacency","matrices","is","used",",","if","False","a","list","of","dense","adjacency","matrices","is","used",".","weighted","(","bool",",","optional",")",":","if","True",",","use","the","edge","weights","from","``","G","``",";","if","False",",","treat","the","graph","as","unweighted","."]
code: def __init__(
      self, G, name=None, sparse=True, transform=None, weighted=False
  ):
      if not isinstance(G, StellarGraph):
          raise TypeError("Graph must be a StellarGraph object.")
  
      self.graph = G
      self.name = name
      self.use_sparse = sparse
      self.multiplicity = 1
  
      # Check if the graph has features
      G.check_graph_for_ml()
  
      # extract node, feature, and edge type info from G
      node_types = list(G.node_types)
      if len(node_types) != 1:
          raise ValueError(
              f"G: expected one node type, found {comma_sep(sorted(node_types))}",
          )
  
      self.features = G.node_features(node_type=node_types[0])
  
      # create a list of adjacency matrices - one adj matrix for each edge type
      # an adjacency matrix is created for each edge type from all edges of that type
      self.As = []
  
      for edge_type in G.edge_types:
          # note that A is the transpose of the standard adjacency matrix
          # this is to aggregate features from incoming nodes
          A = G.to_adjacency_matrix(
              edge_type=edge_type, weighted=weighted
          ).transpose()
  
          if transform is None:
              # normalize here and replace zero row sums with 1
              # to avoid harmless divide by zero warnings
              d = sps.diags(
                  np.float_power(
                      np.ravel(np.maximum(A.sum(axis=1), 1)), -1
                  ),
                  0,
              )
              A = d.dot(A)
  
          else:
              self.features, A = transform(self.features, A)
  
          A = A.tocoo()
          self.As.append(A)
  
imports: import warnings
  import operator
  import random
  import numpy
  import itertools
  import networkx
  import scipy.sparse
  from tensorflow.keras import backend
  from functools import reduce
  from tensorflow.keras.utils import Sequence
  from .None import Generator, FullBatchSequence, SparseFullBatchSequence, RelationalFullBatchNodeSequence, GraphSAGENodeGenerator, DirectedGraphSAGENodeGenerator
  from ..core.graph import StellarGraph
  from ..core.utils import is_real_iterable
  from ..core.utils import GCN_Aadj_feats_op, PPNP_Aadj_feats_op
  from ..core.validation import comma_sep
label_desc: Use image node_id 1 to create a new RelationalFullBatchNodeGenerator object from inherited base classes: Generator with example: obj = RelationalFullBatchNodeGenerator(G, name, sparse, transform, weighted)