/*
* This file is part of MAMMULT: Metrics And Models for Multilayer Networks
*
* 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 .
*/
/**
*
* 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