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

Ruby binding for the igraph library.