## Building Network 2

```+ Tutorial 4:
1. Building Network
2. Building Network 2```

This tutorial shows some networks that can be randomly generated following some predetermined rules. The essence is the same: define the members of networks, define how they are linked to one another, give them coordinates x, y, z in space and we have these images plotted. ```import numpy as np

N=20
r_set=np.random.normal(0.8,0.4,size=(N,1))
azimuth_set = np.random.uniform(0,2*np.pi,size=(N,1))
polar_set = np.random.uniform(0,np.pi,size=(N,1))

import kero.multib.nDnet as nd
import matplotlib.pyplot as plt

fig = plt.figure()
net = nd.Network()
members=[str(i) for i in range(N)]

def compute_distance(p1,p2):
# p1, p2 = [x,y,z]
out = (p2-p1)**2 + (p2-p1)**2 + (p2-p1)**2
return out**0.5

grid_lattice_points={}
for v,r,azim,polar in zip(members,r_set,azimuth_set,polar_set):
x = r * np.sin(polar) * np.cos(azim)
y = r * np.sin(polar) * np.sin(azim)
z = r * np.cos(polar)
grid_lattice_points[v]=[x,y,z]
for u in net.member_set:
if u is not v:
distance = compute_distance(grid_lattice_points[v],grid_lattice_points[u])
else:
continue

net.grid_lattice_points=grid_lattice_points

net.visualize_3D_graph(ax,
no_of_points_per_edge=24,
this_figure=fig,)
plt.show()```

Simulation is done using kero version: 0.5.1.

## Building Network

```+ Tutorial 4:
1. Building Network
2. Building Network 2```

We demonstrate the use of kero.multib to build an arbitrary network in the form of un-directed graphs. The explanations should be self explanatory and embedded as comments in the code below. The code will plot figure 1 to 4 in sequence. ```import kero.multib.nDnet as nd
import matplotlib.pyplot as plt

fig = plt.figure()
net = nd.Network()

# -------------------------------------
# Create network members
# -------------------------------------
groupA=["A1","A2","A3"]
groupB=["B"+str(i) for i in range(5)]
groupC=["C"+str(i) for i in range(5)]
member_set = groupA + groupB + groupC + ["groupA","groupB","groupC"]
for v in member_set:
print("Check point 1. Network members: \n --> ", net.member_set)

# --------------------------------------------
# Give each members a spatial coordinates
# -------------------------------------=======
grid_lattice_points={
"A1": [0,0,0],
"A2": [0,1,0],
"A3": [1,0,0],
"groupA": [0,0,4] ,
"groupB": [2,0,4],
"groupC": [4,0,4]
}
groupB_coord = [[2,0,0],[2,1,0],[2,-1,0],[3,0.5,0],[3,-0.5,0]]
for i in range(len(groupB)):
grid_lattice_points[groupB[i]] = groupB_coord[i]

groupC_coord = [[4,0,0],[4,1,0],[4,-1,0],[5,0,1],[5,0,-1]]
for i in range(len(groupC)):
grid_lattice_points[groupC[i]] = groupC_coord[i]
net.grid_lattice_points = grid_lattice_points

# -----------------------------------------------------
# Let us link members of group A and plot figure 1
# -----------------------------------------------------
print("\nCheck point 2.\nNow we add links between members of group A. See figure 1.")
print(" Network members: \n --> ", net.member_set)

# print(net.member_set)
net.visualize_3D_graph(ax,
title="1",
this_figure=fig,)

# -----------------------------------------------------
# Let us link members of group B and plot figure 2
# -----------------------------------------------------
print("\nCheck point 3.\nNow we add links between members of group B. See figure 2.")
for b1 in groupB:
for b2 in groupB:
if b1 is not b2:
# print(net.member_set)
net.visualize_3D_graph(ax2,
no_of_points_per_edge=12,
title="2",
this_figure=fig,)

# -----------------------------------------------------
# Let us link members of group C and plot figure 3
# -----------------------------------------------------
print("\nCheck point 4.\nNow we add links between members of group C. See figure 3.")
for c1 in groupC:
for c2 in groupC:
if c1 is not c2:
# print(net.member_set)
net.visualize_3D_graph(ax3,
no_of_points_per_edge=10,
title="3",
this_figure=fig,)

# -----------------------------------------------------
# plot figure 4
# -----------------------------------------------------

for b1 in groupB:
for c1 in groupC:
net.visualize_3D_graph(ax4,
no_of_points_per_edge=10,
title="4",
this_figure=fig,)
plt.show()```

