Skip to content

Commit 50340d9

Browse files
committed
tests pass
1 parent 9d92de5 commit 50340d9

File tree

11 files changed

+138
-35
lines changed

11 files changed

+138
-35
lines changed

Makefile

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
NODE_PATH = ./node_modules
22
JS_COMPILER = $(NODE_PATH)/uglify-js/bin/uglifyjs
3+
#JS_TESTER = $(NODE_PATH)/vows/bin/vows --nocolor -v
34

45
all: \
56
reorder.v1.js \

TODO

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,5 +14,12 @@ Reordering:
1414
Correspondence analysis
1515
Chun-Hou Chen methods: http://gap.stat.sinica.edu.tw/Papers/GAP_2002.pdf
1616
Elliptical
17-
Barycenter method: http://www.informatica.si/PDF/29-3/13_Makinen-The%20Barycenter%20Heuristic....pdf
18-
17+
18+
Reordering done:
19+
Barycenter method:
20+
http://www.informatica.si/PDF/29-3/13_Makinen-The%20Barycenter%20Heuristic....pdf
21+
Optimal Leaf Ordering
22+
Ziv Bar-Joseph, Erik D. Demaine, David K. Gifford, Angèle M. Hamel, Tommy S. Jaakkola and Nathan Srebro
23+
K-ary Clustering with Optimal Leaf Ordering for Gene Expression Data.
24+
Bioinformatics, 19(9), pp 1070-8, 2003
25+
http://www.cs.cmu.edu/~zivbj/compBio/k-aryBio.pdf

