GCC Code Coverage Report


Directory: include/polyfloat/
File: include/polyfloat/module/math/logspace_add.hpp
Date: 2026-11-09 15:28:50
Exec Total Coverage
Lines: 17 17 100.0%
Functions: 80 80 100.0%
Branches: 12 12 100.0%

Line Branch Exec Source
1 //======================================================================================================================
2 /*
3 POLYFLOAT - Extended precision floating points
4 Copyright : POLYFLOAT Contributors & Maintainers
5 SPDX-License-Identifier: BSL-1.0
6 */
7 //======================================================================================================================
8 #pragma once
9
10 #include <polyfloat/details/callable.hpp>
11 #include <polyfloat/types/concepts.hpp>
12 #include <polyfloat/types/traits.hpp>
13 #include <type_traits>
14 #include <polyfloat/module/math/pow_abs.hpp>
15
16 namespace plf
17 {
18
19 template<typename Options>
20 struct logspace_add_t : eve::strict_tuple_callable<logspace_add_t, Options, raw_option, pedantic_option>
21 {
22 template<typename... Ts> struct result : as_polyfloat_like<Ts...>
23 {
24 };
25
26 template<concepts::polyfloat_like... Ts>
27 requires(eve::same_lanes_or_scalar<Ts...>)
28 134 POLYFLOAT_ABI typename result<Ts...>::type constexpr operator()(Ts... ts) const noexcept
29 {
30 134 return POLYFLOAT_CALL(ts...);
31 }
32
33 template<eve::non_empty_product_type Tup>
34 requires(eve::same_lanes_or_scalar_tuple<Tup> && !concepts::polyfloat_like<Tup>)
35 POLYFLOAT_ABI constexpr kumi::apply_traits_t<result, Tup> operator()(Tup const& t) const noexcept
36 requires(kumi::size_v<Tup> >= 1)
37 {
38 return POLYFLOAT_CALL(t);
39 }
40
41 134 POLYFLOAT_CALLABLE_OBJECT(logspace_add_t, logspace_add_);
42 };
43 //======================================================================================================================
44 //! @addtogroup math
45 //! @{
46 //! @var logspace_add
47 //! @brief object computing the logspace_add operation: \f$\log\left(\sum_{i = 0}^n e^{\log x_i}\right)\f$
48 //!
49 //! @groupheader{Header file}
50 //!
51 //! @code
52 //! #include <polyfloat/core.hpp>
53 //! @endcode
54 //!
55 //! @groupheader{Callable Signatures}
56 //!
57 //! @code
58 //! namespace polyfloat
59 //! {
60 //! template<polyfloat::concepts::polyfloat_like Z, polyfloat_like ... Zs> constexpr auto logspace_add(Z z, Zs... zs) noexcept;
61 //! }
62 //! @endcode
63 //!
64 //! **Parameters**
65 //!
66 //! * `z, zs...`: Values to process.
67 //!
68 //! **Return value**
69 //!
70 //! Returns the sum of the arguments.
71 //!
72 //! @groupheader{Example}
73 //!
74 //! @godbolt{doc/math/logspace_add.cpp}
75 //======================================================================================================================
76
77 inline constexpr auto logspace_add = eve::functor<logspace_add_t>;
78 //======================================================================================================================
79 //! @}
80 //======================================================================================================================
81 }
82
83 namespace plf::_
84 {
85 template<typename T0, eve::callable_options O>
86 constexpr auto logspace_add_(POLYFLOAT_DELAY(), O const&, T0 t0) noexcept
87 {
88 return plf::abs(t0);
89 }
90
91 template<typename T0, typename T1, typename... Ts, eve::callable_options O>
92 134 constexpr auto logspace_add_(POLYFLOAT_DELAY(), O const& o, T0 const& t0, T1 const& t1, Ts... ts) noexcept
93 {
94 using r_t = as_polyfloat_like_t<T0, T1, Ts...>;
95 using e_t = eve::element_type_t<r_t>;
96 92 auto cvt = [](auto a) { return plf::convert(a, eve::as<e_t>()); };
97 if constexpr (sizeof...(Ts) == 0)
98 {
99 92 auto r0 = cvt(t0);
100 92 auto r1 = cvt(t1);
101 92 auto tmp = -plf::abs(r0 - r1);
102 92 auto r = plf::max(r0, r1) + plf::log[o](inc(plf::exp[o](tmp)));
103 92 if constexpr (eve::platform::supports_invalids) r = plf::if_else(plf::is_nan(tmp), r0 + r1, r);
104 92 return r;
105 }
106 else
107 {
108 42 r_t that(logspace_add[o](t0, t1));
109 21 auto ladd = [o](auto that_, auto next) -> r_t {
110
12/12
✓ Branch 1 taken 2 times.
✓ Branch 5 taken 1 times.
✓ Branch 9 taken 3 times.
✓ Branch 13 taken 1 times.
✓ Branch 17 taken 1 times.
✓ Branch 21 taken 3 times.
✓ Branch 25 taken 1 times.
✓ Branch 29 taken 1 times.
✓ Branch 33 taken 3 times.
✓ Branch 37 taken 1 times.
✓ Branch 41 taken 1 times.
✓ Branch 45 taken 3 times.
21 that_ = logspace_add[o](that_, next);
111 21 return that_;
112 };
113 42 ((that = ladd(that, ts)), ...);
114 42 return that;
115 }
116 }
117 }
118