Skip to content

Commit

Permalink
Refactoring of the nnet.sync and syncnet. New unit-tests has been add…
Browse files Browse the repository at this point in the history
…ed. But with cluster allocation for synchronous ensembles has been fixed
  • Loading branch information
annoviko committed Feb 28, 2014
1 parent ea8bc63 commit 37803d0
Show file tree
Hide file tree
Showing 5 changed files with 55 additions and 89 deletions.
28 changes: 15 additions & 13 deletions nnet/sync/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -264,21 +264,24 @@ def phase_kuramoto(self, teta, t, argv):


def allocate_sync_ensembles(self, tolerance = 0.01):
"Return lists of synchonized ensembles of oscillators"
"BUG: When we have high disorder and high tolerance then we can allocate several clusters that can have shared oscillators"
clusters = list();
if (self.num_osc > 0):
clusters.append( (self._phases[0], [0]) );
"Allocate clusters in line with ensembles of synchronous oscillators where each"
"synchronous ensemble corresponds to only one cluster"
clusters = [ [0] ];

for index in range(1, self.num_osc, 1):
allocated = False;
for i in range(1, self._num_osc, 1):
cluster_allocated = False;
for cluster in clusters:
if ( abs(cluster[0] - self._phases[index]) < tolerance ):
allocated = True;
cluster[1].append(index);
for neuron_index in cluster:
if ( (self._phases[i] < (self._phases[neuron_index] + tolerance)) and (self._phases[i] > (self._phases[neuron_index] - tolerance)) ):
cluster_allocated = True;
cluster.append(i);
break;

if (cluster_allocated == True):
break;

if (allocated != True):
clusters.append( (self._phases[index], [index]) );
if (cluster_allocated == False):
clusters.append([i]);

return clusters;

Expand Down Expand Up @@ -383,7 +386,6 @@ def _calculate_phases(self, solution, t, step, int_step):
return next_phases;



