From df8386f75b0538075d72d52693836bb8878f505b Mon Sep 17 00:00:00 2001 From: KatolaZ Date: Mon, 19 Oct 2015 16:23:00 +0100 Subject: First commit of MAMMULT code --- models/growth/nibilab_nonlinear.c | 493 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 493 insertions(+) create mode 100644 models/growth/nibilab_nonlinear.c (limited to 'models/growth/nibilab_nonlinear.c') diff --git a/models/growth/nibilab_nonlinear.c b/models/growth/nibilab_nonlinear.c new file mode 100644 index 0000000..3ad9ce8 --- /dev/null +++ b/models/growth/nibilab_nonlinear.c @@ -0,0 +1,493 @@ +/** + * + * NiBiLaB model (Nicosia, Bianconi, Latora, Barthelemy) of multiplex + * non-linear preferential attachment. + * + * The probability for a newly arrived node $i$ to create a link to an + * existing node $j$ is + * + * p_{i->j} \propto k\lay{1}^{\alpha}/k\lay{2}^{\beta} + * + * where alpha and beta are two parameters. + * + * Nodes arrive at the same time on both layers. + * + */ + +#include +#include +#include +#include +#include + + +typedef struct{ + int size; + int N; + int *val; +} int_array_t; + + +typedef struct{ + int K; + int N; + int size; + int *i; + int *j; + int *degrees; + int *arrived; + double *cumul; + int_array_t *times; + double *eta; +} ij_net_t; + + + +typedef struct{ + double a; + double b; + double c; + double d; +} coupling_t; + + +typedef struct{ + int N; + double x_min; + double *distr; + double gamma; +} distr_t; + + +int init_network(ij_net_t *G, int m0){ + + int n; + + for(n=0; ni[n] = n; + G->j[n] = n+1 % m0; + G->degrees[n] = 2; + G->arrived[n] = n; + } + G->K = m0; + G->N = m0; + return n; +} + + + +void dump_network(ij_net_t *G){ + + int i; + for(i=0; i< G->K; i ++){ + printf("%d %d\n",G->i[i], G->j[i]); + } +} + + +void dump_network_to_file(ij_net_t *G, char *fname){ + + + FILE *f; + int i; + + + f = fopen(fname, "w+"); + + for(i=0; i< G->K; i ++){ + fprintf(f, "%d %d\n",G->i[i], G->j[i]); + } + fclose(f); +} + + + +double f1(double v1, double v2, coupling_t *matr){ + return v1 * matr->a + v2 * matr->b; +} + +double f2(double v1, double v2, coupling_t *matr){ + return v1 * matr->c + v2 * matr->d; +} + + +void compute_cumul_nlin(ij_net_t *G1, ij_net_t *G2, double alpha){ + + int i; + double val; + + /* The bias at layer 1 is k1/k2^2 */ + if (G1->degrees[G1->arrived[0]] > 0 && G2->degrees[ G1->arrived[0] ]) + G1->cumul[0] = (G1->degrees[G1->arrived[0]]) * 1.0 / pow(G2->degrees[ G1->arrived[0] ],alpha) ; + else + G1->cumul[0] = 0.0; + + if (G2->degrees[G2->arrived[0]] > 0 && G1->degrees[ G2->arrived[0] ] > 0) + G2->cumul[0] = ( G2->degrees[G2->arrived[0]]) * 1.0/ pow(G1->degrees[ G2->arrived[0] ],alpha); + else + G2->cumul[0] = 0.0; + + for(i=1; iN; i ++){ + if (G1->degrees[G1->arrived[i]] > 0 && G2->degrees[ G1->arrived[i] ] > 0) + val = (G1->degrees[G1->arrived[i]]) * 1.0 / pow(G2->degrees[ G1->arrived[i] ],alpha) ; + else + val = 0; + G1->cumul[i] = G1->cumul[i-1] + val; + } + for(i=1; iN; i ++){ + if (G2->degrees[G2->arrived[i]] > 0 && G1->degrees[ G2->arrived[i] ] ) + val = (G2->degrees[G2->arrived[i]]) * 1.0/ pow(G1->degrees[ G2->arrived[i] ], alpha); + else + val = 0.0; + G2->cumul[i] = G2->cumul[i-1] + val; + } +} + + +void compute_cumul_nlin_2(ij_net_t *G1, ij_net_t *G2, double alpha, double beta){ + + int i; + double val; + + /* The bias at layer 1 is k1/k2^2 */ + if (G1->degrees[G1->arrived[0]] > 0 && G2->degrees[ G1->arrived[0] ]) + G1->cumul[0] = pow(G1->degrees[G1->arrived[0]], alpha) / pow(G2->degrees[ G1->arrived[0] ],beta) ; + else + G1->cumul[0] = 0.0; + + if (G2->degrees[G2->arrived[0]] > 0 && G1->degrees[ G2->arrived[0] ] > 0) + G2->cumul[0] = pow(G2->degrees[G2->arrived[0]], alpha)/pow(G1->degrees[ G2->arrived[0] ], beta); + else + G2->cumul[0] = 0.0; + + for(i=1; iN; i ++){ + if (G1->degrees[G1->arrived[i]] > 0 && G2->degrees[ G1->arrived[i] ] > 0) + val = pow(G1->degrees[G1->arrived[i]], alpha)/pow(G2->degrees[ G1->arrived[i] ],beta) ; + else + val = 0; + G1->cumul[i] = G1->cumul[i-1] + val; + } + for(i=1; iN; i ++){ + if (G2->degrees[G2->arrived[i]] > 0 && G1->degrees[ G2->arrived[i] ] ) + val = pow(G2->degrees[G2->arrived[i]],alpha)/pow(G1->degrees[ G2->arrived[i] ], beta); + else + val = 0.0; + G2->cumul[i] = G2->cumul[i-1] + val; + } +} + + +void dump_cumul(ij_net_t *G){ + + int i; + + for (i=0; iN; i ++){ + printf("%d %2.6f\n", G->times[i], G->cumul[i]); + } + +} + + + +int select_neigh_cumul(ij_net_t *G){ + + double r; + int j; + + r = (rand() * 1.0 / RAND_MAX) * G->cumul[ G->N-1 ]; + //printf(" r: %f ", r); + + j = 0; + /* Change with a binary search ???!?!?!?! */ + while (r > G->cumul[j]){ + j ++; + } + return G->arrived[j]; +} + +int already_neighbour(ij_net_t *G, int j, int d, int offset){ + + int i; + + for(i=G-> K + offset; i< G->K + offset + j; i ++){ + if (G->j[i] == d) + return 1; + } + return 0; +} + + +void sample_edges(ij_net_t *G, int n, int m, int offset){ + + int j; + int d; + + //printf("----"); + for(j=0; ji[G->K + offset + j] = n; + d = select_neigh_cumul(G); + while(already_neighbour(G, j, d, offset)){ + d = select_neigh_cumul(G); + } + //printf(" link %d--%d\n", n, d); + G->j[G->K + offset + j] = d; + G->degrees[d] += 1; + } + //printf("\n"); +} + +void create_distr(double *v, double gamma, int x_min, int x_max){ + int n, i; + double sum, new_sum; + + n = x_max-x_min + 1; + + sum = 0; + for(i=0; i v[i]) + i++; + return i; + +} + + +int sample_power_law(distr_t *d){ + + double xi, q, val; + int k; + + while(1){ + xi = rand()* 1.0 / RAND_MAX; + k = find_degree(d->distr, d->N, xi); + val = rand()*1.0/RAND_MAX; + q = d->x_min + xi * d->N; + q = q / (floor(q) + 1); + q = pow(q, d->gamma); + if (val <= q){ + return k; + } + } +} + + + + +int grow_multi_net_nlin_2(ij_net_t *G1, ij_net_t *G2, int N, int m, + int m0, double alpha, double beta){ + + int i, j; + int d; + int i2; + + + for(i=m0; iarrived[i] = i; + sample_edges(G1, G1->arrived[i], m, 0); + G1->degrees[G1->arrived[i]] += m; + + G2->arrived[i] = i; + sample_edges(G2, G2->arrived[i], m, 0); + G2->degrees[G2->arrived[i]] += m; + G1->N += 1; + G1->K += m; + G2->N += 1; + G2->K += m ; + } + return 0; +} + +void init_structure(ij_net_t *G, int N){ + + int i; + + G->i = malloc(G->size * sizeof(int)); + G->j = malloc(G->size * sizeof(int)); + G->degrees = malloc(N * sizeof(int)); + G->arrived = malloc(N * sizeof(int)); + G->cumul = malloc(N * sizeof(double)); + G->eta = malloc(N * sizeof(double)); + G->times = malloc(N * sizeof(int_array_t)); + for (i=0; itimes[i].size = 5; + G->times[i].N = 0; + G->times[i].val = malloc(5 * sizeof(int)); + } + memset(G->degrees, 0, N*sizeof(int)); + G->N = 0; + +} + +void add_node_to_time(ij_net_t *G, int node, int t){ + + if (G->times[t].size == G->times[t].N){ + G->times[t].size += 5; + G->times[t].val = realloc(G->times[t].val, G->times[t].size); + } + G->times[t].val[G->times[t].N] = node; + G->times[t].N += 1; +} + + +void init_times_delta(ij_net_t *G, int N){ + + int i; + + for (i=0; itimes[i].N; j++){ + printf(" %d", G->times[i].val[j]); + } + printf("\n"); + } + +} + + +void init_eta_random(ij_net_t *G, int N){ + + int i; + double val; + + for (i=0; ieta[i] = val; + } +} + +void init_eta_ass(ij_net_t *G2, ij_net_t *G1, int N){ + int i; + + for (i=0; ieta[i] = G1->eta[i]; + } + +} + +void init_eta_dis(ij_net_t *G2, ij_net_t *G1, int N){ + int i; + + for (i=0; ieta[i] = 1 - G1->eta[i]; + } + +} + + +int main(int argc, char *argv[]){ + + ij_net_t G1, G2; + + int N, m, m0, k_max; + coupling_t matr; + double alpha, beta; + distr_t delay_distr; + + char str[256]; + + if (argc < 6){ + printf("Usage: %s \n", argv[0]); + exit(1); + } + + srand(time(NULL)); + + /* Diagonal coupling */ + + N = atoi(argv[1]); + m = atoi(argv[2]); + m0 = atoi(argv[3]); + alpha=atof(argv[5]); + beta = atof(argv[6]); + + G1.size = (N+m0) * m; + G2.size = (N+m0) * m; + + init_structure(&G1, N); + init_structure(&G2, N); + + + G1.K = init_network(&G1, m0); + G2.K = init_network(&G2, m0); + + //init_eta_random(&G1, N); + //init_eta_random(&G2, N); + + + + //init_times_delta(&G1, N); + //init_times_delta(&G2, N); + + //dump_times(&G2, N); + + fprintf(stderr, "Init finished!\n"); + + grow_multi_net_nlin_2(&G1, &G2, N, m, m0, alpha, beta); + + //printf("### G1\n"); + sprintf(str, "%s_layer1.txt", argv[4]); + dump_network_to_file(&G1, str); + + //printf("### G2\n"); + sprintf(str, "%s_layer2.txt", argv[4]); + dump_network_to_file(&G2, str); + + /* dump_network_to_file(S, S_num, argv[4]); */ + /* printf("Network dumped!\n"); */ + /* k_max = degree_distr(S, S_num, &distr); */ + /* printf("k_max is: %d\n", k_max); */ + /* dump_distr_to_file(distr, k_max, argv[5]); */ + +} -- cgit v1.2.3