<jupyter_start><jupyter_text>Experiment: CohesionTo goal of cohesion is to maintain a cohesive collective whose network structure is neither too dense nor too sparse.<jupyter_code>%load_ext autoreload
%autoreload 2
%matplotlib notebook
import numpy as np
import matplotlib.pyplot as plt

from math import sqrt
from math import ceil

from matplotlib import rc
from IPython.display import HTML
import matplotlib.animation as animation

import math
import numpy as np
from interaction import Interaction
from environment import Environment
from fish import Fish
from channel import Channel
from observer import Observer
import pandas as pd

from scipy.spatial import distance
from utils import generate_distortion, generate_fish, run_simulation
#plt.rcParams['animation.ffmpeg_path'] = '/usr/local/bin/ffmpeg'<jupyter_output><empty_output><jupyter_text>Player File ImplementationThis file was obtained from stack overflow by theImportanceOfBeingEarnest<jupyter_code>import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import mpl_toolkits.axes_grid1
import matplotlib.widgets
#This file was originally published by ImportanceofBeingErnest in Stack Overflow

class Player(FuncAnimation):
    def __init__(self, fig, func, frames=None, init_func=None, fargs=None,
                 save_count=None, mini=0, maxi=100, pos=(0.125, 0.92), **kwargs):
        self.i = 0
        self.min=mini
        self.max=maxi
        self.runs = True
        self.forwards = True
        self.fig = fig
        self.func = func
        self.setup(pos)
        FuncAnimation.__init__(self,self.fig, self.func, frames=self.play(), 
                                           init_func=init_func, fargs=fargs,
                                           save_count=save_count, **kwargs )    

    def play(self):
        while self.runs:
            self.i = self.i+self.forwards-(not self.forwards)
            if self.i > self.min and self.i < self.max:
                yield self.i
            else:
                self.stop()
                yield self.i

    def start(self):
        self.runs=True
        self.event_source.start()

    def stop(self, event=None):
        self.runs = False
        self.event_source.stop()

    def forward(self, event=None):
        self.forwards = True
        self.start()
    def backward(self, event=None):
        self.forwards = False
        self.start()
    def oneforward(self, event=None):
        self.forwards = True
        self.onestep()
    def onebackward(self, event=None):
        self.forwards = False
        self.onestep()

    def onestep(self):
        if self.i > self.min and self.i < self.max:
            self.i = self.i+self.forwards-(not self.forwards)
        elif self.i == self.min and self.forwards:
            self.i+=1
        elif self.i == self.max and not self.forwards:
            self.i-=1
        self.func(self.i)
        self.fig.canvas.draw_idle()

    def setup(self, pos):
        playerax = self.fig.add_axes([pos[0],pos[1], 0.22, 0.04])
        divider = mpl_toolkits.axes_grid1.make_axes_locatable(playerax)
        bax = divider.append_axes("right", size="80%", pad=0.05)
        sax = divider.append_axes("right", size="80%", pad=0.05)
        fax = divider.append_axes("right", size="80%", pad=0.05)
        ofax = divider.append_axes("right", size="100%", pad=0.05)
        self.button_oneback = matplotlib.widgets.Button(playerax, label=u'\u29CF')
        self.button_back = matplotlib.widgets.Button(bax, label=u'$\u25C0$')
        self.button_stop = matplotlib.widgets.Button(sax, label=u'$\u25A0$')
        self.button_forward = matplotlib.widgets.Button(fax, label=u'$\u25B6$')
        self.button_oneforward = matplotlib.widgets.Button(ofax, label=u'$\u29D0$')
        self.button_oneback.on_clicked(self.onebackward)
        self.button_back.on_clicked(self.backward)
        self.button_stop.on_clicked(self.stop)
        self.button_forward.on_clicked(self.forward)
        self.button_oneforward.on_clicked(self.oneforward)

### using this class is as easy as using FuncAnimation:            

