Пример #1
0
int igraph_i_eigen_matrix_symmetric_arpack(const igraph_matrix_t *A, 
			   const igraph_sparsemat_t *sA, 
			   igraph_arpack_function_t *fun, 
			   int n, void *extra,
			   const igraph_eigen_which_t *which, 
			   igraph_arpack_options_t *options,
			   igraph_arpack_storage_t *storage,
			   igraph_vector_t *values, 
			   igraph_matrix_t *vectors) {
  
  /* For ARPACK we need a matrix multiplication operation.
     This can be done in any format, so everything is fine, 
     we don't have to convert. */

  igraph_i_eigen_matrix_sym_arpack_data_t myextra = { A, sA };

  if (!options) { 
    IGRAPH_ERROR("`options' must be given for ARPACK algorithm",
		 IGRAPH_EINVAL);
  }

  if (which->pos == IGRAPH_EIGEN_BE) {
    return igraph_i_eigen_matrix_symmetric_arpack_be(A, sA, fun, n, extra,
						     which, options, storage,
						     values, vectors);
  } else {

    switch (which->pos) {
    case IGRAPH_EIGEN_LM:
      options->which[0]='L'; options->which[1]='M';
      options->nev=which->howmany;
      break;
    case IGRAPH_EIGEN_SM:
      options->which[0]='S'; options->which[1]='M';
      options->nev=which->howmany;
      break;
    case IGRAPH_EIGEN_LA:
      options->which[0]='L'; options->which[1]='A';
      options->nev=which->howmany;
      break;
    case IGRAPH_EIGEN_SA:
      options->which[0]='S'; options->which[1]='A';
      options->nev=which->howmany;
      break;
    case IGRAPH_EIGEN_ALL:
      options->which[0]='L'; options->which[1]='M';
      options->nev=n;
      break;
    case IGRAPH_EIGEN_INTERVAL:
      IGRAPH_ERROR("Interval of eigenvectors with ARPACK", 
		   IGRAPH_UNIMPLEMENTED);
      /* TODO */
      break;
    case IGRAPH_EIGEN_SELECT:
      IGRAPH_ERROR("Selected eigenvalues with ARPACK",
		   IGRAPH_UNIMPLEMENTED);
      /* TODO */
      break;
    default:
      /* This cannot happen */
      break;
    }

    options->n=n;
    options->ncv= 2*options->nev < n ? 2*options->nev : n;
    
    if (!fun) { 
      fun=igraph_i_eigen_matrix_sym_arpack_cb;
      extra=(void*) &myextra;
    }
    
    IGRAPH_CHECK(igraph_arpack_rssolve(fun, extra, options, storage, 
				       values, vectors));
    return 0;
  }
}
Пример #2
0
int igraph_i_eigen_matrix_symmetric_arpack_be(const igraph_matrix_t *A, 
			   const igraph_sparsemat_t *sA, 
			   igraph_arpack_function_t *fun, 
			   int n, void *extra,
			   const igraph_eigen_which_t *which, 
			   igraph_arpack_options_t *options,
			   igraph_arpack_storage_t *storage,
			   igraph_vector_t *values, 
			   igraph_matrix_t *vectors) {
  
  igraph_vector_t tmpvalues, tmpvalues2;
  igraph_matrix_t tmpvectors, tmpvectors2;
  igraph_i_eigen_matrix_sym_arpack_data_t myextra = { A, sA };  
  int low=(int) floor(which->howmany/2.0), high=(int) ceil(which->howmany/2.0);
  int l1, l2, w;

  if (low + high >= n) {
    IGRAPH_ERROR("Requested too many eigenvalues/vectors", IGRAPH_EINVAL);
  }

  if (!fun) { 
    fun=igraph_i_eigen_matrix_sym_arpack_cb;
    extra=(void*) &myextra;
  }
  
  IGRAPH_VECTOR_INIT_FINALLY(&tmpvalues, high);
  IGRAPH_MATRIX_INIT_FINALLY(&tmpvectors, n, high);
  IGRAPH_VECTOR_INIT_FINALLY(&tmpvalues2, low);
  IGRAPH_MATRIX_INIT_FINALLY(&tmpvectors2, n, low);

  options->n=n;
  options->nev=high;
  options->ncv= 2*options->nev < n ? 2*options->nev : n;
  options->which[0]='L'; options->which[1]='A';
  
  IGRAPH_CHECK(igraph_arpack_rssolve(fun, extra, options, storage, 
				     &tmpvalues, &tmpvectors));

  options->nev=low;
  options->ncv= 2*options->nev < n ? 2*options->nev : n;
  options->which[0]='S'; options->which[1]='A';

  IGRAPH_CHECK(igraph_arpack_rssolve(fun, extra, options, storage,
				     &tmpvalues2, &tmpvectors2));

  IGRAPH_CHECK(igraph_vector_resize(values, low+high));
  IGRAPH_CHECK(igraph_matrix_resize(vectors, n, low+high));
  
  l1=0; l2=0; w=0;
  while (w < which->howmany) {
    VECTOR(*values)[w] = VECTOR(tmpvalues)[l1];
    memcpy(&MATRIX(*vectors, 0, w), &MATRIX(tmpvectors, 0, l1), 
	   (size_t) n * sizeof(igraph_real_t));
    w++; l1++;
    if (w < which->howmany) {
      VECTOR(*values)[w] = VECTOR(tmpvalues2)[l2];
      memcpy(&MATRIX(*vectors, 0, w), &MATRIX(tmpvectors2, 0, l2), 
	     (size_t) n * sizeof(igraph_real_t));
      w++; l2++;
    }
  }

  igraph_matrix_destroy(&tmpvectors2);
  igraph_vector_destroy(&tmpvalues2);
  igraph_matrix_destroy(&tmpvectors);
  igraph_vector_destroy(&tmpvalues);
  IGRAPH_FINALLY_CLEAN(4);
    
  return 0;
}
Пример #3
0
int igraph_i_kleinberg(const igraph_t *graph, igraph_vector_t *vector,
		       igraph_real_t *value, igraph_bool_t scale,
		       igraph_arpack_options_t *options, int inout) {
  
  igraph_adjlist_t myinadjlist, myoutadjlist;
  igraph_adjlist_t *inadjlist, *outadjlist;
  igraph_vector_t tmp;
  igraph_vector_t values;
  igraph_matrix_t vectors;
  igraph_i_kleinberg_data_t extra;
  long int i;
  
  options->n=igraph_vcount(graph);
  options->start=1;
  
  IGRAPH_VECTOR_INIT_FINALLY(&values, 0);
  IGRAPH_MATRIX_INIT_FINALLY(&vectors, options->n, 1);
  IGRAPH_VECTOR_INIT_FINALLY(&tmp, options->n);
  
  if (inout==0) {
    inadjlist=&myinadjlist; 
    outadjlist=&myoutadjlist;
  } else if (inout==1) {
    inadjlist=&myoutadjlist;
    outadjlist=&myinadjlist;
  } else {
    /* This should not happen */
    IGRAPH_ERROR("Invalid 'inout' argument, plese do not call "
		 "this funtion directly", IGRAPH_FAILURE);
  }

  IGRAPH_CHECK(igraph_adjlist_init(graph, &myinadjlist, IGRAPH_IN));
  IGRAPH_FINALLY(igraph_adjlist_destroy, &myinadjlist);
  IGRAPH_CHECK(igraph_adjlist_init(graph, &myoutadjlist, IGRAPH_OUT));
  IGRAPH_FINALLY(igraph_adjlist_destroy, &myoutadjlist);

  IGRAPH_CHECK(igraph_degree(graph, &tmp, igraph_vss_all(), IGRAPH_ALL, 0));
  for (i=0; i<options->n; i++) {
    if (VECTOR(tmp)[i] != 0) { 
      MATRIX(vectors, i, 0) = VECTOR(tmp)[i];
    } else {
      MATRIX(vectors, i, 0) = 1.0;
    }
  }
	
  extra.in=inadjlist; extra.out=outadjlist; extra.tmp=&tmp;

  options->n = igraph_vcount(graph);
  options->nev = 1;
  options->ncv = 3;
  options->which[0]='L'; options->which[1]='M';
  options->start=1;		/* no random start vector */

  IGRAPH_CHECK(igraph_arpack_rssolve(igraph_i_kleinberg2, &extra,
				     options, 0, &values, &vectors));

  igraph_adjlist_destroy(&myoutadjlist);
  igraph_adjlist_destroy(&myinadjlist);
  igraph_vector_destroy(&tmp);
  IGRAPH_FINALLY_CLEAN(3);

  if (value) { 
    *value = VECTOR(values)[0];
  }

  if (vector) {
    igraph_real_t amax=0;
    long int which=0;
    long int i;
    IGRAPH_CHECK(igraph_vector_resize(vector, options->n));
    for (i=0; i<options->n; i++) {
      igraph_real_t tmp;
      VECTOR(*vector)[i] = MATRIX(vectors, i, 0);
      tmp=fabs(VECTOR(*vector)[i]);
      if (tmp>amax) { amax=tmp; which=i; }
    }
    if (scale && amax!=0) { igraph_vector_scale(vector, 1/VECTOR(*vector)[which]); }
  }
  
  if (options->info) {
    IGRAPH_WARNING("Non-zero return code from ARPACK routine!");
  }
  igraph_matrix_destroy(&vectors);
  igraph_vector_destroy(&values);
  IGRAPH_FINALLY_CLEAN(2);
  
  return 0;
}
Пример #4
0
int igraph_i_eigen_adjacency_arpack(const igraph_t *graph, 
				    const igraph_eigen_which_t *which,
				    igraph_arpack_options_t *options,
				    igraph_arpack_storage_t* storage,
				    igraph_vector_t *values,
				    igraph_matrix_t *vectors,
				    igraph_vector_complex_t *cmplxvalues,
				    igraph_matrix_complex_t *cmplxvectors){

	igraph_adjlist_t adjlist;
	void *extra=(void*) &adjlist;
	int n=igraph_vcount(graph);

  if (!options) { 
    IGRAPH_ERROR("`options' must be given for ARPACK algorithm",
		 IGRAPH_EINVAL);
  }
	
  if (igraph_is_directed(graph)) {
    IGRAPH_ERROR("ARPACK adjacency eigensolver not implemented for "
		 "directed graphs", IGRAPH_UNIMPLEMENTED);
  }
  if (which->pos == IGRAPH_EIGEN_INTERVAL) {
    IGRAPH_ERROR("ARPACK adjacency eigensolver does not implement "
		 "`INTERNAL' eigenvalues", IGRAPH_UNIMPLEMENTED);
  }
  if (which->pos == IGRAPH_EIGEN_SELECT) {
    IGRAPH_ERROR("ARPACK adjacency eigensolver does not implement "
		 "`SELECT' eigenvalues", IGRAPH_UNIMPLEMENTED);
  }
  if (which->pos == IGRAPH_EIGEN_ALL) {
    IGRAPH_ERROR("ARPACK adjacency eigensolver does not implement "
		 "`ALL' eigenvalues", IGRAPH_UNIMPLEMENTED);
  }

  switch (which->pos) {
  case IGRAPH_EIGEN_LM:
    options->which[0]='L'; options->which[1]='M';
    options->nev=which->howmany;
    break;
  case IGRAPH_EIGEN_SM:
    options->which[0]='S'; options->which[1]='M';
    options->nev=which->howmany;
    break;
  case IGRAPH_EIGEN_LA:
    options->which[0]='L'; options->which[1]='A';
    options->nev=which->howmany;
    break;
  case IGRAPH_EIGEN_SA:
    options->which[0]='S'; options->which[1]='A';
    options->nev=which->howmany;
    break;
  case IGRAPH_EIGEN_ALL:
    options->which[0]='L'; options->which[1]='M';
    options->nev=n;
    break;
  case IGRAPH_EIGEN_BE:
    IGRAPH_ERROR("Eigenvectors from both ends with ARPACK",
		 IGRAPH_UNIMPLEMENTED);
    /* TODO */
    break;
  case IGRAPH_EIGEN_INTERVAL:
    IGRAPH_ERROR("Interval of eigenvectors with ARPACK",
		 IGRAPH_UNIMPLEMENTED);
    /* TODO */
    break;
  case IGRAPH_EIGEN_SELECT:
    IGRAPH_ERROR("Selected eigenvalues with ARPACK",
		 IGRAPH_UNIMPLEMENTED);
    /* TODO */
    break;
  default:
    /* This cannot happen */
    break;
  }

  options->n=n;
  options->ncv= 2*options->nev < n ? 2*options->nev : n;

  IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_IN));
  IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist);

  IGRAPH_CHECK(igraph_arpack_rssolve(igraph_i_eigen_adjacency_arpack_sym_cb,
				     extra, options, storage, values, vectors));

  igraph_adjlist_destroy(&adjlist);
  IGRAPH_FINALLY_CLEAN(1);

  return 0;
}
Пример #5
0
int igraph_eigenvector_centrality(const igraph_t *graph, igraph_vector_t *vector,
				  igraph_real_t *value, igraph_bool_t scale,
				  const igraph_vector_t *weights,
				  igraph_arpack_options_t *options) {
  
  igraph_vector_t values;
  igraph_matrix_t vectors;
  igraph_vector_t degree;
  long int i;
  
  options->n=igraph_vcount(graph);
  options->start=1;		/* no random start vector */

  if (weights && igraph_vector_size(weights) != igraph_ecount(graph)) {
    IGRAPH_ERROR("Invalid length of weights vector when calculating "
		 "eigenvector centrality", IGRAPH_EINVAL);
  }

  if (weights && igraph_is_directed(graph)) {
    IGRAPH_WARNING("Weighted directed graph in eigenvector centrality");
  }

  IGRAPH_VECTOR_INIT_FINALLY(&values, 0);
  IGRAPH_MATRIX_INIT_FINALLY(&vectors, options->n, 1);

  IGRAPH_VECTOR_INIT_FINALLY(&degree, options->n);
  IGRAPH_CHECK(igraph_degree(graph, &degree, igraph_vss_all(), 
			     IGRAPH_ALL, /*loops=*/ 0));
  for (i=0; i<options->n; i++) {
    if (VECTOR(degree)[i]) {
      MATRIX(vectors, i, 0) = VECTOR(degree)[i];
    } else {
      MATRIX(vectors, i, 0) = 1.0;
    }
  }
  igraph_vector_destroy(&degree);
  IGRAPH_FINALLY_CLEAN(1);
  
  options->n = igraph_vcount(graph);
  options->nev = 1;
  options->ncv = 3;
  options->which[0]='L'; options->which[1]='A';
  options->start=1;		/* no random start vector */

  if (!weights) {
    
    igraph_adjlist_t adjlist;

    IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, IGRAPH_ALL));
    IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist);
    
    IGRAPH_CHECK(igraph_arpack_rssolve(igraph_i_eigenvector_centrality,
				       &adjlist, options, 0, &values, &vectors));

    igraph_adjlist_destroy(&adjlist);
    IGRAPH_FINALLY_CLEAN(1);
    
  } else {
    
    igraph_adjedgelist_t adjedgelist;
    igraph_i_eigenvector_centrality_t data = { graph, &adjedgelist, weights };
    
    IGRAPH_CHECK(igraph_adjedgelist_init(graph, &adjedgelist, IGRAPH_ALL));
    IGRAPH_FINALLY(igraph_adjedgelist_destroy, &adjedgelist);
    
    IGRAPH_CHECK(igraph_arpack_rssolve(igraph_i_eigenvector_centrality2,
				       &data, options, 0, &values, &vectors));
    
    igraph_adjedgelist_destroy(&adjedgelist);
    IGRAPH_FINALLY_CLEAN(1);
  }

  if (value) {
    *value=VECTOR(values)[0];
  }
  
  if (vector) {
    igraph_real_t amax=0;
    long int which=0;
    long int i;
    IGRAPH_CHECK(igraph_vector_resize(vector, options->n));
    for (i=0; i<options->n; i++) {
      igraph_real_t tmp;
      VECTOR(*vector)[i] = MATRIX(vectors, i, 0);
      tmp=fabs(VECTOR(*vector)[i]);
      if (tmp>amax) { amax=tmp; which=i; }
    }
    if (scale && amax!=0) { igraph_vector_scale(vector, 1/VECTOR(*vector)[which]); }
  }

  if (options->info) {
    IGRAPH_WARNING("Non-zero return code from ARPACK routine!");
  }
  
  igraph_matrix_destroy(&vectors);
  igraph_vector_destroy(&values);
  IGRAPH_FINALLY_CLEAN(2);
  return 0;
}