TheAlgorithms/C++ 1.0.0
All the algorithms implemented in C++
Loading...
Searching...
No Matches
vector_ops.hpp
Go to the documentation of this file.
1
10#ifndef VECTOR_OPS_FOR_NN
11#define VECTOR_OPS_FOR_NN
12
13#include <algorithm>
14#include <chrono>
15#include <iostream>
16#include <random>
17#include <valarray>
18#include <vector>
19
24namespace machine_learning {
31template <typename T>
32std::ostream &operator<<(std::ostream &out,
33 std::vector<std::valarray<T>> const &A) {
34 // Setting output precision to 4 in case of floating point numbers
35 out.precision(4);
36 for (const auto &a : A) { // For each row in A
37 for (const auto &x : a) { // For each element in row
38 std::cout << x << ' '; // print element
39 }
40 std::cout << std::endl;
41 }
42 return out;
43}
44
51template <typename T>
52std::ostream &operator<<(std::ostream &out, const std::pair<T, T> &A) {
53 // Setting output precision to 4 in case of floating point numbers
54 out.precision(4);
55 // printing pair in the form (p, q)
56 std::cout << "(" << A.first << ", " << A.second << ")";
57 return out;
58}
59
66template <typename T>
67std::ostream &operator<<(std::ostream &out, const std::valarray<T> &A) {
68 // Setting output precision to 4 in case of floating point numbers
69 out.precision(4);
70 for (const auto &a : A) { // For every element in the vector.
71 std::cout << a << ' '; // Print element
72 }
73 std::cout << std::endl;
74 return out;
75}
76
84template <typename T>
85std::valarray<T> insert_element(const std::valarray<T> &A, const T &ele) {
86 std::valarray<T> B; // New 1D vector to store resultant vector
87 B.resize(A.size() + 1); // Resizing it accordingly
88 for (size_t i = 0; i < A.size(); i++) { // For every element in A
89 B[i] = A[i]; // Copy element in B
90 }
91 B[B.size() - 1] = ele; // Inserting new element in last position
92 return B; // Return resultant vector
93}
94
101template <typename T>
102std::valarray<T> pop_front(const std::valarray<T> &A) {
103 std::valarray<T> B; // New 1D vector to store resultant vector
104 B.resize(A.size() - 1); // Resizing it accordingly
105 for (size_t i = 1; i < A.size();
106 i++) { // // For every (except first) element in A
107 B[i - 1] = A[i]; // Copy element in B with left shifted position
108 }
109 return B; // Return resultant vector
110}
111
118template <typename T>
119std::valarray<T> pop_back(const std::valarray<T> &A) {
120 std::valarray<T> B; // New 1D vector to store resultant vector
121 B.resize(A.size() - 1); // Resizing it accordingly
122 for (size_t i = 0; i < A.size() - 1;
123 i++) { // For every (except last) element in A
124 B[i] = A[i]; // Copy element in B
125 }
126 return B; // Return resultant vector
127}
128
135template <typename T>
136void equal_shuffle(std::vector<std::vector<std::valarray<T>>> &A,
137 std::vector<std::vector<std::valarray<T>>> &B) {
138 // If two vectors have different sizes
139 if (A.size() != B.size()) {
140 std::cerr << "ERROR (" << __func__ << ") : ";
141 std::cerr
142 << "Can not equally shuffle two vectors with different sizes: ";
143 std::cerr << A.size() << " and " << B.size() << std::endl;
144 std::exit(EXIT_FAILURE);
145 }
146 for (size_t i = 0; i < A.size(); i++) { // For every element in A and B
147 // Genrating random index < size of A and B
148 std::srand(std::chrono::system_clock::now().time_since_epoch().count());
149 size_t random_index = std::rand() % A.size();
150 // Swap elements in both A and B with same random index
151 std::swap(A[i], A[random_index]);
152 std::swap(B[i], B[random_index]);
153 }
154 return;
155}
156
165template <typename T>
166void uniform_random_initialization(std::vector<std::valarray<T>> &A,
167 const std::pair<size_t, size_t> &shape,
168 const T &low, const T &high) {
169 A.clear(); // Making A empty
170 // Uniform distribution in range [low, high]
171 std::default_random_engine generator(
172 std::chrono::system_clock::now().time_since_epoch().count());
173 std::uniform_real_distribution<T> distribution(low, high);
174 for (size_t i = 0; i < shape.first; i++) { // For every row
175 std::valarray<T>
176 row; // Making empty row which will be inserted in vector
177 row.resize(shape.second);
178 for (auto &r : row) { // For every element in row
179 r = distribution(generator); // copy random number
180 }
181 A.push_back(row); // Insert new row in vector
182 }
183 return;
184}
185
192template <typename T>
193void unit_matrix_initialization(std::vector<std::valarray<T>> &A,
194 const std::pair<size_t, size_t> &shape) {
195 A.clear(); // Making A empty
196 for (size_t i = 0; i < shape.first; i++) {
197 std::valarray<T>
198 row; // Making empty row which will be inserted in vector
199 row.resize(shape.second);
200 row[i] = T(1); // Insert 1 at ith position
201 A.push_back(row); // Insert new row in vector
202 }
203 return;
204}
205
212template <typename T>
213void zeroes_initialization(std::vector<std::valarray<T>> &A,
214 const std::pair<size_t, size_t> &shape) {
215 A.clear(); // Making A empty
216 for (size_t i = 0; i < shape.first; i++) {
217 std::valarray<T>
218 row; // Making empty row which will be inserted in vector
219 row.resize(shape.second); // By default all elements are zero
220 A.push_back(row); // Insert new row in vector
221 }
222 return;
223}
224
231template <typename T>
232T sum(const std::vector<std::valarray<T>> &A) {
233 T cur_sum = 0; // Initially sum is zero
234 for (const auto &a : A) { // For every row in A
235 cur_sum += a.sum(); // Add sum of that row to current sum
236 }
237 return cur_sum; // Return sum
238}
239
246template <typename T>
247std::pair<size_t, size_t> get_shape(const std::vector<std::valarray<T>> &A) {
248 const size_t sub_size = (*A.begin()).size();
249 for (const auto &a : A) {
250 // If supplied vector don't have same shape in all rows
251 if (a.size() != sub_size) {
252 std::cerr << "ERROR (" << __func__ << ") : ";
253 std::cerr << "Supplied vector is not 2D Matrix" << std::endl;
254 std::exit(EXIT_FAILURE);
255 }
256 }
257 return std::make_pair(A.size(), sub_size); // Return shape as pair
258}
259
268template <typename T>
269std::vector<std::vector<std::valarray<T>>> minmax_scaler(
270 const std::vector<std::vector<std::valarray<T>>> &A, const T &low,
271 const T &high) {
272 std::vector<std::vector<std::valarray<T>>> B =
273 A; // Copying into new vector B
274 const auto shape = get_shape(B[0]); // Storing shape of B's every element
275 // As this function is used for scaling training data vector should be of
276 // shape (1, X)
277 if (shape.first != 1) {
278 std::cerr << "ERROR (" << __func__ << ") : ";
279 std::cerr
280 << "Supplied vector is not supported for minmax scaling, shape: ";
281 std::cerr << shape << std::endl;
282 std::exit(EXIT_FAILURE);
283 }
284 for (size_t i = 0; i < shape.second; i++) {
285 T min = B[0][0][i], max = B[0][0][i];
286 for (size_t j = 0; j < B.size(); j++) {
287 // Updating minimum and maximum values
288 min = std::min(min, B[j][0][i]);
289 max = std::max(max, B[j][0][i]);
290 }
291 for (size_t j = 0; j < B.size(); j++) {
292 // Applying min-max scaler formula
293 B[j][0][i] =
294 ((B[j][0][i] - min) / (max - min)) * (high - low) + low;
295 }
296 }
297 return B; // Return new resultant 3D vector
298}
299
306template <typename T>
307size_t argmax(const std::vector<std::valarray<T>> &A) {
308 const auto shape = get_shape(A);
309 // As this function is used on predicted (or target) vector, shape should be
310 // (1, X)
311 if (shape.first != 1) {
312 std::cerr << "ERROR (" << __func__ << ") : ";
313 std::cerr << "Supplied vector is ineligible for argmax" << std::endl;
314 std::exit(EXIT_FAILURE);
315 }
316 // Return distance of max element from first element (i.e. index)
317 return std::distance(std::begin(A[0]),
318 std::max_element(std::begin(A[0]), std::end(A[0])));
319}
320
328template <typename T>
329std::vector<std::valarray<T>> apply_function(
330 const std::vector<std::valarray<T>> &A, T (*func)(const T &)) {
331 std::vector<std::valarray<double>> B =
332 A; // New vector to store resultant vector
333 for (auto &b : B) { // For every row in vector
334 b = b.apply(func); // Apply function to that row
335 }
336 return B; // Return new resultant 2D vector
337}
338
346template <typename T>
347std::vector<std::valarray<T>> operator*(const std::vector<std::valarray<T>> &A,
348 const T &val) {
349 std::vector<std::valarray<double>> B =
350 A; // New vector to store resultant vector
351 for (auto &b : B) { // For every row in vector
352 b = b * val; // Multiply row with scaler
353 }
354 return B; // Return new resultant 2D vector
355}
356
364template <typename T>
365std::vector<std::valarray<T>> operator/(const std::vector<std::valarray<T>> &A,
366 const T &val) {
367 std::vector<std::valarray<double>> B =
368 A; // New vector to store resultant vector
369 for (auto &b : B) { // For every row in vector
370 b = b / val; // Divide row with scaler
371 }
372 return B; // Return new resultant 2D vector
373}
374
381template <typename T>
382std::vector<std::valarray<T>> transpose(
383 const std::vector<std::valarray<T>> &A) {
384 const auto shape = get_shape(A); // Current shape of vector
385 std::vector<std::valarray<T>> B; // New vector to store result
386 // Storing transpose values of A in B
387 for (size_t j = 0; j < shape.second; j++) {
388 std::valarray<T> row;
389 row.resize(shape.first);
390 for (size_t i = 0; i < shape.first; i++) {
391 row[i] = A[i][j];
392 }
393 B.push_back(row);
394 }
395 return B; // Return new resultant 2D vector
396}
397
405template <typename T>
406std::vector<std::valarray<T>> operator+(
407 const std::vector<std::valarray<T>> &A,
408 const std::vector<std::valarray<T>> &B) {
409 const auto shape_a = get_shape(A);
410 const auto shape_b = get_shape(B);
411 // If vectors don't have equal shape
412 if (shape_a.first != shape_b.first || shape_a.second != shape_b.second) {
413 std::cerr << "ERROR (" << __func__ << ") : ";
414 std::cerr << "Supplied vectors have different shapes ";
415 std::cerr << shape_a << " and " << shape_b << std::endl;
416 std::exit(EXIT_FAILURE);
417 }
418 std::vector<std::valarray<T>> C;
419 for (size_t i = 0; i < A.size(); i++) { // For every row
420 C.push_back(A[i] + B[i]); // Elementwise addition
421 }
422 return C; // Return new resultant 2D vector
423}
424
432template <typename T>
433std::vector<std::valarray<T>> operator-(
434 const std::vector<std::valarray<T>> &A,
435 const std::vector<std::valarray<T>> &B) {
436 const auto shape_a = get_shape(A);
437 const auto shape_b = get_shape(B);
438 // If vectors don't have equal shape
439 if (shape_a.first != shape_b.first || shape_a.second != shape_b.second) {
440 std::cerr << "ERROR (" << __func__ << ") : ";
441 std::cerr << "Supplied vectors have different shapes ";
442 std::cerr << shape_a << " and " << shape_b << std::endl;
443 std::exit(EXIT_FAILURE);
444 }
445 std::vector<std::valarray<T>> C; // Vector to store result
446 for (size_t i = 0; i < A.size(); i++) { // For every row
447 C.push_back(A[i] - B[i]); // Elementwise substraction
448 }
449 return C; // Return new resultant 2D vector
450}
451
459template <typename T>
460std::vector<std::valarray<T>> multiply(const std::vector<std::valarray<T>> &A,
461 const std::vector<std::valarray<T>> &B) {
462 const auto shape_a = get_shape(A);
463 const auto shape_b = get_shape(B);
464 // If vectors are not eligible for multiplication
465 if (shape_a.second != shape_b.first) {
466 std::cerr << "ERROR (" << __func__ << ") : ";
467 std::cerr << "Vectors are not eligible for multiplication ";
468 std::cerr << shape_a << " and " << shape_b << std::endl;
469 std::exit(EXIT_FAILURE);
470 }
471 std::vector<std::valarray<T>> C; // Vector to store result
472 // Normal matrix multiplication
473 for (size_t i = 0; i < shape_a.first; i++) {
474 std::valarray<T> row;
475 row.resize(shape_b.second);
476 for (size_t j = 0; j < shape_b.second; j++) {
477 for (size_t k = 0; k < shape_a.second; k++) {
478 row[j] += A[i][k] * B[k][j];
479 }
480 }
481 C.push_back(row);
482 }
483 return C; // Return new resultant 2D vector
484}
485
493template <typename T>
494std::vector<std::valarray<T>> hadamard_product(
495 const std::vector<std::valarray<T>> &A,
496 const std::vector<std::valarray<T>> &B) {
497 const auto shape_a = get_shape(A);
498 const auto shape_b = get_shape(B);
499 // If vectors are not eligible for hadamard product
500 if (shape_a.first != shape_b.first || shape_a.second != shape_b.second) {
501 std::cerr << "ERROR (" << __func__ << ") : ";
502 std::cerr << "Vectors have different shapes ";
503 std::cerr << shape_a << " and " << shape_b << std::endl;
504 std::exit(EXIT_FAILURE);
505 }
506 std::vector<std::valarray<T>> C; // Vector to store result
507 for (size_t i = 0; i < A.size(); i++) {
508 C.push_back(A[i] * B[i]); // Elementwise multiplication
509 }
510 return C; // Return new resultant 2D vector
511}
512} // namespace machine_learning
513
514#endif
A* search algorithm
std::vector< std::valarray< T > > operator-(const std::vector< std::valarray< T > > &A, const std::vector< std::valarray< T > > &B)
std::vector< std::valarray< T > > operator*(const std::vector< std::valarray< T > > &A, const T &val)
std::vector< std::valarray< T > > operator+(const std::vector< std::valarray< T > > &A, const std::vector< std::valarray< T > > &B)
std::valarray< T > insert_element(const std::valarray< T > &A, const T &ele)
size_t argmax(const std::vector< std::valarray< T > > &A)
std::vector< std::valarray< T > > multiply(const std::vector< std::valarray< T > > &A, const std::vector< std::valarray< T > > &B)
T sum(const std::vector< std::valarray< T > > &A)
std::ostream & operator<<(std::ostream &out, std::vector< std::valarray< T > > const &A)
std::vector< std::valarray< T > > transpose(const std::vector< std::valarray< T > > &A)
void unit_matrix_initialization(std::vector< std::valarray< T > > &A, const std::pair< size_t, size_t > &shape)
std::valarray< T > pop_front(const std::valarray< T > &A)
std::pair< size_t, size_t > get_shape(const std::vector< std::valarray< T > > &A)
void uniform_random_initialization(std::vector< std::valarray< T > > &A, const std::pair< size_t, size_t > &shape, const T &low, const T &high)
void zeroes_initialization(std::vector< std::valarray< T > > &A, const std::pair< size_t, size_t > &shape)
std::vector< std::vector< std::valarray< T > > > minmax_scaler(const std::vector< std::vector< std::valarray< T > > > &A, const T &low, const T &high)
std::vector< std::valarray< T > > hadamard_product(const std::vector< std::valarray< T > > &A, const std::vector< std::valarray< T > > &B)
std::vector< std::valarray< T > > apply_function(const std::vector< std::valarray< T > > &A, T(*func)(const T &))
std::valarray< T > pop_back(const std::valarray< T > &A)
std::vector< std::valarray< T > > operator/(const std::vector< std::valarray< T > > &A, const T &val)
void equal_shuffle(std::vector< std::vector< std::valarray< T > > > &A, std::vector< std::vector< std::valarray< T > > > &B)