colors = [
    [230/255, 25/255, 75/255, 1.0],
    [60/255, 180/255, 75/255, 1.0],
    [255/255, 225/255, 25/255, 1.0],
    [0/255, 130/255, 200/255, 1.0],
    [245/255, 130/255, 48/255, 1.0],
    [145/255, 30/255, 180/255, 1.0],
    [70/255, 240/255, 240/255, 1.0],
    [240/255, 50/255, 230/255, 1.0],
    [210/255, 245/255, 60/255, 1.0],
    [250/255, 190/255, 190/255, 1.0],
    [0/255, 128/255, 128/255, 1.0],
    [230/255, 190/255, 255/255, 1.0],
    [170/255, 110/255, 40/255, 1.0],
    [255/255, 250/255, 200/255, 1.0],
    [128/255, 0/255, 0/255, 1.0],
    [170/255, 255/255, 195/255, 1.0],
    [128/255, 128/255, 0/255, 1.0],
    [255/255, 215/255, 180/255, 1.0],
    [0/255, 0/255, 128/255, 1.0],
    [128/255, 128/255, 128/255, 1.0],
    [0/255, 0/255, 0/255, 1.0],
]<jupyter_output><empty_output><jupyter_text>Initialize fish to for Local Triangle FormationAll robots start in the same place and have too many neighbors. They disperse to decrease their number of neighbors.<jupyter_code>num_fish = 15
arena_size = [30,30]
arena_center = arena_size[0]/2
initial_spread = 15
fish_pos = np.zeros((num_fish,2))
fish_pos[:,0] = np.random.rand(num_fish)*(arena_size[0]/2)
fish_pos[:,1] = np.random.rand(num_fish)*(arena_size[0]/2)
run_time =20
clock_freqs = 1
verbose = False
orientation = [0,1]
distortion = generate_distortion(type='none', n=arena_size[0])
environment = Environment(
    node_pos=fish_pos,
    arena_size = arena_size,
    distortion=distortion,
    prob_type='binary', 
    noise_magnitude=0,
    conn_thres=30,
    verbose=verbose
)
interaction = Interaction(environment, verbose=verbose)
channel = Channel(environment)
formation_num = 0
fish = generate_fish(
    n=num_fish, 
    channel=channel, 
    orientation = orientation, 
    tolerance = .1,
    formation_num = formation_num, 
    fish_total_error =0,
    interaction=interaction, 
    lim_neighbors=[0,30],
    neighbor_weights=1.0,
    fish_max_speeds=1,
    clock_freqs=clock_freqs,
    verbose=verbose
)
total_error =[]
channel.set_nodes(fish) 
observer = Observer(fish=fish, environment=environment, channel=channel)
run_simulation(fish=fish, observer=observer, run_time=run_time, dark=True, white_axis=False, no_legend=True)

fig = plt.figure()
ax = plt.axes(xlim=(0, 30), ylim=(0,30))
ax.set_facecolor('black')
ax.set_xlabel('x')
ax.set_ylabel('y')
N = observer.num_nodes
#fish = ax.plot( *([[], []]*N), marker=">",markersize =15,alpha = 1)
fish_pos1 = ax.plot( *([[], []]*N), linewidth=1, linestyle = (0, (5, 1)))
fish_pos2 = ax.plot( *([[], []]*N),marker='>')
fish_pos3 = ax.plot( *([[], []]*N),marker='o')  
fish_pos4 = ax.plot( *([[], []]*N),marker='o')
#texts = [ax.text(0.80, 0.95-i*0.05,  '', transform=ax.transAxes) for i in range(N)]

def init():
    print("Initialized")
    for idx,line in enumerate(fish_pos1):
        line.set_data([], [])
        line.set_color(colors[idx])
    for idx,line in enumerate(fish_pos2):
        line.set_data([], [])
        line.set_color(colors[idx])
    for idx,line in enumerate(fish_pos3):
        line.set_data([], [])
        line.set_color(colors[idx])
    return fish_pos1,fish_pos2,fish_pos3


def animate(i):
    for j in range(N): 
        print(j)
        fish_pos1[j].set_data(observer.x[j][:i],observer.y[j][:i])
        fish_pos2[j].set_data(observer.x[j][0],observer.y[j][0])
        fish_pos3[j].set_data(observer.x[j][i-1],observer.y[j][i-1])
    return fish_pos1,fish_pos2, fish_pos3

anim = Player(fig, animate, init_func=init,
                       frames=20, interval=100, blit=True)
#Writer = animation.writers['ffmpeg']
#writer = Writer(fps=5, metadata=dict(artist='Me'))
#anim.save('local_static.mp4', writer=writer)
plt.show()  


