From 3aee2fd43e3059a699af2b63c6f2395e5a55e515 Mon Sep 17 00:00:00 2001 From: KatolaZ Date: Wed, 27 Sep 2017 15:06:31 +0100 Subject: First commit on github -- NetBunch 1.0 --- src/utils/utils.c | 785 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 785 insertions(+) create mode 100644 src/utils/utils.c (limited to 'src/utils/utils.c') diff --git a/src/utils/utils.c b/src/utils/utils.c new file mode 100644 index 0000000..6ed5c19 --- /dev/null +++ b/src/utils/utils.c @@ -0,0 +1,785 @@ +/** + * 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