Day: August 28, 2014

Algoritmo para calcular a curtose e obliquidade

Hoje precisei calcular a curtose e obliquidade dos dados presentes num histograma. Após alguma pesquisa descobri este site com uma implementação em C++. Alterei a implementação para ficar num único arquivo em C:

#include <stdio.h>
#include <math.h<

long long n;
double M1, M2, M3, M4;

void clear()
{
    n = 0;
    M1 = M2 = M3 = M4 = 0.0;
}

void push(double x)
{
    double delta, delta_n, delta_n2, term1;

    long long n1 = n;
    n++;
    delta = x - M1;
    delta_n = delta / n;
    delta_n2 = delta_n * delta_n;
    term1 = delta * delta_n * n1;
    M1 += delta_n;
    M4 += term1 * delta_n2 * (n*n - 3*n + 3) + 6 * delta_n2 * M2 - 4 * delta_n * M3;
    M3 += term1 * delta_n * (n - 2) - 3 * delta_n * M2;
    M2 += term1;
}

long long num_data_values()
{
    return n;
}

double mean()
{
    return M1;
}

double variance()
{
    return M2/(n-1.0);
}

double standard_deviation()
{
    return sqrt( variance() );
}

double skewness()
{
    return sqrt((double)n) * M3/ pow(M2, 1.5);
}

double kurtosis()
{
    return (double) ((n)*M4 / (M2*M2) - 3.0);
}



int main(int argc, const char **argv)
{
	FILE *f;
	int value;
	char val[32];
	double kurt, skew;
		
	if (argc < 2) {
		printf("Use: oblicurto filename.txt\n");
		return -1;
	}
	
	if ((f = fopen(argv[1], "r")) == NULL){
		printf("Cannot open file %s!\n", argv[1]);
		return -1;
	}

	clear();

	while(fgets(val, 30, f) != NULL){
		value = atoi(val);
		push((double) value);
	}

	skew = skewness();
	kurt = kurtosis();

	printf("Amount = %d | Kurtosis = %f | Skewness = %f   ===>   ", (int) num_data_values(), kurt, skew);

	fclose(f);

	return 0;
}