def phase_normalization(teta):
"Normalization of phase of oscillator that should be placed between [0; 2 * pi]"
norm_teta = teta;
Expand Down
10 changes: 4 additions & 6 deletions nnet/sync/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -247,26 +247,24 @@ def template_dynamic_simulation_cluster_parameter(self, num_osc, cluster_paramet
clusters = network.allocate_sync_ensembles(0.1);

assert len(clusters) == cluster_parameter;
assert sum([len(cluster) for cluster in clusters]) == num_osc;


def test_dynamic_simulation_cluster_parameter_2(self):
self.template_dynamic_simulation_cluster_parameter(2, 2);
self.template_dynamic_simulation_cluster_parameter(10, 2);
self.template_dynamic_simulation_cluster_parameter(20, 2);


def test_dynamic_simulation_cluster_parameter_3(self):
self.template_dynamic_simulation_cluster_parameter(3, 3);
self.template_dynamic_simulation_cluster_parameter(10, 3);
self.template_dynamic_simulation_cluster_parameter(20, 3);


def test_dynamic_simulation_cluster_parameter_4(self):
self.template_dynamic_simulation_cluster_parameter(10, 4);
self.template_dynamic_simulation_cluster_parameter(20, 4);


def test_dynamic_simulation_cluster_parameter_6(self):
self.template_dynamic_simulation_cluster_parameter(20, 6);



if __name__ == "__main__":
Expand Down
75 changes: 9 additions & 66 deletions syncnet/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
class syncnet(net):
_loc = None;

def __init__(self, source_data, conn_repr = conn_represent.MATRIX):
def __init__(self, source_data, conn_repr = conn_represent.MATRIX, radius = None):
sample = None;
if ( isinstance(source_data, str) ):
file = open(source_data, 'r');
Expand All @@ -30,6 +30,10 @@ def __init__(self, source_data, conn_repr = conn_represent.MATRIX):
else:
raise NameError("Unknown type of representation of coupling between oscillators");

# Create connections.
if (radius is not None):
self.__create_connections(radius);



def __create_connections(self, radius):
Expand Down Expand Up @@ -57,46 +61,8 @@ def process(self, radius = None, order = 0.998, solution = solve_type.FAST, coll
if (radius != None):
self.__create_connections(radius);

# For statistics
iter_counter = 0;

# If requested input dynamics
dyn_phase = None;
dyn_time = None;
if (collect_dynamic == True):
dyn_phase = list();
dyn_time = list();

dyn_phase.append(self._phases);
dyn_time.append(0);

# Execute until sync state will be reached
while (self.sync_local_order() < order):
iter_counter += 1;
next_phases = [0] * self.num_osc; # new oscillator _phases

for index in range (0, self.num_osc, 1):
if (solution == solve_type.FAST):
result = self._phases[index] + self.phase_kuramoto(self._phases[index], 0, index);
next_phases[index] = phase_normalization(result);

elif (solution == solve_type.ODEINT):
result = odeint(self.phase_kuramoto, self._phases[index], numpy.arange(0, 0.1, 1), (index , ));
next_phases[index] = phase_normalization(result[len(result) - 1][0]);

else:
assert 0; # Should be implemented later.

# update states of oscillators
self._phases = next_phases;

# If requested input dynamic
if (collect_dynamic == True):
dyn_phase.append(next_phases);
dyn_time.append(iter_counter);

print("Number of iteration: ", iter_counter);
return (dyn_time, dyn_phase);
return self.simulate_dynamic(order, solution, collect_dynamic);



def get_neighbors(self, index):
Expand All @@ -122,31 +88,8 @@ def phase_kuramoto(self, teta, t, argv):


def get_clusters(self, eps = 0.1):
clusters = [ [0] ];

for i in range(1, self._num_osc, 1):
cluster_allocated = False;
for cluster in clusters:
for neuron_index in cluster:
if ( (self._phases[i] < (self._phases[neuron_index] + eps)) and (self._phases[i] > (self._phases[neuron_index] - eps)) ):
cluster_allocated = True;
cluster.append(i);
break;

if (cluster_allocated == True):
break;

if (cluster_allocated == False):
clusters.append([i]);

#debug assert
total_length = 0;
for cluster in clusters:
total_length += len(cluster);
print("Total length: ", total_length, ", Real: ", self._num_osc);
assert total_length == self._num_osc;

return clusters;
"Return clusters"
return self.allocate_sync_ensembles(eps);


def show_network(self):
Expand Down
30 changes: 27 additions & 3 deletions syncnet/tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,35 @@ def templateClustering(self, file, radius, order):
network.process(radius, order);
return network.get_clusters(0.05);

def testTwoClusters(self):

def testClusteringSampleSimple1(self):
clusters = self.templateClustering('../Samples/SampleSimple1.txt', 1, 0.998);
assert len(clusters) == 2;
assert len(clusters[0]) == 5;
assert len(clusters[1]) == 5;
assert sorted([len(cluster) for cluster in clusters]) == [5, 5];


def testClusteringSampleSimple2(self):
clusters = self.templateClustering('../Samples/SampleSimple2.txt', 1, 0.998);
assert len(clusters) == 3;
assert sorted([len(cluster) for cluster in clusters]) == [5, 8, 10];


def testClusteringSampleSimple3(self):
clusters = self.templateClustering('../Samples/SampleSimple3.txt', 1, 0.998);
assert len(clusters) == 4;
assert sorted([len(cluster) for cluster in clusters]) == [10, 10, 10, 30];


def testClusteringSampleSimple4(self):
clusters = self.templateClustering('../Samples/SampleSimple4.txt', 0.7, 0.998);
assert len(clusters) == 5;
assert sorted([len(cluster) for cluster in clusters]) == [15, 15, 15, 15, 15];


def testClusteringSampleSimple5(self):
clusters = self.templateClustering('../Samples/SampleSimple5.txt', 1, 0.998);
assert len(clusters) == 4;
assert sorted([len(cluster) for cluster in clusters]) == [15, 15, 15, 15];

if __name__ == "__main__":
#import sys;sys.argv = ['', 'Test.testName']
Expand Down
1 change: 0 additions & 1 deletion syncsom/examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@ def template_clustering(file, map_size, trust_order, sync_order = 0.999, show_dy
print("Sample: ", file, "\t\tExecution time: ", ticks, "\n");

# Show dynamic of the last layer.
# TODO: Fix this fucking bug! It isn't displayed anymore!
if (show_dyn == True):
draw_dynamics(dyn_time, dyn_phase);

Expand Down

0 comments on commit 37803d0

Please sign in to comment.