This commit is contained in:
parent
643ba3e1f5
commit
4dec3731b8
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||
|
|
@ -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
|
||||
|
|
@ -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
|
|
@ -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'
|
||||
|
|
Loading…
Reference in New Issue