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