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

float moyenne(float* valeurs, int n)
{
	float moyenne = 0;
	int i;
	
	/* Somme des valeurs */
	for(i = 0; i < n; i++)
	{
		moyenne = moyenne + valeurs[i];
	}
	/* Division par n */
	moyenne = moyenne / ((float) n);
	return moyenne;
}

float etendue(float* valeurs, int n)
{
	float etendue = 0;
	int i;
	float max = 0;
	float min = 0;
	
	/* Détermination des valeurs extrêmes */
	for(i = 0; i < n; i++)
	{
		if(valeurs[i] > max) max = valeurs[i];
		if(valeurs[i] < min) min = valeurs[i];
	}
	/* On soustrait la plus petite valeur à la plus grande */
	etendue = max - min;
	
	return etendue;
}

float valeur_abs(double nb)
{
	/* Si le nombre est négatif on calcule son opposée */
	if(nb < 0) nb = -1*nb;
	/* On le convertit en float, puisqu'il est positif */
	nb = (float) nb;
	
	return nb;
}

float ecart_moyen(float* valeurs, int n, float moyenne)
{
	float ecart_moyen = 0;
	double tmp;
	int i;
	
	/* Somme des écarts */
	for(i = 0; i < n; i++)
	{
		/* Calcul de l'écart */
		tmp = (double) valeurs[i] - moyenne;
		/* On passe à la valeur absolue */
		tmp = valeur_abs(tmp);
		/* On fait la somme des valeurs absolues des écarts */
		ecart_moyen = ecart_moyen + tmp;
	}
	/* Pour finir on divise la somme par n */
	ecart_moyen = ecart_moyen / n;
	
	return ecart_moyen;
}

float variance(float* valeurs, int n, float moyenne)
{
	float variance = 0;
	double tmp;
	int i;
	
	for(i = 0; i < n; i++)
	{
		/* Calcul de l'écart */
		tmp = (double) valeurs[i] - moyenne;
		/* On met le tout au carré */
		tmp = tmp*tmp;
		/* On fait la somme des carrés des écarts */
		variance = variance + tmp;
	}
	/* Pour finir on divise la somme par n */
	variance = variance / n;
	
	return variance;
}

float ecart_type(float variance)
{
	float ecart_type;
	/* L'écart type est la racine carrée de la variance */
	ecart_type = sqrt(variance);
	
	return ecart_type;
}

float cdv(float ecart_type, float moyenne)
{
	return ecart_type / moyenne;
}

/* Fonction de comparaison de 2 valeurs d'un tableau */
int comparaison(const void* _a, const void* _b)
{
	const float* a = (const float*) _a;
	const float* b = (const float*) _b;

	if(*a > *b) return 1;             
	else if(*a == *b) return  0;       
	else return -1;        
}

float* tri(float* valeurs, int n)
{
	float* valeurs_ord;
	
	/* Création du tableau qui contiendra les valeurs ordonnées */
	valeurs_ord = (float*) malloc(n*sizeof(float));
	
	/* Copie de valeurs[] dans valeurs_ord[] */
	memcpy(valeurs_ord, valeurs, n*sizeof(float));
	
	/* On ordonne le tableau */
	qsort((void *) valeurs_ord, 5, sizeof(valeurs_ord[0]), comparaison);
	
	return valeurs_ord;
}

float mediane(float* valeurs, int n)
{
	float* valeurs_ord;
	int milieu;
	/* On commence par ordonner la série */
	valeurs_ord = tri(valeurs, n);
	/* On calcule l'indice correspondant à la médiane */
	milieu = n/2 + 1;
	/* On retourne la médiane */
	return valeurs_ord[milieu];
}

float quartile(float* valeurs, int n, int num_quartile)
{
	float* valeurs_ord;
	int indice;
	
	if(num_quartile > 0 && num_quartile < 4)
	{
		/* On commence par ordonner la série */
		valeurs_ord = tri(valeurs, n);
		/* On calcule l'indice correspondant au quartile */
		indice = (n/4) * num_quartile + 1;
		/* On retourne le  num_quartile ième quartile */
		return valeurs_ord[indice];
	}
	else return 0;
}

float decile(float* valeurs, int n, int num_decile)
{
	float* valeurs_ord;
	int indice;
	
	if(num_decile > 0 && num_decile < 10)
	{
		/* On commence par ordonner la série */
		valeurs_ord = tri(valeurs, n);
		/* On calcule l'indice correspondant au décile */
		indice = (n/4) * num_decile + 1;
		/* On retourne le num_decile ième décile */
		return valeurs_ord[indice];
	}
	else return 0;
}

float mode(float* valeurs, int n)
{
	int max_found = 0, i = 1, occurences = 0, indice = 0;
	float mode;
	float* valeurs_ord;
	
	/* On commence par ordonner la série */
	valeurs_ord = tri(valeurs, n);
	/* On parcourt le tableau */
	while(i < n)
	{
		occurences = 0;
		/* On compte le nombre de fois que la valeur apparait */
		while(valeurs_ord[i] == valeurs_ord[i-1])
		{
			occurences++;
			i++;
		}
		/* Si le nombre d'occurence est supérieur au plus grand nombre d'occurences déjà trouvées, on le remplace et on sauvegarde l'indice */
		if(occurences > max_found)
		{
			max_found = occurences;
			indice = i;
		}
		i++;
	}
	/* On en déduit le mode, placé à l'indice sauvegardé */
	mode = valeurs_ord[indice];
	return mode;
}

int main()
{
	float test[5] = {1, 1, 1, 2, 3};
	float amode;
	
	amode = mode(test, 5);
	
	printf("%f", amode);
	
	system("PAUSE");
	return 0;
}