Simulation is done using kero version: 0.5.1.

## 2D Interacting Grid

```+ Tutorial 3:
1. 1D Interacting Chain
2. 1D Interacting Chain 3D Quiver Plot
3. 2D Interacting Grid```

We revisit the two-dimensional grid system we built in our first example.  In this post, like the previous tutorial, we split the scripts into 3 parts: 1. run simulation and save data, 2. load and plot static images and 3. load and plot animated quiver image.

1. Run simulation and save data

Run simulation using testrun_beta_3_PNSAVE.py.

2. Load and plot static images Figure 1. (a) The actions of each member (color-coded) over the past 25 time-steps. Action is either P, a1 or a2 (action indices 0, 1 and 2 respectively) and the system settled down to the stable state where each member only performs a2. (b) The ratio of the number of actions to total number of actions over the last 25 steps. Each value at a time-step is the mean number of actions over the last 200 steps. This ratio is plotted over time. Only member “1”, “5” and “6” are shown. (c) The network in the form of 2D grid, where each label is the name of the member. Color intensity denotes the probability that the action a1 is performed (action index = 1), and they are all zero since at this instance the system stabilizes at all a2 state, i.e. all members have near 1.0 probability of performing a2 at any further time steps.

3. Load and plot animated quiver image

Run the script testrun_beta_3_LOADNANIM.py. The script is run twice to show different plotting angle.  Figure 2. The system starts off with each member having probability vector pointing in (1,0,0) direction except for member “5” (not labelled) pointing in (0.8, 0.1, 0.1) direction. After some time it stabilizes at stabilizes at the state where every member is at (0,0,1).

The scripts below import peripheral.py from here.

testrun_beta_3_PNSAVE.py

```import kero.multib.nDnet as nd
import matplotlib.pyplot as plt
from peripheral import *

# --------------------------------------------------------
# Set up system
# --------------------------------------------------------
m=4 # 4
n=3 # 3
net2D = nd.Network()
net2D.build_2D_grid(m,n)

import os
if not os.path.exists("save_folder"):
os.mkdir("save_folder")

def attach_a_probability_vector_field(one_member_to_modify):
net2D.set_of_fields["prob"] = {}
action_set = ["P","a1","a2"]
action_index_set = [0,1,2]
action_probability_set = [1,0,0] # members will perform only action P, 0% a1 and a2
for v in net2D.member_set:
net2D.set_of_fields["prob"][v] = [action_set,action_probability_set]
# For selected member, identified by one_member_to_modify, it has
#  80% change of doing P, and 10% a1,a2 each
net2D.set_of_fields["prob"][one_member_to_modify] = [0.8,0.1,0.1]
return action_set, action_index_set

action_set, action_index_set=attach_a_probability_vector_field("5")
# print(net2D.set_of_fields["prob"])

# --------------------------------------------------------
# Run Simulation
# --------------------------------------------------------
start1 = time.time()
Tset=range(1200) # Simulation length
action_history = {}
field_history = []

field_now={}
field_now["prob"]={}
for v in net2D.member_set:
field_now["prob"][v]=net2D.set_of_fields["prob"][v][:]
field_history.append(field_now)

for v in net2D.member_set:
action_history[v]=[]
for t in Tset: # : #
for v in net2D.member_set:
this_action_set = net2D.set_of_fields["prob"][v][:] # eg [a1,a2]
this_probability_set = net2D.set_of_fields["prob"][v][:] # eg [0.5,0.5]
action,action_index = nd.choose_action_continuous_probability(this_action_set, this_probability_set, N=1)
action_history[v].append([action_index,action])
# ---------------------------------------
# Add interaction in this region
# ---------------------------------------
debuff_factor=0.01 # check this out, switch between 1e-6 and 1e-2
for v in net2D.member_set:
a_set = action_history[v][-1]
neighbors = net2D.member_set[v]
# print(v, " : ", a_set," -> ", neighbors)
if a_set=="a1":
for k in neighbors:
temp = net2D.set_of_fields["prob"][k][:]
temp=temp+0.01
temp=temp-debuff_factor
if temp<0:
temp=0
if temp>1.0:
temp=1
sigma_temp=sum(temp)
net2D.set_of_fields["prob"][k] = [x/sigma_temp for x in temp]

elif a_set=="a2":
for k in neighbors:
temp = net2D.set_of_fields["prob"][k][:]
temp=temp-debuff_factor
temp=temp+0.01
if temp<0:
temp=0
if temp>1.0:
temp=1
sigma_temp=sum(temp)
net2D.set_of_fields["prob"][k] = [x/sigma_temp for x in temp]
# ---------------------------------------
# Store evolved field state
# ---------------------------------------
field_now={}
field_now["prob"]={}
for v in net2D.member_set:
field_now["prob"][v]=net2D.set_of_fields["prob"][v][:]
field_history.append(field_now)
# print(field_now)
time_keeper("Simulation",start1)

processor=nd.Network_processor()
processor.map_action_index(action_set,action_index_set)
mean_over_N=200

start2 = time.time()
interval_mean_history=processor.compute_interval_mean(mean_over_N=mean_over_N)
time_keeper("Processor",start2)
# --------------------------------------------------------
# Save State
# --------------------------------------------------------
import pickle
spt = nd.SAVE_POINT()
spt.data={
# Save any more data here
"m": m, # row number
"n": n, # column number
"mean_over_N": mean_over_N,
"interval_mean_history": interval_mean_history,
}

network_save_pack={
"network" : net2D,
"processor" : processor,
"SAVEPOINT" : spt
}

f = open("save_folder/test_beta3.pckl","wb")
pickle.dump(network_save_pack,f)
f.close()```

