igraph 0.3.3 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,324 @@
1
+ #include "igraph.h"
2
+ #include "ruby.h"
3
+ #include "cIGraph.h"
4
+
5
+ /* call-seq:
6
+ * IGraph::Generate.adjacency(matrix,mode) -> IGraph
7
+ *
8
+ * Creates a graph object from an adjacency matrix.
9
+ *
10
+ * matrix should be given as an IGraphMatrix object. mode controls how the
11
+ * matrix is interpreted:
12
+ *
13
+ * IGraph::ADJ_DIRECTED - The graph will be directed and an element
14
+ * gives the number of edges between two vertex.
15
+ *
16
+ * IGraph::ADJ_UNDIRECTED - This is the same as
17
+ * IGraph::ADJ_MAX, for convenience.
18
+ *
19
+ * IGraph::ADJ_MAX - Undirected graph will be created and the
20
+ * number of edges between vertex i and j is max(A(i,j), A(j,i)).
21
+ *
22
+ * IGraph::ADJ_MIN - Undirected graph will be created with
23
+ * min(A(i,j), A(j,i)) edges between vertex i and j.
24
+ *
25
+ * IGraph::ADJ_PLUS - Undirected graph will be created with
26
+ * A(i,j)+A(j,i) edges between vertex i and j.
27
+ *
28
+ * IGraph::ADJ_UPPER - Undirected graph will be created, only the
29
+ * upper right triangle (including the diagonal) is used for the number of
30
+ * edges.
31
+ *
32
+ * IGraph::ADJ_LOWER - Undirected graph will be created, only the
33
+ * lower left triangle (including th * e diagonal) is used for creating the
34
+ * edges.
35
+ */
36
+ VALUE cIGraph_adjacency(VALUE self, VALUE matrix, VALUE mode){
37
+
38
+ igraph_t *graph;
39
+ igraph_matrix_t *matrixp;
40
+ VALUE new_graph;
41
+
42
+ new_graph = cIGraph_alloc(cIGraph);
43
+ Data_Get_Struct(new_graph, igraph_t, graph);
44
+
45
+ Data_Get_Struct(matrix, igraph_matrix_t, matrixp);
46
+
47
+ igraph_destroy(graph);
48
+ igraph_adjacency(graph, matrixp, NUM2INT(mode));
49
+
50
+ return new_graph;
51
+
52
+ }
53
+
54
+ /* call-seq:
55
+ * IGraph::Generate.star(n,mode,center) -> IGraph
56
+ *
57
+ * Creates a star graph, every vertex connects only to the center.
58
+ *
59
+ * The number of vertices should be given in n. mode gives the type of the
60
+ * star graph to create. Possible values:
61
+ *
62
+ * IGraph::STAR_OUT - directed star graph, edges point from the center to the
63
+ * other vertices.
64
+ *
65
+ * IGraph::STAR_IN - directed star graph, edges point to the center from the
66
+ * other vertices.
67
+ *
68
+ * IGraph::STAR_UNDIRECTED - an undirected star graph is created.
69
+ *
70
+ * The id of the vertex which will be the center of the graph is given by
71
+ * center
72
+ */
73
+ VALUE cIGraph_star(VALUE self, VALUE n, VALUE mode, VALUE center){
74
+
75
+ igraph_t *graph;
76
+ VALUE new_graph;
77
+
78
+ new_graph = cIGraph_alloc(cIGraph);
79
+ Data_Get_Struct(new_graph, igraph_t, graph);
80
+
81
+ igraph_destroy(graph);
82
+ igraph_star(graph, NUM2INT(n), NUM2INT(mode), NUM2INT(center));
83
+
84
+ return new_graph;
85
+
86
+ }
87
+
88
+ /* call-seq:
89
+ * IGraph::Generate.lattice(dim,directed,mutual,circular) -> IGraph
90
+ *
91
+ * Creates most kind of lattices.
92
+ *
93
+ * The dimensions of the lattice should be given as an Array of Fixnums in dim
94
+ *
95
+ * directed: Boolean, whether to create a directed graph. The direction of
96
+ * the edges is determined by the generation algorithm and is unlikely to
97
+ * suit you, so this isn't a very useful option.
98
+ *
99
+ * mutual: Boolean, if the graph is directed this gives whether to create
100
+ * all connections as mutual.
101
+ *
102
+ * circular: Boolean, defines whether the generated lattice is periodic.
103
+ */
104
+ VALUE cIGraph_lattice(VALUE self, VALUE dim, VALUE directed, VALUE mutual, VALUE circular){
105
+
106
+ igraph_t *graph;
107
+ VALUE new_graph;
108
+ igraph_vector_t dimvector;
109
+ int i;
110
+
111
+ new_graph = cIGraph_alloc(cIGraph);
112
+ Data_Get_Struct(new_graph, igraph_t, graph);
113
+
114
+ igraph_vector_init(&dimvector,0);
115
+ for(i=0; i<RARRAY(dim)->len; i++){
116
+ igraph_vector_push_back(&dimvector,NUM2INT(RARRAY(dim)->ptr[i]));
117
+ }
118
+
119
+ igraph_destroy(graph);
120
+ igraph_lattice(graph, &dimvector, 0,
121
+ directed == Qtrue ? 1 : 0,
122
+ mutual == Qtrue ? 1 : 0,
123
+ circular == Qtrue ? 1 : 0);
124
+
125
+ igraph_vector_destroy(&dimvector);
126
+
127
+ return new_graph;
128
+
129
+ }
130
+
131
+ /* call-seq:
132
+ * IGraph::Generate.ring(n,directed,mutual,circular) -> IGraph
133
+ *
134
+ * Creates a ring graph, a one dimensional lattice.
135
+ *
136
+ * n: The number of vertices in the ring.
137
+ *
138
+ * directed: Logical, whether to create a directed ring.
139
+ *
140
+ * mutual: Logical, whether to create mutual edges in a directed ring. It is
141
+ * ignored for undirected graphs.
142
+ *
143
+ * circular: Logical, if false, the ring will be open (this is not a real
144
+ * ring actually).
145
+ */
146
+ VALUE cIGraph_ring(VALUE self, VALUE n, VALUE directed, VALUE mutual, VALUE circular){
147
+
148
+ igraph_t *graph;
149
+ VALUE new_graph;
150
+
151
+ new_graph = cIGraph_alloc(cIGraph);
152
+ Data_Get_Struct(new_graph, igraph_t, graph);
153
+
154
+ igraph_destroy(graph);
155
+ igraph_ring(graph, NUM2INT(n),
156
+ directed == Qtrue ? 1 : 0,
157
+ mutual == Qtrue ? 1 : 0,
158
+ circular == Qtrue ? 1 : 0);
159
+
160
+ return new_graph;
161
+
162
+ }
163
+
164
+ /* call-seq:
165
+ * IGraph::Generate.tree(n,children,type) -> IGraph
166
+ *
167
+ * Creates a tree in which almost all vertices have the same number of
168
+ * children.
169
+ *
170
+ * n: Integer, the number of vertices in the graph.
171
+ *
172
+ * children: Integer, the number of children of a vertex in the tree.
173
+ *
174
+ * type: Constant, gives whether to create a directed tree, and if this is
175
+ * the case, also its orientation. Possible values:
176
+ *
177
+ * IGraph::TREE_OUT - directed tree, the edges point from the parents to
178
+ * their children,
179
+ *
180
+ * IGraph::TREE_IN - directed tree, the edges point from the children to
181
+ * their parents.
182
+ *
183
+ * IGraph::TREE_UNDIRECTED - undirected tree.
184
+ */
185
+ VALUE cIGraph_tree(VALUE self, VALUE n, VALUE children, VALUE type){
186
+
187
+ igraph_t *graph;
188
+ VALUE new_graph;
189
+
190
+ new_graph = cIGraph_alloc(cIGraph);
191
+ Data_Get_Struct(new_graph, igraph_t, graph);
192
+
193
+ igraph_destroy(graph);
194
+ igraph_tree(graph, NUM2INT(n), NUM2INT(children), NUM2INT(type));
195
+
196
+ return new_graph;
197
+
198
+ }
199
+ /* call-seq:
200
+ * IGraph::Generate.full(n,directed,loops) -> IGraph
201
+ *
202
+ * Creates a full graph (directed or undirected, with or without loops).
203
+ *
204
+ * In a full graph every possible edge is present, every vertex is connected
205
+ * to every other vertex.
206
+ *
207
+ * n: Integer, the number of vertices in the graph.
208
+ *
209
+ * directed: Logical, whether to create a directed graph.
210
+ *
211
+ * loops: Logical, whether to include self-edges (loops).
212
+ */
213
+ VALUE cIGraph_full(VALUE self, VALUE n, VALUE directed, VALUE loops){
214
+
215
+ igraph_t *graph;
216
+ VALUE new_graph;
217
+
218
+ new_graph = cIGraph_alloc(cIGraph);
219
+ Data_Get_Struct(new_graph, igraph_t, graph);
220
+
221
+ igraph_destroy(graph);
222
+ igraph_full(graph, NUM2INT(n),
223
+ directed == Qtrue ? 1 : 0,
224
+ loops == Qtrue ? 1 : 0);
225
+
226
+ return new_graph;
227
+
228
+ }
229
+ /* call-seq:
230
+ * IGraph::Generate.atlas(number) -> IGraph
231
+ *
232
+ * Create a small graph from the $B!H(BGraph Atlas$B!I(B.
233
+ *
234
+ * The number of the graph is given as the parameter. The graphs are listed:
235
+ *
236
+ * 1. in increasing order of number of nodes
237
+ * 2. for a fixed number of nodes, in increasing order of the number of edges
238
+ * 3. for fixed numbers of nodes and edges, in increasing order of the degree
239
+ * sequence, for example 111223 < 112222;
240
+ * 4. for fixed degree sequence, in increasing number of automorphisms.
241
+ *
242
+ * The data was converted from the networkx software package, see
243
+ * http://networkx.lanl.gov.
244
+ *
245
+ * See An Atlas of Graphs by Ronald C. Read and Robin J. Wilson, Oxford
246
+ * University Press, 1998.
247
+ */
248
+ VALUE cIGraph_atlas(VALUE self, VALUE n){
249
+
250
+ igraph_t *graph;
251
+ VALUE new_graph;
252
+
253
+ new_graph = cIGraph_alloc(cIGraph);
254
+ Data_Get_Struct(new_graph, igraph_t, graph);
255
+
256
+ igraph_destroy(graph);
257
+ igraph_atlas(graph, NUM2INT(n));
258
+
259
+ return new_graph;
260
+
261
+ }
262
+ /* call-seq:
263
+ * IGraph::Generate.chordal_ring(nodes,w) -> IGraph
264
+ *
265
+ * Create an extended chordal ring. An extended chordal ring is regular graph,
266
+ * each node has the same degree. It can be obtained from a simple ring by
267
+ * adding some extra edges specified by a matrix. Let p denote the number of
268
+ * columns in the W matrix. The extra edges of vertex i are added according
269
+ * to column (i mod p) in W. The number of extra edges is the number of rows
270
+ * in W: for each row j an edge i->i+w[ij] is added if i+w[ij] is less than
271
+ * the number of total nodes.
272
+ *
273
+ * See also Kotsis, G: Interconnection Topologies for Parallel Processing
274
+ * Systems, PARS Mitteilungen 11, 1-6, 1993.
275
+ *
276
+ * nodes: Integer, the number of vertices in the graph. It must be at least 3.
277
+ *
278
+ * w: The matrix specifying the extra edges. The number of columns should
279
+ * divide the number of total vertices.
280
+ */
281
+ VALUE cIGraph_extended_chordal_ring(VALUE self, VALUE n, VALUE matrix){
282
+
283
+ igraph_t *graph;
284
+ igraph_matrix_t *matrixp;
285
+ VALUE new_graph;
286
+
287
+ new_graph = cIGraph_alloc(cIGraph);
288
+ Data_Get_Struct(new_graph, igraph_t, graph);
289
+
290
+ Data_Get_Struct(matrix, igraph_matrix_t, matrixp);
291
+
292
+ igraph_destroy(graph);
293
+ igraph_extended_chordal_ring(graph, NUM2INT(n), matrixp);
294
+
295
+ return new_graph;
296
+
297
+ }
298
+
299
+ /* call-seq:
300
+ * g.connect_neighborhood(order,mode) -> nil
301
+ *
302
+ * Connects every vertex to its neighborhood This function adds new edges to
303
+ * graph. For each vertex vertices reachable by at most order steps and not
304
+ * yet connected to the vertex a new edge is created.
305
+ *
306
+ * order: Integer, it gives the distance within which the vertices will be
307
+ * connected to the source vertex.
308
+ *
309
+ * mode: Constant, it specifies how the neighborhood search is performed for
310
+ * directed graphs. If IGraph::OUT then vertices reachable from the source
311
+ * vertex will be connected, IGraph::IN is the opposite. If IGRAPH_ALL then
312
+ * the directed graph is considered as an undirected one.
313
+ */
314
+ VALUE cIGraph_connect_neighborhood(VALUE self, VALUE order, VALUE mode){
315
+
316
+ igraph_t *graph;
317
+
318
+ Data_Get_Struct(self, igraph_t, graph);
319
+
320
+ igraph_connect_neighborhood(graph, NUM2INT(order), NUM2INT(mode));
321
+
322
+ return Qnil;
323
+
324
+ }
@@ -2,6 +2,20 @@
2
2
  #include "ruby.h"