def run_trials_switch(tolerance_range, k):
    fig, axes = plt.subplots(2, 1, constrained_layout=True)
    top_ax, bottom_ax = axes
    #Map Formation #1
    for e in tolerance_range:
        total_error =np.zeros(30)
        for i in range(k):
            run_time = 17# in seconds
            num_fish = 15
            arena_size = [30,30]
            arena_center = arena_size[0]/2
            initial_spread = 15
            fish_pos = np.zeros((num_fish,2))
            fish_pos[:,0] = np.random.rand(num_fish)*(arena_size[0]/2)
            fish_pos[:,1] = np.random.rand(num_fish)*(arena_size[0]/2)
            clock_freqs = 1
            verbose = False
            orientation = [1,0]
            distortion = generate_distortion(type='none', n=arena_size[0])
            environment = Environment(
                node_pos=fish_pos,
                arena_size = arena_size,
                distortion=distortion,
                prob_type='binary', 
                noise_magnitude=0,
                conn_thres=30,
                verbose=verbose
            )
            interaction = Interaction(environment, verbose=verbose)
            channel = Channel(environment)
            formation_num = 2
            fish = generate_fish(
                n=num_fish, 
                channel=channel, 
                orientation = orientation, 
                tolerance = e,
                formation_num = formation_num, 
                fish_total_error = 10,
                interaction=interaction, 
                lim_neighbors=[0,30],
                neighbor_weights=1.0,
                fish_max_speeds=1,
                clock_freqs=clock_freqs,
                verbose=verbose
            )
            channel.set_nodes(fish) 
            observer = Observer(fish=fish, environment=environment, channel=channel)
            run_simulation(fish=fish, observer=observer, run_time=run_time, dark=True, white_axis=False, no_legend=True)
            total_error= observer.total_error[2:]
            #Get current positions from observer and generate a new batch of fish 
            new_fish_pos = []
            new_fish_pos.append([[x[run_time-1],y[run_time-1]] for x,y in zip(observer.x,observer.y)])
            new_fish_pos = np.array(new_fish_pos[0])
            run_time = 17# in seconds
            num_fish = 15
            arena_size = [30,30]
            initial_spread = 15
            arena_size = [30,30]
            arena_center = arena_size[0]/2
            clock_freqs = 1
            verbose = False
            orientation = [1,0]
            distortion = generate_distortion(type='none', n=arena_size[0])
            environment = Environment(
                node_pos=new_fish_pos,
                arena_size = arena_size,
                distortion=distortion,
                prob_type='binary', 
                noise_magnitude=0,
                conn_thres=30,
                verbose=verbose
            )
            interaction = Interaction(environment, verbose=verbose)
            channel = Channel(environment)
            formation_num = 3
            fish = generate_fish(
                n=num_fish, 
                channel=channel, 
                orientation = orientation, 
                tolerance = e,
                formation_num = formation_num, 
                fish_total_error = 10,
                interaction=interaction, 
                lim_neighbors=[0,30],
                neighbor_weights=1.0,
                fish_max_speeds=1,
                clock_freqs=clock_freqs,
                verbose=verbose
            )
            channel.set_nodes(fish) 
            observer = Observer(fish=fish, environment=environment, channel=channel)
            run_simulation(fish=fish, observer=observer, run_time=run_time, dark=True, white_axis=False, no_legend=True)
            total_error = np.append(total_error,observer.total_error[2:])
        top_ax.plot(np.divide(total_error, len(tolerance_range)), color = colors[tolerance_range.index(e)])
        top_ax.scatter(np.arange(0,len(total_error)),np.divide(total_error, len(tolerance_range)), label=e,color = colors[tolerance_range.index(e)])
        top_ax.legend()
        for e in tolerance_range:
            total_error =np.zeros(30)
            for i in range(k):
                run_time = 17# in seconds
                num_fish = 15
                arena_size = [30,30]
                arena_center = arena_size[0]/2
                initial_spread = 15
                fish_pos = np.zeros((num_fish,2))
                fish_pos[:,0] = np.random.rand(num_fish)*(arena_size[0]/2)
                fish_pos[:,1] = np.random.rand(num_fish)*(arena_size[0]/2)
                clock_freqs = 1
                verbose = False
                orientation = [1,0]
                distortion = generate_distortion(type='none', n=arena_size[0])
                environment = Environment(
                    node_pos=fish_pos,
                    arena_size = arena_size,
                    distortion=distortion,
                    prob_type='binary', 
                    noise_magnitude=0,
                    conn_thres=30,
                    verbose=verbose
                )
                interaction = Interaction(environment, verbose=verbose)
                channel = Channel(environment)
                formation_num = 3
                fish = generate_fish(
                    n=num_fish, 
                    channel=channel, 
                    orientation = orientation, 
                    tolerance = e,
                    formation_num = formation_num, 
                    fish_total_error = 10,
                    interaction=interaction, 
                    lim_neighbors=[0,30],
                    neighbor_weights=1.0,
                    fish_max_speeds=1,
                    clock_freqs=clock_freqs,
                    verbose=verbose
                )
                channel.set_nodes(fish) 
                observer = Observer(fish=fish, environment=environment, channel=channel)
                run_simulation(fish=fish, observer=observer, run_time=run_time, dark=True, white_axis=False, no_legend=True)
                total_error= observer.total_error[2:]
                #Get current positions from observer and generate a new batch of fish 
                new_fish_pos = []
                new_fish_pos.append([[x[run_time-1],y[run_time-1]] for x,y in zip(observer.x,observer.y)])
                new_fish_pos = np.array(new_fish_pos[0])
                run_time = 17# in seconds
                num_fish = 15
                arena_size = [30,30]
                initial_spread = 15
                arena_size = [30,30]
                arena_center = arena_size[0]/2
                clock_freqs = 1
                verbose = False
                orientation = [1,0]
                distortion = generate_distortion(type='none', n=arena_size[0])
                environment = Environment(
                    node_pos=new_fish_pos,
                    arena_size = arena_size,
                    distortion=distortion,
                    prob_type='binary', 
                    noise_magnitude=0,
                    conn_thres=30,
                    verbose=verbose
                )
                interaction = Interaction(environment, verbose=verbose)
                channel = Channel(environment)
                formation_num = 2
                fish = generate_fish(
                    n=num_fish, 
                    channel=channel, 
                    orientation = orientation, 
                    tolerance = e,
                    formation_num = formation_num, 
                    fish_total_error = 10,
                    interaction=interaction, 
                    lim_neighbors=[0,30],
                    neighbor_weights=1.0,
                    fish_max_speeds=1,
                    clock_freqs=clock_freqs,
                    verbose=verbose
                )
                channel.set_nodes(fish) 
                observer = Observer(fish=fish, environment=environment, channel=channel)
                run_simulation(fish=fish, observer=observer, run_time=run_time, dark=True, white_axis=False, no_legend=True)
                total_error = np.append(total_error,observer.total_error[2:])
            bottom_ax.plot(np.divide(total_error, len(tolerance_range)), color = colors[tolerance_range.index(e)])
            bottom_ax.scatter(np.arange(0,len(total_error)),np.divide(total_error, len(tolerance_range)), label=e,color = colors[tolerance_range.index(e)])
            bottom_ax.legend()
    
    #top_ax.set_title('Fitness Level Triangle Formation')
    top_ax.set_xlabel('Time Step (seconds)')
    top_ax.set_ylabel('Fitness Level')
    #middle_ax.set_title('Fitness Level Trigonal Planar Formation')
    #bottom_ax.set_title('Fitness Level Triangle to Trigonal Planar Formation')
    bottom_ax.set_xlabel('Time Step (seconds)')
    bottom_ax.set_ylabel('Fitness Level')
    plt.show()
    plt.savefig("global_switch.png")

