Teuchos: Compare Sorted ParameterLists
Created by: danielsjensen1
For unit testing purposes it would be nice to be able to compare ParameterLists without respect to ordering. This is useful when the tester doesn't have control over the order that values are added to a ParameterList but needs to check for equality regardless of order.
@trilinos/Teuchos
enhancement
Expectations
There should be an option to compare sorted ParameterLists.
Current Behavior
Even the current haveSameValues
function respects ordering and there doesn't appear to be a sorting routine for ParameterLists.
Motivation and Context
This is helpful for unit testing purposes to ensure the proper creation of input values after validation.
Definition of Done
Either a workaround or a new feature should be provided.
Possible Solution
The following modification to the haveSameValues
function appears to work but I'm sure there are better solutions. In particular, it should probably be an optional feature or separate function such as haveSameValuesSorted
.
bool haveSameValues( const Teuchos::ParameterList& list1, const Teuchos::ParameterList& list2, bool verbose )
{
// Check that the top-level names of the two parameter lists are the same
//const std::string ¶mListName1 = list1.name();
//const std::string ¶mListName2 = list2.name();
//if ( paramListName1 != paramListName2 ) {
// return false;
//}
Teuchos::ParameterList::ConstIterator itr1, itr2;
Teuchos::Array<std::string> arr1, arr2;
for(itr1 = list1.begin(); itr1 != list1.end(); ++itr1){
arr1.push_back(list1.name(itr1));
}
for(itr2 = list2.begin(); itr2 != list2.end(); ++itr2){
arr2.push_back(list2.name(itr2));
}
std::sort(arr1.begin(), arr1.end());
std::sort(arr2.begin(), arr2.end());
Teuchos::Array<std::string>::iterator iarr1, iarr2;
for(
iarr1 = arr1.begin(), iarr2 = arr2.begin();
iarr1 != arr1.end() && iarr2 != arr2.end();
++iarr1, ++iarr2
)
{
const std::string &entryName1 = *iarr1;
const std::string &entryName2 = *iarr2;
const Teuchos::ParameterEntry &entry1 = list1.getEntry(entryName1);
const Teuchos::ParameterEntry &entry2 = list2.getEntry(entryName2);
if( entryName1 != entryName2 ) {
if (verbose) std::cerr << "entryName1 \"" << entryName1 << "\" != entryName2 \"" << entryName2 << "\"\n";
return false;
}
if( entry1.isList() && entry2.isList() ) {
if (
!foo::haveSameValues(
Teuchos::getValue<Teuchos::ParameterList>(entry1),
Teuchos::getValue<Teuchos::ParameterList>(entry2),
verbose)
)
{
// Note: Above we cast to a non-const ParameterList even through we
// only need a const ParameterList. We have to do this since a
// non-const ParameterList is always added initially which determines
// the value.
if (verbose) std::cerr << "sublists \"" << entryName1 << "\" differ\n";
return false;
}
}
else {
if( entry1.getAny() != entry2.getAny() ) {
if (verbose) std::cerr << "for key \"" << entryName1 << "\", value \"" << entry1.getAny() << "\" != \"" << entry2.getAny() << "\"\n";
return false;
}
}
}
// Check that the two parameter lists are the same length:
if (arr1.size() != arr2.size()) {
if (verbose) std::cerr << "lists are not the same size\n";
return false;
}
return true;
}
Steps to Reproduce
The following two lists should have the same values even though they aren't sorted:
ParameterList MyList1;
MyList1.set ("Max Iters", 1550, "Maximum number of iterations in the solver");
MyList1.set ("Tolerance", 1e-10, "The tolerance used for the convergence check");
MyList1.print();
std::cout << std::endl;
ParameterList MyList2;
MyList2.set ("Tolerance", 1e-10, "The tolerance used for the convergence check");
MyList2.set ("Max Iters", 1550, "Maximum number of iterations in the solver");
MyList2.print();
std::cout << std::endl;
std::cout << foo::haveSameValues(MyList1, MyList2, true) << std::endl;
Your Environment
- Relevant repo SHA1s:
- Relevant configure flags or configure script:
- Operating system and version:
- Compiler and TPL versions:
Related Issues
- Blocks
- Is blocked by
- Follows
- Precedes
- Related to
- Part of
- Composed of