.. _temp_network_classes: Temporal network classes ======================== Undirected and unweighted temporal networks are composed of :math:`N` nodes and up to :math:`m_{\mathrm{max}}=N(N-1)/2` edges, where each edge :math:`(i,j)` can be described as a series of events where the edge is either switched on or switched off. One way of expressing that is to define the temporal adjacency matrix .. math:: A_{ij}(t) = \begin{cases} 1, & (i,j)\ \mathrm{connected\ at\ time\ } t\\ 0, & \mathrm{else}. \end{cases} In `tacoma`, we will interpret temporal networks as if they were recorded in an experiment. We expect that over the course of time :math:`t_0\leq t < t_\mathrm{max}` in which we recorded activity, we encountered :math:`N` nodes from the node set :math:`V=\{0,1,\dots,N-1\}` (nodes possess an integer label). However, nodes do not need to be active (i.e. connected to other nodes) during the time of the experiment to be considered in the node set. .. figure:: img/example_temporal_network.png :alt: A temporal network and how it was recorded in an experiment A temporal network and how it was recorded in an experiment. We additionally assume to know that the network consists of :math:`N=8` nodes. Edges existed before we started measuring. An edge is considered to be "on" when it exists, shown as a grey bar in this figure. Each time an edge is switched "on" or switched "off", respectively, the network structure changes and hence this event is recorded. Here, the experiment ends before the edge :math:`(0,1)` is switched off. The experiment begins at time :math:`t_0`, where the network consists of an edge set :math:`E_0 \subseteq \{i,j: V\times V, i double containing the similarities of two edges. The integers in the pairs correspond to the index of the edges in `trajectories`. This dictionary is computed when :class:`_tacoma.edge_trajectories` is generated from a conversion using :func:`tacoma.api.get_edge_trajectories` with ``return_edge_similarity = True``. The network described in the figure above would be recorded as .. code:: python import tacoma as tc traj = tc.edge_trajectories() entry = tc.edge_trajectory_entry traj.N = 8 traj.t0 = 0.0 traj.tmax = 8.1 traj.trajectories = [ entry( (0,1), [(0., 3.), (7.0, 8.1)] ), entry( (2,5), [(3., 7.31)] ), entry( (1,7), [(0., 1.), (1.5, 4.0)] ), ] traj.time_unit = 's' traj.notes = 'This experiment was conducted as a test.' traj.int_to_node = { 0 : 'Alice', 1 : 'Bob', 2 : 'Clara', 3 : 'Darren', 4 : 'Elle', 5 : 'Felicitas', 6 : 'George', 7 : 'Harriett', } List of adjacency matrices ~~~~~~~~~~~~~~~~~~~~~~~~~~ For some cases it might be useful to actually have matrices in memory (e.g. to compute the epidemic threshold in SIS-models). ``tacoma`` offers the possibility to convert instances of :class:`_tacoma.edge_lists` and :class:`_tacoma.edge_changes` to :class:`tacoma.network_formats.sparse_adjacency_matrices` or :class:`tacoma.network_formats.adjacency_matrices`. These classes have the same attributes as :class:`_tacoma.edge_lists`, but instead of the attribute ``edges`` they have the attribute ``adjacency_matrices``. Convert a temporal network ``tn`` as follows .. code:: python A = tc.adjacency_matrices(tn) A = tc.sparse_adjacency_matrices(tn) Note that you can pass any desired ``scipy.sparse``-matrix class and ``dtype`` to :class:`tacoma.network_formats.sparse_adjacency_matrices` for matrix construction. Which class to use ~~~~~~~~~~~~~~~~~~ Each of the classes above has its specific use cases. Since most algorithms rely on the actual order of network-changing events, the main classes in tacoma are :class:`_tacoma.edge_lists` and :class:`_tacoma.edge_changes`, meaning that almost all of the algorithms in this package are specifically implemented for both, but not for :class:`_tacoma.edge_trajectories`. :class:`_tacoma.edge_lists` is to prefer if you just want to sample an edge list at a specific time. For :class:`_tacoma.edge_changes`, you would have to start at the beginning of the network, then fast forward to that time to obtain an edge list. Edge lists are often easier to deal with, however, if the inter-event times are rather small and the network is not sparse, two consecutive edge lists might be overlapping strongly. Hence, edge changes are often faster to deal with and need less memory. Furthermore, Algorithms which explicitly rely on edge changes, as e.g. dynamic Gillespie algorithms are natively faster on :class:`_tacoma.edge_changes`. :class:`_tacoma.edge_trajectories` is preffered for drawing an :func:`tacoma.drawing.edge_activity_plot` or to estimate edge-activity rates.