def run_trials(tolerance_range, k):
    fig, axes = plt.subplots(2, 1, constrained_layout=True)
    top_ax, middle_ax = axes
    min_e = 0
    max_e =0
    #Map Formation #1
    for e in tolerance_range:
        total_error =np.zeros(30)
        for i in range(k):
            run_time = 33# in seconds
            num_fish = 15
            arena_size = [30,30]
            arena_center = arena_size[0]/2
            initial_spread = 15
            fish_pos = np.zeros((num_fish,2))
            fish_pos[:,0] = np.random.rand(num_fish)*(arena_size[0]/2)
            fish_pos[:,1] = np.random.rand(num_fish)*(arena_size[0]/2)
            clock_freqs = 1
            verbose = False
            orientation = [1,0]
            distortion = generate_distortion(type='none', n=arena_size[0])
            environment = Environment(
                node_pos=fish_pos,
                arena_size = arena_size,
                distortion=distortion,
                prob_type='binary', 
                noise_magnitude=0,
                conn_thres=30,
                verbose=verbose
            )
            interaction = Interaction(environment, verbose=verbose)
            channel = Channel(environment)
            formation_num = 1
            fish = generate_fish(
                n=num_fish, 
                channel=channel, 
                orientation = orientation, 
                tolerance = e,
                formation_num = formation_num, 
                fish_total_error = 10,
                interaction=interaction, 
                lim_neighbors=[0,30],
                neighbor_weights=1.0,
                fish_max_speeds=1,
                clock_freqs=clock_freqs,
                verbose=verbose
            )
            channel.set_nodes(fish) 
            observer = Observer(fish=fish, environment=environment, channel=channel)
            run_simulation(fish=fish, observer=observer, run_time=run_time, dark=True, white_axis=False, no_legend=True)
            if(np.sum(total_error)>0):
                print(len(observer.total_error))
                total_error = np.add(observer.total_error[-30:],total_error)
            else:
                total_error = observer.total_error[-30:]
        top_ax.plot(np.divide(total_error, len(tolerance_range)), color = colors[tolerance_range.index(e)])
        top_ax.scatter(np.arange(0,len(total_error)),np.divide(total_error, len(tolerance_range)), label=e,color = colors[tolerance_range.index(e)])
        top_ax.legend()
    print('top_done')
    #Map Formation #2
    for e in tolerance_range:
        total_error =np.zeros(30)
        for i in range(k):
            run_time = 33# in seconds
            num_fish = 15
            arena_size = [30,30]
            arena_center = arena_size[0]/2
            initial_spread = 15
            fish_pos = np.zeros((num_fish,2))
            fish_pos[:,0] = np.random.rand(num_fish)*(arena_size[0]/2)
            fish_pos[:,1] = np.random.rand(num_fish)*(arena_size[0]/2)
            clock_freqs = 1
            verbose = False
            orientation = [1,0]
            distortion = generate_distortion(type='none', n=arena_size[0])
            environment = Environment(
                node_pos=fish_pos,
                arena_size = arena_size,
                distortion=distortion,
                prob_type='binary', 
                noise_magnitude=0,
                conn_thres=30,
                verbose=verbose
            )
            interaction = Interaction(environment, verbose=verbose)
            channel = Channel(environment)
            formation_num = 0
            fish = generate_fish(
                n=num_fish, 
                channel=channel, 
                orientation = orientation, 
                tolerance = e,
                formation_num = formation_num, 
                fish_total_error = 10,
                interaction=interaction, 
                lim_neighbors=[0,30],
                neighbor_weights=1.0,
                fish_max_speeds=1,
                clock_freqs=clock_freqs,
                verbose=verbose
            )
            channel.set_nodes(fish) 
            observer = Observer(fish=fish, environment=environment, channel=channel)
            run_simulation(fish=fish, observer=observer, run_time=run_time, dark=True, white_axis=False, no_legend=True)
            if(np.sum(total_error)>0):
                total_error = np.add(observer.total_error[-30:],total_error)
            else:
                total_error = observer.total_error[-30:]
        middle_ax.plot(np.divide(total_error, len(tolerance_range)), color = colors[tolerance_range.index(e)])
        middle_ax.scatter(np.arange(0,len(total_error)),np.divide(total_error, len(tolerance_range)), label=e,color = colors[tolerance_range.index(e)])
        middle_ax.legend()
        print('middle_done')
    
    #top_ax.set_title('Fitness Level Triangle Formation')
    top_ax.set_xlabel('Time Step (seconds)')
    top_ax.set_ylabel('Fitness Level')
    #middle_ax.set_title('Fitness Level Trigonal Planar Formation')
    middle_ax.set_xlabel('Time Step (seconds)')
    middle_ax.set_ylabel('Fitness Level')
    plt.show()
    plt.savefig('local_statics2.png')
