float STATS::median() { //get median float median; inT32 min_pile; inT32 median_pile; inT32 max_pile; if (buckets == NULL) { /* err.log(RESULT_LOGICAL_ERROR,E_LOC,ERR_PRIMITIVES, ERR_SCROLLING,ERR_CONTINUE,ERR_ERROR, "Empty stats");*/ return (float) rangemin; } median = (float) ile ((float) 0.5); median_pile = (inT32) floor (median); if ((total_count > 1) && (pile_count (median_pile) == 0)) { /* Find preceeding non zero pile */ for (min_pile = median_pile; pile_count (min_pile) == 0; min_pile--); /* Find following non zero pile */ for (max_pile = median_pile; pile_count (max_pile) == 0; max_pile++); median = (float) ((min_pile + max_pile) / 2.0); } return median; }
/** * Entrée d'une commande (STDIN) et retour d'une réponse appropriée (STDOUT). * Retourne -1 lors d'une demande de quitter le programme, ou 0 si on continue. * * Invite l'utilisateur à entrer des commandes au format postfixe (ex: 3 2 + 5 * =a). */ int traitement_commande() { printf("> "); char* entree = entreeDynamique(stdin); if(entree == NULL) { printf("Pas assez de mémoire pour allouer l'entrée.\n"); return 0; } if(strcmp(entree, "\0") == 0) { // Si l'utilisateur quitte ou entre une ligne vide. free(entree); return -1; } // Les différentes parties sont séparées par des espaces. char* partie = strtok(entree, " "); // Pile des commandes entrées, une fois exécutées. pile* commandes = malloc(sizeof(pile)); if(commandes == NULL) { printf("Entrée invalide. La mémoire maximale a été dépassée.\n"); free(entree); return 0; } pile_init(commandes); do { if(strcmp(partie, "+") == 0 || strcmp(partie, "-") == 0 || strcmp(partie, "*") == 0) { if(pile_count(commandes) >= 2) { num* r; num* b = pile_pop(commandes); num* a = pile_pop(commandes); if(strcmp(partie, "+") == 0) { r = addition(a, b, a->positif, b->positif); } else if(strcmp(partie, "-") == 0) { r = soustraction(a, b, a->positif, b->positif); } else if(strcmp(partie, "*") == 0) { r = multiplication(a, b); } if(r == NULL) { printf("Mauvais calcul !\n"); superFree(a); superFree(b); free(entree); free(commandes); return 0; } pile_push(commandes, r); } else { printf("Erreur: il manque une entree pour faire une operation !\n"); free(entree); free(commandes); return 0; } } else if(partie[0] == '=' && strlen(partie) == 2 && partie[1] >= 'a' && partie[1] <= 'z') { // Assignation de variable, on assigne et on continue comme si de rien n'était. if(pile_count(commandes) > 0) { variables[(int) partie[1] % 32] = pile_peek(commandes); } else { printf("Que voulez-vous assigner ? Il manque quelque chose...\n"); free(entree); free(commandes); return 0; } } else if(strlen(partie) == 1 && partie[0] >= 'a' && partie[0] <= 'z') { // Variable, on met sa valeur dans la pile d'opérations. if(variables[(int) partie[0] % 32] != NULL) { pile_push(commandes, variables[(int) partie[0] % 32]); } else { printf("La variable '%c' n'est pas encore définie.\n", partie[0]); free(commandes); free(entree); return 0; } } else { int est_un_nombre = 1; int i = 0; while(i < strlen(partie)) { if(partie[i] < '0' || partie[i] > '9') { est_un_nombre = 0; break; } i++; } if(est_un_nombre == 1) { // Valeur, on la met dans un nombre à précision infinie et on met sa référence dans la pile. num* valeur = malloc(sizeof(num)); if(valeur == NULL) { printf("Entrée invalide. La mémoire maximale a été dépassée.\n"); free(entree); free(commandes); return 0; } strToBigNum(partie, valeur); pile_push(commandes, valeur); } else { // Caractère non-valide. printf("Les éléments doivent tous être des variables (a-z, minuscule), des opérateurs ou bien des valeurs positives entières.\n"); return 0; } } } while(partie = strtok(NULL, " ")); if(partie != NULL) { free(partie); } if(entree != NULL) { free(entree); } if(pile_count(commandes) == 1) { printNum(pile_pop(commandes)); } else { printf("Erreur de syntaxe, veuillez completer vos calculs !\n"); } free(commandes->data); free(commandes); return 0; }
inT32 STATS::cluster( //cluster samples float lower, //thresholds float upper, float multiple, //distance threshold inT32 max_clusters, //max no to make STATS *clusters //array of clusters ) { BOOL8 new_cluster; //added one float *centres; //cluster centres inT32 entry; //bucket index inT32 cluster; //cluster index inT32 best_cluster; //one to assign to inT32 new_centre = 0; //residual mode inT32 new_mode; //pile count of new_centre inT32 count; //pile to place float dist; //from cluster float min_dist; //from best_cluster inT32 cluster_count; //no of clusters if (max_clusters < 1) return 0; if (buckets == NULL) { /* err.log(RESULT_LOGICAL_ERROR,E_LOC,ERR_PRIMITIVES, ERR_SCROLLING,ERR_CONTINUE,ERR_ERROR, "Empty stats");*/ return 0; } centres = (float *) alloc_mem ((max_clusters + 1) * sizeof (float)); if (centres == NULL) { /* err.log(RESULT_NO_MEMORY,E_LOC,ERR_PRIMITIVES, ERR_SCROLLING,ERR_CONTINUE,ERR_ERROR, "No memory for centres"); */ return 0; } for (cluster_count = 1; cluster_count <= max_clusters && clusters[cluster_count].buckets != NULL && clusters[cluster_count].total_count > 0; cluster_count++) { centres[cluster_count] = (float) clusters[cluster_count].ile ((float) 0.5); new_centre = clusters[cluster_count].mode (); for (entry = new_centre - 1; centres[cluster_count] - entry < lower && entry >= rangemin && pile_count (entry) <= pile_count (entry + 1); entry--) { count = pile_count (entry) - clusters[0].pile_count (entry); if (count > 0) { clusters[cluster_count].add (entry, count); clusters[0].add (entry, count); } } for (entry = new_centre + 1; entry - centres[cluster_count] < lower && entry < rangemax && pile_count (entry) <= pile_count (entry - 1); entry++) { count = pile_count (entry) - clusters[0].pile_count (entry); if (count > 0) { clusters[cluster_count].add (entry, count); clusters[0].add (entry, count); } } } cluster_count--; if (cluster_count == 0) { clusters[0].set_range (rangemin, rangemax); } do { new_cluster = FALSE; new_mode = 0; for (entry = 0; entry < rangemax - rangemin; entry++) { count = buckets[entry] - clusters[0].buckets[entry]; //remaining pile if (count > 0) { //any to handle min_dist = (float) MAX_INT32; best_cluster = 0; for (cluster = 1; cluster <= cluster_count; cluster++) { dist = entry + rangemin - centres[cluster]; //find distance if (dist < 0) dist = -dist; if (dist < min_dist) { min_dist = dist; //find least best_cluster = cluster; } } if (min_dist > upper //far enough for new && (best_cluster == 0 || entry + rangemin > centres[best_cluster] * multiple || entry + rangemin < centres[best_cluster] / multiple)) { if (count > new_mode) { new_mode = count; new_centre = entry + rangemin; } } } } //need new and room if (new_mode > 0 && cluster_count < max_clusters) { cluster_count++; new_cluster = TRUE; if (!clusters[cluster_count].set_range (rangemin, rangemax)) return 0; centres[cluster_count] = (float) new_centre; clusters[cluster_count].add (new_centre, new_mode); clusters[0].add (new_centre, new_mode); for (entry = new_centre - 1; centres[cluster_count] - entry < lower && entry >= rangemin && pile_count (entry) <= pile_count (entry + 1); entry--) { count = pile_count (entry) - clusters[0].pile_count (entry); if (count > 0) { clusters[cluster_count].add (entry, count); clusters[0].add (entry, count); } } for (entry = new_centre + 1; entry - centres[cluster_count] < lower && entry < rangemax && pile_count (entry) <= pile_count (entry - 1); entry++) { count = pile_count (entry) - clusters[0].pile_count (entry); if (count > 0) { clusters[cluster_count].add (entry, count); clusters[0].add (entry, count); } } centres[cluster_count] = (float) clusters[cluster_count].ile ((float) 0.5); } } while (new_cluster && cluster_count < max_clusters); free_mem(centres); return cluster_count; }