NumCpp  2.9.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 
36 #include "NumCpp/Core/Shape.hpp"
37 #include "NumCpp/NdArray.hpp"
38 
39 namespace nc
40 {
41  //============================================================================
42  // Method Description:
56  template<typename dtype>
57  NdArray<dtype> select(const std::vector<const NdArray<bool>*>& condVec,
58  const std::vector<const NdArray<dtype>*>& choiceVec,
59  dtype defaultValue = dtype{ 0 })
60  {
61  if (choiceVec.size() != condVec.size())
62  {
63  THROW_INVALID_ARGUMENT_ERROR("condVec and choiceVec need to be the same size");
64  }
65 
66  if (choiceVec.size() == 0)
67  {
68  THROW_INVALID_ARGUMENT_ERROR("choiceVec is size 0");
69  }
70 
71  auto theShape = condVec.front()->shape();
72  for (const auto cond : condVec)
73  {
74  const auto& theCond = *cond;
75  if (theCond.shape() != theShape)
76  {
77  THROW_INVALID_ARGUMENT_ERROR("all NdArrays of the condVec must be the same shape");
78  }
79  }
80 
81  for (const auto choice : choiceVec)
82  {
83  const auto& theChoice = *choice;
84  if (theChoice.shape() != theShape)
85  {
87  "all NdArrays of the choiceVec must be the same shape, and the same as condVec");
88  }
89  }
90 
91  using size_type = typename NdArray<dtype>::size_type;
92  constexpr auto nullChoice = std::numeric_limits<size_type>::max();
93 
94  NdArray<size_type> choiceIndices(theShape);
95  choiceIndices.fill(nullChoice);
96  for (size_type condIdx = 0; condIdx < condVec.size(); ++condIdx)
97  {
98  const auto& theCond = *condVec[condIdx];
99  for (size_type i = 0; i < theCond.size(); ++i)
100  {
101  if (theCond[i] && choiceIndices[i] == nullChoice)
102  {
103  choiceIndices[i] = condIdx;
104  }
105  }
106  }
107 
108  NdArray<dtype> result(theShape);
109  result.fill(defaultValue);
110  for (size_type i = 0; i < choiceIndices.size(); ++i)
111  {
112  const auto choiceIndex = choiceIndices[i];
113  if (choiceIndex != nullChoice)
114  {
115  const auto& theChoice = *choiceVec[choiceIndex];
116  result[i] = theChoice[i];
117  }
118  }
119 
120  return result;
121  }
122 
123  //============================================================================
124  // Method Description:
138  template<typename dtype>
139  NdArray<dtype> select(const std::vector<NdArray<bool>>& condList,
140  const std::vector<NdArray<dtype>>& choiceList,
141  dtype defaultValue = dtype{ 0 })
142  {
143  std::vector<const NdArray<bool>*> condVec;
144  condVec.reserve(condList.size());
145  for (auto& cond : condList)
146  {
147  condVec.push_back(&cond);
148  }
149 
150  std::vector<const NdArray<dtype>*> choiceVec;
151  choiceVec.reserve(choiceList.size());
152  for (auto& choice : choiceList)
153  {
154  choiceVec.push_back(&choice);
155  }
156 
157  return select(condVec, choiceVec, defaultValue);
158  }
159 } // namespace nc
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:36
Holds 1D and 2D arrays, the main work horse of the NumCpp library.
Definition: NdArrayCore.hpp:72
uint32 size_type
Definition: NdArrayCore.hpp:88
dtype choice(GeneratorType &generator, const NdArray< dtype > &inArray)
Definition: choice.hpp:54
Definition: Coordinate.hpp:45
NdArray< dtype > select(const std::vector< const NdArray< bool > * > &condVec, const std::vector< const NdArray< dtype > * > &choiceVec, dtype defaultValue=dtype{ 0 })
Definition: select.hpp:57
NdArray< dtype > max(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: max.hpp:44