run_trials([0.1,0.3,0.5,0.7, 0.9], 1)
import numpy as np
run_trials([0.25], 1)
a= [0,1,2] 
b =[0,1,2] 
np.add(a,b)
linespace= 2
x_target = linespace*np.sin(np.deg2rad(120))
y_target = linespace*np.cos(np.deg2rad(120))
v1 = [0,1]
v2 = [-1,-1]
v1_u = v1 / np.linalg.norm(v1)
v2_u = v2 / np.linalg.norm(v2)
np.arccos(np.clip(np.dot(v1_u, v2_u), -1.0, 1.0))* 180 / np.pi<jupyter_output><empty_output><jupyter_text>Initialize  Fish Fibonacci GlobalAll robots start in the same place and have too many neighbors. They disperse to decrease their number of neighbors.<jupyter_code>from events import Move
run_time = 18# in seconds
num_fish = 10
arena_size = [30,30]
arena_center = arena_size[0]/2
initial_spread = 15
fish_pos = np.zeros((num_fish,2))
fish_pos[:,0] = np.random.rand(num_fish)*(arena_size[0]/2)
fish_pos[:,1] = np.random.rand(num_fish)*(arena_size[0]/2)

clock_freqs = 1
verbose = False
orientation = [1,1]
distortion = generate_distortion(type='none', n=arena_size[0])
environment = Environment(
    node_pos=fish_pos,
    arena_size = arena_size,
    distortion=distortion,
    prob_type='binary', 
    noise_magnitude=0,
    conn_thres=30,
    verbose=verbose
)
interaction = Interaction(environment, verbose=verbose)
channel = Channel(environment)
formation_num = 3
fish = generate_fish(
    n=num_fish, 
    channel=channel, 
    orientation = orientation, 
    tolerance = 
    formation_num = formation_num, 
    interaction=interaction, 
    lim_neighbors=[2,15],
    neighbor_weights=1.0,
    fish_max_speeds=1,
    clock_freqs=clock_freqs,
    verbose=verbose
)
channel.set_nodes(fish) 
migrate = Move(1,0)
observer = Observer(fish=fish, environment=environment, channel=channel)
#observer.instruct(event=migrate, rel_clock=0, fish_all=True)
run_simulation(fish=fish, observer=observer, run_time=run_time, dark=True, white_axis=False, no_legend=True)

