# 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

Run the script testrun_beta_3_LOADNPLOT.py. 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.