
    hw8                        S r SSKrSSKr/ SQr\R
                  " SSS9SS j5       r\R
                  " SSS9SS j5       r\R
                  " SSS9SS j5       r\R                  R                  R                  S	5      \R
                  " SSS9SS
SS.S j5       5       r\R                  R                  S5      \R                  R                  S5      \R
                  " SSS00S9SS.S j5       5       5       r\R                  R                  R                  S	5      \R
                  " SSS9SSS
SS.S j5       5       rg)z3Provides explicit constructions of expander graphs.    N)margulis_gabber_galil_graphchordal_cycle_graphpaley_graphmaybe_regular_expanderis_regular_expanderrandom_regular_expander_graphT)graphsreturns_graphc                    [         R                  " SU[         R                  S9nUR                  5       (       d  UR	                  5       (       d  Sn[         R
                  " U5      e[        R                  " [        U 5      SS9 HX  u  pEUSU-  -   U -  U4USU-  S-   -   U -  U4XESU-  -   U -  4XESU-  S-   -   U -  44 H  u  pgUR                  XE4Xg45        M     MZ     SU  S3UR                  S	'   U$ )
a  Returns the Margulis-Gabber-Galil undirected MultiGraph on `n^2` nodes.

The undirected MultiGraph is regular with degree `8`. Nodes are integer
pairs. The second-largest eigenvalue of the adjacency matrix of the graph
is at most `5 \sqrt{2}`, regardless of `n`.

Parameters
----------
n : int
    Determines the number of nodes in the graph: `n^2`.
create_using : NetworkX graph constructor, optional (default MultiGraph)
   Graph type to create. If graph instance, then cleared before populated.

Returns
-------
G : graph
    The constructed undirected multigraph.

Raises
------
NetworkXError
    If the graph is directed or not a multigraph.

r   default0`create_using` must be an undirected multigraph.   )repeat   zmargulis_gabber_galil_graph()name)nxempty_graph
MultiGraphis_directedis_multigraphNetworkXError	itertoolsproductrangeadd_edgegraph)ncreate_usingGmsgxyuvs           O/var/www/html/env/lib/python3.13/site-packages/networkx/generators/expanders.pyr   r   1   s    4 	q,>A}}aoo//@s##!!%(15!a%i1_a 1q519o"A&QUa a!eaiA%&	
DA JJvv&
 6 5QCq9AGGFOH    c                    [         R                  " SU[         R                  S9nUR                  5       (       d  UR	                  5       (       d  Sn[         R
                  " U5      e[        U 5       HF  nUS-
  U -  nUS-   U -  nUS:  a  [        X@S-
  U 5      OSnXVU4 H  nUR                  XH5        M     MH     SU  S3UR                  S'   U$ )	u  Returns the chordal cycle graph on `p` nodes.

The returned graph is a cycle graph on `p` nodes with chords joining each
vertex `x` to its inverse modulo `p`. This graph is a (mildly explicit)
3-regular expander [1]_.

`p` *must* be a prime number.

Parameters
----------
p : a prime number

    The number of vertices in the graph. This also indicates where the
    chordal edges in the cycle will be created.

create_using : NetworkX graph constructor, optional (default=nx.Graph)
   Graph type to create. If graph instance, then cleared before populated.

Returns
-------
G : graph
    The constructed undirected multigraph.

Raises
------
NetworkXError

    If `create_using` indicates directed or not a multigraph.

References
----------

.. [1] Theorem 4.4.2 in A. Lubotzky. "Discrete groups, expanding graphs and
       invariant measures", volume 125 of Progress in Mathematics.
       Birkhäuser Verlag, Basel, 1994.

r   r   r   r   r   zchordal_cycle_graph(r   r   )
r   r   r   r   r   r   r   powr   r   )	pr    r!   r"   r#   leftrightchordr$   s	            r'   r   r   \   s    N 	q,>A}}aoo//@s##1XA{Q! %&EA1ua qu%AJJq &   -QCq1AGGFOHr(   c                    [         R                  " SU[         R                  S9nUR                  5       (       a  Sn[         R                  " U5      e[        SU 5       Vs1 s H  oDS-  U -  S:w  d  M  US-  U -  iM     nn[        U 5       H#  nU H  nUR                  XDU-   U -  5        M     M%     SU  S3UR                  S'   U$ s  snf )	a  Returns the Paley $\frac{(p-1)}{2}$ -regular graph on $p$ nodes.

The returned graph is a graph on $\mathbb{Z}/p\mathbb{Z}$ with edges between $x$ and $y$
if and only if $x-y$ is a nonzero square in $\mathbb{Z}/p\mathbb{Z}$.

If $p \equiv 1  \pmod 4$, $-1$ is a square in $\mathbb{Z}/p\mathbb{Z}$ and therefore $x-y$ is a square if and
only if $y-x$ is also a square, i.e the edges in the Paley graph are symmetric.

If $p \equiv 3 \pmod 4$, $-1$ is not a square in $\mathbb{Z}/p\mathbb{Z}$ and therefore either $x-y$ or $y-x$
is a square in $\mathbb{Z}/p\mathbb{Z}$ but not both.

Note that a more general definition of Paley graphs extends this construction
to graphs over $q=p^n$ vertices, by using the finite field $F_q$ instead of $\mathbb{Z}/p\mathbb{Z}$.
This construction requires to compute squares in general finite fields and is
not what is implemented here (i.e `paley_graph(25)` does not return the true
Paley graph associated with $5^2$).

Parameters
----------
p : int, an odd prime number.

create_using : NetworkX graph constructor, optional (default=nx.Graph)
   Graph type to create. If graph instance, then cleared before populated.

Returns
-------
G : graph
    The constructed directed graph.

Raises
------
NetworkXError
    If the graph is a multigraph.

References
----------
Chapter 13 in B. Bollobas, Random Graphs. Second edition.
Cambridge Studies in Advanced Mathematics, 73.
Cambridge University Press, Cambridge (2001).
r   r   z&`create_using` cannot be a multigraph.r   r   zpaley(r   r   )r   r   DiGraphr   r   r   r   r   )r+   r    r!   r"   r#   
square_setx2s          r'   r   r      s    T 	q,

;A6s##
 ',AqkEkdaZ1_*1a41*kJE1XBJJqr6Q,'   qcmAGGFOH Fs    C3Cseedd   r    	max_triesr3   c                   SSK nU S:  a  [        R                  " S5      eUS:  d  [        R                  " S5      eUS-  S:X  d  [        R                  " S5      eU S-
  U:  d   [        R                  " SUS-   S	U  S
35      e[        R                  " X5      nU S:  a  U$ / n[	        5       n[        US-  5       GH  n	Un
[        U5      U	S-   U -  :w  d  M  U
S-  n
UR                  U S-
  5      R                  5       nUR                  U S-
  5        [        R                  R                  USS9 VVs1 s H  u  pX4U;  d  M  X4U;  d  M  X4iM     nnn[        U5      U :X  a"  UR                  U5        UR                  U5        U
S:X  a  [        R                  " S5      e[        U5      U	S-   U -  :w  a  M  GM     UR                  U5        U$ s  snnf )u  Utility for creating a random regular expander.

Returns a random $d$-regular graph on $n$ nodes which is an expander
graph with very good probability.

Parameters
----------
n : int
  The number of nodes.
d : int
  The degree of each node.
create_using : Graph Instance or Constructor
  Indicator of type of graph to return.
  If a Graph-type instance, then clear and use it.
  If a constructor, call it to create an empty graph.
  Use the Graph constructor by default.
max_tries : int. (default: 100)
  The number of allowed loops when generating each independent cycle
seed : (default: None)
  Seed used to set random number generation state. See :ref`Randomness<randomness>`.

Notes
-----
The nodes are numbered from $0$ to $n - 1$.

The graph is generated by taking $d / 2$ random independent cycles.

Joel Friedman proved that in this model the resulting
graph is an expander with probability
$1 - O(n^{-\tau})$ where $\tau = \lceil (\sqrt{d - 1}) / 2 \rceil - 1$. [1]_

Examples
--------
>>> G = nx.maybe_regular_expander(n=200, d=6, seed=8020)

Returns
-------
G : graph
    The constructed undirected graph.

Raises
------
NetworkXError
    If $d % 2 != 0$ as the degree must be even.
    If $n - 1$ is less than $ 2d $ as the graph is complete at most.
    If max_tries is reached

See Also
--------
is_regular_expander
random_regular_expander_graph

References
----------
.. [1] Joel Friedman,
   A Proof of Alon’s Second Eigenvalue Conjecture and Related Problems, 2004
   https://arxiv.org/abs/cs/0405020

r   Nr   zn must be a positive integerr   z$d must be greater than or equal to 2zd must be evenzNeed n-1>= d to have room for z independent cycles with z nodesT)cyclicz-Too many iterations in maybe_regular_expander)numpyr   r   r   setr   lenpermutationtolistappendutilspairwiseupdateadd_edges_from)r   dr    r6   r3   npr!   cyclesedgesi
iterationscycler%   r&   	new_edgess                  r'   r   r      s   ~ 1u=>>FEFFEQJ/00EQJ,QTF2KA3fU
 	
 	q'A1uFEE 16]
%jQUaK'!OJ $$QU+224ELLQ HH--eD-AADA6& ,-6+> A   9~"e$Y'Q&&'VWW' %jQUaK'' 0 UH!s   6GGGdirected
multigraphr!   weightr   )preserve_edge_attrsepsilonc                   SSK nSSKJn  US:  a  [        R                  " S5      e[        R
                  " U 5      (       d  g[        R                  R                  U R                  5      u  pE[        R                  " U [        S9nU" USSSS	9n[        U5      n[        [        U5      SUR                  US
-
  5      -  U-   :  5      $ )a  Determines whether the graph G is a regular expander. [1]_

An expander graph is a sparse graph with strong connectivity properties.

More precisely, this helper checks whether the graph is a
regular $(n, d, \lambda)$-expander with $\lambda$ close to
the Alon-Boppana bound and given by
$\lambda = 2 \sqrt{d - 1} + \epsilon$. [2]_

In the case where $\epsilon = 0$ then if the graph successfully passes the test
it is a Ramanujan graph. [3]_

A Ramanujan graph has spectral gap almost as large as possible, which makes them
excellent expanders.

Parameters
----------
G : NetworkX graph
epsilon : int, float, default=0

Returns
-------
bool
    Whether the given graph is a regular $(n, d, \lambda)$-expander
    where $\lambda = 2 \sqrt{d - 1} + \epsilon$.

Examples
--------
>>> G = nx.random_regular_expander_graph(20, 4)
>>> nx.is_regular_expander(G)
True

See Also
--------
maybe_regular_expander
random_regular_expander_graph

References
----------
.. [1] Expander graph, https://en.wikipedia.org/wiki/Expander_graph
.. [2] Alon-Boppana bound, https://en.wikipedia.org/wiki/Alon%E2%80%93Boppana_bound
.. [3] Ramanujan graphs, https://en.wikipedia.org/wiki/Ramanujan_graph

r   N)eigshzepsilon must be non negativeF)dtypeLMr   )whichkreturn_eigenvectorsr   )r9   scipy.sparse.linalgrR   r   r   
is_regularr?   arbitrary_elementdegreeadjacency_matrixfloatminboolabssqrt)	r!   rP   rD   rR   _rC   Alamslambda2s	            r'   r   r   L  s    b ){=>>==88%%ahh/DA
AU+A$!?D $iG GqBGGAEN2W<<==r(   )rP   r    r6   r3   c                    [        XX4US9nUn[        XbS9(       d<  US-  n[        XX4US9nUS:X  a  [        R                  " S5      e[        XbS9(       d  M<  U$ )ap  Returns a random regular expander graph on $n$ nodes with degree $d$.

An expander graph is a sparse graph with strong connectivity properties. [1]_

More precisely the returned graph is a $(n, d, \lambda)$-expander with
$\lambda = 2 \sqrt{d - 1} + \epsilon$, close to the Alon-Boppana bound. [2]_

In the case where $\epsilon = 0$ it returns a Ramanujan graph.
A Ramanujan graph has spectral gap almost as large as possible,
which makes them excellent expanders. [3]_

Parameters
----------
n : int
  The number of nodes.
d : int
  The degree of each node.
epsilon : int, float, default=0
max_tries : int, (default: 100)
  The number of allowed loops, also used in the maybe_regular_expander utility
seed : (default: None)
  Seed used to set random number generation state. See :ref`Randomness<randomness>`.

Raises
------
NetworkXError
    If max_tries is reached

Examples
--------
>>> G = nx.random_regular_expander_graph(20, 4)
>>> nx.is_regular_expander(G)
True

Notes
-----
This loops over `maybe_regular_expander` and can be slow when
$n$ is too big or $\epsilon$ too small.

See Also
--------
maybe_regular_expander
is_regular_expander

References
----------
.. [1] Expander graph, https://en.wikipedia.org/wiki/Expander_graph
.. [2] Alon-Boppana bound, https://en.wikipedia.org/wiki/Alon%E2%80%93Boppana_bound
.. [3] Ramanujan graphs, https://en.wikipedia.org/wiki/Ramanujan_graph

r5   rO   r   )r   rC   r    r6   r3   r   z4Too many iterations in random_regular_expander_graph)r   r   r   r   )r   rC   rP   r    r6   r3   r!   rH   s           r'   r   r     sr    p 		<4	A J!!5a
"<4
 ?""F  "!55 Hr(   )N)__doc__r   networkxr   __all___dispatchabler   r   r   r?   
decoratorsnp_random_stater   not_implemented_forr   r    r(   r'   <module>ro      si   9  T T2' 3'T T2< 3<~ T27 37t $$V,T2154 p 3 -pf j)l+sXqM&:;&' @> < , *@>F $$V,T2TStF 3 -Fr(   