```import kero.multib.nDnet as nd
import matplotlib.pyplot as plt
from peripheral import *

import pickle
f = open("save_folder/test_beta3.pckl","rb")
f.close()
# spt.data={
# 	"mean_over_N": mean_over_N,
# 	"interval_mean_history": interval_mean_history,
# }

# network_save_pack={
# 	"network" : net2D,
# 	"processor" : processor,
# 	"SAVEPOINT" : spt
# }
net2D = network_save_pack["network"]
processor = network_save_pack["processor"]
spt = network_save_pack["SAVEPOINT"]

Tset=processor.Tset
action_history=processor.action_history
action_set = [x for x in processor.action_to_index_map] # ["P","a1","a2"]
action_index_set = [x for x in processor.index_to_action_map] # [0,1,2]
# for a,ai in zip(action_set,action_index_set):
# 	print("(action,index) = (",a,",",ai,")")
field_history = processor.field_history
mean_over_N=spt.data["mean_over_N"]
interval_mean_history=spt.data["interval_mean_history"]

fig=plt.figure()

# --------------------------------------------------------
# --------------------------------------------------------
start2=time.time()

processor.plot_action_over_time(
ax2,
plot_interval=(len(Tset)-24,None),
title="Action-time",
)
time_keeper("Action-time",start2)

# --------------------------------------------------------
# --------------------------------------------------------
start3=time.time()
member_set_to_display= ["1","5","6"] # net2D.member_set #
action_index_set_to_display=action_index_set # [0,1] #

processor.plot_interval_mean_over_time(
ax3,
interval_mean_history,
member_set_to_display,
action_index_set_to_display,
plotting_interval= (100,None), # (1,None)
plotting_interval_step_length=40,
title="Mean over last " + str(mean_over_N) +" steps"
)
time_keeper("Mean-time",start3)

# --------------------------------------------------------
# --------------------------------------------------------
start4=time.time()
action_index_to_display=1
time_step=None
interval_mean_at_t=processor.extract_interval_mean_at_a_time_step(interval_mean_history,time_step=time_step)
# print("interval_mean_at_t:\n",interval_mean_at_t)
CS=[interval_mean_at_t[action_index_to_display][v] for v in interval_mean_at_t[action_index_to_display]]
# print(CS)
net2D.visualize_3D_graph(ax,color_set=CS,
this_figure=fig,
no_of_points_per_edge=4,
member_set=net2D.member_set,
title="2D chain: act="+str(action_index_to_display),
cmap=plt.cm.hot
)
time_keeper("Graph",start4)

plt.show()```

