kmeans
k-means clustering in C++
Loading...
Searching...
No Matches
SimpleMatrix.hpp
Go to the documentation of this file.
1#ifndef KMEANS_SIMPLE_MATRIX_HPP
2#define KMEANS_SIMPLE_MATRIX_HPP
3
4#include <cstddef>
5#include <limits>
6
7#include "sanisizer/sanisizer.hpp"
8
9#include "Matrix.hpp"
10
16namespace kmeans {
17
21template<typename Index_, typename Data_>
22class SimpleMatrix;
23
24#ifdef KMEANS_DEBUG_POINTER_USAGE
55template<typename Data_>
56class Buffer {
57public:
58 Buffer(std::size_t n) : my_buffer(n * MULT), my_n(n), my_eng(n + 1) {}
59
60private:
61 static constexpr std::size_t MULT = 5;
62 std::vector<Data_> my_buffer;
63 std::size_t my_n;
64 std::mt19937_64 my_eng;
65
66public:
67 const Data_* update(const Data_* const ptr) {
68 std::fill(my_buffer.begin(), my_buffer.end(), std::numeric_limits<Data_>::quiet_NaN());
69 auto host = (my_eng() % MULT) * my_n;
70 std::copy_n(ptr, my_n, host);
71 return host;
72 }
73};
74#endif
75
76template<typename Index_, typename Data_>
77class SimpleMatrixRandomAccessExtractor final : public RandomAccessExtractor<Index_, Data_> {
78public:
79 SimpleMatrixRandomAccessExtractor(const SimpleMatrix<Index_, Data_>& parent) :
80 my_parent(parent)
81#ifdef KMEANS_DEBUG_POINTER
82 , my_buffer(my_parent.num_dimensions())
83#endif
84 {}
85
86private:
87 const SimpleMatrix<Index_, Data_>& my_parent;
88#ifdef KMEANS_DEBUG_POINTER
89 Buffer<Data_> my_buffer;
90#endif
91
92public:
93 const Data_* get_observation(const Index_ i) {
94 const auto output = my_parent.my_data + sanisizer::product_unsafe<std::size_t>(i, my_parent.my_num_dim);
95#ifndef KMEANS_DEBUG_POINTER
96 return output;
97#else
98 return my_buffer.update(output);
99#endif
100 }
101};
102
103template<typename Index_, typename Data_>
104class SimpleMatrixConsecutiveAccessExtractor final : public ConsecutiveAccessExtractor<Index_, Data_> {
105public:
106 SimpleMatrixConsecutiveAccessExtractor(const SimpleMatrix<Index_, Data_>& parent, const Index_ start) :
107 my_parent(parent),
108 my_position(start)
109#ifdef KMEANS_DEBUG_POINTER
110 , my_buffer(my_parent.num_dimensions())
111#endif
112 {}
113
114private:
115 const SimpleMatrix<Index_, Data_>& my_parent;
116 Index_ my_position;
117#ifdef KMEANS_DEBUG_POINTER
118 Buffer<Data_> my_buffer;
119#endif
120
121public:
122 const Data_* get_observation() {
123 const auto output = my_parent.my_data + sanisizer::product_unsafe<std::size_t>(my_position++, my_parent.my_num_dim);
124#ifndef KMEANS_DEBUG_POINTER
125 return output;
126#else
127 return my_buffer.update(output);
128#endif
129 }
130};
131
132template<typename Index_, typename Data_>
133class SimpleMatrixIndexedAccessExtractor final : public IndexedAccessExtractor<Index_, Data_> {
134public:
135 SimpleMatrixIndexedAccessExtractor(const SimpleMatrix<Index_, Data_>& parent, const Index_* const sequence) :
136 my_parent(parent),
137 my_sequence(sequence)
138#ifdef KMEANS_DEBUG_POINTER
139 , my_buffer(my_parent.num_dimensions())
140#endif
141 {}
142
143private:
144 const SimpleMatrix<Index_, Data_>& my_parent;
145 const Index_* my_sequence;
146 std::size_t my_position = 0;
147#ifdef KMEANS_DEBUG_POINTER
148 Buffer<Data_> my_buffer;
149#endif
150
151public:
152 const Data_* get_observation() {
153 const auto output = my_parent.my_data + sanisizer::product_unsafe<std::size_t>(my_sequence[my_position++], my_parent.my_num_dim);
154#ifndef KMEANS_DEBUG_POINTER
155 return output;
156#else
157 return my_buffer.update(output);
158#endif
159 }
160};
173template<typename Index_, typename Data_>
174class SimpleMatrix final : public Matrix<Index_, Data_> {
175public:
182 SimpleMatrix(const std::size_t num_dimensions, const Index_ num_observations, const Data_* const data) :
183 my_num_dim(num_dimensions), my_num_obs(num_observations), my_data(data) {}
184
185private:
186 std::size_t my_num_dim;
187 Index_ my_num_obs;
188 const Data_* my_data;
189 friend class SimpleMatrixRandomAccessExtractor<Index_, Data_>;
190 friend class SimpleMatrixConsecutiveAccessExtractor<Index_, Data_>;
191 friend class SimpleMatrixIndexedAccessExtractor<Index_, Data_>;
192
193public:
197 Index_ num_observations() const {
198 return my_num_obs;
199 }
200
201 std::size_t num_dimensions() const {
202 return my_num_dim;
203 }
204
205public:
206 std::unique_ptr<RandomAccessExtractor<Index_, Data_> > new_extractor() const {
207 return std::make_unique<SimpleMatrixRandomAccessExtractor<Index_, Data_> >(*this);
208 }
209
210 std::unique_ptr<ConsecutiveAccessExtractor<Index_, Data_> > new_extractor(const Index_ start, const Index_) const {
211 return std::make_unique<SimpleMatrixConsecutiveAccessExtractor<Index_, Data_> >(*this, start);
212 }
213
214 std::unique_ptr<IndexedAccessExtractor<Index_, Data_> > new_extractor(const Index_* sequence, const std::size_t) const {
215 return std::make_unique<SimpleMatrixIndexedAccessExtractor<Index_, Data_> >(*this, sequence);
216 }
220};
221
222}
223
224#endif
Interface for matrix inputs.
Interface for matrix data.
Definition Matrix.hpp:142
virtual std::size_t num_dimensions() const =0
virtual std::unique_ptr< RandomAccessExtractor< Index_, Data_ > > new_extractor() const =0
virtual Index_ num_observations() const =0
A simple matrix of observations.
Definition SimpleMatrix.hpp:174
SimpleMatrix(const std::size_t num_dimensions, const Index_ num_observations, const Data_ *const data)
Definition SimpleMatrix.hpp:182
Perform k-means clustering.
Definition compute_wcss.hpp:16