LCOV - code coverage report
Current view: top level - core/include/scipp/core/element - util.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 39 42 92.9 %
Date: 2024-04-28 01:25:40 Functions: 42 82 51.2 %

          Line data    Source code
       1             : // SPDX-License-Identifier: BSD-3-Clause
       2             : // Copyright (c) 2023 Scipp contributors (https://github.com/scipp)
       3             : /// @file
       4             : /// @author Simon Heybrock
       5             : #pragma once
       6             : 
       7             : #include <cstddef>
       8             : 
       9             : #include "scipp/common/numeric.h"
      10             : #include "scipp/common/overloaded.h"
      11             : #include "scipp/core/eigen.h"
      12             : #include "scipp/core/element/arg_list.h"
      13             : #include "scipp/core/subbin_sizes.h"
      14             : #include "scipp/core/time_point.h"
      15             : #include "scipp/core/transform_common.h"
      16             : #include "scipp/core/value_and_variance.h"
      17             : #include "scipp/units/except.h"
      18             : #include "scipp/units/unit.h"
      19             : 
      20             : namespace scipp::core::element {
      21             : 
      22             : /// Set the elements referenced by a span to 0
      23       54594 : template <class T> void zero(const scipp::span<T> &data) {
      24      189643 :   for (auto &x : data)
      25      135049 :     x = 0.0;
      26       54594 : }
      27             : 
      28             : /// Set the elements references by the spans for values and variances to 0
      29             : template <class T>
      30         124 : void zero(const core::ValueAndVariance<scipp::span<T>> &data) {
      31         124 :   zero(data.value);
      32         124 :   zero(data.variance);
      33         124 : }
      34             : 
      35             : constexpr auto values = overloaded{
      36             :     transform_flags::no_out_variance, transform_flags::force_variance_broadcast,
      37        1481 :     core::element::arg_list<double, float>, [](const auto &x) {
      38             :       if constexpr (is_ValueAndVariance_v<std::decay_t<decltype(x)>>)
      39        1194 :         return x.value;
      40             :       else
      41         287 :         return x;
      42             :     }};
      43             : 
      44             : constexpr auto variances =
      45             :     overloaded{transform_flags::no_out_variance,
      46             :                core::element::arg_list<double, float>,
      47             :                transform_flags::expect_variance_arg<0>,
      48             :                transform_flags::force_variance_broadcast,
      49          17 :                [](const auto &x) {
      50             :                  if constexpr (is_ValueAndVariance_v<std::decay_t<decltype(x)>>)
      51          17 :                    return x.variance;
      52             :                  else
      53           0 :                    return x; // unreachable but required for instantiation
      54             :                },
      55          13 :                [](const units::Unit &u) { return u * u; }};
      56             : 
      57             : constexpr auto stddevs =
      58             :     overloaded{transform_flags::no_out_variance,
      59             :                core::element::arg_list<double, float>,
      60             :                transform_flags::expect_variance_arg<0>,
      61             :                transform_flags::force_variance_broadcast,
      62        1009 :                [](const auto &x) {
      63             :                  using std::sqrt;
      64             :                  if constexpr (is_ValueAndVariance_v<std::decay_t<decltype(x)>>)
      65        1009 :                    return sqrt(x.variance);
      66             :                  else
      67           0 :                    return sqrt(x); // unreachable but required for instantiation
      68             :                },
      69         103 :                [](const units::Unit &u) { return u; }};
      70             : 
      71             : constexpr auto issorted_common = overloaded{
      72             :     core::element::arg_list<
      73             :         std::tuple<bool, double, double>, std::tuple<bool, float, float>,
      74             :         std::tuple<bool, int64_t, int64_t>, std::tuple<bool, int32_t, int32_t>,
      75             :         std::tuple<bool, std::string, std::string>,
      76             :         std::tuple<bool, time_point, time_point>>,
      77             :     transform_flags::expect_no_variance_arg<1>,
      78             :     [](units::Unit &out, const units::Unit &left, const units::Unit &right) {
      79             :       core::expect::equals(left, right);
      80             :       out = units::none;
      81             :     }};
      82             : 
      83             : constexpr auto issorted_nondescending = overloaded{
      84      463155 :     issorted_common, [](bool &out, const auto &left, const auto &right) {
      85      463155 :       out = out && (left <= right);
      86      463155 :     }};
      87             : 
      88             : constexpr auto issorted_nonascending = overloaded{
      89        1603 :     issorted_common, [](bool &out, const auto &left, const auto &right) {
      90        1603 :       out = out && (left >= right);
      91        1603 :     }};
      92             : 
      93             : constexpr auto islinspace =
      94             :     overloaded{arg_list<scipp::span<const double>, scipp::span<const float>,
      95             :                         scipp::span<const int64_t>, scipp::span<const int32_t>,
      96             :                         scipp::span<const time_point>>,
      97             :                transform_flags::expect_no_variance_arg<0>,
      98        9686 :                [](const units::Unit &) { return units::one; },
      99        9711 :                [](const auto &range) { return numeric::islinspace(range); }};
     100             : 
     101             : constexpr auto isarange =
     102             :     overloaded{arg_list<scipp::span<const int64_t>, scipp::span<const int32_t>>,
     103             :                transform_flags::expect_no_variance_arg<0>,
     104        4831 :                [](const units::Unit &) { return units::one; },
     105        4831 :                [](const auto &range) { return numeric::isarange(range); }};
     106             : 
     107             : constexpr auto zip =
     108             :     overloaded{arg_list<int64_t>, transform_flags::expect_no_variance_arg<0>,
     109             :                transform_flags::expect_no_variance_arg<1>,
     110      248921 :                [](const units::Unit &first, const units::Unit &second) {
     111      248921 :                  expect::equals(first, second);
     112      248921 :                  return first;
     113             :                },
     114    18792787 :                [](const auto first, const auto second) {
     115    18792787 :                  return std::pair{first, second};
     116             :                }};
     117             : 
     118             : template <int N>
     119             : constexpr auto get = overloaded{arg_list<std::pair<scipp::index, scipp::index>>,
     120             :                                 transform_flags::expect_no_variance_arg<0>,
     121             :                                 [](const auto &x) { return std::get<N>(x); },
     122             :                                 [](const units::Unit &u) { return u; }};
     123             : 
     124             : constexpr auto fill =
     125             :     overloaded{arg_list<double, float, std::tuple<float, double>>,
     126           0 :                [](auto &x, const auto &value) { x = value; }};
     127             : 
     128             : constexpr auto fill_zeros =
     129             :     overloaded{arg_list<double, float, int64_t, int32_t, SubbinSizes>,
     130      107680 :                [](units::Unit &) {}, [](auto &x) { x = 0; }};
     131             : 
     132             : template <class... Ts>
     133             : constexpr arg_list_t<std::tuple<bool, Ts, Ts>...> where_arg_list{};
     134             : 
     135             : constexpr auto where = overloaded{
     136             :     where_arg_list<double, float, int64_t, int32_t, bool, core::time_point,
     137             :                    index_pair, std::string, Eigen::Vector3d, Eigen::Matrix3d,
     138             :                    Eigen::Affine3d, core::Quaternion, core::Translation>,
     139             :     transform_flags::force_variance_broadcast,
     140       91411 :     [](const auto &condition, const auto &x, const auto &y) {
     141       91411 :       return condition ? x : y;
     142             :     },
     143        2476 :     [](const units::Unit &condition, const units::Unit &x,
     144             :        const units::Unit &y) {
     145        2476 :       expect::equals(units::none, condition);
     146        2476 :       expect::equals(x, y);
     147        2476 :       return x;
     148             :     }};
     149             : 
     150             : } // namespace scipp::core::element

Generated by: LCOV version 1.14