```import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
from mpl_toolkits.mplot3d import Axes3D

import kero.multib.nDnet as nd
from peripheral import *

import pickle
f = open("save_folder/test_beta3.pckl","rb")
f.close()
# spt.data={
# 	# Save any more data here
# 	"m": m, # row number
# 	"n": n, # column number
# 	"mean_over_N": mean_over_N,
# 	"interval_mean_history": interval_mean_history,
# }

# network_save_pack={
# 	"network" : net2D,
# 	"processor" : processor,
# 	"SAVEPOINT" : spt
# }

net2D = network_save_pack["network"]
processor = network_save_pack["processor"]
spt = network_save_pack["SAVEPOINT"]

Tset=processor.Tset
action_history=processor.action_history
action_set = [x for x in processor.action_to_index_map] # ["P","a1","a2"]
action_index_set = [x for x in processor.index_to_action_map] # [0,1,2]
# for a,ai in zip(action_set,action_index_set):
# 	print("(action,index) = (",a,",",ai,")")
field_history = processor.field_history
Tset = processor.Tset
mean_over_N=spt.data["mean_over_N"]
interval_mean_history=spt.data["interval_mean_history"]
m=spt.data["m"]
n=spt.data["n"]

###############################################
# Probability Quiver
###############################################
fig=plt.figure()

gallery = nd.SpecialGallery()
no_of_steps_to_animate=400
field_name_to_plot="prob"
gallery.quiver3D_lattice3D(
fig,
ax,
no_of_steps_to_animate,
net2D.grid_lattice_points,
field_history,
field_name_to_plot,
field_index_to_plot=[0,1,2],
field_name_label=action_set,
grid_shape=[m,n],
time_between_steps_in_ms=1,
gif_filename='save_folder/test_beta3_quiver.gif',
show_real_time=True,
view_angle_elevation=30,
view_angle_azimuth=-60,
# xlim=[-1,4],
# ylim=[-1,4],
# zlim=[-1,4],
arrow_length_scale=0.8,
)
plt.show()```

Simulation is done using kero version: 0.5.1.

## SpecialGallery

This class of object is reserved for visualization of data for Network object processed by Network_processor object.

```kero.multib.nDnet.py

class SpecialGallery:
def __init__(self):
self.quiver3D_lattice3D_settings={}
return
def quiver3D_lattice3D(self,
fig,
ax,
no_of_steps_to_animate,
grid_lattice_points,
field_history,
field_name_to_plot,
field_index_to_plot=[0,1,2],
field_name_label=["X","Y","Z"],
grid_shape=None,
time_between_steps_in_ms=1,
gif_filename='quiver.gif',
show_real_time=True,
view_angle_elevation=90,
view_angle_azimuth=90,
xlim=None,
ylim=None,
zlim=None,
arrow_length_scale=None,
):
return```
 Properties Description quiver3D_lattice3D_settings TO BE UPDATED

kero version: 0.5.1 and above

## quiver3D_lattice3D()

Given a Network object whose members three-dimensional coordinates in space are specified by grid_lattice_points, which can be reshaped into a grid form specified by grid_shape. Also, given that the Network object has been evolved in time with the field data stored as field_history in the proper format,. Then this function plots a 3D quiver showing three of the components of a one of the fields in the field_history.

```kero.multib.nDnet.py

class SpecialGallery:
def quiver3D_lattice3D(self,
fig,
ax,
no_of_steps_to_animate,
grid_lattice_points,
field_history,
field_name_to_plot,
field_index_to_plot=[0,1,2],
field_name_label=["X","Y","Z"],
grid_shape=None,
time_between_steps_in_ms=1,
gif_filename='quiver.gif',
show_real_time=True,
view_angle_elevation=90,
view_angle_azimuth=90,
xlim=None,
ylim=None,
zlim=None,
arrow_length_scale=None,
):
return```

