LCOV - code coverage report
Current view: top level - elsa/storage/transforms - Extrema.h (source / functions) Hit Total Coverage
Test: coverage-all.lcov Lines: 56 75 74.7 %
Date: 2025-01-15 06:42:32 Functions: 38 130 29.2 %

          Line data    Source code
       1             : #pragma once
       2             : 
       3             : #include "functions/Abs.hpp"
       4             : 
       5             : #include <thrust/transform.h>
       6             : #include <thrust/extrema.h>
       7             : #include <type_traits>
       8             : 
       9             : namespace elsa
      10             : {
      11             :     namespace detail
      12             :     {
      13             :         struct CwiseMaxFn {
      14             :             template <class T, class U>
      15             :             __host__ __device__ auto operator()(const T& lhs, const U& rhs) const noexcept
      16             :                 -> std::common_type_t<T, U>
      17         107 :             {
      18         107 :                 using data_t = std::common_type_t<T, U>;
      19         107 :                 return thrust::max(static_cast<data_t>(lhs), static_cast<data_t>(rhs));
      20         107 :             }
      21             : 
      22             :             template <class T, class U>
      23             :             __host__ __device__ auto operator()(const thrust::complex<T>& lhs,
      24             :                                                 const U& rhs) const noexcept
      25             :                 -> std::common_type_t<T, U>
      26          99 :             {
      27          99 :                 using data_t = std::common_type_t<T, U>;
      28          99 :                 return thrust::max(static_cast<data_t>(elsa::abs(lhs)), static_cast<data_t>(rhs));
      29          99 :             }
      30             : 
      31             :             template <class T, class U>
      32             :             __host__ __device__ auto operator()(const T& lhs,
      33             :                                                 const thrust::complex<U>& rhs) const noexcept
      34             :                 -> std::common_type_t<T, U>
      35          92 :             {
      36          92 :                 using data_t = std::common_type_t<T, U>;
      37          92 :                 return thrust::max(static_cast<data_t>(lhs), static_cast<data_t>(elsa::abs(rhs)));
      38          92 :             }
      39             : 
      40             :             template <class T, class U>
      41             :             __host__ __device__ auto operator()(const thrust::complex<T>& lhs,
      42             :                                                 const thrust::complex<U>& rhs) const noexcept
      43             :                 -> std::common_type_t<T, U>
      44         110 :             {
      45         110 :                 using data_t = std::common_type_t<T, U>;
      46         110 :                 return thrust::max(static_cast<data_t>(elsa::abs(lhs)),
      47         110 :                                    static_cast<data_t>(elsa::abs(rhs)));
      48         110 :             }
      49             :         };
      50             : 
      51             :         struct CwiseMinFn {
      52             :             template <class T, class U>
      53             :             __host__ __device__ auto operator()(const T& lhs, const U& rhs) const noexcept
      54             :                 -> std::common_type_t<T, U>
      55           0 :             {
      56           0 :                 using data_t = std::common_type_t<T, U>;
      57           0 :                 return thrust::min(static_cast<data_t>(lhs), static_cast<data_t>(rhs));
      58           0 :             }
      59             : 
      60             :             template <class T, class U>
      61             :             __host__ __device__ auto operator()(const thrust::complex<T>& lhs,
      62             :                                                 const U& rhs) const noexcept
      63             :                 -> std::common_type_t<T, U>
      64           0 :             {
      65           0 :                 using data_t = std::common_type_t<T, U>;
      66           0 :                 return thrust::min(static_cast<data_t>(elsa::abs(lhs)), static_cast<data_t>(rhs));
      67           0 :             }
      68             : 
      69             :             template <class T, class U>
      70             :             __host__ __device__ auto operator()(const T& lhs,
      71             :                                                 const thrust::complex<U>& rhs) const noexcept
      72             :                 -> std::common_type_t<T, U>
      73           0 :             {
      74           0 :                 using data_t = std::common_type_t<T, U>;
      75           0 :                 return thrust::min<data_t>(lhs, elsa::abs(rhs));
      76           0 :             }
      77             : 
      78             :             template <class T, class U>
      79             :             __host__ __device__ auto operator()(const thrust::complex<T>& lhs,
      80             :                                                 const thrust::complex<U>& rhs) const noexcept
      81             :                 -> std::common_type_t<T, U>
      82           0 :             {
      83           0 :                 using data_t = std::common_type_t<T, U>;
      84           0 :                 return thrust::min<data_t>(elsa::abs(lhs), elsa::abs(rhs));
      85           0 :             }
      86             :         };
      87             : 
      88             :         struct TernaryLess {
      89             :             template <class T, class U>
      90             :             __host__ __device__ auto operator()(const T& lhs, const U& rhs) const noexcept
      91             :                 -> std::common_type_t<T, U>
      92          68 :             {
      93          68 :                 using data_t = std::common_type_t<T, U>;
      94          68 :                 return thrust::less{}(lhs, rhs) ? static_cast<data_t>(lhs)
      95          68 :                                                 : static_cast<data_t>(rhs);
      96          68 :             }
      97             : 
      98             :             template <class T, class U>
      99             :             __host__ __device__ auto operator()(const thrust::complex<T>& lhs,
     100             :                                                 const thrust::complex<U>& rhs) const noexcept
     101             :                 -> thrust::complex<std::common_type_t<T, U>>
     102          32 :             {
     103          32 :                 using data_t = std::common_type_t<T, U>;
     104          32 :                 return thrust::less{}(static_cast<data_t>(elsa::abs(lhs)),
     105          32 :                                       static_cast<data_t>(elsa::abs(rhs)))
     106          32 :                            ? lhs
     107          32 :                            : rhs;
     108          32 :             }
     109             :         };
     110             : 
     111             :         struct TernaryGreater {
     112             :             template <class T, class U>
     113             :             __host__ __device__ auto operator()(const T& lhs, const U& rhs) const noexcept
     114             :                 -> std::common_type_t<T, U>
     115       11061 :             {
     116       11061 :                 using data_t = std::common_type_t<T, U>;
     117       11061 :                 return thrust::greater{}(lhs, rhs) ? static_cast<data_t>(lhs)
     118       11061 :                                                    : static_cast<data_t>(rhs);
     119       11061 :             }
     120             : 
     121             :             template <class T, class U>
     122             :             __host__ __device__ auto operator()(const thrust::complex<T>& lhs,
     123             :                                                 const thrust::complex<U>& rhs) const noexcept
     124             :                 -> thrust::complex<std::common_type_t<T, U>>
     125         647 :             {
     126         647 :                 using data_t = std::common_type_t<T, U>;
     127         647 :                 return thrust::greater{}(static_cast<data_t>(elsa::abs(lhs)),
     128         647 :                                          static_cast<data_t>(elsa::abs(rhs)))
     129         696 :                            ? lhs
     130 >1844*10^16 :                            : rhs;
     131         647 :             }
     132             :         };
     133             : 
     134             :         template <class Scalar>
     135             :         struct CwiseMinScalarFn {
     136             :             Scalar scalar_;
     137             : 
     138             :             template <class T>
     139             :             __host__ __device__ auto operator()(const T& val) const noexcept
     140         106 :             {
     141         106 :                 return TernaryLess{}(val, scalar_);
     142         106 :             }
     143             :         };
     144             : 
     145             :         template <class Scalar>
     146             :         struct CwiseMaxScalarFn {
     147             :             Scalar scalar_;
     148             : 
     149             :             template <class T>
     150             :             __host__ __device__ auto operator()(const T& val) const noexcept
     151       11746 :             {
     152       11746 :                 return TernaryGreater{}(val, scalar_);
     153       11746 :             }
     154             :         };
     155             : 
     156             :     } // namespace detail
     157             : 
     158             :     /// @brief Compute the coefficient wise maximum of two input ranges. For complex input's the
     159             :     /// absolute value of the complex number is used.
     160             :     /// @ingroup transforms
     161             :     template <class InputIter1, class InputIter2, class OutIter>
     162             :     void cwiseMax(InputIter1 xfirst, InputIter1 xlast, InputIter2 yfirst, OutIter out)
     163          20 :     {
     164          20 :         thrust::transform(xfirst, xlast, yfirst, out, detail::CwiseMaxFn{});
     165          20 :     }
     166             : 
     167             :     /// @brief Compute the coefficient wise minimum of two input ranges. For complex input's the
     168             :     /// absolute value of the complex number is used.
     169             :     /// @ingroup transforms
     170             :     template <class InputIter1, class InputIter2, class OutIter>
     171             :     void cwiseMin(InputIter1 xfirst, InputIter1 xlast, InputIter2 yfirst, OutIter out)
     172           0 :     {
     173           0 :         thrust::transform(xfirst, xlast, yfirst, out, detail::CwiseMinFn{});
     174           0 :     }
     175             : 
     176             :     /// @brief For each element in the vector set the element to the minimum of the element and the
     177             :     /// given scalar
     178             :     /// @ingroup transforms
     179             :     template <class InputIter1, class Scalar, class OutIter>
     180             :     void minimum(InputIter1 xfirst, InputIter1 xlast, Scalar scalar, OutIter out)
     181           7 :     {
     182           7 :         thrust::transform(xfirst, xlast, out, detail::CwiseMinScalarFn<Scalar>{scalar});
     183           7 :     }
     184             : 
     185             :     /// @brief For each element in the vector set the element to the maximum of the element and the
     186             :     /// given scalar
     187             :     /// @ingroup transforms
     188             :     template <class InputIter1, class Scalar, class OutIter>
     189             :     void maximum(InputIter1 xfirst, InputIter1 xlast, Scalar scalar, OutIter out)
     190         178 :     {
     191         178 :         thrust::transform(xfirst, xlast, out, detail::CwiseMaxScalarFn<Scalar>{scalar});
     192         178 :     }
     193             : } // namespace elsa

Generated by: LCOV version 1.14