DGtalTools 2.0.0
Loading...
Searching...
No Matches
statisticsEstimators.cpp
1
31#include <iostream>
32#include <fstream>
33#include <sstream>
34#include <string>
35#include <cmath>
36#include <math.h>
37#include <limits>
38#include <boost/foreach.hpp>
39#include <boost/tokenizer.hpp>
40
41#include "CLI11.hpp"
42
43#include "DGtal/base/Common.h"
44
45using namespace DGtal;
46
47
106bool LoadingStringFromFile( std::ifstream & file, std::string & value )
107{
108 if( file.good() )
109 {
110 std::getline( file, value );
111 return true;
112 }
113 return false;
114}
115
123void split( const std::string & s, char delim, std::vector< std::string > & elems )
124{
125 std::stringstream ss( s );
126 std::string item;
127 while( std::getline( ss, item, delim ))
128 {
129 elems.push_back( item );
130 }
131}
132
143int ComputeStatistics ( const std::string & inputdata1,
144 const std::string & inputdata2,
145 const unsigned int & idColumnData1,
146 const unsigned int & idColumnData2,
147 const bool & isMongeMean,
148 std::ofstream & output )
149{
150 std::ifstream file1( inputdata1.c_str() );
151 std::ifstream file2( inputdata2.c_str() );
152
153 double absd1d2;
154 double L1 = 0.0;
155 double L2 = 0.0;
156 double Linf = 0.0;
157
158 std::string s1, s2;
159 double v1, v2;
160 double h = - std::numeric_limits<double>::max();
161
162 unsigned int nb_elements = 0;
163 bool finish = false;
164 while(( LoadingStringFromFile( file1, s1 ) && LoadingStringFromFile( file2, s2 )) && !finish )
165 {
166 while ( s1[ 0 ] == '#' )
167 {
168 std::size_t p = s1.find( "# h = " );
169 if ( p != std::string::npos )
170 {
171 h = atof((s1.erase( p, 5 )).c_str());
172 }
173 if( ! LoadingStringFromFile( file1, s1 ) )
174 {
175 s1 = "NA";
176 finish = true;
177 }
178 }
179
180 while ( s2[ 0 ] == '#' )
181 {
182 if( ! LoadingStringFromFile( file2, s2 ) )
183 {
184 s2 = "NA";
185 finish = true;
186 }
187 }
188
189 if ( s1 == "NA" || s1 == "-nan" || s1 == "-inf" || s1 == "inf" || s1 == "" || s1 == " " )
190 continue;
191 if ( s2 == "NA" || s2 == "-nan" || s2 == "-inf" || s2 == "inf" || s2 == "" || s2 == " " )
192 continue;
193
194 std::vector< std::string > elems1;
195 split( s1, ' ', elems1 );
196 std::vector< std::string > elems2;
197 split( s2, ' ', elems2 );
198
199 if( elems1.size() <= idColumnData1 )
200 {
201 std::cerr << "Can't found " << idColumnData1 << " column on file1 (" << inputdata1 << "). Is the file/column exist ?" << std::endl;
202 continue;
203 }
204 if( elems2.size() <= idColumnData2 )
205 {
206 std::cerr << "Can't found " << idColumnData2 << " column on file2 (" << inputdata2 << "). Is the file/column exist ?" << std::endl;
207 continue;
208 }
209
210 v1 = atof( elems1[ idColumnData1 ].c_str() );
211 v2 = atof( elems2[ idColumnData2 ].c_str() );
212
213 if( isMongeMean && (( v1 >= 0.0 ) ^ ( v2 >= 0.0 ))) // hack for Monge. Can be reversed.
214 {
215 v2 = -v2;
216 }
217
218 absd1d2 = std::abs ( v1 - v2 );
219 if ( Linf < absd1d2 )
220 {
221 Linf = absd1d2;
222 }
223 L1 += absd1d2;
224 L2 += absd1d2 * absd1d2;
225
226 ++nb_elements;
227 }
228
229 if( h == - std::numeric_limits<double>::max())
230 {
231 std::cerr << "Can't found h value on file1 (" << inputdata1 << "). Is the file exist ?" << std::endl;
232 return 0;
233 }
234
235 double meanL1 = L1 / (double)nb_elements;
236 double meanL2 = ( sqrt ( L2 )) / (double)nb_elements;
237
238 output << h << " "
239 << meanL1 << " "
240 << meanL2 << " "
241 << Linf
242 << std::endl;
243
244 return 1;
245}
246
247int main( int argc, char** argv )
248{
249 // parse command line CLI ----------------------------------------------
250 CLI::App app;
251 std::string filename1;
252 std::string filename2;
253 unsigned int column1;
254 unsigned int column2;
255 std::string output_filename;
256 bool isMongeMean {false};
257
258 app.description("Computes satistics (L1, L2, Loo) from results of two estimators.\n Typical use example:\n \t statisticsEstimators --file1 <file1> --column1 <column1> --file2 <file2> --column2 <column2> --output <output>\n");
259 app.add_option("-f,--file1,1",filename1,"File 1.")->required()->check(CLI::ExistingFile);
260 app.add_option("-F,--file2,2",filename2,"File 2.")->required()->check(CLI::ExistingFile);
261 app.add_option("--column1,-c", column1, "Column of file 1" )->required();
262 app.add_option("--column2,-C", column2, "Column of file 2" )->required();
263 app.add_option("--output,-o,2", output_filename, "Output file")->required();
264 app.add_option("--monge,-m", isMongeMean, "Is from Monge mean computation (optional, default false)");
265
266 app.get_formatter()->column_width(40);
267 CLI11_PARSE(app, argc, argv);
268 // END parse command line using CLI ----------------------------------------------
269
270 std::ifstream inFileEmptyTest; inFileEmptyTest.open(output_filename.c_str());
271 bool isNew = inFileEmptyTest.peek() == std::ifstream::traits_type::eof(); inFileEmptyTest.close();
272 std::ofstream file( output_filename.c_str(), std::ofstream::out | std::ofstream::app );
273
274 if( isNew )
275 {
276 file << "# h | "
277 << "L1 Mean Error | "
278 << "L2 Mean Error | "
279 << "Loo Mean Error"
280 << std::endl;
281 }
282
283 if ( ComputeStatistics( filename1, filename2, column1, column2, isMongeMean, file ) == 0 )
284 {
285 file.close();
286 return -1;
287 }
288
289 file.close();
290 return 1;
291}
Definition ATu0v1.h:57