source: util/src/average.cpp@ 37ec1b

Last change on this file since 37ec1b was 37ec1b, checked in by Frederik Heber <heber@…>, 15 years ago

BUGFIX: Extended AverageColumnsUnitTest, found one bug in AverageColumns.

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