Line data Source code
1 : #include "testHelpers.h"
2 :
3 : namespace elsa
4 : {
5 : namespace detail
6 : {
7 : template <typename First, typename Second>
8 0 : bool isCwiseApproxImpl(const First& x, const Second& y)
9 : {
10 0 : for (index_t i = 0; i < x.getSize(); ++i) {
11 0 : INFO("DataHandler is different as pos ", i);
12 0 : auto eq = approxEq(x[i], y[i]);
13 0 : if (!eq)
14 0 : return false;
15 : }
16 :
17 0 : return true;
18 : }
19 :
20 : template <typename data_t, typename First, typename Second, typename Third>
21 0 : bool isApproxImpl(const First& x, const Second& y, Third& z, real_t prec)
22 : {
23 0 : z -= y;
24 :
25 : if constexpr (std::is_same_v<data_t, index_t>) {
26 0 : auto lhs = z.l2Norm();
27 0 : auto rhs = std::min(x.l2Norm(), y.l2Norm());
28 0 : return lhs == rhs;
29 : } else {
30 0 : auto lhs = z.l2Norm();
31 0 : auto rhs = prec * std::min(x.l2Norm(), y.l2Norm());
32 0 : return lhs <= rhs;
33 : }
34 : }
35 : } // namespace detail
36 :
37 : template <typename data_t>
38 0 : bool isCwiseApprox(const DataHandler<data_t>& x, const Vector_t<data_t>& y)
39 : {
40 0 : CHECK_EQ(x.getSize(), y.size());
41 :
42 0 : return detail::isCwiseApproxImpl(x, y);
43 : }
44 :
45 : template <typename data_t>
46 0 : bool isCwiseApprox(const DataHandler<data_t>& x, const DataHandler<data_t>& y)
47 : {
48 0 : CHECK_EQ(x.getSize(), y.getSize());
49 :
50 0 : return detail::isCwiseApproxImpl(x, y);
51 : }
52 :
53 : template <typename data_t>
54 0 : bool isCwiseApprox(const DataContainer<data_t>& x, const Vector_t<data_t>& y)
55 : {
56 0 : CHECK_EQ(x.getSize(), y.size());
57 :
58 0 : return detail::isCwiseApproxImpl(x, y);
59 : }
60 :
61 : template <typename data_t>
62 0 : bool isCwiseApprox(const DataContainer<data_t>& x, const DataContainer<data_t>& y)
63 : {
64 0 : CHECK_EQ(x.getSize(), y.getSize());
65 :
66 0 : return detail::isCwiseApproxImpl(x, y);
67 : }
68 :
69 : template <typename data_t>
70 0 : bool isApprox(const DataContainer<data_t>& x, const DataContainer<data_t>& y, real_t prec)
71 : {
72 : // check if size is the same, but do not throw an exception
73 0 : REQUIRE_EQ(x.getSize(), y.getSize());
74 :
75 0 : DataContainer<data_t> z = x;
76 :
77 0 : return detail::isApproxImpl<data_t>(x, y, z, prec);
78 0 : }
79 :
80 : template <typename data_t>
81 0 : bool isApprox(const DataContainer<data_t>& x, const Vector_t<data_t>& y, real_t prec)
82 : {
83 : // check if size is the same, but do not throw an exception
84 0 : REQUIRE_EQ(x.getSize(), y.size());
85 :
86 0 : DataContainer<data_t> z = x;
87 0 : DataContainer<data_t> yDc(x.getDataDescriptor(), y);
88 :
89 0 : return detail::isApproxImpl<data_t>(x, yDc, z, prec);
90 0 : }
91 :
92 : // template <typename data_t>
93 : // bool isApprox(const DataHandler<data_t>& x, const Eigen::Matrix<data_t, Eigen::Dynamic, 1>&
94 : // y,
95 : // real_t prec)
96 : // {
97 : // // check if size is the same, but do not throw an exception
98 : // REQUIRE_EQ(x.getSize(), y.size());
99 :
100 : // auto z = x.clone();
101 :
102 : // return detail::isApproxImpl<data_t>(x, y, *z, prec);
103 : // }
104 :
105 : template <typename data_t>
106 0 : bool isApprox(const DataHandler<data_t>& x, const DataHandler<data_t>& y, real_t prec)
107 : {
108 : // check if size is the same, but do not throw an exception
109 0 : REQUIRE_EQ(x.getSize(), y.getSize());
110 :
111 0 : auto z = x.clone();
112 :
113 0 : return detail::isApproxImpl<data_t>(x, y, *z, prec);
114 0 : }
115 :
116 0 : doctest::Approx operator"" _a(long double val)
117 : {
118 0 : return doctest::Approx(static_cast<double>(val));
119 : }
120 :
121 0 : doctest::Approx operator"" _a(unsigned long long val)
122 : {
123 0 : return doctest::Approx(static_cast<double>(val));
124 : }
125 :
126 : // ------------------------------------------
127 : // explicit template instantiation
128 : template bool isCwiseApprox(const DataContainer<index_t>& c, const DataContainer<index_t>& y);
129 : template bool isCwiseApprox(const DataContainer<float>& c, const DataContainer<float>& y);
130 : template bool isCwiseApprox(const DataContainer<double>& c, const DataContainer<double>& y);
131 : template bool isCwiseApprox(const DataContainer<complex<float>>& c,
132 : const DataContainer<complex<float>>& y);
133 : template bool isCwiseApprox(const DataContainer<complex<double>>& c,
134 : const DataContainer<complex<double>>& y);
135 :
136 : template bool isCwiseApprox(const DataContainer<index_t>& c, const Vector_t<index_t>& y);
137 : template bool isCwiseApprox(const DataContainer<float>& c, const Vector_t<float>& y);
138 : template bool isCwiseApprox(const DataContainer<double>& c, const Vector_t<double>& y);
139 : template bool isCwiseApprox(const DataContainer<complex<float>>& c,
140 : const Vector_t<complex<float>>& y);
141 : template bool isCwiseApprox(const DataContainer<complex<double>>& c,
142 : const Vector_t<complex<double>>& y);
143 :
144 : template bool isCwiseApprox(const DataHandler<index_t>& c, const DataHandler<index_t>& y);
145 : template bool isCwiseApprox(const DataHandler<float>& c, const DataHandler<float>& y);
146 : template bool isCwiseApprox(const DataHandler<double>& c, const DataHandler<double>& y);
147 : template bool isCwiseApprox(const DataHandler<complex<float>>& c,
148 : const DataHandler<complex<float>>& y);
149 : template bool isCwiseApprox(const DataHandler<complex<double>>& c,
150 : const DataHandler<complex<double>>& y);
151 :
152 : template bool isCwiseApprox(const DataHandler<index_t>& c, const Vector_t<index_t>& y);
153 : template bool isCwiseApprox(const DataHandler<float>& c, const Vector_t<float>& y);
154 : template bool isCwiseApprox(const DataHandler<double>& c, const Vector_t<double>& y);
155 : template bool isCwiseApprox(const DataHandler<complex<float>>& c,
156 : const Vector_t<complex<float>>& y);
157 : template bool isCwiseApprox(const DataHandler<complex<double>>& c,
158 : const Vector_t<complex<double>>& y);
159 :
160 : template bool isApprox(const DataContainer<index_t>& x, const DataContainer<index_t>& y,
161 : real_t prec);
162 : template bool isApprox(const DataContainer<float>& x, const DataContainer<float>& y,
163 : real_t prec);
164 : template bool isApprox(const DataContainer<double>& x, const DataContainer<double>& y,
165 : real_t prec);
166 : template bool isApprox(const DataContainer<complex<float>>& x,
167 : const DataContainer<complex<float>>& y, real_t prec);
168 : template bool isApprox(const DataContainer<complex<double>>& x,
169 : const DataContainer<complex<double>>& y, real_t prec);
170 :
171 : template bool isApprox(const DataContainer<index_t>& x, const Vector_t<index_t>& y,
172 : real_t prec);
173 : template bool isApprox(const DataContainer<float>& x, const Vector_t<float>& y, real_t prec);
174 : template bool isApprox(const DataContainer<double>& x, const Vector_t<double>& y, real_t prec);
175 : template bool isApprox(const DataContainer<complex<float>>& x,
176 : const Vector_t<complex<float>>& y, real_t prec);
177 : template bool isApprox(const DataContainer<complex<double>>& x,
178 : const Vector_t<complex<double>>& y, real_t prec);
179 :
180 : template bool isApprox(const DataHandler<index_t>& x, const DataHandler<index_t>& y,
181 : real_t prec);
182 : template bool isApprox(const DataHandler<float>& x, const DataHandler<float>& y, real_t prec);
183 : template bool isApprox(const DataHandler<double>& x, const DataHandler<double>& y, real_t prec);
184 : template bool isApprox(const DataHandler<complex<float>>& x,
185 : const DataHandler<complex<float>>& y, real_t prec);
186 : template bool isApprox(const DataHandler<complex<double>>& x,
187 : const DataHandler<complex<double>>& y, real_t prec);
188 : } // namespace elsa
|