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: 2024-05-16 04:22:26 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         117 :             {
      18         117 :                 using data_t = std::common_type_t<T, U>;
      19         117 :                 return thrust::max(static_cast<data_t>(lhs), static_cast<data_t>(rhs));
      20         117 :             }
      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         104 :             {
      27         104 :                 using data_t = std::common_type_t<T, U>;
      28         104 :                 return thrust::max(static_cast<data_t>(elsa::abs(lhs)), static_cast<data_t>(rhs));
      29         104 :             }
      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         100 :             {
      36         100 :                 using data_t = std::common_type_t<T, U>;
      37         100 :                 return thrust::max(static_cast<data_t>(lhs), static_cast<data_t>(elsa::abs(rhs)));
      38         100 :             }
      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         111 :             {
      45         111 :                 using data_t = std::common_type_t<T, U>;
      46         111 :                 return thrust::max(static_cast<data_t>(elsa::abs(lhs)),
      47         111 :                                    static_cast<data_t>(elsa::abs(rhs)));
      48         111 :             }
      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          69 :             {
      93          69 :                 using data_t = std::common_type_t<T, U>;
      94          69 :                 return thrust::less{}(lhs, rhs) ? static_cast<data_t>(lhs)
      95          69 :                                                 : static_cast<data_t>(rhs);
      96          69 :             }
      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          26 :             {
     103          26 :                 using data_t = std::common_type_t<T, U>;
     104          26 :                 return thrust::less{}(static_cast<data_t>(elsa::abs(lhs)),
     105          26 :                                       static_cast<data_t>(elsa::abs(rhs)))
     106          26 :                            ? lhs
     107          26 :                            : rhs;
     108          26 :             }
     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       10743 :             {
     116       10743 :                 using data_t = std::common_type_t<T, U>;
     117       10743 :                 return thrust::greater{}(lhs, rhs) ? static_cast<data_t>(lhs)
     118       10743 :                                                    : static_cast<data_t>(rhs);
     119       10743 :             }
     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         566 :             {
     126         566 :                 using data_t = std::common_type_t<T, U>;
     127         566 :                 return thrust::greater{}(static_cast<data_t>(elsa::abs(lhs)),
     128         566 :                                          static_cast<data_t>(elsa::abs(rhs)))
     129         615 :                            ? lhs
     130 >1844*10^16 :                            : rhs;
     131         566 :             }
     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          95 :             {
     141          95 :                 return TernaryLess{}(val, scalar_);
     142          95 :             }
     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       11293 :             {
     152       11293 :                 return TernaryGreater{}(val, scalar_);
     153       11293 :             }
     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