def active_information(net, k, timesteps, size=None, local=False): """ Compute the active information storage for each node in a network. .. doctest:: information >>> active_information(s_pombe, k=5, timesteps=20) array([0. , 0.4083436 , 0.62956679, 0.62956679, 0.37915718, 0.40046165, 0.67019615, 0.67019615, 0.39189127]) >>> lais = active_information(s_pombe, k=5, timesteps=20, local=True) >>> lais[1] array([[0.13079175, 0.13079175, 0.13079175, ..., 0.13079175, 0.13079175, 0.13079175], [0.13079175, 0.13079175, 0.13079175, ..., 0.13079175, 0.13079175, 0.13079175], [0.13079175, 0.13079175, 0.13079175, ..., 0.13079175, 0.13079175, 0.13079175], ..., [0.13079175, 0.13079175, 0.13079175, ..., 0.13079175, 0.13079175, 0.13079175], [0.13079175, 0.13079175, 0.13079175, ..., 0.13079175, 0.13079175, 0.13079175], [0.13079175, 0.13079175, 0.13079175, ..., 0.13079175, 0.13079175, 0.13079175]]) >>> np.mean(lais[1]) 0.4083435963963132 :param net: a NEET network :param k: the history length :param timesteps: the number of timesteps to evaluate the network :param size: the size of variable-sized network (or ``None``) :param local: whether or not to compute the local active information :returns: a numpy array of active information values """ series = timeseries(net, timesteps=timesteps, size=size) shape = series.shape if local: active_info = np.empty((shape[0], shape[1], shape[2] - k), dtype=np.float) for i in range(shape[0]): active_info[i, :, :] = pi.active_info(series[i], k=k, local=local) else: active_info = np.empty(shape[0], dtype=np.float) for i in range(shape[0]): active_info[i] = pi.active_info(series[i], k=k, local=local) return active_info
def __initialize(self): """ Initialize the internal variables storing the computed information measures. """ k = self.__k series = self.__series nodes = self.__series.shape[0] local_active_info = self.__local_active_info active_info = self.__active_info for i in range(nodes): local_active_info[i, :, :] = pi.active_info(series[i], k=k, local=True) active_info[i] = np.mean(local_active_info[i, :, :]) local_entropy_rate = self.__local_entropy_rate ent_rate = self.__entropy_rate for i in range(nodes): local_entropy_rate[i, :, :] = pi.entropy_rate(series[i], k=k, local=True) ent_rate[i] = np.mean(local_entropy_rate[i, :, :]) local_transfer_entropy = self.__local_transfer_entropy trans_entropy = self.__transfer_entropy for i in range(nodes): for j in range(nodes): te = pi.transfer_entropy(series[j], series[i], k=k, local=True) local_transfer_entropy[i, j, :, :] = te trans_entropy[i, j] = np.mean(te) local_mutual_info = self.__local_mutual_info mutual_info = self.__mutual_info for i in range(nodes): for j in range(nodes): local_mutual_info[i, j, :, :] = pi.mutual_info(series[j], series[i], local=True) mutual_info[i, j] = np.mean(local_mutual_info[i, j, :, :])
def game_loop(size=10, initial_p_alive=0.1, n_iters=1000, p_stasis=1., p_overpopulation=0., p_underpopulation=0., p_reproduction=1.): X = (torch.rand(size, size) < initial_p_alive).long().cuda() states = [] ts_alive = [] for i in range(n_iters): X = step_gol(X, p_stasis=p_stasis, p_overpopulation=p_overpopulation, p_underpopulation=p_underpopulation, p_reproduction=p_reproduction) write_gol(X) encoded_state = utils.encode(X[:4, :2].reshape(-1).cpu(), b=2) states.append(encoded_state) ts_alive.append(X.sum().cpu().numpy()) return active_info(states, k=2), np.mean(ts_alive)
def main(): main_dir = Path(r'P:\Synchronize\IWS\Testings\fourtrans_practice\phsann') os.chdir(main_dir) data_file = Path( r'P:\Synchronize\IWS\Testings\fourtrans_practice\phsann\neckar_norm_cop_infill_discharge_1961_2015_20190118.csv' ) beg_time = '2000-01-01' end_time = '2010-12-31' col = '427' n_sims = 1000 k = 2 data = pd.read_csv(data_file, sep=';', index_col=0).loc[beg_time:end_time, col].values if data.size % 2: data = data[:-1] assert np.all(np.isfinite(data)) data_mag_spec, data_phs_spec = get_mag_and_phs_spec(data) data_sorted = np.sort(data) data_ai = pim.active_info(data, k=k, local=True)[0] data_ai_mag_spec, data_ai_phs_spec = get_mag_and_phs_spec(data_ai) periods = (data_ai.size) / (np.arange(1, data_ai_mag_spec.size - 1)) periods = np.concatenate(([data_ai.size * 2], periods)) plt.figure(figsize=(10, 6)) for i in range(n_sims): rand_phs_spec = (-np.pi + (2 * np.pi * np.random.random(data_phs_spec.size))) rand_phs_spec[+0] = data_phs_spec[+0] rand_phs_spec[-1] = data_phs_spec[-1] rand_data = get_irfted_vals(data_mag_spec, rand_phs_spec) rand_data = data_sorted[np.argsort(np.argsort(rand_data))] rand_ai = pim.active_info(rand_data, k=k, local=True)[0] rand_ai_mag_spec, rand_ai_phs_spec = get_mag_and_phs_spec(rand_ai) plt.semilogx(periods, rand_ai_mag_spec[1:].cumsum(), alpha=0.5, lw=1, c='b') plt.semilogx(periods, data_ai_mag_spec[1:].cumsum(), alpha=0.75, lw=2, c='r') plt.grid() plt.gca().set_axisbelow(True) plt.xlabel('Time step') plt.ylabel('Mag spec') plt.xlim(plt.xlim()[::-1]) plt.show() return
def active_information(self, local=False): """ Get the local or average active information. Active information (AI) was introduced in [Lizier2012]_ to quantify information storage in distributed computation. AI is defined in terms of a temporally local variant .. math:: a_{X,i}(k) = \\log_2 \\frac{p(x^{(k)}_i, x_{i+1})}{p(x^{(k)}_i)p(x_{i+1})} where the probabilites are constructed emperically from an *entire* time series. From this local variant, the temporally global active information is defined as .. math:: A_X(k) = \\langle a_{X,i}(k) \\rangle_{i} = \\sum_{x^{(k)}_i,\\, x_{i+1}} p(x^{(k)}_i, x_{i+1}) \\log_2 \\frac{p(x^{(k)}_i, x_{i+1})}{p(x^{(k)}_i)p(x_{i+1})}. .. rubric:: Examples .. doctest:: information >>> arch = Information(s_pombe, k=5, timesteps=20) >>> arch.active_information() array([0. , 0.4083436 , 0.62956679, 0.62956679, 0.37915718, 0.40046165, 0.67019615, 0.67019615, 0.39189127]) >>> lais = arch.active_information(local=True) >>> lais[1] array([[0.13079175, 0.13079175, 0.13079175, ..., 0.13079175, 0.13079175, 0.13079175], [0.13079175, 0.13079175, 0.13079175, ..., 0.13079175, 0.13079175, 0.13079175], ..., [0.13079175, 0.13079175, 0.13079175, ..., 0.13079175, 0.13079175, 0.13079175], [0.13079175, 0.13079175, 0.13079175, ..., 0.13079175, 0.13079175, 0.13079175]]) >>> np.mean(lais[1]) 0.4083435... :param local: whether to return local (True) or global active information :type local: bool :return: a :class:`numpy.ndarray` containing the (local) active information for every node in the network """ if local: if self.__local_active_info is None: k = self.__k series = self.__series shape = series.shape local_active_info = np.empty((shape[0], shape[1], shape[2] - k)) for i in range(shape[0]): local_active_info[i, :, :] = pi.active_info(series[i], k=k, local=True) self.__local_active_info = local_active_info return self.__local_active_info else: if self.__active_info is None: k = self.__k series = self.__series shape = series.shape active_info = np.empty(shape[0]) for i in range(shape[0]): active_info[i] = pi.active_info(series[i], k=k) self.__active_info = active_info return self.__active_info