AARE
Data analysis library for PSI hybrid detectors
Loading...
Searching...
No Matches
NDView.hpp
Go to the documentation of this file.
1#pragma once
2#include <algorithm>
3#include <array>
4#include <cassert>
5#include <cstdint>
6#include <numeric>
7#include <stdexcept>
8#include <vector>
9
10namespace aare {
11
12template <ssize_t Ndim> using Shape = std::array<ssize_t, Ndim>;
13
14// TODO! fix mismatch between signed and unsigned
15template <ssize_t Ndim> Shape<Ndim> make_shape(const std::vector<size_t> &shape) {
16 if (shape.size() != Ndim)
17 throw std::runtime_error("Shape size mismatch");
18 Shape<Ndim> arr;
19 std::copy_n(shape.begin(), Ndim, arr.begin());
20 return arr;
21}
22
23template <ssize_t Dim = 0, typename Strides> ssize_t element_offset(const Strides &) { return 0; }
24
25template <ssize_t Dim = 0, typename Strides, typename... Ix>
26ssize_t element_offset(const Strides &strides, ssize_t i, Ix... index) {
27 return i * strides[Dim] + element_offset<Dim + 1>(strides, index...);
28}
29
30template <ssize_t Ndim> std::array<ssize_t, Ndim> c_strides(const std::array<ssize_t, Ndim> &shape) {
31 std::array<ssize_t, Ndim> strides;
32 std::fill(strides.begin(), strides.end(), 1);
33 for (ssize_t i = Ndim - 1; i > 0; --i) {
34 strides[i - 1] = strides[i] * shape[i];
35 }
36 return strides;
37}
38
39template <ssize_t Ndim> std::array<ssize_t, Ndim> make_array(const std::vector<ssize_t> &vec) {
40 assert(vec.size() == Ndim);
41 std::array<ssize_t, Ndim> arr;
42 std::copy_n(vec.begin(), Ndim, arr.begin());
43 return arr;
44}
45
46template <typename T, ssize_t Ndim = 2> class NDView {
47 public:
48 NDView(){};
49
50 NDView(T *buffer, std::array<ssize_t, Ndim> shape) {
51 buffer_ = buffer;
52 strides_ = c_strides<Ndim>(shape);
53 shape_ = shape;
54 size_ = std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<ssize_t>());
55 }
56
57 NDView(T *buffer, const std::vector<ssize_t> &shape) {
58 buffer_ = buffer;
59 strides_ = c_strides<Ndim>(make_array<Ndim>(shape));
60 shape_ = make_array<Ndim>(shape);
61 size_ = std::accumulate(std::begin(shape), std::end(shape), 1, std::multiplies<ssize_t>());
62 }
63
64 template <typename... Ix> typename std::enable_if<sizeof...(Ix) == Ndim, T &>::type operator()(Ix... index) {
65 return buffer_[element_offset(strides_, index...)];
66 }
67
68 template <typename... Ix> typename std::enable_if<sizeof...(Ix) == Ndim, T &>::type operator()(Ix... index) const {
69 return buffer_[element_offset(strides_, index...)];
70 }
71
72 ssize_t size() const { return size_; }
73
74 NDView(const NDView &) = default;
75 NDView(NDView &&) = default;
76
77 T *begin() { return buffer_; }
78 T *end() { return buffer_ + size_; }
79 T &operator()(ssize_t i) { return buffer_[i]; }
80 T &operator[](ssize_t i) { return buffer_[i]; }
81
82 bool operator==(const NDView &other) const {
83 if (size_ != other.size_)
84 return false;
85 for (ssize_t i = 0; i != size_; ++i) {
86 if (buffer_[i] != other.buffer_[i])
87 return false;
88 }
89 return true;
90 }
91
92 NDView &operator+=(const T val) { return elemenwise(val, std::plus<T>()); }
93 NDView &operator-=(const T val) { return elemenwise(val, std::minus<T>()); }
94 NDView &operator*=(const T val) { return elemenwise(val, std::multiplies<T>()); }
95 NDView &operator/=(const T val) { return elemenwise(val, std::divides<T>()); }
96
97 NDView &operator/=(const NDView &other) { return elemenwise(other, std::divides<T>()); }
98
99 NDView &operator=(const T val) {
100 for (auto it = begin(); it != end(); ++it)
101 *it = val;
102 return *this;
103 }
104
105 NDView &operator=(const NDView &other) {
106 shape_ = other.shape_;
107 strides_ = other.strides_;
108 size_ = other.size_;
109 buffer_ = other.buffer_;
110 return *this;
111 }
112 auto &shape() { return shape_; }
113 auto shape(ssize_t i) const { return shape_[i]; }
114
115 T *data() { return buffer_; }
116
117 private:
118 T *buffer_{nullptr};
119 std::array<ssize_t, Ndim> strides_{};
120 std::array<ssize_t, Ndim> shape_{};
121 ssize_t size_{};
122
123 template <class BinaryOperation> NDView &elemenwise(T val, BinaryOperation op) {
124 for (ssize_t i = 0; i != size_; ++i) {
125 buffer_[i] = op(buffer_[i], val);
126 }
127 return *this;
128 }
129 template <class BinaryOperation> NDView &elemenwise(const NDView &other, BinaryOperation op) {
130 for (ssize_t i = 0; i != size_; ++i) {
131 buffer_[i] = op(buffer_[i], other.buffer_[i]);
132 }
133 return *this;
134 }
135};
136
137template class NDView<uint16_t, 2>;
138
139} // namespace aare
Definition NDView.hpp:46
T & operator()(ssize_t i)
Definition NDView.hpp:79
ssize_t size() const
Definition NDView.hpp:72
NDView & operator+=(const T val)
Definition NDView.hpp:92
NDView(const NDView &)=default
NDView & operator-=(const T val)
Definition NDView.hpp:93
NDView & operator=(const NDView &other)
Definition NDView.hpp:105
std::array< ssize_t, Ndim > shape_
Definition NDView.hpp:120
T * data()
Definition NDView.hpp:115
auto & shape()
Definition NDView.hpp:112
NDView(T *buffer, std::array< ssize_t, Ndim > shape)
Definition NDView.hpp:50
std::array< ssize_t, Ndim > strides_
Definition NDView.hpp:119
NDView()
Definition NDView.hpp:48
bool operator==(const NDView &other) const
Definition NDView.hpp:82
NDView & operator/=(const T val)
Definition NDView.hpp:95
NDView(T *buffer, const std::vector< ssize_t > &shape)
Definition NDView.hpp:57
NDView & operator*=(const T val)
Definition NDView.hpp:94
ssize_t size_
Definition NDView.hpp:121
NDView & operator/=(const NDView &other)
Definition NDView.hpp:97
NDView & operator=(const T val)
Definition NDView.hpp:99
T * end()
Definition NDView.hpp:78
NDView & elemenwise(T val, BinaryOperation op)
Definition NDView.hpp:123
T * buffer_
Definition NDView.hpp:118
NDView(NDView &&)=default
T & operator[](ssize_t i)
Definition NDView.hpp:80
NDView & elemenwise(const NDView &other, BinaryOperation op)
Definition NDView.hpp:129
auto shape(ssize_t i) const
Definition NDView.hpp:113
T * begin()
Definition NDView.hpp:77
Frame class to represent a single frame of data model class should be able to work with streams comin...
Definition CircularFifo.hpp:11
std::array< ssize_t, Ndim > make_array(const std::vector< ssize_t > &vec)
Definition NDView.hpp:39
std::array< ssize_t, Ndim > Shape
Definition NDView.hpp:12
Shape< Ndim > make_shape(const std::vector< size_t > &shape)
Definition NDView.hpp:15
ssize_t element_offset(const Strides &)
Definition NDView.hpp:23
std::array< ssize_t, Ndim > c_strides(const std::array< ssize_t, Ndim > &shape)
Definition NDView.hpp:30