1 /*
2  * Copyright (C) 1998-2018 ALPS Collaboration. See COPYRIGHT.TXT
3  * All rights reserved. Use is subject to license terms. See LICENSE.TXT
4  * For use in publications, see ACKNOWLEDGE.TXT
5  */
6 
7 #ifndef ALPS_UTILITIES_TEST_VECTOR_COMPARISON_PREDICATES_HPP
8 #define ALPS_UTILITIES_TEST_VECTOR_COMPARISON_PREDICATES_HPP
9 
10 #include <vector>
11 #include <algorithm> /* for std::max() */
12 #include "gtest/gtest.h"
13 
14 namespace alps {
15     namespace testing {
16 
17         template <typename T>
is_near(T v1,T v2,double tol=1E-10)18         ::testing::AssertionResult is_near(T v1, T v2, double tol=1E-10) {
19             if (std::fabs(v1-v2)<tol) {
20                 return ::testing::AssertionSuccess() << v1 << " almost equals " << v2 << " with tolerance " << tol;
21             } else {
22                 return ::testing::AssertionFailure() << v1 << " not equal " << v2 << " with tolerance " << tol;
23             }
24         }
25 
26         template <typename T>
is_rel_near(T v1,T v2,double tol=1E-10)27         ::testing::AssertionResult is_rel_near(T v1, T v2, double tol=1E-10) {
28 	    T vmax=std::max(std::fabs(v1),std::fabs(v2));
29             if (v1==v2 || std::fabs(v1-v2)/vmax < tol) {
30                 return ::testing::AssertionSuccess() << v1 << " almost equals " << v2 << " with relative tolerance " << tol;
31             } else {
32                 return ::testing::AssertionFailure() << v1 << " not equal " << v2 << " with relative tolerance " << tol;
33             }
34         }
35 
36         template <typename T>
is_near(const std::vector<T> & v1,const std::vector<T> & v2,double tol=1E-10)37         ::testing::AssertionResult is_near(const std::vector<T>& v1, const std::vector<T>& v2, double tol=1E-10) {
38             std::size_t sz1=v1.size(), sz2=v2.size();
39             if (sz2!=sz1) {
40                 return ::testing::AssertionFailure() << "sizes differ: left=" << sz1 << " right=" << sz2;
41             }
42             for (std::size_t i=0; i<sz1; ++i) {
43                 ::testing::AssertionResult res=is_near(v1[i], v2[i], tol);
44                 if (!res) {
45                     res << "; content differs at #" << i;
46                     return res;
47                 }
48             }
49             return ::testing::AssertionSuccess() << "vectors are (almost) equal";
50         }
51 
52         template <typename T>
is_rel_near(const std::vector<T> & v1,const std::vector<T> & v2,double tol=1E-10)53         ::testing::AssertionResult is_rel_near(const std::vector<T>& v1, const std::vector<T>& v2, double tol=1E-10) {
54             std::size_t sz1=v1.size(), sz2=v2.size();
55             if (sz2!=sz1) {
56                 return ::testing::AssertionFailure() << "sizes differ: left=" << sz1 << " right=" << sz2;
57             }
58             for (std::size_t i=0; i<sz1; ++i) {
59                 ::testing::AssertionResult res=is_rel_near(v1[i], v2[i], tol);
60                 if (!res) {
61                     res << "; content differs at #" << i;
62                     return res;
63                 }
64             }
65             return ::testing::AssertionSuccess() << "vectors are (almost) equal within the tolerance " << tol;
66         }
67     } // testing::
68 } // alps::
69 
70 #endif /* ALPS_UTILITIES_TEST_VECTOR_COMPARISON_PREDICATES_HPP */
71