Arguments/Return

 fig ax Any matplotlib plotting axes, for example an object from no_of_steps_to_animate Integer. Number of steps out of the entire length of simulation to animate, starting from time step 0. The entire length is specified as Tset in Network_processor object. grid_lattice_points Dictionary – key: (string) a member of network. When initialized, it is to have the same key as member_set. – values: tuples showing the key’s coordinates in space, typically (x,y,z) or 3D field_history List of dictionary, [field1, field2,…] where each fieldk is a dictionary: – key: (string) field name – value: dictionary + key: (string) network member + values: [[a1,a2,…], [p1, p2, …]] where each ak is an action and each pk the probability of the occurrence of  the action ak at a time step. field_name_to_plot String. The name of field to be plotted into the quiver. This will be the key of set_of_fields of Network object. field_index_to_plot List of integers, [i, j, k]. For multi-dimensional fields, select 3 components to be displayed in the quiver plot. For example, if the network is attached with vector field [P, Q, R, S] and we are interested to look at the evolution of P, Q, S w.r.t. time, then choose [0, 1, 3]. The indices are zero-based. Default=[0,1,2] field_name_label List of strings [label_X, label_Y, label_Z], each a label for an axis in this three dimensional plot. Default =[“X”,”Y”,”Z”] grid_shape List of integers, X. This is the input of reshape argument to the function tuple_to_grid(grid_lattice_points.,reshape=X). For example, if the grid used is two-dimensional, it can take the shape X=[m,n] for integers m, n. If it is a one-dimensional chain, it can be set to X=[N,1] for integer N or set to None. If set to None, it will be set to [N,1] where N is the length of grid_lattice_points. Default=None time_between_steps_in_ms Integer, number of milliseconds between frame in quiver plot. Default=1 gif_filename String. Name of quiver plot image to be saved. Default=’quiver.gif’ show_real_time Boolean. If True, before saving the image, animation is shown. Default=True view_angle_elevation Float. Elevation angle from which to view three-dimensional quiver plot. Default=90 view_angle_azimuth Float. Azimuth angle from which to view three-dimensional quiver plot. Default=90 xlim List of floats, [xmin, xmax]. The range of x values to be shown in the quiver plot. Default=None ylim List of floats, [ymin, ymax]. The range of y values to be shown in the quiver plot. Default=None zlim List of floats, [zmin, zmax]. The range of z values to be shown in the quiver plot. Default=None arrow_length_scale Float. This is a multiplier to which the lengths of all quiver arrows are multiplied. If set to None, then it is set to 1.0, i.e. the arrow lengths are plotted as they are. Default=None

Example Usage 1

See here. The quiver plot is the following. kero version: 0.5.1 and above

## 1D Interacting Chain 3D Quiver Plot

```+ Tutorial 3:
1. 1D Interacting Chain
2. 1D Interacting Chain 3D Quiver Plot
3. 2D Interacting Grid```

Continuing from the previous tutorial, we start with a chain of ten particles capable of performing action P, Q or R at each time step with probability 0.2, 0.4 and 0.4 respectively. Now we place the probabilities of P, Q and R occurring into a three dimensional vector and see how it evolves over time. Initially, all vectors point in the same direction corresponding to (0.2,0.4,0.4). As network members start to interact and influence each other to perform more P, the vectors will start aligning themselves to (1,0,0) as seen in figure 1. Figure 1. The system starts off with each member having probability vector pointing in (0.2,0.4,0.4) direction and stabilizes at (1,0,0).

Known issue: matplotlib ImageMagick is used to plot the animated gif above. However, there might be issue with accessing ImageMagick. Accessing it through virtual environment, for example, had given us some error.

The code imports peripheral.py from here.

