/** * * Fit a given sequence with a power-law function * * a*x^{b} * * The fit is actually performed as a linear fit on the * exponential-binned log-log distribution * * */ #include #include #include #include /** * * Load a sequence from a file, which contains one element on each line * */ void load_sequence(char *fname, double **v, int *N){ int size; char buff[256]; FILE *f; f = fopen(fname, "r"); if (!f){ fprintf(stderr, "Error opening file %s!!!! Exiting...\n", fname); exit(1); } *N =0; size = 10; if (*v == NULL) *v = malloc(size * sizeof(double)); else{ *v = realloc(*v, size * sizeof(double)); } while (fgets(buff, 255, f)){ (*v)[*N] = atof(buff); *N += 1; if (*N == size){ size += 10; *v = realloc(*v, size * sizeof(double)); } } *v = realloc(*v, (*N) * sizeof(double)); fclose(f); } /** * * Load a sequence, getting the "col"-th column of the input file * */ void load_sequence_col(char *fname, double **v, int *N, int col){ int size, n; char buff[256]; char *ptr; FILE *f; f = fopen(fname, "r"); if (!f){ fprintf(stderr, "Error opening file %s!!!! Exiting...\n", fname); exit(1); } *N =0; size = 10; if (*v == NULL) *v = malloc(size * sizeof(double)); else{ *v = realloc(*v, size * sizeof(double)); } while (fgets(buff, 255, f)){ ptr = strtok(buff, " "); if (col > 0){ n = 0; while (n max_v) max_v = v[i]; else if (v[i] > 0 && v[i] < min_v) min_v = v[i]; } size = 10; if (*x == NULL){ *x = malloc(size * sizeof(double)); } else{ *x = realloc(*x, size * sizeof(double)); } val = min_v; last_size = min_v; (*x)[0] = min_v; num_x = 1; while(val < max_v){ new_size = last_size * alpha; val = last_size + new_size; last_size = new_size; last_val = val; (*x)[num_x] = val; num_x += 1; if (num_x == size){ size += 10; *x = realloc(*x, size * sizeof(double)); } } if (*y == NULL){ *y = malloc(num_x * sizeof(double)); } else{ *y = realloc(*y, num_x * sizeof(double)); } for (i=0; i < num_x; i++){ (*y)[i] = 0; } for(i=0; i (*x)[j]){ j ++; } (*y)[j] += 1; } *num = num_x; } /** * * Make the exponential binning of a distribution, with a giving * exponent alpha. The value of y[i] is the average of the values in * the vector "w" whose corresponding v lies between x[i-1] and x[i]... * */ void exp_bin_avg(double *v, double *w, int N, double alpha, double **x, double **y, int *num){ double min_v, max_v, val, last_val; int i, j, size, num_x; double last_size, new_size; int *cnt; min_v = max_v = v[0]; for (i=1; i max_v) max_v = v[i]; else if (v[i] > 0 && v[i] < min_v) min_v = v[i]; } size = 10; if (*x == NULL){ *x = malloc(size * sizeof(double)); } else{ *x = realloc(*x, size * sizeof(double)); } val = min_v; last_size = min_v; (*x)[0] = min_v; num_x = 1; while(val < max_v){ new_size = last_size * alpha; val = last_size + new_size; last_size = new_size; last_val = val; (*x)[num_x] = val; num_x += 1; if (num_x == size){ size += 10; *x = realloc(*x, size * sizeof(double)); } } cnt = malloc(num_x * sizeof(int)); if (*y == NULL){ *y = malloc(num_x * sizeof(double)); } else{ *y = realloc(*y, num_x * sizeof(double)); } for (i=0; i < num_x; i++){ (*y)[i] = 0; cnt[i] = 0; } for(i=0; i (*x)[j]){ j ++; } if(j == num_x){ printf("Error!!!!! Trying to assing a non-existing bin!!! -- fit_utils.c:exp_bin_avg!!!\n"); exit(37); } (*y)[j] += w[i]; cnt[j] += 1; } *num = num_x; for(i=0; i< num_x; i++){ if (cnt[i] > 0){ (*y)[i] = (*y)[i] / cnt[i]; } } free(cnt); } /** * * Print a distribution on stdout * */ void dump_distr(double *x, double *y, int N){ int i; for(i=0; i 0 * */ void compact_distr(double *x, double *y, int *num){ int i, j; i = j = 0; while(j < *num){ while(j < *num && y[j] == 0){ j ++; } if (j==*num){ break; } x[i] = x[j]; y[i] = y[j]; i ++; j ++; } *num = i; } /** * * Apply the function "f" on all the elemnts of a vector, in-place * */ void map_vec(double *v, int N, double (*f)(double)){ int i; for (i=0; i