plt.ion()
plt.clf()
fig = plt.figure(10)
ax = plt.axes(xlim=(0, 30), ylim=(0,30))
ax.set_facecolor('black')
ax.set_xlabel('x')
ax.set_ylabel('y')
N = observer.num_nodes
#fish = ax.plot( *([[], []]*N), marker=">",markersize =15,alpha = 1)
fish_pos1 = ax.plot( *([[], []]*N), linewidth=1, linestyle = (0, (5, 1)))
fish_pos2 = ax.plot( *([[], []]*N),marker='>')
fish_pos3 = ax.plot( *([[], []]*N),marker='o')  
fish_pos4 = ax.plot( *([[], []]*N),marker='o')
texts = [ax.text(0.80, 0.95-i*0.05,  '', transform=ax.transAxes) for i in range(N)]

def init():    
    for idx,line in enumerate(fish_pos1):
        line.set_data([], [])
        line.set_color(colors[idx])
    for idx,line in enumerate(fish_pos2):
        line.set_data([], [])
        line.set_color(colors[idx])
    for idx,line in enumerate(fish_pos3):
        line.set_data([], [])
        line.set_color(colors[idx])
    for line in fish_pos4:
        line.set_data([], [])
        line.set_color(colors[idx])
    return fish_pos1,fish_pos2,fish_pos3


def animate(i):
    for j in range(N): 
        fish_pos1[j].set_data(observer.x[j][:i],observer.y[j][:i])
        fish_pos2[j].set_data(observer.x[j][0],observer.y[j][0])
        fish_pos3[j].set_data(observer.x[j][i-1],observer.y[j][i-1])
        #texts[j].set_text(observer.fish[j].id)
    return fish_pos1,fish_pos2, fish_pos3

anim = Player(fig, animate, init_func=init,
                       frames=20, interval=1, blit=False)
#Writer = animation.writers['ffmpeg']
#writer = Writer(fps=1, metadata=dict(artist='Me'), bitrate=1800)
#anim.save('fibo_line.mp4', writer=writer)
plt.show()
#print(observer.c[0])
def F(i):
        return ((1+sqrt(5))**i-(1-sqrt(5))**i)/(2**i*sqrt(5))
def get_row_n(front_neighbors):
    my_index = front_neighbors+1
    f_i =0
    i =0
    while(f_i<my_index):
        f_i = F(i)
        i+=1
    return my_index-1, i-3,np.round(F(i-2)), np.round(F(i-1))


V4= [1,1]
V5 = [1,0]
np.dot(V4,V5)

