NumCpp  2.12.1
A Templatized Header Only C++ Implementation of the Python NumPy Library
select.hpp
Go to the documentation of this file.
1
28#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
40namespace 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:139
uint32 size_type
Definition: NdArrayCore.hpp:156
dtype choice(GeneratorType &generator, const NdArray< dtype > &inArray)
Definition: choice.hpp:53
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