
    h                         S r SSKrSSKJr  S/r\" S5      \" S5      \R                  " SSS.S	9S
SS.S j5       5       5       rg)zTime dependent algorithms.    N)not_implemented_forcd_index
undirected
multigraph   )timeweight)
node_attrsr   c          	      6  ^ ^^^ [        U U4S jT  5       5      (       d  [        R                  " S5      e T R                  T   T   U-   nT R                  T    Vs1 s H  nT R                  U   T   U::  d  M  UiM     nnU V^s/ s H%  m[        U U4S jT T    5       5      (       a  SOSPM'     nn[        UR                  " U U4S jT T    5       6 5      n	U	S:X  a  [        R                  " S	5      eUc  [        [        S
 U 5       5      U	-  S5      $ U Vs/ s H"  nT R                  U   R                  US5      PM$     n
n[        [        S [        X5       5       5      U	-  S5      $ s  snf !   [        R                  " S5      e= fs  snf s  snf )a  Compute the CD index for `node` within the graph `G`.

Calculates the CD index for the given node of the graph,
considering only its predecessors who have the `time` attribute
smaller than or equal to the `time` attribute of the `node`
plus `time_delta`.

Parameters
----------
G : graph
   A directed networkx graph whose nodes have `time` attributes and optionally
   `weight` attributes (if a weight is not given, it is considered 1).
node : node
   The node for which the CD index is calculated.
time_delta : numeric or timedelta
   Amount of time after the `time` attribute of the `node`. The value of
   `time_delta` must support comparison with the `time` node attribute. For
   example, if the `time` attribute of the nodes are `datetime.datetime`
   objects, then `time_delta` should be a `datetime.timedelta` object.
time : string (Optional, default is "time")
    The name of the node attribute that will be used for the calculations.
weight : string (Optional, default is None)
    The name of the node attribute used as weight.

Returns
-------
float
   The CD index calculated for the node `node` within the graph `G`.

Raises
------
NetworkXError
   If not all nodes have a `time` attribute or
   `time_delta` and `time` attribute types are not compatible or
   `n` equals 0.

NetworkXNotImplemented
    If `G` is a non-directed graph or a multigraph.

Examples
--------
>>> from datetime import datetime, timedelta
>>> G = nx.DiGraph()
>>> nodes = {
...     1: {"time": datetime(2015, 1, 1)},
...     2: {"time": datetime(2012, 1, 1), "weight": 4},
...     3: {"time": datetime(2010, 1, 1)},
...     4: {"time": datetime(2008, 1, 1)},
...     5: {"time": datetime(2014, 1, 1)},
... }
>>> G.add_nodes_from([(n, nodes[n]) for n in nodes])
>>> edges = [(1, 3), (1, 4), (2, 3), (3, 4), (3, 5)]
>>> G.add_edges_from(edges)
>>> delta = timedelta(days=5 * 365)
>>> nx.cd_index(G, 3, time_delta=delta, time="time")
0.5
>>> nx.cd_index(G, 3, time_delta=delta, time="time", weight="weight")
0.12

Integers can also be used for the time values:
>>> node_times = {1: 2015, 2: 2012, 3: 2010, 4: 2008, 5: 2014}
>>> nx.set_node_attributes(G, node_times, "new_time")
>>> nx.cd_index(G, 3, time_delta=4, time="new_time")
0.5
>>> nx.cd_index(G, 3, time_delta=4, time="new_time", weight="weight")
0.12

Notes
-----
This method implements the algorithm for calculating the CD index,
as described in the paper by Funk and Owen-Smith [1]_. The CD index
is used in order to check how consolidating or destabilizing a patent
is, hence the nodes of the graph represent patents and the edges show
the citations between these patents. The mathematical model is given
below:

.. math::
    CD_{t}=\frac{1}{n_{t}}\sum_{i=1}^{n}\frac{-2f_{it}b_{it}+f_{it}}{w_{it}},

where `f_{it}` equals 1 if `i` cites the focal patent else 0, `b_{it}` equals
1 if `i` cites any of the focal patents successors else 0, `n_{t}` is the number
of forward citations in `i` and `w_{it}` is a matrix of weight for patent `i`
at time `t`.

The `datetime.timedelta` package can lead to off-by-one issues when converting
from years to days. In the example above `timedelta(days=5 * 365)` looks like
5 years, but it isn't because of leap year days. So it gives the same result
as `timedelta(days=4 * 365)`. But using `timedelta(days=5 * 365 + 1)` gives
a 5 year delta **for this choice of years** but may not if the 5 year gap has
more than 1 leap year. To avoid these issues, use integers to represent years,
or be very careful when you convert units of time.

References
----------
.. [1] Funk, Russell J., and Jason Owen-Smith.
       "A dynamic network measure of technological change."
       Management science 63, no. 3 (2017): 791-817.
       http://russellfunk.org/cdindex/static/papers/funk_ms_2017.pdf

c              3   H   >#    U  H  nTTR                   U   ;   v   M     g 7fN)nodes).0nGr   s     T/var/www/html/env/lib/python3.13/site-packages/networkx/algorithms/time_dependent.py	<genexpr>cd_index.<locals>.<genexpr>q   s     -1atqwwqz!1s   "z&Not all nodes have a 'time' attribute.zPAddition and comparison are not supported between 'time_delta' and 'time' types.c              3   2   >#    U  H  oTT   ;   v   M     g 7fr    )r   jr   is     r   r   r      s     .g!9gs   r   c              3   f   >#    U  H&  nTR                   U   R                  5       T1-
  v   M(     g 7fr   )predkeys)r   sr   nodes     r   r   r      s'     DGq)TF2Gs   .1r   zThe cd index cannot be defined.c              3   $   #    U  H  ov   M     g 7fr   r   )r   bis     r   r   r      s     (aas      c              3   .   #    U  H  u  pX-  v   M     g 7fr   r   )r   r    wts      r   r   r      s     ?VRs   )allnxNetworkXErrorr   r   anylenunionroundsumgetzip)r   r   
time_deltar   r	   target_dater   r   br   weightss   `` `  `    r   r   r   	   s{   P -1---GHH	
ggdmD)J666$<K<a1771:d+;{+J<K @DDt!s.ag...A	5tAD 	DJJDAdGDEFAAv@AA ~S(a((1,a00 7;;d1771:>>&!,d;S?s1??!CQGG- L
 
 	
 	E <s/   &E6 E1;E1E6 ,F)F1E6 6F)__doc__networkxr%   networkx.utilsr   __all___dispatchabler   r       r   <module>r8      s\       ., \"\"da89*0 BH : # #BHr7   