diff --git a/examples/tutorials/EventSeriesAnalysis.ipynb b/examples/tutorials/EventSeriesAnalysis.ipynb index 42275ed6..e8bffc12 100644 --- a/examples/tutorials/EventSeriesAnalysis.ipynb +++ b/examples/tutorials/EventSeriesAnalysis.ipynb @@ -51,29 +51,29 @@ "id": "a0721685", "metadata": {}, "source": [ - "As mentioned before, the paramter free method ES offers a fast and reliable method to measure synchronizations between time series.\n", + "As mentioned before, the parameter free method ES offers a fast and reliable method to measure synchronizations between time series.\n", "The fundamental idea of the method is illustrated by the picture below (from [Odenweller et al., 2020](https://journals.aps.org/pre/abstract/10.1103/PhysRevE.101.052213)):\n", "\n", "![Event Synchronisation](images/EventSynchronisation.png)\n", "\n", - "Two events $l$ and $m$, from timeseries $i$ and $j$ are considered synchronous if they occur within a certain time interal $\\tau$ retrieved from the data properties. The time interval $\\tau$ is defined as:\n", + "Two events $l$ and $m$, from timeseries $i$ and $j$ are considered synchronous if they occur within a certain time interal $\\tau$ retrieved from the data properties. The time interval $\\tau$ is defined as:\n", "\n", "$$\\tau_{lm}^{ij}=\\frac{1}{2}min\\left[(t_{l+1}^{i}-t_{l}^{i}), \\; (t_{l}^{i}-t_{l-1}^{i}), \\; (t_{m+1}^{j}-t_{m}^{j}), \\; (t_{m}^{j}-t_{m-1}^{j})\\right]$$\n", "\n", "From here the occurences of synchronised events in timeseries $i$ when given an event in $j$ gives:\n", "\n", - "$$c(i|j|)=\\sum_{l=2}^{s_i-1}\\sum_{m=2}^{s_j-1}J_{lm}^{im}$$\n", + "$$c(i|j)=\\sum_{l=2}^{s_i-1}\\sum_{m=2}^{s_j-1}J_{lm}^{im}$$\n", "\n", "whereby $J_{lm}^{im}$ counts the events that match the synchronization condition. For more detail on this, see [Odenweller et al., 2020](https://journals.aps.org/pre/abstract/10.1103/PhysRevE.101.052213).\n", "\n", "Finally, we can define the strength of event synchronisation between the timeseries $i$ and $j$ by:\n", "\n", - "$$Q_{ij}^{ES}=\\frac{c(i|j|)+c(j|i)}{\\sqrt{(s_i-2)(s_j-2)}}$$\n", + "$$Q_{ij}^{ES}=\\frac{c(i|j)+c(j|i)}{\\sqrt{(s_i-2)(s_j-2)}}$$\n", "\n", - "In the usual case for which the timeseries are not fully synchronized, $0 <= Q_{ij}^{ES} <= 1$. For total or abscent synchronisation $Q_{ij}^{ES} = 1$ or $Q_{ij}^{ES} = 0$, respectively. \n", + "In the usual case for which the timeseries are not fully synchronised, $0 <= Q_{ij}^{ES} <= 1$. For total or absent synchronisation $Q_{ij}^{ES} = 1$ or $Q_{ij}^{ES} = 0$, respectively. \n", "\n", - "To generate a network from a set of timeseries, we can consider the the $Q_{ij}^{ES}$ values, as the coefficients of a square symmetric matrix $Q^{ES}$, from which an unidrected network from multivariate data can be constructed. \n", - "It is to be noted that fully synchronized time series will adapt a value of $Q_{ii}^{ES} = Q_{jj}^{ES} = 1$. \n", + "To generate a network from a set of timeseries, we can consider the the $Q_{ij}^{ES}$ values, as the coefficients of a square symmetric matrix $Q^{ES}$, from which an unidirected network from multivariate data can be constructed. \n", + "It is to be noted that fully synchronised time series will adapt a value of $Q_{ii}^{ES} = Q_{jj}^{ES} = 1$. \n", "\n", "The advatage of ES is that no parameters, specially a delay specification of the two timeseries, has to selected a priori as the algorithm classifies two events as snychronized automatically. " ] @@ -101,11 +101,11 @@ "\n", "$$r_p(i|j;\\Delta T,\\tau) = \\frac{1}{s_i-s_{i}^{'}}\\sum_{l=1+s_{i}^{'}}^{s_i} \\Theta \\left[\\sum_{m=1}^{s_j} 1_{[0,\\Delta T]}\\left[(t_{l}^{i}-\\tau)-t_m^j\\right]\\right]$$\n", "\n", - "The trigger event cincidence rate on the other hand is defined as:\n", + "The trigger event coincidence rate on the other hand is defined as:\n", "\n", "$$r_p(i|j;\\Delta T,\\tau)=\\frac{1}{s_i-s_{i}^{''}}\\sum_{m=1}^{s_j-s_j^{''}}\\Theta\\left[\\sum_{l=1}^{s_i} 1_{[0,\\Delta T]} \\left[(t_l^i-\\tau)-t_m^j\\right]\\right]$$\n", "\n", - "For detailed information on the calculation of e.g. $s_i^{''}$ or $s_j^{''}$, consult [Odenweller et al., 2020](https://journals.aps.org/pre/abstract/10.1103/PhysRevE.101.052213)). \n", + "For detailed information on the calculation of e.g. $s_i^{''}$ or $s_j^{''}$, consult [Odenweller et al., 2020](https://journals.aps.org/pre/abstract/10.1103/PhysRevE.101.052213). \n", "\n", "By changing the indices of the precursor and trigger rate, one gets the rate in the other directions e.g. for $r_t(i|j; \\Delta T, \\tau)$.\n", "\n", @@ -163,19 +163,19 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 6, "id": "a2c1ca5e", "metadata": {}, "outputs": [], "source": [ "series = np.array([[0, 1, 0],\n", - " [0, 0, 0],\n", + " [1, 0, 1],\n", " [0, 0, 0],\n", " [1, 0, 1],\n", " [0, 1, 0],\n", " [0, 0, 0],\n", - " [0, 0, 0],\n", - " [0, 0, 0],\n", + " [1, 0, 0],\n", + " [0, 0, 1],\n", " [0, 1, 0],\n", " [0, 0, 0]])" ] @@ -190,7 +190,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 7, "id": "eeddb65f", "metadata": {}, "outputs": [ @@ -198,13 +198,13 @@ "name": "stdout", "output_type": "stream", "text": [ - "The initialized Event Series of the examples is EventSeries: 3 variables, 10 timesteps, taumax: 1.0, lag: 0.0\n" + "The initialized Event Series of our example is EventSeries: 3 variables, 10 timesteps, taumax: 1.0, lag: 0.0\n" ] } ], "source": [ "ev = EventSeries(series, taumax=1)\n", - "print(f\"The initialized Event Series of the examples is\", ev)" + "print(f\"The initialized Event Series of our example is\", ev)" ] }, { @@ -225,7 +225,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 8, "id": "9295b844", "metadata": {}, "outputs": [ @@ -233,22 +233,8 @@ "name": "stdout", "output_type": "stream", "text": [ - "(0.0, 0.0)\n", - "(nan, nan, nan, nan)\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/fritz/Desktop/23_H2_PIK/pyunicorn/src/pyunicorn/eventseries/event_series.py:578: RuntimeWarning: invalid value encountered in divide\n", - " return (np.float32(prec12) / (l1 - n11),\n", - "/Users/fritz/Desktop/23_H2_PIK/pyunicorn/src/pyunicorn/eventseries/event_series.py:579: RuntimeWarning: invalid value encountered in divide\n", - " np.float32(trig12) / (l2 - n22),\n", - "/Users/fritz/Desktop/23_H2_PIK/pyunicorn/src/pyunicorn/eventseries/event_series.py:580: RuntimeWarning: invalid value encountered in divide\n", - " np.float32(prec21) / (l2 - n21),\n", - "/Users/fritz/Desktop/23_H2_PIK/pyunicorn/src/pyunicorn/eventseries/event_series.py:581: RuntimeWarning: invalid value encountered in divide\n", - " np.float32(trig21) / (l1 - n12))\n" + "(0.5, 0.5)\n", + "(0.5, 1.0, 1.0, 1.0)\n" ] } ], @@ -278,30 +264,21 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 11, "id": "56cec935", "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "/Users/fritz/Desktop/23_H2_PIK/pyunicorn/src/pyunicorn/eventseries/event_series.py:354: UserWarning: No 'threshold_types' given. If 'threshold_values' >= median, 'above' is used by default!\n", - " warnings.warn(\"No 'threshold_types' given. If 'threshold_values' \"\n" - ] - } - ], + "outputs": [], "source": [ "series = 10*np.random.rand(10,3)\n", "series = series.astype(int)\n", "\n", - "#Initialize dataset as EventSeries \n", - "ev = EventSeries(series[:, :2], threshold_method = 'quantile', threshold_values = 0.5, taumax=1)" + "#Initialize dataset as EventSeries\n", + "ev = EventSeries(series[:, :2], threshold_method = 'quantile', threshold_values = 0.5, threshold_types='below', taumax=1)" ] }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 12, "id": "08e046a8", "metadata": {}, "outputs": [ @@ -309,7 +286,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "(0.43301270189221935, 0.43301270189221935)\n", + "(0.42857142857142855, 0.42857142857142855)\n", "(1.0, 1.0, 1.0, 1.0)\n" ] } @@ -322,7 +299,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 13, "id": "f6caefe2", "metadata": {}, "outputs": [ @@ -332,7 +309,7 @@ "(1.0, 1.0)" ] }, - "execution_count": 8, + "execution_count": 13, "metadata": {}, "output_type": "execute_result" } @@ -356,7 +333,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 14, "id": "0f5cf4b9", "metadata": {}, "outputs": [ @@ -364,10 +341,10 @@ "name": "stdout", "output_type": "stream", "text": [ - "Matrix of Es strenghts is [[0. 0. ]\n", - " [0.40824829 0. ]]\n", - "Matrix of ECA strengths is [[0. 0.625]\n", - " [0.625 0. ]]\n" + "Matrix of Es strenghts is [[0. 0.16666667]\n", + " [0.16666667 0. ]]\n", + "Matrix of ECA strengths is [[0. 0.875]\n", + " [0.875 0. ]]\n" ] } ], @@ -407,7 +384,7 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 15, "id": "0bf34e66", "metadata": {}, "outputs": [ @@ -415,10 +392,10 @@ "name": "stdout", "output_type": "stream", "text": [ - "[[0. 0. ]\n", - " [0.834 0. ]]\n", - "[[0. 0.239]\n", - " [0.239 0. ]]\n" + "[[0. 0.119]\n", + " [0.123 0. ]]\n", + "[[0. 0.609]\n", + " [0.609 0. ]]\n" ] } ], @@ -431,7 +408,7 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": 16, "id": "726c572a", "metadata": {}, "outputs": [ @@ -439,10 +416,10 @@ "name": "stdout", "output_type": "stream", "text": [ - "[[0. 0. ]\n", - " [0.822 0. ]]\n", - "[[0. 0.247]\n", - " [0.247 0. ]]\n" + "[[0. 0.12 ]\n", + " [0.112 0. ]]\n", + "[[0. 0.609]\n", + " [0.609 0. ]]\n" ] } ], @@ -479,10 +456,18 @@ }, { "cell_type": "code", - "execution_count": 204, + "execution_count": 17, "id": "ea03f3ea", "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "climate: Package Ngl could not be loaded. Some functionality in class MapPlots might not be available!\n" + ] + } + ], "source": [ "#import additonal packages to generate Climate Networks \n", "from pyunicorn.climate.eventseries_climatenetwork import EventSeriesClimateNetwork\n", @@ -499,7 +484,7 @@ }, { "cell_type": "code", - "execution_count": 205, + "execution_count": 18, "id": "9b8c2e94", "metadata": {}, "outputs": [ @@ -555,7 +540,7 @@ }, { "cell_type": "code", - "execution_count": 206, + "execution_count": 19, "id": "e591bcf2", "metadata": {}, "outputs": [ @@ -593,7 +578,7 @@ }, { "cell_type": "code", - "execution_count": 207, + "execution_count": 20, "id": "bbb03017", "metadata": {}, "outputs": [ diff --git a/src/pyunicorn/eventseries/event_series.py b/src/pyunicorn/eventseries/event_series.py index 212d3cda..553642c1 100644 --- a/src/pyunicorn/eventseries/event_series.py +++ b/src/pyunicorn/eventseries/event_series.py @@ -55,13 +55,13 @@ def __init__(self, data, timestamps=None, taumax=np.inf, lag=0.0, eventmatrix could look like array([[0, 1, 0], - [0, 0, 0], + [1, 0, 1], [0, 0, 0], [1, 0, 1], [0, 1, 0], [0, 0, 0], - [0, 0, 0], - [0, 0, 0], + [1, 0, 0], + [0, 0, 1], [0, 1, 0], [0, 0, 0]])