def fibonacci_formation(nfish,linespace):
    columns = ['X', 'Y', 'dist']
    index= np.arange(nfish)
    df= pd.DataFrame(index=index, columns=columns)
    df= df.fillna(0.0)
    #print(df)
    for i,row in df.iterrows():
        my_index, my_row, rs, re = get_row_n(i)
        if(my_row<=0):
            my_index =0
            my_row =0
        if(my_index in [0,1,2]):
            df.iloc[i]['X'] = my_row*linespace
            df.iloc[i]['dist'] = my_index
            df.iloc[i]['Y'] = 0

        else:
            df.iloc[i]['X'] = my_row*linespace
            df.iloc[i]['dist'] = my_index
            if(re-rs ==2):
                if(my_index==3):
                    df.iloc[i]['Y'] =-.5
                else:
                    df.iloc[i]['Y'] =.5
            elif((re-rs)%2==0):
                ys = np.linspace(-(re-rs)/2,int(re-rs)/2,int(re-rs))
                df.iloc[i]['Y'] = ys[int(my_index -rs)]
            else:
                df.iloc[i]['Y'] = ceil((re-rs)/2) - (re-my_index)
    return df
df = fibonacci_formation(21,1)
print(df)
fig = plt.figure(2)
plt.scatter(-df['X'], df['Y'])
plt.show()
def define_target(rel_pos,target_map):
    target_map['X'] += my_leader_x
    target_map['Y'] += my_leader_y
    target_map['dist'] = np.sqrt( (target_map.X)**2 + (target_map.Y)**2)
    target_map = target_map.sort_values(['dist'],ascending =True)
    
    while(len(target_map)>0):
        my_target = [target_map.iloc[0]['X'],target_map.iloc[0]['Y']]
        my_dist = np.sqrt((my_target[0])**2 + (my_target[1])**2)
        df = pd.DataFrame.from_dict(rel_pos,orient = 'index', columns=['X', 'Y'])
        df['dist'] = np.sqrt( (df.X-my_target[0])**2 + (df.Y-my_target[1])**2)
        rel_pos = df.sort_values(['dist'],ascending =True)
        if(rel_pos.iloc[0]['dist']>=my_dist):
            return my_target
        else:
            target_map.drop(target_map.index[0]) 
    return my_target

print(df)
fig = plt.figure(4)
plt.scatter(-df['X'], df['Y'])
plt.show()
def generate_map(n_fish,map_type,linespace):
    if(map_type==0):
        df = fibonacci_formation(n_fish,linespace)
            
    elif(map_type==1):
        df = triangle_formation(n_fish,linespace)
    return df
def triangle_formation(nfish,linespace):
    columns = ['X', 'Y', 'dist']
    index= np.arange(nfish)
    df= pd.DataFrame(index=index, columns=columns)
    df= df.fillna(0.0)
    for i,row in df.iterrows():
        my_index, my_row, rs, re = get_row_n2(i)
        df.iloc[i]['X'] = my_row*linespace
        df.iloc[i]['dist'] = my_index
        if(re-rs>0):
            ys = np.linspace(-(re-rs)/2,(re-rs)/2,int(re-rs)+1)
            df.iloc[i]['Y'] = ys[int(my_index-rs)]
    df['X'] = -df['X'] 
    df['X'] += my_row
    return df
df = triangle_formation(15,1)


fig = plt.figure(3)
plt.scatter(df['X'], df['Y'])
plt.show()
def T(i):
     return i*(i+1)/2<jupyter_output><empty_output><jupyter_text>df = pd.DataFrame([[-4,6],[-2,2],[-2,]], columns = ['x','y'])<jupyter_code>orientation = [0,1]
df = pd.DataFrame([[-4,7],[30,-30],[-2,1]], columns = ['x','y'])
df['cross'] = 0
for i,row in df.iterrows():
    row['cross'] = np.cross([row.x-orientation[0],row.x-orientation[1]], np.negative(orientation))
nr = df[df['cross']>0]
print(nr)
M =np.add([2,2],[4,2])/2
n = np.subtract([4,2], [2,2])
n = np.add(M,[n[1],-n[0]])

p = [0,1]
orientation = [0,1]

cross_p = np.cross([p[0]-orientation[0],p[1]-orientation[1]], orientation)
print(cross_p)
#end_not_inclusive this time
#row = number of els in this row 
#total number of els = n(n+1)
def get_row_n2(front_neighbors):
    if(front_neighbors==0):
        return 0,0,0,0
    else:
        my_index=front_neighbors 
        f_i =0
        i =1
        while(f_i<=my_index):
            f_i = T(i)
            i+=1        
        return my_index, i-2, T(i-1)-i+1,T(i)-(i+1)

        
    my_index = front_neighbors+1
    
