<SYSTEM_TASK:>
Given the following text description, write Python code to implement the functionality described below step by step
<END_TASK>
<USER_TASK:>
Description:
 Time Series Analysis
One important area of application for information theory is time series analysis. Here, we will demonstrate how to compute the modes of information flow --- intrinsic, shared, and synergistic --- between the two dimensions of the tinkerbell attractor.
Step1:  Here we define a few constants for this notebook
Step2:  Generating the Time Series
We write a generator for our two time series
Step3:  And then we generate the time series
Step4:  And we plot the attractor because it's pretty
Step5:  Discretizing the Time Series
Step6:  Constructing a Distribution from the Time Series
Step7:  Finally, we assign helpful variable names to the indicies of the distribution
Step8:  Measuring the Modes of Information Flow
<ASSISTANT_TASK:>
Python Code:
import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import dit
from dit.inference import binned, dist_from_timeseries
from dit.multivariate import total_correlation as I, intrinsic_total_correlation as IMI
dit.ditParams['repr.print'] = True
Explanation: Time Series Analysis
One important area of application for information theory is time series analysis. Here, we will demonstrate how to compute the modes of information flow --- intrinsic, shared, and synergistic --- between the two dimensions of the tinkerbell attractor.
End of explanation
TRANSIENTS = 1000
ITERATIONS = 1000000
BINS = 3
HISTORY_LENGTH = 2
Explanation: Here we define a few constants for this notebook:
End of explanation
def tinkerbell(x=None, y=None, a=0.9, b=-0.6013, c=2.0, d=0.5):
    if x is None:
        x = np.random.random() - 1
    if y is None:
        y = np.random.random() - 1
    while True:
        x, y = x**2 - y**2 + a*x + b*y, 2*x*y + c*x + d*y
        yield x, y
Explanation: Generating the Time Series
We write a generator for our two time series:
End of explanation
tb = tinkerbell()
# throw away transients
[next(tb) for _ in range(TRANSIENTS)]
time_series = np.asarray([next(tb) for _ in range(ITERATIONS)])
Explanation: And then we generate the time series:
End of explanation
plt.figure(figsize=(8, 6))
plt.scatter(time_series[:,0], time_series[:,1], alpha=0.1, s=0.01)
Explanation: And we plot the attractor because it's pretty:
End of explanation
binary_time_series = binned(time_series, bins=BINS)
print(binary_time_series[:10])
Explanation: Discretizing the Time Series
End of explanation
time_series_distribution = dist_from_timeseries(binary_time_series, history_length=HISTORY_LENGTH)
time_series_distribution
Explanation: Constructing a Distribution from the Time Series
End of explanation
x_past = [0]
y_past = [1]
x_pres = [2]
y_pres = [3]
Explanation: Finally, we assign helpful variable names to the indicies of the distribution:
End of explanation
intrinsic_x_to_y = IMI(time_series_distribution, [x_past, y_pres], y_past)
time_delayed_mutual_information_x_to_y = I(time_series_distribution, [x_past, y_pres])
transfer_entropy_x_to_y = I(time_series_distribution, [x_past, y_pres], y_past)
shared_x_to_y = time_delayed_mutual_information_x_to_y - intrinsic_x_to_y
synergistic_x_to_y = transfer_entropy_x_to_y - intrinsic_x_to_y
print(f"Flows from x to y:\n\tIntrinsic: {intrinsic_x_to_y}\n\tShared: {shared_x_to_y}\n\tSynergistic: {synergistic_x_to_y}")
intrinsic_y_to_x = IMI(time_series_distribution, [y_past, x_pres], x_past)
time_delayed_mutual_informtaion_y_to_x = I(time_series_distribution, [y_past, x_pres])
transfer_entropy_y_to_x = I(time_series_distribution, [y_past, x_pres], x_past)
shared_y_to_x = time_delayed_mutual_informtaion_y_to_x - intrinsic_y_to_x
synergistic_y_to_x = transfer_entropy_y_to_x - intrinsic_y_to_x
print(f"Flows from y to x:\n\tIntrinsic: {intrinsic_y_to_x}\n\tShared: {shared_y_to_x}\n\tSynergistic: {synergistic_y_to_x}")
Explanation: Measuring the Modes of Information Flow
End of explanation
<END_TASK>