17 #ifndef MOAB_HAVE_EIGEN3
18 #error compareMaps tool requires eigen3 configuration
26 #include <Eigen/Sparse>
29 printf( "Error: %s\n", nc_strerror( e ) ); \
38 #define GET_DIM1( ncdim, name, val ) \
40 int gdfail = nc_inq_dimid( ncFile1, name, &( ncdim ) ); \
41 if( NC_NOERR == gdfail ) \
44 gdfail = nc_inq_dimlen( ncFile1, ncdim, &tmp_val ); \
45 if( NC_NOERR != gdfail ) \
56 #define GET_VAR1( name, id, dims ) \
59 int gvfail = nc_inq_varid( ncFile1, name, &( id ) ); \
60 if( NC_NOERR == gvfail ) \
63 gvfail = nc_inq_varndims( ncFile1, id, &ndims ); \
64 if( NC_NOERR == gvfail ) \
66 ( dims ).resize( ndims ); \
67 gvfail = nc_inq_vardimid( ncFile1, id, &( dims )[0] ); \
68 if( NC_NOERR != gvfail ) \
76 #define GET_1D_INT_VAR1( name, id, vals ) \
78 GET_VAR1( name, id, vals ); \
82 int ivfail = nc_inq_dimlen( ncFile1, ( vals )[0], &ntmp ); \
83 if( NC_NOERR != ivfail ) \
87 ( vals ).resize( ntmp ); \
89 ivfail = nc_get_vara_int( ncFile1, id, &ntmp1, &ntmp, &( vals )[0] ); \
90 if( NC_NOERR != ivfail ) \
97 #define GET_1D_DBL_VAR1( name, id, vals ) \
99 std::vector< int > dum_dims; \
100 GET_VAR1( name, id, dum_dims ); \
104 int dvfail = nc_inq_dimlen( ncFile1, dum_dims[0], &ntmp ); \
105 if( NC_NOERR != dvfail ) \
109 ( vals ).resize( ntmp ); \
111 dvfail = nc_get_vara_double( ncFile1, id, &ntmp1, &ntmp, &( vals )[0] ); \
112 if( NC_NOERR != dvfail ) \
121 #define GET_DIM2( ncdim, name, val ) \
123 int gdfail = nc_inq_dimid( ncFile2, name, &( ncdim ) ); \
124 if( NC_NOERR == gdfail ) \
127 gdfail = nc_inq_dimlen( ncFile2, ncdim, &tmp_val ); \
128 if( NC_NOERR != gdfail ) \
139 #define GET_VAR2( name, id, dims ) \
142 int gvfail = nc_inq_varid( ncFile2, name, &( id ) ); \
143 if( NC_NOERR == gvfail ) \
146 gvfail = nc_inq_varndims( ncFile2, id, &ndims ); \
147 if( NC_NOERR == gvfail ) \
149 ( dims ).resize( ndims ); \
150 gvfail = nc_inq_vardimid( ncFile2, id, &( dims )[0] ); \
151 if( NC_NOERR != gvfail ) \
159 #define GET_1D_INT_VAR2( name, id, vals ) \
161 GET_VAR2( name, id, vals ); \
165 int ivfail = nc_inq_dimlen( ncFile2, ( vals )[0], &ntmp ); \
166 if( NC_NOERR != ivfail ) \
170 ( vals ).resize( ntmp ); \
172 ivfail = nc_get_vara_int( ncFile2, id, &ntmp1, &ntmp, &( vals )[0] ); \
173 if( NC_NOERR != ivfail ) \
180 #define GET_1D_DBL_VAR2( name, id, vals ) \
182 std::vector< int > dum_dims; \
183 GET_VAR2( name, id, dum_dims ); \
187 int dvfail = nc_inq_dimlen( ncFile2, dum_dims[0], &ntmp ); \
188 if( NC_NOERR != dvfail ) \
192 ( vals ).resize( ntmp ); \
194 dvfail = nc_get_vara_double( ncFile2, id, &ntmp1, &ntmp, &( vals )[0] ); \
195 if( NC_NOERR != dvfail ) \
202 #define GET_2D_DBL_VAR1( name, id, vals ) \
204 std::vector< int > dum_dims; \
205 GET_VAR1( name, id, dum_dims ); \
209 int dvfail = nc_inq_dimlen( ncFile1, dum_dims[0], &ntmp[0] ); \
210 if( NC_NOERR != dvfail ) \
214 dvfail = nc_inq_dimlen( ncFile1, dum_dims[1], &ntmp[1] ); \
215 if( NC_NOERR != dvfail ) \
219 ( vals ).resize( ntmp[0] * ntmp[1] ); \
220 size_t ntmp1[2] = { 0, 0 }; \
221 dvfail = nc_get_vara_double( ncFile1, id, ntmp1, ntmp, &( vals )[0] ); \
222 if( NC_NOERR != dvfail ) \
229 #define GET_2D_DBL_VAR2( name, id, vals ) \
231 std::vector< int > dum_dims; \
232 GET_VAR2( name, id, dum_dims ); \
236 int dvfail = nc_inq_dimlen( ncFile2, dum_dims[0], &ntmp[0] ); \
237 if( NC_NOERR != dvfail ) \
241 dvfail = nc_inq_dimlen( ncFile2, dum_dims[1], &ntmp[1] ); \
242 if( NC_NOERR != dvfail ) \
246 ( vals ).resize( ntmp[0] * ntmp[1] ); \
247 size_t ntmp1[2] = { 0, 0 }; \
248 dvfail = nc_get_vara_double( ncFile2, id, ntmp1, ntmp, &( vals )[0] ); \
249 if( NC_NOERR != dvfail ) \
256 typedef Eigen::Map< Eigen::VectorXd >
EigenV;
261 std::vector< double > fraca1( n ), fraca2( n );
264 EigenV fa1( fraca1.data(), n );
266 EigenV fa2( fraca2.data(), n );
268 EigenV diff( fraca2.data(), n );
272 double minV = diff.minCoeff( &imin );
273 double maxV = diff.maxCoeff( &imax );
274 std::cout << var_name <<
" diff norm: " << diff.norm() <<
" min at " << imin <<
" : " << minV <<
" max at " << imax
275 <<
" : " << maxV <<
"\n";
282 std::vector< double > fraca1( n ), fraca2( n );
285 EigenV fa1( fraca1.data(), n );
287 EigenV fa2( fraca2.data(), n );
288 std::cout << var_name <<
" diff norm: " << ( fa1 - fa2 ).norm() <<
"\n";
291 int main(
int argc,
char* argv[] )
296 std::string inputfile1, inputfile2;
297 opts.
addOpt< std::string >(
"firstMap,i",
"input filename 1", &inputfile1 );
298 opts.
addOpt< std::string >(
"secondMap,j",
"input second map", &inputfile2 );
300 opts.
addOpt<
int >(
"print_differences,p",
"print differences ", &print_diff );
301 double fraction = 0.9;
302 opts.
addOpt<
double >(
"fraction_diff,f",
"fraction threshold", &fraction );
307 int fail = nc_open( inputfile1.c_str(), 0, &
ncFile1 );
308 if( NC_NOWRITE !=
fail )
313 std::cout <<
" opened " << inputfile1 <<
" for map 1 \n";
316 if( NC_NOWRITE !=
fail )
321 std::cout <<
" opened " << inputfile2 <<
" for map 2 \n";
323 int na1, nb1, ns1, na2, nb2, ns2, nv_a, nv_b, nv_a2, nv_b2;
331 GET_DIM2( temp_dim,
"nv_a", nv_a2 );
333 GET_DIM2( temp_dim,
"nv_b", nv_b2 );
334 if( nv_a != nv_a2 || nv_b != nv_b2 )
336 std::cout <<
" different nv dimensions:" << nv_a <<
" == " << nv_a2 <<
" or " << nv_b <<
" == " << nv_b2
340 std::cout <<
" n_a, n_b, n_s : " << na1 <<
", " << nb1 <<
", " << ns1 <<
" for map 1 \n";
342 std::cout <<
" n_a, n_b, n_s : " << na2 <<
", " << nb2 <<
", " << ns2 <<
" for map 2 \n";
343 if( na1 != na2 || nb1 != nb2 )
345 std::cout <<
" different dimensions bail out \n";
348 std::vector< int > col1( ns1 ), row1( ns1 );
349 std::vector< int > col2( ns2 ), row2( ns2 );
351 std::vector< double > val1( ns1 ), val2( ns2 );
353 int idrow1, idcol1, idrow2, idcol2, ids1, ids2;
362 typedef Eigen::Triplet< double > Triplet;
363 std::vector< Triplet > tripletList;
364 tripletList.reserve( ns1 );
365 for(
int iv = 0; iv < ns1; iv++ )
367 tripletList.push_back( Triplet( row1[iv] - 1, col1[iv] - 1, val1[iv] ) );
369 Eigen::SparseMatrix< double > weight1( nb1, na1 );
371 weight1.setFromTriplets( tripletList.begin(), tripletList.end() );
372 weight1.makeCompressed();
374 if( ns1 != ns2 ) tripletList.resize( ns2 );
375 for(
int iv = 0; iv < ns2; iv++ )
377 tripletList[iv] = Triplet( row2[iv] - 1, col2[iv] - 1, val2[iv] );
379 Eigen::SparseMatrix< double > weight2( nb2, na2 );
381 weight2.setFromTriplets( tripletList.begin(), tripletList.end() );
382 weight2.makeCompressed();
385 Eigen::SparseMatrix< double > diff = weight1 - weight2;
386 diff.makeCompressed();
387 auto coeffs = diff.coeffs();
388 double maxv = coeffs.maxCoeff();
389 double minv = coeffs.minCoeff();
390 std::cout <<
" euclidian norm for difference: " << diff.norm()
391 <<
" \n squared norm for difference: " << diff.squaredNorm() <<
"\n"
392 <<
" minv: " << minv <<
" maxv: " << maxv <<
"\n";
394 double min_threshold = fraction * minv;
395 double max_threshold = fraction * maxv;
397 std::cout << std::setprecision( 9 );
398 for(
int k = 0; ( k < diff.outerSize() ); ++k )
400 for( Eigen::SparseMatrix< double >::InnerIterator it( diff, k ); ( it ) && ( counter < print_diff ); ++it )
402 double val = it.value();
403 if( val <= min_threshold || val >= max_threshold )
407 std::cout <<
" counter:" << counter <<
"\t col: " << col + 1 <<
"\t row: " << row + 1
408 <<
"\t diff: " << val;
409 std::cout <<
"\t map1: " << weight1.coeffRef( row, col ) <<
"\t map2: " << weight2.coeffRef( row, col )