reorder.v1.js

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
(function(exports){
2-
reorder = {version: "0.0.2"}; // semver
2+
reorder = {version: "0.0.3"}; // semver
33

44
reorder.dot = science.lin.dot;
55
reorder.length = science.lin.length;
@@ -644,6 +644,16 @@ function count_crossings(graph, north, south) {
644644
firstIndex, treeSize, tree, index, weightSum,
645645
invert = false, crosscount;
646646

647+
if (north==undefined) {
648+
var comp = reorder.permutation(graph.nodes().length);
649+
north = comp.filter(function(n) {
650+
return graph.outEdges(n).length!=0;
651+
}),
652+
south = comp.filter(function(n) {
653+
return graph.inEdges(n).length!=0;
654+
});
655+
}
656+
647657
// Choose the smaller axis
648658
if (north.length < south.length) {
649659
var tmp = north;
@@ -693,14 +703,18 @@ function count_crossings(graph, north, south) {
693703
}
694704
reorder.count_crossings = count_crossings;
695705
reorder.barycenter = function(graph, iter, comps) {
696-
var perm = [];
706+
var perms = [[], [], 0];
697707
// Compute the barycenter heuristic on each connected component
698708
if (! comps) {
699709
comps = graph.components();
700710
}
701-
for (var i = 0; i < comps.length; i++)
702-
perm = perm.concat(reorder.barycenter1(graph, comps[i], iter));
703-
return perm;
711+
for (var i = 0; i < comps.length; i++) {
712+
var p = reorder.barycenter1(graph, comps[i], iter);
713+
perms = [ perms[0].concat(p[0]),
714+
perms[1].concat(p[1]),
715+
perms[2]+p[2] ];
716+
}
717+
return perms;
704718
};
705719

706720
// Take the list of neighbor indexes and return the median according to
@@ -733,8 +747,16 @@ reorder.barycenter1 = function(graph, comp, max_iter) {
733747
layer,
734748
i, v, neighbors;
735749

736-
if (comp.length < 3)
737-
return comp;
750+
layer1 = comp.filter(function(n) {
751+
return graph.outEdges(n).length!=0;
752+
});
753+
layer2 = comp.filter(function(n) {
754+
return graph.inEdges(n).length!=0;
755+
});
756+
if (comp.length < 3) {
757+
return [layer1, layer2,
758+
count_crossings(graph, layer1, layer2)];
759+
}
738760

739761
if (! max_iter)
740762
max_iter = 24;
@@ -786,7 +808,7 @@ reorder.barycenter1 = function(graph, comp, max_iter) {
786808
else if (d > 0) return 1;
787809
return 0;
788810
});
789-
for (i = 0; i < layer2.length; i++)
811+
for (i = 0; i < layer.length; i++)
790812
nodes[layer[i]].pos = i;
791813
crossings = count_crossings(graph, layer1, layer2);
792814
if (crossings < best_crossings) {
@@ -796,7 +818,7 @@ reorder.barycenter1 = function(graph, comp, max_iter) {
796818
best_iter = iter;
797819
}
798820
}
799-
console.log('Best iter: '+best_iter);
821+
//console.log('Best iter: '+best_iter);
800822
return [best_layer1, best_layer2, best_crossings];
801823
};
802824
reorder.dijkstra = function(graph) {

reorder.v1.min.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/barycenter.js

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
11
reorder.barycenter = function(graph, iter, comps) {
2-
var perm = [];
2+
var perms = [[], [], 0];
33
// Compute the barycenter heuristic on each connected component
44
if (! comps) {
55
comps = graph.components();
66
}
7-
for (var i = 0; i < comps.length; i++)
8-
perm = perm.concat(reorder.barycenter1(graph, comps[i], iter));
9-
return perm;
7+
for (var i = 0; i < comps.length; i++) {
8+
var p = reorder.barycenter1(graph, comps[i], iter);
9+
perms = [ perms[0].concat(p[0]),
10+
perms[1].concat(p[1]),
11+
perms[2]+p[2] ];
12+
}
13+
return perms;
1014
};
1115

1216
// Take the list of neighbor indexes and return the median according to
@@ -39,8 +43,16 @@ reorder.barycenter1 = function(graph, comp, max_iter) {
3943
layer,
4044
i, v, neighbors;
4145

42-
if (comp.length < 3)
43-
return comp;
46+
layer1 = comp.filter(function(n) {
47+
return graph.outEdges(n).length!=0;
48+
});
49+
layer2 = comp.filter(function(n) {
50+
return graph.inEdges(n).length!=0;
51+
});
52+
if (comp.length < 3) {
53+
return [layer1, layer2,
54+
count_crossings(graph, layer1, layer2)];
55+
}
4456

4557
if (! max_iter)
4658
max_iter = 24;
@@ -92,7 +104,7 @@ reorder.barycenter1 = function(graph, comp, max_iter) {
92104
else if (d > 0) return 1;
93105
return 0;
94106
});
95-
for (i = 0; i < layer2.length; i++)
107+
for (i = 0; i < layer.length; i++)
96108
nodes[layer[i]].pos = i;
97109
crossings = count_crossings(graph, layer1, layer2);
98110
if (crossings < best_crossings) {
@@ -102,6 +114,6 @@ reorder.barycenter1 = function(graph, comp, max_iter) {
102114
best_iter = iter;
103115
}
104116
}
105-
console.log('Best iter: '+best_iter);
117+
//console.log('Best iter: '+best_iter);
106118
return [best_layer1, best_layer2, best_crossings];
107119
};

src/core.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
reorder = {version: "0.0.2"}; // semver
1+
reorder = {version: "0.0.3"}; // semver
22

src/count_crossings.js

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@ function count_crossings(graph, north, south) {
66
firstIndex, treeSize, tree, index, weightSum,
77
invert = false, crosscount;
88

9+
if (north==undefined) {
10+
var comp = reorder.permutation(graph.nodes().length);
11+
north = comp.filter(function(n) {
12+
return graph.outEdges(n).length!=0;
13+
}),
14+
south = comp.filter(function(n) {
15+
return graph.inEdges(n).length!=0;
16+
});
17+
}
18+
919
// Choose the smaller axis
1020
if (north.length < south.length) {
1121
var tmp = north;

test/barycenter-test.js

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,22 +7,34 @@ var vows = require("vows"),
77

88
var suite = vows.describe("reorder.barycenter");
99

10+
function dotest(mat) {
11+
var graph = reorder.mat2graph(mat, true);
12+
//reorder.printmat(mat);
13+
var initial_crossings = reorder.count_crossings(graph);
14+
var perms = reorder.barycenter(graph);
15+
//console.log('VOrder: %j, HOrder: %j, Crossings: %d',
16+
//perms[1], perms[0], perms[2]);
17+
//reorder.printmat(mat, perms[1], perms[0]);
18+
assert.isTrue(initial_crossings > perms[2]);
19+
}
20+
1021
suite.addBatch({
1122
"barycenter": {
1223
"simple": function() {
1324
var mat = [
1425
[0, 1, 0, 1, 0],
1526
[1, 0, 1, 0, 1],
1627
[0, 1, 0, 1, 1],
17-
[1, 1, 1, 0, 0]],
18-
graph = reorder.mat2graph(mat, true),
19-
expect = [0, 1, 3, 2, 4];
20-
reorder.printmat(mat);
21-
perm = reorder.barycenter(graph);
22-
console.log('VOrder: %j, HOrder: %j, Crossings: %d',
23-
perm[1], perm[0], perm[2]);
24-
reorder.printmat(mat, perm[1], perm[0]);
25-
//assert.deepEqual(perm, expect);
28+
[1, 1, 1, 0, 0]];
29+
dotest(mat);
30+
},
31+
"hard": function() {
32+
for (var i = 10; i < 100; i += 20) {
33+
for (var j = 10; j < 100; j += 20) {
34+
var mat = reorder.randomMatrix(0.2, i, j, false);
35+
dotest(mat);
36+
}
37+
}
2638
}
2739
}
2840
});

test/ca-test.js

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,19 @@ Math.seedrandom('reorder');
99

1010
var suite = vows.describe("reorder.ca");
1111

12+
function inDeltaArray(actual, expected, delta) {
13+
var n = expected.length, i = -1;
14+
if (actual.length !== n) return false;
15+
while (++i < n) if (!inDeltaNumber(actual[i], expected[i], delta)) return false;
16+
return true;
17+
}
18+
19+
function inDeltaNumber(actual, expected, delta) {
20+
var d = Math.abs(actual-expected);
21+
//console.log("d="+d+": "+((d < delta) ? "pass" : "fail"));
22+
return d < delta;
23+
}
24+
1225
suite.addBatch({
1326
"ca": {
1427
"simple": function() {
@@ -20,7 +33,10 @@ suite.addBatch({
2033
res = reorder.ca(mat, 0.0001);
2134

2235
//assert.isTrue(true);
23-
assert.inDeltaArray(res, [-0.5354605, -0.2626774, 0.8026722], 0.001);
36+
if (!inDeltaArray(res, [-0.5354605, -0.2626774, 0.8026722], 0.001)
37+
&& !inDeltaArray(res, [0.5354605, 0.2626774, -0.8026722], 0.001)) {
38+
assert.fail(actual, expected, message || "expected {actual} to be in within *" + delta + "* of {expected}", null, assert.inDelta);
39+
}
2440
}
2541
}
2642
});

test/count_crossings-test.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ function naive_count_crossings(graph, north, south) {
3434
return count;
3535
}
3636

37-
function dohard(mat) {
37+
function dotest(mat) {
3838
var graph = reorder.mat2graph(mat, true),
3939
comps = graph.components(),
4040
comp = comps.reduce(function(a, b) {
@@ -95,7 +95,7 @@ suite.addBatch({
9595
12);
9696
},
9797
"bug": function() {
98-
dohard([
98+
dotest([
9999
[0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0],
100100
[0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
101101
[0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
@@ -132,7 +132,7 @@ suite.addBatch({
132132
for (var i = 10; i < 100; i += 20) {
133133
for (var j = 10; j < 100; j += 20) {
134134
var mat = reorder.randomMatrix(0.2, i, j, false);
135-
dohard(mat);
135+
dotest(mat);
136136
}
137137
}
138138
}

0 commit comments

Comments
 (0)