NumCpp  2.12.1
A Templatized Header Only C++ Implementation of the Python NumPy Library
average.hpp
Go to the documentation of this file.
1
28#pragma once
29
30#include <complex>
31#include <string>
32
38#include "NumCpp/Core/Shape.hpp"
39#include "NumCpp/Core/Types.hpp"
41#include "NumCpp/NdArray.hpp"
42
43namespace nc
44{
45 //============================================================================
46 // Method Description:
55 template<typename dtype>
56 auto average(const NdArray<dtype>& inArray, Axis inAxis = Axis::NONE)
57 {
58 return mean(inArray, inAxis);
59 }
60
61 //============================================================================
62 // Method Description:
72 template<typename dtype>
73 NdArray<double> average(const NdArray<dtype>& inArray, const NdArray<dtype>& inWeights, Axis inAxis = Axis::NONE)
74 {
76
77 switch (inAxis)
78 {
79 case Axis::NONE:
80 {
81 if (inWeights.shape() != inArray.shape())
82 {
83 THROW_INVALID_ARGUMENT_ERROR("input array and weight values are not consistant.");
84 }
85
86 NdArray<double> weightedArray(inArray.shape());
88 inArray.cend(),
89 inWeights.cbegin(),
90 weightedArray.begin(),
91 std::multiplies<double>()); // NOLINT(modernize-use-transparent-functors)
92
93 double sum = std::accumulate(weightedArray.begin(), weightedArray.end(), 0.);
94 NdArray<double> returnArray = { sum /= inWeights.template astype<double>().sum().item() };
95
96 return returnArray;
97 }
98 case Axis::COL:
99 {
100 const Shape arrayShape = inArray.shape();
101 if (inWeights.size() != arrayShape.cols)
102 {
103 THROW_INVALID_ARGUMENT_ERROR("input array and weights value are not consistant.");
104 }
105
106 double weightSum = inWeights.template astype<double>().sum().item();
107 NdArray<double> returnArray(1, arrayShape.rows);
108 for (uint32 row = 0; row < arrayShape.rows; ++row)
109 {
110 NdArray<double> weightedArray(1, arrayShape.cols);
112 inArray.cend(row),
113 inWeights.cbegin(),
114 weightedArray.begin(),
115 std::multiplies<double>()); // NOLINT(modernize-use-transparent-functors)
116
117 double sum = std::accumulate(weightedArray.begin(), weightedArray.end(), 0.);
118 returnArray(0, row) = sum / weightSum;
119 }
120
121 return returnArray;
122 }
123 case Axis::ROW:
124 {
125 return average(inArray.transpose(), inWeights, Axis::COL);
126 }
127 default:
128 {
129 THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
130 return {};
131 }
132 }
133 }
134
135 //============================================================================
136 // Method Description:
146 template<typename dtype>
147 NdArray<std::complex<double>>
148 average(const NdArray<std::complex<dtype>>& inArray, const NdArray<dtype>& inWeights, Axis inAxis = Axis::NONE)
149 {
151
152 const auto multiplies = [](const std::complex<dtype>& lhs, dtype rhs) -> std::complex<double>
153 { return complex_cast<double>(lhs) * static_cast<double>(rhs); };
154
155 switch (inAxis)
156 {
157 case Axis::NONE:
158 {
159 if (inWeights.shape() != inArray.shape())
160 {
161 THROW_INVALID_ARGUMENT_ERROR("input array and weight values are not consistant.");
162 }
163
164 NdArray<std::complex<double>> weightedArray(inArray.shape());
165 stl_algorithms::transform(inArray.cbegin(),
166 inArray.cend(),
167 inWeights.cbegin(),
168 weightedArray.begin(),
169 multiplies);
170
171 std::complex<double> sum =
172 std::accumulate(weightedArray.begin(), weightedArray.end(), std::complex<double>(0.));
173 NdArray<std::complex<double>> returnArray = { sum /= inWeights.template astype<double>().sum().item() };
174
175 return returnArray;
176 }
177 case Axis::COL:
178 {
179 const Shape arrayShape = inArray.shape();
180 if (inWeights.size() != arrayShape.cols)
181 {
182 THROW_INVALID_ARGUMENT_ERROR("input array and weights value are not consistant.");
183 }
184
185 double weightSum = inWeights.template astype<double>().sum().item();
186 NdArray<std::complex<double>> returnArray(1, arrayShape.rows);
187 for (uint32 row = 0; row < arrayShape.rows; ++row)
188 {
189 NdArray<std::complex<double>> weightedArray(1, arrayShape.cols);
190 stl_algorithms::transform(inArray.cbegin(row),
191 inArray.cend(row),
192 inWeights.cbegin(),
193 weightedArray.begin(),
194 multiplies);
195
196 const std::complex<double> sum =
197 std::accumulate(weightedArray.begin(), weightedArray.end(), std::complex<double>(0.));
198 returnArray(0, row) = sum / weightSum;
199 }
200
201 return returnArray;
202 }
203 case Axis::ROW:
204 {
205 return average(inArray.transpose(), inWeights, Axis::COL);
206 }
207 default:
208 {
209 THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
210 return {}; // get rid of compiler warning
211 }
212 }
213 }
214} // namespace nc
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:37
#define STATIC_ASSERT_ARITHMETIC(dtype)
Definition: StaticAsserts.hpp:39
Holds 1D and 2D arrays, the main work horse of the NumCpp library.
Definition: NdArrayCore.hpp:139
size_type size() const noexcept
Definition: NdArrayCore.hpp:4524
const_iterator cbegin() const noexcept
Definition: NdArrayCore.hpp:1365
iterator end() noexcept
Definition: NdArrayCore.hpp:1623
self_type transpose() const
Definition: NdArrayCore.hpp:4882
const Shape & shape() const noexcept
Definition: NdArrayCore.hpp:4511
const_iterator cend() const noexcept
Definition: NdArrayCore.hpp:1673
iterator begin() noexcept
Definition: NdArrayCore.hpp:1315
value_type item() const
Definition: NdArrayCore.hpp:3022
self_type sum(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:4618
A Shape Class for NdArrays.
Definition: Core/Shape.hpp:41
uint32 rows
Definition: Core/Shape.hpp:44
uint32 cols
Definition: Core/Shape.hpp:45
OutputIt transform(InputIt first, InputIt last, OutputIt destination, UnaryOperation unaryFunction)
Definition: StlAlgorithms.hpp:775
Definition: Cartesian.hpp:40
NdArray< double > mean(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: mean.hpp:52
Axis
Enum To describe an axis.
Definition: Enums.hpp:36
auto average(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: average.hpp:56
NdArray< dtype > sum(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: sum.hpp:46
std::uint32_t uint32
Definition: Types.hpp:40