This commit is contained in:
alexgutteridge 2007-08-31 05:46:40 +00:00
parent 643ba3e1f5
commit 4dec3731b8
17 changed files with 415 additions and 3 deletions

View File

@ -198,6 +198,11 @@ void Init_igraph(){
rb_define_const(cIGraph, "WEAK", INT2NUM(1));
rb_define_const(cIGraph, "STRONG", INT2NUM(2));
rb_define_const(cIGraph, "ARBITRARY", INT2NUM(0));
rb_define_const(cIGraph, "MUTUAL", INT2NUM(1));
rb_define_const(cIGraph, "EACH", INT2NUM(0));
rb_define_const(cIGraph, "COLLAPSE", INT2NUM(1));
rb_define_method(cIGraph, "[]", cIGraph_get_edge_attr, 2); /* in cIGraph_attribute_handler.c */
rb_define_method(cIGraph, "[]=", cIGraph_set_edge_attr, 3); /* in cIGraph_attribute_handler.c */
rb_define_alias (cIGraph, "get_edge_attr", "[]");
@ -269,9 +274,16 @@ void Init_igraph(){
rb_define_method(cIGraph, "minimum_spanning_tree_unweighted", cIGraph_minimum_spanning_tree_unweighted, 0); /* in cIGraph_spanning.c */
rb_define_method(cIGraph, "minimum_spanning_tree_prim", cIGraph_minimum_spanning_tree_prim, 1); /* in cIGraph_spanning.c */
rb_define_method(cIGraph, "transitivity", cIGraph_transitivity, 0);
rb_define_method(cIGraph, "transitivity_local", cIGraph_transitivity_local, 1);
rb_define_method(cIGraph, "transitivity_avglocal", cIGraph_transitivity_avglocal, 0);
rb_define_method(cIGraph, "transitivity", cIGraph_transitivity, 0); /* in cIGraph_transitivity.c */
rb_define_method(cIGraph, "transitivity_local", cIGraph_transitivity_local, 1); /* in cIGraph_transitivity.c */
rb_define_method(cIGraph, "transitivity_avglocal", cIGraph_transitivity_avglocal, 0); /* in cIGraph_transitivity.c */
rb_define_method(cIGraph, "to_directed", cIGraph_to_directed, 1); /* in cIGraph_direction.c */
rb_define_method(cIGraph, "to_undirected", cIGraph_to_undirected, 1); /* in cIGraph_direction.c */
rb_define_method(cIGraph, "laplacian", cIGraph_laplacian, 1); /* in cIGraph_spectral.c */
rb_define_method(cIGraph, "coreness", cIGraph_coreness, 1); /* in cIGraph_kcores.c */
rb_define_method(cIGraph, "topological_sorting", cIGraph_topological_sorting, 1); /* in cIGraph_topological_sort.c */

View File

@ -109,6 +109,16 @@ VALUE cIGraph_transitivity (VALUE self);
VALUE cIGraph_transitivity_local (VALUE self, VALUE vs);
VALUE cIGraph_transitivity_avglocal(VALUE self);
//Directedness conversion
VALUE cIGraph_to_directed (VALUE self, VALUE mode);
VALUE cIGraph_to_undirected(VALUE self, VALUE mode);
//Spectral properties
VALUE cIGraph_laplacian(VALUE self, VALUE mode);
//K-Cores
VALUE cIGraph_coreness(VALUE self, VALUE mode);
//Topological sorting
VALUE cIGraph_topological_sorting(VALUE self, VALUE mode);

39
ext/cIGraph_direction.c Normal file
View File

@ -0,0 +1,39 @@
#include "igraph.h"
#include "ruby.h"
#include "cIGraph.h"
/* call-seq:
* graph.to_directed(mode)
*
* Converts the graph to a directed graph.
*/
VALUE cIGraph_to_directed(VALUE self, VALUE mode){
igraph_t *graph;
igraph_neimode_t pmode = NUM2INT(mode);
int ret;
Data_Get_Struct(self, igraph_t, graph);
IGRAPH_CHECK(ret = igraph_to_directed(graph,pmode));
return INT2NUM(ret);
}
/* call-seq:
* graph.to_undirected(mode)
*
* Converts the graph to a directed graph.
*/
VALUE cIGraph_to_undirected(VALUE self, VALUE mode){
igraph_t *graph;
igraph_neimode_t pmode = NUM2INT(mode);
int ret;
Data_Get_Struct(self, igraph_t, graph);
IGRAPH_CHECK(ret = igraph_to_undirected(graph,pmode));
return INT2NUM(ret);
}

39
ext/cIGraph_kcores.c Normal file
View File

@ -0,0 +1,39 @@
#include "igraph.h"
#include "ruby.h"
#include "cIGraph.h"
/* call-seq:
* graph.coreness(mode) -> Array
*
* Finding the coreness of the vertices in a network. The k-core of a
* graph is a maximal subgraph in which each vertex has at least degree k.
* (Degree here means the degree in the subgraph of course.). The coreness
* of a vertex is the highest order of a k-core containing the vertex.
*
* This function implements the algorithm presented in Vladimir Batagelj,
* Matjaz Zaversnik: An O(m) Algorithm for Cores Decomposition of Networks.
*/
VALUE cIGraph_coreness(VALUE self, VALUE mode){
igraph_t *graph;
igraph_neimode_t pmode = NUM2INT(mode);
igraph_vector_t cores;
int i;
VALUE result = rb_ary_new();
Data_Get_Struct(self, igraph_t, graph);
//vector to hold the results of the calculations
igraph_vector_init(&cores,0);
igraph_coreness(graph,&cores,pmode);
for(i=0; i< igraph_vector_size(&cores); i++){
rb_ary_push(result,VECTOR(cores)[i]);
}
igraph_vector_destroy(&cores);
return result;
}

57
ext/cIGraph_spectral.c Normal file
View File

@ -0,0 +1,57 @@
#include "igraph.h"
#include "ruby.h"
#include "cIGraph.h"
/* call-seq:
* graph.laplacian(mode) -> Array
*
* Returns the Laplacian matrix of a graph
*
* The graph Laplacian matrix is similar to an adjacency matrix but
* contains -1's instead of 1's and the vertex degrees are included
* in the diagonal. So the result for edge i--j is -1 if i!=j and is
* equal to the degree of vertex i if i==j. igraph_laplacian will work
* on a directed graph (although this does not seem to make much sense)
* and ignores loops.
*
* Mode is a boolean specifying whether the normalized version should be used
* The normalised Laplacian matrix has 1 in the diagonal
* and -1/sqrt(d[i]d[j]) if there is an edge from i to j.
*
* The first version of this function was written by Vincent Matossian.
*/
VALUE cIGraph_laplacian(VALUE self, VALUE mode){
igraph_t *graph;
igraph_bool_t pmode = 0;
igraph_matrix_t res;
int i;
int j;
VALUE row;
VALUE val;
VALUE matrix = rb_ary_new();
if(mode = Qtrue)
pmode = 1;
Data_Get_Struct(self, igraph_t, graph);
//matrix to hold the results of the calculations
igraph_matrix_init(&res,igraph_vcount(graph),igraph_vcount(graph));
IGRAPH_CHECK(igraph_laplacian(graph,&res,pmode));
for(i=0; i<igraph_matrix_nrow(&res); i++){
row = rb_ary_new();
rb_ary_push(matrix,row);
for(j=0; j<igraph_matrix_ncol(&res); j++){
val = rb_float_new(MATRIX(res,i,j));
rb_ary_push(row,val);
}
}
igraph_matrix_destroy(&res);
return matrix;
}

10
test/tc_cores.rb Normal file
View File

@ -0,0 +1,10 @@
require 'test/unit'
require 'igraph'
class TestGraph < Test::Unit::TestCase
def test_coreness
g = IGraph.new(['A','B','C','D'],true)
c = g.coreness(IGraph::ALL)
assert_equal c.length, g.vcount
end
end

31
test/tc_directedness.rb Normal file
View File

@ -0,0 +1,31 @@
require 'test/unit'
require 'igraph'
class TestGraph < Test::Unit::TestCase
def test_directed_conv
g = IGraph.new(['A','B','B','C','C','D'],false)
g.to_directed(IGraph::ARBITRARY)
assert g.are_connected?('A','B') || g.are_connected?('B','A')
assert !(g.are_connected?('A','B') && g.are_connected?('B','A'))
g = IGraph.new(['A','B','B','C','C','D'],false)
g.to_directed(IGraph::MUTUAL)
assert g.are_connected?('A','B') && g.are_connected?('B','A')
end
def test_undirected
g = IGraph.new(['A','B','B','A','B','C','C','D'],true)
g.to_undirected(IGraph::EACH)
assert_equal 4, g.ecount
g = IGraph.new(['A','B','B','A','B','C','C','D'],true)
g.to_undirected(IGraph::COLLAPSE)
assert_equal 3, g.ecount
end
end

31
test/tc_directedness.rb~ Normal file
View File

@ -0,0 +1,31 @@
require 'test/unit'
require 'igraph'
class TestGraph < Test::Unit::TestCase
def test_directed
g = IGraph.new(['A','B','B','C','C','D'],false)
g.to_directed(IGraph::ARBITRARY)
assert g.are_connected?('A','B') || g.are_connected?('B','A')
assert !(g.are_connected?('A','B') && g.are_connected?('B','A'))
g = IGraph.new(['A','B','B','C','C','D'],false)
g.to_directed(IGraph::MUTUAL)
assert g.are_connected?('A','B') && g.are_connected?('B','A')
end
def test_undirected
g = IGraph.new(['A','B','B','A','B','C','C','D'],true)
g.to_undirected(IGraph::EACH)
assert_equal 4, g.ecount
g = IGraph.new(['A','B','B','A','B','C','C','D'],true)
g.to_undirected(IGraph::COLLAPSE)
assert_equal 3, g.ecount
end
end

View File

@ -0,0 +1,44 @@
require 'test/unit'
require 'igraph'
class TestGraph < Test::Unit::TestCase
def test_shortest_paths
graph = IGraph.new(['A','B','C','D'],true)
m = graph.shortest_paths(['A'],IGraph::ALL)
assert_equal 1, m[0][1]
assert_equal 0, m[0][0]
assert_equal graph.vcount, m[0].size
assert_equal nil, m[0][2]
end
def test_get_shortest_paths
graph = IGraph.new(['A','B','C','D'],true)
m = graph.get_shortest_paths('A',['B'],IGraph::ALL)
assert_equal ['A','B'], m[0]
#assert_equal [], m[1]
end
def test_get_all_shortest_paths
graph = IGraph.new(['A','B','A','C','B','D','C','D'],true)
m = graph.get_all_shortest_paths('A',['D'],IGraph::ALL)
assert_equal 2, m.length
end
def test_average_path_length
graph = IGraph.new(['A','B','A','C','B','D','C','D'],true)
m = graph.average_path_length(true,true)
assert_equal 1.2, m
end
def test_diameter_girth
graph = IGraph.new(['A','B','A','C','B','D'],true)
m = graph.diameter(true,true)
assert_equal 3, m.length
assert_raises IGraphError do
graph.girth
end
graph = IGraph.new(['A','B','A','C','B','D','C','D'],true)
assert_equal 4, graph.girth.length
end
end

33
test/tc_spanning.rb~ Normal file
View File

@ -0,0 +1,33 @@
require 'test/unit'
require 'igraph'
class TestGraph < Test::Unit::TestCase
def test_closeness
g = IGraph.new(['A','B','B','C','C','D'],true)
assert_equal [0.75], g.closeness(['B'],IGraph::ALL)
end
def test_betweenness
g = IGraph.new(['A','B','B','C','C','D'],true)
assert_equal [0,2], g.betweenness(['A','B'],true)
end
def test_edge_betweenness
g = IGraph.new(['A','B','C','D'],true)
assert_equal [1,1], g.edge_betweenness(true)
end
def test_pagerank
g = IGraph.new(['A','B','C','D','E','B','F','B'],true)
assert_equal 67, (g.pagerank(['B'],true,100,0.01,0.8)[0] * 100).to_i
end
def test_constraint
g = IGraph.new(['A','B','C','D'],true)
assert_equal [1], g.constraint(['A'])
assert_raises IGraphError do
g.constraint(['A'],[3])
end
assert_equal [1], g.constraint(['A'],[2,3])
end
def test_maxdegree
g = IGraph.new(['A','B','C','D','A','E','A','F'],true)
assert_equal 3, g.maxdegree(g.vertices,IGraph::ALL,true)
end
end

12
test/tc_spectral.rb Normal file
View File

@ -0,0 +1,12 @@
require 'test/unit'
require 'igraph'
class TestGraph < Test::Unit::TestCase
def test_laplacian
g = IGraph.new(['A','B','C','D'],false)
m = g.laplacian(false)
assert_equal m.length, g.vcount
m = g.laplacian(true)
assert_equal m.length, g.vcount
end
end

12
test/tc_spectral.rb~ Normal file
View File

@ -0,0 +1,12 @@
require 'test/unit'
require 'igraph'
class TestGraph < Test::Unit::TestCase
def test_laplacian
g = IGraph.new(['A','B','C','D'],true)
m = g.laplacian(false)
p m
m = g.laplacian(true)
p m
end
end

41
test/tc_thrash.rb Normal file
View File

@ -0,0 +1,41 @@
require 'test/unit'
require 'igraph'
class Array
def mean
total = 0.0
self.each do |i|
total += i
end
total / self.length.to_f
end
end
class TestGraph < Test::Unit::TestCase
def test_thrash
g = IGraph.new([],true)
v = 100
v.times do |x|
g.add_vertex(x)
end
200.times do |x|
g.add_edge(rand(v/2),rand(v/2))
end
200.times do |x|
g.add_edge(rand(v/2)+v/2,rand(v/2)+v/2)
end
assert_equal v, g.vcount
h,i = g.decompose(IGraph::WEAK,-1,2)
p h.vcount
p i.vcount
p h.degree(h.to_a[20..30],IGraph::ALL,false).mean
p h.degree(h.to_a[10..20],IGraph::ALL,false).mean
p h.betweenness(h.to_a[20..30],true).mean
p h.betweenness(h.to_a[10..20],true).mean
end
end

13
test/tc_thrash.rb~ Normal file
View File

@ -0,0 +1,13 @@
require 'test/unit'
require 'igraph'
class TestGraph < Test::Unit::TestCase
def test_thrash
g = IGraph.new([],true)
10_000.times do |x|
g.add_vertex(x)
end
assert_equal 10_000, g.vcount
end
end

25
test/tc_transitivity.rb~ Normal file
View File

@ -0,0 +1,25 @@
require 'test/unit'
require 'igraph'
class TestGraph < Test::Unit::TestCase
def test_subcomponent
g = IGraph.new([1,2,3,4])
assert_equal [1,2], g.subcomponent(1,IGraph::ALL)
end
def test_subgraph
g = IGraph.new([1,2,3,4])
h = g.subgraph([1,2])
assert_equal 2, h.vcount
assert_equal [1,2], h.vertices
end
def test_clusters
g = IGraph.new([1,2,3,4])
assert_equal 2, g.clusters(IGraph::WEAK).length
assert_equal [1,2], g.clusters(IGraph::WEAK)[0]
end
def test_decompose
g = IGraph.new([1,2,3,4])
assert_equal 2, g.decompose(IGraph::WEAK).length
assert_equal [1,2], g.decompose(IGraph::WEAK)[0].vertices
end
end

View File

@ -12,12 +12,15 @@ require 'tc_basic_properties'
require 'tc_centrality'
require 'tc_components'
require 'tc_copy'
require 'tc_cores'
require 'tc_directedness'
require 'tc_error_handling'
require 'tc_file_read_write'
require 'tc_layout'
require 'tc_matrix'
require 'tc_shortest_paths'
require 'tc_spanning'
require 'tc_spectral'
require 'tc_topological_sort'
require 'tc_transitivity'
require 'tc_vertex_neighbourhood'