ATLAS Offline Software
ap_fixedTest.cxx
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2024 CERN for the benefit of the ATLAS collaboration
3 */
4 
7 
8 #include "gtest/gtest.h"
9 #include "../ap_fixed.h"
10 
11 #include <sstream>
12 #include <cmath>
13 
14 // this function will be templated on the int type.
15 constexpr int pow(int base, int exp) noexcept {
16  auto result{1};
17 
18  for(int i = 0; i < exp; ++i) {
19  result *= base;
20  }
21 
22  return result;
23 }
24 
25 template<int W, int P>
26 constexpr double min() {
27  static_assert(W >= P);
28  static_assert(P >= 0);
29  return -pow(2, W-1)/pow(2, P);
30 }
31 
32 template<int W, int P>
33 constexpr double max () {
34  static_assert(W >= P);
35  static_assert(P >= 0);
36  return static_cast<double>(pow(2, W-1)-1)/static_cast<double>(pow(2, P));
37 }
38 
39 TEST (ap_fixedTester, minmax) {
40 
41  auto min_v = min<10, 5>();
42  auto max_v = max<10, 5>();
43  EXPECT_EQ(-16, min_v);
44  EXPECT_EQ(15.96875, max_v);
45 }
46 
47 TEST(ap_fixedTester, stablity) {
48 
49 
50  constexpr int width{10};
51  constexpr int prec{5};
52  double delta = pow(2, -prec-1); // step by a value less then precision
53 
54  double val = min<width, prec>();
55  double max_val = max<width, prec>();
56  double cval = -val;
57 
58  std::size_t i{0};
59 
60  while (cval <= max_val) {
61 
63  double d0 = static_cast<double>(ap_gs0);
64  auto ap_gs1 = GlobalSim::ap_fixed<10, 5>(d0);
65  double d1 = static_cast<double>(ap_gs1);
66  auto ap_gs2 = GlobalSim::ap_fixed<10, 5>(d1);
67  double d2 = static_cast<double>(ap_gs2);
68 
69  EXPECT_EQ (d2, d0);
70  EXPECT_EQ (ap_gs0.m_value, ap_gs2.m_value);
71  EXPECT_LT (std::abs(d0 -cval), 1./(2*2*2*2*2));
72 
73 
74  cval = -val + ((++i) * delta);
75  }
76 }
77 
78 TEST(ap_fixedTester, specialValue) {
79 
80  //Xylinx ap_fixed gets this wrong
81  auto apf = GlobalSim::ap_fixed<10, 5, GlobalSim::Round>(-0.327374935);
82  EXPECT_EQ (-0.3125, static_cast<double>(apf));
83  std::stringstream ss;
84  ss << std::hex << apf.m_value;
85  EXPECT_EQ ("fff6", ss.str());
86 }
87 
88 
89 
90 TEST(ap_fixedTester, overflow_h) {
91  constexpr int width{10};
92  constexpr int prec{5};
93 
96  // out of range by 0.5*prec
97  double outOfRange = max<width, prec>() + pow(2, -prec-1);
98 
99  EXPECT_THROW ((ap(outOfRange)), std::out_of_range);
100 }
101 
102 TEST(ap_fixedTester, overflow_l) {
103  constexpr int width{10};
104  constexpr int prec{5};
105 
106  // out of range by 0.5*prec
107  double outOfRange = min<width, prec>() - pow(2, -prec-1);
109 
110  EXPECT_THROW ((ap(outOfRange)), std::out_of_range);
111 }
112 
113 
114 TEST(ap_fixedTester, addition) {
115 
116  constexpr int width{10};
117  constexpr int prec{5};
118  const double eps {std::pow(2.0, -prec)};
120 
121  ap ap_sum = ap(1) + ap(2);
122  auto val = static_cast<double>(ap_sum);
123  auto diff = std::abs(val - 3);
124 
125  EXPECT_EQ (3, val);
126  EXPECT_LT (diff, eps);
127 
128  ap_sum = ap(1.5) + ap(2.5);
129  val = static_cast<double>(ap_sum);
130  diff = std::abs(val - 4);
131 
132  EXPECT_EQ (4, val);
133  EXPECT_LT (diff, eps);
134 }
135 
136 TEST(ap_fixedTester, addition1) {
137 
138  constexpr int width{10};
139  constexpr int prec{5};
140  const double eps {std::pow(2.0, -prec)};
142 
143  ap ap_sum = ap(2) += 1;
144  auto val = static_cast<double>(ap_sum);
145  auto diff = std::abs(val - 3);
146 
147  EXPECT_EQ (3, val);
148  EXPECT_LT (diff, eps);
149 
150  ap_sum = ap(1.5) += 2.5;
151  val = static_cast<double>(ap_sum);
152  diff = std::abs(val - 4);
153 
154  EXPECT_EQ (4, val);
155  EXPECT_LT (diff, eps);
156 }
157 
158 
159 TEST(ap_fixedTester, subtraction) {
160 
161  constexpr int width{10};
162  constexpr int prec{5};
163  const double eps {std::pow(2.0, -prec)};
165 
166  ap ap_diff = ap(1) - ap(2);
167  auto val = static_cast<double>(ap_diff);
168  auto diff = std::abs(val + 1);
169 
170  EXPECT_EQ (-1, val);
171  EXPECT_LT (diff, eps);
172 
173  ap_diff = ap(1.5) - ap(2.5);
174  val = static_cast<double>(ap_diff);
175  diff = std::abs(val + 1);
176 
177  EXPECT_EQ (-1, val);
178  EXPECT_LT (diff, eps);
179 }
180 
181 TEST(ap_fixedTester, subtraction1) {
182 
183  constexpr int width{10};
184  constexpr int prec{5};
185  const double eps {std::pow(2.0, -prec)};
187 
188  ap ap_diff = ap(1) -= 2;
189  auto val = static_cast<double>(ap_diff);
190  auto diff = std::abs(val + 1);
191 
192  EXPECT_EQ (-1, val);
193  EXPECT_LT (diff, eps);
194 
195  ap_diff = ap(1.5) -= 2.5;
196  val = static_cast<double>(ap_diff);
197  diff = std::abs(val + 1);
198 
199  EXPECT_EQ (-1, val);
200  EXPECT_LT (diff, eps);
201 }
202 
203 
204 
205 TEST(ap_fixedTester, multiplication) {
206 
207  constexpr int width{10};
208  constexpr int prec{5};
209  const double eps {std::pow(2.0, -prec)};
211 
212  ap ap_prod = ap(1) * ap(2);
213  auto val = static_cast<double>(ap_prod);
214  auto diff = std::abs(val - 2);
215 
216  EXPECT_EQ (2, val);
217  EXPECT_LT (diff, eps);
218 
219  ap_prod = ap(-1.5)*ap(2);
220  val = static_cast<double>(ap_prod);
221  diff = std::abs(val +3);
222 
223  EXPECT_EQ (-3, val);
224  EXPECT_LT (diff, eps);
225 }
226 
227 TEST(ap_fixedTester, multiplication1) {
228  constexpr int width{10};
229  constexpr int prec{5};
230  const double eps {std::pow(2.0, -prec)};
232 
233  ap ap_prod = ap(1) *= ap(2);
234  auto val = static_cast<double>(ap_prod);
235  auto diff = std::abs(val - 2);
236 
237  EXPECT_EQ (2, val);
238  EXPECT_LT (diff, eps);
239 
240  ap_prod = ap(-1.5) *= ap(2.);
241  val = static_cast<double>(ap_prod);
242  diff = std::abs(val +3);
243 
244  EXPECT_EQ (-3, val);
245  EXPECT_LT (diff, eps);
246 }
247 
248 
249 TEST(ap_fixedTester, division) {
250 
251  constexpr int width{10};
252  constexpr int prec{5};
253  const double eps {std::pow(2.0, -prec)};
255 
256  ap ap_div = ap(1)/ap(2);
257  auto val = static_cast<double>(ap_div);
258  auto diff = std::abs(val - 0.5);
259 
260  EXPECT_EQ (0.5, val);
261  EXPECT_LT (diff, eps);
262 
263  ap_div = ap(-1.5)/ap(2);
264  val = static_cast<double>(ap_div);
265  diff = std::abs(val + 0.75);
266 
267  EXPECT_EQ (-0.75, val);
268  EXPECT_LT (diff, eps);
269 }
270 
271 
272 TEST(ap_fixedTester, division1) {
273 
274  constexpr int width{10};
275  constexpr int prec{5};
276  const double eps {std::pow(2.0, -prec)};
278 
279  ap ap_div = ap(1)/=ap(2);
280  auto val = static_cast<double>(ap_div);
281  auto diff = std::abs(val - 0.5);
282 
283  EXPECT_EQ (0.5, val);
284  EXPECT_LT (diff, eps);
285 
286  ap_div = ap(-1.5)/ap(2);
287  val = static_cast<double>(ap_div);
288  diff = std::abs(val + 0.75);
289 
290  EXPECT_EQ (-0.75, val);
291  EXPECT_LT (diff, eps);
292 }
293 
294 
295 TEST(ap_fixedTester, negation) {
296 
297  constexpr int width{10};
298  constexpr int prec{5};
299 
301 
302  auto ap_p = ap(1);
303  auto ap_n = -ap_p;
304  auto ap_pp = -ap_n;
305 
306  auto val_p = static_cast<double>(ap_p);
307  auto val_n = static_cast<double>(ap_n);
308  auto val_pp = static_cast<double>(ap_pp);
309 
310  EXPECT_EQ (val_p, -val_n);
311  EXPECT_EQ (val_p, val_pp);
312 }
313 
314 TEST(ap_fixedTester, doubleMult) {
315 
316  constexpr int width{10};
317  constexpr int prec{5};
318 
320  ap ap_mul = 9.99 * ap(1);
321 
322  EXPECT_EQ (10, static_cast<double>(ap_mul));
323 }
324 
325 
base
std::string base
Definition: hcg.cxx:78
ATLAS_NO_CHECK_FILE_THREAD_SAFETY
ATLAS_NO_CHECK_FILE_THREAD_SAFETY
Definition: ap_fixedTest.cxx:6
get_generator_info.result
result
Definition: get_generator_info.py:21
PowhegControl_ttHplus_NLO.ss
ss
Definition: PowhegControl_ttHplus_NLO.py:83
JetTiledMap::W
@ W
Definition: TiledEtaPhiMap.h:44
max
constexpr double max()
Definition: ap_fixedTest.cxx:33
DMTest::P
P_v1 P
Definition: P.h:23
min
constexpr double min()
Definition: ap_fixedTest.cxx:26
mc.diff
diff
Definition: mc.SFGenPy8_MuMu_DD.py:14
TEST
TEST(ap_fixedTester, minmax)
Definition: ap_fixedTest.cxx:39
dq_defect_virtual_defect_validation.d1
d1
Definition: dq_defect_virtual_defect_validation.py:79
drawFromPickle.exp
exp
Definition: drawFromPickle.py:36
python.AtlRunQueryParser.ap
ap
Definition: AtlRunQueryParser.py:826
lumiFormat.i
int i
Definition: lumiFormat.py:85
GlobalSim::ap_fixed
Definition: ap_fixed.h:44
TRT::Track::d0
@ d0
Definition: InnerDetector/InDetCalibEvent/TRT_CalibData/TRT_CalibData/TrackInfo.h:62
PlotCalibFromCool.val_n
val_n
Definition: PlotCalibFromCool.py:93
Base_Fragment.width
width
Definition: Sherpa_i/share/common/Base_Fragment.py:59
Pythia8_RapidityOrderMPI.val
val
Definition: Pythia8_RapidityOrderMPI.py:14
dq_defect_virtual_defect_validation.d2
d2
Definition: dq_defect_virtual_defect_validation.py:81
jobOptions.prec
prec
Definition: jobOptions.Superchic_UPC_yyMuMu.py:20
checker_macros.h
Define macros for attributes used to control the static checker.
pow
constexpr int pow(int base, int exp) noexcept
Definition: ap_fixedTest.cxx:15