You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

cIGraph_attribute_handler.c 18 kB

19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
19 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751
  1. #include "igraph.h"
  2. #include "ruby.h"
  3. #include "cIGraph.h"
  4. /* call-seq:
  5. * graph[u,v] -> Object
  6. *
  7. * Returns the object associated with the edge connecting vertices u and v.
  8. * Aliased to graph.get_edge_attr(u,v)
  9. */
  10. VALUE cIGraph_get_edge_attr(VALUE self, VALUE from, VALUE to){
  11. int idx;
  12. igraph_t *graph;
  13. VALUE e_ary;
  14. Data_Get_Struct(self, igraph_t, graph);
  15. e_ary = ((VALUE*)graph->attr)[1];
  16. idx = NUM2INT(cIGraph_get_eid(self, from, to, 1));
  17. return rb_ary_entry(e_ary,idx);
  18. }
  19. /* call-seq:
  20. * graph[u,v] = w
  21. *
  22. * Sets the object associated with the edge connecting vertices u and v.
  23. * Aliased to graph.set_edge_attr(u,v)
  24. */
  25. VALUE cIGraph_set_edge_attr(VALUE self, VALUE from, VALUE to, VALUE attr){
  26. int idx;
  27. igraph_t *graph;
  28. VALUE e_ary;
  29. Data_Get_Struct(self, igraph_t, graph);
  30. e_ary = ((VALUE*)graph->attr)[1];
  31. idx = NUM2INT(cIGraph_get_eid(self, from, to, 1));
  32. rb_ary_store(e_ary,idx,attr);
  33. return Qtrue;
  34. }
  35. VALUE cIGraph_graph_attributes(VALUE self){
  36. igraph_t *graph;
  37. VALUE hsh;
  38. Data_Get_Struct(self, igraph_t, graph);
  39. hsh = ((VALUE*)graph->attr)[2];
  40. return hsh;
  41. }
  42. igraph_attribute_table_t cIGraph_attribute_table = {
  43. cIGraph_attribute_init,
  44. cIGraph_attribute_destroy,
  45. cIGraph_attribute_copy,
  46. cIGraph_attribute_add_vertices,
  47. cIGraph_attribute_delete_vertices,
  48. cIGraph_attribute_add_edges,
  49. cIGraph_attribute_delete_edges,
  50. cIGraph_attribute_permute_edges,
  51. cIGraph_attribute_get_info,
  52. cIGraph_attribute_has_attr,
  53. cIGraph_attribute_get_type,
  54. cIGraph_get_numeric_graph_attr,
  55. cIGraph_get_string_graph_attr,
  56. cIGraph_get_numeric_vertex_attr,
  57. cIGraph_get_string_vertex_attr,
  58. cIGraph_get_numeric_edge_attr,
  59. cIGraph_get_string_edge_attr,
  60. };
  61. int cIGraph_attribute_init(igraph_t *graph, igraph_vector_ptr_t *attr) {
  62. VALUE* attrs;
  63. int i;
  64. VALUE key;
  65. VALUE value;
  66. attrs = ALLOC_N(VALUE, 3);
  67. if(!attrs)
  68. IGRAPH_ERROR("Error allocating Arrays\n", IGRAPH_ENOMEM);
  69. //[0] is vertex array, [1] is edge array, [2] is graph attr
  70. attrs[0] = rb_ary_new();
  71. attrs[1] = rb_ary_new();
  72. attrs[2] = rb_hash_new();
  73. if(attr){
  74. for(i=0;i<igraph_vector_ptr_size(attr);i++){
  75. igraph_i_attribute_record_t *attr_rec;
  76. char *s;
  77. attr_rec = VECTOR(*attr)[i];
  78. key = rb_str_new2(attr_rec->name);
  79. switch (attr_rec->type) {
  80. case IGRAPH_ATTRIBUTE_NUMERIC:
  81. value=rb_float_new((double)VECTOR(*(igraph_vector_t*)attr_rec->value)[0]);
  82. break;
  83. case IGRAPH_ATTRIBUTE_STRING:
  84. igraph_strvector_get((igraph_strvector_t*)attr_rec->value, 0, &s);
  85. value=rb_str_new2(s);
  86. break;
  87. default:
  88. IGRAPH_WARNING("unsupported attribute type (not string and not numeric)");
  89. value=0;
  90. break;
  91. }
  92. if (value){
  93. rb_hash_aset((VALUE)attrs[2],key,value);
  94. }
  95. }
  96. }
  97. graph->attr = attrs;
  98. return IGRAPH_SUCCESS;
  99. }
  100. /* Destruction */
  101. void cIGraph_attribute_destroy(igraph_t *graph) {
  102. free(graph->attr);
  103. return;
  104. }
  105. /* Copying */
  106. int replace_i(VALUE key, VALUE val, VALUE hash){
  107. if (key != Qundef) {
  108. rb_hash_aset(hash, key, val);
  109. }
  110. //return ST_CONTINUE;
  111. return 0;
  112. }
  113. int cIGraph_attribute_copy(igraph_t *to, const igraph_t *from) {
  114. #ifdef DEBUG
  115. printf("Entering cIGraph_attribute_copy\n");
  116. #endif
  117. VALUE* attrs;
  118. VALUE vertex_array = ((VALUE*)from->attr)[0];
  119. VALUE edge_array = ((VALUE*)from->attr)[1];
  120. VALUE graph_attr = ((VALUE*)from->attr)[2];
  121. attrs = ALLOC_N(VALUE, 3);
  122. attrs[0] = rb_ary_dup(vertex_array);
  123. attrs[1] = rb_ary_dup(edge_array);
  124. attrs[2] = rb_hash_new();
  125. rb_hash_foreach(graph_attr, replace_i, attrs[2]);
  126. to->attr = attrs;
  127. #ifdef DEBUG
  128. printf("Leaving cIGraph_attribute_copy\n");
  129. #endif
  130. return IGRAPH_SUCCESS;
  131. }
  132. /* Adding vertices */
  133. int cIGraph_attribute_add_vertices(igraph_t *graph, long int nv, igraph_vector_ptr_t *attr) {
  134. #ifdef DEBUG
  135. printf("Entering cIGraph_attribute_add_vertices\n");
  136. #endif
  137. int i,j;
  138. VALUE vertex_array = ((VALUE*)graph->attr)[0];
  139. VALUE values;
  140. if(attr){
  141. if(igraph_vector_ptr_size(attr) > 0 && ((igraph_i_attribute_record_t*)VECTOR(*attr)[0])->type == IGRAPH_ATTRIBUTE_PY_OBJECT){
  142. values = (VALUE)((igraph_i_attribute_record_t*)VECTOR(*attr)[0])->value;
  143. Check_Type(values, T_ARRAY);
  144. for(i=0;i<RARRAY(values)->len;i++){
  145. rb_ary_push(vertex_array, RARRAY(values)->ptr[i]);
  146. }
  147. //Otherwise read each attriute into hashes and use those
  148. } else {
  149. for(i=0;i<nv;i++){
  150. VALUE record;
  151. igraph_i_attribute_record_t *attr_rec;
  152. char *s;
  153. record = rb_hash_new();
  154. //For when no attributes are given
  155. if(igraph_vector_ptr_size(attr) == 0){
  156. record = INT2NUM(i+1);
  157. }
  158. for (j=0; j<igraph_vector_ptr_size(attr); j++) {
  159. VALUE key;
  160. VALUE value;
  161. //Add key value pair
  162. attr_rec = VECTOR(*attr)[j];
  163. key = rb_str_new2(attr_rec->name);
  164. switch (attr_rec->type) {
  165. case IGRAPH_ATTRIBUTE_NUMERIC:
  166. value=rb_float_new((double)VECTOR(*(igraph_vector_t*)attr_rec->value)[i]);
  167. break;
  168. case IGRAPH_ATTRIBUTE_STRING:
  169. igraph_strvector_get((igraph_strvector_t*)attr_rec->value, i, &s);
  170. value=rb_str_new2(s);
  171. break;
  172. default:
  173. IGRAPH_WARNING("unsupported attribute type (not string and not numeric)");
  174. value=Qnil;
  175. break;
  176. }
  177. rb_hash_aset(record,key,value);
  178. }
  179. rb_ary_push(vertex_array,record);
  180. }
  181. }
  182. }
  183. #ifdef DEBUG
  184. printf("Leaving cIGraph_attribute_add_vertices\n");
  185. #endif
  186. return IGRAPH_SUCCESS;
  187. }
  188. /* Deleting vertices */
  189. void cIGraph_attribute_delete_vertices(igraph_t *graph,
  190. const igraph_vector_t *eidx,
  191. const igraph_vector_t *vidx) {
  192. #ifdef DEBUG
  193. printf("Entering cIGraph_attribute_delete_vertices\n");
  194. #endif
  195. int i;
  196. VALUE vertex_array = ((VALUE*)graph->attr)[0];
  197. VALUE edge_array = ((VALUE*)graph->attr)[1];
  198. VALUE n_v_ary = rb_ary_new();
  199. VALUE n_e_ary = rb_ary_new();
  200. for(i=0;i<igraph_vector_size(vidx);i++){
  201. if(VECTOR(*vidx)[i] != 0)
  202. rb_ary_store(n_v_ary,VECTOR(*vidx)[i]-1,rb_ary_entry(vertex_array,i));
  203. }
  204. for(i=0;i<igraph_vector_size(eidx);i++){
  205. if(VECTOR(*eidx)[i] != 0)
  206. rb_ary_store(n_e_ary,VECTOR(*eidx)[i]-1,rb_ary_entry(edge_array,i));
  207. }
  208. ((VALUE*)graph->attr)[0] = n_v_ary;
  209. ((VALUE*)graph->attr)[1] = n_e_ary;
  210. #ifdef DEBUG
  211. printf("Leaving cIGraph_attribute_delete_vertices\n");
  212. #endif
  213. return;
  214. }
  215. /* Adding edges */
  216. int cIGraph_attribute_add_edges(igraph_t *graph,
  217. const igraph_vector_t *edges,
  218. igraph_vector_ptr_t *attr) {
  219. #ifdef DEBUG
  220. printf("Entering cIGraph_attribute_add_edges\n");
  221. #endif
  222. int i,j;
  223. VALUE edge_array = ((VALUE*)graph->attr)[1];
  224. VALUE values;
  225. if(attr){
  226. //If the only record is of type PY_OBJ then use the values as attributes
  227. if(((igraph_i_attribute_record_t*)VECTOR(*attr)[0])->type == IGRAPH_ATTRIBUTE_PY_OBJECT){
  228. values = (VALUE)((igraph_i_attribute_record_t*)VECTOR(*attr)[0])->value;
  229. Check_Type(values, T_ARRAY);
  230. for(i=0;i<RARRAY(values)->len;i++){
  231. rb_ary_push(edge_array, RARRAY(values)->ptr[i]);
  232. }
  233. //Otherwise read each attriute into hashes and use those
  234. } else {
  235. for(i=0;i<igraph_vector_size(edges)/2;i++){
  236. VALUE record;
  237. igraph_i_attribute_record_t *attr_rec;
  238. char *s;
  239. record = rb_hash_new();
  240. for (j=0; j<igraph_vector_ptr_size(attr); j++) {
  241. VALUE key;
  242. VALUE value;
  243. //Add key value pair
  244. attr_rec = VECTOR(*attr)[j];
  245. key = rb_str_new2(attr_rec->name);
  246. switch (attr_rec->type) {
  247. case IGRAPH_ATTRIBUTE_NUMERIC:
  248. value=rb_float_new((double)VECTOR(*(igraph_vector_t*)attr_rec->value)[i]);
  249. break;
  250. case IGRAPH_ATTRIBUTE_STRING:
  251. igraph_strvector_get((igraph_strvector_t*)attr_rec->value, i, &s);
  252. value=rb_str_new2(s);
  253. break;
  254. default:
  255. IGRAPH_WARNING("unsupported attribute type (not string and not numeric)");
  256. value=Qnil;
  257. break;
  258. }
  259. rb_hash_aset(record,key,value);
  260. }
  261. rb_ary_push(edge_array,record);
  262. }
  263. }
  264. }
  265. #ifdef DEBUG
  266. printf("Leaving cIGraph_attribute_add_edges\n");
  267. #endif
  268. return IGRAPH_SUCCESS;
  269. }
  270. /* Deleting edges */
  271. void cIGraph_attribute_delete_edges(igraph_t *graph, const igraph_vector_t *idx) {
  272. #ifdef DEBUG
  273. printf("Entering cIGraph_attribute_delete_edges\n");
  274. #endif
  275. int i;
  276. VALUE edge_array = ((VALUE*)graph->attr)[1];
  277. VALUE n_e_ary = rb_ary_new();
  278. for(i=0;i<igraph_vector_size(idx);i++){
  279. if(VECTOR(*idx)[i] != 0)
  280. rb_ary_store(n_e_ary,VECTOR(*idx)[i]-1,rb_ary_entry(edge_array,i));
  281. }
  282. ((VALUE*)graph->attr)[1] = n_e_ary;
  283. #ifdef DEBUG
  284. printf("Leaving cIGraph_attribute_delete_edges\n");
  285. #endif
  286. return;
  287. }
  288. /* Permuting edges */
  289. int cIGraph_attribute_permute_edges(igraph_t *graph,
  290. const igraph_vector_t *idx) {
  291. #ifdef DEBUG
  292. printf("Entering cIGraph_attribute_permute_edges\n");
  293. #endif
  294. int i;
  295. VALUE edge_array = ((VALUE*)graph->attr)[1];
  296. VALUE n_e_ary = rb_ary_new();
  297. for(i=0;i<igraph_vector_size(idx);i++){
  298. rb_ary_push(n_e_ary,rb_ary_entry(edge_array,VECTOR(*idx)[i]));
  299. }
  300. ((VALUE*)graph->attr)[1] = n_e_ary;
  301. #ifdef DEBUG
  302. printf("Leaving cIGraph_attribute_permute_edges\n");
  303. #endif
  304. return 0;
  305. }
  306. VALUE keys_to_strvec(VALUE data, VALUE arr){
  307. VALUE key = rb_ary_entry(data, 0);
  308. VALUE val = rb_ary_entry(data, 1);
  309. VALUE rb_names = rb_ary_entry(arr, 0);
  310. VALUE rb_types = rb_ary_entry(arr, 1);
  311. VALUE str = StringValue(key);
  312. rb_ary_push(rb_names,str);
  313. if(TYPE(val) == T_STRING){
  314. rb_ary_push(rb_types,INT2FIX(IGRAPH_ATTRIBUTE_STRING));
  315. } else if (TYPE(val) == T_FLOAT || TYPE(val) == T_FIXNUM){
  316. rb_ary_push(rb_types,INT2FIX(IGRAPH_ATTRIBUTE_NUMERIC));
  317. } else {
  318. rb_ary_push(rb_types,INT2FIX(IGRAPH_ATTRIBUTE_PY_OBJECT));
  319. }
  320. return data;
  321. }
  322. /* Getting attribute names and types */
  323. int cIGraph_attribute_get_info(const igraph_t *graph,
  324. igraph_strvector_t *gnames,
  325. igraph_vector_t *gtypes,
  326. igraph_strvector_t *vnames,
  327. igraph_vector_t *vtypes,
  328. igraph_strvector_t *enames,
  329. igraph_vector_t *etypes) {
  330. #ifdef DEBUG
  331. printf("Entering cIGraph_attribute_get_info\n");
  332. #endif
  333. igraph_strvector_t *names[3] = { vnames, enames, gnames };
  334. igraph_vector_t *types[3] = { vtypes, etypes, gtypes };
  335. long int i,j;
  336. for (i=0; i<3; i++) {
  337. igraph_strvector_t *n = names[i];
  338. igraph_vector_t *t = types[i];
  339. VALUE rb_names = rb_ary_new();
  340. VALUE rb_types = rb_ary_new();
  341. VALUE obj_hash;
  342. //Graph attributes are different
  343. if (i != 2){
  344. VALUE store = ((VALUE*)graph->attr)[i];
  345. VALUE obj = RARRAY(store)->ptr[0];
  346. obj_hash = Qnil;
  347. if(rb_funcall(obj, rb_intern("respond_to?"), 1, rb_str_new2("to_hash")) == Qtrue){
  348. obj_hash = rb_funcall(obj, rb_intern("to_hash"), 0);
  349. }
  350. } else {
  351. obj_hash = ((VALUE*)graph->attr)[2];
  352. }
  353. if(!NIL_P(obj_hash)){
  354. //Take the keys of the hash, convert to strings and put in vector n
  355. rb_iterate(rb_each, obj_hash, keys_to_strvec, rb_ary_new3(2,rb_names,rb_types));
  356. }
  357. //Push names onto n and types onto t
  358. for(j=0;j<RARRAY(rb_names)->len;j++){
  359. igraph_strvector_add(n, RSTRING(RARRAY(rb_names)->ptr[j])->ptr);
  360. igraph_vector_push_back(t, NUM2INT(RARRAY(rb_types)->ptr[j]));
  361. }
  362. }
  363. #ifdef DEBUG
  364. printf("Leaving cIGraph_attribute_get_info\n");
  365. #endif
  366. return 0;
  367. }
  368. /* Checks whether the graph has a graph/vertex/edge attribute with the given name */
  369. igraph_bool_t cIGraph_attribute_has_attr(const igraph_t *graph,
  370. igraph_attribute_elemtype_t type,
  371. const char* name) {
  372. #ifdef DEBUG
  373. printf("Entering cIGraph_attribute_has_attr\n");
  374. #endif
  375. long int attrnum;
  376. igraph_bool_t res = 0;
  377. VALUE obj;
  378. switch (type) {
  379. case IGRAPH_ATTRIBUTE_GRAPH: attrnum=0; break;
  380. case IGRAPH_ATTRIBUTE_VERTEX: attrnum=1; break;
  381. case IGRAPH_ATTRIBUTE_EDGE: attrnum=2; break;
  382. default: return 0; break;
  383. }
  384. obj = ((VALUE*)graph->attr)[attrnum];
  385. if (attrnum != 2)
  386. obj = RARRAY(obj)->ptr[0];
  387. if(rb_funcall(obj,rb_intern("include?"), 1, rb_str_new2(name))){
  388. res = 1;
  389. }
  390. #ifdef DEBUG
  391. printf("Leaving cIGraph_attribute_has_attr\n");
  392. #endif
  393. return res;
  394. }
  395. /* Returns the type of a given attribute */
  396. int cIGraph_attribute_get_type(const igraph_t *graph,
  397. igraph_attribute_type_t *type,
  398. igraph_attribute_elemtype_t elemtype,
  399. const char *name) {
  400. #ifdef DEBUG
  401. printf("Entering cIGraph_attribute_get_type\n");
  402. #endif
  403. long int attrnum;
  404. VALUE obj;
  405. VALUE val;
  406. switch (elemtype) {
  407. case IGRAPH_ATTRIBUTE_GRAPH: attrnum=0; break;
  408. case IGRAPH_ATTRIBUTE_VERTEX: attrnum=1; break;
  409. case IGRAPH_ATTRIBUTE_EDGE: attrnum=2; break;
  410. default: return 0; break;
  411. }
  412. obj = ((VALUE*)graph->attr)[attrnum];
  413. if (attrnum != 2)
  414. obj = RARRAY(obj)->ptr[0];
  415. if(rb_funcall(obj,rb_intern("includes"), rb_str_new2(name))){
  416. val = rb_hash_aref(obj,rb_str_new2(name));
  417. if (TYPE(val) == T_STRING){
  418. *type = IGRAPH_ATTRIBUTE_STRING;
  419. } else if (TYPE(val) == T_FIXNUM || TYPE(val) == T_FLOAT){
  420. *type = IGRAPH_ATTRIBUTE_NUMERIC;
  421. } else {
  422. *type = IGRAPH_ATTRIBUTE_PY_OBJECT;
  423. }
  424. }
  425. #ifdef DEBUG
  426. printf("Leaving cIGraph_attribute_get_type\n");
  427. #endif
  428. return 0;
  429. }
  430. /* Getting numeric graph attributes */
  431. int cIGraph_get_numeric_graph_attr(const igraph_t *graph,
  432. const char *name, igraph_vector_t *value) {
  433. #ifdef DEBUG
  434. printf("Entering cIGraph_get_numeric_graph_attr\n");
  435. #endif
  436. VALUE val;
  437. val = rb_hash_aref(((VALUE*)graph->attr)[2],rb_str_new2(name));
  438. VECTOR(*value)[0] = NUM2DBL(val);
  439. #ifdef DEBUG
  440. printf("Leaving cIGraph_get_numeric_graph_attr\n");
  441. #endif
  442. return 0;
  443. }
  444. /* Getting string graph attributes */
  445. int cIGraph_get_string_graph_attr(const igraph_t *graph,
  446. const char *name, igraph_strvector_t *value) {
  447. #ifdef DEBUG
  448. printf("Entering cIGraph_get_string_graph_attr\n");
  449. #endif
  450. VALUE val;
  451. val = rb_hash_aref(((VALUE*)graph->attr)[2],rb_str_new2(name));
  452. igraph_strvector_set(value,0,RSTRING(val)->ptr);
  453. #ifdef DEBUG
  454. printf("Leaving cIGraph_get_string_graph_attr\n");
  455. #endif
  456. return 0;
  457. }
  458. /* Getting numeric vertex attributes */
  459. int cIGraph_get_numeric_vertex_attr(const igraph_t *graph,
  460. const char *name,
  461. igraph_vs_t vs,
  462. igraph_vector_t *value) {
  463. #ifdef DEBUG
  464. printf("Entering cIGraph_get_numeric_vertex_attr\n");
  465. #endif
  466. VALUE array = ((VALUE*)graph->attr)[0];
  467. VALUE val, vertex;
  468. igraph_vit_t it;
  469. int i = 0;
  470. IGRAPH_CHECK(igraph_vit_create(graph, vs, &it));
  471. IGRAPH_FINALLY(igraph_vit_destroy, &it);
  472. IGRAPH_CHECK(igraph_vector_resize(value, IGRAPH_VIT_SIZE(it)));
  473. while(!IGRAPH_VIT_END(it)){
  474. vertex = RARRAY(array)->ptr[(int)IGRAPH_VIT_GET(it)];
  475. val = rb_hash_aref(vertex,rb_str_new2(name));
  476. if(val == Qnil)
  477. val = rb_float_new(NAN);
  478. VECTOR(*value)[i] = NUM2DBL(val);
  479. IGRAPH_VIT_NEXT(it);
  480. i++;
  481. }
  482. igraph_vit_destroy(&it);
  483. IGRAPH_FINALLY_CLEAN(1);
  484. #ifdef DEBUG
  485. printf("Leaving cIGraph_get_numeric_vertex_attr\n");
  486. #endif
  487. return 0;
  488. }
  489. /* Getting string vertex attributes */
  490. int cIGraph_get_string_vertex_attr(const igraph_t *graph,
  491. const char *name,
  492. igraph_vs_t vs,
  493. igraph_strvector_t *value) {
  494. #ifdef DEBUG
  495. printf("Entering cIGraph_get_string_vertex_attr\n");
  496. #endif
  497. VALUE array = ((VALUE*)graph->attr)[0];
  498. VALUE val, vertex;
  499. igraph_vit_t it;
  500. int i=0;
  501. IGRAPH_CHECK(igraph_vit_create(graph, vs, &it));
  502. IGRAPH_FINALLY(igraph_vit_destroy, &it);
  503. IGRAPH_CHECK(igraph_strvector_resize(value, IGRAPH_VIT_SIZE(it)));
  504. while(!IGRAPH_VIT_END(it)){
  505. vertex = RARRAY(array)->ptr[(int)IGRAPH_VIT_GET(it)];
  506. val = rb_hash_aref(vertex,rb_str_new2(name));
  507. if(val == Qnil)
  508. val = rb_str_new2("");
  509. igraph_strvector_set(value,i,RSTRING(val)->ptr);
  510. IGRAPH_VIT_NEXT(it);
  511. i++;
  512. }
  513. igraph_vit_destroy(&it);
  514. IGRAPH_FINALLY_CLEAN(1);
  515. #ifdef DEBUG
  516. printf("Leaving cIGraph_get_string_vertex_attr\n");
  517. #endif
  518. return 0;
  519. }
  520. /* Getting numeric edge attributes */
  521. int cIGraph_get_numeric_edge_attr(const igraph_t *graph,
  522. const char *name,
  523. igraph_es_t es,
  524. igraph_vector_t *value) {
  525. #ifdef DEBUG
  526. printf("Entering cIGraph_get_numeric_edge_attr\n");
  527. #endif
  528. VALUE array = ((VALUE*)graph->attr)[1];
  529. VALUE val, vertex;
  530. igraph_eit_t it;
  531. int i = 0;
  532. IGRAPH_CHECK(igraph_eit_create(graph, es, &it));
  533. IGRAPH_FINALLY(igraph_eit_destroy, &it);
  534. IGRAPH_CHECK(igraph_vector_resize(value, IGRAPH_EIT_SIZE(it)));
  535. while(!IGRAPH_EIT_END(it)){
  536. vertex = RARRAY(array)->ptr[(int)IGRAPH_EIT_GET(it)];
  537. val = rb_hash_aref(vertex,rb_str_new2(name));
  538. if(val == Qnil)
  539. val = rb_float_new(NAN);
  540. VECTOR(*value)[i] = NUM2DBL(val);
  541. IGRAPH_EIT_NEXT(it);
  542. i++;
  543. }
  544. igraph_eit_destroy(&it);
  545. IGRAPH_FINALLY_CLEAN(1);
  546. #ifdef DEBUG
  547. printf("Leaving cIGraph_get_numeric_edge_attr\n");
  548. #endif
  549. return 0;
  550. }
  551. /* Getting string edge attributes */
  552. int cIGraph_get_string_edge_attr(const igraph_t *graph,
  553. const char *name,
  554. igraph_es_t es,
  555. igraph_strvector_t *value) {
  556. #ifdef DEBUG
  557. printf("Entering cIGraph_get_string_edge_attr\n");
  558. #endif
  559. VALUE array = ((VALUE*)graph->attr)[1];
  560. VALUE val, vertex;
  561. igraph_eit_t it;
  562. int i=0;
  563. IGRAPH_CHECK(igraph_eit_create(graph, es, &it));
  564. IGRAPH_FINALLY(igraph_eit_destroy, &it);
  565. IGRAPH_CHECK(igraph_strvector_resize(value, IGRAPH_EIT_SIZE(it)));
  566. while(!IGRAPH_EIT_END(it)){
  567. vertex = RARRAY(array)->ptr[(int)IGRAPH_EIT_GET(it)];
  568. val = rb_hash_aref(vertex,rb_str_new2(name));
  569. if(val == Qnil)
  570. val = rb_str_new2("");
  571. igraph_strvector_set(value,i,RSTRING(val)->ptr);
  572. IGRAPH_EIT_NEXT(it);
  573. i++;
  574. }
  575. igraph_eit_destroy(&it);
  576. IGRAPH_FINALLY_CLEAN(1);
  577. #ifdef DEBUG
  578. printf("Leaving cIGraph_get_string_edge_attr\n");
  579. #endif
  580. return 0;
  581. }

Ruby binding for the igraph library.