ó
ú£Õ\c           @   s¼   d  Z  d d l Z d d l m Z d j d d d g ƒ Z d d	 d
 d g Z d „  Z d „  Z	 d „  Z
 d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d „  Z d S(   s   
Graph products.
iÿÿÿÿN(   t   products   
s   Aric Hagberg (hagberg@lanl.gov)s   Pieter Swart (swart@lanl.gov)s?   Dan Schult(dschult@colgate.edu)Ben Edwards(bedwards@cs.unm.edu)t   tensor_productt   cartesian_productt   lexicographic_productt   strong_productc            s-   t  ‡  ‡ f d †  t ˆ  ƒ t ˆ ƒ BDƒ ƒ S(   Nc         3   s3   |  ]) } | ˆ  j  | ƒ ˆ j  | ƒ f f Vq d  S(   N(   t   get(   t   .0t   k(   t   d1t   d2(    s]   /Users/dxp/prism/prism-games/prism-examples/smgs/car/networkx/algorithms/operators/product.pys	   <genexpr>   s    (   t   dictt   set(   R   R	   (    (   R   R	   s]   /Users/dxp/prism/prism-games/prism-examples/smgs/car/networkx/algorithms/operators/product.pyt   _dict_product   s    c         c   sL   xE t  |  | ƒ D]4 \ } } | | f t |  j | | j | ƒ f Vq Wd  S(   N(   R    R   t   node(   t   Gt   Ht   ut   v(    (    s]   /Users/dxp/prism/prism-games/prism-examples/smgs/car/networkx/algorithms/operators/product.pyt   _node_product   s    c   
      c   sc  |  j  ƒ  rŒ | j  ƒ  rŒ xo |  j d t ƒ D]X \ } } } xF | j d t ƒ D]2 \ } } } | | f | | f t | | ƒ f VqO Wq- Wn  |  j  ƒ  r#| j  ƒ  r#x{ |  j d t ƒ D]d \ } } } xR | j d t d t ƒ D]8 \ } } } } | | f | | f | t | | ƒ f Vqà Wq¸ Wn  |  j  ƒ  rº| j  ƒ  rºx{ |  j d t d t ƒ D]^ \ } } } } xI | j d t ƒ D]5 \ } } } | | f | | f | t | | ƒ f VqzWqUWn  |  j  ƒ  r_| j  ƒ  r_xŠ |  j d t d t ƒ D]m \ } } }	 } xX | j d t d t ƒ D]> \ } } } } | | f | | f |	 | f t | | ƒ f VqWqëWn  d  S(   Nt   datat   keys(   t   is_multigrapht
   edges_itert   TrueR   (
   R   R   R   R   t   ct   xt   yt   dR   t   j(    (    s]   /Users/dxp/prism/prism-games/prism-examples/smgs/car/networkx/algorithms/operators/product.pyt   _directed_edges_cross_edges   s     ""."+1+"1++c   
      c   sc  |  j  ƒ  rŒ | j  ƒ  rŒ xo |  j d t ƒ D]X \ } } } xF | j d t ƒ D]2 \ } } } | | f | | f t | | ƒ f VqO Wq- Wn  |  j  ƒ  r#| j  ƒ  r#x{ |  j d t ƒ D]d \ } } } xR | j d t d t ƒ D]8 \ } } } } | | f | | f | t | | ƒ f Vqà Wq¸ Wn  |  j  ƒ  rº| j  ƒ  rºx{ |  j d t d t ƒ D]^ \ } } } } xI | j d t ƒ D]5 \ } } } | | f | | f | t | | ƒ f VqzWqUWn  |  j  ƒ  r_| j  ƒ  r_xŠ |  j d t d t ƒ D]m \ } } }	 } xX | j d t d t ƒ D]> \ } } } } | | f | | f |	 | f t | | ƒ f VqWqëWn  d  S(   NR   R   (   R   R   R   R   (
   R   R   R   R   R   R   R   R   R   R   (    (    s]   /Users/dxp/prism/prism-games/prism-examples/smgs/car/networkx/algorithms/operators/product.pyt   _undirected_edges_cross_edges0   s     ""."+1+"1++c         c   sí   |  j  ƒ  rl xÚ |  j d t d t ƒ D]@ \ } } } } x+ | D]# } | | f | | f | | f Vq> Wq% Wn} xz |  j d t ƒ D]f \ } } } xT | D]L } | j  ƒ  rÇ | | f | | f d  | f Vq• | | f | | f | f Vq• Wq Wd  S(   NR   R   (   R   R   R   t   None(   R   R   R   R   R   R   R   (    (    s]   /Users/dxp/prism/prism-games/prism-examples/smgs/car/networkx/algorithms/operators/product.pyt   _edges_cross_nodesB   s    +(" c         c   sí   | j  ƒ  rl xÚ |  D]R } xI | j d t d t ƒ D]/ \ } } } } | | f | | f | | f Vq2 Wq Wn} xz |  D]r } xi | j d t ƒ D]U \ } } } |  j  ƒ  rÇ | | f | | f d  | f VqŒ | | f | | f | f VqŒ Wqs Wd  S(   NR   R   (   R   R   R   R   (   R   R   R   R   R   R   R   (    (    s]   /Users/dxp/prism/prism-games/prism-examples/smgs/car/networkx/algorithms/operators/product.pyt   _nodes_cross_edgesP   s    +(" c         c   s  |  j  ƒ  r} xü |  j d t d t ƒ D]Q \ } } } } x< | D]4 } x+ | D]# } | | f | | f | | f VqK Wq> Wq% WnŽ x‹ |  j d t ƒ D]w \ } } } xe | D]] } xT | D]L } | j  ƒ  rå | | f | | f d  | f Vq³ | | f | | f | f Vq³ Wq¦ Wq Wd  S(   NR   R   (   R   R   R   R   (   R   R   R   R   R   R   R   R   (    (    s]   /Users/dxp/prism/prism-games/prism-examples/smgs/car/networkx/algorithms/operators/product.pyt   _edges_cross_nodes_and_nodes]   s    +," c         C   s   |  j  ƒ  | j  ƒ  k s- t j d d ƒ ‚ n  |  j ƒ  sE | j ƒ  rT t j ƒ  } n t j ƒ  } |  j  ƒ  r{ | j ƒ  } n  | S(   Ns    G and H must be both directed ors   both undirected(   t   is_directedt   nxt   NetworkXErrorR   t
   MultiGrapht   Grapht   to_directed(   R   R   t   GH(    (    s]   /Users/dxp/prism/prism-games/prism-examples/smgs/car/networkx/algorithms/operators/product.pyt   _init_product_graphl   s    	c         C   sƒ   t  |  | ƒ } | j t |  | ƒ ƒ | j t |  | ƒ ƒ | j ƒ  s` | j t |  | ƒ ƒ n  d |  j d | j d | _ | S(   sÍ  Return the tensor product of G and H.

    The tensor product P of the graphs G and H has a node set that
    is the Cartesian product of the node sets, $V(P)=V(G) \times V(H)$.
    P has an edge ((u,v),(x,y)) if and only if (u,v) is an edge in G
    and (x,y) is an edge in H.

    Sometimes referred to as the categorical product. 


    Parameters
    ----------
    G, H: graphs
     Networkx graphs. 

    Returns
    -------
    P: NetworkX graph
     The tensor product of G and H. P will be a multi-graph if either G
     or H is a multi-graph. Will be a directed if G and H are directed,
     and undirected if G and H are undirected.

    Raises
    ------
    NetworkXError
     If G and H are not both directed or both undirected.

    Notes
    -----
    Node attributes in P are two-tuple of the G and H node attributes.
    Missing attributes are assigned None.

    For example
    >>> G = nx.Graph()
    >>> H = nx.Graph()
    >>> G.add_node(0,a1=True)
    >>> H.add_node('a',a2='Spam')
    >>> P = nx.tensor_product(G,H)
    >>> P.nodes(data=True)
    [((0, 'a'), {'a1': (True, None), 'a2': (None, 'Spam')})]

    Edge attributes and edge keys (for multigraphs) are also copied to the
    new product graph
    s   Tensor product(t   ,t   )(   R*   t   add_nodes_fromR   t   add_edges_fromR   R#   R   t   name(   R   R   R)   (    (    s]   /Users/dxp/prism/prism-games/prism-examples/smgs/car/networkx/algorithms/operators/product.pyR   y   s    -c         C   s¡   |  j  ƒ  | j  ƒ  k s- t j d d ƒ ‚ n  t |  | ƒ } | j t |  | ƒ ƒ | j t |  | ƒ ƒ | j t |  | ƒ ƒ d |  j	 d | j	 d | _	 | S(   sÏ  Return the Cartesian product of G and H.

    The tensor product P of the graphs G and H has a node set that
    is the Cartesian product of the node sets, $V(P)=V(G) 	imes V(H)$.
    P has an edge ((u,v),(x,y)) if and only if (u,v) is an edge in G 
    and x==y or  and (x,y) is an edge in H and u==v.
    and (x,y) is an edge in H.

    Parameters
    ----------
    G, H: graphs
     Networkx graphs. 

    Returns
    -------
    P: NetworkX graph
     The Cartesian product of G and H. P will be a multi-graph if either G
     or H is a multi-graph. Will be a directed if G and H are directed,
     and undirected if G and H are undirected.

    Raises
    ------
    NetworkXError
     If G and H are not both directed or both undirected.

    Notes
    -----
    Node attributes in P are two-tuple of the G and H node attributes.
    Missing attributes are assigned None.

    For example
    >>> G = nx.Graph()
    >>> H = nx.Graph()
    >>> G.add_node(0,a1=True)
    >>> H.add_node('a',a2='Spam')
    >>> P = nx.tensor_product(G,H)
    >>> P.nodes(data=True)
    [((0, 'a'), {'a1': (True, None), 'a2': (None, 'Spam')})]

    Edge attributes and edge keys (for multigraphs) are also copied to the
    new product graph
    s    G and H must be both directed ors   both undirecteds   Cartesian product(R+   R,   (
   R#   R$   R%   R*   R-   R   R.   R    R!   R/   (   R   R   R)   (    (    s]   /Users/dxp/prism/prism-games/prism-examples/smgs/car/networkx/algorithms/operators/product.pyR   ®   s    +	c         C   st   t  |  | ƒ } | j t |  | ƒ ƒ | j t |  | ƒ ƒ | j t |  | ƒ ƒ d |  j d | j d | _ | S(   s¯  Return the lexicographic product of G and H.

    The lexicographical product P of the graphs G and H has a node set that
    is the Cartesian product of the node sets, $V(P)=V(G) 	imes V(H)$.
    P has an edge ((u,v),(x,y)) if and only if (u,v) is an edge in G 
    or u==v and (x,y) is an edge in H.

    Parameters
    ----------
    G, H: graphs
     Networkx graphs. 

    Returns
    -------
    P: NetworkX graph
     The Cartesian product of G and H. P will be a multi-graph if either G
     or H is a multi-graph. Will be a directed if G and H are directed,
     and undirected if G and H are undirected.

    Raises
    ------
    NetworkXError
     If G and H are not both directed or both undirected.

    Notes
    -----
    Node attributes in P are two-tuple of the G and H node attributes.
    Missing attributes are assigned None.

    For example
    >>> G = nx.Graph()
    >>> H = nx.Graph()
    >>> G.add_node(0,a1=True)
    >>> H.add_node('a',a2='Spam')
    >>> P = nx.tensor_product(G,H)
    >>> P.nodes(data=True)
    [((0, 'a'), {'a1': (True, None), 'a2': (None, 'Spam')})]

    Edge attributes and edge keys (for multigraphs) are also copied to the
    new product graph
    s   Lexographic product(R+   R,   (   R*   R-   R   R.   R"   R!   R/   (   R   R   R)   (    (    s]   /Users/dxp/prism/prism-games/prism-examples/smgs/car/networkx/algorithms/operators/product.pyR   ã   s    *c         C   s¯   t  |  | ƒ } | j t |  | ƒ ƒ | j t |  | ƒ ƒ | j t |  | ƒ ƒ | j t |  | ƒ ƒ | j ƒ  sŒ | j t |  | ƒ ƒ n  d |  j	 d | j	 d | _	 | S(   så  Return the strong product of G and H.

    The strong product P of the graphs G and H has a node set that
    is the Cartesian product of the node sets, $V(P)=V(G) 	imes V(H)$.
    P has an edge ((u,v),(x,y)) if and only if 
    u==v and (x,y) is an edge in H, or
    x==y and (u,v) is an edge in G, or
    (u,v) is an edge in G and (x,y) is an edge in H.

    Parameters
    ----------
    G, H: graphs
     Networkx graphs. 

    Returns
    -------
    P: NetworkX graph
     The Cartesian product of G and H. P will be a multi-graph if either G
     or H is a multi-graph. Will be a directed if G and H are directed,
     and undirected if G and H are undirected.

    Raises
    ------
    NetworkXError
     If G and H are not both directed or both undirected.

    Notes
    -----
    Node attributes in P are two-tuple of the G and H node attributes.
    Missing attributes are assigned None.

    For example
    >>> G = nx.Graph()
    >>> H = nx.Graph()
    >>> G.add_node(0,a1=True)
    >>> H.add_node('a',a2='Spam')
    >>> P = nx.tensor_product(G,H)
    >>> P.nodes(data=True)
    [((0, 'a'), {'a1': (True, None), 'a2': (None, 'Spam')})]

    Edge attributes and edge keys (for multigraphs) are also copied to the
    new product graph
    s   Strong product(R+   R,   (
   R*   R-   R   R.   R!   R    R   R#   R   R/   (   R   R   R)   (    (    s]   /Users/dxp/prism/prism-games/prism-examples/smgs/car/networkx/algorithms/operators/product.pyR     s    ,(   t   __doc__t   networkxR$   t	   itertoolsR    t   joint
   __author__t   __all__R   R   R   R   R    R!   R"   R*   R   R   R   R   (    (    (    s]   /Users/dxp/prism/prism-games/prism-examples/smgs/car/networkx/algorithms/operators/product.pyt   <module>   s&   										5	5	3