int igraph_layout_kamada_kawai(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t maxiter, igraph_real_t epsilon, igraph_real_t kkconst, const igraph_vector_t *weights, const igraph_vector_t *minx, const igraph_vector_t *maxx, const igraph_vector_t *miny, const igraph_vector_t *maxy) { igraph_integer_t no_nodes=igraph_vcount(graph); igraph_integer_t no_edges=igraph_ecount(graph); igraph_real_t L, L0=sqrt(no_nodes); igraph_matrix_t dij, lij, kij; igraph_real_t max_dij; igraph_vector_t D1, D2; igraph_integer_t i, j, m; if (maxiter < 0) { IGRAPH_ERROR("Number of iterations must be non-negatice in " "Kamada-Kawai layout", IGRAPH_EINVAL); } if (kkconst <= 0) { IGRAPH_ERROR("`K' constant must be positive in Kamada-Kawai 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 " "Kamada-Kawai layout", IGRAPH_EINVAL); } if (weights && igraph_vector_size(weights) != no_edges) { IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL); } if (minx && igraph_vector_size(minx) != no_nodes) { IGRAPH_ERROR("Invalid minx vector length", IGRAPH_EINVAL); } if (maxx && igraph_vector_size(maxx) != no_nodes) { IGRAPH_ERROR("Invalid maxx vector length", IGRAPH_EINVAL); } if (minx && maxx && !igraph_vector_all_le(minx, maxx)) { IGRAPH_ERROR("minx must not be greater than maxx", IGRAPH_EINVAL); } if (miny && igraph_vector_size(miny) != no_nodes) { IGRAPH_ERROR("Invalid miny vector length", IGRAPH_EINVAL); } if (maxy && igraph_vector_size(maxy) != no_nodes) { IGRAPH_ERROR("Invalid maxy vector length", IGRAPH_EINVAL); } if (miny && maxy && !igraph_vector_all_le(miny, maxy)) { IGRAPH_ERROR("miny must not be greater than maxy", IGRAPH_EINVAL); } if (!use_seed) { if (minx || maxx || miny || maxy) { const igraph_real_t width=sqrt(no_nodes), height=width; IGRAPH_CHECK(igraph_matrix_resize(res, no_nodes, 2)); RNG_BEGIN(); for (i=0; i<no_nodes; i++) { igraph_real_t x1=minx ? VECTOR(*minx)[i] : -width/2; igraph_real_t x2=maxx ? VECTOR(*maxx)[i] : width/2; igraph_real_t y1=miny ? VECTOR(*miny)[i] : -height/2; igraph_real_t y2=maxy ? VECTOR(*maxy)[i] : height/2; if (!igraph_finite(x1)) { x1 = -width/2; } if (!igraph_finite(x2)) { x2 = width/2; } if (!igraph_finite(y1)) { y1 = -height/2; } if (!igraph_finite(y2)) { y2 = height/2; } MATRIX(*res, i, 0) = RNG_UNIF(x1, x2); MATRIX(*res, i, 1) = RNG_UNIF(y1, y2); } RNG_END(); } else { igraph_layout_circle(graph, res, /* order= */ igraph_vss_all()); } } if (no_nodes <= 1) { return 0; } IGRAPH_MATRIX_INIT_FINALLY(&dij, no_nodes, no_nodes); IGRAPH_MATRIX_INIT_FINALLY(&kij, no_nodes, no_nodes); IGRAPH_MATRIX_INIT_FINALLY(&lij, no_nodes, no_nodes); IGRAPH_CHECK(igraph_shortest_paths_dijkstra(graph, &dij, igraph_vss_all(), igraph_vss_all(), weights, IGRAPH_ALL)); max_dij = 0.0; for (i=0; i<no_nodes; i++) { for (j=i+1; j<no_nodes; j++) { if (!igraph_finite(MATRIX(dij, i, j))) { continue; } if (MATRIX(dij, i, j) > max_dij) { max_dij = MATRIX(dij, i, j); } } } for (i=0; i<no_nodes; i++) { for (j=0; j<no_nodes; j++) { if (MATRIX(dij, i, j) > max_dij) { MATRIX(dij, i, j) = max_dij; } } } L = L0 / max_dij; for (i=0; i<no_nodes; i++) { for (j=0; j<no_nodes; j++) { igraph_real_t tmp=MATRIX(dij, i, j) * MATRIX(dij, i, j); if (i==j) { continue; } MATRIX(kij, i, j) = kkconst / tmp; MATRIX(lij, i, j) = L * MATRIX(dij, i, j); } } /* Initialize delta */ IGRAPH_VECTOR_INIT_FINALLY(&D1, no_nodes); IGRAPH_VECTOR_INIT_FINALLY(&D2, no_nodes); for (m=0; m<no_nodes; m++) { igraph_real_t myD1=0.0, myD2=0.0; for (i=0; i<no_nodes; i++) { if (i==m) { continue; } igraph_real_t dx=MATRIX(*res, m, 0) - MATRIX(*res, i, 0); igraph_real_t dy=MATRIX(*res, m, 1) - MATRIX(*res, i, 1); igraph_real_t mi_dist=sqrt(dx * dx + dy * dy); myD1 += MATRIX(kij, m, i) * (dx - MATRIX(lij, m, i) * dx / mi_dist); myD2 += MATRIX(kij, m, i) * (dy - MATRIX(lij, m, i) * dy / mi_dist); } VECTOR(D1)[m] = myD1; VECTOR(D2)[m] = myD2; } for (j=0; j<maxiter; j++) { igraph_real_t myD1=0.0, myD2=0.0, A=0.0, B=0.0, C=0.0; igraph_real_t max_delta, delta_x, delta_y; igraph_real_t old_x, old_y, new_x, new_y; /* Select maximal delta */ m=0; max_delta=-1; for (i=0; i<no_nodes; i++) { igraph_real_t delta=(VECTOR(D1)[i] * VECTOR(D1)[i] + VECTOR(D2)[i] * VECTOR(D2)[i]); if (delta > max_delta) { m=i; max_delta=delta; } } if (max_delta < epsilon) { break; } old_x=MATRIX(*res, m, 0); old_y=MATRIX(*res, m, 1); /* Calculate D1 and D2, A, B, C */ for (i=0; i<no_nodes; i++) { if (i==m) { continue; } igraph_real_t dx=old_x - MATRIX(*res, i, 0); igraph_real_t dy=old_y - MATRIX(*res, i, 1); igraph_real_t dist=sqrt(dx * dx + dy * dy); igraph_real_t den=dist * (dx * dx + dy * dy); A += MATRIX(kij, m, i) * (1 - MATRIX(lij, m, i) * dy * dy / den); B += MATRIX(kij, m, i) * MATRIX(lij, m, i) * dx * dy / den; C += MATRIX(kij, m, i) * (1 - MATRIX(lij, m, i) * dx * dx / den); } myD1 = VECTOR(D1)[m]; myD2 = VECTOR(D2)[m]; /* Need to solve some linear equations */ delta_y = (B * myD1 - myD2 * A) / (C * A - B * B); delta_x = - (myD1 + B * delta_y) / A; new_x = old_x + delta_x; new_y = old_y + delta_y; /* Limits, if given */ if (minx && new_x < VECTOR(*minx)[m]) { new_x = VECTOR(*minx)[m]; } if (maxx && new_x > VECTOR(*maxx)[m]) { new_x = VECTOR(*maxx)[m]; } if (miny && new_y < VECTOR(*miny)[m]) { new_y = VECTOR(*miny)[m]; } if (maxy && new_y > VECTOR(*maxy)[m]) { new_y = VECTOR(*maxy)[m]; } /* Update delta, only with/for the affected node */ VECTOR(D1)[m] = VECTOR(D2)[m] = 0.0; for (i=0; i<no_nodes; i++) { if (i==m) { continue; } igraph_real_t old_dx=old_x - MATRIX(*res, i, 0); igraph_real_t old_dy=old_y - MATRIX(*res, i, 1); igraph_real_t old_mi_dist=sqrt(old_dx * old_dx + old_dy * old_dy); igraph_real_t new_dx=new_x - MATRIX(*res, i, 0); igraph_real_t new_dy=new_y - MATRIX(*res, i, 1); igraph_real_t new_mi_dist=sqrt(new_dx * new_dx + new_dy * new_dy); VECTOR(D1)[i] -= MATRIX(kij, m, i) * (-old_dx + MATRIX(lij, m, i) * old_dx / old_mi_dist); VECTOR(D2)[i] -= MATRIX(kij, m, i) * (-old_dy + MATRIX(lij, m, i) * old_dy / old_mi_dist); VECTOR(D1)[i] += MATRIX(kij, m, i) * (-new_dx + MATRIX(lij, m, i) * new_dx / new_mi_dist); VECTOR(D2)[i] += MATRIX(kij, m, i) * (-new_dy + MATRIX(lij, m, i) * new_dy / new_mi_dist); VECTOR(D1)[m] += MATRIX(kij, m, i) * (new_dx - MATRIX(lij, m, i) * new_dx / new_mi_dist); VECTOR(D2)[m] += MATRIX(kij, m, i) * (new_dy - MATRIX(lij, m, i) * new_dy / new_mi_dist); } /* Update coordinates*/ MATRIX(*res, m, 0) = new_x; MATRIX(*res, m, 1) = new_y; } igraph_vector_destroy(&D2); igraph_vector_destroy(&D1); igraph_matrix_destroy(&lij); igraph_matrix_destroy(&kij); igraph_matrix_destroy(&dij); IGRAPH_FINALLY_CLEAN(5); return 0; }
int main() { igraph_t g; igraph_vector_t tdist; igraph_matrix_t pmat; igraph_bool_t conn; igraph_vector_bool_t bs; int i, ret; /* Symmetric preference game */ igraph_vector_bool_init(&bs, 0); igraph_vector_init_real(&tdist, 3, 1.0, 1.0, 1.0); igraph_matrix_init(&pmat, 3, 3); for (i=0; i<3; i++) MATRIX(pmat, i, i) = 0.2; /* undirected, no loops */ IGRAPH_CHECK(igraph_preference_game(&g, 1000, 3, &tdist, /*fixed_sizes=*/ 0, &pmat, 0, 0, 0)); if (igraph_vcount(&g) != 1000) return 18; if (igraph_is_directed(&g)) return 2; igraph_is_connected(&g, &conn, IGRAPH_STRONG); if (conn) return 3; igraph_is_loop(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs)) return 4; igraph_is_multiple(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs)) return 5; igraph_destroy(&g); for (i=0; i<2; i++) MATRIX(pmat, i, i+1) = 0.1; /* directed, no loops */ IGRAPH_CHECK(igraph_preference_game(&g, 1000, 3, &tdist, /*fixed_sizes=*/0, &pmat, 0, 1, 0)); if (igraph_vcount(&g) != 1000) return 17; if (!igraph_is_directed(&g)) return 6; igraph_is_loop(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs)) return 7; igraph_is_multiple(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs)) return 8; igraph_destroy(&g); /* undirected, loops */ for (i=0; i<3; i++) MATRIX(pmat, i, i) = 1.0; IGRAPH_CHECK(igraph_preference_game(&g, 100, 3, &tdist, /*fixed_sizes=*/ 0, &pmat, 0, 0, 1)); if (igraph_vcount(&g) != 100) return 16; if (igraph_ecount(&g) < 1395) return 20; if (igraph_is_directed(&g)) return 9; igraph_is_loop(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs) == 0) return 10; igraph_is_multiple(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs)) return 11; igraph_destroy(&g); /* directed, loops */ IGRAPH_CHECK(igraph_preference_game(&g, 100, 3, &tdist, /*fixed_sizes=*/ 0, &pmat, 0, 1, 1)); if (igraph_vcount(&g) != 100) return 15; if (igraph_ecount(&g) < 2700) return 19; if (!igraph_is_directed(&g)) return 12; igraph_is_loop(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs) == 0) return 13; igraph_is_multiple(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs)) return 14; igraph_destroy(&g); /* Asymmetric preference game */ /* directed, no loops */ igraph_matrix_resize(&pmat, 2, 2); MATRIX(pmat, 0, 0) = 1; MATRIX(pmat, 0, 1) = 1; MATRIX(pmat, 1, 0) = 1; MATRIX(pmat, 1, 1) = 1; IGRAPH_CHECK(igraph_asymmetric_preference_game(&g, 100, 2, 0, &pmat, 0, 0, 0)); if (igraph_vcount(&g) != 100) return 21; if (igraph_ecount(&g) != 9900) return 22; if (!igraph_is_directed(&g)) return 23; igraph_is_loop(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs)) return 24; igraph_is_multiple(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs)) return 25; igraph_destroy(&g); /* directed, loops */ igraph_matrix_resize(&pmat, 2, 2); MATRIX(pmat, 0, 0) = 1; MATRIX(pmat, 0, 1) = 1; MATRIX(pmat, 1, 0) = 1; MATRIX(pmat, 1, 1) = 1; IGRAPH_CHECK(igraph_asymmetric_preference_game(&g, 100, 2, 0, &pmat, 0, 0, 1)); if (igraph_vcount(&g) != 100) return 26; if (igraph_ecount(&g) != 10000) return 27; if (!igraph_is_directed(&g)) return 28; igraph_is_loop(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs) != 100) return 29; igraph_is_multiple(&g, &bs, igraph_ess_all(IGRAPH_EDGEORDER_ID)); if (igraph_vector_bool_sum(&bs)) return 30; igraph_destroy(&g); igraph_vector_destroy(&tdist); igraph_matrix_destroy(&pmat); igraph_vector_bool_destroy(&bs); assert(IGRAPH_FINALLY_STACK_EMPTY); return 0; }
int igraph_layout_kamada_kawai_3d(const igraph_t *graph, igraph_matrix_t *res, igraph_bool_t use_seed, igraph_integer_t maxiter, igraph_real_t epsilon, igraph_real_t kkconst, const igraph_vector_t *weights, const igraph_vector_t *minx, const igraph_vector_t *maxx, const igraph_vector_t *miny, const igraph_vector_t *maxy, const igraph_vector_t *minz, const igraph_vector_t *maxz) { igraph_integer_t no_nodes=igraph_vcount(graph); igraph_integer_t no_edges=igraph_ecount(graph); igraph_real_t L, L0=sqrt(no_nodes); igraph_matrix_t dij, lij, kij; igraph_real_t max_dij; igraph_vector_t D1, D2, D3; igraph_integer_t i, j, m; if (maxiter < 0) { IGRAPH_ERROR("Number of iterations must be non-negatice in " "Kamada-Kawai layout", IGRAPH_EINVAL); } if (kkconst <= 0) { IGRAPH_ERROR("`K' constant must be positive in Kamada-Kawai layout", IGRAPH_EINVAL); } if (use_seed && (igraph_matrix_nrow(res) != no_nodes || igraph_matrix_ncol(res) != 3)) { IGRAPH_ERROR("Invalid start position matrix size in " "3d Kamada-Kawai layout", IGRAPH_EINVAL); } if (weights && igraph_vector_size(weights) != no_edges) { IGRAPH_ERROR("Invalid weight vector length", IGRAPH_EINVAL); } if (minx && igraph_vector_size(minx) != no_nodes) { IGRAPH_ERROR("Invalid minx vector length", IGRAPH_EINVAL); } if (maxx && igraph_vector_size(maxx) != no_nodes) { IGRAPH_ERROR("Invalid maxx vector length", IGRAPH_EINVAL); } if (minx && maxx && !igraph_vector_all_le(minx, maxx)) { IGRAPH_ERROR("minx must not be greater than maxx", IGRAPH_EINVAL); } if (miny && igraph_vector_size(miny) != no_nodes) { IGRAPH_ERROR("Invalid miny vector length", IGRAPH_EINVAL); } if (maxy && igraph_vector_size(maxy) != no_nodes) { IGRAPH_ERROR("Invalid maxy vector length", IGRAPH_EINVAL); } if (miny && maxy && !igraph_vector_all_le(miny, maxy)) { IGRAPH_ERROR("miny must not be greater than maxy", IGRAPH_EINVAL); } if (minz && igraph_vector_size(minz) != no_nodes) { IGRAPH_ERROR("Invalid minz vector length", IGRAPH_EINVAL); } if (maxz && igraph_vector_size(maxz) != no_nodes) { IGRAPH_ERROR("Invalid maxz vector length", IGRAPH_EINVAL); } if (minz && maxz && !igraph_vector_all_le(minz, maxz)) { IGRAPH_ERROR("minz must not be greater than maxz", IGRAPH_EINVAL); } if (!use_seed) { if (minx || maxx || miny || maxy || minz || maxz) { const igraph_real_t width=sqrt(no_nodes), height=width, depth=width; IGRAPH_CHECK(igraph_matrix_resize(res, no_nodes, 3)); RNG_BEGIN(); for (i=0; i<no_nodes; i++) { igraph_real_t x1=minx ? VECTOR(*minx)[i] : -width/2; igraph_real_t x2=maxx ? VECTOR(*maxx)[i] : width/2; igraph_real_t y1=miny ? VECTOR(*miny)[i] : -height/2; igraph_real_t y2=maxy ? VECTOR(*maxy)[i] : height/2; igraph_real_t z1=minz ? VECTOR(*minz)[i] : -depth/2; igraph_real_t z2=maxz ? VECTOR(*maxz)[i] : depth/2; if (!igraph_finite(x1)) { x1 = -width/2; } if (!igraph_finite(x2)) { x2 = width/2; } if (!igraph_finite(y1)) { y1 = -height/2; } if (!igraph_finite(y2)) { y2 = height/2; } if (!igraph_finite(z1)) { z1 = -depth/2; } if (!igraph_finite(z2)) { z2 = depth/2; } MATRIX(*res, i, 0) = RNG_UNIF(x1, x2); MATRIX(*res, i, 1) = RNG_UNIF(y1, y2); MATRIX(*res, i, 2) = RNG_UNIF(z1, z2); } RNG_END(); } else { igraph_layout_sphere(graph, res); } } if (no_nodes <= 1) { return 0; } IGRAPH_MATRIX_INIT_FINALLY(&dij, no_nodes, no_nodes); IGRAPH_MATRIX_INIT_FINALLY(&kij, no_nodes, no_nodes); IGRAPH_MATRIX_INIT_FINALLY(&lij, no_nodes, no_nodes); IGRAPH_CHECK(igraph_shortest_paths_dijkstra(graph, &dij, igraph_vss_all(), igraph_vss_all(), weights, IGRAPH_ALL)); max_dij = 0.0; for (i=0; i<no_nodes; i++) { for (j=i+1; j<no_nodes; j++) { if (!igraph_finite(MATRIX(dij, i, j))) { continue; } if (MATRIX(dij, i, j) > max_dij) { max_dij = MATRIX(dij, i, j); } } } for (i=0; i<no_nodes; i++) { for (j=0; j<no_nodes; j++) { if (MATRIX(dij, i, j) > max_dij) { MATRIX(dij, i, j) = max_dij; } } } L = L0 / max_dij; for (i=0; i<no_nodes; i++) { for (j=0; j<no_nodes; j++) { igraph_real_t tmp=MATRIX(dij, i, j) * MATRIX(dij, i, j); if (i==j) { continue; } MATRIX(kij, i, j) = kkconst / tmp; MATRIX(lij, i, j) = L * MATRIX(dij, i, j); } } /* Initialize delta */ IGRAPH_VECTOR_INIT_FINALLY(&D1, no_nodes); IGRAPH_VECTOR_INIT_FINALLY(&D2, no_nodes); IGRAPH_VECTOR_INIT_FINALLY(&D3, no_nodes); for (m=0; m<no_nodes; m++) { igraph_real_t myD1=0.0, myD2=0.0, myD3=0.0; for (i=0; i<no_nodes; i++) { if (i==m) { continue; } igraph_real_t dx=MATRIX(*res, m, 0) - MATRIX(*res, i, 0); igraph_real_t dy=MATRIX(*res, m, 1) - MATRIX(*res, i, 1); igraph_real_t dz=MATRIX(*res, m, 2) - MATRIX(*res, i, 2); igraph_real_t mi_dist=sqrt(dx * dx + dy * dy + dz * dz); myD1 += MATRIX(kij, m, i) * (dx - MATRIX(lij, m, i) * dx / mi_dist); myD2 += MATRIX(kij, m, i) * (dy - MATRIX(lij, m, i) * dy / mi_dist); myD3 += MATRIX(kij, m, i) * (dz - MATRIX(lij, m, i) * dz / mi_dist); } VECTOR(D1)[m] = myD1; VECTOR(D2)[m] = myD2; VECTOR(D3)[m] = myD3; } for (j=0; j<maxiter; j++) { igraph_real_t Ax=0.0, Ay=0.0, Az=0.0; igraph_real_t Axx=0.0, Axy=0.0, Axz=0.0, Ayy=0.0, Ayz=0.0, Azz=0.0; igraph_real_t max_delta, delta_x, delta_y, delta_z; igraph_real_t old_x, old_y, old_z, new_x, new_y, new_z; igraph_real_t detnum; /* Select maximal delta */ m=0; max_delta=-1; for (i=0; i<no_nodes; i++) { igraph_real_t delta=(VECTOR(D1)[i] * VECTOR(D1)[i] + VECTOR(D2)[i] * VECTOR(D2)[i] + VECTOR(D3)[i] * VECTOR(D3)[i]); if (delta > max_delta) { m=i; max_delta=delta; } } if (max_delta < epsilon) { break; } old_x=MATRIX(*res, m, 0); old_y=MATRIX(*res, m, 1); old_z=MATRIX(*res, m, 2); /* Calculate D1, D2 and D3, and other coefficients */ for (i=0; i<no_nodes; i++) { if (i==m) { continue; } igraph_real_t dx=old_x - MATRIX(*res, i, 0); igraph_real_t dy=old_y - MATRIX(*res, i, 1); igraph_real_t dz=old_z - MATRIX(*res, i, 2); igraph_real_t dist=sqrt(dx * dx + dy * dy + dz *dz); igraph_real_t den=dist * (dx * dx + dy * dy + dz * dz); igraph_real_t k_mi=MATRIX(kij, m, i); igraph_real_t l_mi=MATRIX(lij, m, i); Axx += k_mi * (1 - l_mi * (dy*dy + dz*dz) / den); Ayy += k_mi * (1 - l_mi * (dx*dx + dz*dz) / den); Azz += k_mi * (1 - l_mi * (dx*dx + dy*dy) / den); Axy += k_mi * l_mi * dx * dy / den; Axz += k_mi * l_mi * dx * dz / den; Ayz += k_mi * l_mi * dy * dz / den; } Ax = -VECTOR(D1)[m]; Ay = -VECTOR(D2)[m]; Az = -VECTOR(D3)[m]; /* Need to solve some linear equations, we just use Cramer's rule */ #define DET(a,b,c,d,e,f,g,h,i) ((a*e*i+b*f*g+c*d*h)-(c*e*g+b*d*i+a*f*h)) detnum = DET(Axx,Axy,Axz, Axy,Ayy,Ayz, Axz,Ayz,Azz); delta_x = DET(Ax ,Ay ,Az , Axy,Ayy,Ayz, Axz,Ayz,Azz) / detnum; delta_y = DET(Axx,Axy,Axz, Ax ,Ay ,Az , Axz,Ayz,Azz) / detnum; delta_z = DET(Axx,Axy,Axz, Axy,Ayy,Ayz, Ax ,Ay ,Az ) / detnum; new_x = old_x + delta_x; new_y = old_y + delta_y; new_z = old_z + delta_z; /* Limits, if given */ if (minx && new_x < VECTOR(*minx)[m]) { new_x = VECTOR(*minx)[m]; } if (maxx && new_x > VECTOR(*maxx)[m]) { new_x = VECTOR(*maxx)[m]; } if (miny && new_y < VECTOR(*miny)[m]) { new_y = VECTOR(*miny)[m]; } if (maxy && new_y > VECTOR(*maxy)[m]) { new_y = VECTOR(*maxy)[m]; } if (minz && new_z < VECTOR(*minz)[m]) { new_z = VECTOR(*minz)[m]; } if (maxz && new_z > VECTOR(*maxz)[m]) { new_z = VECTOR(*maxz)[m]; } /* Update delta, only with/for the affected node */ VECTOR(D1)[m] = VECTOR(D2)[m] = VECTOR(D3)[m] = 0.0; for (i=0; i<no_nodes; i++) { if (i==m) { continue; } igraph_real_t old_dx=old_x - MATRIX(*res, i, 0); igraph_real_t old_dy=old_y - MATRIX(*res, i, 1); igraph_real_t old_dz=old_z - MATRIX(*res, i, 2); igraph_real_t old_mi_dist=sqrt(old_dx * old_dx + old_dy * old_dy + old_dz * old_dz); igraph_real_t new_dx=new_x - MATRIX(*res, i, 0); igraph_real_t new_dy=new_y - MATRIX(*res, i, 1); igraph_real_t new_dz=new_z - MATRIX(*res, i, 2); igraph_real_t new_mi_dist=sqrt(new_dx * new_dx + new_dy * new_dy + new_dz * new_dz); VECTOR(D1)[i] -= MATRIX(kij, m, i) * (-old_dx + MATRIX(lij, m, i) * old_dx / old_mi_dist); VECTOR(D2)[i] -= MATRIX(kij, m, i) * (-old_dy + MATRIX(lij, m, i) * old_dy / old_mi_dist); VECTOR(D3)[i] -= MATRIX(kij, m, i) * (-old_dz + MATRIX(lij, m, i) * old_dz / old_mi_dist); VECTOR(D1)[i] += MATRIX(kij, m, i) * (-new_dx + MATRIX(lij, m, i) * new_dx / new_mi_dist); VECTOR(D2)[i] += MATRIX(kij, m, i) * (-new_dy + MATRIX(lij, m, i) * new_dy / new_mi_dist); VECTOR(D3)[i] += MATRIX(kij, m, i) * (-new_dz + MATRIX(lij, m, i) * new_dz / new_mi_dist); VECTOR(D1)[m] += MATRIX(kij, m, i) * (new_dx - MATRIX(lij, m, i) * new_dx / new_mi_dist); VECTOR(D2)[m] += MATRIX(kij, m, i) * (new_dy - MATRIX(lij, m, i) * new_dy / new_mi_dist); VECTOR(D3)[m] += MATRIX(kij, m, i) * (new_dz - MATRIX(lij, m, i) * new_dz / new_mi_dist); } /* Update coordinates*/ MATRIX(*res, m, 0) = new_x; MATRIX(*res, m, 1) = new_y; MATRIX(*res, m, 2) = new_z; } igraph_vector_destroy(&D3); igraph_vector_destroy(&D2); igraph_vector_destroy(&D1); igraph_matrix_destroy(&lij); igraph_matrix_destroy(&kij); igraph_matrix_destroy(&dij); IGRAPH_FINALLY_CLEAN(6); return 0; }
// Orthnormalization using the Gram-Schmidt algorithm void MATRIX(_gramschmidt)(T * _x, unsigned int _rx, unsigned int _cx, T * _v) { // validate input if (_rx == 0 || _cx == 0) { fprintf(stderr,"error: matrix_gramschmidt(), input matrix cannot have zero-length dimensions\n"); exit(1); } unsigned int i; unsigned int j; unsigned int k; // copy _x to _u memmove(_v, _x, _rx * _cx * sizeof(T)); unsigned int n = _rx; // dimensionality of each vector T proj_ij[n]; for (j=0; j<_cx; j++) { for (i=0; i<j; i++) { // v_j <- v_j - proj(v_i, v_j) #if DEBUG_MATRIX_GRAMSCHMIDT printf("computing proj(v_%u, v_%u)\n", i, j); #endif // compute proj(v_i, v_j) T vij = 0.; // dotprod(v_i, v_j) T vii = 0.; // dotprod(v_i, v_i) T ti; T tj; for (k=0; k<n; k++) { ti = matrix_access(_v, _rx, _cx, k, i); tj = matrix_access(_v, _rx, _cx, k, j); T prodij = ti * conj(tj); vij += prodij; T prodii = ti * conj(ti); vii += prodii; } // TODO : vii should be 1.0 from normalization step below T g = vij / vii; // complete projection for (k=0; k<n; k++) proj_ij[k] = matrix_access(_v, _rx, _cx, k, i) * g; // subtract projection from v_j for (k=0; k<n; k++) matrix_access(_v, _rx, _cx, k, j) -= proj_ij[k]; } // normalize v_j T vjj = 0.; // dotprod(v_j, v_j) T tj = 0.; for (k=0; k<n; k++) { tj = matrix_access(_v, _rx, _cx, k, j); T prodjj = tj * conj(tj); vjj += prodjj; } // TODO : check magnitude of vjj T g = 1. / sqrt( creal(vjj) ); for (k=0; k<n; k++) matrix_access(_v, _rx, _cx, k, j) *= g; #if DEBUG_MATRIX_GRAMSCHMIDT MATRIX(_print)(_v, _rx, _cx); #endif } }
void Matrix_transpose(Matrix * matrix) { *matrix = MATRIX(matrix->m[0], matrix->m[1], matrix->m[2], matrix->m[3], matrix->m[4], matrix->m[5], matrix->m[6], matrix->m[7], matrix->m[8], matrix->m[9], matrix->m[10], matrix->m[11], matrix->m[12], matrix->m[13], matrix->m[14], matrix->m[15]); }
/* zeroHMM - Sets all of the transition probabilities to 0.0. */ void zeroHMM(Hmm *m) { int u, v; for (u = 0; u<m->uu; u++) { VECTOR(m->logB)[u] = NEGATIVE_INFINITY; for (v = 0; v<m->uu; v++) { MATRIX(m->logA)[u][v] = NEGATIVE_INFINITY;}}}
void LayoutBuilder::produce(AbstractPetriNetBuilder *builder){ if(!attrTableAttached){ igraph_i_set_attribute_table(&igraph_cattribute_table); attrTableAttached = true; } size_t V = places.size() + transitions.size(); size_t E = inArcs.size() + outArcs.size(); igraph_t graph; // Create a directed graph igraph_empty(&graph, V, true); // Create vector with all edges igraph_vector_t edges; igraph_vector_init(&edges, E * 2); // Add edges to vector int i = 0; for(ArcIter it = inArcs.begin(); it != inArcs.end(); it++){ VECTOR(edges)[i++] = numberFromName(it->start); VECTOR(edges)[i++] = numberFromName(it->end); } for(ArcIter it = outArcs.begin(); it != outArcs.end(); it++){ VECTOR(edges)[i++] = numberFromName(it->start); VECTOR(edges)[i++] = numberFromName(it->end); } // Add the edges to graph igraph_add_edges(&graph, &edges, 0); // Delete the vector with edges igraph_vector_destroy(&edges); // Arrays to store result in double posx[V]; double posy[V]; // Provide current positions, if they're used at all if(startFromCurrentPositions){ int i = 0; for(PlaceIter it = places.begin(); it != places.end(); it++){ posx[i] = it->x; posy[i] = it->y; igraph_cattribute_VAN_set(&graph, "id", i, i); i++; } for(TransitionIter it = transitions.begin(); it != transitions.end(); it++){ posx[i] = it->x; posy[i] = it->y; igraph_cattribute_VAN_set(&graph, "id", i, i); i++; } } // Decompose the graph, and layout subgraphs induvidually igraph_vector_ptr_t subgraphs; igraph_vector_ptr_init(&subgraphs, 0); igraph_decompose(&graph, &subgraphs, IGRAPH_WEAK, -1, 0); // Offset for places subgraphs double offsetx = 0; double offsety = 0; // Layout, translate and extract results for each subgraph for(int i = 0; i < igraph_vector_ptr_size(&subgraphs); i++){ //Get the subgraph igraph_t* subgraph = (igraph_t*)VECTOR(subgraphs)[i]; // Allocate result matrix igraph_matrix_t sublayout; igraph_matrix_init(&sublayout, 0, 0); // Vertex selector and iterator igraph_vs_t vs; igraph_vit_t vit; // Select all and create iterator igraph_vs_all(&vs); igraph_vit_create(subgraph, vs, &vit); // Initialize sublayout, using original positions if(startFromCurrentPositions){ // Count vertices int vertices = 0; // Iterator over vertices to count them, hacked but it works while(!IGRAPH_VIT_END(vit)){ vertices++; IGRAPH_VIT_NEXT(vit); } //Reset vertex iterator IGRAPH_VIT_RESET(vit); // Resize sublayout igraph_matrix_resize(&sublayout, vertices, 2); // Iterator over vertices while(!IGRAPH_VIT_END(vit)){ int subindex = (int)IGRAPH_VIT_GET(vit); int index = (int)igraph_cattribute_VAN(subgraph, "id", subindex); MATRIX(sublayout, subindex, 0) = posx[index]; MATRIX(sublayout, subindex, 1) = posy[index]; IGRAPH_VIT_NEXT(vit); } //Reset vertex iterator IGRAPH_VIT_RESET(vit); } igraph_layout_kamada_kawai(subgraph, &sublayout, 1000, ((double)V)/4.0, 10, 0.99, V*V, startFromCurrentPositions); // Other layout algorithms with reasonable parameters //igraph_layout_kamada_kawai(subgraph, &sublayout, 1000, ((double)V)/4.0, 10, 0.99, V*V, startFromCurrentPositions); //igraph_layout_grid_fruchterman_reingold(subgraph, &sublayout, 500, V, V*V, 1.5, V*V*V, V*V/4, startFromCurrentPositions); //igraph_layout_fruchterman_reingold(subgraph, &sublayout, 500, V, V*V, 1.5, V*V*V, startFromCurrentPositions, NULL); //igraph_layout_lgl(subgraph, &sublayout, 150, V, V*V, 1.5, V*V*V, sqrt(V), -1); //Find min and max values: double minx = DBL_MAX, miny = DBL_MAX, maxx = -DBL_MAX, maxy = -DBL_MAX; //Iterator over all vertices while(!IGRAPH_VIT_END(vit)){ int subindex = (int)IGRAPH_VIT_GET(vit); double x = MATRIX(sublayout, subindex, 0) * factor; double y = MATRIX(sublayout, subindex, 1) * factor; minx = minx < x ? minx : x; miny = miny < y ? miny : y; maxx = maxx > x ? maxx : x; maxy = maxy > y ? maxy : y; IGRAPH_VIT_NEXT(vit); } //Reset vertex iterator IGRAPH_VIT_RESET(vit); // Compute translation double tx = margin - minx; double ty = margin - miny; // Decide whether to put it below or left of current content if(maxx - minx + offsetx < maxy - miny + offsety){ tx += offsetx; offsetx += maxx - minx + margin; if(offsety < maxy - miny + margin) offsety = maxy - miny + margin; }else{ ty += offsety; offsety += maxy - miny + margin; if(offsetx < maxx - minx + margin) offsetx = maxx - minx + margin; } // Translate and extract results while(!IGRAPH_VIT_END(vit)){ int subindex = (int)IGRAPH_VIT_GET(vit); int index = (int)igraph_cattribute_VAN(subgraph, "id", subindex); double x = MATRIX(sublayout, subindex, 0) * factor; double y = MATRIX(sublayout, subindex, 1) * factor; posx[index] = x + tx; posy[index] = y + ty; IGRAPH_VIT_NEXT(vit); } // Destroy iterator and selector igraph_vit_destroy(&vit); igraph_vs_destroy(&vs); // Destroy the sublayout igraph_matrix_destroy(&sublayout); // Destroy subgraph igraph_destroy(subgraph); free(VECTOR(subgraphs)[i]); } // Remove the attributes igraph_cattribute_remove_v(&graph, "id"); // Destroy the graph igraph_destroy(&graph); // Insert results i = 0; for(PlaceIter it = places.begin(); it != places.end(); it++){ it->x = posx[i]; it->y = posy[i]; i++; } for(TransitionIter it = transitions.begin(); it != transitions.end(); it++){ it->x = posx[i]; it->y = posy[i]; i++; } // Produce variables for(VarIter it = vars.begin(); it != vars.end(); it++) builder->addVariable(it->name, it->initialValue, it->range); for(BoolVarIter it = boolVars.begin(); it != boolVars.end(); it++) builder->addBoolVariable(it->name, it->initialValue); for(PlaceIter it = places.begin(); it != places.end(); it++) builder->addPlace(it->name, it->tokens, it->x, it->y); for(TransitionIter it = transitions.begin(); it != transitions.end(); it++) builder->addTransition(it->name, it->conditions, it->assignments, it->x, it->y); for(ArcIter it = inArcs.begin(); it != inArcs.end(); it++) builder->addInputArc(it->start, it->end, it->weight); for(ArcIter it = outArcs.begin(); it != outArcs.end(); it++) builder->addInputArc(it->start, it->end, it->weight); //Reset builder state (just in case some idoit decides to reuse it! vars.clear(); boolVars.clear(); places.clear(); transitions.clear(); inArcs.clear(); outArcs.clear(); }
int main() { float dist[8][8] = { {0.00, 4.69, 6.79, 3.50, 3.11, 4.46, 5.57, 3.00}, {4.69, 0.00, 2.10, 2.27, 2.65, 2.36, 1.99, 1.74}, {6.79, 2.10, 0.00, 3.78, 4.53, 2.83, 2.44, 3.79}, {3.50, 2.27, 3.78, 0.00, 1.98, 4.35, 2.07, 0.53}, {3.11, 2.65, 4.53, 1.98, 0.00, 3.80, 3.31, 1.47}, {4.46, 2.36, 2.83, 4.35, 3.80, 0.00, 4.35, 3.82}, {5.57, 1.99, 2.44, 2.07, 3.31, 4.35, 0.00, 2.57}, {3.00, 1.74, 3.79, 0.53, 1.47, 3.82, 2.57, 0.00}, }; igraph_t g; igraph_matrix_t coords, dist_mat; igraph_real_t vc; igraph_arpack_options_t options; int i, j; srand(time(0)); igraph_arpack_options_init(&options); igraph_tree(&g, 10, 2, IGRAPH_TREE_UNDIRECTED); igraph_matrix_init(&coords, 0, 0); igraph_layout_mds(&g, &coords, 0, 2, &options); if (MATRIX(coords, 0, 0) > 0) { for (i = 0; i < igraph_matrix_nrow(&coords); i++) MATRIX(coords, i, 0) *= -1; } if (MATRIX(coords, 0, 1) < 0) { for (i = 0; i < igraph_matrix_nrow(&coords); i++) MATRIX(coords, i, 1) *= -1; } igraph_matrix_print(&coords); igraph_matrix_destroy(&coords); igraph_destroy(&g); igraph_full(&g, 8, IGRAPH_UNDIRECTED, 0); igraph_matrix_init(&coords, 8, 2); igraph_matrix_init(&dist_mat, 8, 8); for (i = 0; i < 8; i++) for (j = 0; j < 2; j++) MATRIX(coords, i, j) = rand() % 1000; for (i = 0; i < 8; i++) for (j = i+1; j < 8; j++) { double dist_sq = 0.0; dist_sq += sqr(MATRIX(coords, i, 0)-MATRIX(coords, j, 0)); dist_sq += sqr(MATRIX(coords, i, 1)-MATRIX(coords, j, 1)); MATRIX(dist_mat, i, j) = sqrt(dist_sq); MATRIX(dist_mat, j, i) = sqrt(dist_sq); } igraph_layout_mds(&g, &coords, &dist_mat, 2, &options); for (i = 0; i < 8; i++) for (j = i+1; j < 8; j++) { double dist_sq = 0.0; dist_sq += sqr(MATRIX(coords, i, 0)-MATRIX(coords, j, 0)); dist_sq += sqr(MATRIX(coords, i, 1)-MATRIX(coords, j, 1)); if (fabs(sqrt(dist_sq) - MATRIX(dist_mat, i, j)) > 1e-2) { printf("dist(%d,%d) should be %.4f, but it is %.4f\n", i, j, MATRIX(dist_mat, i, j), sqrt(dist_sq)); return 1; } } igraph_matrix_destroy(&dist_mat); igraph_matrix_destroy(&coords); igraph_destroy(&g); return 0; }
static double mdet(double *ap, int dimen, int rowa) /* double *ap; input matrix */ /* int dimen; Dimension of linre and row, those must be equal, that is square matrix. */ /* int rowa; ROW Dimension of matrix A */ { double det = 1.0; double work; int is = 0; int mmax; int i, j, k; for(k = 0; k < dimen - 1; k++) { mmax = k; for(i = k + 1; i < dimen; i++) if (fabs(MATRIX(ap, i, k, rowa)) > fabs(MATRIX(ap, mmax, k, rowa))) mmax = i; if(mmax != k) { for (j = k; j < dimen; j++) { work = MATRIX(ap, k, j, rowa); MATRIX(ap, k, j, rowa) = MATRIX(ap, mmax, j, rowa); MATRIX(ap, mmax, j, rowa) = work; } is++; } for(i = k + 1; i < dimen; i++) { work = MATRIX(ap, i, k, rowa) / MATRIX(ap, k, k, rowa); for (j = k + 1; j < dimen; j++) MATRIX(ap, i, j, rowa) -= work * MATRIX(ap, k, j, rowa); } } for(i = 0; i < dimen; i++) det *= MATRIX(ap, i, i, rowa); for(i = 0; i < is; i++) det *= -1.0; return(det); }
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; }
int igraph_pagerank(const igraph_t *graph, igraph_vector_t *vector, igraph_real_t *value, const igraph_vs_t vids, igraph_bool_t directed, igraph_real_t damping, const igraph_vector_t *weights, igraph_arpack_options_t *options) { igraph_matrix_t values; igraph_matrix_t vectors; igraph_integer_t dirmode; igraph_vector_t outdegree; igraph_vector_t tmp; long int i; long int no_of_nodes=igraph_vcount(graph); long int no_of_edges=igraph_ecount(graph); 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 */ directed = directed && igraph_is_directed(graph); if (weights && igraph_vector_size(weights) != igraph_ecount(graph)) { IGRAPH_ERROR("Invalid length of weights vector when calculating " "PageRank scores", IGRAPH_EINVAL); } IGRAPH_MATRIX_INIT_FINALLY(&values, 0, 0); IGRAPH_MATRIX_INIT_FINALLY(&vectors, options->n, 1); if (directed) { dirmode=IGRAPH_IN; } else { dirmode=IGRAPH_ALL; } IGRAPH_VECTOR_INIT_FINALLY(&outdegree, options->n); IGRAPH_VECTOR_INIT_FINALLY(&tmp, options->n); RNG_BEGIN(); if (!weights) { igraph_adjlist_t adjlist; igraph_i_pagerank_data_t data = { graph, &adjlist, damping, &outdegree, &tmp }; IGRAPH_CHECK(igraph_degree(graph, &outdegree, igraph_vss_all(), directed ? IGRAPH_OUT : IGRAPH_ALL, /*loops=*/ 0)); /* Avoid division by zero */ for (i=0; i<options->n; i++) { if (VECTOR(outdegree)[i]==0) { VECTOR(outdegree)[i]=1; } MATRIX(vectors, i, 0) = VECTOR(outdegree)[i]; } IGRAPH_CHECK(igraph_adjlist_init(graph, &adjlist, dirmode)); IGRAPH_FINALLY(igraph_adjlist_destroy, &adjlist); IGRAPH_CHECK(igraph_arpack_rnsolve(igraph_i_pagerank, &data, options, 0, &values, &vectors)); igraph_adjlist_destroy(&adjlist); IGRAPH_FINALLY_CLEAN(1); } else { igraph_adjedgelist_t adjedgelist; igraph_i_pagerank_data2_t data = { graph, &adjedgelist, weights, damping, &outdegree, &tmp }; IGRAPH_CHECK(igraph_adjedgelist_init(graph, &adjedgelist, dirmode)); IGRAPH_FINALLY(igraph_adjedgelist_destroy, &adjedgelist); /* Weighted degree */ for (i=0; i<no_of_edges; i++) { long int from=IGRAPH_FROM(graph, i); long int to=IGRAPH_TO(graph, i); igraph_real_t weight=VECTOR(*weights)[i]; VECTOR(outdegree)[from] += weight; if (!directed) { VECTOR(outdegree)[to] += weight; } } /* Avoid division by zero */ for (i=0; i<options->n; i++) { if (VECTOR(outdegree)[i]==0) { VECTOR(outdegree)[i]=1; } MATRIX(vectors, i, 0) = VECTOR(outdegree)[i]; } IGRAPH_CHECK(igraph_arpack_rnsolve(igraph_i_pagerank2, &data, options, 0, &values, &vectors)); igraph_adjedgelist_destroy(&adjedgelist); IGRAPH_FINALLY_CLEAN(1); } RNG_END(); igraph_vector_destroy(&tmp); igraph_vector_destroy(&outdegree); IGRAPH_FINALLY_CLEAN(2); if (value) { *value=MATRIX(values, 0, 0); } if (vector) { long int i; igraph_vit_t vit; long int nodes_to_calc; igraph_real_t sum=0; for (i=0; i<no_of_nodes; i++) { sum += MATRIX(vectors, i, 0); } IGRAPH_CHECK(igraph_vit_create(graph, vids, &vit)); IGRAPH_FINALLY(igraph_vit_destroy, &vit); nodes_to_calc=IGRAPH_VIT_SIZE(vit); IGRAPH_CHECK(igraph_vector_resize(vector, nodes_to_calc)); for (IGRAPH_VIT_RESET(vit), i=0; !IGRAPH_VIT_END(vit); IGRAPH_VIT_NEXT(vit), i++) { VECTOR(*vector)[i] = MATRIX(vectors, (long int)IGRAPH_VIT_GET(vit), 0); VECTOR(*vector)[i] /= sum; } igraph_vit_destroy(&vit); IGRAPH_FINALLY_CLEAN(1); } if (options->info) { IGRAPH_WARNING("Non-zero return code from ARPACK routine!"); } igraph_matrix_destroy(&vectors); igraph_matrix_destroy(&values); IGRAPH_FINALLY_CLEAN(2); return 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(°ree, options->n); IGRAPH_CHECK(igraph_degree(graph, °ree, 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(°ree); 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; }
/* HMM_updateModel - * Given an HMM and a vector of log likelihoods for states in the sequences, * calculates the responsibilities of each state in the HMM for each symbol * in the sequences, and maximises the model parameters based on the * assigned log likelihoods. */ Real HMM_updateModel(Hmm *m, Hmm *new_m, RVec *logL, RVec *gamma, Real log_D, Real postpC, int c, int c_ls, enum training_mode training_mode) { int t, u, v, tt = VLENGTH(logL[0]); Real **a = MATRIX(m->logA), *b = VECTOR(m->logB), **al, **be, ***ps; Real logD = 0, like, dtf; int Sc = (c==c_ls); switch (training_mode) { case HMM_ML: assert(postpC==0.0); logD = NEGATIVE_INFINITY; break; case HMM_DT: assert(c>=0&&c_ls>=0); logD = log_D; break; default: panic("unrecognized training mode"); } assert(VLENGTH(logL[0])==VLENGTH(gamma[0])); HMM_initGlobals(m->uu, tt); al = MATRIX(g_alpha); be = MATRIX(g_beta); ps = MATRIX(g_psi); /* calculate alpha's */ HMM_calcAlphas(m, logL); /* calculate beta's - * beta[u][tt] = 1 * beta[u][t] = sum(v = 1 ... m->uu, a[u][v]*beta[v][t+1]*logL[v][t+1]) */ for (u = 0; u<m->uu; u++) be[u][tt-1] = 0.0; for (t = tt-2; t>=0; t--) { for (u = 0; u<m->uu; u++) { be[u][t] = NEGATIVE_INFINITY; for (v = 0; v<m->uu; v++) { be[u][t] = add_exp(be[u][t], a[u][v]+be[v][t+1]+VECTOR(logL[v])[t+1]);}}} /* calculate logL of sequence - * P(sequence|m) = sum(u = 1 ... m->uu, alpha[u][tt]) */ like = NEGATIVE_INFINITY; for (u = 0; u<m->uu; u++) like = add_exp(like, al[u][tt-1]); /* A sample that can NEVER belong to this category */ if(like == NEGATIVE_INFINITY){ assert(postpC == 0.0); assert(Sc==0); } /* calculate responsibilities * alpha[u][t]*beta[u][t] * gamma[u][t] = ---------------------- * P(data|model) */ for (t = 0; t<tt; t++){ for (u = 0; u<m->uu; u++){ if(like!=NEGATIVE_INFINITY) VECTOR(gamma[u])[t] = al[u][t]+be[u][t]-like; else VECTOR(gamma[u])[t] = NEGATIVE_INFINITY; } } /* calculate time-indexed transition probabilities * alpha[u][t]*a[u][v]*logL[v][t+1]*beta[v][t+1] * psi[u][v][t] = --------------------------------------------- * P(data|model) */ for (u = 0; u<m->uu; u++){ for (v = 0; v<m->uu; v++){ for (t = 0; t<tt-1; t++){ if(like!=NEGATIVE_INFINITY) ps[u][v][t] = al[u][t]+a[u][v]+VECTOR(logL[v])[t+1]+be[v][t+1]-like; else ps[u][v][t] = NEGATIVE_INFINITY; } } } /* Update new model. The model may have been partly updated by some training samples. */ a = MATRIX(new_m->logA); b = VECTOR(new_m->logB); /* calculate B b[u] = gamma[u][1] - added scaling by sum of gammas to catch any numerical accuracy problems not log space here */ for (u = 0; u<m->uu; u++) { /* This may be negative */ b[u] += (Sc-postpC)*my_exp(VECTOR(gamma[u])[0]) +my_exp(logD+VECTOR(m->logB)[u]); } /* calculate A matrix * sum(t = 1 ... tt-1, psi[u][v][t]) * a[u][v] = ------------------------------------------------------- * sum(t = 1 ... tt-1, sum(w = 1 ... m->uu, psi[u][w][t])) * see note above about log space */ for (u = 0; u<m->uu; u++) { for (v = 0; v<m->uu; v++) { /* This may be negative */ dtf = 0.0; for(t = 0; t<tt-1; t++) dtf += my_exp(ps[u][v][t])*(Sc-postpC) + my_exp(logD+MATRIX(m->logA)[u][v]); a[u][v] += dtf; } } for (t = 0; t<tt; t++) { for (u = 0; u<m->uu; u++) VECTOR(gamma[u])[t] = my_exp(VECTOR(gamma[u])[t]); } return like; }
/* zeroHMMlinear - Sets all of the transition probabilities to 0.0 in the orginal space. This function is needed in dt training because during update a negative value may occur. */ void zeroHMMlinear(Hmm *m) { int u, v; for (u = 0; u<m->uu; u++) { VECTOR(m->logB)[u] = 0.0; for (v = 0; v<m->uu; v++) { MATRIX(m->logA)[u][v] = 0.0;}}}
float LevenshteinDistance(const Py_UNICODE * s1, int len1, const Py_UNICODE * s2, int len2) { /* Step 1 */ /* Check string lengths */ if (len1 == 0) return 0.0f; if (len2 == 0) return 0.0f; /* Step 2 */ /* Allocate matrix for algorithm and fill it with default values */ int *matrix = new int[(len1 + 1) * (len2 + 1)]; for (int index1 = 0; index1 <= len1; index1++) MATRIX(index1, 0) = index1; for (int index2 = 0; index2 <= len2; index2++) MATRIX(0, index2) = index2; /* Step 3 */ /* Loop through first string */ for (int index1 = 1; index1 <= len1; index1++) { Py_UNICODE s1_current = s1[index1 - 1]; /* Step 4 */ /* Loop through second string */ for (int index2 = 1; index2 <= len2; index2++) { Py_UNICODE s2_current = s2[index2 - 1]; /* Step 5 */ /* Calculate cost of this iteration (handles deletion, insertion, and substitution) */ int cost = (s1_current == s2_current) ? 0 : 1; /* Step 6 */ /* Calculate the total cost up to this point */ int above = MATRIX(index1 - 1, index2); int left = MATRIX(index1, index2 - 1); int diagonal = MATRIX(index1 - 1, index2 - 1); int cell = min(min(above + 1, left + 1), diagonal + cost); /* Step 6a */ /* Also cover transposition. This step is taken from: Berghel, Hal ; Roach, David : "An Extension of Ukkonen's Enhanced Dynamic Programming ASM Algorithm" (http://berghel.net/publications/asm/asm.php) */ if (index1 > 2 && index2 > 2) { int trans = MATRIX(index1 - 2, index2 - 2) + 1; if (s1[index1 - 2] != s2_current) trans++; if (s1_current != s2[index2 - 2]) trans++; if (cell > trans) cell = trans; } MATRIX(index1, index2) = cell; } } /* Step 7 */ /* Return result */ float result = ((float)1 - ((float)MATRIX(len1, len2) / (float)max(len1, len2))); delete [] matrix; return result; }
void schur(Matrix M, Matrix V, Matrix W, int nb) { Matrix M00, M01, M10, M11; Matrix V00, V01, V10, V11; Matrix W00, W01, W10, W11; int hnb; /* Check base case. */ if (nb == 1) { block_schur(*M, *V, *W); return; } /* Break matrices into 4 pieces. */ hnb = nb / 2; M00 = &MATRIX(M, 0, 0); M01 = &MATRIX(M, 0, hnb); M10 = &MATRIX(M, hnb, 0); M11 = &MATRIX(M, hnb, hnb); V00 = &MATRIX(V, 0, 0); V01 = &MATRIX(V, 0, hnb); V10 = &MATRIX(V, hnb, 0); V11 = &MATRIX(V, hnb, hnb); W00 = &MATRIX(W, 0, 0); W01 = &MATRIX(W, 0, hnb); W10 = &MATRIX(W, hnb, 0); W11 = &MATRIX(W, hnb, hnb); /* Form Schur complement with recursive calls. */ cilk_spawn schur(M00, V00, W00, hnb); cilk_spawn schur(M01, V00, W01, hnb); cilk_spawn schur(M10, V10, W00, hnb); cilk_spawn schur(M11, V10, W01, hnb); cilk_sync; cilk_spawn schur(M00, V01, W10, hnb); cilk_spawn schur(M01, V01, W11, hnb); cilk_spawn schur(M10, V11, W10, hnb); cilk_spawn schur(M11, V11, W11, hnb); cilk_sync; return; }
void multi_burg(int *pn, double *x, int *pomax, int *pnser, double *coef, double *pacf, double *var, double *aic, int *porder, int *useaic, int *vmethod) { int i, j, m, omax = *pomax, n = *pn, nser=*pnser, order=*porder; int dim1[3]; double aicmin; Array xarr, resid_f, resid_b, resid_f_tmp; Array *A, *B, P, V; dim1[0] = omax+1; dim1[1] = dim1[2] = nser; A = (Array *) R_alloc(omax+1, sizeof(Array)); B = (Array *) R_alloc(omax+1, sizeof(Array)); for (i = 0; i <= omax; i++) { A[i] = make_zero_array(dim1, 3); B[i] = make_zero_array(dim1, 3); } P = make_array(pacf, dim1, 3); V = make_array(var, dim1, 3); xarr = make_matrix(x, nser, n); resid_f = make_zero_matrix(nser, n); resid_b = make_zero_matrix(nser, n); set_array_to_zero(resid_b); copy_array(xarr, resid_f); copy_array(xarr, resid_b); resid_f_tmp = make_zero_matrix(nser, n); burg0(omax, resid_f, resid_b, A, B, P, V, *vmethod); /* Model order selection */ for (i = 0; i <= omax; i++) { aic[i] = n * ldet(subarray(V,i)) + 2 * i * nser * nser; } if (*useaic) { order = 0; aicmin = aic[0]; for (i = 1; i <= omax; i++) { if (aic[i] < aicmin) { aicmin = aic[i]; order = i; } } } else order = omax; *porder = order; for(i = 0; i < vector_length(A[order]); i++) coef[i] = VECTOR(A[order])[i]; if (*useaic) { /* Recalculate residuals for chosen model */ set_array_to_zero(resid_f); set_array_to_zero(resid_f_tmp); for (m = 0; m <= order; m++) { for (i = 0; i < NROW(resid_f_tmp); i++) { for (j = 0; j < NCOL(resid_f_tmp) - order; j++) { MATRIX(resid_f_tmp)[i][j + order] = MATRIX(xarr)[i][j + order - m]; } } matrix_prod(subarray(A[order],m), resid_f_tmp, 0, 0, resid_f_tmp); array_op(resid_f_tmp, resid_f, '+', resid_f); } } copy_array(resid_f, xarr); }
/* normaliseHMMlinear - Normalises an HMM in the original space so that transition probabilites sum to 1. After this, convert all the values from the original space to log space. */ int normaliseHMMlinear(Hmm *m, int upper_triangular, enum training_mode train_mode, int *xu) { int u, v, w; Real sum, corrected_sum; int flag; sum = 0.0; for (u = 0; u < m->uu; u++) sum += VECTOR(m->logB)[u]; assert(fabs(sum)>0.0); flag = 0; corrected_sum = NEGATIVE_INFINITY; for (u = 0; u<m->uu; u++) { if(VECTOR(m->logB)[u]/sum < -1e-50){ printf("normaliseHMMlinear: b error\n"); return FALSE; } VECTOR(m->logB)[u] = my_log(VECTOR(m->logB)[u]/sum); /* Clip the value to zero if it is smaller than CORRECTION_EPS */ if(train_mode == HMM_DT && VECTOR(m->logB)[u] != NEGATIVE_INFINITY && VECTOR(m->logB)[u] < my_log(CORRECTION_EPS)){ printf("normaliseHMMlinear: clip zero\n"); VECTOR(m->logB)[u] = NEGATIVE_INFINITY; flag = 1; } corrected_sum = add_exp(corrected_sum, VECTOR(m->logB)[u]); } assert(corrected_sum != NEGATIVE_INFINITY); if(flag){ for(u = 0; u < m->uu; u ++) VECTOR(m->logB)[u] -= corrected_sum; } for (u = 0; u<m->uu; u++) { sum = 0.0; w = (upper_triangular?u:0); for (v = w; v<m->uu; v++) sum += MATRIX(m->logA)[u][v]; if (sum==0.0) { /* A state never jumps to another state (include itself) This is not the unreachable state. It may be a final state or a useless state. An unreachable state is finally to be a useless state. We can just keep all the outward transition probabilities zero. */ // Do NOTHING. We don't want a corrected uniform distribution. for(v = 0; v < m->uu; v ++) MATRIX(m->logA)[u][v] = NEGATIVE_INFINITY; continue; } flag = 0; corrected_sum = NEGATIVE_INFINITY; for (v = 0; v<m->uu; v ++) { if(MATRIX(m->logA)[u][v]/sum < -1e-50){ printf("normaliseHMMlinear: a error\n"); return FALSE; } MATRIX(m->logA)[u][v] = my_log(MATRIX(m->logA)[u][v]/sum); /* Clip the value to zero if it is smaller than CORRECTION_EPS */ if(train_mode == HMM_DT && MATRIX(m->logA)[u][v] != NEGATIVE_INFINITY && MATRIX(m->logA)[u][v] < my_log(CORRECTION_EPS)){ printf("normaliseHMMlinear: clip zero\n"); MATRIX(m->logA)[u][v] = NEGATIVE_INFINITY; flag = 1; } corrected_sum = add_exp(corrected_sum, MATRIX(m->logA)[u][v]); } assert(corrected_sum != NEGATIVE_INFINITY); if(flag){ for(v = 0; v < m->uu; v ++) MATRIX(m->logA)[u][v] -= corrected_sum; } } /* Check whether any column in logA has entries that are all NEGATIVE_INFINITY, which is an unreachable state. */ if (xu != NULL){ memset(xu, 0, sizeof(int) * m->uu); for(u = 0; u < m->uu; u ++){ flag = 0; /* 1. The entry of initial probability is 0 */ if(VECTOR(m->logB)[u] == NEGATIVE_INFINITY) flag ++; /* 2. No other state (include itself) can reach this state */ for(v = 0; v < m->uu; v ++) if(MATRIX(m->logA)[v][u] != NEGATIVE_INFINITY) break; if(v == m->uu) flag ++; if(flag == 2){ printf("AN UNREACHABLE STATE IS REMOVED! State_#: %d Total state_#: %d\n", u, m->uu); xu[u] = 1; } } } return TRUE; }