print("res:",get_row_n2(0))
print("res:",get_row_n2(1))
print("res:",get_row_n2(2))
print("res:",get_row_n2(3))
print("res:",get_row_n2(4))
print("res:",get_row_n2(5))
print("res:",get_row_n2(6))
print("res:",get_row_n2(7))
print("res:",get_row_n2(8))
print("res:",get_row_n2(9))
print("res:",get_row_n2(10))
print("res:",get_row_n2(11))
print("res:",get_row_n2(12))
print("res:",get_row_n2(13))
print("res:",get_row_n2(14))
print("res:",get_row_n2(15))
print("res:",get_row_n2(16))
print("res:",get_row_n2(17))
def align(rel_pos, linespace, r, fish_size):
    rel_pos = visible_neighbors(rel_pos, r, fish_size)
    xline = rel_pos[(rel_pos['X'] < linespace )& (rel_pos['X'] > -linespace)]
    avx = np.mean(xline['X'])
    return [avx,0]
print(align(rel_pos,0.3,2,.1))
#x align 
xline = df[(df['X'] < .1 )& (df['X'] > -.1)]
avx = np.mean(xline['X'])
#average of x of my neighbors within such range
#if i have no neighbors in front<jupyter_output><empty_output><jupyter_text>Aggregation in a counterclockwise curlThey robots start spread out and have too few neighbors. They aggregate to increase their number of neighbors. While doing so, they are affacted by a distortion of the type of a counterclockwise curl.<jupyter_code>run_time = 5 # in seconds
num_fish = 50
arena_size = 30
arena_center = arena_size / 2.0
initial_spread = 25
fish_pos = initial_spread * np.random.rand(num_fish, 2) + arena_center - initial_spread / 2.0
clock_freqs = 1
verbose = False

distortion = generate_distortion(type='curl', n=arena_size)
environment = Environment(
    node_pos=fish_pos,
    distortion=distortion,
    prob_type='binary',
    noise_magnitude=0,
    conn_thres=10,
    verbose=verbose
)
interaction = Interaction(environment, verbose=verbose)
channel = Channel(environment)

fish = generate_fish(
    n=num_fish, 
    channel=channel, 
    interaction=interaction, 
    lim_neighbors=[math.inf,math.inf],
    neighbor_weights=1.0,
    fish_max_speeds=1,
    clock_freqs=clock_freqs,
    verbose=verbose
)
channel.set_nodes(fish)

observer = Observer(fish=fish, environment=environment, channel=channel)
run_simulation(fish=fish, observer=observer, run_time=run_time, dark=True, white_axis=False, no_legend=True)<jupyter_output><empty_output><jupyter_text>Aggregation and migrationThe robots start dispersed and gather first to then migrate from left to right. This is similar to salmons who come from different places in the ocean and then swim up their rivers of origin for reproduction.<jupyter_code>from events import Move

run_time = 20 # in seconds
num_fish = 25
arena_size = 30
arena_center = arena_size / 2.0
initial_spread = 10
fish_pos = np.zeros((num_fish,2))
fish_pos[:,0] = np.random.rand(num_fish) * initial_spread
fish_pos[:,1] = np.random.rand(num_fish) * initial_spread + arena_center - initial_spread/2
clock_freqs = 1
verbose = False

distortion = generate_distortion(type='none', n=arena_size)
environment = Environment(
    node_pos=fish_pos,
    distortion=distortion,
    prob_type='binary',
    noise_magnitude=0.2,
    conn_thres=10,
    verbose=verbose
)
interaction = Interaction(environment, verbose=verbose)
channel = Channel(environment)

fish = generate_fish(
    n=num_fish, 
    channel=channel, 
    interaction=interaction, 
    lim_neighbors=[math.inf,math.inf],
    neighbor_weights=1.0,
    fish_max_speeds=1,
    clock_freqs=clock_freqs,
    verbose=verbose
)
channel.set_nodes(fish)

observer = Observer(fish=fish, environment=environment, channel=channel)

migrate = Move(1,0)
observer.instruct(event=migrate, rel_clock=0, fish_all=True)

run_simulation(fish=fish, observer=observer, run_time=run_time, dark=True, white_axis=False, no_legend=True, no_star=True)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1309776277666597, 'fraction_numerical': 0.03417067415394725, 'mean_word_length': 2.5383639822447686, 'pattern_counts': {'":': 0, '<': 36, '<?xml version=': 0, '>': 43, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '436365', 'license': 'MIT', 'n_tokens_mistral': 12123, 'n_tokens_neox': 11154, 'n_words': 2003, 'path': 'FishFormationSimulator/Cohesion.ipynb', 'repo_name': 'fberlinger/FISH', 'size': '33479'}