NumCpp  2.9.0
A Templatized Header Only C++ Implementation of the Python NumPy Library
histogram.hpp
Go to the documentation of this file.
1 #pragma once
29 
30 #include <string>
31 #include <utility>
32 
35 #include "NumCpp/Core/Types.hpp"
39 #include "NumCpp/NdArray.hpp"
40 
41 namespace nc
42 {
43  //============================================================================
44  // Method Description:
56  template<typename dtype>
57  NdArray<uint32> histogram(const NdArray<dtype>& inArray, const NdArray<double>& inBinEdges)
58  {
60 
61  if (inBinEdges.size() < 2)
62  {
63  THROW_INVALID_ARGUMENT_ERROR("number of bin edges must be >= 2.");
64  }
65 
66  // sort just in case the user hasn't already
67  const auto binEdges = sort(inBinEdges);
68 
69  NdArray<uint32> histo = zeros<uint32>(1, binEdges.size() - 1);
70  for (const auto value : inArray)
71  {
72  if (value < binEdges.front() || value > binEdges.back())
73  {
74  continue;
75  }
76 
77  // binary search to find the bin idx
78  constexpr bool keepSearching = true;
79  uint32 lowIdx = 0;
80  uint32 highIdx = binEdges.size() - 1;
81  while (keepSearching)
82  {
83  const uint32 idx = (lowIdx + highIdx) / 2; // integer division
84  if (lowIdx == highIdx || lowIdx == highIdx - 1)
85  {
86  // we found the bin
87  ++histo[lowIdx];
88  break;
89  }
90 
91  if (value > binEdges[idx])
92  {
93  lowIdx = idx;
94  }
95  else if (value < binEdges[idx])
96  {
97  highIdx = idx;
98  }
99  else
100  {
101  // we found the bin
102  ++histo[idx];
103  break;
104  }
105  }
106  }
107 
108  return histo;
109  }
110 
111  //============================================================================
112  // Method Description:
123  template<typename dtype>
124  std::pair<NdArray<uint32>, NdArray<double>> histogram(const NdArray<dtype>& inArray, uint32 inNumBins = 10)
125  {
127 
128  if (inNumBins == 0)
129  {
130  THROW_INVALID_ARGUMENT_ERROR("number of bins must be positive.");
131  }
132 
133  constexpr bool useEndPoint = true;
134  const NdArray<double> binEdges = linspace(static_cast<double>(inArray.min().item()),
135  static_cast<double>(inArray.max().item()),
136  inNumBins + 1,
137  useEndPoint);
138 
139  const auto histo = histogram(inArray, binEdges);
140  return std::make_pair(histo, binEdges);
141  }
142 } // namespace nc
#define THROW_INVALID_ARGUMENT_ERROR(msg)
Definition: Error.hpp:36
#define STATIC_ASSERT_ARITHMETIC(dtype)
Definition: StaticAsserts.hpp:37
Holds 1D and 2D arrays, the main work horse of the NumCpp library.
Definition: NdArrayCore.hpp:72
size_type size() const noexcept
Definition: NdArrayCore.hpp:4105
NdArray< dtype > min(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:2872
NdArray< dtype > max(Axis inAxis=Axis::NONE) const
Definition: NdArrayCore.hpp:2828
Definition: Coordinate.hpp:45
NdArray< dtype > linspace(dtype inStart, dtype inStop, uint32 inNum=50, bool endPoint=true)
Definition: linspace.hpp:60
NdArray< dtype > sort(const NdArray< dtype > &inArray, Axis inAxis=Axis::NONE)
Definition: sort.hpp:46
NdArray< uint32 > histogram(const NdArray< dtype > &inArray, const NdArray< double > &inBinEdges)
Definition: histogram.hpp:57
std::uint32_t uint32
Definition: Types.hpp:40