```import numpy as np
from matplotlib import pyplot as plt
from matplotlib import animation
from mpl_toolkits.mplot3d import Axes3D

import kero.multib.nDnet as nd
from peripheral import *

import pickle
f = open("save_folder/test_beta2.pckl","rb")
f.close()
# spt.data={
#   # Save any more data here
#   "N": N, # chain length
#   "mean_over_N": mean_over_N,
#   "interval_mean_history": interval_mean_history,
# }

# network_save_pack={
#   "network" : chain,
#   "processor" : processor,
#   "SAVEPOINT" : spt
# }

chain = network_save_pack["network"]
processor = network_save_pack["processor"]
spt = network_save_pack["SAVEPOINT"]

Tset=processor.Tset
action_history=processor.action_history
action_set = [x for x in processor.action_to_index_map] # ["P","a1","a2"]
action_index_set = [x for x in processor.index_to_action_map] # [0,1,2]
# for a,ai in zip(action_set,action_index_set):
# 	print("(action,index) = (",a,",",ai,")")
field_history = processor.field_history
Tset = processor.Tset
mean_over_N=spt.data["mean_over_N"]
interval_mean_history=spt.data["interval_mean_history"]
N=spt.data["N"]

###############################################
# Probability Quiver
###############################################
fig=plt.figure()

gallery = nd.SpecialGallery()
no_of_steps_to_animate=48
field_name_to_plot="prob"
gallery.quiver3D_lattice3D(
fig,
ax,
no_of_steps_to_animate,
chain.grid_lattice_points,
field_history,
field_name_to_plot,
field_index_to_plot=[0,1,2],
field_name_label=action_set,
grid_shape=[N,1],
time_between_steps_in_ms=100,
gif_filename='save_folder/test_beta2_quiver.gif',
show_real_time=True,
view_angle_elevation=45,
view_angle_azimuth=-60,
# xlim=[-1,4],
# ylim=[-1,4],
# zlim=[-1,4],
arrow_length_scale=0.8,
)
plt.show()```

Simulation is done using kero version: 0.5.1.

## 1D Interacting Chain

```+ Tutorial 3:
1. 1D Interacting Chain
2. 1D Interacting Chain 3D Quiver Plot
3. 2D Interacting Grid```

Simulate and save data

This is a chain of ten particles capable of performing action P, Q or R at each time step with probability 0.2, 0.4 and 0.4 respectively.

Most code is the same as this previous tutorial. However, we now add an interaction between members of network, shown below bolded in blue. If P is performed by a member v, then the neighbors NN(P) will gain the 0.1 probability to perform P in the next step (before normalization). This is done using script testrun_beta_2_PNSAVE.py below.

The plots in figure 1 is similar to the previous tutorial as well, so we do not explain it here. Figure 2. (a) The actions of each member (color-coded) over the past 25 time-steps. Action is either P, Q or R and the plot shows their action indices 0, 1 and 2 respectively. (b) The ratio of the number of actions to total number of actions over the last 25 steps. Each value at a time-step is the mean number of actions over the last 100 steps. This ratio is plotted over time. Only member “1” and “2” are shown. (c) The network in the form of 1D chain, where each label is the name of the member. Color intensity denotes the probability that the action P is performed (action index = 0).

This is done using testrun_beta_2_LOADNPLOT.py below.

In the next part, we will plot 3D animated gif to visualize the evolving system.

The codes import peripheral.py from here.

testrun_beta_2_PNSAVE.py

