-
Notifications
You must be signed in to change notification settings - Fork 251
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Updated hSync algorithm; Added unit-tests for hSync; Added examples f…
…or hSync
- Loading branch information
Showing
5 changed files
with
190 additions
and
19 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,33 +1,70 @@ | ||
from nnet.sync import *; | ||
|
||
from syncnet import syncnet; | ||
from support import average_neighbor_distance, read_sample, draw_clusters; | ||
from support import average_neighbor_distance, read_sample; | ||
|
||
class hsyncnet(syncnet): | ||
def __init__(self, source_data): | ||
"Costructor of the oscillatory network hSync" | ||
|
||
"(in) source_data - input data set defines structure of the network" | ||
|
||
super().__init__(source_data); | ||
|
||
def process(self, number_clusters, order = 0.998, solution = solve_type.FAST, collect_dynamic = False): | ||
"Perform clustering of input data set in line with input parameters" | ||
|
||
"(in) number_clusters - number of clusters that should be allocated" | ||
"(in) order - level of local synchronization between oscillator that defines end of process of synchronization, range [0..1]" | ||
"(in) solution - type of solving differential equation: ode45, usual diff, etc." | ||
"(in) collect_dynamic - if True - return whole history of process synchronization otherwise - final state (when process of clustering is over)" | ||
|
||
"Returns dynamic of the network as tuple (time, oscillator_phases) that depends on collect_dynamic parameters" | ||
|
||
number_neighbors = 3; | ||
current_number_clusters = numpy.Inf; | ||
|
||
while(current_number_clusters > number_clusters): | ||
radius = average_neighbor_distance(self._osc_loc, number_neighbors); | ||
dyn_phase = []; | ||
dyn_time = []; | ||
|
||
radius = average_neighbor_distance(self._osc_loc, number_neighbors); | ||
|
||
while(current_number_clusters > number_clusters): | ||
self._create_connections(radius); | ||
|
||
self.simulate_dynamic(order, solution, collect_dynamic); | ||
clusters = self.get_clusters(); | ||
(t, dyn) = self.simulate_dynamic(order, solution, collect_dynamic); | ||
if (collect_dynamic == True): | ||
dyn_phase += dyn; | ||
|
||
if (len(dyn_time) > 0): | ||
point_time_last = dyn_time[len(dyn_time) - 1]; | ||
dyn_time += [time_point + point_time_last for time_point in t]; | ||
else: | ||
dyn_time += t; | ||
|
||
clusters = self.get_clusters(0.05); | ||
|
||
# Get current number of allocated clusters | ||
current_number_clusters = len(clusters); | ||
|
||
# Increase number of neighbors that should be used | ||
number_neighbors += 1; | ||
|
||
# Update connectivity radius and check if average function can be used anymore | ||
if (number_neighbors >= len(self._osc_loc)): | ||
radius = radius * 0.1 + radius; | ||
else: | ||
radius = average_neighbor_distance(self._osc_loc, number_neighbors); | ||
|
||
|
||
return (dyn_time, dyn_phase); | ||
|
||
sample = read_sample('../Samples/SampleSimple1.txt'); | ||
network = hsyncnet(sample); | ||
|
||
network.process(2); | ||
|
||
# sample = read_sample('../Samples/SampleSimple1.txt'); | ||
# network = hsyncnet(sample); | ||
# | ||
# (dyn_time, dyn_phase) = network.process(2, collect_dynamic = True); | ||
# | ||
# draw_dynamics(dyn_time, dyn_phase); | ||
|
||
clusters = network.get_clusters(); | ||
draw_clusters(sample, clusters); | ||
# | ||
# clusters = network.get_clusters(); | ||
# draw_clusters(sample, clusters); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,78 @@ | ||
from nnet.sync import draw_dynamics; | ||
|
||
from support import read_sample, draw_clusters; | ||
from hsyncnet import hsyncnet; | ||
|
||
def template_clustering(file, number_clusters, arg_collect_dynamic = True, show_network_structure = False, arg_order = 0.999, arg_eps = 0.1): | ||
sample = read_sample(file); | ||
network = hsyncnet(sample); | ||
|
||
(time, dynamic) = network.process(number_clusters, order = arg_order, collect_dynamic = arg_collect_dynamic); | ||
clusters = network.get_clusters(); | ||
|
||
if (show_network_structure == True): | ||
network.show_network(); | ||
|
||
if (arg_collect_dynamic == True): | ||
draw_dynamics(time, dynamic); | ||
|
||
draw_clusters(sample, clusters); | ||
|
||
|
||
def cluster_sample1(): | ||
template_clustering('../Samples/SampleSimple1.txt', 2); | ||
|
||
def cluster_sample2(): | ||
template_clustering('../Samples/SampleSimple2.txt', 3); | ||
|
||
def cluster_sample3(): | ||
template_clustering('../Samples/SampleSimple3.txt', 4); | ||
|
||
def cluster_simple4(): | ||
template_clustering('../Samples/SampleSimple4.txt', 5); | ||
|
||
def cluster_simple5(): | ||
template_clustering('../Samples/SampleSimple5.txt', 4); | ||
|
||
def cluster_elongate(): | ||
template_clustering('../Samples/SampleElongate.txt', 2, arg_collect_dynamic = False); | ||
|
||
def cluster_lsun(): | ||
"NOTE: Too slow" | ||
template_clustering('../Samples/SampleLsun.txt', 3, arg_collect_dynamic = False); | ||
|
||
def cluster_hepta(): | ||
template_clustering('../Samples/SampleHepta.txt', 7, arg_collect_dynamic = False); | ||
|
||
def cluster_tetra(): | ||
"NOTE: Too slow" | ||
template_clustering('../Samples/SampleTetra.txt', 4, arg_collect_dynamic = False); | ||
|
||
def cluster_target(): | ||
"NOTE: Too slow" | ||
template_clustering('../Samples/SampleTarget.txt', 6, arg_collect_dynamic = False); | ||
|
||
def cluster_chainlink(): | ||
"NOTE: Too slow" | ||
template_clustering('../Samples/SampleChainlink.txt', 2, arg_collect_dynamic = False); | ||
|
||
def cluster_wing_nut(): | ||
"NOTE: Too slow" | ||
template_clustering('../Samples/SampleWingNut.txt', 2, arg_collect_dynamic = False); | ||
|
||
def cluster_two_diamonds(): | ||
"NOTE: Too slow" | ||
template_clustering('../Samples/SampleTwoDiamonds.txt', 2, arg_collect_dynamic = False); | ||
|
||
# cluster_sample1(); | ||
# cluster_sample2(); | ||
# cluster_sample3(); | ||
# cluster_simple4(); | ||
# cluster_elongate(); | ||
# cluster_lsun(); | ||
# cluster_hepta(); | ||
# cluster_tetra(); | ||
# cluster_target(); | ||
# cluster_chainlink(); | ||
# cluster_wing_nut(); | ||
# cluster_two_diamonds(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
import unittest; | ||
|
||
from support import read_sample; | ||
from hsyncnet import hsyncnet; | ||
|
||
class Test(unittest.TestCase): | ||
def templateClusteringResults(self, path, number_clusters, expected_length_clusters): | ||
sample = read_sample(path); | ||
network = hsyncnet(sample); | ||
|
||
(t, d) = network.process(number_clusters, order = 0.999, collect_dynamic = True); | ||
clusters = network.get_clusters(); | ||
|
||
assert sum([len(cluster) for cluster in clusters]) == sum(expected_length_clusters); | ||
|
||
if (sorted([len(cluster) for cluster in clusters]) != expected_length_clusters): | ||
# print("Result: ", sorted([len(cluster) for cluster in clusters]), "Expect: ", expected_length_clusters); | ||
# network.show_network(); | ||
# draw_dynamics(t, d); | ||
# draw_clusters(sample, clusters); | ||
|
||
assert sorted([len(cluster) for cluster in clusters]) == expected_length_clusters; | ||
|
||
|
||
def testClusteringSampleSimple1(self): | ||
self.templateClusteringResults("../Samples/SampleSimple1.txt", 2, [5, 5]); | ||
self.templateClusteringResults("../Samples/SampleSimple1.txt", 1, [10]); | ||
|
||
def testClusteringSampleSimple2(self): | ||
self.templateClusteringResults("../Samples/SampleSimple2.txt", 3, [5, 8, 10]); | ||
self.templateClusteringResults("../Samples/SampleSimple2.txt", 1, [23]); | ||
|
||
def testClusteringSampleSimple3(self): | ||
self.templateClusteringResults("../Samples/SampleSimple3.txt", 4, [10, 10, 10, 30]); | ||
self.templateClusteringResults("../Samples/SampleSimple3.txt", 1, [60]); | ||
|
||
def testClusteringSampleSimple4(self): | ||
self.templateClusteringResults("../Samples/SampleSimple4.txt", 5, [15, 15, 15, 15, 15]); | ||
self.templateClusteringResults("../Samples/SampleSimple4.txt", 1, [75]); | ||
|
||
def testClusteringSampleSimple5(self): | ||
self.templateClusteringResults("../Samples/SampleSimple5.txt", 4, [15, 15, 15, 15]); | ||
self.templateClusteringResults("../Samples/SampleSimple5.txt", 1, [60]); | ||
|
||
|
||
if __name__ == "__main__": | ||
unittest.main() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters