MCPcopy Create free account
hub / github.com/avaxman/Directional / float_pow_test_impl

Function float_pow_test_impl

external/eigen/test/array_cwise.cpp:241–300  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

239
240template <typename Base, typename Exponent>
241void float_pow_test_impl() {
242 const Base tol = test_precision<Base>();
243 std::vector<Base> abs_base_vals = special_values<Base>();
244 std::vector<Exponent> abs_exponent_vals = special_values<Exponent>();
245 for (int i = 0; i < 100; i++) {
246 abs_base_vals.push_back(internal::random<Base>(Base(0), Base(10)));
247 abs_exponent_vals.push_back(internal::random<Exponent>(Exponent(0), Exponent(10)));
248 }
249 const Index num_repeats = internal::packet_traits<Base>::size + 1;
250 ArrayX<Base> bases(num_repeats), eigenPow(num_repeats);
251 bool all_pass = true;
252 for (Base abs_base : abs_base_vals)
253 for (Base base : {negative_or_zero(abs_base), abs_base}) {
254 bases.setConstant(base);
255 for (Exponent abs_exponent : abs_exponent_vals) {
256 for (Exponent exponent : {negative_or_zero(abs_exponent), abs_exponent}) {
257 eigenPow = bases.pow(exponent);
258 for (Index j = 0; j < num_repeats; j++) {
259 Base e = ref_pow<Base, Exponent>::run(bases(j), exponent);
260 if (is_integer(exponent)) {
261 // std::pow may return an incorrect result for a very large integral exponent
262 // if base is negative and the exponent is odd, then the result must be negative
263 // if std::pow returns otherwise, flip the sign
264 bool exp_is_odd = is_odd(exponent);
265 bool base_is_neg = !(numext::isnan)(base) && (bool)numext::signbit(base);
266 bool result_is_neg = exp_is_odd && base_is_neg;
267 bool ref_is_neg = !(numext::isnan)(e) && (bool)numext::signbit(e);
268 bool flip_sign = result_is_neg != ref_is_neg;
269 if (flip_sign) e = -e;
270 }
271
272 Base a = eigenPow(j);
273 #ifdef EIGEN_COMP_MSVC
274 // Work around MSVC return value on underflow.
275 // if std::pow returns 0 and Eigen returns a denormalized value, then skip the test
276 int eigen_fpclass = std::fpclassify(a);
277 if (e == Base(0) && eigen_fpclass == FP_SUBNORMAL) continue;
278 #endif
279
280 #ifdef EIGEN_VECTORIZE_NEON
281 // Work around NEON flush-to-zero mode
282 // if std::pow returns denormalized value and Eigen returns 0, then skip the test
283 int ref_fpclass = std::fpclassify(e);
284 if (a == Base(0) && ref_fpclass == FP_SUBNORMAL) continue;
285 #endif
286
287 bool both_nan = (numext::isnan)(a) && (numext::isnan)(e);
288 bool exact_or_approx = (a == e) || internal::isApprox(a, e, tol);
289 bool same_sign = (bool)numext::signbit(e) == (bool)numext::signbit(a);
290 bool success = both_nan || (exact_or_approx && same_sign);
291 all_pass &= success;
292 if (!success) {
293 std::cout << "pow(" << bases(j) << "," << exponent << ") = " << a << " != " << e << std::endl;
294 }
295 }
296 }
297 }
298 }

Callers

nothing calls this directly

Calls 7

negative_or_zeroFunction · 0.85
is_integerFunction · 0.85
is_oddFunction · 0.85
signbitFunction · 0.85
powMethod · 0.80
runFunction · 0.70
isApproxFunction · 0.50

Tested by

no test coverage detected