```import kero.multib.nDnet as nd
import matplotlib.pyplot as plt
from peripheral import *

# 2018 Oct 14 Erico Tjoa

# --------------------------------------------------------
# 1. Set up system
# --------------------------------------------------------
N=10
chain=nd.Network()
chain.build_1D_chain(N)

import os
if not os.path.exists("save_folder"):
os.mkdir("save_folder")
def attach_a_probability_vector_field():
chain.set_of_fields["prob"] = {}
action_set = ["P","Q","R"]
action_index_set = [0,1,2]
action_probability_set = [0.2,0.4,0.4]
for v in chain.member_set:
chain.set_of_fields["prob"][v] = [action_set,action_probability_set]
return action_set, action_index_set # 6.

action_set, action_index_set=attach_a_probability_vector_field()
# print(chain.set_of_fields["prob"])

# --------------------------------------------------------
# 2. Run Simulation
# --------------------------------------------------------
start1 = time.time()
Tset=range(100) # Simulation length
action_history = {}
field_history = []

field_now={}
field_now["prob"]={}
for v in chain.member_set:
field_now["prob"][v]=chain.set_of_fields["prob"][v][:]
field_history.append(field_now)

for v in chain.member_set:
action_history[v]=[]
for t in Tset: # : #
for v in chain.member_set:
this_action_set = chain.set_of_fields["prob"][v][:] # eg [a1,a2]
this_probability_set = chain.set_of_fields["prob"][v][:] # eg [0.5,0.5]
action,action_index = nd.choose_action_continuous_probability(this_action_set, this_probability_set, N=1)
action_history[v].append([action_index,action])
# ---------------------------------------
# Add interaction in this region
# ---------------------------------------
for v in chain.member_set:
a_set = action_history[v][-1]
neighbors = chain.member_set[v]
if a_set=="P":
for k in neighbors:
temp = chain.set_of_fields["prob"][k][:]
temp = temp + 0.1
if temp>1:
temp = 1
sigma_temp = sum(temp)
chain.set_of_fields["prob"][k] = [x/sigma_temp for x in temp]
# ---------------------------------------
# Store evolved field state
# ---------------------------------------
field_now={}
field_now["prob"]={}
for v in chain.member_set:
field_now["prob"][v]=chain.set_of_fields["prob"][v][:]
field_history.append(field_now)
# print(field_now)
time_keeper("Simulation",start1)

processor=nd.Network_processor()
processor.map_action_index(action_set,action_index_set)
mean_over_N=100

start2 = time.time()
interval_mean_history=processor.compute_interval_mean(mean_over_N=mean_over_N)
time_keeper("Processor",start2)

# --------------------------------------------------------
# 3. Save State
# --------------------------------------------------------
import pickle
spt = nd.SAVE_POINT()
spt.data={
# Save any more data here
"N": N, # chain length
"mean_over_N": mean_over_N,
"interval_mean_history": interval_mean_history,
}

network_save_pack={
"network" : chain,
"processor" : processor,
"SAVEPOINT" : spt
}

f = open("save_folder/test_beta2.pckl","wb")
pickle.dump(network_save_pack,f)
f.close()```

```import kero.multib.nDnet as nd
import matplotlib.pyplot as plt
from peripheral import *

import pickle
f = open("save_folder/test_beta2.pckl","rb")
f.close()
# spt.data={
# 	# Save any more data here
# 	"N": N, # chain length
# 	"mean_over_N": mean_over_N,
# 	"interval_mean_history": interval_mean_history,
# }

# network_save_pack={
# 	"network" : chain,
# 	"processor" : processor,
# 	"SAVEPOINT" : spt
# }

chain = network_save_pack["network"]
processor = network_save_pack["processor"]
spt = network_save_pack["SAVEPOINT"]

Tset=processor.Tset
action_history=processor.action_history
action_set = [x for x in processor.action_to_index_map]
action_index_set = [x for x in processor.index_to_action_map]
# for a,ai in zip(action_set,action_index_set):
# 	print("(action,index) = (",a,",",ai,")")
field_history = processor.field_history
mean_over_N=spt.data["mean_over_N"]
interval_mean_history=spt.data["interval_mean_history"]

fig=plt.figure()

# --------------------------------------------------------
# --------------------------------------------------------
start2=time.time()
processor.plot_action_over_time(
ax2,
plot_interval=(len(Tset)-24,None),
title="Action-time",
)
time_keeper("Action-time",start2)

# --------------------------------------------------------
# --------------------------------------------------------
start3=time.time()
member_set_to_display= ["1","2"] # chain.member_set #
action_index_set_to_display=action_index_set # [0,1] #

processor.plot_interval_mean_over_time(
ax3,
interval_mean_history,
member_set_to_display,
action_index_set_to_display,
plotting_interval= (1,None), # (1,None)
plotting_interval_step_length=1,
title="Mean over last " + str(mean_over_N) +" steps"
)
time_keeper("Mean-time",start3)

# --------------------------------------------------------
# --------------------------------------------------------
start4=time.time()
action_index_to_display=0
time_step=None
interval_mean_at_t=processor.extract_interval_mean_at_a_time_step(interval_mean_history,time_step=time_step)
# print("interval_mean_at_t:\n",interval_mean_at_t)
CS=[interval_mean_at_t[action_index_to_display][v] for v in interval_mean_at_t[action_index_to_display]]
# print(CS)
chain.visualize_3D_graph(ax,color_set=CS,
this_figure=fig,
no_of_points_per_edge=4,
title="2D chain: act="+str(action_index_to_display),
cmap=plt.cm.hot
)
time_keeper("Graph",start4)

plt.show()```

