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