NumCpp  2.11.0
A Templatized Header Only C++ Implementation of the Python NumPy Library
select.hpp
Go to the documentation of this file.
1 #pragma once
29 
30 #include <cstdlib>
31 #include <initializer_list>
32 #include <limits>
33 #include <vector>
34 
37 #include "NumCpp/Core/Shape.hpp"
38 #include "NumCpp/NdArray.hpp"
39 
40 namespace nc
41 {
42  //============================================================================
43  // Method Description:
57  template<typename dtype>
58  NdArray<dtype> select(const std::vector<const NdArray<bool>*>& condVec,
59  const std::vector<const NdArray<dtype>*>& choiceVec,
60  dtype defaultValue = dtype{ 0 })
61  {
62  if (choiceVec.size() != condVec.size())
63  {
64  THROW_INVALID_ARGUMENT_ERROR("condVec and choiceVec need to be the same size");
65  }
66 
67  if (choiceVec.size() == 0)
68  {
69  THROW_INVALID_ARGUMENT_ERROR("choiceVec is size 0");
70  }
71 
72  auto theShape = condVec.front()->shape();
73  for (const auto cond : condVec)
74  {
75  const auto& theCond = *cond;
76  if (theCond.shape() != theShape)
77  {
78  THROW_INVALID_ARGUMENT_ERROR("all NdArrays of the condVec must be the same shape");
79  }
80  }
81 
82  for (const auto choice : choiceVec)
83  {
84  const auto& theChoice = *choice;
85  if (theChoice.shape() != theShape)
86  {
88  "all NdArrays of the choiceVec must be the same shape, and the same as condVec");
89  }
90  }
91 
92  using size_type = typename NdArray<dtype>::size_type;
93  constexpr auto nullChoice = std::numeric_limits<size_type>::max();
94 
95  NdArray<size_type> choiceIndices(theShape);
96  choiceIndices.fill(nullChoice);
97  for (size_type condIdx = 0; condIdx < condVec.size(); ++condIdx)
98  {
99  const auto& theCond = *condVec[condIdx];
100  for (size_type i = 0; i < theCond.size(); ++i)
101  {
102  if (theCond[i] && choiceIndices[i] == nullChoice)
103  {
104  choiceIndices[i] = condIdx;
105  }
106  }
107  }
108 
109  NdArray<dtype> result(theShape);
110  result.fill(defaultValue);
111  for (size_type i = 0; i < choiceIndices.size(); ++i)
112  {
113  const auto choiceIndex = choiceIndices[i];
114  if (choiceIndex != nullChoice)
115  {
116  const auto& theChoice = *choiceVec[choiceIndex];
117  result[i] = theChoice[i];
118  }
119  }
120 
121  return result;
122  }
123 
124  //============================================================================
125  // Method Description:
139  template<typename dtype>
140  NdArray<dtype> select(const std::vector<NdArray<bool>>& condList,
141  const std::vector<NdArray<dtype>>& choiceList,
142  dtype defaultValue = dtype{ 0 })
143  {
144  std::vector<const NdArray<bool>*> condVec(condList.size());
145  stl_algorithms::transform(condList.begin(),
146  condList.end(),
147  condVec.begin(),
148  [](auto& cond) noexcept -> const NdArray<bool>* { return &cond; });
149 
150  std::vector<const NdArray<dtype>*> choiceVec(choiceList.size());
151  stl_algorithms::transform(choiceList.begin(),
152  choiceList.end(),
153  choiceVec.begin(),
154  [](auto& choice) noexcept -> const NdArray<dtype>* { return &choice; });
155 
156  return select(condVec, choiceVec, defaultValue);
157  }
158 } // namespace nc
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:37
Holds 1D and 2D arrays, the main work horse of the NumCpp library.
Definition: NdArrayCore.hpp:138
uint32 size_type
Definition: NdArrayCore.hpp:155
dtype choice(GeneratorType &generator, const NdArray< dtype > &inArray)
Definition: choice.hpp:52
OutputIt transform(InputIt first, InputIt last, OutputIt destination, UnaryOperation unaryFunction)
Definition: StlAlgorithms.hpp:775
Definition: Cartesian.hpp:40
NdArray< dtype > select(const std::vector< const NdArray< bool > * > &condVec, const std::vector< const NdArray< dtype > * > &choiceVec, dtype defaultValue=dtype{ 0 })
Definition: select.hpp:58
NdArray< dtype > max(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: max.hpp:44