将A和arma :: mat邻接矩阵转换为C中的igraph图(Rcpp)

时间:2019-09-06 11:03:04

标签: type-conversion igraph rcpp armadillo

我在处理矩阵的某些(Rcpp)代码中使用Armadillo对象。

这些矩阵是邻接矩阵,尽管我可以通过igraph来完成,但是我需要快速计算底层网络的组成部分。

但是我已经无法将邻接矩阵转换为可以与igraph一起使用的东西。

#include <RcppArmadillo.h>
#include <iostream>
#include <igraph-0.7.1\include\igraph.h>

using namespace arma;

// [[Rcpp::depends(RcppArmadillo)]]

// [[Rcpp::export]]
vec component_membership(const mat& adjacencymatrix) {
  igraph_t  g;
  igraph_adjacency(&g,&adjacencymatrix,IGRAPH_ADJ_DIRECTED);
  // here is more code that is immaterial to my problem
}

编译时会抱怨

 cannot convert 'const mat* {aka const arma::Mat<double>*}' to  
  'igraph_matrix_t*' for argument '2' to 
  'int igraph_adjacency(igraph_t*, igraph_matrix_t*, igraph_adjacency_t)'

我理解为什么会这样:我相信igraph_matrix_tarma::matrix必须是根本不同的数据类型。如何进行转换,即如何轻松解决此问题?

2 个答案:

答案 0 :(得分:3)

您怀疑igraph_matrix_tarma::matrix是完全不同的类型。 igraph documentation没有列出使用C数组构造igraph_matrix_t的方法,因此我认为必须手动完成。这样的事情可能会起作用(完全未经测试!):

igraph_matrix_t *m;
int rc = igraph_matrix_init(m, mat.n_rows, mat.n_cols);
for (unsigned long j = 0; j < mat.n_cols; ++j)
    for (unsigned long i = 0; i < mat.n_rows; ++i)
        igraph_matrix_set(m, i, j, mat(i, j));              

答案 1 :(得分:0)

按照@Ralf_Stubner的建议,我最终使用了以下代码。不确定它是否聪明,我想还是应该分享它

void armamat_to_igraph_matrix(const mat &x_in, igraph_matrix_t *x_out) {
  igraph_matrix_init(x_out, x_in.n_rows, x_in.n_cols);
  for (unsigned long j = 0; j < x_in.n_cols; ++j)
    for (unsigned long i = 0; i < x_in.n_rows; ++i)
      igraph_matrix_set(x_out, i, j, x_in(i, j));        
  return;
}
void igraph_vector_to_armauvec(const igraph_vector_t *x_in, uvec  &x_out) {
  x_out = uvec(igraph_vector_size(x_in));
  for (unsigned long j = 0; j < igraph_vector_size(x_in); ++j)
    x_out(j) = igraph_vector_e(x_in,j);        
  return;
}
void igraph_vector_to_armavec(const igraph_vector_t *x_in, vec  &x_out) {
  x_out = vec(igraph_vector_size(x_in));
  for (unsigned long j = 0; j < igraph_vector_size(x_in); ++j)
    x_out(j) = igraph_vector_e(x_in,j);        
  return;
}