Ignore:
Timestamp:
Apr 15, 2010, 12:34:20 PM (16 years ago)
Author:
Frederik Heber <heber@…>
Children:
e34098
Parents:
35bab2
Message:

Rewrite of average.cpp and added first UnitTest.

  • average.cpp is now called averager.cpp and uses a function AverageColumns().
  • new function AverageColumns(): takes an input streamd and a set of column indices for which averages shall be computed
  • Introduced unit tests to Utils part of ESPACK:
    • new unit test AverageColumnsUnitTest testing the above.
    • Makefile generation introduced into configure.ac
    • subdir forked in Makefile.am
File:
1 edited

Legend:

Unmodified
Added
Removed
  • util/src/average.cpp

    r35bab2 r5a84ee  
     1/*
     2 * average.cpp
     3 *
     4 *  Created on: Apr 15, 2010
     5 *      Author: heber
     6 */
     7
    18using namespace std;
     9
    210#include <iostream>
    311#include <iomanip>
    4 #include <fstream>
     12#include <string>
    513#include <sstream>
    6 #include <math.h>
    7 #include <string>
    814
    9 #include "version.h"
     15#include "average.hpp"
    1016
    11 int main(int argc, char **argv) {
     17/** Takes the average over all entries in a list of columns per column.
     18 * Note that point in ifstream \a data is returned to its position on beginning.
     19 * \param data input stream with entries, columns are white-space separated, rows by new-line.
     20 * \param Columns set of indices (zero-based) for which columns to compute the average,
     21 *        note that Columns is copied to allow for removal of faulty column indices.
     22 * \return pointer to map with column index as key and tuple (mean,std deviation) as value
     23 */
     24MeanErrorMap *AverageColumns(istream &data, IndexSet Columns)
     25{
     26  MeanErrorMap *Values = new MeanErrorMap;
     27  map<int, int> CountMap;
     28  double tmp = 0.;
     29  int cols = 0;
     30  int lines = 0;
     31  string zeile;
     32  stringstream line;
    1233
    13         double avg, dev;
    14         double tmp;
    15         int zaehler;
    16   int col;
    17         int flag;
    18         int skiplines=0;
    19         string zeile;
    20         stringstream line;
    21        
    22         cout << ESPACKVersion << endl;
     34  // store position of ifstream
     35  size_t position = data.tellg();
    2336
    24         if (argc <= 2) {
    25                 cout << "Usage: " << argv[0] << " <column (zero-based)> <data file> [#skip initial lines]\n";
    26                 return(1);
    27         }
    28         {
    29     line.str(argv[1]);
    30     line >> col;
    31     cout << "Using column " << col << "." << endl;
    32     line.clear();
    33         }
    34         if (argc > 3) {
    35     line.str(argv[3]);
    36     line >> skiplines;
    37     cout << "Will skip first " << skiplines << " lines." << endl;
    38     line.clear();
    39         }
     37  // set initial values in maps to zero
     38  for (IndexSet::iterator ColRunner = Columns.begin(); ColRunner != Columns.end(); ++ColRunner) {
     39    Values->insert( pair<int, pair<double, double> > (*ColRunner, pair<double, double> (0., 0.) ) );
     40    CountMap.insert( pair<int, int> (0, 0) );
     41  }
    4042
    41         // get average
    42         avg = 0.;
    43         zaehler=0;
    44         ifstream test(argv[2]);
    45         if (test == NULL) { cout << "Can't open File " << argv[2] << "\n"; return(255); }
    46         flag=1;
    47         while (getline(test, zeile, '\n')) {
    48           if (skiplines) {
    49             skiplines--;
    50             continue;
    51           }
     43  /// The average is taken by going through each line, scanning the desired column, adding up
     44  /// and keeping count of the number of summands.
     45  lines = 0;
     46  while (getline(data, zeile, '\n')) {
     47    // get next line
    5248    line.clear();
    5349    line.str(zeile);
    54     for (int j=0;j<=col;j++)
    55       if (!line.eof()) {
    56         line >> ws >> tmp;
     50    lines++;
     51    // go through the columns
     52    cols = -1;
     53    IndexSet::const_iterator Eraser = Columns.end();
     54    for (IndexSet::const_iterator ColRunner = Columns.begin(); ColRunner != Columns.end(); ++ColRunner) {
     55      // delete earlier column if necessary
     56      if (Eraser != Columns.end()) {
     57        Columns.erase(Eraser);
     58        Eraser = Columns.end();
     59      }
     60      // skip to next desired column
     61      for(;cols!=*ColRunner;++cols)
     62        if (!line.eof()) // check for end of line
     63          line >> ws >> tmp;
     64        else
     65          break;
     66      if (cols == *ColRunner) { // if end of line has not been reached
     67        (*Values)[*ColRunner].first += tmp;
     68        ++CountMap[*ColRunner];
    5769      } else {
    58         flag=0;
     70        cerr << "Not enough columns in line " << lines << "." << endl;
     71        Eraser = ColRunner;
     72        break;
    5973      }
    60     if (flag) {
    61       avg += tmp;
    62       zaehler++;
    6374    }
    64         }
    65         if (!flag) {
    66     cerr << "File does not contain " << col << " column(s)." << endl;
    67     exit(1);
    68         } else
    69           if (zaehler != 0) avg /= zaehler;
    70         // goto to beginning again
    71         test.clear();
    72   test.seekg(ios::beg);
     75    if (Eraser != Columns.end()) {
     76      Columns.erase(Eraser);
     77      Eraser = Columns.end();
     78    }
     79  }
    7380
    74         // get deviation
    75         dev = 0.;
    76         zaehler=0;
    77         flag=1;
    78   while (getline(test, zeile, '\n')) {
    79     if (skiplines) {
    80       skiplines--;
    81       continue;
     81  // go through each value in Results and take average
     82  {
     83    MeanErrorMap::iterator Eraser = Values->end();
     84    for (MeanErrorMap::iterator Runner = Values->begin(); Runner != Values->end(); ++Runner) {
     85      if(Eraser != Values->end()) {
     86        Values->erase(Eraser);
     87        Eraser = Values->end();
     88      }
     89      if (CountMap[Runner->first] != 0)
     90        Runner->second.first /= CountMap[Runner->first];
     91      else {
     92        cerr << "For column " << CountMap[Runner->first] << " no entries have been found." << endl;
     93        Eraser = Runner;
     94      }
    8295    }
     96    if(Eraser != Values->end()) {
     97      Values->erase(Eraser);
     98      Eraser = Values->end();
     99    }
     100  }
     101
     102  // goto to beginning again for second sweep
     103  data.clear();
     104  data.seekg(position);
     105
     106  /// The average is taken by going through each line, scanning the desired column, adding up
     107  /// and keeping count of the number of summands.
     108  lines = 0;
     109  while (getline(data, zeile, '\n')) {
     110    // get next line
    83111    line.clear();
    84112    line.str(zeile);
    85     for (int j=0;j<=col;j++)
    86       line >> ws >> tmp;
    87     if (!line.eof()) {
    88       dev += (tmp - avg)*(tmp - avg);
    89       zaehler++;
     113    lines++;
     114    // go through the columns
     115    cols = 0;
     116    for (IndexSet::const_iterator ColRunner = Columns.begin(); ColRunner != Columns.end(); ++ColRunner) {
     117      // skip to next desired column
     118      for(;cols!=*ColRunner;++cols)
     119        if (!line.eof()) // check for end of line
     120          line >> ws >> tmp;
     121        else
     122          break;
     123      if (cols == *ColRunner) { // if end of line has not been reached
     124        (*Values)[*ColRunner].second += (tmp - (*Values)[*ColRunner].first)*(tmp - (*Values)[*ColRunner].first);
     125      } else {
     126        cerr << "Not enough columns in line " << lines << "." << endl;
     127        break;
     128      }
    90129    }
    91130  }
    92         test.close();
    93         if (zaehler != 0) dev /= zaehler;
    94                        
    95         cout << setprecision(8) << avg << "\t" << setprecision(8) << sqrt(dev) << "\n";
    96         return(0);
    97 }
     131
     132  // go through each value in Results and take std deviation
     133  for (MeanErrorMap::iterator Runner = Values->begin(); Runner != Values->end(); ++Runner)
     134    if (CountMap[Runner->first] != 0)
     135      Runner->second.second /= CountMap[Runner->first];
     136    else
     137      cerr << "For column " << CountMap[Runner->first] << " no entries have been found." << endl;
     138
     139  // go back to initial pointer of data
     140  data.clear();
     141  data.seekg(position);
     142
     143  return Values;
     144};
Note: See TracChangeset for help on using the changeset viewer.