Algorithms_in_C++ 1.0.0
Set of algorithms implemented in C++.
Loading...
Searching...
No Matches
vector_ops.hpp
Go to the documentation of this file.
1/**
2 * @file vector_ops.hpp
3 * @author [Deep Raval](https://github.com/imdeep2905)
4 *
5 * @brief Various functions for vectors associated with [NeuralNetwork (aka
6 * Multilayer Perceptron)]
7 * (https://en.wikipedia.org/wiki/Multilayer_perceptron).
8 *
9 */
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
20/**
21 * @namespace machine_learning
22 * @brief Machine Learning algorithms
23 */
24namespace machine_learning {
25/**
26 * Overloaded operator "<<" to print 2D vector
27 * @tparam T typename of the vector
28 * @param out std::ostream to output
29 * @param A 2D vector to be printed
30 */
31template <typename T>
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 }
41 }
42 return out;
43}
44
45/**
46 * Overloaded operator "<<" to print a pair
47 * @tparam T typename of the pair
48 * @param out std::ostream to output
49 * @param A Pair to be printed
50 */
51template <typename T>
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
60/**
61 * Overloaded operator "<<" to print a 1D vector
62 * @tparam T typename of the vector
63 * @param out std::ostream to output
64 * @param A 1D vector to be printed
65 */
66template <typename T>
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 }
74 return out;
75}
76
77/**
78 * Function to insert element into 1D vector
79 * @tparam T typename of the 1D vector and the element
80 * @param A 1D vector in which element will to be inserted
81 * @param ele element to be inserted
82 * @return new resultant vector
83 */
84template <typename T>
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
95/**
96 * Function to remove first element from 1D vector
97 * @tparam T typename of the vector
98 * @param A 1D vector from which first element will be removed
99 * @return new resultant vector
100 */
101template <typename T>
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
112/**
113 * Function to remove last element from 1D vector
114 * @tparam T typename of the vector
115 * @param A 1D vector from which last element will be removed
116 * @return new resultant vector
117 */
118template <typename T>
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
129/**
130 * Function to equally shuffle two 3D vectors (used for shuffling training data)
131 * @tparam T typename of the vector
132 * @param A First 3D vector
133 * @param B Second 3D vector
134 */
135template <typename T>
138 // If two vectors have different sizes
139 if (A.size() != B.size()) {
140 std::cerr << "ERROR (" << __func__ << ") : ";
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
157/**
158 * Function to initialize given 2D vector using uniform random initialization
159 * @tparam T typename of the vector
160 * @param A 2D vector to be initialized
161 * @param shape required shape
162 * @param low lower limit on value
163 * @param high upper limit on value
164 */
165template <typename T>
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]
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
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
186/**
187 * Function to Intialize 2D vector as unit matrix
188 * @tparam T typename of the vector
189 * @param A 2D vector to be initialized
190 * @param shape required shape
191 */
192template <typename T>
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++) {
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
206/**
207 * Function to Intialize 2D vector as zeroes
208 * @tparam T typename of the vector
209 * @param A 2D vector to be initialized
210 * @param shape required shape
211 */
212template <typename T>
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++) {
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
225/**
226 * Function to get sum of all elements in 2D vector
227 * @tparam T typename of the vector
228 * @param A 2D vector for which sum is required
229 * @return returns sum of all elements of 2D vector
230 */
231template <typename T>
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
240/**
241 * Function to get shape of given 2D vector
242 * @tparam T typename of the vector
243 * @param A 2D vector for which shape is required
244 * @return shape as pair
245 */
246template <typename T>
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
260/**
261 * Function to scale given 3D vector using min-max scaler
262 * @tparam T typename of the vector
263 * @param A 3D vector which will be scaled
264 * @param low new minimum value
265 * @param high new maximum value
266 * @return new scaled 3D vector
267 */
268template <typename T>
270 const std::vector<std::vector<std::valarray<T>>> &A, const T &low,
271 const T &high) {
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__ << ") : ";
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
300/**
301 * Function to get index of maximum element in 2D vector
302 * @tparam T typename of the vector
303 * @param A 2D vector for which maximum index is required
304 * @return index of maximum element
305 */
306template <typename T>
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
321/**
322 * Function which applys supplied function to every element of 2D vector
323 * @tparam T typename of the vector
324 * @param A 2D vector on which function will be applied
325 * @param func Function to be applied
326 * @return new resultant vector
327 */
328template <typename T>
330 const std::vector<std::valarray<T>> &A, T (*func)(const T &)) {
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
339/**
340 * Overloaded operator "*" to multiply given 2D vector with scaler
341 * @tparam T typename of both vector and the scaler
342 * @param A 2D vector to which scaler will be multiplied
343 * @param val Scaler value which will be multiplied
344 * @return new resultant vector
345 */
346template <typename T>
348 const T &val) {
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
357/**
358 * Overloaded operator "/" to divide given 2D vector with scaler
359 * @tparam T typename of the vector and the scaler
360 * @param A 2D vector to which scaler will be divided
361 * @param val Scaler value which will be divided
362 * @return new resultant vector
363 */
364template <typename T>
366 const T &val) {
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
375/**
376 * Function to get transpose of 2D vector
377 * @tparam T typename of the vector
378 * @param A 2D vector which will be transposed
379 * @return new resultant vector
380 */
381template <typename T>
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++) {
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
398/**
399 * Overloaded operator "+" to add two 2D vectors
400 * @tparam T typename of the vector
401 * @param A First 2D vector
402 * @param B Second 2D vector
403 * @return new resultant vector
404 */
405template <typename T>
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 }
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
425/**
426 * Overloaded operator "-" to add subtract 2D vectors
427 * @tparam T typename of the vector
428 * @param A First 2D vector
429 * @param B Second 2D vector
430 * @return new resultant vector
431 */
432template <typename T>
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
452/**
453 * Function to multiply two 2D vectors
454 * @tparam T typename of the vector
455 * @param A First 2D vector
456 * @param B Second 2D vector
457 * @return new resultant vector
458 */
459template <typename T>
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++) {
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
486/**
487 * Function to get hadamard product of two 2D vectors
488 * @tparam T typename of the vector
489 * @param A First 2D vector
490 * @param B Second 2D vector
491 * @return new resultant vector
492 */
493template <typename T>
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
T begin(T... args)
T distance(T... args)
T end(T... args)
T endl(T... args)
T exit(T... args)
T make_pair(T... args)
T max_element(T... args)
T max(T... args)
T min(T... args)
A* search algorithm
std::vector< std::valarray< T > > operator-(const std::vector< std::valarray< T > > &A, const std::vector< std::valarray< T > > &B)
Definition vector_ops.hpp:433
std::vector< std::valarray< T > > operator*(const std::vector< std::valarray< T > > &A, const T &val)
Definition vector_ops.hpp:347
std::vector< std::valarray< T > > operator+(const std::vector< std::valarray< T > > &A, const std::vector< std::valarray< T > > &B)
Definition vector_ops.hpp:406
std::valarray< T > insert_element(const std::valarray< T > &A, const T &ele)
Definition vector_ops.hpp:85
size_t argmax(const std::vector< std::valarray< T > > &A)
Definition vector_ops.hpp:307
std::vector< std::valarray< T > > multiply(const std::vector< std::valarray< T > > &A, const std::vector< std::valarray< T > > &B)
Definition vector_ops.hpp:460
T sum(const std::vector< std::valarray< T > > &A)
Definition vector_ops.hpp:232
std::ostream & operator<<(std::ostream &out, std::vector< std::valarray< T > > const &A)
Definition vector_ops.hpp:32
std::vector< std::valarray< T > > transpose(const std::vector< std::valarray< T > > &A)
Definition vector_ops.hpp:382
void unit_matrix_initialization(std::vector< std::valarray< T > > &A, const std::pair< size_t, size_t > &shape)
Definition vector_ops.hpp:193
std::valarray< T > pop_front(const std::valarray< T > &A)
Definition vector_ops.hpp:102
std::pair< size_t, size_t > get_shape(const std::vector< std::valarray< T > > &A)
Definition vector_ops.hpp:247
void uniform_random_initialization(std::vector< std::valarray< T > > &A, const std::pair< size_t, size_t > &shape, const T &low, const T &high)
Definition vector_ops.hpp:166
void zeroes_initialization(std::vector< std::valarray< T > > &A, const std::pair< size_t, size_t > &shape)
Definition vector_ops.hpp:213
std::vector< std::vector< std::valarray< T > > > minmax_scaler(const std::vector< std::vector< std::valarray< T > > > &A, const T &low, const T &high)
Definition vector_ops.hpp:269
std::vector< std::valarray< T > > hadamard_product(const std::vector< std::valarray< T > > &A, const std::vector< std::valarray< T > > &B)
Definition vector_ops.hpp:494
std::vector< std::valarray< T > > apply_function(const std::vector< std::valarray< T > > &A, T(*func)(const T &))
Definition vector_ops.hpp:329
std::valarray< T > pop_back(const std::valarray< T > &A)
Definition vector_ops.hpp:119
std::vector< std::valarray< T > > operator/(const std::vector< std::valarray< T > > &A, const T &val)
Definition vector_ops.hpp:365
void equal_shuffle(std::vector< std::vector< std::valarray< T > > > &A, std::vector< std::vector< std::valarray< T > > > &B)
Definition vector_ops.hpp:136
T precision(T... args)
T push_back(T... args)
T rand(T... args)
T size(T... args)
T srand(T... args)
T swap(T... args)