NumCpp  2.9.0
A Templatized Header Only C++ Implementation of the Python NumPy Library
unpackbits.hpp
Go to the documentation of this file.
1 #pragma once
29 
30 #include <type_traits>
31 
33 #include "NumCpp/NdArray.hpp"
34 
35 namespace nc
36 {
37  //============================================================================
38  // Method Description:
52  {
53  switch (axis)
54  {
55  case Axis::NONE:
56  {
57  NdArray<uint8> result(1, a.size() * 8);
58 
59  for (NdArray<uint8>::size_type byte = 0; byte < a.size(); ++byte)
60  {
61  const auto startIdx = byte * 8;
62  const auto byteValue = a[byte];
63 
64  for (auto bit = 0; bit < 8; ++bit)
65  {
66  result[startIdx + bit] = (byteValue & (1 << bit)) >> bit;
67  }
68  }
69 
70  return result;
71  }
72  case Axis::COL:
73  {
74  const auto aShape = a.shape();
75  NdArray<uint8> result(aShape.rows, aShape.cols * 8);
76  const auto resultCSlice = result.cSlice();
77  const auto aCSlice = a.cSlice();
78 
79  for (NdArray<uint8>::size_type row = 0; row < aShape.rows; ++row)
80  {
81  result.put(row, resultCSlice, unpackbitsLittleEndian(a(row, aCSlice)));
82  }
83 
84  return result;
85  }
86  case Axis::ROW:
87  {
88  return unpackbitsLittleEndian(a.transpose(), Axis::COL).transpose();
89  }
90  default:
91  {
92  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
93  return {}; // get rid of compiler warning
94  }
95  }
96  }
97 
98  //============================================================================
99  // Method Description:
113  {
114  switch (axis)
115  {
116  case Axis::NONE:
117  {
118  NdArray<uint8> result(1, a.size() * 8);
119 
120  for (NdArray<uint8>::size_type byte = 0; byte < a.size(); ++byte)
121  {
122  const auto startIdx = byte * 8;
123  const auto byteValue = a[byte];
124 
125  for (auto bit = 0; bit < 8; ++bit)
126  {
127  const auto bitToMask = static_cast<uint8>(7 - bit);
128  result[startIdx + bit] = (byteValue & (1 << bitToMask)) >> bitToMask;
129  }
130  }
131 
132  return result;
133  }
134  case Axis::COL:
135  {
136  const auto aShape = a.shape();
137  NdArray<uint8> result(aShape.rows, aShape.cols * 8);
138  const auto resultCSlice = result.cSlice();
139  const auto aCSlice = a.cSlice();
140 
141  for (NdArray<uint8>::size_type row = 0; row < aShape.rows; ++row)
142  {
143  result.put(row, resultCSlice, unpackbitsBigEndian(a(row, aCSlice)));
144  }
145 
146  return result;
147  }
148  case Axis::ROW:
149  {
150  return unpackbitsBigEndian(a.transpose(), Axis::COL).transpose();
151  }
152  default:
153  {
154  THROW_INVALID_ARGUMENT_ERROR("Unimplemented axis type.");
155  return {}; // get rid of compiler warning
156  }
157  }
158  }
159 
160 } // 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
NdArray< dtype > & put(int32 inIndex, value_type inValue)
Definition: NdArrayCore.hpp:3479
size_type size() const noexcept
Definition: NdArrayCore.hpp:4105
Slice cSlice(int32 inStartIdx=0, uint32 inStepSize=1) const noexcept
Definition: NdArrayCore.hpp:969
Shape shape() const noexcept
Definition: NdArrayCore.hpp:4092
NdArray< dtype > transpose() const
Definition: NdArrayCore.hpp:4457
uint32 size_type
Definition: NdArrayCore.hpp:88
Definition: Coordinate.hpp:45
NdArray< uint8 > unpackbitsBigEndian(const NdArray< uint8 > &a, Axis axis=Axis::NONE)
Definition: unpackbits.hpp:112
Axis
Enum To describe an axis.
Definition: Types.hpp:47
std::uint8_t uint8
Definition: Types.hpp:42
NdArray< uint8 > unpackbitsLittleEndian(const NdArray< uint8 > &a, Axis axis=Axis::NONE)
Definition: unpackbits.hpp:51