Simulation is done using kero version: 0.5.1.

## Load 1D Chain and Plot

```+ Tutorial 2:
1. Initiate and Save 1D Chain
2. Load 1D Chain and Plot```

Load all the data simulated from part 1, and plot them in figure 1.As expected, mean number of action P tends to 0.75 and Q 0.25. These values as they appear in figure 1(b) will be closer to 0.75 and 0.25 if the simulation is run over longer period.

Figure 1(b) only shows the plot for members “1” and “2”. To show other members, adjust the variable member_set_to_display.

Figure 1(c) shows the probability for action Q. If we want to show the plot for action P, adjust the variable action_index_to_display=0, pointing to the action index of P. Figure 1. (a) The actions of each member (color-coded) over the past 25 time-steps. Action is either P or Q, and the plot shows their action indices 0 and 1 respectively. (b) The ratio of the number of actions to total number of actions over the last 20 steps. This ratio is plotted over time. (c) The network in the form of 1D chain, where each label is the name of the member. Color intensity denotes the probability that the action Q is performed (action index = 1).

The code imports peripheral.py from here.

```import kero.multib.nDnet as nd
import matplotlib.pyplot as plt
from peripheral import *

import pickle
f = open("save_folder/test_beta1.pckl","rb")
f.close()
# spt.data={
# 	# Save any more data here
# 	"N": N, # chain length
# 	"mean_over_N": mean_over_N,
# 	"interval_mean_history": interval_mean_history,
# }

# network_save_pack={
# 	"network" : chain,
# 	"processor" : processor,
# 	"SAVEPOINT" : spt
# }

chain = network_save_pack["network"]
processor = network_save_pack["processor"]
spt = network_save_pack["SAVEPOINT"]

Tset=processor.Tset
action_history=processor.action_history
action_set = [x for x in processor.action_to_index_map]
action_index_set = [x for x in processor.index_to_action_map]
# for a,ai in zip(action_set,action_index_set):
# 	print("(action,index) = (",a,",",ai,")")
field_history = processor.field_history
mean_over_N=spt.data["mean_over_N"]
interval_mean_history=spt.data["interval_mean_history"]

fig=plt.figure()

# --------------------------------------------------------
# --------------------------------------------------------
start2=time.time()
processor.plot_action_over_time(
ax2,
plot_interval=(len(Tset)-24,None),
title="Action-time",
)
time_keeper("Action-time",start2)

# --------------------------------------------------------
# --------------------------------------------------------
start3=time.time()
member_set_to_display= ["1","2"] # chain.member_set #
action_index_set_to_display=action_index_set # [0,1] #

processor.plot_interval_mean_over_time(
ax3,
interval_mean_history,
member_set_to_display,
action_index_set_to_display,
plotting_interval= (1,None), # (1,None)
plotting_interval_step_length=1,
title="Mean over last " + str(mean_over_N) +" steps"
)
time_keeper("Mean-time",start3)

# --------------------------------------------------------
# --------------------------------------------------------
start4=time.time()
action_index_to_display=1
time_step=None
interval_mean_at_t=processor.extract_interval_mean_at_a_time_step(interval_mean_history,time_step=time_step)
# print("interval_mean_at_t:\n",interval_mean_at_t)
CS=[interval_mean_at_t[action_index_to_display][v] for v in interval_mean_at_t[action_index_to_display]]
# import numpy as np
# print(CS)
# print("shape=",np.array(CS).shape, " / len = ",len(CS))
chain.visualize_3D_graph(ax,color_set=CS,
this_figure=fig,
no_of_points_per_edge=4,
title="1D chain: act="+str(action_index_to_display),
cmap=plt.cm.spring
)
time_keeper("Graph",start4)

plt.show()```

Simulation is done using kero version: 0.5.1.