ACTS
Experiment-independent tracking
Loading...
Searching...
No Matches
vc_aos_approximately_equal.hpp
1// This file is part of the ACTS project.
2//
3// Copyright (C) 2016 CERN for the benefit of the ACTS project
4//
5// This Source Code Form is subject to the terms of the Mozilla Public
6// License, v. 2.0. If a copy of the MPL was not distributed with this
7// file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9#pragma once
10
11// Project include(s)
12#include "detray/algebra/concepts.hpp"
13#include "detray/definitions/detail/qualifiers.hpp"
14
15// Vc include(s).
16#ifdef _MSC_VER
17#pragma warning(push, 0)
18#endif // MSVC
19#include <Vc/Vc>
20#ifdef _MSC_VER
21#pragma warning(pop)
22#endif // MSVC
23
24// System include(s)
25#include <concepts>
26#include <limits>
27
28namespace detray::algebra {
29
43template <typename simd1_t, typename simd2_t>
44 requires((Vc::is_simd_vector<simd1_t>::value &&
45 std::convertible_to<simd2_t, simd1_t>) ||
46 (Vc::is_simd_vector<simd2_t>::value &&
47 std::convertible_to<simd1_t, simd2_t>))
48DETRAY_HOST_DEVICE constexpr auto approx_equal(
49 const simd1_t a, const simd2_t b,
50 const typename simd1_t::value_type rel_error =
51 16.f * std::numeric_limits<typename simd1_t::value_type>::epsilon(),
52 const typename simd1_t::value_type max_error =
53 std::numeric_limits<typename simd1_t::value_type>::epsilon()) {
54 static_assert(
55 std::same_as<typename simd1_t::value_type, typename simd2_t::value_type>);
56
57 if constexpr (std::integral<typename simd1_t::value_type>) {
58 return (a == b).isFull();
59 } else {
60 // Calculate the difference.
61 const simd1_t diff{Vc::abs(a - b)};
62
63 // If the numbers are is close to zero
64 if ((diff <= simd1_t(max_error)).isFull()) {
65 return true;
66 }
67
68 // Find the largest entries and scale the epsilon
69 const simd1_t largest = Vc::max(Vc::abs(a), Vc::abs(b));
70
71 return (diff <= (largest * rel_error)).isFull();
72 }
73}
74
75} // namespace detray::algebra