igraph_bool_t check_ev(const igraph_matrix_t *A, const igraph_vector_t *values_real, const igraph_vector_t *values_imag, const igraph_matrix_t *vectors_left, const igraph_matrix_t *vectors_right, igraph_real_t tol) { int n=igraph_matrix_nrow(A); igraph_vector_t v_real, v_imag; igraph_vector_t AV_real, AV_imag, lv_real, lv_imag; igraph_vector_t null; int i; if (igraph_matrix_ncol(A) != n) { return 1; } if (igraph_vector_size(values_real) != n) { return 1; } if (igraph_vector_size(values_imag) != n) { return 1; } if (igraph_matrix_nrow(vectors_left) != n) { return 1; } if (igraph_matrix_ncol(vectors_left) != n) { return 1; } if (igraph_matrix_nrow(vectors_right) != n) { return 1; } if (igraph_matrix_ncol(vectors_right) != n) { return 1; } igraph_vector_init(&AV_real, n); igraph_vector_init(&AV_imag, n); igraph_vector_init(&lv_real, n); igraph_vector_init(&lv_imag, n); igraph_vector_init(&null, n); igraph_vector_null(&null); for (i=0; i<n; i++) { if (VECTOR(*values_imag)[i]==0.0) { igraph_vector_view(&v_real, &MATRIX(*vectors_right, 0, i), n); igraph_vector_view(&v_imag, VECTOR(null), n); } else if (VECTOR(*values_imag)[i] > 0.0) { igraph_vector_view(&v_real, &MATRIX(*vectors_right, 0, i), n); igraph_vector_view(&v_imag, &MATRIX(*vectors_right, 0, i+1), n); } else if (VECTOR(*values_imag)[i] < 0.0) { igraph_vector_view(&v_real, &MATRIX(*vectors_right, 0, i-1), n); igraph_vector_view(&v_imag, &MATRIX(*vectors_right, 0, i), n); igraph_vector_scale(&v_imag, -1.0); } real_cplx_mult(A, &v_real, &v_imag, &AV_real, &AV_imag); sc_cplx_cplx_mult(VECTOR(*values_real)[i], VECTOR(*values_imag)[i], &v_real, &v_imag, &lv_real, &lv_imag); if (igraph_vector_maxdifference(&AV_real, &lv_real) > tol || igraph_vector_maxdifference(&AV_imag, &lv_imag) > tol) { igraph_vector_print(&AV_real); igraph_vector_print(&AV_imag); igraph_vector_print(&lv_real); igraph_vector_print(&lv_imag); return 1; } } igraph_vector_destroy(&null); igraph_vector_destroy(&AV_imag); igraph_vector_destroy(&AV_real); igraph_vector_destroy(&lv_imag); igraph_vector_destroy(&lv_real); return 0; }
int igraph_lapack_dgetrs(igraph_bool_t transpose, const igraph_matrix_t *a, igraph_vector_int_t *ipiv, igraph_matrix_t *b) { char trans = transpose ? 'T' : 'N'; int n=(int) igraph_matrix_nrow(a); int nrhs=(int) igraph_matrix_ncol(b); int lda= n > 0 ? n : 1; int ldb= n > 0 ? n : 1; int info; if (n != igraph_matrix_ncol(a)) { IGRAPH_ERROR("Cannot LU solve matrix", IGRAPH_NONSQUARE); } if (n != igraph_matrix_nrow(b)) { IGRAPH_ERROR("Cannot LU solve matrix, RHS of wrong size", IGRAPH_EINVAL); } igraphdgetrs_(&trans, &n, &nrhs, VECTOR(a->data), &lda, VECTOR(*ipiv), VECTOR(b->data), &ldb, &info); if (info < 0) { switch(info) { case -1: IGRAPH_ERROR("Invalid transpose argument", IGRAPH_ELAPACK); break; case -2: IGRAPH_ERROR("Invalid number of rows/columns", IGRAPH_ELAPACK); break; case -3: IGRAPH_ERROR("Invalid number of RHS vectors", IGRAPH_ELAPACK); break; case -4: IGRAPH_ERROR("Invalid LU matrix", IGRAPH_ELAPACK); break; case -5: IGRAPH_ERROR("Invalid LDA parameter", IGRAPH_ELAPACK); break; case -6: IGRAPH_ERROR("Invalid pivot vector", IGRAPH_ELAPACK); break; case -7: IGRAPH_ERROR("Invalid RHS matrix", IGRAPH_ELAPACK); break; case -8: IGRAPH_ERROR("Invalid LDB parameter", IGRAPH_ELAPACK); break; case -9: IGRAPH_ERROR("Invalid info argument", IGRAPH_ELAPACK); break; default: IGRAPH_ERROR("Unknown LAPACK error", IGRAPH_ELAPACK); break; } } return 0; }
/* call-seq: * graph.get_adjacency(type) -> Array * * Returns the adjacency matrix of a graph * */ VALUE cIGraph_get_adjacency(VALUE self, VALUE mode){ igraph_t *graph; igraph_get_adjacency_t pmode = NUM2INT(mode); igraph_matrix_t res; int i; int j; VALUE row; VALUE path_length; VALUE matrix = rb_ary_new(); int n; Data_Get_Struct(self, igraph_t, graph); n = igraph_vcount(graph); //matrix to hold the results of the calculations igraph_matrix_init(&res,n,n); igraph_get_adjacency(graph,&res,pmode); for(i=0; i<igraph_matrix_nrow(&res); i++){ row = rb_ary_new(); rb_ary_push(matrix,row); for(j=0; j<igraph_matrix_ncol(&res); j++){ path_length = INT2NUM(MATRIX(res,i,j)); rb_ary_push(row,path_length); } } igraph_matrix_destroy(&res); return matrix; }
int check_ev(const igraph_matrix_t *A, const igraph_vector_t *values, const igraph_matrix_t *vectors) { int i, n=igraph_matrix_nrow(A); int ne=igraph_matrix_ncol(vectors); igraph_vector_t v, lhs, rhs; if (ne != igraph_vector_size(values)) { printf("'values' and 'vectors' sizes do not match\n"); exit(1); } igraph_vector_init(&lhs, n); igraph_vector_init(&rhs, n); for (i=0; i<ne; i++) { igraph_vector_view(&v, &MATRIX(*vectors, 0, i), n); igraph_blas_dgemv(/*transpose=*/ 0, /*alpha=*/ 1, A, &v, /*beta=*/ 0, &lhs); igraph_vector_update(&rhs, &v); igraph_vector_scale(&rhs, VECTOR(*values)[i]); if (igraph_vector_maxdifference(&lhs, &rhs) > 1e-10) { printf("LHS: "); igraph_vector_print(&lhs); printf("RHS: "); igraph_vector_print(&rhs); exit(2); } } igraph_vector_destroy(&rhs); igraph_vector_destroy(&lhs); return 0; }
int real_cplx_mult(const igraph_matrix_t *A, const igraph_vector_t *v_real, const igraph_vector_t *v_imag, igraph_vector_t *res_real, igraph_vector_t *res_imag) { int n=igraph_vector_size(v_real); int r, c; if (igraph_matrix_nrow(A) != n || igraph_matrix_ncol(A) != n || igraph_vector_size(v_imag) != n) { printf("Wrong matrix or vector size"); return 1; } igraph_vector_resize(res_real, n); igraph_vector_resize(res_imag, n); for (r=0; r<n; r++) { igraph_real_t s_real=0.0; igraph_real_t s_imag=0.0; for (c=0; c<n; c++) { s_real += MATRIX(*A, r, c) * VECTOR(*v_real)[c]; s_imag += MATRIX(*A, r, c) * VECTOR(*v_imag)[c]; } VECTOR(*res_real)[r]=s_real; VECTOR(*res_imag)[r]=s_imag; } return 0; }
/* call-seq: * matrix.ncol -> Integer * * Returns the number of columns in the matrix. */ VALUE cIGraph_matrix_ncol(VALUE self){ igraph_matrix_t *m; Data_Get_Struct(self, igraph_matrix_t, m); return LONG2FIX(igraph_matrix_ncol(m)); }
void print_matrix(igraph_matrix_t *m, FILE *f) { long int i, j; for (i=0; i<igraph_matrix_nrow(m); i++) { for (j=0; j<igraph_matrix_ncol(m); j++) { fprintf(f, " %li", (long int) MATRIX(*m, i, j)); } fprintf(f, "\n"); } }
void byrow(igraph_matrix_t *m) { long int r=igraph_matrix_nrow(m), c=igraph_matrix_ncol(m); long int n=0, i, j; for (i=0; i<r; i++) { for (j=0; j<c; j++) { MATRIX(*m, i, j) = n++; } } }
void print_matrix(igraph_matrix_t *m) { long int i, j; for (i=0; i<igraph_matrix_nrow(m); i++) { for (j=0; j<igraph_matrix_ncol(m); j++) { printf(" %g", MATRIX(*m, i, j)); } printf("\n"); } }
/* call-seq: * graph.dijkstra_shortest_paths(varray,weights,mode) -> Array * * Calculates the length of the shortest paths from each of the vertices in * the varray Array to all of the other vertices in the graph given a set of * edge weights given in the weights Array. The result * is returned as an Array of Array. Each top-level Array contains the results * for a vertex in the varray Array. Each entry in the Array is the path length * to another vertex in the graph in vertex order (the order the vertices were * added to the graph. (This should probalby be changed to give a Hash of Hash * to allow easier look up.) */ VALUE cIGraph_dijkstra_shortest_paths(VALUE self, VALUE from, VALUE weights, VALUE mode){ igraph_t *graph; igraph_vs_t vids; igraph_vector_t vidv; igraph_vector_t wghts; igraph_neimode_t pmode = NUM2INT(mode); igraph_matrix_t res; int i; int j; VALUE row; VALUE path_length; VALUE matrix = rb_ary_new(); int n_row; int n_col; Data_Get_Struct(self, igraph_t, graph); n_row = NUM2INT(rb_funcall(from,rb_intern("length"),0)); n_col = igraph_vcount(graph); //matrix to hold the results of the calculations igraph_matrix_init(&res,n_row,n_col); igraph_vector_init(&wghts,RARRAY_LEN(weights)); for(i=0;i<RARRAY_LEN(weights);i++){ VECTOR(wghts)[i] = NUM2DBL(RARRAY_PTR(weights)[i]); } //Convert an array of vertices to a vector of vertex ids igraph_vector_init_int(&vidv,0); cIGraph_vertex_arr_to_id_vec(self,from,&vidv); //create vertex selector from the vecotr of ids igraph_vs_vector(&vids,&vidv); igraph_dijkstra_shortest_paths(graph,&res,vids,&wghts,pmode); for(i=0; i<igraph_matrix_nrow(&res); i++){ row = rb_ary_new(); rb_ary_push(matrix,row); for(j=0; j<igraph_matrix_ncol(&res); j++){ path_length = MATRIX(res,i,j) == n_col ? Qnil : rb_float_new(MATRIX(res,i,j)); rb_ary_push(row,path_length); } } igraph_vector_destroy(&vidv); igraph_matrix_destroy(&res); igraph_vs_destroy(&vids); igraph_vector_destroy(&wghts); return matrix; }
int print_matrix(const igraph_matrix_t *m) { long int i, j, nrow=igraph_matrix_nrow(m), ncol=igraph_matrix_ncol(m); for (i=0; i<nrow; i++) { for (j=0; j<ncol; j++) { printf("%.2g", (double)MATRIX(*m, i, j)); if (j!=ncol-1) { printf(" "); } } printf("\n"); } return 0; }
void print_matrix(igraph_matrix_t* m) { long int nr=igraph_matrix_nrow(m); long int nc=igraph_matrix_ncol(m); long int i, j; for (i=0; i<nr; i++) { for (j=0; j<nc; j++) { if (j!=0) { putchar(' '); } printf("%d", (int)MATRIX(*m, i, j)); } printf("\n"); } }
int print_matrix(const igraph_matrix_t *m) { long int nrow=igraph_matrix_nrow(m); long int ncol=igraph_matrix_ncol(m); long int i, j; for (i=0; i<nrow; i++) { printf("%li:", i); for (j=0; j<ncol; j++) { printf(" %3.0F", MATRIX(*m, i, j)); } printf("\n"); } return 0; }
int igraph_lapack_dgetrf(igraph_matrix_t *a, igraph_vector_int_t *ipiv, int *info) { int m=(int) igraph_matrix_nrow(a); int n=(int) igraph_matrix_ncol(a); int lda=m > 0 ? m : 1; igraph_vector_int_t *myipiv=ipiv, vipiv; if (!ipiv) { IGRAPH_CHECK(igraph_vector_int_init(&vipiv, m<n ? m : n)); IGRAPH_FINALLY(igraph_vector_int_destroy, &vipiv); myipiv=&vipiv; } igraphdgetrf_(&m, &n, VECTOR(a->data), &lda, VECTOR(*myipiv), info); if (*info > 0) { IGRAPH_WARNING("LU: factor is exactly singular"); } else if (*info < 0) { switch(*info) { case -1: IGRAPH_ERROR("Invalid number of rows", IGRAPH_ELAPACK); break; case -2: IGRAPH_ERROR("Invalid number of columns", IGRAPH_ELAPACK); break; case -3: IGRAPH_ERROR("Invalid input matrix", IGRAPH_ELAPACK); break; case -4: IGRAPH_ERROR("Invalid LDA parameter", IGRAPH_ELAPACK); break; case -5: IGRAPH_ERROR("Invalid pivot vector", IGRAPH_ELAPACK); break; case -6: IGRAPH_ERROR("Invalid info argument", IGRAPH_ELAPACK); break; default: IGRAPH_ERROR("Unknown LAPACK error", IGRAPH_ELAPACK); break; } } if (!ipiv) { igraph_vector_int_destroy(&vipiv); IGRAPH_FINALLY_CLEAN(1); } return 0; }
int igraph_dot_product_game(igraph_t *graph, const igraph_matrix_t *vecs, igraph_bool_t directed) { igraph_integer_t nrow=igraph_matrix_nrow(vecs); igraph_integer_t ncol=igraph_matrix_ncol(vecs); int i, j; igraph_vector_t edges; igraph_bool_t warned_neg=0, warned_big=0; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); RNG_BEGIN(); for (i = 0; i < ncol; i++) { int from=directed ? 0 : i+1; igraph_vector_t v1; igraph_vector_view(&v1, &MATRIX(*vecs, 0, i), nrow); for (j = from; j < ncol; j++) { igraph_real_t prob; igraph_vector_t v2; if (i==j) { continue; } igraph_vector_view(&v2, &MATRIX(*vecs, 0, j), nrow); igraph_lapack_ddot(&v1, &v2, &prob); if (prob < 0 && ! warned_neg) { warned_neg=1; IGRAPH_WARNING("Negative connection probability in " "dot-product graph"); } else if (prob > 1 && ! warned_big) { warned_big=1; IGRAPH_WARNING("Greater than 1 connection probability in " "dot-product graph"); IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, j)); } else if (RNG_UNIF01() < prob) { IGRAPH_CHECK(igraph_vector_push_back(&edges, i)); IGRAPH_CHECK(igraph_vector_push_back(&edges, j)); } } } RNG_END(); igraph_create(graph, &edges, ncol, directed); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); return 0; }
/** * \ingroup structural * \function igraph_similarity_dice * \brief Dice similarity coefficient. * * </para><para> * The Dice similarity coefficient of two vertices is twice the number of common * neighbors divided by the sum of the degrees of the vertices. This function * calculates the pairwise Dice similarities for some (or all) of the vertices. * * \param graph The graph object to analyze * \param res Pointer to a matrix, the result of the calculation will * be stored here. The number of its rows and columns is the same * as the number of vertex ids in \p vids. * \param vids The vertex ids of the vertices for which the * calculation will be done. * \param mode The type of neighbors to be used for the calculation in * directed graphs. Possible values: * \clist * \cli IGRAPH_OUT * the outgoing edges will be considered for each node. * \cli IGRAPH_IN * the incoming edges will be considered for each node. * \cli IGRAPH_ALL * the directed graph is considered as an undirected one for the * computation. * \endclist * \param loops Whether to include the vertices themselves as their own * neighbors. * \return Error code: * \clist * \cli IGRAPH_ENOMEM * not enough memory for temporary data. * \cli IGRAPH_EINVVID * invalid vertex id passed. * \cli IGRAPH_EINVMODE * invalid mode argument. * \endclist * * Time complexity: O(|V|^2 d), * |V| is the number of vertices in the vertex iterator given, d is the * (maximum) degree of the vertices in the graph. * * \sa \ref igraph_similarity_jaccard(), a measure very similar to the Dice * coefficient * * \example examples/simple/igraph_similarity.c */ int igraph_similarity_dice(const igraph_t *graph, igraph_matrix_t *res, const igraph_vs_t vids, igraph_neimode_t mode, igraph_bool_t loops) { long int i, j, nr, nc; IGRAPH_CHECK(igraph_similarity_jaccard(graph, res, vids, mode, loops)); nr = igraph_matrix_nrow(res); nc = igraph_matrix_ncol(res); for (i = 0; i < nr; i++) { for (j = 0; j < nc; j++) { igraph_real_t x = MATRIX(*res, i, j); MATRIX(*res, i, j) = 2*x / (1+x); } } return IGRAPH_SUCCESS; }
/* call-seq: * graph.cocitation(varray) -> Array * * Cocitation coupling. * * Two vertices are cocited if there is another vertex citing both of them. * igraph_cocitation() simply counts how many types two vertices are cocited. * The cocitation score for each given vertex and all other vertices in the * graph will be calculated. * */ VALUE cIGraph_cocitation(VALUE self, VALUE vs){ igraph_t *graph; igraph_vs_t vids; igraph_vector_t vidv; igraph_matrix_t res; int i; int j; VALUE row; VALUE path_length; VALUE matrix = rb_ary_new(); int n_row; int n_col; Data_Get_Struct(self, igraph_t, graph); n_row = NUM2INT(rb_funcall(vs,rb_intern("length"),0)); n_col = igraph_vcount(graph); //matrix to hold the results of the calculations igraph_matrix_init(&res,n_row,n_col); //Convert an array of vertices to a vector of vertex ids igraph_vector_init_int(&vidv,0); cIGraph_vertex_arr_to_id_vec(self,vs,&vidv); //create vertex selector from the vecotr of ids igraph_vs_vector(&vids,&vidv); igraph_cocitation(graph,&res,vids); for(i=0; i<igraph_matrix_nrow(&res); i++){ row = rb_ary_new(); rb_ary_push(matrix,row); for(j=0; j<igraph_matrix_ncol(&res); j++){ path_length = INT2NUM(MATRIX(res,i,j)); rb_ary_push(row,path_length); } } igraph_vector_destroy(&vidv); igraph_matrix_destroy(&res); igraph_vs_destroy(&vids); return matrix; }
int igraph_i_eigen_checks(const igraph_matrix_t *A, const igraph_sparsemat_t *sA, igraph_arpack_function_t *fun, int n) { if ( (A?1:0)+(sA?1:0)+(fun?1:0) != 1) { IGRAPH_ERROR("Exactly one of 'A', 'sA' and 'fun' must be given", IGRAPH_EINVAL); } if (A) { if (n != igraph_matrix_ncol(A) || n != igraph_matrix_nrow(A)) { IGRAPH_ERROR("Invalid matrix", IGRAPH_NONSQUARE); } } else if (sA) { if (n != igraph_sparsemat_ncol(sA) || n != igraph_sparsemat_nrow(sA)) { IGRAPH_ERROR("Invalid matrix", IGRAPH_NONSQUARE); } } return 0; }
int igraph_lapack_dgeevx(igraph_lapack_dgeevx_balance_t balance, const igraph_matrix_t *A, igraph_vector_t *valuesreal, igraph_vector_t *valuesimag, igraph_matrix_t *vectorsleft, igraph_matrix_t *vectorsright, int *ilo, int *ihi, igraph_vector_t *scale, igraph_real_t *abnrm, igraph_vector_t *rconde, igraph_vector_t *rcondv, int *info) { char balanc; char jobvl= vectorsleft ? 'V' : 'N'; char jobvr= vectorsright ? 'V' : 'N'; char sense; int n=(int) igraph_matrix_nrow(A); int lda=n, ldvl=n, ldvr=n, lwork=-1; igraph_vector_t work; igraph_vector_int_t iwork; igraph_matrix_t Acopy; int error=*info; igraph_vector_t *myreal=valuesreal, *myimag=valuesimag, vreal, vimag; igraph_vector_t *myscale=scale, vscale; if (igraph_matrix_ncol(A) != n) { IGRAPH_ERROR("Cannot calculate eigenvalues (dgeevx)", IGRAPH_NONSQUARE); } switch (balance) { case IGRAPH_LAPACK_DGEEVX_BALANCE_NONE: balanc='N'; break; case IGRAPH_LAPACK_DGEEVX_BALANCE_PERM: balanc='P'; break; case IGRAPH_LAPACK_DGEEVX_BALANCE_SCALE: balanc='S'; break; case IGRAPH_LAPACK_DGEEVX_BALANCE_BOTH: balanc='B'; break; default: IGRAPH_ERROR("Invalid 'balance' argument", IGRAPH_EINVAL); break; } if (!rconde && !rcondv) { sense='N'; } else if (rconde && !rcondv) { sense='E'; } else if (!rconde && rcondv) { sense='V'; } else { sense='B'; } IGRAPH_CHECK(igraph_matrix_copy(&Acopy, A)); IGRAPH_FINALLY(igraph_matrix_destroy, &Acopy); IGRAPH_VECTOR_INIT_FINALLY(&work, 1); IGRAPH_CHECK(igraph_vector_int_init(&iwork, n)); IGRAPH_FINALLY(igraph_vector_int_destroy, &iwork); if (!valuesreal) { IGRAPH_VECTOR_INIT_FINALLY(&vreal, n); myreal=&vreal; } else { IGRAPH_CHECK(igraph_vector_resize(myreal, n)); } if (!valuesimag) { IGRAPH_VECTOR_INIT_FINALLY(&vimag, n); myimag=&vimag; } else { IGRAPH_CHECK(igraph_vector_resize(myimag, n)); } if (!scale) { IGRAPH_VECTOR_INIT_FINALLY(&vscale, n); myscale=&vscale; } else { IGRAPH_CHECK(igraph_vector_resize(scale, n)); } if (vectorsleft) { IGRAPH_CHECK(igraph_matrix_resize(vectorsleft, n, n)); } if (vectorsright) { IGRAPH_CHECK(igraph_matrix_resize(vectorsright, n, n)); } igraphdgeevx_(&balanc, &jobvl, &jobvr, &sense, &n, &MATRIX(Acopy,0,0), &lda, VECTOR(*myreal), VECTOR(*myimag), vectorsleft ? &MATRIX(*vectorsleft ,0,0) : 0, &ldvl, vectorsright ? &MATRIX(*vectorsright,0,0) : 0, &ldvr, ilo, ihi, VECTOR(*myscale), abnrm, rconde ? VECTOR(*rconde) : 0, rcondv ? VECTOR(*rcondv) : 0, VECTOR(work), &lwork, VECTOR(iwork), info); lwork=(int) VECTOR(work)[0]; IGRAPH_CHECK(igraph_vector_resize(&work, lwork)); igraphdgeevx_(&balanc, &jobvl, &jobvr, &sense, &n, &MATRIX(Acopy,0,0), &lda, VECTOR(*myreal), VECTOR(*myimag), vectorsleft ? &MATRIX(*vectorsleft ,0,0) : 0, &ldvl, vectorsright ? &MATRIX(*vectorsright,0,0) : 0, &ldvr, ilo, ihi, VECTOR(*myscale), abnrm, rconde ? VECTOR(*rconde) : 0, rcondv ? VECTOR(*rcondv) : 0, VECTOR(work), &lwork, VECTOR(iwork), info); if (*info < 0) { IGRAPH_ERROR("Cannot calculate eigenvalues (dgeev)", IGRAPH_ELAPACK); } else if (*info > 0) { if (error) { IGRAPH_ERROR("Cannot calculate eigenvalues (dgeev)", IGRAPH_ELAPACK); } else { IGRAPH_WARNING("Cannot calculate eigenvalues (dgeev)"); } } if (!scale) { igraph_vector_destroy(&vscale); IGRAPH_FINALLY_CLEAN(1); } if (!valuesimag) { igraph_vector_destroy(&vimag); IGRAPH_FINALLY_CLEAN(1); } if (!valuesreal) { igraph_vector_destroy(&vreal); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_int_destroy(&iwork); igraph_vector_destroy(&work); igraph_matrix_destroy(&Acopy); IGRAPH_FINALLY_CLEAN(3); return 0; }
int main() { igraph_matrix_t m, m2; igraph_vector_t v; long int i, j, i2, j2; igraph_real_t r1, r2; igraph_matrix_init(&m, 4, 3); byrow(&m); /* igraph_matrix_e */ printf("igraph_matrix_e\n"); apply(m, printf("%i ", (int)igraph_matrix_e(&m, i, j)), printf("\n")); /* igraph_matrix_e_ptr */ printf("igraph_matrix_e_ptr\n"); apply(m, printf("%i ", (int)igraph_matrix_e_ptr(&m, i, j)[0]), printf("\n")); /* igraph_matrix_set */ printf("igraph_matrix_set\n"); apply(m, igraph_matrix_set(&m, i, j, i), (void) 0 ); print_matrix(&m); apply(m, igraph_matrix_set(&m, i, j, j), (void) 0 ); print_matrix(&m); /* igraph_matrix_fill */ printf("igraph_matrix_fill\n"); igraph_matrix_fill(&m, 42); print_matrix(&m); igraph_matrix_fill(&m, -42.1); print_matrix(&m); /* igraph_matrix_update */ printf("igraph_matrix_update\n"); igraph_matrix_init(&m2, 0, 0); byrow(&m); igraph_matrix_update(&m2, &m); print_matrix(&m2); /* igraph_matrix_rbind */ printf("igraph_matrix_rbind\n"); igraph_matrix_rbind(&m2, &m); print_matrix(&m2); printf("\n"); igraph_matrix_resize(&m, 0, igraph_matrix_ncol(&m2)); igraph_matrix_rbind(&m2, &m); print_matrix(&m2); printf("\n"); igraph_matrix_rbind(&m, &m2); print_matrix(&m); /* igraph_matrix_cbind */ printf("igraph_matrix_cbind\n"); igraph_matrix_resize(&m, 4, 3); igraph_matrix_resize(&m2, 4, 2); byrow(&m); byrow(&m2); igraph_matrix_cbind(&m, &m2); print_matrix(&m); /* igraph_matrix_swap */ printf("igraph_matrix_swap\n"); igraph_matrix_update(&m, &m2); igraph_matrix_null(&m); igraph_matrix_swap(&m, &m2); print_matrix(&m); print_matrix(&m2); /* igraph_matrix_get_row */ /* igraph_matrix_set_row */ printf("igraph_matrix_get_row\n"); printf("igraph_matrix_set_row\n"); igraph_vector_init(&v, 0); for (i=0; i<igraph_matrix_nrow(&m); i++) { igraph_matrix_get_row(&m, &v, i); igraph_matrix_set_row(&m2, &v, i); } print_matrix(&m2); /* igraph_matrix_set_col */ printf("igraph_matrix_set_col\n"); igraph_matrix_null(&m2); for (i=0; i<igraph_matrix_ncol(&m); i++) { igraph_matrix_get_col(&m, &v, i); igraph_matrix_set_col(&m2, &v, i); } print_matrix(&m2); /* igraph_matrix_swap_rows */ printf("igraph_matrix_swap_rows\n"); igraph_matrix_swap_rows(&m2, 0, 0); igraph_matrix_swap_rows(&m2, 0, 2); print_matrix(&m2); /* igraph_matrix_swap_cols */ printf("igraph_matrix_swap_cols\n"); igraph_matrix_swap_cols(&m2, 0, 0); igraph_matrix_swap_cols(&m2, 0, 1); print_matrix(&m2); /* igraph_matrix_add_constant */ printf("igraph_matrix_add_constant\n"); igraph_matrix_add_constant(&m2, 0); print_matrix(&m2); igraph_matrix_add_constant(&m2, -1); print_matrix(&m2); /* igraph_matrix_add */ printf("igraph_matrix_add\n"); byrow(&m2); byrow(&m); igraph_matrix_add(&m2, &m); print_matrix(&m2); /* igraph_matrix_sub */ printf("igraph_matrix_sub\n"); igraph_matrix_sub(&m2, &m); print_matrix(&m2); /* igraph_matrix_mul_elements */ printf("igraph_matrix_mul_elements\n"); igraph_matrix_mul_elements(&m2, &m); print_matrix(&m2); /* igraph_matrix_div_elements */ printf("igraph_matrix_div_elements\n"); igraph_matrix_fill(&m, 2); igraph_matrix_div_elements(&m2, &m); print_matrix(&m2); /* igraph_matrix_min */ printf("igraph_matrix_min\n"); if (igraph_matrix_min(&m2) != 0) { return 1; } if (igraph_matrix_min(&m) != 2) { return 1; } /* igraph_matrix_which_min */ printf("igraph_matrix_which_min\n"); igraph_matrix_which_min(&m2, &i, &j); if (i != 0 || j != 0) { return 2; } MATRIX(m2,0,1) = -1; igraph_matrix_which_min(&m2, &i, &j); if (i != 0 || j != 1) { return 2; } MATRIX(m2,3,1) = -2; igraph_matrix_which_min(&m2, &i, &j); if (i != 3 || j != 1) { return 2; } /* igraph_matrix_which_max */ printf("igraph_matrix_which_max\n"); MATRIX(m2,3,0) = 100; igraph_matrix_which_max(&m2, &i, &j); if (i != 3 || j != 0) { return 3; } /* igraph_matrix_minmax */ printf("igraph_matrix_minmax\n"); igraph_matrix_minmax(&m2, &r1, &r2); printf("%g %g\n", r1, r2); /* igraph_matrix_which_minmax */ printf("igraph_matrix_which_minmax\n"); igraph_matrix_which_minmax(&m2, &i, &j, &i2, &j2); if (i != 3 || j != 1 || i2 != 3 || j2 != 0) { return 4; } /* igraph_matrix_isnull */ printf("igraph_matrix_isnull\n"); if (igraph_matrix_isnull(&m2)) { return 5; } igraph_matrix_null(&m); if (!igraph_matrix_isnull(&m)) { return 5; } igraph_matrix_resize(&m2, 5, 0); if (!igraph_matrix_isnull(&m2)) { return 5; } /* igraph_matrix_empty */ printf("igraph_matrix_empty\n"); if (!igraph_matrix_empty(&m2)) { return 6; } igraph_matrix_resize(&m2, 5, 5); if (igraph_matrix_empty(&m2)) { return 6; } /* igraph_matrix_is_symmetric */ printf("igraph_matrix_is_symmetric\n"); byrow(&m2); if (igraph_matrix_is_symmetric(&m2)) { return 7; } igraph_matrix_update(&m, &m2); igraph_matrix_transpose(&m); igraph_matrix_add(&m, &m2); if (!igraph_matrix_is_symmetric(&m)) { return 7; } /* igraph_matrix_prod */ printf("igraph_matrix_prod\n"); igraph_matrix_resize(&m, 3,2); byrow(&m); igraph_matrix_add_constant(&m, 1); print_matrix(&m); printf("product: %g\n", igraph_matrix_prod(&m)); /* igraph_matrix_rowsum */ printf("igraph_matrix_rowsum\n"); igraph_matrix_rowsum(&m, &v); print_vector(&v); /* igraph_matrix_colsum */ printf("igraph_matrix_colsum\n"); igraph_matrix_colsum(&m, &v); print_vector(&v); /* igraph_matrix_contains */ printf("igraph_matrix_contains\n"); if (igraph_matrix_contains(&m, 0)) { return 8; } if (igraph_matrix_contains(&m, 6.0001)) { return 8; } if (igraph_matrix_contains(&m, 7)) { return 8; } if (!igraph_matrix_contains(&m, 1)) { return 8; } if (!igraph_matrix_contains(&m, 6)) { return 8; } /* igraph_matrix_search */ printf("igraph_matrix_search\n"); if (!igraph_matrix_search(&m, 0, 6.0, &i2, &i, &j)) { return 9; } if (i2 != 5 || i != 2 || j != 1) { return 9; } /* igraph_matrix_remove_row */ printf("igraph_matrix_remove_row\n"); igraph_matrix_remove_row(&m, 1); print_matrix(&m); igraph_matrix_resize(&m,5,4); byrow(&m); igraph_matrix_remove_row(&m, 4); print_matrix(&m); igraph_matrix_remove_row(&m, 0); print_matrix(&m); /* igraph_matrix_select_cols */ printf("igraph_matrix_select_cols\n"); igraph_matrix_resize(&m, 6, 5); apply(m, igraph_matrix_set(&m, i, j, j), (void) 0 ); igraph_vector_resize(&v, 3); VECTOR(v)[0]=0; VECTOR(v)[1]=4; VECTOR(v)[2]=2; igraph_matrix_select_cols(&m, &m2, &v); print_matrix(&m2); igraph_vector_resize(&v, 1); igraph_matrix_select_cols(&m, &m2, &v); print_matrix(&m2); igraph_vector_clear(&v); igraph_matrix_select_cols(&m, &m2, &v); if (!igraph_matrix_empty(&m2)) { return 9; } igraph_vector_destroy(&v); igraph_matrix_destroy(&m2); igraph_matrix_destroy(&m); if (IGRAPH_FINALLY_STACK_SIZE() != 0) return 10; return 0; }
int igraph_lapack_dgeev(const igraph_matrix_t *A, igraph_vector_t *valuesreal, igraph_vector_t *valuesimag, igraph_matrix_t *vectorsleft, igraph_matrix_t *vectorsright, int *info) { char jobvl= vectorsleft ? 'V' : 'N'; char jobvr= vectorsright ? 'V' : 'N'; int n=(int) igraph_matrix_nrow(A); int lda=n, ldvl=n, ldvr=n, lwork=-1; igraph_vector_t work; igraph_vector_t *myreal=valuesreal, *myimag=valuesimag, vreal, vimag; igraph_matrix_t Acopy; int error=*info; if (igraph_matrix_ncol(A) != n) { IGRAPH_ERROR("Cannot calculate eigenvalues (dgeev)", IGRAPH_NONSQUARE); } IGRAPH_CHECK(igraph_matrix_copy(&Acopy, A)); IGRAPH_FINALLY(igraph_matrix_destroy, &Acopy); IGRAPH_VECTOR_INIT_FINALLY(&work, 1); if (!valuesreal) { IGRAPH_VECTOR_INIT_FINALLY(&vreal, n); myreal=&vreal; } else { IGRAPH_CHECK(igraph_vector_resize(myreal, n)); } if (!valuesimag) { IGRAPH_VECTOR_INIT_FINALLY(&vimag, n); myimag=&vimag; } else { IGRAPH_CHECK(igraph_vector_resize(myimag, n)); } if (vectorsleft) { IGRAPH_CHECK(igraph_matrix_resize(vectorsleft, n, n)); } if (vectorsright) { IGRAPH_CHECK(igraph_matrix_resize(vectorsright, n, n)); } igraphdgeev_(&jobvl, &jobvr, &n, &MATRIX(Acopy,0,0), &lda, VECTOR(*myreal), VECTOR(*myimag), vectorsleft ? &MATRIX(*vectorsleft ,0,0) : 0, &ldvl, vectorsright ? &MATRIX(*vectorsright,0,0) : 0, &ldvr, VECTOR(work), &lwork, info); lwork=(int) VECTOR(work)[0]; IGRAPH_CHECK(igraph_vector_resize(&work, lwork)); igraphdgeev_(&jobvl, &jobvr, &n, &MATRIX(Acopy,0,0), &lda, VECTOR(*myreal), VECTOR(*myimag), vectorsleft ? &MATRIX(*vectorsleft ,0,0) : 0, &ldvl, vectorsright ? &MATRIX(*vectorsright,0,0) : 0, &ldvr, VECTOR(work), &lwork, info); if (*info < 0) { IGRAPH_ERROR("Cannot calculate eigenvalues (dgeev)", IGRAPH_ELAPACK); } else if (*info > 0) { if (error) { IGRAPH_ERROR("Cannot calculate eigenvalues (dgeev)", IGRAPH_ELAPACK); } else { IGRAPH_WARNING("Cannot calculate eigenvalues (dgeev)"); } } if (!valuesimag) { igraph_vector_destroy(&vimag); IGRAPH_FINALLY_CLEAN(1); } if (!valuesreal) { igraph_vector_destroy(&vreal); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_destroy(&work); igraph_matrix_destroy(&Acopy); IGRAPH_FINALLY_CLEAN(2); return 0; }
int igraph_lapack_dsyevr(const igraph_matrix_t *A, igraph_lapack_dsyev_which_t which, igraph_real_t vl, igraph_real_t vu, int vestimate, int il, int iu, igraph_real_t abstol, igraph_vector_t *values, igraph_matrix_t *vectors, igraph_vector_int_t *support) { igraph_matrix_t Acopy; char jobz = vectors ? 'V' : 'N', range, uplo='U'; int n=(int) igraph_matrix_nrow(A), lda=n, ldz=n; int m, info; igraph_vector_t *myvalues=values, vvalues; igraph_vector_int_t *mysupport=support, vsupport; igraph_vector_t work; igraph_vector_int_t iwork; int lwork=-1, liwork=-1; if (n != igraph_matrix_ncol(A)) { IGRAPH_ERROR("Cannot find eigenvalues/vectors", IGRAPH_NONSQUARE); } if (which==IGRAPH_LAPACK_DSYEV_INTERVAL && (vestimate < 1 || vestimate > n)) { IGRAPH_ERROR("Estimated (upper bound) number of eigenvalues must be " "between 1 and n", IGRAPH_EINVAL); } if (which==IGRAPH_LAPACK_DSYEV_SELECT && iu-il < 0) { IGRAPH_ERROR("Invalid 'il' and/or 'iu' values", IGRAPH_EINVAL); } IGRAPH_CHECK(igraph_matrix_copy(&Acopy, A)); IGRAPH_FINALLY(igraph_matrix_destroy, &Acopy); IGRAPH_VECTOR_INIT_FINALLY(&work, 1); IGRAPH_CHECK(igraph_vector_int_init(&iwork, 1)); IGRAPH_FINALLY(igraph_vector_int_destroy, &iwork); if (!values) { IGRAPH_VECTOR_INIT_FINALLY(&vvalues, 0); myvalues=&vvalues; } if (!support) { IGRAPH_CHECK(igraph_vector_int_init(&vsupport, 0)); IGRAPH_FINALLY(igraph_vector_int_destroy, &vsupport); mysupport=&vsupport; } switch (which) { case IGRAPH_LAPACK_DSYEV_ALL: range = 'A'; IGRAPH_CHECK(igraph_vector_resize(myvalues, n)); IGRAPH_CHECK(igraph_vector_int_resize(mysupport, 2*n)); if (vectors) { IGRAPH_CHECK(igraph_matrix_resize(vectors, n, n)); } break; case IGRAPH_LAPACK_DSYEV_INTERVAL: range = 'V'; IGRAPH_CHECK(igraph_vector_resize(myvalues, vestimate)); IGRAPH_CHECK(igraph_vector_int_resize(mysupport, 2*vestimate)); if (vectors) { IGRAPH_CHECK(igraph_matrix_resize(vectors,n, vestimate)); } break; case IGRAPH_LAPACK_DSYEV_SELECT: range = 'I'; IGRAPH_CHECK(igraph_vector_resize(myvalues, iu-il+1)); IGRAPH_CHECK(igraph_vector_int_resize(mysupport, 2*(iu-il+1))); if (vectors) { IGRAPH_CHECK(igraph_matrix_resize(vectors, n, iu-il+1)); } break; } igraphdsyevr_(&jobz, &range, &uplo, &n, &MATRIX(Acopy,0,0), &lda, &vl, &vu, &il, &iu, &abstol, &m, VECTOR(*myvalues), vectors ? &MATRIX(*vectors,0,0) : 0, &ldz, VECTOR(*mysupport), VECTOR(work), &lwork, VECTOR(iwork), &liwork, &info); lwork=(int) VECTOR(work)[0]; liwork=VECTOR(iwork)[0]; IGRAPH_CHECK(igraph_vector_resize(&work, lwork)); IGRAPH_CHECK(igraph_vector_int_resize(&iwork, liwork)); igraphdsyevr_(&jobz, &range, &uplo, &n, &MATRIX(Acopy,0,0), &lda, &vl, &vu, &il, &iu, &abstol, &m, VECTOR(*myvalues), vectors ? &MATRIX(*vectors,0,0) : 0, &ldz, VECTOR(*mysupport), VECTOR(work), &lwork, VECTOR(iwork), &liwork, &info); if (values) { IGRAPH_CHECK(igraph_vector_resize(values, m)); } if (vectors) { IGRAPH_CHECK(igraph_matrix_resize(vectors, n, m)); } if (support) { IGRAPH_CHECK(igraph_vector_int_resize(support, m)); } if (!support) { igraph_vector_int_destroy(&vsupport); IGRAPH_FINALLY_CLEAN(1); } if (!values) { igraph_vector_destroy(&vvalues); IGRAPH_FINALLY_CLEAN(1); } igraph_vector_int_destroy(&iwork); igraph_vector_destroy(&work); igraph_matrix_destroy(&Acopy); IGRAPH_FINALLY_CLEAN(3); return 0; }
int igraph_lapack_dgesv(igraph_matrix_t *a, igraph_vector_int_t *ipiv, igraph_matrix_t *b, int *info) { int n=(int) igraph_matrix_nrow(a); int nrhs=(int) igraph_matrix_ncol(b); int lda= n > 0 ? n : 1; int ldb= n > 0 ? n : 1; igraph_vector_int_t *myipiv=ipiv, vipiv; if (n != igraph_matrix_ncol(a)) { IGRAPH_ERROR("Cannot LU solve matrix", IGRAPH_NONSQUARE); } if (n != igraph_matrix_nrow(b)) { IGRAPH_ERROR("Cannot LU solve matrix, RHS of wrong size", IGRAPH_EINVAL); } if (!ipiv) { IGRAPH_CHECK(igraph_vector_int_init(&vipiv, n)); IGRAPH_FINALLY(igraph_vector_int_destroy, &vipiv); myipiv=&vipiv; } igraphdgesv_(&n, &nrhs, VECTOR(a->data), &lda, VECTOR(*myipiv), VECTOR(b->data), &ldb, info); if (*info > 0) { IGRAPH_WARNING("LU: factor is exactly singular"); } else if (*info < 0) { switch(*info) { case -1: IGRAPH_ERROR("Invalid number of rows/column", IGRAPH_ELAPACK); break; case -2: IGRAPH_ERROR("Invalid number of RHS vectors", IGRAPH_ELAPACK); break; case -3: IGRAPH_ERROR("Invalid input matrix", IGRAPH_ELAPACK); break; case -4: IGRAPH_ERROR("Invalid LDA parameter", IGRAPH_ELAPACK); break; case -5: IGRAPH_ERROR("Invalid pivot vector", IGRAPH_ELAPACK); break; case -6: IGRAPH_ERROR("Invalid RHS matrix", IGRAPH_ELAPACK); break; case -7: IGRAPH_ERROR("Invalid LDB parameter", IGRAPH_ELAPACK); break; case -8: IGRAPH_ERROR("Invalid info argument", IGRAPH_ELAPACK); break; default: IGRAPH_ERROR("Unknown LAPACK error", IGRAPH_ELAPACK); break; } } if (!ipiv) { igraph_vector_int_destroy(&vipiv); IGRAPH_FINALLY_CLEAN(1); } return 0; }
long int Matrix::ncol() const noexcept { return igraph_matrix_ncol(ptr()); }
/** * \ingroup nongraph * \function igraph_convex_hull * \brief Determines the convex hull of a given set of points in the 2D plane * * </para><para> * The convex hull is determined by the Graham scan algorithm. * See the following reference for details: * * </para><para> * Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford * Stein. Introduction to Algorithms, Second Edition. MIT Press and * McGraw-Hill, 2001. ISBN 0262032937. Pages 949-955 of section 33.3: * Finding the convex hull. * * \param data vector containing the coordinates. The length of the * vector must be even, since it contains X-Y coordinate pairs. * \param resverts the vector containing the result, e.g. the vector of * vertex indices used as the corners of the convex hull. Supply * \c NULL here if you are only interested in the coordinates of * the convex hull corners. * \param rescoords the matrix containing the coordinates of the selected * corner vertices. Supply \c NULL here if you are only interested in * the vertex indices. * \return Error code: * \c IGRAPH_ENOMEM: not enough memory * * Time complexity: O(n log(n)) where n is the number of vertices */ int igraph_convex_hull(const igraph_matrix_t *data, igraph_vector_t *resverts, igraph_matrix_t *rescoords) { igraph_integer_t no_of_nodes; long int i, pivot_idx=0, last_idx, before_last_idx, next_idx, j; igraph_real_t* angles; igraph_vector_t stack; igraph_indheap_t order; igraph_real_t px, py, cp; no_of_nodes=igraph_matrix_nrow(data); if (igraph_matrix_ncol(data) != 2) { IGRAPH_ERROR("matrix must have 2 columns", IGRAPH_EINVAL); } if (no_of_nodes == 0) { if (resverts != 0) { IGRAPH_CHECK(igraph_vector_resize(resverts, 0)); } if (rescoords != 0) { IGRAPH_CHECK(igraph_matrix_resize(rescoords, 0, 2)); } /**************************** this is an exit here *********/ return 0; } angles=igraph_Calloc(no_of_nodes, igraph_real_t); if (!angles) IGRAPH_ERROR("not enough memory for angle array", IGRAPH_ENOMEM); IGRAPH_FINALLY(free, angles); IGRAPH_VECTOR_INIT_FINALLY(&stack, 0); /* Search for the pivot vertex */ for (i=1; i<no_of_nodes; i++) { if (MATRIX(*data, i, 1)<MATRIX(*data, pivot_idx, 1)) pivot_idx=i; else if (MATRIX(*data, i, 1) == MATRIX(*data, pivot_idx, 1) && MATRIX(*data, i, 0) < MATRIX(*data, pivot_idx, 0)) pivot_idx=i; } px=MATRIX(*data, pivot_idx, 0); py=MATRIX(*data, pivot_idx, 1); /* Create angle array */ for (i=0; i<no_of_nodes; i++) { if (i == pivot_idx) { /* We can't calculate the angle of the pivot point with itself, * so we use 10 here. This way, after sorting the angle vector, * the pivot point will always be the first one, since the range * of atan2 is -3.14..3.14 */ angles[i] = 10; } else { angles[i] = atan2(MATRIX(*data, i, 1)-py, MATRIX(*data, i, 0)-px); } } IGRAPH_CHECK(igraph_indheap_init_array(&order, angles, no_of_nodes)); IGRAPH_FINALLY(igraph_indheap_destroy, &order); igraph_Free(angles); IGRAPH_FINALLY_CLEAN(1); if (no_of_nodes == 1) { IGRAPH_CHECK(igraph_vector_push_back(&stack, 0)); igraph_indheap_delete_max(&order); } else { /* Do the trick */ IGRAPH_CHECK(igraph_vector_push_back(&stack, igraph_indheap_max_index(&order)-1)); igraph_indheap_delete_max(&order); IGRAPH_CHECK(igraph_vector_push_back(&stack, igraph_indheap_max_index(&order)-1)); igraph_indheap_delete_max(&order); j=2; while (!igraph_indheap_empty(&order)) { /* Determine whether we are at a left or right turn */ last_idx=VECTOR(stack)[j-1]; before_last_idx=VECTOR(stack)[j-2]; next_idx=(long)igraph_indheap_max_index(&order)-1; igraph_indheap_delete_max(&order); cp=(MATRIX(*data, last_idx, 0)-MATRIX(*data, before_last_idx, 0))* (MATRIX(*data, next_idx, 1)-MATRIX(*data, before_last_idx, 1))- (MATRIX(*data, next_idx, 0)-MATRIX(*data, before_last_idx, 0))* (MATRIX(*data, last_idx, 1)-MATRIX(*data, before_last_idx, 1)); /* printf("B L N cp: %d, %d, %d, %f [", before_last_idx, last_idx, next_idx, (float)cp); for (k=0; k<j; k++) printf("%ld ", (long)VECTOR(stack)[k]); printf("]\n"); */ if (cp == 0) { /* The last three points are collinear. Replace the last one in * the stack to the newest one */ VECTOR(stack)[j-1]=next_idx; } else if (cp < 0) { /* We are turning into the right direction */ IGRAPH_CHECK(igraph_vector_push_back(&stack, next_idx)); j++; } else { /* No, skip back until we're okay */ while (cp >= 0 && j > 2) { igraph_vector_pop_back(&stack); j--; last_idx=VECTOR(stack)[j-1]; before_last_idx=VECTOR(stack)[j-2]; cp=(MATRIX(*data, last_idx, 0)-MATRIX(*data, before_last_idx, 0))* (MATRIX(*data, next_idx, 1)-MATRIX(*data, before_last_idx, 1))- (MATRIX(*data, next_idx, 0)-MATRIX(*data, before_last_idx, 0))* (MATRIX(*data, last_idx, 1)-MATRIX(*data, before_last_idx, 1)); } IGRAPH_CHECK(igraph_vector_push_back(&stack, next_idx)); j++; } } } /* Create result vector */ if (resverts != 0) { igraph_vector_clear(resverts); IGRAPH_CHECK(igraph_vector_append(resverts, &stack)); } if (rescoords != 0) { igraph_matrix_select_rows(data, rescoords, &stack); } /* Free everything */ igraph_vector_destroy(&stack); igraph_indheap_destroy(&order); IGRAPH_FINALLY_CLEAN(2); return 0; }
int igraph_incidence(igraph_t *graph, igraph_vector_bool_t *types, const igraph_matrix_t *incidence, igraph_bool_t directed, igraph_neimode_t mode, igraph_bool_t multiple) { igraph_integer_t n1=(igraph_integer_t) igraph_matrix_nrow(incidence); igraph_integer_t n2=(igraph_integer_t) igraph_matrix_ncol(incidence); igraph_integer_t no_of_nodes=n1+n2; igraph_vector_t edges; long int i, j, k; IGRAPH_VECTOR_INIT_FINALLY(&edges, 0); if (multiple) { for (i=0; i<n1; i++) { for (j=0; j<n2; j++) { long int elem=(long int) MATRIX(*incidence, i, j); long int from, to; if (!elem) { continue; } if (mode == IGRAPH_IN) { from=n1+j; to=i; } else { from=i; to=n1+j; } if (mode != IGRAPH_ALL || !directed) { for (k=0; k<elem; k++) { IGRAPH_CHECK(igraph_vector_push_back(&edges, from)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to)); } } else { for (k=0; k<elem; k++) { IGRAPH_CHECK(igraph_vector_push_back(&edges, from)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to)); IGRAPH_CHECK(igraph_vector_push_back(&edges, from)); } } } } } else { for (i=0; i<n1; i++) { for (j=0; j<n2; j++) { long int from, to; if (MATRIX(*incidence, i, j) != 0) { if (mode == IGRAPH_IN) { from=n1+j; to=i; } else { from=i; to=n1+j; } if (mode != IGRAPH_ALL || !directed) { IGRAPH_CHECK(igraph_vector_push_back(&edges, from)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to)); } else { IGRAPH_CHECK(igraph_vector_push_back(&edges, from)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to)); IGRAPH_CHECK(igraph_vector_push_back(&edges, to)); IGRAPH_CHECK(igraph_vector_push_back(&edges, from)); } } } } } IGRAPH_CHECK(igraph_create(graph, &edges, no_of_nodes, directed)); igraph_vector_destroy(&edges); IGRAPH_FINALLY_CLEAN(1); IGRAPH_FINALLY(igraph_destroy, graph); if (types) { IGRAPH_CHECK(igraph_vector_bool_resize(types, no_of_nodes)); igraph_vector_bool_null(types); for (i=n1; i<no_of_nodes; i++) { VECTOR(*types)[i] = 1; } } IGRAPH_FINALLY_CLEAN(1); return 0; }
int igraph_lapack_dgehrd(const igraph_matrix_t *A, int ilo, int ihi, igraph_matrix_t *result) { int n=(int) igraph_matrix_nrow(A); int lda=n; int lwork=-1; igraph_vector_t work; igraph_real_t optwork; igraph_vector_t tau; igraph_matrix_t Acopy; int info=0; int i; if (igraph_matrix_ncol(A) != n) { IGRAPH_ERROR("Hessenberg reduction failed", IGRAPH_NONSQUARE); } if (ilo < 1 || ihi > n || ilo > ihi) { IGRAPH_ERROR("Invalid `ilo' and/or `ihi'", IGRAPH_EINVAL); } if (n <= 1) { IGRAPH_CHECK(igraph_matrix_update(result, A)); return 0; } IGRAPH_CHECK(igraph_matrix_copy(&Acopy, A)); IGRAPH_FINALLY(igraph_matrix_destroy, &Acopy); IGRAPH_VECTOR_INIT_FINALLY(&tau, n-1); igraphdgehrd_(&n, &ilo, &ihi, &MATRIX(Acopy, 0, 0), &lda, VECTOR(tau), &optwork, &lwork, &info); if (info != 0) { IGRAPH_ERROR("Internal Hessenberg transformation error", IGRAPH_EINTERNAL); } lwork=(int) optwork; IGRAPH_VECTOR_INIT_FINALLY(&work, lwork); igraphdgehrd_(&n, &ilo, &ihi, &MATRIX(Acopy, 0, 0), &lda, VECTOR(tau), VECTOR(work), &lwork, &info); if (info != 0) { IGRAPH_ERROR("Internal Hessenberg transformation error", IGRAPH_EINTERNAL); } igraph_vector_destroy(&work); igraph_vector_destroy(&tau); IGRAPH_FINALLY_CLEAN(2); IGRAPH_CHECK(igraph_matrix_update(result, &Acopy)); igraph_matrix_destroy(&Acopy); IGRAPH_FINALLY_CLEAN(1); for (i=0; i<n-2; i++) { int j; for (j=i+2; j<n; j++) { MATRIX(*result, j, i) = 0.0; } } return 0; }
/** * \ingroup nongraph * \function igraph_convex_hull * \brief Determines the convex hull of a given set of points in the 2D plane * * </para><para> * The convex hull is determined by the Graham scan algorithm. * See the following reference for details: * * </para><para> * Thomas H. Cormen, Charles E. Leiserson, Ronald L. Rivest, and Clifford * Stein. Introduction to Algorithms, Second Edition. MIT Press and * McGraw-Hill, 2001. ISBN 0262032937. Pages 949-955 of section 33.3: * Finding the convex hull. * * \param data vector containing the coordinates. The length of the * vector must be even, since it contains X-Y coordinate pairs. * \param resverts the vector containing the result, e.g. the vector of * vertex indices used as the corners of the convex hull. Supply * \c NULL here if you are only interested in the coordinates of * the convex hull corners. * \param rescoords the matrix containing the coordinates of the selected * corner vertices. Supply \c NULL here if you are only interested in * the vertex indices. * \return Error code: * \c IGRAPH_ENOMEM: not enough memory * * Time complexity: O(n log(n)) where n is the number of vertices * * \example examples/simple/igraph_convex_hull.c */ int igraph_convex_hull(const igraph_matrix_t *data, igraph_vector_t *resverts, igraph_matrix_t *rescoords) { igraph_integer_t no_of_nodes; long int i, pivot_idx=0, last_idx, before_last_idx, next_idx, j; igraph_vector_t angles, stack, order; igraph_real_t px, py, cp; no_of_nodes=(igraph_integer_t) igraph_matrix_nrow(data); if (igraph_matrix_ncol(data) != 2) { IGRAPH_ERROR("matrix must have 2 columns", IGRAPH_EINVAL); } if (no_of_nodes == 0) { if (resverts != 0) { IGRAPH_CHECK(igraph_vector_resize(resverts, 0)); } if (rescoords != 0) { IGRAPH_CHECK(igraph_matrix_resize(rescoords, 0, 2)); } /**************************** this is an exit here *********/ return 0; } IGRAPH_VECTOR_INIT_FINALLY(&angles, no_of_nodes); IGRAPH_VECTOR_INIT_FINALLY(&stack, 0); /* Search for the pivot vertex */ for (i=1; i<no_of_nodes; i++) { if (MATRIX(*data, i, 1)<MATRIX(*data, pivot_idx, 1)) pivot_idx=i; else if (MATRIX(*data, i, 1) == MATRIX(*data, pivot_idx, 1) && MATRIX(*data, i, 0) < MATRIX(*data, pivot_idx, 0)) pivot_idx=i; } px=MATRIX(*data, pivot_idx, 0); py=MATRIX(*data, pivot_idx, 1); /* Create angle array */ for (i=0; i<no_of_nodes; i++) { if (i == pivot_idx) { /* We can't calculate the angle of the pivot point with itself, * so we use 10 here. This way, after sorting the angle vector, * the pivot point will always be the first one, since the range * of atan2 is -3.14..3.14 */ VECTOR(angles)[i] = 10; } else { VECTOR(angles)[i] = atan2(MATRIX(*data, i, 1)-py, MATRIX(*data, i, 0)-px); } } /* Sort points by angles */ IGRAPH_VECTOR_INIT_FINALLY(&order, no_of_nodes); IGRAPH_CHECK(igraph_vector_qsort_ind(&angles, &order, 0)); /* Check if two points have the same angle. If so, keep only the point that * is farthest from the pivot */ j = 0; last_idx = (long int) VECTOR(order)[0]; pivot_idx = (long int) VECTOR(order)[no_of_nodes - 1]; for (i=1; i < no_of_nodes; i++) { next_idx = (long int) VECTOR(order)[i]; if (VECTOR(angles)[last_idx] == VECTOR(angles)[next_idx]) { /* Keep the vertex that is farther from the pivot, drop the one that is * closer */ px = pow(MATRIX(*data, last_idx, 0) - MATRIX(*data, pivot_idx, 0), 2) + pow(MATRIX(*data, last_idx, 1) - MATRIX(*data, pivot_idx, 1), 2); py = pow(MATRIX(*data, next_idx, 0) - MATRIX(*data, pivot_idx, 0), 2) + pow(MATRIX(*data, next_idx, 1) - MATRIX(*data, pivot_idx, 1), 2); if (px > py) { VECTOR(order)[i] = -1; } else { VECTOR(order)[j] = -1; last_idx = next_idx; j = i; } } else { last_idx = next_idx; j = i; } } j=0; last_idx=-1; before_last_idx=-1; while (!igraph_vector_empty(&order)) { next_idx=(long int)VECTOR(order)[igraph_vector_size(&order) - 1]; if (next_idx < 0) { /* This vertex should be skipped; was excluded in an earlier step */ igraph_vector_pop_back(&order); continue; } /* Determine whether we are at a left or right turn */ if (j < 2) { /* Pretend that we are turning into the right direction if we have less * than two items in the stack */ cp=-1; } else { cp=(MATRIX(*data, last_idx, 0)-MATRIX(*data, before_last_idx, 0))* (MATRIX(*data, next_idx, 1)-MATRIX(*data, before_last_idx, 1))- (MATRIX(*data, next_idx, 0)-MATRIX(*data, before_last_idx, 0))* (MATRIX(*data, last_idx, 1)-MATRIX(*data, before_last_idx, 1)); } /* printf("B L N cp: %ld, %ld, %ld, %f [", before_last_idx, last_idx, next_idx, (float)cp); for (int k=0; k<j; k++) printf("%ld ", (long)VECTOR(stack)[k]); printf("]\n"); */ if (cp < 0) { /* We are turning into the right direction */ igraph_vector_pop_back(&order); IGRAPH_CHECK(igraph_vector_push_back(&stack, next_idx)); before_last_idx = last_idx; last_idx = next_idx; j++; } else { /* No, skip back and try again in the next iteration */ igraph_vector_pop_back(&stack); j--; last_idx = before_last_idx; before_last_idx = (j >= 2) ? (long int) VECTOR(stack)[j-2] : -1; } } /* Create result vector */ if (resverts != 0) { igraph_vector_clear(resverts); IGRAPH_CHECK(igraph_vector_append(resverts, &stack)); } if (rescoords != 0) { igraph_matrix_select_rows(data, rescoords, &stack); } /* Free everything */ igraph_vector_destroy(&order); igraph_vector_destroy(&stack); igraph_vector_destroy(&angles); IGRAPH_FINALLY_CLEAN(3); return 0; }
/*__________________________________________________________________________ MAIN CYCLE (FLTK CYCLE) ____*/ void mainidle_cb(void*){ //this routine updates the program. //thus, it computes the EVOLUTION double shooted; double dens, err; double totdens, toterr, totimerr; char s[100]; // ---- running controls AND PRINTING if( (amstepping==0 && runningcontrol==1 && graphisloaded==1 && ticks<=maxtime ) || (amstepping==1 && runningcontrol==1 && graphisloaded==1 && ticks<=maxtime && tickstep<=step-1) ) { Evolution(deltat); //PRINTS if((int)printdatabutton->value()==1){ //if have steady state if(usesteady==1){ igraph_matrix_t activation; igraph_matrix_init(&activation,nodesnumber,totrun); igraph_matrix_null(&activation); igraph_vector_t correlation; igraph_vector_init(&correlation,(nodesnumber*nodesnumber)); igraph_vector_null(&correlation); fprintf(output1,"%i ", ticks); fprintf(output2,"%i ", ticks); fprintf(output5,"%i ", ticks); fprintf(output6,"%i ", ticks); totdens=0; toterr=0; for(int i=0;i<nodesnumber;++i){ shooted=0; dens=0; err=0; for(int j=0; j<totrun; ++j){ dens=dens+MATRIX(density,i,j); err=err+((VECTOR(statstate)[i]-MATRIX(density,i,j))*(VECTOR(statstate)[i]-MATRIX(density,i,j))); shooted=shooted+MATRIX(loss,i,j); if(MATRIX(loss,i,j)!=0){++MATRIX(activation,i,j);} } dens=dens/totrun; err=sqrt(err)/totrun; shooted=shooted/totrun; totdens=totdens+dens; toterr=toterr+err; fprintf(output1,"%f ",dens); fprintf(output2,"%f ",err); fprintf(output5,"%f ",shooted); } totdens=totdens/nodesnumber; toterr=toterr/nodesnumber; fprintf(output1,"%f ",totdens); fprintf(output2,"%f ",toterr); // printf("\n\n ACTIVATION MATRIX \n \n"); print_matrix_ur(&activation,stdout); printf("\n\n"); // ---- CORRELATION --- igraph_vector_t meanactivation; igraph_vector_init(&meanactivation,nodesnumber); igraph_vector_null(&meanactivation); //calculate mean activation for (int j=0; j<totrun; ++j) { for (int i=0; i<nodesnumber; ++i) { VECTOR(meanactivation)[i]=VECTOR(meanactivation)[i]+MATRIX(activation,i,j); } } igraph_vector_scale(&meanactivation,1./totrun); //calculate actual correlation for (int x=0; x<nodesnumber ; ++x) { for(int y=0; y<nodesnumber; ++y){ double prod=0; for (int j=0; j<totrun; ++j) { prod=prod+ ( MATRIX(activation,x,j)*MATRIX(activation,y,j) ); } prod=prod/totrun; VECTOR(correlation)[(x*nodesnumber+y)] = prod - (VECTOR(meanactivation)[x]*VECTOR(meanactivation)[y]); } } igraph_vector_destroy(&meanactivation); for (int i=0; i<(nodesnumber*nodesnumber); ++i) { fprintf(output6,"%f ",VECTOR(correlation)[i]); } //calculate error on run igraph_matrix_t distl1; igraph_matrix_t distimel1; igraph_matrix_init(&distl1,nodesnumber,totrun); igraph_matrix_init(&distimel1,nodesnumber,totrun); igraph_matrix_null(&distl1); igraph_matrix_null(&distimel1); igraph_vector_t rundistl1; igraph_vector_t rundistimel1; igraph_vector_init(&rundistl1,totrun); igraph_vector_init(&rundistimel1,totrun); igraph_vector_null(&rundistl1); igraph_vector_null(&rundistimel1); toterr=0; totimerr=0; //for every run for(int j=0;j<totrun;++j){ //i evaluate the distance between the state and the stationary state (toterr) and the distance between old and new density (totimerr) for(int i=0; i<nodesnumber; ++i) { //L1 DISTANCE WRT STATSTATE & DENSITY MATRIX(distl1,i,j)=fabs(VECTOR(statstate)[i]-MATRIX(density,i,j)); //L1 DISTANCE WRT OLD DENSITY & DENSITY MATRIX(distimel1,i,j)=fabs(MATRIX(densityold,i,j)-MATRIX(density,i,j)); } } igraph_matrix_rowsum(&distl1,&rundistl1); igraph_matrix_rowsum(&distimel1,&rundistimel1); igraph_vector_scale(&rundistl1,(1./nodesnumber)); igraph_vector_scale(&rundistimel1,(1./nodesnumber)); toterr= (double)( igraph_vector_sum(&rundistl1) ) / (double)totrun ; totimerr= (double)( igraph_vector_sum(&rundistimel1)) / (double)totrun; igraph_vector_destroy(&rundistl1); igraph_vector_destroy(&rundistimel1); igraph_matrix_destroy(&distl1); igraph_matrix_destroy(&distimel1); fprintf(output2,"%f %f",toterr, totimerr); fprintf(output1,"\n"); fprintf(output2,"\n"); fprintf(output5,"\n"); fprintf(output6,"\n"); //if i have BRIDGES ("clustered" graph), I print the traffic on the BRIDGES, using "output3" file if(isclustered==1){ //for each bridge fprintf(output3,"%i ",ticks); for(int nbri=0; nbri<igraph_matrix_ncol(&bridgeslinks); ++nbri){ for(int i=0; i<igraph_matrix_nrow(&bridgeslinks);++i){ double tfl=0; for(int j=0; j<totrun; ++j){ int beid; beid=(int)MATRIX(bridgeslinks,i,nbri); tfl=tfl+MATRIX(flux,beid,j); } fprintf(output3,"%f ",tfl); } } fprintf(output3,"\n"); } igraph_matrix_destroy(&activation); igraph_vector_destroy(&correlation); } //if i HAVENT STEADY STATE else { fprintf(output1,"%i ", ticks); fprintf(output5,"%i ", ticks); for(int i=0;i<nodesnumber;++i){ shooted=0; dens=0; for(int j=0; j<totrun; ++j){ dens=dens+MATRIX(density,i,j); shooted=shooted+MATRIX(loss,i,j); } dens=dens/totrun; shooted=shooted/totrun; fprintf(output1,"%f " ,dens); fprintf(output5,"%f " ,shooted); } fprintf(output1,"\n"); fprintf(output5,"\n"); } } } if((ticks==maxtime || tickstep==step) && runningcontrol==1){ run(); } // ---- no graph loaded if(graphisloaded==0 && rewrite==1) { runbutton->deactivate(); sprintf(s,"No\nnetwork\nloaded"); databuff->text(s); } // ---- graph loaded else { runbutton->activate(); if(islattice==1 && rewrite==1){ if(istoro==1){ sprintf(s,"Nodes=%i\nToroidal\nLattice\n%iD Side=%i",nodesnumber, latticedim, latticeside); } else{ sprintf(s,"Nodes=%i\nLattice\n%iD Side=%i",nodesnumber, latticedim, latticeside); } databuff->text(s); } else if(rewrite==1){ sprintf(s,"Nodes=%i",nodesnumber); databuff->text(s); } } //have path if(havepath==1 && rewrite==1){pathbuff->text(path); } else if(havepath==0 && rewrite==1){pathbuff->text("No Path");} if(error==1 && rewrite==1){ sprintf(s,errorstring); databuff->text(s); } if (ticks<=maxtime){ scene->redraw(); datascene->redraw(); } rewrite=0; //Fl::repeat_timeout(1.0, mainidle_cb); }
int igraph_layout_gem(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t maxiter, igraph_real_t temp_max, igraph_real_t temp_min, igraph_real_t temp_init) { igraph_integer_t no_nodes = igraph_vcount(graph); igraph_vector_int_t perm; igraph_vector_float_t impulse_x, impulse_y, temp, skew_gauge; igraph_integer_t i; float temp_global; igraph_integer_t perm_pointer = 0; float barycenter_x = 0.0, barycenter_y = 0.0; igraph_vector_t phi; igraph_vector_t neis; const float elen_des2 = 128 * 128; const float gamma = 1/16.0; const float alpha_o = M_PI; const float alpha_r = M_PI / 3.0; const float sigma_o = 1.0 / 3.0; const float sigma_r = 1.0 / 2.0 / no_nodes; if (maxiter < 0) { IGRAPH_ERROR("Number of iterations must be non-negative in GEM layout", IGRAPH_EINVAL); } if (use_seed && (igraph_matrix_nrow(res) != no_nodes || igraph_matrix_ncol(res) != 2)) { IGRAPH_ERROR("Invalid start position matrix size in GEM layout", IGRAPH_EINVAL); } if (temp_max <= 0) { IGRAPH_ERROR("Maximum temperature should be positive in GEM layout", IGRAPH_EINVAL); } if (temp_min <= 0) { IGRAPH_ERROR("Minimum temperature should be positive in GEM layout", IGRAPH_EINVAL); } if (temp_init <= 0) { IGRAPH_ERROR("Initial temperature should be positive in GEM layout", IGRAPH_EINVAL); } if (temp_max < temp_init || temp_init < temp_min) { IGRAPH_ERROR("Minimum <= Initial <= Maximum temperature is required " "in GEM layout", IGRAPH_EINVAL); } if (no_nodes == 0) { return 0; } IGRAPH_CHECK(igraph_vector_float_init(&impulse_x, no_nodes)); IGRAPH_FINALLY(igraph_vector_float_destroy, &impulse_x); IGRAPH_CHECK(igraph_vector_float_init(&impulse_y, no_nodes)); IGRAPH_FINALLY(igraph_vector_float_destroy, &impulse_y); IGRAPH_CHECK(igraph_vector_float_init(&temp, no_nodes)); IGRAPH_FINALLY(igraph_vector_float_destroy, &temp); IGRAPH_CHECK(igraph_vector_float_init(&skew_gauge, no_nodes)); IGRAPH_FINALLY(igraph_vector_float_destroy, &skew_gauge); IGRAPH_CHECK(igraph_vector_int_init_seq(&perm, 0, no_nodes-1)); IGRAPH_FINALLY(igraph_vector_int_destroy, &perm); IGRAPH_VECTOR_INIT_FINALLY(&phi, no_nodes); IGRAPH_VECTOR_INIT_FINALLY(&neis, 10); RNG_BEGIN(); /* Initialization */ igraph_degree(graph, &phi, igraph_vss_all(), IGRAPH_ALL, IGRAPH_LOOPS); if (!use_seed) { const igraph_real_t width_half=no_nodes*100, height_half=width_half; IGRAPH_CHECK(igraph_matrix_resize(res, no_nodes, 2)); for (i=0; i<no_nodes; i++) { MATRIX(*res, i, 0) = RNG_UNIF(-width_half, width_half); MATRIX(*res, i, 1) = RNG_UNIF(-height_half, height_half); barycenter_x += MATRIX(*res, i, 0); barycenter_y += MATRIX(*res, i, 1); VECTOR(phi)[i] *= (VECTOR(phi)[i] / 2.0 + 1.0); } } else { for (i=0; i<no_nodes; i++) { barycenter_x += MATRIX(*res, i, 0); barycenter_y += MATRIX(*res, i, 1); VECTOR(phi)[i] *= (VECTOR(phi)[i] / 2.0 + 1.0); } } igraph_vector_float_fill(&temp, temp_init); temp_global = temp_init * no_nodes; while (temp_global > temp_min * no_nodes && maxiter > 0) { /* choose a vertex v to update */ igraph_integer_t u, v, nlen, j; float px, py, pvx, pvy; if (!perm_pointer) { igraph_vector_int_shuffle(&perm); perm_pointer=no_nodes-1; } v=VECTOR(perm)[perm_pointer--]; /* compute v's impulse */ px = (barycenter_x/no_nodes - MATRIX(*res, v, 0)) * gamma * VECTOR(phi)[v]; py = (barycenter_y/no_nodes - MATRIX(*res, v, 1)) * gamma * VECTOR(phi)[v]; px += RNG_UNIF(-32.0, 32.0); py += RNG_UNIF(-32.0, 32.0); for (u = 0; u < no_nodes; u++) { float dx, dy, dist2; if (u == v) { continue; } dx=MATRIX(*res, v, 0) - MATRIX(*res, u, 0); dy=MATRIX(*res, v, 1) - MATRIX(*res, u, 1); dist2=dx * dx + dy * dy; if (dist2 != 0) { px += dx * elen_des2 / dist2; py += dy * elen_des2 / dist2; } } IGRAPH_CHECK(igraph_neighbors(graph, &neis, v, IGRAPH_ALL)); nlen=igraph_vector_size(&neis); for (j = 0; j < nlen; j++) { igraph_integer_t u=VECTOR(neis)[j]; float dx=MATRIX(*res, v, 0) - MATRIX(*res, u, 0); float dy=MATRIX(*res, v, 1) - MATRIX(*res, u, 1); float dist2= dx * dx + dy * dy; px -= dx * dist2 / (elen_des2 * VECTOR(phi)[v]); py -= dy * dist2 / (elen_des2 * VECTOR(phi)[v]); } /* update v's position and temperature */ if (px != 0 || py != 0) { float plen = sqrtf(px * px + py * py); px *= VECTOR(temp)[v] / plen; py *= VECTOR(temp)[v] / plen; MATRIX(*res, v, 0) += px; MATRIX(*res, v, 1) += py; barycenter_x += px; barycenter_y += py; } pvx=VECTOR(impulse_x)[v]; pvy=VECTOR(impulse_y)[v]; if (pvx != 0 || pvy != 0) { float beta = atan2f(pvy - py, pvx - px); float sin_beta = sinf(beta); float sign_sin_beta = (sin_beta > 0) ? 1 : ((sin_beta < 0) ? -1 : 0); float cos_beta = cosf(beta); float abs_cos_beta = fabsf(cos_beta); float old_temp=VECTOR(temp)[v]; if (sin(beta) >= sin(M_PI_2 + alpha_r / 2.0)) { VECTOR(skew_gauge)[v] += sigma_r * sign_sin_beta; } if (abs_cos_beta >= cosf(alpha_o / 2.0)) { VECTOR(temp)[v] *= sigma_o * cos_beta; } VECTOR(temp)[v] *= (1 - fabsf(VECTOR(skew_gauge)[v])); if (VECTOR(temp)[v] > temp_max) { VECTOR(temp)[v] = temp_max; } VECTOR(impulse_x)[v] = px; VECTOR(impulse_y)[v] = py; temp_global += VECTOR(temp)[v] - old_temp; } maxiter--; } /* while temp && iter */ RNG_END(); igraph_vector_destroy(&neis); igraph_vector_destroy(&phi); igraph_vector_int_destroy(&perm); igraph_vector_float_destroy(&skew_gauge); igraph_vector_float_destroy(&temp); igraph_vector_float_destroy(&impulse_y); igraph_vector_float_destroy(&impulse_x); IGRAPH_FINALLY_CLEAN(7); return 0; }