3
3
  #include "cIGraph.h"
4
4
 
5
+ /* call-seq:
6
+ * IGraph::GenerateRandom.grg_game(nodes,radius,torus) -> IGraph
7
+ *
8
+ * Generating geometric random graphs. A geometric random graph is created by
9
+ * dropping points (=vertices) randomly to the unit square and then
10
+ * connecting all those pairs which are less than radius apart in Euclidean
11
+ * norm.
12
+ *
13
+ * nodes: The number of vertices in the graph.
14
+ *
15
+ * radius: The radius within which the vertices will be connected.
16
+ * torus: Logical constant, if true periodic boundary conditions will be used,
17
+ * ie. the vertices are assumed to be on a torus instead of a square.
18
+ */
5
19
  VALUE cIGraph_grg_game(VALUE self, VALUE nodes, VALUE radius, VALUE torus){
6
20
 
7
21
  igraph_t *graph;
@@ -18,6 +32,20 @@ VALUE cIGraph_grg_game(VALUE self, VALUE nodes, VALUE radius, VALUE torus){
18
32
 
19
33
  }
20
34
 
35
+ /* call-seq:
36
+ * IGraph::GenerateRandom.barabasi_game(n,m,outpref,directed) -> IGraph
37
+ *
38
+ * Generates a graph based on the Barab�si-Albert model.
39
+ *
40
+ * n: The number of vertices in the graph.
41
+ * m: The number of outgoing edges generated for each vertex.
42
+ *
43
+ * outpref: Boolean, if true not only the in- but also the out-degree of a
44
+ * vertex increases its citation probability. Ie. the citation probability is
45
+ * determined by the total degree of the vertices.
46
+ *
47
+ * directed: Boolean, whether to generate a directed graph.
48
+ */
21
49
  VALUE cIGraph_barabasi_game(VALUE self, VALUE nodes, VALUE m, VALUE outpref, VALUE directed){
22
50
 
23
51
  igraph_t *graph;
@@ -34,6 +62,37 @@ VALUE cIGraph_barabasi_game(VALUE self, VALUE nodes, VALUE m, VALUE outpref, VAL
34
62
 
35
63
  }
36
64
 
65
+ /* call-seq:
66
+ * IGraph::GenerateRandom.nonlinear_barabasi_game(n,m,outpref,directed) -> IGraph
67
+ *
68
+ * Generates graph with non-linear preferential attachment.
69
+ *
70
+ * This function is very similar to barabasi_game(), only in this game the
71
+ * probability that a new vertex attaches to a given old vertex is not
72
+ * proportional to the degree of the old node, but some power of the degree
73
+ * of the old node.
74
+ *
75
+ * More precisely the attachment probability is the degree to the power of
76
+ * power plus zeroappeal.
77
+ *
78
+ * This function might generate graphs with multiple edges if the value of m
79
+ * is at least two. You can call simplify() to get rid of the multiple
80
+ * edges.
81
+ *
82
+ * n: The number of vertices in the generated graph.
83
+ *
84
+ * power: The power of the preferential attachment.
85
+ *
86
+ * m: The number of edges to generate in each time step.
87
+ *
88
+ * outpref: Logical constant, if TRUE then the preferential attachment is
89
+ * based on the total degree of the nodes instead of the in-degree.
90
+ *
91
+ * zeroappeal: Positive number, the attachment probability for vertices with
92
+ * degree zero.
93
+ *
94
+ * directed: Logical constant, whether to generate a directed graph.
95
+ */
37
96
  VALUE cIGraph_nonlinear_barabasi_game(VALUE self, VALUE nodes, VALUE power, VALUE m, VALUE outpref, VALUE zeroappeal, VALUE directed){
38
97
 
39
98
  igraph_t *graph;
@@ -53,6 +112,28 @@ VALUE cIGraph_nonlinear_barabasi_game(VALUE self, VALUE nodes, VALUE power, VALU
53
112
 
54
113
  }
55
114
 
115
+ /* call-seq:
116
+ * IGraph::GenerateRandom.erdos_renyi_game(type,n,p_or_m,directed,loops) -> IGraph
117
+ *
118
+ * Generates a random (Erdos-Renyi) graph.
119
+ *
120
+ * type: The type of the random graph, possible values:
121
+ *
122
+ * IGraph::ERDOS_RENYI_GNM - G(n,m) graph, m edges are selected uniformly
123
+ * randomly in a graph with n vertices.
124
+ *
125
+ * IGraph::ERDOS_RENYI_GNP - G(n,p) graph, every possible edge is included in
126
+ * the graph with probability p.
127
+ *
128
+ * n: The number of vertices in the graph.
129
+ *
130
+ * p_or_m: This is the p parameter for G(n,p) graphs and the m parameter
131
+ * for G(n,m) graphs.
132
+ *
133
+ * directed: Logical, whether to generate a directed graph.
134
+ *
135
+ * loops: Logical, whether to generate loops (self) edges.
136
+ */
56
137
  VALUE cIGraph_erdos_renyi_game(VALUE self, VALUE type, VALUE nodes, VALUE mp, VALUE directed, VALUE loops){
57
138
 
58
139
  igraph_t *graph;
@@ -70,3 +151,640 @@ VALUE cIGraph_erdos_renyi_game(VALUE self, VALUE type, VALUE nodes, VALUE mp, VA
70
151
  return new_graph;
71
152
 
72
153
  }
154
+
155
+ /* call-seq:
156
+ * IGraph::GenerateRandom.watts_strogatz_game(dim,size,nei,p) -> IGraph
157
+ *
158
+ * The Watts-Strogatz small-world model This function generates a graph
159
+ * according to the Watts-Strogatz model of small-world networks. The graph
160
+ * is obtained by creating a circular undirected lattice and then rewire the
161
+ * edges randomly with a constant probability.
162
+ *
163
+ * dim: The dimension of the lattice.
164
+ *
165
+ * size: The size of the lattice along each dimension.
166
+ *
167
+ * nei: The size of the neighborhood for each vertex.
168
+ *
169
+ * p: The rewiring probability. A real number between zero and one (inclusive).
170
+ */
171
+ VALUE cIGraph_watts_strogatz_game(VALUE self, VALUE dim, VALUE size, VALUE nei, VALUE p){
172
+
173
+ igraph_t *graph;
174
+ VALUE new_graph;
175
+
176
+ new_graph = cIGraph_alloc(cIGraph);
177
+ Data_Get_Struct(new_graph, igraph_t, graph);
178
+
179
+ igraph_destroy(graph);
180
+ igraph_watts_strogatz_game(graph, NUM2INT(dim), NUM2INT(size),
181
+ NUM2INT(nei), NUM2DBL(p));
182
+
183
+ return new_graph;
184
+
185
+ }
186
+
187
+ /* call-seq:
188
+ * IGraph::GenerateRandom.degree_sequence_game(out_deg,in_deg) -> IGraph
189
+ *
190
+ * Generates a random graph with a given degree sequence
191
+ *
192
+ * out_deg: The degree sequence for an undirected graph (if in_seq is of
193
+ * length zero), or the out-degree sequence of a directed graph (if in_deq is
194
+ * not of length zero.
195
+ *
196
+ * in_deg: It is either a zero-length Array or the in-degree sequence.
197
+ */
198
+ VALUE cIGraph_degree_sequence_game(VALUE self, VALUE out_deg, VALUE in_deg){
199
+
200
+ igraph_t *graph;
201
+ VALUE new_graph;
202
+ igraph_vector_t out_degv;
203
+ igraph_vector_t in_degv;
204
+ int i;
205
+
206
+ new_graph = cIGraph_alloc(cIGraph);
207
+ Data_Get_Struct(new_graph, igraph_t, graph);
208
+
209
+ igraph_vector_init(&out_degv,0);
210
+ igraph_vector_init(&in_degv,0);
211
+
212
+ for(i=0;i<RARRAY(out_deg)->len;i++){
213
+ igraph_vector_push_back(&out_degv,NUM2INT(RARRAY(out_deg)->ptr[i]));
214
+ }
215
+ for(i=0;i<RARRAY(in_deg)->len;i++){
216
+ igraph_vector_push_back(&in_degv,NUM2INT(RARRAY(in_deg)->ptr[i]));
217
+ }
218
+
219
+ igraph_destroy(graph);
220
+ igraph_degree_sequence_game(graph, &out_degv, &in_degv, 0);
221
+
222
+ igraph_vector_destroy(&out_degv);
223
+ igraph_vector_destroy(&in_degv);
224
+
225
+ return new_graph;
226
+
227
+ }
228
+
229
+ /* call-seq:
230
+ * IGraph::GenerateRandom.growing_random_game(n,m,directed,citation) -> IGraph
231
+ *
232
+ * Generates a growing random graph.
233
+ *
234
+ * This function simulates a growing random graph. In each discrete time
235
+ * step a new vertex is added and a number of new edges are also added.
236
+ * These graphs are known to be different from standard (not growing) random
237
+ * graphs.
238
+ *
239
+ * n: The number of vertices in the graph.
240
+ *
241
+ * m: The number of edges to add in a time step (ie. after adding a vertex).
242
+ *
243
+ * directed: Boolean, whether to generate a directed graph.
244
+ *
245
+ * citation: Boolean, if TRUE, the edges always originate from the most
246
+ * recently added vertex.
247
+ */
248
+ VALUE cIGraph_growing_random_game(VALUE self, VALUE n, VALUE m, VALUE directed, VALUE citation){
249
+
250
+ igraph_t *graph;
251
+ VALUE new_graph;
252
+
253
+ new_graph = cIGraph_alloc(cIGraph);
254
+ Data_Get_Struct(new_graph, igraph_t, graph);
255
+
256
+ igraph_destroy(graph);
257
+ igraph_growing_random_game(graph, NUM2INT(n), NUM2INT(m),
258
+ directed == Qtrue ? 1: 0,
259
+ citation == Qtrue ? 1: 0);
260
+
261
+ return new_graph;
262
+
263
+ }
264
+
265
+ /* call-seq:
266
+ * IGraph::GenerateRandom.callaway_traits_game(nodes,types,edges_per_step,type_dist,pref_matrix,directed) -> IGraph
267
+ *
268
+ * This function simulates a growing network with vertex types. The different
269
+ * types of vertices prefer to connect other types of vertices with a given
270
+ * probability.
271
+ *
272
+ * The simulation goes like this: in each discrete time step a new vertex is
273
+ * added to the graph. The type of this vertex is generated based on
274
+ * type_dist. Then two vertices are selected uniformly randomly from the
275
+ * graph. The probability that they will be connected depends on the types
276
+ * of these vertices and is taken from pref_matrix. Then another two vertices
277
+ * are selected and this is repeated edges_per_step times in each time step.
278
+ *
279
+ * nodes: The number of nodes in the graph.
280
+ *
281
+ * types: Number of node types.
282
+ *
283
+ * edges_per_step: The number of edges to be add per time step.
284
+ *
285
+ * type_dist: Array giving the distribution of the vertex types.
286
+ *
287
+ * pref_matrix: IGraphMatrix giving the connection probabilities for the
288
+ * vertex types.
289
+ *
290
+ * directed: Logical, whether to generate a directed graph.
291
+ */
292
+ VALUE cIGraph_callaway_traits_game(VALUE self, VALUE nodes, VALUE types, VALUE e_per_step, VALUE type_dist, VALUE pref_matrix, VALUE directed){
293
+
294
+ igraph_t *graph;
295
+ VALUE new_graph;
296
+ igraph_vector_t type_distv;
297
+ igraph_matrix_t *pref_matrixm;
298
+ int i;
299
+
300
+ new_graph = cIGraph_alloc(cIGraph);
301
+ Data_Get_Struct(new_graph, igraph_t, graph);
302
+
303
+ Data_Get_Struct(pref_matrix, igraph_matrix_t, pref_matrixm);
304
+
305
+ igraph_vector_init(&type_distv,0);
306
+
307
+ for(i=0;i<RARRAY(type_dist)->len;i++){
308
+ igraph_vector_push_back(&type_distv,NUM2DBL(RARRAY(type_dist)->ptr[i]));
309
+ }
310
+
311
+ igraph_destroy(graph);
312
+ igraph_callaway_traits_game(graph, NUM2INT(nodes), NUM2INT(types),
313
+ NUM2INT(e_per_step), &type_distv,
314
+ pref_matrixm,
315
+ directed == Qtrue ? 1: 0);
316
+
317
+ igraph_vector_destroy(&type_distv);
318
+
319
+ return new_graph;
320
+
321
+
322
+ }
323
+
324
+ /* call-seq:
325
+ * IGraph::GenerateRandom.establishment_game(nodes,types,k,type_dist,pref_matrix,directed) -> IGraph
326
+ *
327
+ * Generates a graph with a simple growing model with vertex types
328
+ *
329
+ * The simulation goes like this: a single vertex is added at each time step.
330
+ * This new vertex tries to connect to k vertices in the graph. The
331
+ * probability that such a connection is realized depends on the types of the
332
+ * vertices involved.
333
+ *
334
+ * nodes: The number of vertices in the graph.
335
+ *
336
+ * types: The number of vertex types.
337
+ *
338
+ * k: The number of connections tried in each time step.
339
+ *
340
+ * type_dist: Array giving the distribution of vertex types.
341
+ *
342
+ * pref_matrix: IGraphMatrix giving the connection probabilities for
343
+ * different vertex types.
344
+ *
345
+ * directed: Logical, whether to generate a directed graph.
346
+ */
347
+ VALUE cIGraph_establishment_game(VALUE self, VALUE nodes, VALUE types, VALUE k, VALUE type_dist, VALUE pref_matrix, VALUE directed){
348
+
349
+ igraph_t *graph;
350
+ VALUE new_graph;
351
+ igraph_vector_t type_distv;
352
+ igraph_matrix_t *pref_matrixm;
353
+ int i;
354
+
355
+ new_graph = cIGraph_alloc(cIGraph);
356
+ Data_Get_Struct(new_graph, igraph_t, graph);
357
+
358
+ Data_Get_Struct(pref_matrix, igraph_matrix_t, pref_matrixm);
359
+
360
+ igraph_vector_init(&type_distv,0);
361
+
362
+ for(i=0;i<RARRAY(type_dist)->len;i++){
363
+ igraph_vector_push_back(&type_distv,NUM2DBL(RARRAY(type_dist)->ptr[i]));
364
+ }
365
+
366
+ igraph_destroy(graph);
367
+ igraph_establishment_game(graph, NUM2INT(nodes), NUM2INT(types),
368
+ NUM2INT(k), &type_distv,
369
+ pref_matrixm,
370
+ directed == Qtrue ? 1: 0);
371
+
372
+ igraph_vector_destroy(&type_distv);
373
+
374
+ return new_graph;
375
+
376
+
377
+ }
378
+
379
+ /* call-seq:
380
+ * IGraph::GenerateRandom.preference_game(nodes,types,type_dist,pref_matrixdirected,loops) -> IGraph
381
+ *
382
+ * Generates a graph with vertex types and connection preferences
383
+ *
384
+ * This is practically the nongrowing variant of igraph_establishment_game.
385
+ * A given number of vertices are generated. Every vertex is assigned to a
386
+ * vertex type according to the given type probabilities. Finally, every
387
+ * vertex pair is evaluated and an edge is created between them with a
388
+ * probability depending on the types of the vertices involved.
389
+ *
390
+ * nodes: The number of vertices in the graph.
391
+ *
392
+ * types: The number of vertex types.
393
+ *
394
+ * type_dist: Vector giving the distribution of vertex types.
395
+ *
396
+ * pref_matrix: IGraphMatrix giving the connection probabilities for
397
+ * different vertex types.
398
+ *
399
+ * directed: Logical, whether to generate a directed graph. If undirected
400
+ * graphs are requested, only the lower left triangle of the preference
401
+ * matrix is considered.
402
+ *
403
+ * loops: Logical, whether loop edges are allowed.
404
+ */
405
+ VALUE cIGraph_preference_game(VALUE self, VALUE nodes, VALUE types, VALUE type_dist, VALUE pref_matrix, VALUE directed, VALUE loops){
406
+
407
+ igraph_t *graph;
408
+ VALUE new_graph;
409
+ igraph_vector_t type_distv;
410
+ igraph_matrix_t *pref_matrixm;
411
+ int i;
412
+
413
+ new_graph = cIGraph_alloc(cIGraph);
414
+ Data_Get_Struct(new_graph, igraph_t, graph);
415
+
416
+ Data_Get_Struct(pref_matrix, igraph_matrix_t, pref_matrixm);
417
+
418
+ igraph_vector_init(&type_distv,0);
419
+
420
+ for(i=0;i<RARRAY(type_dist)->len;i++){
421
+ igraph_vector_push_back(&type_distv,NUM2DBL(RARRAY(type_dist)->ptr[i]));
422
+ }
423
+
424
+ igraph_destroy(graph);
425
+ igraph_preference_game(graph, NUM2INT(nodes), NUM2INT(types),
426
+ &type_distv,
427
+ pref_matrixm,
428
+ NULL,
429
+ directed == Qtrue ? 1: 0,
430
+ loops == Qtrue ? 1 : 0);
431
+
432
+ igraph_vector_destroy(&type_distv);
433
+
434
+ return new_graph;
435
+
436
+
437
+ }
438
+
439
+ /* call-seq:
440
+ * IGraph::GenerateRandom.asymmetric_preference_game(nodes,types,type_dist_matrix,pref_matrix,loops) -> IGraph
441
+ *
442
+ * Generates a graph with asymmetric vertex types and connection preferences
443
+ *
444
+ * This is the asymmetric variant of preference_game() . A given number of
445
+ * vertices are generated. Every vertex is assigned to an "incoming" and an
446
+ * "outgoing" vertex type according to the given joint type probabilities.
447
+ * Finally, every vertex pair is evaluated and a directed edge is created
448
+ * between them with a probability depending on the "outgoing" type of the
449
+ * source vertex and the "incoming" type of the target vertex.
450
+ *
451
+ * nodes: The number of vertices in the graph.
452
+ *
453
+ * types: The number of vertex types.
454
+ *
455
+ * type_dist_matrix: IGraphMatrix giving the joint distribution of vertex
456
+ * types.
457
+ *
458
+ * pref_matrix: IGraphMatrix giving the connection probabilities for different
459
+ * vertex types.
460
+ *
461
+ * loops: Logical, whether loop edges are allowed.
462
+ */
463
+ VALUE cIGraph_asymmetric_preference_game(VALUE self, VALUE nodes, VALUE types, VALUE type_dist_matrix, VALUE pref_matrix, VALUE loops){
464
+
465
+ igraph_t *graph;
466
+ VALUE new_graph;
467
+ igraph_matrix_t *type_dist_matrixm;
468
+ igraph_matrix_t *pref_matrixm;
469
+
470
+ new_graph = cIGraph_alloc(cIGraph);
471
+ Data_Get_Struct(new_graph, igraph_t, graph);
472
+
473
+ Data_Get_Struct(pref_matrix, igraph_matrix_t, pref_matrixm);
474
+ Data_Get_Struct(type_dist_matrix, igraph_matrix_t, type_dist_matrixm);
475
+
476
+ igraph_destroy(graph);
477
+ igraph_asymmetric_preference_game(graph, NUM2INT(nodes), NUM2INT(types),
478
+ type_dist_matrixm,
479
+ pref_matrixm,
480
+ NULL, NULL,
481
+ loops == Qtrue ? 1 : 0);
482
+
483
+ return new_graph;
484
+
485
+ }
486
+
487
+ /* call-seq:
488
+ * IGraph::GenerateRandom.recent_degree_game(n,power,window,m,outseq,outpref,zero_appeal,directed) -> IGraph
489
+ *
490
+ * Stochastic graph generator based on the number of adjacent edges a node
491
+ * has gained recently
492
+ *
493
+ * n: The number of vertices in the graph, this is the same as the number of
494
+ * time steps.
495
+ *
496
+ * power: The exponent, the probability that a node gains a new edge is
497
+ * proportional to the number of edges it has gained recently (in the last
498
+ * window time steps) to power.
499
+ *
500
+ * window: Integer constant, the size of the time window to use to count the
501
+ * number of recent edges.
502
+ *
503
+ * m: Integer constant, the number of edges to add per time step
504
+ *
505
+ * outpref: Logical constant, if true the edges originated by a vertex also
506
+ * count as recent adjacent edges. It is false in most cases.
507
+ *
508
+ * zero_appeal: Constant giving the attractiveness of the vertices which
509
+ * haven't gained any edge recently.
510
+
511
+ * directed: Logical constant, whether to generate a directed graph.
512
+ */
513
+ VALUE cIGraph_recent_degree_game(VALUE self, VALUE n, VALUE power, VALUE window, VALUE m, VALUE outpref, VALUE zero_appeal, VALUE directed){
514
+
515
+ igraph_t *graph;
516
+ VALUE new_graph;
517
+
518
+ new_graph = cIGraph_alloc(cIGraph);
519
+ Data_Get_Struct(new_graph, igraph_t, graph);
520
+
521
+ igraph_destroy(graph);
522
+ igraph_recent_degree_game(graph, NUM2INT(n), NUM2DBL(power),
523
+ NUM2INT(window), NUM2INT(m),
524
+ NULL,
525
+ outpref == Qtrue ? 1: 0,
526
+ NUM2DBL(zero_appeal),
527
+ directed == Qtrue ? 1: 0);
528
+
529
+ return new_graph;
530
+
531
+ }
532
+
533
+ /* call-seq:
534
+ * IGraph::GenerateRandom.barabasi_aging_game(nodes,m,outpref,pa_exp,aging_exp,aging_bin,zero_deg_appeal,zero_age_appeal,deg_coef,age_coef,directed) -> IGraph
535
+ *
536
+ * Preferential attachment with aging of vertices.
537
+ *
538
+ * In this game, the probability that a node gains a new edge is given by
539
+ * its (in-)degree (k) and age (l). This probability has a degree dependent
540
+ * component multiplied by an age dependent component. The degree dependent
541
+ * part is: deg_coef times k to the power of pa_exp plus zero_deg_appeal; and
542
+ * the age dependent part is age_coef times l to the power of aging_exp plus
543
+ * zero_age_appeal.
544
+ *
545
+ * The age is based on the number of vertices in the network and the
546
+ * aging_bin argument: vertices grew one unit older after each aging_bin
547
+ * vertices added to the network.
548
+ *
549
+ * nodes: The number of vertices in the graph.
550
+ *
551
+ * m: The number of edges to add in each time step.
552
+ *
553
+ * outpref: Logical constant, whether the edges initiated by a vertex
554
+ * contribute to the probability to gain a new edge.
555
+ *
556
+ * pa_exp: The exponent of the preferential attachment, a small positive
557
+ * number usually, the value 1 yields the classic linear preferential
558
+ * attachment.
559
+ *
560
+ * aging_exp: The exponent of the aging, this is a negative number usually.
561
+ *
562
+ * aging_bin: Integer constant, the number of vertices to add before vertices
563
+ * in the network grew one unit older.
564
+ *
565
+ * zero_deg_appeal: The degree dependent part of the attractiveness of the
566
+ * zero degree vertices.
567
+ *
568
+ * zero_age_appeal: The age dependent part of the attractiveness of the
569
+ * vertices of age zero. This parameter is usually zero.
570
+ *
571
+ * deg_coef: The coefficient for the degree.
572
+ *
573
+ * age_coef: The coefficient for the age.
574
+ *
575
+ * directed: Logical constant, whether to generate a directed graph.
576
+ */
577
+ VALUE cIGraph_barabasi_aging_game(VALUE self, VALUE nodes, VALUE m, VALUE outpref, VALUE pa_exp, VALUE aging_exp, VALUE aging_bin, VALUE zero_deg_appeal, VALUE zero_age_appeal, VALUE deg_coef, VALUE age_coef, VALUE directed){
578
+
579
+ igraph_t *graph;
580
+ VALUE new_graph;
581
+
582
+ new_graph = cIGraph_alloc(cIGraph);
583
+ Data_Get_Struct(new_graph, igraph_t, graph);
584
+
585
+ igraph_destroy(graph);
586
+ igraph_barabasi_aging_game(graph, NUM2INT(nodes), NUM2INT(m),
587
+ NULL,
588
+ outpref == Qtrue ? 1: 0,
589
+ NUM2DBL(pa_exp), NUM2DBL(aging_exp),
590
+ NUM2INT(aging_bin),
591
+ NUM2DBL(zero_deg_appeal),
592
+ NUM2DBL(zero_age_appeal),
593
+ NUM2DBL(deg_coef),
594
+ NUM2DBL(age_coef),
595
+ directed == Qtrue ? 1: 0);
596
+
597
+ return new_graph;
598
+
599
+ }
600
+
601
+ /* call-seq:
602
+ * IGraph::GenerateRandom.recent_degree_aging_game(nodes,m,outpref,pa_exp,aging_exp,aging_bin,time_window,zero_appeal,directed) -> IGraph
603
+ *
604
+ * Preferential attachment based on the number of edges gained recently, with
605
+ * aging of vertices
606
+ *
607
+ * This game is very similar to igraph_barabasi_aging_game(), except that
608
+ * instead of the total number of adjacent edges the number of edges gained
609
+ * in the last time_window time steps are counted.
610
+ *
611
+ * The degree dependent part of the attractiveness is given by k to the power
612
+ * of pa_exp plus zero_appeal; the age dependent part is l to the power to
613
+ * aging_exp. k is the number of edges gained in the last time_window time
614
+ * steps, l is the age of the vertex.
615
+ *
616
+ * nodes: The number of vertices in the graph.
617
+ *
618
+ * m: The number of edges to add in each time step.
619
+ *
620
+ * outpref: Logical constant, whether the edges initiated by a vertex
621
+ * contribute to the probability to gain a new edge.
622
+ *
623
+ * pa_exp: The exponent of the preferential attachment, a small positive
624
+ * number usually, the value 1 yields the classic linear preferential
625
+ * attachment.
626
+ *
627
+ * aging_exp: The exponent of the aging, this is a negative number usually.
628
+ *
629
+ * aging_bin: Integer constant, the number of vertices to add before vertices
630
+ * in the network grew one unit older.
631
+ *
632
+ * zero_appeal: The degree dependent part of the attractiveness of the
633
+ * zero degree vertices.
634
+ *
635
+ * time_window: The time window to use to count the number of adjacent edges
636
+ * for the vertices.
637
+ *
638
+ * directed: Logical constant, whether to generate a directed graph.
639
+ */
640
+ VALUE cIGraph_recent_degree_aging_game(VALUE self, VALUE nodes, VALUE m, VALUE outpref, VALUE pa_exp, VALUE aging_exp, VALUE aging_bin, VALUE time_window, VALUE zero_appeal, VALUE directed){
641
+
642
+ igraph_t *graph;
643
+ VALUE new_graph;
644
+
645
+ new_graph = cIGraph_alloc(cIGraph);
646
+ Data_Get_Struct(new_graph, igraph_t, graph);
647
+
648
+ igraph_destroy(graph);
649
+ igraph_recent_degree_aging_game(graph, NUM2INT(nodes), NUM2INT(m),
650
+ NULL,
651
+ outpref == Qtrue ? 1: 0,
652
+ NUM2DBL(pa_exp), NUM2DBL(aging_exp),
653
+ NUM2INT(aging_bin),
654
+ NUM2INT(time_window),
655
+ NUM2DBL(zero_appeal),
656
+ directed == Qtrue ? 1: 0);
657
+
658
+ return new_graph;
659
+
660
+ }
661
+
662
+ /* call-seq:
663
+ * IGraph::GenerateRandom.cited_type_game(nodes,types,pref,edges_per_step_directed) -> IGraph
664
+ *
665
+ * Function to create a network based on some vertex categories. This function
666
+ * creates a citation network, in each step a single vertex and edges_per_step
667
+ * citating edges are added, nodes with different categories (may) have
668
+ * different probabilities to get cited, as given by the pref vector.
669
+ *
670
+ * Note that this function might generate networks with multiple edges if
671
+ * edges_per_step is greater than one. You might want to call
672
+ * igraph_simplify() on the result to remove multiple edges.
673
+ *
674
+ * nodes: The number of vertices in the network.
675
+ *
676
+ * types: Numeric Array giving the categories of the vertices, so it should
677
+ * contain nodes non-negative integer numbers. Types are numbered from zero.
678
+ *
679
+ * pref: The attractivity of the different vertex categories in an Array. Its
680
+ * length should be the maximum element in types plus one (types are numbered
681
+ * from zero).
682
+ *
683
+ * edges_per_step: Integer constant, the number of edges to add in each time
684
+ * step.
685
+ *
686
+ * directed: Logical constant, whether to create a directed network.
687
+ */
688
+ VALUE cIGraph_cited_type_game(VALUE self, VALUE nodes, VALUE types, VALUE pref, VALUE e_per_s, VALUE directed){
689
+
690
+ igraph_t *graph;
691
+ VALUE new_graph;
692
+ igraph_vector_t type_distv;
693
+ igraph_vector_t prefv;
694
+ int i;
695
+
696
+ new_graph = cIGraph_alloc(cIGraph);
697
+ Data_Get_Struct(new_graph, igraph_t, graph);
698
+
699
+ igraph_vector_init(&type_distv,0);
700
+ igraph_vector_init(&prefv,0);
701
+
702
+ for(i=0;i<RARRAY(types)->len;i++){
703
+ igraph_vector_push_back(&type_distv,NUM2DBL(RARRAY(types)->ptr[i]));
704
+ }
705
+ for(i=0;i<RARRAY(pref)->len;i++){
706
+ igraph_vector_push_back(&prefv,NUM2DBL(RARRAY(pref)->ptr[i]));
707
+ }
708
+
709
+ igraph_destroy(graph);
710
+ igraph_cited_type_game(graph, NUM2INT(nodes),
711
+ &type_distv,
712
+ &prefv,
713
+ NUM2INT(e_per_s),
714
+ directed == Qtrue ? 1: 0);
715
+
716
+ igraph_vector_destroy(&type_distv);
717
+ igraph_vector_destroy(&prefv);
718
+
719
+ return new_graph;
720
+
721
+
722
+ }
723
+ /* call-seq:
724
+ * IGraph::GenerateRandom.citing_cited_type_game(nodes,types,pref,edges_per_step_directed) -> IGraph
725
+ *
726
+ * This game is similar to igraph_cited_type_game() but here the category of
727
+ * the citing vertex is also considered.
728
+ *
729
+ * An evolving citation network is modeled here, a single vertex and its
730
+ * edges_per_step citation are added in each time step. The odds the a given
731
+ * vertex is cited by the new vertex depends on the category of both the
732
+ * citing and the cited vertex and is given in the pref matrix. The categories
733
+ * of the citing vertex correspond to the rows, the categories of the cited
734
+ * vertex to the columns of this matrix. Ie. the element in row i and column
735
+ * j gives the probability that a j vertex is cited, if the category of the
736
+ * citing vertex is i.
737
+ *
738
+ * Note that this function might generate networks with multiple edges if
739
+ * edges_per_step is greater than one. You might want to call
740
+ * igraph_simplify() on the result to remove multiple edges.
741
+ *
742
+ * nodes: The number of vertices in the network.
743
+ *
744
+ * types: A numeric IGraphMatrix of length nodes, containing the categories
745
+ * of the vertices. The categories are numbered from zero.
746
+ *
747
+ * pref: The preference IGraphMatrix, a square matrix is required, both the
748
+ * number of rows and columns should be the maximum element in types plus
749
+ * one (types are numbered from zero).
750
+ *
751
+ * edges_per_step: Integer constant, the number of edges to add in each time
752
+ * step.
753
+ *
754
+ * directed: Logical constant, whether to create a directed network.
755
+ */
756
+ VALUE cIGraph_citing_cited_type_game(VALUE self, VALUE nodes, VALUE types, VALUE pref, VALUE e_per_s, VALUE directed){
757
+
758
+ igraph_t *graph;
759
+ VALUE new_graph;
760
+ igraph_vector_t typev;
761
+ igraph_matrix_t *prefm;
762
+ int i;
763
+
764
+ new_graph = cIGraph_alloc(cIGraph);
765
+ Data_Get_Struct(new_graph, igraph_t, graph);
766
+ Data_Get_Struct(pref, igraph_matrix_t, prefm);
767
+
768
+ igraph_vector_init(&typev,0);
769
+
770
+ for(i=0;i<RARRAY(types)->len;i++){
771
+ igraph_vector_push_back(&typev,NUM2INT(RARRAY(types)->ptr[i]));
772
+ }
773
+
774
+ printf("ok\n");
775
+
776
+ igraph_destroy(graph);
777
+ igraph_citing_cited_type_game(graph, NUM2INT(nodes),
778
+ &typev,
779
+ prefm,
780
+ NUM2INT(e_per_s),
781
+ directed == Qtrue ? 1: 0);
782
+
783
+ printf("death\n");
784
+
785
+ igraph_vector_destroy(&typev);
786
+
787
+ return new_graph;
788
+
789
+
790
+ }