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