#ifndef __ANALYZER_HPP__ #define __ANALYZER_HPP__ #include<cmath> #include <vector> #include <iostream> #include <fstream> /** Classe utilisée pour faire des statistiques élémentaires sur une séquence d'opérations. */ class Analyzer{ public: /** Constructeur de la classe analyse Complexité en temps/espace, pire et meilleur cas : O(1) */ Analyzer():cumulative_square(0){} /** Ajoute un coût, une valeur à l'analyse. Complexité en temps/espace, pire cas : O(size) Complexité en temps/espace, meilleur cas : O(1) Complexité amortie : O(1) @param x est la valeur que l'on souhaite ajouter à l'analyse. */ void append(const double & x){ cost.push_back(x); cumulative_cost.push_back( (cumulative_cost.size()) ? cumulative_cost.back()+x : x); cumulative_square += x*x; } /** Renvoie la somme des coûts enregistrés dans cette analyse. Complexité en temps/espace, meilleur cas : O(1) @returns la somme des coûts enregistrés dans cette analyse. */ double get_total_cost(){ return cumulative_cost.back(); } /** Renvoie le coût amorti d'une opération. Complexité en temps/espace, meilleur cas : O(1) @param pos est l'indice de l'opération pour laquelle on veut connaître le coût amorti. @returns le coût amorti d'une opération. */ double get_amortized_cost(size_t pos){ return (pos)? cumulative_cost.at(pos)/pos : cumulative_cost.at(pos); } /** Renvoie la moyenne des coûts de toutes les opérations enregistrées dans l'analyse. Complexité en temps/espace, meilleur cas : O(1) @returns la moyenne des coûts de toutes les opérations enregistrées dans l'analyse. */ double get_average_cost(){ if(cumulative_cost.empty()) throw std::runtime_error("List is empty"); return cumulative_cost.back()/cumulative_cost.size(); } /** Renvoie la variance des coûts de toutes les opérations enregistrées dans l'analyse. Complexité en temps/espace, meilleur cas : O(1) @returns la variance des coûts de toutes les opérations enregistrées dans l'analyse. */ double get_variance(){ double mean, mean_square; mean = get_average_cost(); mean_square = mean * mean; return cumulative_square - mean_square; } /** Renvoie l'écart-type des coûts de toutes les opérations enregistrées dans l'analyse. Complexité en temps/espace, meilleur cas : O(1) @returns l'écart-type des coûts de toutes les opérations enregistrées dans l'analyse. */ double get_standard_deviation(){ return std::sqrt(get_variance()); } /** Sauvegarde la liste des coûts et des coûts amortis dans un fichier. Complexité en temps, meilleur/pire cas : O(size) @param path est le chemin du fichier dans lequel la sauvegarde est faite. */ void save_values(const std::string & path){ std::ofstream f; size_t i; f.open(path.c_str()); for (i = 0; i < cost.size(); ++i) f<<i<<" "<<cost.at(i)<<" "<<get_amortized_cost(i)<<std::endl; f.close(); } /** Affiche la liste des coûts et des coûts amortis sur la sortie standard. Complexité en temps, meilleur/pire cas : O(size) */ void plot_values(){ size_t i; for (i = 0; i < cost.size(); ++i) std::cout<<i<<" "<<cost.at(i)<<" "<<get_amortized_cost(i)<<std::endl; } private: // Coût de chaque opération. Peut représenter du temps ou une autre mesure. std::vector<double> cost; // Coût cumulatif. La case i contient la somme des coûts des i premières opérations. // Permet de calculer le coût amorti d'une opération. std::vector<double> cumulative_cost; // Carré du coût cumulatif. Sert à calculer la variance. On ne garde que la dernière valeur. double cumulative_square; }; #endif