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
19 years ago
19 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765
  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. } else {
  191. //Default: Add numbered vertices.
  192. for(i=0;i<nv;i++){
  193. rb_ary_push(vertex_array,INT2NUM(i));
  194. }
  195. }
  196. #ifdef DEBUG
  197. printf("Leaving cIGraph_attribute_add_vertices\n");
  198. #endif
  199. return IGRAPH_SUCCESS;
  200. }
  201. /* Deleting vertices */
  202. void cIGraph_attribute_delete_vertices(igraph_t *graph,
  203. const igraph_vector_t *eidx,
  204. const igraph_vector_t *vidx) {
  205. #ifdef DEBUG
  206. printf("Entering cIGraph_attribute_delete_vertices\n");
  207. #endif
  208. int i;
  209. VALUE vertex_array = ((VALUE*)graph->attr)[0];
  210. VALUE edge_array = ((VALUE*)graph->attr)[1];
  211. VALUE n_v_ary = rb_ary_new();
  212. VALUE n_e_ary = rb_ary_new();
  213. for(i=0;i<igraph_vector_size(vidx);i++){
  214. if(VECTOR(*vidx)[i] != 0)
  215. rb_ary_store(n_v_ary,VECTOR(*vidx)[i]-1,rb_ary_entry(vertex_array,i));
  216. }
  217. for(i=0;i<igraph_vector_size(eidx);i++){
  218. if(VECTOR(*eidx)[i] != 0)
  219. rb_ary_store(n_e_ary,VECTOR(*eidx)[i]-1,rb_ary_entry(edge_array,i));
  220. }
  221. ((VALUE*)graph->attr)[0] = n_v_ary;
  222. ((VALUE*)graph->attr)[1] = n_e_ary;
  223. #ifdef DEBUG
  224. printf("Leaving cIGraph_attribute_delete_vertices\n");
  225. #endif
  226. return;
  227. }
  228. /* Adding edges */
  229. int cIGraph_attribute_add_edges(igraph_t *graph,
  230. const igraph_vector_t *edges,
  231. igraph_vector_ptr_t *attr) {
  232. #ifdef DEBUG
  233. printf("Entering cIGraph_attribute_add_edges\n");
  234. #endif
  235. int i,j;
  236. VALUE edge_array = ((VALUE*)graph->attr)[1];
  237. VALUE values;
  238. if(attr){
  239. //If the only record is of type PY_OBJ then use the values as attributes
  240. if(((igraph_i_attribute_record_t*)VECTOR(*attr)[0])->type == IGRAPH_ATTRIBUTE_PY_OBJECT){
  241. values = (VALUE)((igraph_i_attribute_record_t*)VECTOR(*attr)[0])->value;
  242. Check_Type(values, T_ARRAY);
  243. for(i=0;i<RARRAY(values)->len;i++){
  244. rb_ary_push(edge_array, RARRAY(values)->ptr[i]);
  245. }
  246. //Otherwise read each attriute into hashes and use those
  247. } else {
  248. for(i=0;i<igraph_vector_size(edges)/2;i++){
  249. VALUE record;
  250. igraph_i_attribute_record_t *attr_rec;
  251. char *s;
  252. record = rb_hash_new();
  253. for (j=0; j<igraph_vector_ptr_size(attr); j++) {
  254. VALUE key;
  255. VALUE value;
  256. //Add key value pair
  257. attr_rec = VECTOR(*attr)[j];
  258. key = rb_str_new2(attr_rec->name);
  259. switch (attr_rec->type) {
  260. case IGRAPH_ATTRIBUTE_NUMERIC:
  261. value=rb_float_new((double)VECTOR(*(igraph_vector_t*)attr_rec->value)[i]);
  262. break;
  263. case IGRAPH_ATTRIBUTE_STRING:
  264. igraph_strvector_get((igraph_strvector_t*)attr_rec->value, i, &s);
  265. value=rb_str_new2(s);
  266. break;
  267. default:
  268. IGRAPH_WARNING("unsupported attribute type (not string and not numeric)");
  269. value=Qnil;
  270. break;
  271. }
  272. rb_hash_aset(record,key,value);
  273. }
  274. rb_ary_push(edge_array,record);
  275. }
  276. }
  277. }
  278. #ifdef DEBUG
  279. printf("Leaving cIGraph_attribute_add_edges\n");
  280. #endif
  281. return IGRAPH_SUCCESS;
  282. }
  283. /* Deleting edges */
  284. void cIGraph_attribute_delete_edges(igraph_t *graph, const igraph_vector_t *idx) {
  285. #ifdef DEBUG
  286. printf("Entering cIGraph_attribute_delete_edges\n");
  287. #endif
  288. int i;
  289. VALUE edge_array = ((VALUE*)graph->attr)[1];
  290. VALUE n_e_ary = rb_ary_new();
  291. for(i=0;i<igraph_vector_size(idx);i++){
  292. if(VECTOR(*idx)[i] != 0)
  293. rb_ary_store(n_e_ary,VECTOR(*idx)[i]-1,rb_ary_entry(edge_array,i));
  294. }
  295. ((VALUE*)graph->attr)[1] = n_e_ary;
  296. #ifdef DEBUG
  297. printf("Leaving cIGraph_attribute_delete_edges\n");
  298. #endif
  299. return;
  300. }
  301. /* Permuting edges */
  302. int cIGraph_attribute_permute_edges(igraph_t *graph,
  303. const igraph_vector_t *idx) {
  304. #ifdef DEBUG
  305. printf("Entering cIGraph_attribute_permute_edges\n");
  306. #endif
  307. int i;
  308. VALUE edge_array = ((VALUE*)graph->attr)[1];
  309. VALUE n_e_ary = rb_ary_new();
  310. for(i=0;i<igraph_vector_size(idx);i++){
  311. rb_ary_push(n_e_ary,rb_ary_entry(edge_array,VECTOR(*idx)[i]));
  312. }
  313. ((VALUE*)graph->attr)[1] = n_e_ary;
  314. #ifdef DEBUG
  315. printf("Leaving cIGraph_attribute_permute_edges\n");
  316. #endif
  317. return 0;
  318. }
  319. VALUE keys_to_strvec(VALUE data, VALUE arr){
  320. VALUE key = rb_ary_entry(data, 0);
  321. VALUE val = rb_ary_entry(data, 1);
  322. VALUE rb_names = rb_ary_entry(arr, 0);
  323. VALUE rb_types = rb_ary_entry(arr, 1);
  324. VALUE str = StringValue(key);
  325. rb_ary_push(rb_names,str);
  326. if(TYPE(val) == T_STRING){
  327. rb_ary_push(rb_types,INT2FIX(IGRAPH_ATTRIBUTE_STRING));
  328. } else if (TYPE(val) == T_FLOAT || TYPE(val) == T_FIXNUM){
  329. rb_ary_push(rb_types,INT2FIX(IGRAPH_ATTRIBUTE_NUMERIC));
  330. } else {
  331. rb_ary_push(rb_types,INT2FIX(IGRAPH_ATTRIBUTE_PY_OBJECT));
  332. }
  333. return data;
  334. }
  335. /* Getting attribute names and types */
  336. int cIGraph_attribute_get_info(const igraph_t *graph,
  337. igraph_strvector_t *gnames,
  338. igraph_vector_t *gtypes,
  339. igraph_strvector_t *vnames,
  340. igraph_vector_t *vtypes,
  341. igraph_strvector_t *enames,
  342. igraph_vector_t *etypes) {
  343. #ifdef DEBUG
  344. printf("Entering cIGraph_attribute_get_info\n");
  345. #endif
  346. igraph_strvector_t *names[3] = { vnames, enames, gnames };
  347. igraph_vector_t *types[3] = { vtypes, etypes, gtypes };
  348. long int i,j;
  349. for (i=0; i<3; i++) {
  350. igraph_strvector_t *n = names[i];
  351. igraph_vector_t *t = types[i];
  352. VALUE rb_names = rb_ary_new();
  353. VALUE rb_types = rb_ary_new();
  354. VALUE obj_hash;
  355. //Graph attributes are different
  356. if (i != 2){
  357. VALUE store = ((VALUE*)graph->attr)[i];
  358. VALUE obj = RARRAY(store)->ptr[0];
  359. obj_hash = Qnil;
  360. if(rb_funcall(obj, rb_intern("respond_to?"), 1, rb_str_new2("to_hash")) == Qtrue){
  361. obj_hash = rb_funcall(obj, rb_intern("to_hash"), 0);
  362. }
  363. } else {
  364. obj_hash = ((VALUE*)graph->attr)[2];
  365. }
  366. if(!NIL_P(obj_hash)){
  367. //Take the keys of the hash, convert to strings and put in vector n
  368. rb_iterate(rb_each, obj_hash, keys_to_strvec, rb_ary_new3(2,rb_names,rb_types));
  369. }
  370. //Push names onto n and types onto t
  371. for(j=0;j<RARRAY(rb_names)->len;j++){
  372. igraph_strvector_add(n, RSTRING(RARRAY(rb_names)->ptr[j])->ptr);
  373. igraph_vector_push_back(t, NUM2INT(RARRAY(rb_types)->ptr[j]));
  374. }
  375. }
  376. #ifdef DEBUG
  377. printf("Leaving cIGraph_attribute_get_info\n");
  378. #endif
  379. return 0;
  380. }
  381. /* Checks whether the graph has a graph/vertex/edge attribute with the given name */
  382. igraph_bool_t cIGraph_attribute_has_attr(const igraph_t *graph,
  383. igraph_attribute_elemtype_t type,
  384. const char* name) {
  385. #ifdef DEBUG
  386. printf("Entering cIGraph_attribute_has_attr\n");
  387. #endif
  388. long int attrnum;
  389. igraph_bool_t res = 0;
  390. VALUE obj;
  391. switch (type) {
  392. case IGRAPH_ATTRIBUTE_GRAPH: attrnum=0; break;
  393. case IGRAPH_ATTRIBUTE_VERTEX: attrnum=1; break;
  394. case IGRAPH_ATTRIBUTE_EDGE: attrnum=2; break;
  395. default: return 0; break;
  396. }
  397. obj = ((VALUE*)graph->attr)[attrnum];
  398. if (attrnum != 2)
  399. obj = RARRAY(obj)->ptr[0];
  400. if(rb_funcall(obj,rb_intern("include?"), 1, rb_str_new2(name))){
  401. res = 1;
  402. }
  403. #ifdef DEBUG
  404. printf("Leaving cIGraph_attribute_has_attr\n");
  405. #endif
  406. return res;
  407. }
  408. /* Returns the type of a given attribute */
  409. int cIGraph_attribute_get_type(const igraph_t *graph,
  410. igraph_attribute_type_t *type,
  411. igraph_attribute_elemtype_t elemtype,
  412. const char *name) {
  413. #ifdef DEBUG
  414. printf("Entering cIGraph_attribute_get_type\n");
  415. #endif
  416. long int attrnum;
  417. VALUE obj;
  418. VALUE val;
  419. switch (elemtype) {
  420. case IGRAPH_ATTRIBUTE_GRAPH: attrnum=0; break;
  421. case IGRAPH_ATTRIBUTE_VERTEX: attrnum=1; break;
  422. case IGRAPH_ATTRIBUTE_EDGE: attrnum=2; break;
  423. default: return 0; break;
  424. }
  425. obj = ((VALUE*)graph->attr)[attrnum];
  426. if (attrnum != 2)
  427. obj = RARRAY(obj)->ptr[0];
  428. if(rb_funcall(obj,rb_intern("includes"), rb_str_new2(name))){
  429. val = rb_hash_aref(obj,rb_str_new2(name));
  430. if (TYPE(val) == T_STRING){
  431. *type = IGRAPH_ATTRIBUTE_STRING;
  432. } else if (TYPE(val) == T_FIXNUM || TYPE(val) == T_FLOAT){
  433. *type = IGRAPH_ATTRIBUTE_NUMERIC;
  434. } else {
  435. *type = IGRAPH_ATTRIBUTE_PY_OBJECT;
  436. }
  437. }
  438. #ifdef DEBUG
  439. printf("Leaving cIGraph_attribute_get_type\n");
  440. #endif
  441. return 0;
  442. }
  443. /* Getting numeric graph attributes */
  444. int cIGraph_get_numeric_graph_attr(const igraph_t *graph,
  445. const char *name, igraph_vector_t *value) {
  446. #ifdef DEBUG
  447. printf("Entering cIGraph_get_numeric_graph_attr\n");
  448. #endif
  449. VALUE val;
  450. val = rb_hash_aref(((VALUE*)graph->attr)[2],rb_str_new2(name));
  451. VECTOR(*value)[0] = NUM2DBL(val);
  452. #ifdef DEBUG
  453. printf("Leaving cIGraph_get_numeric_graph_attr\n");
  454. #endif
  455. return 0;
  456. }
  457. /* Getting string graph attributes */
  458. int cIGraph_get_string_graph_attr(const igraph_t *graph,
  459. const char *name, igraph_strvector_t *value) {
  460. #ifdef DEBUG
  461. printf("Entering cIGraph_get_string_graph_attr\n");
  462. #endif
  463. VALUE val;
  464. val = rb_hash_aref(((VALUE*)graph->attr)[2],rb_str_new2(name));
  465. igraph_strvector_set(value,0,RSTRING(val)->ptr);
  466. #ifdef DEBUG
  467. printf("Leaving cIGraph_get_string_graph_attr\n");
  468. #endif
  469. return 0;
  470. }
  471. /* Getting numeric vertex attributes */
  472. int cIGraph_get_numeric_vertex_attr(const igraph_t *graph,
  473. const char *name,
  474. igraph_vs_t vs,
  475. igraph_vector_t *value) {
  476. #ifdef DEBUG
  477. printf("Entering cIGraph_get_numeric_vertex_attr\n");
  478. #endif
  479. VALUE array = ((VALUE*)graph->attr)[0];
  480. VALUE val, vertex;
  481. igraph_vit_t it;
  482. int i = 0;
  483. IGRAPH_CHECK(igraph_vit_create(graph, vs, &it));
  484. IGRAPH_FINALLY(igraph_vit_destroy, &it);
  485. IGRAPH_CHECK(igraph_vector_resize(value, IGRAPH_VIT_SIZE(it)));
  486. while(!IGRAPH_VIT_END(it)){
  487. vertex = RARRAY(array)->ptr[(int)IGRAPH_VIT_GET(it)];
  488. val = rb_hash_aref(vertex,rb_str_new2(name));
  489. if(val == Qnil)
  490. val = rb_float_new(NAN);
  491. VECTOR(*value)[i] = NUM2DBL(val);
  492. IGRAPH_VIT_NEXT(it);
  493. i++;
  494. }
  495. igraph_vit_destroy(&it);
  496. IGRAPH_FINALLY_CLEAN(1);
  497. #ifdef DEBUG
  498. printf("Leaving cIGraph_get_numeric_vertex_attr\n");
  499. #endif
  500. return 0;
  501. }
  502. /* Getting string vertex attributes */
  503. int cIGraph_get_string_vertex_attr(const igraph_t *graph,
  504. const char *name,
  505. igraph_vs_t vs,
  506. igraph_strvector_t *value) {
  507. #ifdef DEBUG
  508. printf("Entering cIGraph_get_string_vertex_attr\n");
  509. #endif
  510. VALUE array = ((VALUE*)graph->attr)[0];
  511. VALUE val, vertex;
  512. igraph_vit_t it;
  513. int i=0;
  514. IGRAPH_CHECK(igraph_vit_create(graph, vs, &it));
  515. IGRAPH_FINALLY(igraph_vit_destroy, &it);
  516. IGRAPH_CHECK(igraph_strvector_resize(value, IGRAPH_VIT_SIZE(it)));
  517. while(!IGRAPH_VIT_END(it)){
  518. vertex = RARRAY(array)->ptr[(int)IGRAPH_VIT_GET(it)];
  519. val = rb_hash_aref(vertex,rb_str_new2(name));
  520. if(val == Qnil)
  521. val = rb_str_new2("");
  522. igraph_strvector_set(value,i,RSTRING(val)->ptr);
  523. IGRAPH_VIT_NEXT(it);
  524. i++;
  525. }
  526. igraph_vit_destroy(&it);
  527. IGRAPH_FINALLY_CLEAN(1);
  528. #ifdef DEBUG
  529. printf("Leaving cIGraph_get_string_vertex_attr\n");
  530. #endif
  531. return 0;
  532. }
  533. /* Getting numeric edge attributes */
  534. int cIGraph_get_numeric_edge_attr(const igraph_t *graph,
  535. const char *name,
  536. igraph_es_t es,
  537. igraph_vector_t *value) {
  538. #ifdef DEBUG
  539. printf("Entering cIGraph_get_numeric_edge_attr\n");
  540. #endif
  541. VALUE array = ((VALUE*)graph->attr)[1];
  542. VALUE val, vertex;
  543. igraph_eit_t it;
  544. int i = 0;
  545. IGRAPH_CHECK(igraph_eit_create(graph, es, &it));
  546. IGRAPH_FINALLY(igraph_eit_destroy, &it);
  547. IGRAPH_CHECK(igraph_vector_resize(value, IGRAPH_EIT_SIZE(it)));
  548. while(!IGRAPH_EIT_END(it)){
  549. vertex = RARRAY(array)->ptr[(int)IGRAPH_EIT_GET(it)];
  550. val = rb_hash_aref(vertex,rb_str_new2(name));
  551. if(val == Qnil)
  552. val = rb_float_new(NAN);
  553. VECTOR(*value)[i] = NUM2DBL(val);
  554. IGRAPH_EIT_NEXT(it);
  555. i++;
  556. }
  557. igraph_eit_destroy(&it);
  558. IGRAPH_FINALLY_CLEAN(1);
  559. #ifdef DEBUG
  560. printf("Leaving cIGraph_get_numeric_edge_attr\n");
  561. #endif
  562. return 0;
  563. }
  564. /* Getting string edge attributes */
  565. int cIGraph_get_string_edge_attr(const igraph_t *graph,
  566. const char *name,
  567. igraph_es_t es,
  568. igraph_strvector_t *value) {
  569. #ifdef DEBUG
  570. printf("Entering cIGraph_get_string_edge_attr\n");
  571. #endif
  572. VALUE array = ((VALUE*)graph->attr)[1];
  573. VALUE val, vertex;
  574. igraph_eit_t it;
  575. int i=0;
  576. IGRAPH_CHECK(igraph_eit_create(graph, es, &it));
  577. IGRAPH_FINALLY(igraph_eit_destroy, &it);
  578. IGRAPH_CHECK(igraph_strvector_resize(value, IGRAPH_EIT_SIZE(it)));
  579. while(!IGRAPH_EIT_END(it)){
  580. vertex = RARRAY(array)->ptr[(int)IGRAPH_EIT_GET(it)];
  581. val = rb_hash_aref(vertex,rb_str_new2(name));
  582. if(val == Qnil)
  583. val = rb_str_new2("");
  584. igraph_strvector_set(value,i,RSTRING(val)->ptr);
  585. IGRAPH_EIT_NEXT(it);
  586. i++;
  587. }
  588. igraph_eit_destroy(&it);
  589. IGRAPH_FINALLY_CLEAN(1);
  590. #ifdef DEBUG
  591. printf("Leaving cIGraph_get_string_edge_attr\n");
  592. #endif
  593. return 0;
  594. }

Ruby binding for the igraph library.