/** * This program is free software: you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see * . * * (c) Vincenzo Nicosia 2009-2017 -- * * This file is part of NetBunch, a package for complex network * analysis and modelling. For more information please visit: * * http://www.complex-networks.net/ * * If you use this software, please add a reference to * * V. Latora, V. Nicosia, G. Russo * "Complex Networks: Principles, Methods and Applications" * Cambridge University Press (2017) * ISBN: 9781107103184 * *********************************************************************** * * This file contains general utilities to handle input/output of * graphs, convert between different sparse matrix representations, * and other ancillary functions. It is linked against most of the * programs in NetBunch. * */ #include #include #include #include #include #include "utils.h" /* Read a degree distribution -- OBSOLETE */ int read_deg_distr(FILE *filein, unsigned int **degs, unsigned int **Nk, double **p){ int n_degs = 0; int size = 10; char buff[256]; int k_i, num_i; double p_i; char *ptr; *degs = realloc(*degs, size*sizeof(unsigned int)); *Nk = realloc(*Nk, size*sizeof(unsigned int)); *p = realloc(*p, size*sizeof(double)); while(fgets(buff, 256, filein)){ ptr = strtok(buff, " "); VALID_PTR_OR_EXIT(ptr, 7); if (ptr[0] == '#') continue; k_i = atoi(ptr); ptr = strtok(NULL, " " ); VALID_PTR_OR_EXIT(ptr, 7); num_i = atoi(ptr); ptr = strtok(NULL, " \n"); VALID_PTR_OR_EXIT(ptr, 7); p_i = atof(ptr); if (n_degs == size){ size += 10; *degs = realloc(*degs, size*sizeof(unsigned int)); *Nk = realloc(*Nk, size*sizeof(unsigned int)); *p = realloc(*p, size*sizeof(double)); } (*degs)[n_degs] = k_i; (*Nk)[n_degs] = num_i; (*p)[n_degs] = p_i; n_degs += 1; } if (n_degs > 0){ *degs = realloc(*degs, n_degs*sizeof(unsigned int)); *Nk = realloc(*Nk, n_degs*sizeof(unsigned int)); *p = realloc(*p, n_degs*sizeof(double)); } return n_degs; } int read_deg_seq(FILE *filein, unsigned int **nodes){ int size, N, k; char buff[256]; char *ptr; N = 0; size = 10; *nodes = (unsigned int*)malloc(size * sizeof(unsigned int)); while(fgets(buff, 256, filein)){ ptr = strtok(buff, " "); VALID_PTR_OR_EXIT(ptr, 7); if (ptr[0] == '#') continue; k = atoi(ptr); if (N == size){ size += 10; *nodes = realloc(*nodes, size*sizeof(unsigned int)); } (*nodes)[N] = k; N += 1; } if (N > 0) *nodes = realloc(*nodes, N * sizeof(unsigned int)); return N; } int read_stubs(FILE *filein, unsigned int **S){ int size, K; char buff[256]; char *ptr; K=0; size = 20; *S = malloc(size * sizeof(unsigned int)); while(fgets(buff, 256, filein)){ if (K == size){ size += 20; *S = realloc(*S, size*sizeof(unsigned int)); } ptr = strtok(buff, " "); /* read the first node */ VALID_PTR_OR_EXIT(ptr, 7); (*S)[K++] = atoi(ptr); ptr = strtok(NULL, " "); /* read the second node */ VALID_PTR_OR_EXIT(ptr, 7); (*S)[K++] = atoi(ptr); } if (K > 0) *S = realloc(*S, K * sizeof(unsigned int)); return K; } /* * Read a file in ij format */ int read_ij(FILE *filein, unsigned int **I, unsigned int **J){ unsigned int size, K; char buff[256]; char *ptr; size = 20; K = 0; *I = malloc(size * sizeof(unsigned int)); *J = malloc(size * sizeof(unsigned int)); while(fgets(buff, 256, filein)){ if (buff[0] == '#') continue; if (K == size){ size += 20; *I = realloc(*I, size*sizeof(unsigned int)); *J = realloc(*J, size*sizeof(unsigned int)); } ptr = strtok(buff, " "); /* read the first node */ VALID_PTR_OR_EXIT(ptr, 7); (*I)[K] = atoi(ptr); ptr = strtok(NULL, " "); /* read the second node */ VALID_PTR_OR_EXIT(ptr, 7); (*J)[K] = atoi(ptr); K += 1; } if (K > 0){ *I = realloc(*I, K * sizeof(unsigned int)); *J = realloc(*J, K * sizeof(unsigned int)); } return K; } /* * Read a file in ij format -- weighted graphs -- if the input file is * unweighted (i.e., no weights are provided), all the edges are * assumed to have weight equal to 1.0 */ int read_ij_w(FILE *filein, unsigned int **I, unsigned int **J, double **W){ unsigned int size, K; char buff[256]; char *ptr; size = 20; K = 0; *I = malloc(size * sizeof(unsigned int)); *J = malloc(size * sizeof(unsigned int)); *W = malloc(size * sizeof(double)); while(fgets(buff, 256, filein)){ if (buff[0] == '#') continue; if (K == size){ size += 20; *I = realloc(*I, size*sizeof(unsigned int)); *J = realloc(*J, size*sizeof(unsigned int)); *W = realloc(*W, size*sizeof(double)); } ptr = strtok(buff, " "); /* read the first node */ VALID_PTR_OR_EXIT(ptr, 7); (*I)[K] = atoi(ptr); ptr = strtok(NULL, " "); /* read the second node */ VALID_PTR_OR_EXIT(ptr, 7); (*J)[K] = atoi(ptr); ptr = strtok(NULL, " "); /* read the weight */ if (!ptr) (*W)[K] = 1.0; else (*W)[K] = atof(ptr); K += 1; } if (K > 0){ *I = realloc(*I, K * sizeof(unsigned int)); *J = realloc(*J, K * sizeof(unsigned int)); *W = realloc(*W, K * sizeof(double)); } return K; } void read_slap(FILE *filein, unsigned int *K, unsigned int *N, unsigned int **J_slap, unsigned int **r_slap){ unsigned int *I=NULL, *J=NULL; unsigned int i, k; k = read_ij(filein, &I, &J); *K = 2 * k; I = realloc(I, 2*k * sizeof(unsigned int)); J = realloc(J, 2*k * sizeof(unsigned int)); for (i=k; i<2*k; i ++){ I[i] = J[i-k]; J[i] = I[i-k]; } *N = convert_ij2slap(I, J, 2*k, r_slap, J_slap); free(I); free(J); return; } void read_slap_w(FILE *filein, unsigned int *K, unsigned int *N, unsigned int **J_slap, unsigned int **r_slap, double **W_slap){ unsigned int *I=NULL, *J=NULL; double *W=NULL; unsigned int i, k; k = read_ij_w(filein, &I, &J, &W); *K = 2 * k; if (*K > 0){ I = realloc(I, (*K) * sizeof(unsigned int)); J = realloc(J, (*K) * sizeof(unsigned int)); W = realloc(W, (*K) * sizeof(double)); } for (i=k; i<2*k; i ++){ I[i] = J[i-k]; J[i] = I[i-k]; W[i] = W[i-k]; } *N = convert_ij2slap_w(I, J, W, 2*k, r_slap, J_slap, W_slap); free(I); free(J); free(W); return; } /** * * Read an I-J (directed) edge list, and transform it in SLAP * notation, where the members of J_slap will be the outgoing * neighbours * */ void read_slap_dir(FILE *filein, unsigned int *K, unsigned int *N, unsigned int **J_slap, unsigned int **r_slap){ unsigned int *I=NULL, *J=NULL; unsigned int k; k = read_ij(filein, &I, &J); *K = k; *N = convert_ij2slap(I, J, k, r_slap, J_slap); free(I); free(J); return; } /** * * Read an I-J (directed) edge list, and transform it in SLAP * notation, where the members of J_slap will be the incoming * neighbours * */ void read_slap_dir_incoming(FILE *filein, unsigned int *K, unsigned int *N, unsigned int **J_slap, unsigned int **r_slap){ unsigned int *I=NULL, *J=NULL; unsigned int k; k = read_ij(filein, &I, &J); *K = k; *N = convert_ij2slap(J, I, k, r_slap, J_slap); free(I); free(J); return; } unsigned int find_max(unsigned int *v, unsigned int N){ unsigned int i, max; max = v[0]; i = 0; while(++i < N){ if (v[i] > max) max = v[i]; } return max; } int convert_ij2slap(unsigned int *I, unsigned int *J, unsigned int K, unsigned int ** r_slap, unsigned int **J_slap){ unsigned int tmp, max; unsigned int i, pos; unsigned int *p; if (K < 1){ return 0; } max = find_max(I, K) + 1; tmp = find_max(J, K) + 1; if (tmp > max){ max = tmp ; } *r_slap = malloc( (max+1) * sizeof(unsigned int)); p = malloc(max * sizeof(unsigned int)); *J_slap = malloc(K * sizeof(unsigned int)); memset(*r_slap, 0, (max+1) * sizeof(unsigned int)); for(i=0; i max){ max = tmp ; } if (K<1){ return 0; } *r_slap = malloc( (max+1) * sizeof(unsigned int)); p = malloc(max * sizeof(unsigned int)); *J_slap = malloc(K * sizeof(unsigned int)); *W_slap = malloc(K * sizeof(double)); memset(*r_slap, 0, (max+1) * sizeof(unsigned int)); for(i=0; i *l2 ? 1 : 0)); } void print_int(void *e){ int d; d = *((int*)e); printf("%d ", d); } void print_double(void *e){ double d; d = *((double*)e); printf("%g ", d); } void write_edges(FILE *fileout, unsigned int *J_slap, unsigned int *r_slap, unsigned int N){ unsigned int i, j; for(i=0; i i){ fprintf(fileout, "%d %d\n", i, J_slap[j]); } } } } void write_edges_dir(FILE *fileout, unsigned int *J_slap, unsigned int *r_slap, unsigned int N){ unsigned int i, j; for(i=0; i=N || j >=N) return 0; for(l=r_slap[i]; l= 0){ if (i > num_char) str[i] = ' '; else str[i] = '.'; } str[20] = '\0'; fprintf(fout, "\r%s [%s] %3d%%\r", s, str, (int)(frac * 100)); } void shuffle_vector(unsigned int *v, unsigned int N){ int i, pos; for(i=N-1; i>=0; i--){ pos = rand() % N; if (pos != i){ v[i] ^= v[pos]; v[pos] ^= v[i]; v[i] ^= v[pos]; } } } unsigned int read_partition(FILE *fin, unsigned int N, unsigned int *part){ unsigned int i; char *ptr; char buff[256]; unsigned int max_part = 0, val; while(fgets(buff, 256, fin)){ if (buff[0] == '#') continue; ptr = strtok(buff, " "); /* read the node */ VALID_PTR_OR_EXIT(ptr, 7); i = atoi(ptr); if(i >= N){ fprintf(stderr, "Index %d out of bounds (0, %d) in read_partition (%s: %d)\n", i, N, __FILE__, __LINE__); } ptr = strtok(NULL, " "); /* read the partition number */ VALID_PTR_OR_EXIT(ptr, 7); val = atoi(ptr); if (val > max_part){ max_part = val; } part[i] = val; } return max_part; } int degree(unsigned int *r_slap, unsigned int i){ return r_slap[i+1] - r_slap[i]; } int my_strcasecmp(const char *s1, const char *s2){ char *c1, *c2; int l1, l2; int res, i; l1 = strlen(s1); l2 = strlen(s2); c1 = malloc((1 + l1) * sizeof(char)); c2 = malloc((1 + l2) * sizeof(char)); for (i=0; i