matrix.h
1 // OpenNN: Open Neural Networks Library
2 // www.opennn.net
3 //
4 // M A T R I X C O N T A I N E R
5 //
6 // Artificial Intelligence Techniques, SL
7 // artelnics@artelnics.com
8 
9 #ifndef MATRIX_H
10 #define MATRIX_H
11 
12 // System includes
13 
14 #include <cmath>
15 #include <cstdlib>
16 #include <fstream>
17 #include <iomanip>
18 #include <iostream>
19 #include <sstream>
20 #include <stdexcept>
21 #include <math.h>
22 #include <stdlib.h>
23 #include <stdio.h>
24 
25 // OpenNN includes
26 
27 #include "vector.h"
28 #include "tensor.h"
29 #include "opennn_strings.h"
30 
31 using namespace std;
32 
33 namespace OpenNN
34 {
35 
37 
40 
41 template <class T>
42 class Matrix : public vector<T>
43 {
44 
45 public:
46 
47  // CONSTRUCTORS
48 
49  explicit Matrix();
50 
51  explicit Matrix(const size_t&, const size_t&);
52 
53  explicit Matrix(const size_t&, const size_t&, const T&);
54 
55  explicit Matrix(const string&, const char&, const bool&);
56 
57  Matrix(const Matrix&);
58 
59  Matrix(const initializer_list<Vector<T>>&);
60 
61  Matrix(const initializer_list<Vector<T>>&, const initializer_list<string>&);
62 
63  virtual ~Matrix();
64 
65  // ASSIGNMENT OPERATORS
66 
67  inline Matrix<T>& operator = (const Matrix<T>&);
68 
69  // REFERENCE OPERATORS
70 
71  inline T& operator()(const size_t&, const size_t&);
72 
73  inline const T& operator()(const size_t&, const size_t&) const;
74 
75  inline T& operator()(const size_t&, const string&);
76 
77  inline const T& operator()(const size_t&, const string&) const;
78 
79  bool operator == (const Matrix<T>&) const;
80 
81  bool operator == (const T&) const;
82 
83  bool operator != (const Matrix<T>&) const;
84 
85  bool operator != (const T& value) const;
86 
87  bool operator > (const Matrix<T>&) const;
88 
89  bool operator > (const T& value) const;
90 
91  bool operator < (const Matrix<T>&) const;
92 
93  bool operator < (const T& value) const;
94 
95  bool operator >= (const Matrix<T>&) const;
96 
97  bool operator >= (const T&) const;
98 
99  bool operator <= (const Matrix<T>&) const;
100 
101  bool operator <= (const T&) const;
102 
103  Matrix<T> operator + (const T&) const;
104 
105  Matrix<T> operator + (const Matrix<T>&) const;
106 
107  Matrix<T> operator - (const T& scalar) const;
108 
109  Matrix<T> operator - (const Matrix<T>&) const;
110 
111  Matrix<T> operator * (const T&) const;
112 
113  Matrix<T> operator * (const Matrix<T>&) const;
114 
115  Matrix<T> operator * (const Tensor<T>&) const;
116 
117  Matrix<T> operator / (const T&) const;
118 
119  Matrix<T> operator / (const Vector<T>&) const;
120 
121  Matrix<T> operator / (const Matrix<T>&) const;
122 
123  void operator += (const T& value);
124 
125  void operator += (const Matrix<T>& other_matrix);
126 
127  void operator -= (const T&);
128 
129  void operator -= (const Matrix<T>&);
130 
131  void operator *= (const T&);
132 
133  void operator *= (const Matrix<T>&);
134 
135  void operator /= (const T&);
136 
137  void operator /= (const Matrix<T>&);
138 
139  // Get methods
140 
141  const size_t& get_rows_number() const;
142 
143  const size_t& get_columns_number() const;
144 
145  const Vector<string> get_header() const;
146 
147  const string get_header(const size_t&) const;
148 
149  size_t get_column_index(const string&) const;
150 
151  Vector<size_t> get_columns_indices(const Vector<string>&) const;
152 
153  Vector<size_t> get_binary_columns_indices() const;
154 
155  Vector<size_t> get_rows_equal_to(const Vector<T>&) const;
156 
157  Matrix<T> get_submatrix(const Vector<size_t>&, const Vector<size_t>&) const;
158 
159  Tensor<T> get_tensor(const Vector<size_t>&, const Vector<size_t>&, const Vector<size_t>&) const;
160 
161  Matrix<T> get_submatrix_rows(const Vector<size_t>&) const;
162  Matrix<T> get_submatrix_columns(const Vector<size_t>&) const;
163 
164  Vector<T> get_row(const size_t&) const;
165 
166  Vector<T> get_rows(const size_t&, const size_t&) const;
167 
168  Vector<T> get_row(const size_t&, const Vector<size_t>&) const;
169 
170  Vector<T> get_column(const size_t&) const;
171  Vector<T> get_column(const string&) const;
172 
173  Matrix<T> get_columns(const Vector<string>&) const;
174 
175  Vector<T> get_column(const size_t&, const Vector<size_t>&) const;
176 
177  Vector<T> get_diagonal() const;
178 
179  T get_first(const size_t&) const;
180  T get_first(const string&) const;
181 
182  T get_last(const size_t&) const;
183  T get_last(const string&) const;
184 
185  Vector<size_t> get_constant_columns_indices() const;
186 
187  Matrix<T> get_first_rows(const size_t&) const;
188  Matrix<T> get_first_columns(const size_t&) const;
189  Matrix<T> get_last_columns(const size_t&) const;
190  Matrix<T> get_last_rows(const size_t&) const;
191 
192  // Set methods
193 
194  void set();
195 
196  void set(const size_t&, const size_t&);
197 
198  void set(const size_t&, const size_t&, const T&);
199 
200  void set(const Matrix<T>&);
201 
202  void set(const string&);
203 
204  void set(const initializer_list<Vector<T>>&);
205 
206  void set_identity(const size_t&);
207 
208  void set_rows_number(const size_t&);
209 
210  void set_columns_number(const size_t&);
211 
212  void set_header(const Vector<string>&);
213 
214  void set_header(const size_t&, const string&);
215 
216  void set_row(const size_t&, const Vector<T>&);
217 
218  void set_row(const size_t&, const T&);
219 
220  void set_submatrix_rows(const size_t&, const Matrix<T>&);
221 
222  void set_column(const size_t&, const Vector<T>&, const string& = "");
223  void set_column(const string&, const Vector<T>&, const string& = "");
224 
225  void set_column(const string&, const T&, const string& = "");
226  void set_column(const size_t&, const T&, const string& = "");
227 
228  void set_diagonal(const T&);
229 
230  void set_diagonal(const Vector<T>&);
231 
232  // Check methods
233 
234  bool empty() const;
235 
236  bool is_square() const;
237 
238  bool is_symmetric() const;
239 
240  bool is_antisymmetric() const;
241 
242  bool is_diagonal() const;
243 
244  bool is_scalar() const;
245 
246  bool is_identity() const;
247 
248  bool is_binary() const;
249 
250  bool is_column_binary(const size_t&) const;
251 
252  bool is_column_constant(const size_t&) const;
253 
254  bool is_positive() const;
255 
256  bool is_row_equal_to(const size_t&, const Vector<size_t>&, const T&) const;
257 
258  bool has_column_value(const size_t&, const T&) const;
259 
260  // Count methods
261 
262  size_t count_diagonal_elements() const;
263 
264  size_t count_off_diagonal_elements() const;
265 
266  size_t count_equal_to(const T&) const;
267 
268  size_t count_equal_to(const size_t&, const T&) const;
269  size_t count_equal_to(const size_t&, const Vector<T>&) const;
270 
271  size_t count_equal_to(const size_t&, const Vector<T>&,
272  const size_t&, const T&) const;
273 
274  size_t count_equal_to(const size_t&, const Vector<T>&,
275  const size_t&, const T&,
276  const size_t&, const T&,
277  const size_t&, const T&) const;
278 
279  size_t count_equal_to(const size_t&, const T&, const size_t&, const T&) const;
280  size_t count_equal_to(const size_t&, const T&, const size_t&, const T&, const size_t&, const T&, const size_t&, const T&) const;
281 
282  size_t count_equal_to(const string&, const T&) const;
283  size_t count_equal_to(const string&, const Vector<T>&) const;
284  size_t count_equal_to(const string&, const T&, const string&, const T&) const;
285 
286  Vector<size_t> count_equal_to_by_rows(const T&) const;
287 
288  Vector<double> count_equal_to_by_rows(const T&, const Vector<double>&) const;
289 
290  size_t count_not_equal_to(const T&) const;
291 
292  size_t count_not_equal_to(const size_t&, const T&) const;
293  size_t count_not_equal_to(const size_t&, const Vector<T>&) const;
294 
295  size_t count_not_equal_to(const size_t&, const T&, const size_t&, const T&) const;
296 
297  size_t count_not_equal_to(const string&, const T&) const;
298  size_t count_not_equal_to(const string&, const T&, const string&, const T&) const;
299 
300  size_t count_rows_equal_to(const T&) const;
301  size_t count_rows_not_equal_to(const T&) const;
302 
303  size_t count_rows_equal_to(const Vector<size_t>&, const T&) const;
304  size_t count_columns_equal_to(const Vector<T>&, const T&) const;
305 
306  Vector<size_t> count_unique_elements() const;
307 
308  Vector<size_t> count_column_occurrences(const T&) const;
309 
310  // Not a number
311 
312  bool has_nan() const;
313 
314  bool has_nan_row(const size_t&) const;
315  bool has_nan_column(const size_t&) const;
316 
317  size_t count_nan() const;
318  size_t count_not_NAN() const;
319 
320  size_t count_rows_with_nan() const;
321  Vector<size_t> get_nan_indices() const;
322  size_t count_columns_with_nan() const;
323 
324  Vector<size_t> count_nan_rows() const;
325  Vector<size_t> count_nan_columns() const;
326 
327  // FILTER
328 
329  void filter(const T&, const T&);
330 
331  Matrix<T> filter_column_equal_to(const size_t&, const T&) const;
332  Matrix<T> filter_column_equal_to(const string&, const T&) const;
333 
334  Matrix<T> filter_column_equal_to(const size_t&, const Vector<T>&) const;
335  Matrix<T> filter_column_equal_to(const string&, const Vector<T>&) const;
336 
337  Matrix<T> filter_column_equal_to(const size_t&, const Vector<T>&,
338  const size_t&, const T&) const;
339 
340  Matrix<T> filter_column_equal_to(const string&, const Vector<T>&,
341  const string&, const T&) const;
342 
343  Matrix<T> filter_column_equal_to(const size_t&, const T&,
344  const size_t&, const T&,
345  const size_t&, const T&,
346  const size_t&, const T&) const;
347 
348  Matrix<T> filter_column_equal_to(const string&, const T&,
349  const string&, const T&,
350  const string&, const T&,
351  const string&, const T&) const;
352 
353  Matrix<T> filter_column_equal_to(const size_t&, const Vector<T>&,
354  const size_t&, const T&,
355  const size_t&, const T&,
356  const size_t&, const T&) const;
357 
358  Matrix<T> filter_column_equal_to(const string&, const Vector<T>&,
359  const string&, const T&,
360  const string&, const T&,
361  const string&, const T&) const;
362 
363  Matrix<T> filter_column_not_equal_to(const size_t&, const T&) const;
364  Matrix<T> filter_column_not_equal_to(const string&, const T&) const;
365 
366  Matrix<T> filter_column_not_equal_to(const string&, const Vector<T>&) const;
367  Matrix<T> filter_column_not_equal_to(const size_t&, const Vector<T>&) const;
368 
369  Matrix<T> filter_column_less_than(const size_t&, const T&) const;
370  Matrix<T> filter_column_less_than(const string&, const T&) const;
371 
372  Matrix<T> filter_column_greater_than(const size_t&, const T&) const;
373  Matrix<T> filter_column_greater_than(const string&, const T&) const;
374 
375  Matrix<T> filter_column_less_than_string(const string&, const double&) const;
376  Matrix<T> filter_column_greater_than_string(const string&, const double&) const;
377 
378  Matrix<T> filter_column_minimum_maximum(const size_t&, const T&, const T&) const;
379  Matrix<T> filter_column_minimum_maximum(const string&, const T&, const T&) const;
380 
381  Matrix<T> filter_extreme_values(const size_t&, const double&, const double&) const;
382  Matrix<T> filter_extreme_values(const string&, const double&, const double&) const;
383 
384  // INITIALIZATION
385 
386  void initialize(const T&);
387  void initialize_sequential();
388 
389  void randomize_uniform(const double& = -1.0, const double& = 1.0);
390  void randomize_uniform(const Vector<double>&, const Vector<double>&);
391  void randomize_uniform(const Matrix<double>&, const Matrix<double>&);
392 
393  void randomize_normal(const double& = 0.0, const double& = 1.0);
394  void randomize_normal(const Vector<double>&, const Vector<double>&);
395  void randomize_normal(const Matrix<double>&, const Matrix<double>&);
396 
397  void initialize_identity();
398 
399  void initialize_diagonal(const T&);
400 
401  void initialize_diagonal(const size_t&, const T&);
402 
403  void initialize_diagonal(const size_t&, const Vector<T>&);
404 
405  void append_header(const string&);
406 
407  void embed(const size_t&, const size_t&, const Matrix<T>&);
408 
409  void embed(const size_t&, const size_t&, const Vector<T>&);
410 
411  void sum_diagonal(const T&);
412 
413  void multiply_diagonal(const T&);
414 
415  void sum_diagonal(const Vector<T>&);
416 
417  Matrix<T> append_row(const Vector<T>&) const;
418 
419  Matrix<T> append_column(const Vector<T>&, const string& = "") const;
420 
421  Matrix<T> insert_row(const size_t&, const Vector<T>&) const;
422 
423  void insert_row_values(const size_t&, const size_t&, const Vector<T>&);
424 
425  Matrix<T> insert_column(const size_t&, const Vector<T>&, const string& = "") const;
426  Matrix<T> insert_column(const string&, const Vector<T>&, const string& = "") const;
427 
428  Matrix<T> insert_matrix(const size_t&, const Matrix<T>&) const;
429 
430  Matrix<T> insert_padding(const size_t& , const size_t&) const;
431 
432  Matrix<T> add_columns(const size_t&) const;
433  Matrix<T> add_columns_first(const size_t&) const;
434 
435  void split_column(const string&, const Vector<string>&, const char& = ',', const string& = "NA");
436 
437  void split_column(const string&, const string&, const string&, const size_t&, const size_t&);
438 
439  void swap_columns(const size_t&, const size_t&);
440  void swap_columns(const string&, const string&);
441 
442  // Merge mthods
443 
444  void merge_columns(const string&, const string&, const string&, const char&);
445  void merge_columns(const size_t&, const size_t&, const char&);
446 
447  Matrix<T> merge_matrices(const Matrix<T>&, const string&, const string&, const string& = "", const string& = "") const;
448  Matrix<T> merge_matrices(const Matrix<T>&, const size_t&, const size_t&) const;
449 
450  // Join methods
451 
452  Matrix<T> right_join(const Matrix<T>&, const string&, const string&, const string& = "", const string& = "") const;
453  Matrix<T> right_join(const Matrix<T>&, const size_t&, const size_t&) const;
454 
455  Matrix<T> left_join(const Matrix<T>&, const string&, const string&, const string& = "", const string& = "") const;
456  Matrix<T> left_join(const Matrix<T>&, const string&, const string&, const string&, const string&, const string& = "", const string& = "") const;
457  Matrix<T> left_join(const Matrix<T>&, const size_t&, const size_t&) const;
458 
459  // Delete methods
460 
461  Matrix<T> delete_row(const size_t&) const;
462  Matrix<T> delete_rows(const Vector<size_t>&) const;
463 
464  Matrix<T> delete_rows_with_value(const T&) const;
465  Matrix<T> delete_columns_with_value(const T&) const;
466 
467  Matrix<T> delete_rows_equal_to(const T&) const;
468 
469  Matrix<T> delete_first_rows(const size_t&) const;
470  Matrix<T> delete_last_rows(const size_t&) const;
471 
472  Matrix<T> delete_first_columns(const size_t&) const;
473  Matrix<T> delete_last_columns(const size_t&) const;
474 
475  Matrix<T> delete_column(const size_t&) const;
476  Matrix<T> delete_columns(const Vector<size_t>&) const;
477 
478  Matrix<T> delete_column(const string&) const;
479  Matrix<T> delete_columns(const Vector<string>&) const;
480 
481  Matrix<T> delete_columns_name_contains(const Vector<string>&) const;
482 
483  Matrix<T> delete_constant_rows() const;
484  Matrix<T> delete_constant_columns() const;
485 
486  Matrix<T> delete_binary_columns() const;
487 
488  Matrix<T> delete_binary_columns(const double&) const;
489 
490  // Assemble
491 
492  Matrix<T> assemble_rows(const Matrix<T>&) const;
493 
494  Matrix<T> assemble_columns(const Matrix<T>&) const;
495 
496  // SORTING
497 
498  Matrix<T> sort_ascending(const size_t&) const;
499  Matrix<T> sort_descending(const size_t&) const;
500 
501  Matrix<T> sort_ascending_strings(const size_t&) const;
502  Matrix<T> sort_descending_strings(const size_t&) const;
503 
504  Matrix<T> sort_rank_rows(const Vector<size_t>&) const;
505 
506  Matrix<T> sort_columns(const Vector<size_t>&) const;
507  Matrix<T> sort_columns(const Vector<string>&) const;
508 
509  // REPLACE
510 
511  void replace(const T&, const T&);
512 
513  void replace_header(const string&, const string&);
514 
515  void replace_in_row(const size_t&, const T&, const T&);
516  void replace_in_column(const size_t&, const T&, const T&);
517  void replace_in_column(const string&, const T&, const T&);
518 
519  void replace_substring(const string&, const string&);
520  void replace_substring(const size_t&, const string&, const string&);
521  void replace_substring(const string&, const string&, const string&);
522 
523  void replace_contains(const string&, const string&);
524  void replace_contains_in_row(const size_t&, const string&, const string&);
525 
526  void replace_column_equal_to(const size_t&, const T&, const T&);
527  void replace_column_equal_to(const string&, const T&, const T&);
528  void replace_column_not_equal_to(const string&, const T&, const T&);
529  void replace_column_not_equal_to(const string&, const Vector<T>&, const T&);
530 
531  void replace_column_less_than_string(const string&, const double&, const T&);
532 
533  void replace_column_contains(const string&, const string&, const string&);
534  size_t count_column_contains(const string&, const string&) const;
535 
536  // Mathematical methods
537 
538  T calculate_sum() const;
539 
540  Vector<T> calculate_rows_sum() const;
541  Vector<T> calculate_columns_sum() const;
542  T calculate_column_sum(const size_t&) const;
543  T calculate_row_sum(const size_t&) const;
544 
545  void sum_row(const size_t&, const Vector<T>&);
546  void sum_column(const size_t&, const Vector<T>&);
547  Matrix<T> sum_rows(const Vector<T>&) const;
548  Matrix<T> subtract_rows(const Vector<T>&) const;
549  Matrix<T> multiply_rows(const Vector<T>&) const;
550  Vector<Matrix<T>> multiply_rows(const Matrix<T>&) const;
551 
552 
553  double calculate_trace() const;
554 
555  Vector<double> calculate_missing_values_percentage() const;
556 
557  Matrix<size_t> get_indices_less_than(const T&) const;
558 
559  Matrix<size_t> get_indices_greater_than(const T&) const;
560 
561  Matrix<T> calculate_reverse_columns() const;
562 
563  Matrix<T> calculate_transpose() const;
564 
565  bool compare_rows(const size_t&, const Matrix<T>&, const size_t&) const;
566 
567  void divide_rows(const Vector<T>&);
568 
569  // CONVERSIONS
570 
571  string matrix_to_string(const char& = ' ') const;
572 
573  Matrix<size_t> to_size_t_matrix() const;
574  Matrix<float> to_float_matrix() const;
575  Matrix<double> to_double_matrix() const;
576  Matrix<string> to_string_matrix(const size_t& = 3) const;
577 
578  Matrix<double> to_zeros() const;
579  Matrix<double> to_ones() const;
580 
581  Matrix<double> bool_to_double() const;
582 
583  Matrix<size_t> string_to_size_t() const;
584  Matrix<double> string_to_double() const;
585 
586  vector<T> to_std_vector() const;
587 
588  Vector<T> to_vector() const;
589 
590  Vector<Vector<T>> to_vector_of_vectors() const;
591 
592  Vector< Matrix<T> > to_vector_matrix(const size_t&, const size_t&, const size_t&) const;
593 
594  Matrix<T> to_categorical(const size_t&) const;
595  Tensor<T> to_tensor() const;
596 
597  // Serialization methods
598 
599  void print() const;
600 
601  void load_csv(const string&, const char& = ',', const bool& = false, const string& = "NA");
602  void load_csv_string(const string&, const char& = ',', const bool& = true);
603  void load_binary(const string&);
604 
605  void save_binary(const string&) const;
606 
607  void save_csv(const string&, const char& = ',', const Vector<string>& = Vector<string>(), const string& = "Id") const;
608 
609  void save_json(const string&, const Vector<string>& = Vector<string>()) const;
610 
611  void parse(const string&);
612 
613  void print_preview() const;
614 
615 private:
616 
618 
619  size_t rows_number;
620 
622 
624 
626 
628 
629 };
630 
631 
633 
634 template <class T>
635 Matrix<T>::Matrix() : vector<T>()
636 {
637  set();
638 }
639 
640 
645 
646 template <class T>
647 Matrix<T>::Matrix(const size_t& new_rows_number, const size_t& new_columns_number) : vector<T>(new_rows_number*new_columns_number)
648 {
649  if(new_rows_number == 0 && new_columns_number == 0)
650  {
651  set();
652  }
653  else if(new_rows_number == 0)
654  {
655  set();
656  }
657  else if(new_columns_number == 0)
658  {
659  set();
660  }
661  else
662  {
663  set(new_rows_number,new_columns_number);
664  }
665 }
666 
667 
673 
674 template <class T>
675 Matrix<T>::Matrix(const size_t& new_rows_number, const size_t& new_columns_number, const T& value) : vector<T>(new_rows_number*new_columns_number)
676 {
677  if(new_rows_number == 0 && new_columns_number == 0)
678  {
679  set();
680  }
681  else if(new_rows_number == 0)
682  {
683  ostringstream buffer;
684 
685  buffer << "OpenNN Exception: Matrix Template.\n"
686  << "Constructor Matrix(const size_t&, const size_t&, const T&).\n"
687  << "Number of rows must be greater than zero.\n";
688 
689  throw logic_error(buffer.str());
690  }
691  else if(new_columns_number == 0)
692  {
693  ostringstream buffer;
694 
695  buffer << "OpenNN Exception: Matrix Template.\n"
696  << "Constructor Matrix(const size_t&, const size_t&, const T&).\n"
697  << "Number of columns must be greater than zero.\n";
698 
699  throw logic_error(buffer.str());
700  }
701  else
702  {
703  // Set sizes
704 
705  set(new_rows_number,new_columns_number,value);
706  }
707 }
708 
709 
714 
715 template <class T>
716 Matrix<T>::Matrix(const string& file_name, const char& separator, const bool& header) : vector<T>()
717 {
718  rows_number = 0;
719  columns_number = 0;
720 
721  load_csv(file_name, separator, header);
722 }
723 
724 
727 
728 template <class T>
729 Matrix<T>::Matrix(const Matrix& other_matrix) : vector<T>(other_matrix.begin(), other_matrix.end())
730 {
731  rows_number = other_matrix.rows_number;
732  columns_number = other_matrix.columns_number;
733 
734  header = other_matrix.header;
735 }
736 
737 
738 template <class T>
739 Matrix<T>::Matrix(const initializer_list<Vector<T>>& new_columns) : vector<T>()
740 {
741  set(new_columns);
742 }
743 
744 
745 template <class T>
746 Matrix<T>::Matrix(const initializer_list<Vector<T>>& new_columns, const initializer_list<string>& new_header) : vector<T>()
747 {
748  set(new_columns);
749 
750  set_header(new_header);
751 }
752 
753 
755 
756 template <class T>
758 {
759  rows_number = 0;
760  columns_number = 0;
761 }
762 
763 
766 
767 template <class T>
769 {
770  if(other_matrix.rows_number != rows_number || other_matrix.columns_number != columns_number)
771  {
772  rows_number = other_matrix.rows_number;
773  columns_number = other_matrix.columns_number;
774 
775  set(rows_number, columns_number);
776  }
777 
778  copy(other_matrix.begin(), other_matrix.end(), this->begin());
779 
780  copy(other_matrix.header.begin(), other_matrix.header.end(), header.begin());
781 
782  return *this;
783 }
784 
785 
786 // REFERENCE OPERATORS
787 
789 
793 
794 template <class T>
795 inline T& Matrix<T>::operator()(const size_t& row, const size_t& column)
796 {
797  #ifdef __OPENNN_DEBUG__
798 
799  if(row >= rows_number)
800  {
801  ostringstream buffer;
802 
803  buffer << "OpenNN Exception: Matrix Template.\n"
804  << "operator()(const size_t&, const size_t&).\n"
805  << "Row index (" << row << ") must be less than number of rows (" << rows_number << ").\n";
806 
807  throw logic_error(buffer.str());
808  }
809  else if(column >= columns_number)
810  {
811  ostringstream buffer;
812 
813  buffer << "OpenNN Exception: Matrix Template.\n"
814  << "operator()(const size_t&, const size_t&).\n"
815  << "Column index (" << column << ") must be less than number of columns (" << columns_number << ").\n";
816 
817  throw logic_error(buffer.str());
818  }
819 
820  #endif
821 
822  // Return matrix element
823 
824  return (*this)[rows_number*column+row];
825 }
826 
827 
829 
833 
834 template <class T>
835 inline const T& Matrix<T>::operator()(const size_t& row, const size_t& column) const
836 {
837  #ifdef __OPENNN_DEBUG__
838 
839  if(row >= rows_number)
840  {
841  ostringstream buffer;
842 
843  buffer << "OpenNN Exception: Matrix Template.\n"
844  << "operator()(const size_t&, const size_t&).\n"
845  << "Row index (" << row << ") must be less than number of rows (" << rows_number << ").\n";
846 
847  throw logic_error(buffer.str());
848  }
849  else if(column >= columns_number)
850  {
851  ostringstream buffer;
852 
853  buffer << "OpenNN Exception: Matrix Template.\n"
854  << "operator()(const size_t&, const size_t&).\n"
855  << "Column index (" << column << ") must be less than number of columns (" << columns_number << ").\n";
856 
857  throw logic_error(buffer.str());
858  }
859 
860  #endif
861 
862  // Return matrix element
863 
864  return (*this)[rows_number*column+row];
865 }
866 
867 
868 template <class T>
869 inline T& Matrix<T>::operator()(const size_t& row, const string& column_name)
870 {
871  const size_t column = get_column_index(column_name);
872 
873  return (*this)(row, column);
874 }
875 
876 
878 
879 template <class T>
880 inline const T& Matrix<T>::operator()(const size_t& row, const string& column_name) const
881 {
882  const size_t column = get_column_index(column_name);
883 
884  return (*this)(row, column);
885 }
886 
887 
891 
892 template <class T>
893 bool Matrix<T>::operator == (const Matrix<T>& other_matrix) const
894 {
895  const size_t other_rows_number = other_matrix.get_rows_number();
896  const size_t other_columns_number = other_matrix.get_columns_number();
897 
898  if(other_rows_number != rows_number)
899  {
900  return false;
901  }
902  else if(other_columns_number != columns_number)
903  {
904  return false;
905  }
906  else
907  {
908  for(size_t i = 0; i < this->size(); i++)
909  {
910  if((*this)[i] != other_matrix[i])
911  {
912  return false;
913  }
914  }
915  }
916 
917  return true;
918 }
919 
920 
924 
925 template <class T>
926 bool Matrix<T>::operator == (const T& value) const
927 {
928  for(size_t i = 0; i < this->size(); i++)
929  {
930  if((*this)[i] != value)
931  {
932  return false;
933  }
934  }
935 
936  return true;
937 }
938 
939 
943 
944 template <class T>
945 bool Matrix<T>::operator != (const Matrix<T>& other_matrix) const
946 {
947 
948 
949  #ifdef __OPENNN_DEBUG__
950 
951  const size_t other_rows_number = other_matrix.get_rows_number();
952  const size_t other_columns_number = other_matrix.get_columns_number();
953 
954  if(other_rows_number != rows_number)
955  {
956  ostringstream buffer;
957 
958  buffer << "OpenNN Exception: Matrix Template.\n"
959  << "bool operator != (const Matrix<T>&) const.\n"
960  << "Both numbers of rows must be the same.\n";
961 
962  throw logic_error(buffer.str());
963  }
964  else if(other_columns_number != columns_number)
965  {
966  ostringstream buffer;
967 
968  buffer << "OpenNN Exception: Matrix Template.\n"
969  << "bool operator != (const Matrix<T>&) const.\n"
970  << "Both numbers of columns must be the same.\n";
971 
972  throw logic_error(buffer.str());
973  }
974 
975  #endif
976 
977  for(size_t i = 0; i < this->size(); i++)
978  {
979  if((*this)[i] != other_matrix[i])
980  {
981  return true;
982  }
983  }
984 
985  return false;
986 }
987 
988 
992 
993 template <class T>
994 bool Matrix<T>::operator != (const T& value) const
995 {
996 
997 
998  for(size_t i = 0; i < this->size(); i++)
999  {
1000  if((*this)[i] != value)
1001  {
1002  return true;
1003  }
1004  }
1005 
1006  return false;
1007 }
1008 
1009 
1014 
1015 template <class T>
1016 bool Matrix<T>::operator >(const Matrix<T>& other_matrix) const
1017 {
1018 
1019 
1020  #ifdef __OPENNN_DEBUG__
1021 
1022  const size_t other_rows_number = other_matrix.get_rows_number();
1023  const size_t other_columns_number = other_matrix.get_columns_number();
1024 
1025  if(other_rows_number != rows_number)
1026  {
1027  ostringstream buffer;
1028 
1029  buffer << "OpenNN Exception: Matrix Template.\n"
1030  << "bool operator >(const Matrix<T>&) const.\n"
1031  << "Both numbers of rows must be the same.\n";
1032 
1033  throw logic_error(buffer.str());
1034  }
1035  else if(other_columns_number != columns_number)
1036  {
1037  ostringstream buffer;
1038 
1039  buffer << "OpenNN Exception: Matrix Template.\n"
1040  << "bool operator >(const Matrix<T>&) const.\n"
1041  << "Both numbers of columns must be the same.\n";
1042 
1043  throw logic_error(buffer.str());
1044  }
1045 
1046  #endif
1047 
1048  for(size_t i = 0; i < this->size(); i++)
1049  {
1050  if((*this)[i] <= other_matrix[i])
1051  {
1052  return false;
1053  }
1054  }
1055 
1056  return true;
1057 }
1058 
1059 
1063 
1064 template <class T>
1065 bool Matrix<T>::operator >(const T& value) const
1066 {
1067  for(size_t i = 0; i < this->size(); i++)
1068  {
1069  if((*this)[i] <= value)
1070  {
1071  return false;
1072  }
1073  }
1074 
1075  return true;
1076 }
1077 
1078 
1083 
1084 template <class T>
1085 bool Matrix<T>::operator <(const Matrix<T>& other_matrix) const
1086 {
1087 
1088 
1089  #ifdef __OPENNN_DEBUG__
1090 
1091  const size_t other_rows_number = other_matrix.get_rows_number();
1092  const size_t other_columns_number = other_matrix.get_columns_number();
1093 
1094  if(other_rows_number != rows_number)
1095  {
1096  ostringstream buffer;
1097 
1098  buffer << "OpenNN Exception: Matrix Template.\n"
1099  << "bool operator <(const Matrix<T>&) const.\n"
1100  << "Both numbers of rows must be the same.\n";
1101 
1102  throw logic_error(buffer.str());
1103  }
1104  else if(other_columns_number != columns_number)
1105  {
1106  ostringstream buffer;
1107 
1108  buffer << "OpenNN Exception: Matrix Template.\n"
1109  << "bool operator <(const Matrix<T>&) const.\n"
1110  << "Both numbers of columns must be the same.\n";
1111 
1112  throw logic_error(buffer.str());
1113  }
1114 
1115  #endif
1116 
1117  for(size_t i = 0; i < this->size(); i++)
1118  {
1119  if((*this)[i] >= other_matrix[i])
1120  {
1121  return false;
1122  }
1123  }
1124 
1125  return true;
1126 }
1127 
1128 
1132 
1133 template <class T>
1134 bool Matrix<T>::operator <(const T& value) const
1135 {
1136  for(size_t i = 0; i < this->size(); i++)
1137  {
1138  if((*this)[i] >= value)
1139  {
1140  return false;
1141  }
1142  }
1143 
1144  return true;
1145 }
1146 
1147 
1152 
1153 template <class T>
1154 bool Matrix<T>::operator >= (const Matrix<T>& other_matrix) const
1155 {
1156 
1157 
1158  #ifdef __OPENNN_DEBUG__
1159 
1160  const size_t other_rows_number = other_matrix.get_rows_number();
1161  const size_t other_columns_number = other_matrix.get_columns_number();
1162 
1163  if(other_rows_number != rows_number)
1164  {
1165  ostringstream buffer;
1166 
1167  buffer << "OpenNN Exception: Matrix Template.\n"
1168  << "bool operator >= (const Matrix<T>&) const.\n"
1169  << "Both numbers of rows must be the same.\n";
1170 
1171  throw logic_error(buffer.str());
1172  }
1173  else if(other_columns_number != columns_number)
1174  {
1175  ostringstream buffer;
1176 
1177  buffer << "OpenNN Exception: Matrix Template.\n"
1178  << "bool operator >= (const Matrix<T>&) const.\n"
1179  << "Both numbers of columns must be the same.\n";
1180 
1181  throw logic_error(buffer.str());
1182  }
1183 
1184  #endif
1185 
1186  for(size_t i = 0; i < this->size(); i++)
1187  {
1188  if((*this)[i] < other_matrix[i])
1189  {
1190  return false;
1191  }
1192  }
1193 
1194  return true;
1195 }
1196 
1197 
1201 
1202 template <class T>
1203 bool Matrix<T>::operator >= (const T& value) const
1204 {
1205  for(size_t i = 0; i < this->size(); i++)
1206  {
1207  if((*this)[i] < value)
1208  {
1209  return false;
1210  }
1211  }
1212 
1213  return true;
1214 }
1215 
1216 
1221 
1222 template <class T>
1223 bool Matrix<T>::operator <= (const Matrix<T>& other_matrix) const
1224 {
1225  #ifdef __OPENNN_DEBUG__
1226 
1227  const size_t other_rows_number = other_matrix.get_rows_number();
1228  const size_t other_columns_number = other_matrix.get_columns_number();
1229 
1230  if(other_rows_number != rows_number)
1231  {
1232  ostringstream buffer;
1233 
1234  buffer << "OpenNN Exception: Matrix Template.\n"
1235  << "bool operator >= (const Matrix<T>&) const.\n"
1236  << "Both numbers of rows must be the same.\n";
1237 
1238  throw logic_error(buffer.str());
1239  }
1240  else if(other_columns_number != columns_number)
1241  {
1242  ostringstream buffer;
1243 
1244  buffer << "OpenNN Exception: Matrix Template.\n"
1245  << "bool operator >= (const Matrix<T>&) const.\n"
1246  << "Both numbers of columns must be the same.\n";
1247 
1248  throw logic_error(buffer.str());
1249  }
1250 
1251  #endif
1252 
1253  for(size_t i = 0; i < this->size(); i++)
1254  {
1255  if((*this)[i] > other_matrix[i])
1256  {
1257  return false;
1258  }
1259  }
1260 
1261  return true;
1262 }
1263 
1264 
1268 
1269 template <class T>
1270 bool Matrix<T>::operator <= (const T& value) const
1271 {
1272  for(size_t i = 0; i < this->size(); i++)
1273  {
1274  if((*this)[i] > value)
1275  {
1276  return false;
1277  }
1278  }
1279 
1280  return true;
1281 }
1282 
1283 
1285 
1286 template <class T>
1287 const size_t& Matrix<T>::get_rows_number() const
1288 {
1289  return rows_number;
1290 }
1291 
1292 
1294 
1295 template <class T>
1296 const size_t& Matrix<T>::get_columns_number() const
1297 {
1298  return columns_number;
1299 }
1300 
1301 
1303 
1304 template <class T>
1306 {
1307  return(header);
1308 }
1309 
1310 
1313 
1314 template <class T>
1315 const string Matrix<T>::get_header(const size_t& index) const
1316 {
1317  return(header[index]);
1318 }
1319 
1320 
1323 
1324 template <class T>
1325 size_t Matrix<T>::get_column_index(const string& column_name) const
1326 {
1327  if(rows_number == 0)
1328  {
1329  ostringstream buffer;
1330 
1331  buffer << "OpenNN Exception: Matrix Template.\n"
1332  << "size_t get_column_index(const string&) const.\n"
1333  << "Number of rows must be greater than zero.\n";
1334 
1335  throw logic_error(buffer.str());
1336  }
1337 
1338  size_t count = 0;
1339 
1340  for(size_t i = 0; i < columns_number; i++)
1341  {
1342  if(header[i] == column_name)
1343  {
1344  count++;
1345  }
1346  }
1347 
1348  if(count == 0)
1349  {
1350  ostringstream buffer;
1351 
1352  buffer << "OpenNN Exception: Matrix Template.\n"
1353  << "size_t get_column_index(const string&) const.\n"
1354  << "Header does not contain " << column_name << ":\n"
1355  << header;
1356 
1357  throw logic_error(buffer.str());
1358  }
1359 
1360  if(count > 1)
1361  {
1362  ostringstream buffer;
1363 
1364  buffer << "OpenNN Exception: Matrix Template.\n"
1365  << "size_t get_column_index(const string&) const.\n"
1366  << "Multiple occurrences of column name " << column_name << ".\n";
1367 
1368  throw logic_error(buffer.str());
1369  }
1370 
1371  size_t index;
1372 
1373  for(size_t i = 0; i < columns_number; i++)
1374  {
1375  if(header[i] == column_name)
1376  {
1377  index = i;
1378  }
1379  }
1380 
1381  return index;
1382 }
1383 
1384 
1387 
1388 template <class T>
1390 {
1391  const size_t size = names.size();
1392 
1393  if(header == "")
1394  {
1395  ostringstream buffer;
1396 
1397  buffer << "OpenNN Exception: Matrix Template.\n"
1398  << "Vector<size_t> get_columns_indices(const Vector<string>&) const.\n"
1399  << "Header is empty.\n";
1400 
1401  throw logic_error(buffer.str());
1402  }
1403 
1404  size_t count = 0;
1405 
1406  for(size_t i = 0; i < size; i++)
1407  {
1408  for(size_t j = 0; j < header.size(); j++)
1409  {
1410  if(names[i] == header[j])
1411  {
1412  count++;
1413  break;
1414  }
1415  }
1416  }
1417 
1418  if(size != count)
1419  {
1420  ostringstream buffer;
1421 
1422  buffer << "OpenNN Exception: Matrix Template.\n"
1423  << "Vector<size_t> get_columns_indices(const Vector<string>&) const.\n"
1424  << "Header does not contain some name.\n";
1425 
1426  buffer << "Header: " << header << endl;
1427 
1428 
1429  buffer << "Names: " << names << endl;
1430 
1431  throw logic_error(buffer.str());
1432  }
1433 
1434  Vector<size_t> indices(size);
1435 
1436  for(size_t i = 0; i < size; i++)
1437  {
1438  indices[i] = get_column_index(names[i]);
1439  }
1440 
1441  return indices;
1442 }
1443 
1444 
1446 
1447 template <class T>
1449 {
1450  Vector<size_t> binary_columns;
1451 
1452  for(size_t i = 0; i < columns_number; i++)
1453  {
1454  if(is_column_binary(i))
1455  {
1456  binary_columns.push_back(i);
1457  }
1458  }
1459 
1460  return binary_columns;
1461 }
1462 
1463 
1465 
1466 template <class T>
1468 {
1469  rows_number = 0;
1470  columns_number = 0;
1471 
1472  Vector<string>().swap(header);
1473 
1474  vector<T>().swap(*this);
1475 }
1476 
1477 
1481 
1482 template <class T>
1483 void Matrix<T>::set(const size_t& new_rows_number, const size_t& new_columns_number)
1484 {
1485  if(new_rows_number == 0 && new_columns_number == 0)
1486  {
1487  set();
1488  }
1489  else if(new_rows_number == 0)
1490  {
1491  set();
1492  }
1493  else if(new_columns_number == 0)
1494  {
1495  set();
1496  }
1497  else
1498  {
1499  rows_number = new_rows_number;
1500  columns_number = new_columns_number;
1501 
1502  this->resize(rows_number*columns_number);
1503 
1504  header.set(columns_number, "");
1505  }
1506 }
1507 
1508 
1514 
1515 template <class T>
1516 void Matrix<T>::set(const size_t& new_rows_number, const size_t& new_columns_number, const T& value)
1517 {
1518  if(new_rows_number == 0 && new_columns_number == 0)
1519  {
1520  set();
1521  }
1522  else if(new_rows_number == 0)
1523  {
1524  ostringstream buffer;
1525 
1526  buffer << "OpenNN Exception: Matrix Template.\n"
1527  << "void set(const size_t&, const size_t&, const T&) method.\n"
1528  << "Number of rows must be greater than zero.\n";
1529 
1530  throw logic_error(buffer.str());
1531  }
1532  else if(new_columns_number == 0)
1533  {
1534  ostringstream buffer;
1535 
1536  buffer << "OpenNN Exception: Matrix Template.\n"
1537  << "void set(const size_t&, const size_t&, const T&) method.\n"
1538  << "Number of columns must be greater than zero.\n";
1539 
1540  throw logic_error(buffer.str());
1541  }
1542  else
1543  {
1544  set(new_rows_number, new_columns_number);
1545  initialize(value);
1546  }
1547 }
1548 
1549 
1552 
1553 template <class T>
1554 void Matrix<T>::set(const Matrix<T>& other_matrix)
1555 {
1556  if(other_matrix.rows_number != this->rows_number || other_matrix.columns_number != this->columns_number)
1557  {
1558  rows_number = other_matrix.rows_number;
1559  columns_number = other_matrix.columns_number;
1560 
1561  set(rows_number, columns_number);
1562  }
1563 
1564  copy(other_matrix.begin(), other_matrix.end(), this->begin());
1565 
1566  copy(other_matrix.header.begin(), other_matrix.header.end(), header.begin());
1567 }
1568 
1569 
1572 
1573 template <class T>
1574 void Matrix<T>::set(const string& file_name)
1575 {
1576  load_csv(file_name);
1577 }
1578 
1579 
1581 
1582 template <class T>
1583 void Matrix<T>::set(const initializer_list<Vector<T>>& columns)
1584 {
1585  if(columns.size() == 0)
1586  {
1587  set();
1588  }
1589 
1590  const size_t new_columns_number = columns.size();
1591 
1592  const size_t new_rows_number = (*columns.begin()).size();
1593 
1594  if(new_rows_number == 0)
1595  {
1596  ostringstream buffer;
1597 
1598  buffer << "OpenNN Exception: Matrix Template.\n"
1599  << "void set(const initializer_list<Vector<T>>&) method.\n"
1600  << "Size of list vectors must be greater than zero.\n";
1601 
1602  throw logic_error(buffer.str());
1603  }
1604 
1605  set(new_rows_number, new_columns_number);
1606 
1607  for(size_t i = 0; i < new_columns_number; i++)
1608  {
1609  const Vector<T> new_column(*(columns.begin() + i));
1610 
1611  if(new_column.size() != new_rows_number)
1612  {
1613  ostringstream buffer;
1614 
1615  buffer << "OpenNN Exception: Matrix Template.\n"
1616  << "Matrix(const initializer_list<Vector<T>>& list) constructor.\n"
1617  << "Size of vector " << i << " (" << new_column.size() << ") must be equal to number of rows (" << new_rows_number << ").\n";
1618 
1619  throw logic_error(buffer.str());
1620  }
1621 
1622  set_column(i, new_column);
1623  }
1624 }
1625 
1626 
1629 
1630 template <class T>
1631 void Matrix<T>::set_identity(const size_t& new_size)
1632 {
1633  set(new_size, new_size);
1634  initialize_identity();
1635 }
1636 
1637 
1640 
1641 template <class T>
1642 void Matrix<T>::set_rows_number(const size_t& new_rows_number)
1643 {
1644  if(new_rows_number != rows_number)
1645  {
1646  set(new_rows_number, columns_number);
1647  }
1648 }
1649 
1650 
1653 
1654 template <class T>
1655 void Matrix<T>::set_columns_number(const size_t& new_columns_number)
1656 {
1657  if(new_columns_number != columns_number)
1658  {
1659  set(rows_number, new_columns_number);
1660  }
1661 }
1662 
1663 
1666 
1667 template <class T>
1668 void Matrix<T>::set_header(const Vector<string>& new_header)
1669 {
1670  this->header = new_header;
1671 }
1672 
1673 
1677 
1678 template <class T>
1679 void Matrix<T>::set_header(const size_t& index, const string& index_name)
1680 {
1681  header[index] = index_name;
1682 }
1683 
1684 
1686 
1687 template <class T>
1688 void Matrix<T>::append_header(const string& str)
1689 {
1690  for(size_t i = 0; i < header.size(); i++)
1691  {
1692  header[i].append(str);
1693  }
1694 }
1695 
1696 
1701 
1702 template <class T>
1703 void Matrix<T>::embed(const size_t& row_position, const size_t& column_position, const Matrix<T>& other_matrix)
1704 {
1705  const size_t other_rows_number = other_matrix.get_rows_number();
1706  const size_t other_columns_number = other_matrix.get_columns_number();
1707 
1708  #ifdef __OPENNN_DEBUG__
1709 
1710  if(row_position + other_rows_number > rows_number)
1711  {
1712  ostringstream buffer;
1713 
1714  buffer << "OpenNN Exception: Matrix Template.\n"
1715  << "void insert(const size_t&, const size_t&, const Matrix<T>&) const method.\n"
1716  << "Cannot tuck in matrix.\n";
1717 
1718  throw logic_error(buffer.str());
1719  }
1720 
1721  if(column_position + other_columns_number > columns_number)
1722  {
1723  ostringstream buffer;
1724 
1725  buffer << "OpenNN Exception: Matrix Template.\n"
1726  << "void insert(const size_t&, const size_t&, const Matrix<T>&) const method.\n"
1727  << "Cannot tuck in matrix.\n";
1728 
1729  throw logic_error(buffer.str());
1730  }
1731 
1732  #endif
1733 
1734  for(size_t i = 0; i < other_rows_number; i++)
1735  {
1736  for(size_t j = 0; j < other_columns_number; j++)
1737  {
1738  (*this)(row_position+i,column_position+j) = other_matrix(i,j);
1739  }
1740  }
1741 }
1742 
1743 
1748 
1749 template <class T>
1750 void Matrix<T>::embed(const size_t& row_position, const size_t& column_position, const Vector<T>& other_vector)
1751 {
1752  const size_t other_columns_number = other_vector.size();
1753 
1754  #ifdef __OPENNN_DEBUG__
1755 
1756  if(row_position > rows_number)
1757  {
1758  ostringstream buffer;
1759 
1760  buffer << "OpenNN Exception: Matrix Template.\n"
1761  << "void insert(const size_t&, const size_t&, const Vector<T>&) const method.\n"
1762  << "Cannot tuck in vector.\n";
1763 
1764  throw logic_error(buffer.str());
1765  }
1766 
1767  if(column_position + other_columns_number > columns_number)
1768  {
1769  ostringstream buffer;
1770 
1771  buffer << "OpenNN Exception: Matrix Template.\n"
1772  << "void insert(const size_t&, const size_t&, const Vector<T>&) const method.\n"
1773  << "Cannot tuck in vector.\n";
1774 
1775  throw logic_error(buffer.str());
1776  }
1777 
1778  #endif
1779 
1780  for(size_t j = 0; j < other_columns_number; j++)
1781  {
1782  (*this)(row_position,column_position+j) = other_vector[j];
1783  }
1784 }
1785 
1786 
1789 
1790 template <class T>
1792 {
1793  #ifdef __OPENNN_DEBUG__
1794 
1795  if(!is_square())
1796  {
1797  ostringstream buffer;
1798 
1799  buffer << "OpenNN Exception: Matrix Template.\n"
1800  << "size_t count_diagonal_elements() const method.\n"
1801  << "The matrix is not square.\n";
1802 
1803  throw logic_error(buffer.str());
1804  }
1805 
1806  #endif
1807 
1808  size_t count = 0;
1809 
1810  for(size_t i = 0; i < rows_number; i++)
1811  {
1812  if((*this)(i,i) != 0)
1813  {
1814  count++;
1815  }
1816  }
1817 
1818  return count;
1819 }
1820 
1821 
1824 
1825 template <class T>
1827 {
1828  #ifdef __OPENNN_DEBUG__
1829 
1830  if(!is_square())
1831  {
1832  ostringstream buffer;
1833 
1834  buffer << "OpenNN Exception: Matrix Template.\n"
1835  << "size_t count_off_diagonal_elements() const method.\n"
1836  << "The matrix is not square.\n";
1837 
1838  throw logic_error(buffer.str());
1839  }
1840 
1841  #endif
1842 
1843  size_t count = 0;
1844 
1845  for(size_t i = 0; i < rows_number; i++)
1846  {
1847  for(size_t j = 0; j < columns_number; j++)
1848  {
1849  if(i != j &&(*this)(i,j) != 0)
1850  {
1851  count++;
1852  }
1853  }
1854  }
1855 
1856  return count;
1857 }
1858 
1859 
1862 
1863 template <class T>
1864 size_t Matrix<T>::count_equal_to(const T& value) const
1865 {
1866  size_t count = 0;
1867 
1868  for(size_t i = 0; i < rows_number; i++)
1869  {
1870  for(size_t j = 0; j < columns_number; j++)
1871  {
1872  if((*this)(i, j) == value)
1873  {
1874  count++;
1875  }
1876  }
1877  }
1878 
1879  return count;
1880 }
1881 
1882 
1886 
1887 template <class T>
1888 size_t Matrix<T>::count_equal_to(const size_t& column_index, const T& value) const
1889 {
1890  size_t count = 0;
1891 
1892  for(size_t i = 0; i < rows_number; i++)
1893  {
1894  if((*this)(i, column_index) == value)
1895  {
1896  count++;
1897  }
1898  }
1899 
1900  return count;
1901 }
1902 
1903 
1907 
1908 template <class T>
1909 size_t Matrix<T>::count_equal_to(const size_t& column_index, const Vector<T>& values) const
1910 {
1911  const size_t values_size = values.size();
1912 
1913  size_t count = 0;
1914 
1915  for(size_t i = 0; i < rows_number; i++)
1916  {
1917  for(size_t j = 0; j < values_size; j++)
1918  {
1919  if((*this)(i, column_index) == values[j])
1920  {
1921  count++;
1922 
1923  break;
1924  }
1925  }
1926  }
1927 
1928  return count;
1929 }
1930 
1931 
1938 
1939 template <class T>
1940 size_t Matrix<T>::count_equal_to(const size_t& column_1_index, const Vector<T>& values_1,
1941  const size_t& column_2_index, const T& value_2) const
1942 {
1943  const size_t values_1_size = values_1.size();
1944 
1945  size_t count = 0;
1946 
1947  T matrix_element;
1948 
1949  for(size_t i = 0; i < rows_number; i++)
1950  {
1951  if((*this)(i, column_2_index) == value_2)
1952  {
1953  matrix_element = (*this)(i, column_1_index);
1954 
1955  for(size_t j = 0; j < values_1_size; j++)
1956  {
1957  if(matrix_element == values_1[j])
1958  {
1959  count++;
1960 
1961  break;
1962  }
1963  }
1964  }
1965  }
1966 
1967  return count;
1968 }
1969 
1970 
1982 
1983 template <class T>
1984 size_t Matrix<T>::count_equal_to(const size_t& column_1_index, const Vector<T>& values_1,
1985  const size_t& column_2_index, const T& value_2,
1986  const size_t& column_3_index, const T& value_3,
1987  const size_t& column_4_index, const T& value_4) const
1988 {
1989  const size_t values_1_size = values_1.size();
1990 
1991  size_t count = 0;
1992 
1993  T matrix_element;
1994 
1995  for(size_t i = 0; i < rows_number; i++)
1996  {
1997  if((*this)(i, column_2_index) == value_2
1998  &&(*this)(i, column_3_index) == value_3
1999  &&(*this)(i, column_4_index) == value_4)
2000  {
2001  matrix_element = (*this)(i, column_1_index);
2002 
2003  for(size_t j = 0; j < values_1_size; j++)
2004  {
2005  if(matrix_element == values_1[j])
2006  {
2007  count++;
2008 
2009  break;
2010  }
2011  }
2012  }
2013  }
2014 
2015  return count;
2016 }
2017 
2018 
2026 
2027 template <class T>
2028 size_t Matrix<T>::count_equal_to(const size_t& column_1_index, const T& value_1,
2029  const size_t& column_2_index, const T& value_2) const
2030 {
2031  size_t count = 0;
2032 
2033  for(size_t i = 0; i < rows_number; i++)
2034  {
2035  if((*this)(i, column_1_index) == value_1
2036  &&(*this)(i, column_2_index) == value_2)
2037  {
2038  count++;
2039  }
2040  }
2041 
2042  return count;
2043 }
2044 
2045 
2056 
2057 template <class T>
2058 size_t Matrix<T>::count_equal_to(const size_t& column_1_index, const T& value_1,
2059  const size_t& column_2_index, const T& value_2,
2060  const size_t& column_3_index, const T& value_3,
2061  const size_t& column_4_index, const T& value_4) const
2062 {
2063  size_t count = 0;
2064 
2065  for(size_t i = 0; i < rows_number; i++)
2066  {
2067  if((*this)(i, column_1_index) == value_1
2068  &&(*this)(i, column_2_index) == value_2
2069  &&(*this)(i, column_3_index) == value_3
2070  &&(*this)(i, column_4_index) == value_4)
2071  {
2072  count++;
2073  }
2074  }
2075 
2076  return count;
2077 }
2078 
2079 
2084 
2085 template <class T>
2086 size_t Matrix<T>::count_equal_to(const string& column_name, const T& value) const
2087 {
2088  const size_t column_index = get_column_index(column_name);
2089 
2090  return(count_equal_to(column_index, value));
2091 }
2092 
2093 
2098 
2099 template <class T>
2100 size_t Matrix<T>::count_equal_to(const string& column_name, const Vector<T>& values) const
2101 {
2102  const size_t column_index = get_column_index(column_name);
2103 
2104  return(count_equal_to(column_index, values));
2105 }
2106 
2107 
2115 
2116 template <class T>
2117 size_t Matrix<T>::count_equal_to(const string& column_1_name, const T& value_1,
2118  const string& column_2_name, const T& value_2) const
2119 {
2120  const size_t column_1_index = get_column_index(column_1_name);
2121  const size_t column_2_index = get_column_index(column_2_name);
2122 
2123  return(count_equal_to(column_1_index, value_1, column_2_index, value_2));
2124 }
2125 
2126 
2131 
2132 template <class T>
2134 {
2135  Vector<size_t> count_by_rows(rows_number);
2136 
2137  for(size_t i = 0; i < rows_number; i++)
2138  {
2139  count_by_rows[i] = this->get_row(i).count_equal_to(value);
2140  }
2141 
2142  return count_by_rows;
2143 }
2144 
2145 
2151 
2152 template <class T>
2154 {
2155  Vector<double> count_by_rows(rows_number);
2156 
2157  for(size_t i = 0; i < rows_number; i++)
2158  {
2159  count_by_rows[i] = this->get_row(i).count_equal_to(value, weights);
2160  }
2161 
2162  return count_by_rows;
2163 }
2164 
2165 
2168 
2169 template <class T>
2170 size_t Matrix<T>::count_not_equal_to(const T& value) const
2171 {
2172  const size_t this_size = this->size();
2173 
2174  return(this_size-count_equal_to(value));
2175 }
2176 
2177 
2181 
2182 template <class T>
2183 size_t Matrix<T>::count_not_equal_to(const size_t& column_index, const T& value) const
2184 {
2185  size_t count = 0;
2186 
2187  for(size_t i = 0; i < rows_number; i++)
2188  {
2189  if((*this)(i, column_index) != value)
2190  {
2191  count++;
2192  }
2193  }
2194 
2195  return count;
2196 }
2197 
2198 
2202 
2203 template <class T>
2204 size_t Matrix<T>::count_not_equal_to(const size_t& column_index, const Vector<T>& values) const
2205 {
2206  const size_t values_size = values.size();
2207 
2208  size_t index = 0;
2209 
2210  for(size_t i = 0; i < rows_number; i++)
2211  {
2212  size_t count = 0;
2213 
2214  for(size_t j = 0; j < values_size; j++)
2215  {
2216  if((*this)(i, column_index) != values[j])
2217  {
2218  count++;
2219  }
2220  }
2221 
2222  if(count == values.size())
2223  {
2224  index++;
2225  }
2226  }
2227 
2228  return index;
2229 }
2230 
2231 
2239 
2240 template <class T>
2241 size_t Matrix<T>::count_not_equal_to(const size_t& column_1_index, const T& value_1,
2242  const size_t& column_2_index, const T& value_2) const
2243 {
2244  size_t count = 0;
2245 
2246  for(size_t i = 0; i < rows_number; i++)
2247  {
2248  if((*this)(i, column_1_index) != value_1 &&(*this)(i, column_2_index) != value_2)
2249  {
2250  count++;
2251  }
2252  }
2253 
2254  return count;
2255 }
2256 
2257 
2261 
2262 template <class T>
2263 size_t Matrix<T>::count_not_equal_to(const string& column_name, const T& value) const
2264 {
2265  const size_t column_index = get_column_index(column_name);
2266 
2267  return(count_not_equal_to(column_index, value));
2268 }
2269 
2270 
2278 
2279 template <class T>
2280 size_t Matrix<T>::count_not_equal_to(const string& column_1_name, const T& value_1,
2281  const string& column_2_name, const T& value_2) const
2282 {
2283  const size_t column_1_index = get_column_index(column_1_name);
2284  const size_t column_2_index = get_column_index(column_2_name);
2285 
2286  return(count_not_equal_to(column_1_index, value_1, column_2_index, value_2));
2287 }
2288 
2289 
2293 
2294 template <class T>
2295 size_t Matrix<T>::count_rows_equal_to(const T& value) const
2296 {
2297  size_t count = rows_number;
2298 
2299  for(size_t i = 0; i < rows_number; i++)
2300  {
2301  for(size_t j = 0; j < columns_number; j++)
2302  {
2303  if((*this)(i,j) != value)
2304  {
2305  count--;
2306 
2307  break;
2308  }
2309  }
2310  }
2311 
2312  return count;
2313 }
2314 
2315 
2319 
2320 template <class T>
2321 size_t Matrix<T>::count_rows_not_equal_to(const T& value) const
2322 {
2323  size_t count = 0;
2324 
2325  for(size_t i = 0; i < rows_number; i++)
2326  {
2327  if(get_row(i) != value) count++;
2328  }
2329 
2330  return count;
2331 }
2332 
2333 
2337 
2338 template <class T>
2340 {
2341  Vector<size_t> indices;
2342 
2343  for(size_t i = 0; i < rows_number; i++)
2344  {
2345  if(get_row(i) == vector)
2346  {
2347  indices.push_back(i);
2348  }
2349  }
2350 
2351  return indices;
2352 }
2353 
2354 
2359 
2360 template <class T>
2361 size_t Matrix<T>::count_rows_equal_to(const Vector<size_t>& columns_indices, const T& value) const
2362 {
2363  size_t count = 0;
2364 
2365  for(size_t i = 0; i < rows_number; i++)
2366  {
2367  if(is_row_equal_to(i, columns_indices, value))
2368  {
2369  count++;
2370  }
2371  }
2372 
2373  return count;
2374 }
2375 
2376 
2382 
2383 template <class T>
2384 bool Matrix<T>::is_row_equal_to(const size_t& row_index, const Vector<size_t>& columns_indices, const T& value) const
2385 {
2386  const size_t columns_indices_size = columns_indices.size();
2387 
2388  for(size_t i = 0; i < columns_indices_size; i++)
2389  {
2390  if((*this)(row_index,columns_indices[i]) != value)
2391  {
2392  return false;
2393  }
2394  }
2395 
2396  return true;
2397 }
2398 
2399 
2403 
2404 template <class T>
2405 Matrix<T> Matrix<T>::get_submatrix(const Vector<size_t>& row_indices, const Vector<size_t>& columns_indices) const
2406 {
2407  const size_t row_indices_size = row_indices.size();
2408  const size_t columns_indices_size = columns_indices.size();
2409 
2410  Matrix<T> sub_matrix(row_indices_size, columns_indices_size);
2411 
2412  size_t row_index;
2413  size_t column_index;
2414 
2415  for(size_t i = 0; i < row_indices_size; i++)
2416  {
2417  row_index = row_indices[i];
2418 
2419  for(size_t j = 0; j < columns_indices_size; j++)
2420  {
2421  column_index = columns_indices[j];
2422  sub_matrix(i,j) = (*this)(row_index,column_index);
2423  }
2424  }
2425 
2426  return sub_matrix;
2427 }
2428 
2429 
2430 template <class T>
2431 Tensor<T> Matrix<T>::get_tensor(const Vector<size_t>& rows_indices,
2432  const Vector<size_t>& columns_indices,
2433  const Vector<size_t>& columns_dimensions) const
2434 {
2435 #ifdef __OPENNN_DEBUG__
2436 
2437  if(columns_indices.size() != columns_dimensions.calculate_product())
2438  {
2439  ostringstream buffer;
2440 
2441  buffer << "OpenNN Exception: Matrix Template.\n"
2442  << "Tensor<T> get_tensor(const Vector<size_t>&, const Vector<size_t>&, const Vector<size_t>&) const method.\n"
2443  << "Size of columns indices(" << columns_indices.size() << ") must be equal to product of columns dimensions(" << columns_dimensions.calculate_product() << ").\n";
2444 
2445  throw logic_error(buffer.str());
2446  }
2447 
2448 #endif
2449 
2450  const size_t rows_number = rows_indices.size();
2451  const size_t columns_number = columns_indices.size();
2452 
2453  const Vector<size_t> dimensions = Vector<size_t>(1, rows_number).assemble(columns_dimensions);
2454 
2455  Tensor<T> tensor(dimensions);
2456 
2457  size_t row_index;
2458  size_t column_index;
2459 
2460  size_t tensor_index = 0;
2461 
2462  for(size_t j = 0; j < columns_number; j++)
2463  {
2464  column_index = columns_indices[j];
2465 
2466  for(size_t i = 0; i < rows_number; i++)
2467  {
2468  row_index = rows_indices[i];
2469 
2470  tensor[tensor_index] = (*this)(row_index, column_index);
2471 
2472  tensor_index++;
2473  }
2474  }
2475 
2476  return tensor;
2477 }
2478 
2479 
2482 
2483 template <class T>
2485 {
2486  const size_t row_indices_size = row_indices.size();
2487 
2488  Matrix<T> sub_matrix(row_indices_size, columns_number);
2489 
2490  size_t row_index;
2491 
2492  for(size_t i = 0; i < row_indices_size; i++)
2493  {
2494  row_index = row_indices[i];
2495 
2496  for(size_t j = 0; j < columns_number; j++)
2497  {
2498  sub_matrix(i,j) = (*this)(row_index,j);
2499  }
2500  }
2501 
2502  sub_matrix.set_header(get_header());
2503 
2504  return sub_matrix;
2505 }
2506 
2507 
2510 
2511 template <class T>
2513 {
2514  const size_t columns_indices_size = columns_indices.size();
2515 
2516  #ifdef __OPENNN_DEBUG__
2517 
2518  for(size_t i = 0; i < columns_indices_size; i++)
2519  {
2520  if(columns_indices[i] >= columns_number)
2521  {
2522  ostringstream buffer;
2523 
2524  buffer << "OpenNN Exception: Matrix Template.\n"
2525  << "Matrix<T> get_submatrix_columns(const Vector<size_t>&) const method.\n"
2526  << "Column index (" << i << ") must be less than number of columns(" << columns_number << ").\n";
2527 
2528  throw logic_error(buffer.str());
2529  }
2530  }
2531 
2532  #endif
2533 
2534  Matrix<T> sub_matrix(rows_number, columns_indices_size);
2535 
2536  size_t column_index;
2537 
2538  for(size_t i = 0; i < rows_number; i++)
2539  {
2540  for(size_t j = 0; j < columns_indices_size; j++)
2541  {
2542  column_index = columns_indices[j];
2543 
2544  sub_matrix(i,j) = (*this)(i,column_index);
2545  }
2546  }
2547 
2548  if(!header.empty())
2549  {
2550  const Vector<string> sub_header = header.get_subvector(columns_indices);
2551 
2552  sub_matrix.set_header(sub_header);
2553  }
2554 
2555  return sub_matrix;
2556 }
2557 
2558 
2561 
2562 template <class T>
2563 Vector<T> Matrix<T>::get_row(const size_t& index) const
2564 {
2565  #ifdef __OPENNN_DEBUG__
2566 
2567  if(index >= rows_number)
2568  {
2569  ostringstream buffer;
2570 
2571  buffer << "OpenNN Exception: Matrix Template.\n"
2572  << "Vector<T> get_row(const size_t&) const method.\n"
2573  << "Row index (" << index << ") must be less than number of rows (" << rows_number << ").\n";
2574 
2575  throw logic_error(buffer.str());
2576  }
2577 
2578  #endif
2579 
2580  Vector<T> row(columns_number);
2581 
2582  for(size_t j = 0; j < columns_number; j++)
2583  {
2584  row[j] = (*this)(index,j);
2585  }
2586 
2587  return row;
2588 }
2589 
2590 
2594 
2595 template <class T>
2596 Vector<T> Matrix<T>::get_rows(const size_t& first_index, const size_t& last_index) const
2597 {
2598  #ifdef __OPENNN_DEBUG__
2599 
2600  if(last_index > rows_number)
2601  {
2602  ostringstream buffer;
2603 
2604  buffer << "OpenNN Exception: Matrix Template.\n"
2605  << "Vector<T> get_rows(const size_t&, const size_t&) const method.\n"
2606  << "Last index (" << last_index << ") must be less than number of rows(" << rows_number << ").\n";
2607 
2608  throw logic_error(buffer.str());
2609  }
2610 
2611  #endif
2612 
2613  Vector<double> new_row;
2614 
2615  for(size_t i = first_index-1; i < last_index; i++)
2616  {
2617  new_row = new_row.assemble(get_row(i));
2618  }
2619 
2620  return new_row;
2621 }
2622 
2623 
2627 
2628 template <class T>
2629 Vector<T> Matrix<T>::get_row(const size_t& row_index, const Vector<size_t>& columns_indices) const
2630 {
2631  #ifdef __OPENNN_DEBUG__
2632 
2633  if(row_index >= rows_number)
2634  {
2635  ostringstream buffer;
2636 
2637  buffer << "OpenNN Exception: Matrix Template.\n"
2638  << "Vector<T> get_row(const size_t&, const Vector<size_t>&) const method.\n"
2639  << "Row index (" << row_index << ") must be less than number of rows(" << rows_number << ").\n";
2640 
2641  throw logic_error(buffer.str());
2642  }
2643 
2644  #endif
2645 
2646  const size_t size = columns_indices.size();
2647 
2648  Vector<T> row(size);
2649 
2650  for(size_t i = 0; i < size; i++)
2651  {
2652  row[i] = (*this)(row_index,columns_indices[i]);
2653  }
2654 
2655  return row;
2656 }
2657 
2658 
2661 
2662 template <class T>
2663 Vector<T> Matrix<T>::get_column(const size_t& column_index) const
2664 {
2665  #ifdef __OPENNN_DEBUG__
2666 
2667  if(column_index >= columns_number)
2668  {
2669  ostringstream buffer;
2670 
2671  buffer << "OpenNN Exception: Matrix Template.\n"
2672  << "Vector<T> get_column(const size_t&) const method.\n"
2673  << "Column index (" << column_index << ") must be less than number of columns(" << columns_number << ").\n";
2674 
2675  throw logic_error(buffer.str());
2676  }
2677 
2678  #endif
2679 
2680  Vector<T> column(rows_number);
2681 
2682  for(size_t i = 0; i < rows_number; i++)
2683  {
2684  column[i] = (*this)(i,column_index);
2685  }
2686 
2687  return column;
2688 }
2689 
2690 
2693 
2694 template <class T>
2695 Vector<T> Matrix<T>::get_column(const string& column_name) const
2696 {
2697  #ifdef __OPENNN_DEBUG__
2698 
2699  if(this->empty())
2700  {
2701  ostringstream buffer;
2702 
2703  buffer << "OpenNN Exception: Matrix Template.\n"
2704  << "Vector<T> get_column(const string&) const method.\n"
2705  << "Matrix is empty.\n";
2706 
2707  throw logic_error(buffer.str());
2708  }
2709 
2710  #endif
2711 
2712  const size_t column_index = get_column_index(column_name);
2713 
2714  return(get_column(column_index));
2715 }
2716 
2717 
2718 
2721 
2722 template <class T>
2724 {
2725  const Vector<size_t> indices = get_columns_indices(column_names);
2726 
2727  return(get_submatrix_columns(indices));
2728 }
2729 
2730 
2734 
2735 template <class T>
2736 Vector<T> Matrix<T>::get_column(const size_t& column_index, const Vector<size_t>& row_indices) const
2737 {
2738  #ifdef __OPENNN_DEBUG__
2739 
2740  if(column_index >= columns_number)
2741  {
2742  ostringstream buffer;
2743 
2744  buffer << "OpenNN Exception: Matrix Template.\n"
2745  << "Vector<T> get_column(const size_t&, const Vector<size_t>&) const method.\n"
2746  << "Column index (" << column_index << ") must be less than number of rows(" << columns_number << ").\n";
2747 
2748  throw logic_error(buffer.str());
2749  }
2750 
2751  #endif
2752 
2753  const size_t size = row_indices.size();
2754 
2755  Vector<T> column(size);
2756 
2757  for(size_t i = 0; i < size; i++)
2758  {
2759  column[i] = (*this)(row_indices[i],column_index);
2760  }
2761 
2762  return column;
2763 }
2764 
2765 
2767 
2768 template <class T>
2770 {
2771  const size_t this_size = this->size();
2772 
2773  for(size_t i = 0; i < this_size; i++)
2774  {
2775  if(::isnan((*this)[i])) return true;
2776  }
2777 
2778  return false;
2779 }
2780 
2783 
2784 template <class T>
2785 bool Matrix<T>::has_nan_row(const size_t& row_index) const
2786 {
2787  for(size_t j = 0; j < columns_number; j++)
2788  {
2789  if(::isnan((*this)(row_index, j))) return true;
2790  }
2791 
2792  return false;
2793 }
2794 
2795 
2798 
2799 template <class T>
2800 bool Matrix<T>::has_nan_column(const size_t& column_index) const
2801 {
2802  for(size_t i = 0; i < rows_number; i++)
2803  {
2804  if(::isnan((*this)(i, column_index))) return true;
2805  }
2806 
2807  return false;
2808 }
2809 
2810 
2812 
2813 template <class T>
2814 size_t Matrix<T>::count_nan() const
2815 {
2816  const size_t this_size = this->size();
2817 
2818  size_t count = 0;
2819 
2820  for(size_t i = 0; i < this_size; i++)
2821  {
2822  if(::isnan((*this)[i])) count++;
2823  }
2824 
2825  return count;
2826 }
2827 
2828 
2830 
2831 template <class T>
2833 {
2834  size_t count = 0;
2835 
2836  const size_t this_size = this->size();
2837 
2838  for(size_t i = 0; i < this_size; i++)
2839  {
2840  if(!::isnan((*this)[i])) count++;
2841  }
2842 
2843  return count;
2844 }
2845 
2846 
2848 
2849 template <class T>
2851 {
2852  size_t count = 0;
2853 
2854  for(size_t i = 0; i < rows_number; i++)
2855  {
2856  for(size_t j = 0; j < columns_number; j++)
2857  {
2858  if(::isnan((*this)(i,j)))
2859  {
2860  count++;
2861 
2862  break;
2863  }
2864  }
2865 
2866  }
2867 
2868  return count;
2869 }
2870 
2871 
2873 
2874 template <class T>
2876 {
2877  Vector<size_t> nan_indices;
2878 
2879  for(size_t i = 0; i < rows_number; i++)
2880  {
2881  for(size_t j = 0; j < columns_number; j++)
2882  {
2883  if(::isnan((*this)(i,j)))
2884  {
2885  nan_indices.push_back(i);
2886 
2887  break;
2888  }
2889  }
2890 
2891  }
2892 
2893  return nan_indices;
2894 }
2895 
2896 
2898 
2899 template <class T>
2901 {
2902  size_t count = 0;
2903 
2904  for(size_t j = 0; j < columns_number; j++)
2905  {
2906  for(size_t i = 0; i < rows_number; i++)
2907  {
2908  if(::isnan((*this)(i,j))) count++;
2909  break;
2910  }
2911  }
2912 
2913  return count;
2914 }
2915 
2916 
2920 
2921 template <class T>
2923 {
2924  Vector<size_t> count(rows_number, 0);
2925 
2926  for(size_t i = 0; i < rows_number; i++)
2927  {
2928  for(size_t j = 0; j < columns_number; j++)
2929  {
2930  if(::isnan((*this)(i,j))) count[i]++;
2931  }
2932  }
2933 
2934  return count;
2935 }
2936 
2937 
2941 
2942 template <class T>
2944 {
2945  Vector<size_t> count(columns_number, 0);
2946 
2947  for(size_t i = 0; i < rows_number; i++)
2948  {
2949  for(size_t j = 0; j < columns_number; j++)
2950  {
2951  if(::isnan((*this)(i,j))) count[j]++;
2952  }
2953  }
2954 
2955  return count;
2956 }
2957 
2958 
2960 
2961 template <class T>
2963 {
2964  Vector<size_t> unique_elements;
2965 
2966  for(size_t i = 0; i < columns_number; i++)
2967  {
2968  unique_elements.push_back(this->get_column(i).get_unique_elements().size());
2969  }
2970 
2971  return unique_elements;
2972 }
2973 
2974 
2976 
2977 template <class T>
2979 {
2980  #ifdef __OPENNN_DEBUG__
2981 
2982  if(rows_number != columns_number)
2983  {
2984  ostringstream buffer;
2985 
2986  buffer << "OpenNN Exception: Matrix Template.\n"
2987  << "Vector<T> get_diagonal() const method.\n"
2988  << "Matrix must be squared.\n";
2989 
2990  throw logic_error(buffer.str());
2991  }
2992 
2993  #endif
2994 
2995  Vector<T> diagonal(rows_number);
2996 
2997  for(size_t i = 0; i < rows_number; i++)
2998  {
2999  diagonal[i] = (*this)(i,i);
3000  }
3001 
3002  return(diagonal);
3003 }
3004 
3005 
3009 
3010 template <class T>
3011 void Matrix<T>::set_row(const size_t& row_index, const Vector<T>& new_row)
3012 {
3013  #ifdef __OPENNN_DEBUG__
3014 
3015  if(row_index >= rows_number)
3016  {
3017  ostringstream buffer;
3018 
3019  buffer << "OpenNN Exception: Matrix Template.\n"
3020  << "set_row(const size_t&, const Vector<T>&) method.\n"
3021  << "Index must be less than number of rows.\n";
3022 
3023  throw logic_error(buffer.str());
3024  }
3025 
3026  const size_t size = new_row.size();
3027 
3028  if(size != columns_number)
3029  {
3030  ostringstream buffer;
3031 
3032  buffer << "OpenNN Exception: Matrix Template.\n"
3033  << "set_row(const size_t&, const Vector<T>&) method.\n"
3034  << "Size(" << size << ") must be equal to number of columns(" << columns_number << ").\n";
3035 
3036  throw logic_error(buffer.str());
3037  }
3038 
3039  #endif
3040 
3041  // Set new row
3042 
3043  for(size_t i = 0; i < columns_number; i++)
3044  {
3045  (*this)(row_index,i) = new_row[i];
3046  }
3047 }
3048 
3049 
3053 
3054 template <class T>
3055 void Matrix<T>::set_row(const size_t& row_index, const T& value)
3056 {
3057  #ifdef __OPENNN_DEBUG__
3058 
3059  if(row_index >= rows_number)
3060  {
3061  ostringstream buffer;
3062 
3063  buffer << "OpenNN Exception: Matrix Template.\n"
3064  << "set_row(const size_t&, const T&) method.\n"
3065  << "Index must be less than number of rows.\n";
3066 
3067  throw logic_error(buffer.str());
3068  }
3069 
3070  #endif
3071 
3072  // Set new row
3073 
3074  for(size_t i = 0; i < columns_number; i++)
3075  {
3076  (*this)(row_index,i) = value;
3077  }
3078 }
3079 
3080 
3084 
3085 template <class T>
3086 void Matrix<T>::set_submatrix_rows(const size_t& row_index, const Matrix<T>& submatrix)
3087 {
3088  #ifdef __OPENNN_DEBUG__
3089 
3090  if(row_index+submatrix.get_rows_number()>= rows_number)
3091  {
3092  ostringstream buffer;
3093 
3094  buffer << "OpenNN Exception: Matrix Template.\n"
3095  << "set_row(const size_t&, const T&) method.\n"
3096  << "Submatrix doesn't fix in this matrix.\n";
3097 
3098  throw logic_error(buffer.str());
3099  }
3100  if(submatrix.get_columns_number() != columns_number)
3101  {
3102  ostringstream buffer;
3103 
3104  buffer << "OpenNN Exception: Matrix Template.\n"
3105  << "set_row(const size_t&, const T&) method.\n"
3106  << "Submatrix columns number is different than matrix columns number.\n";
3107 
3108  throw logic_error(buffer.str());
3109  }
3110 
3111  #endif
3112 
3113  // Set new row
3114 
3115  for(size_t i = 0; i < submatrix.get_rows_number(); i++)
3116  {
3117  this->set_row(row_index+i,submatrix.get_row(i));
3118  }
3119 
3120  if(header == "" && row_index == 0)
3121  {
3122  set_header(submatrix.get_header());
3123  }
3124 }
3125 
3126 
3131 
3132 template <class T>
3133 void Matrix<T>::set_column(const size_t& column_index, const Vector<T>& new_column, const string& new_name)
3134 {
3135  #ifdef __OPENNN_DEBUG__
3136 
3137  if(column_index >= columns_number)
3138  {
3139  ostringstream buffer;
3140 
3141  buffer << "OpenNN Exception: Matrix Template.\n"
3142  << "set_column(const size_t&, const Vector<T>&).\n"
3143  << "index (" << column_index << ") must be less than number of columns(" << columns_number << ").\n";
3144 
3145  throw logic_error(buffer.str());
3146  }
3147 
3148  const size_t size = new_column.size();
3149 
3150  if(size != rows_number)
3151  {
3152  ostringstream buffer;
3153 
3154  buffer << "OpenNN Exception: Matrix Template.\n"
3155  << "set_column(const size_t&, const Vector<T>&).\n"
3156  << "Size must be equal to number of rows.\n";
3157 
3158  throw logic_error(buffer.str());
3159  }
3160 
3161  #endif
3162 
3163  // Set new column
3164 
3165  for(size_t i = 0; i < rows_number; i++)
3166  {
3167  (*this)(i,column_index) = new_column[i];
3168  }
3169 
3170  header[column_index] = new_name;
3171 }
3172 
3173 
3178 
3179 template <class T>
3180 void Matrix<T>::set_column(const string& column_name, const Vector<T>& new_column, const string& new_name)
3181 {
3182  const size_t column_index = get_column_index(column_name);
3183 
3184  this->set_column(column_index, new_column, new_name);
3185 }
3186 
3187 
3192 
3193 template <class T>
3194 void Matrix<T>::set_column(const string& column_name, const T& value, const string& new_name)
3195 {
3196  const size_t column_index = get_column_index(column_name);
3197 
3198  set_column(column_index, value, new_name);
3199 }
3200 
3201 
3206 
3207 template <class T>
3208 void Matrix<T>::set_column(const size_t& column_index, const T& value, const string& new_name)
3209 {
3210  #ifdef __OPENNN_DEBUG__
3211 
3212  if(column_index >= columns_number)
3213  {
3214  ostringstream buffer;
3215 
3216  buffer << "OpenNN Exception: Matrix Template.\n"
3217  << "set_column(const size_t&, const T&).\n"
3218  << "Index must be less than number of columns.\n";
3219 
3220  throw logic_error(buffer.str());
3221  }
3222 
3223  #endif
3224 
3225  // Set new column
3226 
3227  for(size_t i = 0; i < rows_number; i++)
3228  {
3229  (*this)(i,column_index) = value;
3230  }
3231 
3232  header[column_index] = new_name;
3233 }
3234 
3235 
3239 
3240 template <class T>
3241 void Matrix<T>::set_diagonal(const T& new_diagonal)
3242 {
3243  #ifdef __OPENNN_DEBUG__
3244 
3245  if(rows_number != columns_number)
3246  {
3247  ostringstream buffer;
3248 
3249  buffer << "OpenNN Exception: Matrix Template.\n"
3250  << "set_diagonal(const T&).\n"
3251  << "Matrix must be square.\n";
3252 
3253  throw logic_error(buffer.str());
3254  }
3255 
3256  #endif
3257 
3258  // Set new column
3259 
3260  for(size_t i = 0; i < rows_number; i++)
3261  {
3262  (*this)(i,i) = new_diagonal;
3263  }
3264 }
3265 
3266 
3270 
3271 template <class T>
3272 void Matrix<T>::set_diagonal(const Vector<T>& new_diagonal)
3273 {
3274  #ifdef __OPENNN_DEBUG__
3275 
3276  if(rows_number != columns_number)
3277  {
3278  ostringstream buffer;
3279 
3280  buffer << "OpenNN Exception: Matrix Template.\n"
3281  << "set_diagonal(const Vector<T>&) const.\n"
3282  << "Matrix is not square.\n";
3283 
3284  throw logic_error(buffer.str());
3285  }
3286 
3287  const size_t size = new_diagonal.size();
3288 
3289  if(size != rows_number)
3290  {
3291  ostringstream buffer;
3292 
3293  buffer << "OpenNN Exception: Matrix Template.\n"
3294  << "set_diagonal(const Vector<T>&) const.\n"
3295  << "Size of diagonal(" << size << ") is not equal to size of matrix (" << rows_number << ").\n";
3296 
3297  throw logic_error(buffer.str());
3298  }
3299 
3300  #endif
3301 
3302  // Set new column
3303 
3304  for(size_t i = 0; i < rows_number; i++)
3305  {
3306  (*this)(i,i) = new_diagonal[i];
3307  }
3308 }
3309 
3310 
3316 
3317 template <class T>
3318 void Matrix<T>::initialize_diagonal(const size_t& new_size, const T& new_value)
3319 {
3320  this->set(new_size, new_size, 0);
3321  this->set_diagonal(new_value);
3322 }
3323 
3324 
3330 
3331 template <class T>
3332 void Matrix<T>::initialize_diagonal(const size_t& new_size, const Vector<T>& new_values)
3333 {
3334  #ifdef __OPENNN_DEBUG__
3335 
3336  const size_t new_values_size = new_values.size();
3337 
3338  if(new_values_size != new_size)
3339  {
3340  ostringstream buffer;
3341 
3342  buffer << "OpenNN Exception: Matrix Template.\n"
3343  << "initialize_diagonal(const size_t&, const size_t&) const.\n"
3344  << "Size of new values is not equal to size of square matrix.\n";
3345 
3346  throw logic_error(buffer.str());
3347  }
3348 
3349  #endif
3350 
3351  set(new_size, new_size, 0.0);
3352  set_diagonal(new_values);
3353 }
3354 
3355 
3359 
3360 template <class T>
3361 void Matrix<T>::sum_diagonal(const T& value)
3362 {
3363  #ifdef __OPENNN_DEBUG__
3364 
3365  if(rows_number != columns_number)
3366  {
3367  ostringstream buffer;
3368 
3369  buffer << "OpenNN Exception: Matrix Template.\n"
3370  << "sum_diagonal(const T&).\n"
3371  << "Matrix must be square.\n";
3372 
3373  throw logic_error(buffer.str());
3374  }
3375 
3376  #endif
3377 
3378  for(size_t i = 0; i < rows_number; i++)
3379  {
3380  (*this)(i,i) += value;
3381  }
3382 }
3383 
3384 
3388 
3389 template <class T>
3390 void Matrix<T>::multiply_diagonal(const T& value)
3391 {
3392  #ifdef __OPENNN_DEBUG__
3393 
3394  if(rows_number != columns_number)
3395  {
3396  ostringstream buffer;
3397 
3398  buffer << "OpenNN Exception: Matrix Template.\n"
3399  << "multiply_diagonal(const T&).\n"
3400  << "Matrix must be square.\n";
3401 
3402  throw logic_error(buffer.str());
3403  }
3404 
3405  #endif
3406 
3407  for(size_t i = 0; i < rows_number; i++)
3408  {
3409  (*this)(i,i) = (*this)(i,i)*value;
3410  }
3411 }
3412 
3413 
3417 
3418 template <class T>
3419 void Matrix<T>::sum_diagonal(const Vector<T>& new_summing_values)
3420 {
3421  #ifdef __OPENNN_DEBUG__
3422 
3423  if(rows_number != columns_number)
3424  {
3425  ostringstream buffer;
3426 
3427  buffer << "OpenNN Exception: Matrix Template.\n"
3428  << "sum_diagonal(const Vector<T>&).\n"
3429  << "Matrix must be square.\n";
3430 
3431  throw logic_error(buffer.str());
3432  }
3433 
3434  const size_t size = new_summing_values.size();
3435 
3436  if(size != rows_number)
3437  {
3438  ostringstream buffer;
3439 
3440  buffer << "OpenNN Exception: Matrix Template.\n"
3441  << "sum_diagonal(const Vector<T>&).\n"
3442  << "Size must be equal to number of rows.\n";
3443 
3444  throw logic_error(buffer.str());
3445  }
3446 
3447  #endif
3448 
3449  for(size_t i = 0; i < rows_number; i++)
3450  {
3451  (*this)(i,i) += new_summing_values[i];
3452  }
3453 }
3454 
3455 
3460 
3461 template <class T>
3463 {
3464  #ifdef __OPENNN_DEBUG__
3465 
3466  const size_t size = new_row.size();
3467 
3468  if(size != columns_number)
3469  {
3470  ostringstream buffer;
3471 
3472  buffer << "OpenNN Exception: Matrix Template.\n"
3473  << "append_row(const Vector<T>&) const.\n"
3474  << "Size(" << size << ") must be equal to number of columns(" << columns_number << ").\n";
3475 
3476  throw logic_error(buffer.str());
3477  }
3478 
3479  #endif
3480 
3481  Matrix<T> copy;
3482 
3483  if(this->empty())
3484  {
3485  copy.set(1,new_row.size());
3486  copy.set_row(0,new_row);
3487 
3488  return copy;
3489  }
3490 
3491  copy.set(rows_number+1, columns_number);
3492 
3493  for(size_t i = 0; i < rows_number; i++)
3494  {
3495  for(size_t j = 0; j < columns_number; j++)
3496  {
3497  copy(i,j) = (*this)(i,j);
3498  }
3499  }
3500 
3501  copy.set_row(rows_number, new_row);
3502 
3503  if(!header.empty()) copy.set_header(header);
3504 
3505  return copy;
3506 }
3507 
3508 
3514 
3515 template <class T>
3516 Matrix<T> Matrix<T>::append_column(const Vector<T>& new_column, const string& new_name) const
3517 {
3518  #ifdef __OPENNN_DEBUG__
3519 
3520  const size_t size = new_column.size();
3521 
3522  if(size != rows_number)
3523  {
3524  ostringstream buffer;
3525 
3526  buffer << "OpenNN Exception: Matrix Template.\n"
3527  << "append_column(const Vector<T>&) const.\n"
3528  << "Size(" << size << ") must be equal to number of rows(" << rows_number << ").\n";
3529 
3530  throw logic_error(buffer.str());
3531  }
3532 
3533  #endif
3534 
3535  const size_t new_columns_number = columns_number + 1;
3536 
3537  Matrix<T> new_matrix;
3538 
3539  if(this->empty())
3540  {
3541  new_matrix.set(new_column.size(), 1);
3542 
3543  new_matrix.set_column(0, new_column, new_name);
3544 
3545  return new_matrix;
3546  }
3547  else
3548  {
3549  new_matrix.set(rows_number, new_columns_number);
3550 
3551  for(size_t i = 0; i < rows_number; i++)
3552  {
3553  for(size_t j = 0; j < columns_number; j++)
3554  {
3555  new_matrix(i,j) = (*this)(i,j);
3556  }
3557 
3558  new_matrix(i,columns_number) = new_column[i];
3559  }
3560  }
3561 
3562  if(!header.empty())
3563  {
3564  Vector<string> new_header = get_header();
3565 
3566  new_header.push_back(new_name);
3567 
3568  new_matrix.set_header(new_header);
3569  }
3570 
3571  return new_matrix;
3572 }
3573 
3574 
3579 
3580 template <class T>
3581 Matrix<T> Matrix<T>::insert_row(const size_t& position, const Vector<T>& new_row) const
3582 {
3583  #ifdef __OPENNN_DEBUG__
3584 
3585  if(position > rows_number)
3586  {
3587  ostringstream buffer;
3588 
3589  buffer << "OpenNN Exception: Matrix Template.\n"
3590  << "insert_row(const size_t&, const Vector<T>&) const.\n"
3591  << "Position must be less or equal than number of rows.\n";
3592 
3593  throw logic_error(buffer.str());
3594  }
3595 
3596  const size_t size = new_row.size();
3597 
3598  if(size != columns_number)
3599  {
3600  ostringstream buffer;
3601 
3602  buffer << "OpenNN Exception: Matrix Template.\n"
3603  << "insert_row(const size_t&, const Vector<T>&) const.\n"
3604  << "Size must be equal to number of columns.\n";
3605 
3606  throw logic_error(buffer.str());
3607  }
3608 
3609  #endif
3610 
3611  const size_t new_rows_number = rows_number + 1;
3612 
3613  Matrix<T> new_matrix(new_rows_number, columns_number);
3614 
3615  for(size_t i = 0; i < position; i++)
3616  {
3617  for(size_t j = 0; j < columns_number; j++)
3618  {
3619  new_matrix(i,j) = (*this)(i,j);
3620  }
3621  }
3622 
3623  for(size_t j = 0; j < columns_number; j++)
3624  {
3625  new_matrix(position,j) = new_row[j];
3626  }
3627 
3628  for(size_t i = position+1; i < new_rows_number; i++)
3629  {
3630  for(size_t j = 0; j < columns_number; j++)
3631  {
3632  new_matrix(i,j) = (*this)(i-1,j);
3633  }
3634  }
3635 
3636  new_matrix.set_header(header);
3637 
3638  return new_matrix;
3639 }
3640 
3641 
3646 
3647 template <class T>
3648 void Matrix<T>::insert_row_values(const size_t& row_index, const size_t& column_position, const Vector<T>& values)
3649 {
3650  const size_t values_size = values.size();
3651 
3652  for(size_t i = 0; i < values_size; i++)
3653  {
3654  (*this)(row_index, column_position + i) = values[i];
3655  }
3656 }
3657 
3658 
3664 
3665 template <class T>
3666 Matrix<T> Matrix<T>::insert_column(const size_t& position, const Vector<T>& new_column, const string& new_name) const
3667 {
3668  #ifdef __OPENNN_DEBUG__
3669 
3670  if(position > columns_number)
3671  {
3672  ostringstream buffer;
3673 
3674  buffer << "OpenNN Exception: Matrix Template.\n"
3675  << "insert_column(const size_t&, const Vector<T>&) const.\n"
3676  << "Position must be less or equal than number of columns.\n";
3677 
3678  throw logic_error(buffer.str());
3679  }
3680 
3681  const size_t size = static_cast<size_t>(new_column.size());
3682 
3683  if(size != rows_number)
3684  {
3685  ostringstream buffer;
3686 
3687  buffer << "OpenNN Exception: Matrix Template.\n"
3688  << "insert_column(const size_t, const Vector<T>&) const.\n"
3689  << "Size(" << size << ") must be equal to number of rows(" << rows_number << ").\n";
3690 
3691  throw logic_error(buffer.str());
3692  }
3693 
3694  #endif
3695 
3696  const size_t new_columns_number = columns_number + 1;
3697 
3698  Matrix<T> new_matrix(rows_number, new_columns_number);
3699 
3700  for(size_t i = 0; i < rows_number; i++)
3701  {
3702  for(size_t j = 0; j < position; j++)
3703  {
3704  new_matrix(i,j) = (*this)(i,j);
3705  }
3706 
3707  new_matrix(i,position) = new_column[i];
3708 
3709  for(size_t j = position+1; j < new_columns_number; j++)
3710  {
3711  new_matrix(i,j) = (*this)(i,j-1);
3712  }
3713  }
3714 
3715  if(!header.empty())
3716  {
3717  Vector<string> new_header = get_header();
3718 
3719  new_matrix.set_header(new_header.insert_element(position, new_name));
3720  }
3721 
3722  return new_matrix;
3723 }
3724 
3725 
3731 
3732 template <class T>
3733 Matrix<T> Matrix<T>::insert_column(const string& column_name, const Vector<T>& new_column, const string& new_name) const
3734 {
3735  const size_t column_index = get_column_index(column_name);
3736 
3737  return insert_column(column_index, new_column, new_name);
3738 }
3739 
3740 
3745 
3746 template <class T>
3747 Matrix<T> Matrix<T>::insert_matrix(const size_t& position, const Matrix<T>& other_matrix) const
3748 {
3749 
3750  #ifdef __OPENNN_DEBUG__
3751 
3752  if(position > columns_number)
3753  {
3754  ostringstream buffer;
3755 
3756  buffer << "OpenNN Exception: Matrix Template.\n"
3757  << "insert_matrix(const size_t& , const Matrix<T>& ) const.\n"
3758  << "Position (" << position << ") must be less or equal than number of columns (" << columns_number << ").\n";
3759 
3760  throw logic_error(buffer.str());
3761  }
3762 
3763  const size_t size = static_cast<size_t>(other_matrix.get_rows_number());
3764 
3765  if(size != rows_number)
3766  {
3767  ostringstream buffer;
3768 
3769  buffer << "OpenNN Exception: Matrix Template.\n"
3770  << "insert_matrix(const size_t& , const Matrix<T>& ) const.\n"
3771  << "Size(" << size << ") must be equal to number of rows(" << rows_number << ").\n";
3772 
3773  throw logic_error(buffer.str());
3774  }
3775 
3776  #endif
3777 
3778  const size_t columns_other_matrix = other_matrix.get_columns_number();
3779  const size_t new_columns_number = columns_number + columns_other_matrix;
3780 
3781  Matrix<T> new_matrix(rows_number, new_columns_number);
3782 
3783  for(size_t i = 0; i < rows_number; i++)
3784  {
3785  for(size_t j = 0; j < position; j++)
3786  {
3787  new_matrix(i,j) = (*this)(i,j);
3788  }
3789 
3790  for(size_t j = position ; j < position+columns_other_matrix ; j++)
3791  {
3792  new_matrix(i,j) = other_matrix(i,j-position);
3793  }
3794 
3795  for(size_t j = position+columns_other_matrix; j < new_columns_number; j++)
3796  {
3797  new_matrix(i,j) = (*this)(i,j-columns_other_matrix);
3798  }
3799  }
3800 
3801 
3802  if(!header.empty())
3803  {
3804  Vector<string> old_header = get_header();
3805  Vector<string> new_header = other_matrix.get_header();
3806 
3807  new_matrix.set_header(old_header.insert_elements(position,new_header));
3808  }
3809 
3810  return new_matrix;
3811 }
3812 
3813 
3817 
3818 template <class T>
3819 Matrix<T> Matrix<T>::add_columns(const size_t& columns_to_add) const
3820 {
3821  Matrix<T> new_matrix(rows_number,columns_number+columns_to_add, T());
3822 
3823  Vector<string> new_header(columns_number+columns_to_add, "");
3824 
3825  for(size_t j = 0; j < columns_number; j++)
3826  {
3827  new_header[j] = header[j];
3828  }
3829 
3830  for(int i = 0; i < rows_number; i++)
3831  {
3832  for(size_t j = 0; j < columns_number; j++)
3833  {
3834  new_matrix(i,j) = (*this)(i,j);
3835  }
3836  }
3837 
3838  new_matrix.set_header(new_header);
3839 
3840  return new_matrix;
3841 }
3842 
3843 
3847 
3848 template <class T>
3849 Matrix<T> Matrix<T>::add_columns_first(const size_t& columns_to_add) const
3850 {
3851  Matrix<T> new_matrix(rows_number,columns_number+columns_to_add, T());
3852 
3853  Vector<string> new_header(columns_number+columns_to_add, "");
3854 
3855  for(size_t j = 0; j < columns_number; j++)
3856  {
3857  new_header[columns_to_add+j] = header[j];
3858  }
3859 
3860  for(int i = 0; i < rows_number; i++)
3861  {
3862  for(size_t j = 0; j < columns_number; j++)
3863  {
3864  new_matrix(i,columns_to_add+j) = (*this)(i,j);
3865  }
3866  }
3867 
3868  new_matrix.set_header(new_header);
3869 
3870  return new_matrix;
3871 }
3872 
3873 
3874 template <class T>
3875 void Matrix<T>::split_column(const string& column_name, const Vector<string>& new_columns_name,
3876  const char& delimiter, const string& missing_value_label)
3877 {
3878  const size_t column_index = get_column_index(column_name);
3879 
3880  const size_t new_columns_name_size = new_columns_name.size();
3881 
3882  const size_t new_columns_number = columns_number - 1 + new_columns_name_size;
3883 
3884  Matrix<T> new_matrix(rows_number, new_columns_number);
3885 
3886  Vector<T> new_row(new_columns_number);
3887 
3888  Vector<string> missing_values_vector(new_columns_name_size, missing_value_label);
3889 
3890  new_row = get_row(0).replace_element(column_index, new_columns_name);
3891  new_matrix.set_row(0, new_row);
3892 
3893  for(size_t i = 1; i < rows_number; i++)
3894  {
3895  if((*this)(i,column_index) == missing_value_label)
3896  {
3897  new_row = get_row(i).replace_element(column_index, missing_values_vector);
3898  }
3899  else
3900  {
3901  new_row = get_row(i).split_element(column_index, delimiter);
3902  }
3903 
3904  new_matrix.set_row(i, new_row);
3905  }
3906 
3907  set(new_matrix);
3908 }
3909 
3910 
3911 template <class T>
3912 void Matrix<T>::split_column(const string& column_name, const string& column_1_name, const string& column_2_name,
3913  const size_t& size_1, const size_t& size_2)
3914 {
3915  const size_t column_index = get_column_index(column_name);
3916 
3917  const Vector<T> column = get_column(column_index);
3918 
3919  Vector<T> column_1(rows_number);
3920  Vector<T> column_2(rows_number);
3921 
3922  column_1[0] = column_1_name;
3923  column_2[0] = column_2_name;
3924 
3925  for(size_t i = 1; i < rows_number; i++)
3926  {
3927  column_1[i] = column[i].substr(0, size_1);
3928  column_2[i] = column[i].substr(size_1, size_2);
3929  }
3930 
3931  set_column(column_index, column_1, column_1_name);
3932  (*this) = insert_column(column_index+1, column_2, column_2_name);
3933 }
3934 
3935 
3939 
3940 template <class T>
3941 void Matrix<T>::swap_columns(const size_t& column_1_index, const size_t& column_2_index)
3942 {
3943  const Vector<T> column_1 = get_column(column_1_index);
3944  const Vector<T> column_2 = get_column(column_2_index);
3945 
3946  const string header_1 = header[column_1_index];
3947  const string header_2 = header[column_2_index];
3948 
3949  set_column(column_1_index, column_2);
3950 
3951  set_column(column_2_index, column_1);
3952 
3953  header[column_1_index] = header_2;
3954  header[column_2_index] = header_1;
3955 }
3956 
3957 
3961 
3962 template <class T>
3963 void Matrix<T>::swap_columns(const string& column_1_name, const string& column_2_name)
3964 {
3965  const size_t column_1_index = get_column_index(column_1_name);
3966  const size_t column_2_index = get_column_index(column_2_name);
3967 
3968  swap_columns(column_1_index, column_2_index);
3969 }
3970 
3971 
3977 
3978 template <class T>
3979 void Matrix<T>::merge_columns(const string& column_1_name, const string& column_2_name, const string& merged_column_name, const char& separator)
3980 {
3981  const size_t column_1_index = get_column_index(column_1_name);
3982  const size_t column_2_index = get_column_index(column_2_name);
3983 
3984  const Vector<T> column_1 = get_column(column_1_index);
3985  const Vector<T> column_2 = get_column(column_2_index);
3986 
3987  Vector<T> merged_column(column_1.size());
3988 
3989  for(size_t i = 0; i < column_1.size(); i++)
3990  {
3991  merged_column[i] = column_1[i] + separator + column_2[i];
3992  }
3993 
3994  set_column(column_1_index, merged_column);
3995 
3996  set_header(column_1_index, merged_column_name);
3997 
3998  delete_column(column_2_index);
3999 }
4000 
4001 
4006 
4007 template <class T>
4008 void Matrix<T>::merge_columns(const size_t& column_1_index, const size_t& column_2_index, const char& separator)
4009 {
4010  const Vector<T> column_1 = get_column(column_1_index);
4011  const Vector<T> column_2 = get_column(column_2_index);
4012 
4013  Vector<T> merged_column(column_1.size());
4014 
4015  for(size_t i = 0; i < column_1.size(); i++)
4016  {
4017  merged_column[i] = column_1[i] + separator + column_2[i];
4018  }
4019 
4020  set_column(column_1_index, merged_column);
4021 
4022  delete_column(column_2_index);
4023 }
4024 
4025 
4026 template <class T>
4027 Matrix<T> Matrix<T>::merge_matrices(const Matrix<T>& other_matrix, const string& columns_1_name, const string& columns_2_name,
4028  const string& left_header_tag, const string& right_header_tag) const
4029 {
4030  const size_t other_columns_number = other_matrix.get_columns_number();
4031 
4032  const size_t columns_1_index = this->get_column_index(columns_1_name);
4033  const size_t columns_2_index = other_matrix.get_column_index(columns_2_name);
4034 
4035  const Vector<T> columns_1 = this->get_column(columns_1_index);
4036  const Vector<T> columns_2 = other_matrix.get_column(columns_2_index);
4037 
4038  const size_t columns_1_size = columns_1.size();
4039 
4040  const Vector<T> header_1 = this->get_header();
4041  const Vector<T> header_2 = other_matrix.get_header();
4042 
4043  size_t merged_rows_number = columns_1.count_equal_to(columns_2);
4044 
4045  Vector<T> merged_header = header_1.delete_element(columns_1_index) + left_header_tag;
4046 
4047  merged_header = merged_header.assemble(header_2.delete_element(columns_2_index) + right_header_tag);
4048 
4049  merged_header = merged_header.insert_element(columns_1_index, columns_1_name);
4050 
4051  if(merged_rows_number == 0)
4052  {
4053  Matrix<T> merged_matrix;
4054 
4055  return merged_matrix;
4056  }
4057 
4058  Matrix<T> merged_matrix(merged_rows_number,merged_header.size());
4059 
4060  merged_matrix.set_header(merged_header);
4061 
4062  size_t current_merged_row_index = 0;
4063 
4064  Vector<T> columns_2_sorted_values = columns_2.sort_ascending_values();
4065  Vector<size_t> columns_2_sorted_indices = columns_2.sort_ascending_indices();
4066 
4067  for(size_t i = 0; i < columns_1_size; i++)
4068  {
4069  const T current_index_value = columns_1[i];
4070 
4071  pair<typename vector<T>::iterator,typename vector<T>::iterator> bounds = equal_range(columns_2_sorted_values.begin(), columns_2_sorted_values.end(), current_index_value);
4072 
4073  const size_t initial_index = bounds.first - columns_2_sorted_values.begin();
4074  const size_t final_index = bounds.second - columns_2_sorted_values.begin();
4075 
4076  for(size_t j = initial_index; j < final_index; j++)
4077  {
4078  const size_t current_row_2_index = columns_2_sorted_indices[j];
4079 
4080  for(size_t k = 0; k < columns_number; k++)
4081  {
4082  merged_matrix(current_merged_row_index,k) = (*this)(i,k);
4083  }
4084 
4085  for(size_t k = 0; k < other_columns_number; k++)
4086  {
4087  if(k < columns_2_index)
4088  {
4089  merged_matrix(current_merged_row_index,k+columns_number) = other_matrix(current_row_2_index,k);
4090  }
4091  else if(k > columns_2_index)
4092  {
4093  merged_matrix(current_merged_row_index,k+columns_number-1) = other_matrix(current_row_2_index,k);
4094  }
4095  }
4096 
4097  current_merged_row_index++;
4098  }
4099  }
4100 
4101  return merged_matrix;
4102 }
4103 
4104 
4105 template <class T>
4106 Matrix<T> Matrix<T>::merge_matrices(const Matrix<T>& other_matrix, const size_t& columns_1_index, const size_t& columns_2_index) const
4107 {
4108  const size_t other_columns_number = other_matrix.get_columns_number();
4109 
4110  const Vector<T> columns_1 = this->get_column(columns_1_index);
4111  const Vector<T> columns_2 = other_matrix.get_column(columns_2_index);
4112 
4113  const size_t columns_1_size = columns_1.size();
4114 
4115  size_t merged_rows_number = columns_1.count_equal_to(columns_2);
4116 
4117  if(merged_rows_number == 0)
4118  {
4119  Matrix<T> merged_matrix;
4120 
4121  return merged_matrix;
4122  }
4123 
4124  Matrix<T> merged_matrix(merged_rows_number,columns_number + other_columns_number - 1);
4125 
4126  size_t current_merged_row_index = 0;
4127 
4128  Vector<T> columns_2_sorted_values = columns_2.sort_ascending_values();
4129  Vector<size_t> columns_2_sorted_indices = columns_2.sort_ascending_indices();
4130 
4131  for(size_t i = 0; i < columns_1_size; i++)
4132  {
4133  const T current_index_value = columns_1[i];
4134 
4135  pair<typename vector<T>::iterator,typename vector<T>::iterator> bounds = equal_range(columns_2_sorted_values.begin(), columns_2_sorted_values.end(), current_index_value);
4136 
4137  const size_t initial_index = bounds.first - columns_2_sorted_values.begin();
4138  const size_t final_index = bounds.second - columns_2_sorted_values.begin();
4139 
4140  for(size_t j = initial_index; j < final_index; j++)
4141  {
4142  const size_t current_row_2_index = columns_2_sorted_indices[j];
4143 
4144  for(size_t k = 0; k < columns_number; k++)
4145  {
4146  merged_matrix(current_merged_row_index,k) = (*this)(i,k);
4147  }
4148 
4149  for(size_t k = 0; k < other_columns_number; k++)
4150  {
4151  if(k < columns_2_index)
4152  {
4153  merged_matrix(current_merged_row_index,k+columns_number) = other_matrix(current_row_2_index,k);
4154  }
4155  else if(k > columns_2_index)
4156  {
4157  merged_matrix(current_merged_row_index,k+columns_number-1) = other_matrix(current_row_2_index,k);
4158  }
4159  }
4160 
4161  current_merged_row_index++;
4162  }
4163  }
4164 
4165  return merged_matrix;
4166 }
4167 
4168 
4169 template <class T>
4170 Matrix<T> Matrix<T>::right_join(const Matrix<T>& other_matrix, const string& columns_1_name, const string& columns_2_name,
4171  const string& left_header_tag, const string& right_header_tag) const
4172 {
4173  const size_t columns_1_index = this->get_column_index(columns_1_name);
4174  const size_t columns_2_index = other_matrix.get_column_index(columns_2_name);
4175 
4176  const Vector<T> columns_1 = this->get_column(columns_1_index);
4177  const Vector<T> columns_2 = other_matrix.get_column(columns_2_index);
4178 
4179  const size_t columns_1_size = columns_1.size();
4180  const size_t columns_2_size = columns_2.size();
4181 
4182  const Vector<T> header_1 = this->get_header();
4183  const Vector<T> header_2 = other_matrix.get_header();
4184 
4185  Vector<T> merged_header = header_1.delete_element(columns_1_index) + left_header_tag;
4186 
4187  merged_header = merged_header.assemble(header_2.delete_element(columns_2_index) + right_header_tag);
4188 
4189  merged_header = merged_header.insert_element(columns_1_index, columns_1_name);
4190 
4191  Matrix<T> merged_matrix = other_matrix.add_columns_first(columns_number-1);
4192 
4193  merged_matrix = merged_matrix.insert_column(columns_1_index, columns_2);
4194  merged_matrix = merged_matrix.delete_column(columns_number+columns_2_index);
4195 
4196  merged_matrix.set_header(merged_header);
4197 
4198  Vector<size_t> columns_1_sorted_indices = columns_1.sort_ascending_indices();
4199  Vector<size_t> columns_2_sorted_indices = columns_2.sort_ascending_indices();
4200 
4201  size_t columns_1_pointer = 0;
4202 
4203  for(size_t i = 0; i < columns_2_size; i++)
4204  {
4205  const size_t current_row_index = columns_2_sorted_indices[i];
4206 
4207  const T current_index_value = columns_2[current_row_index];
4208 
4209  if(columns_1[columns_1_sorted_indices[columns_1_pointer]] > current_index_value) continue;
4210 
4211  while(columns_1_pointer < columns_1_size)
4212  {
4213  const size_t current_row_1_index = columns_1_sorted_indices[columns_1_pointer];
4214 
4215  if(columns_1[current_row_1_index] < current_index_value)
4216  {
4217  columns_1_pointer++;
4218 
4219  continue;
4220  }
4221  else if(columns_1[current_row_1_index] == current_index_value)
4222  {
4223  for(size_t k = 0; k < columns_number; k++)
4224  {
4225  if(k < columns_1_index)
4226  {
4227  merged_matrix(current_row_index,k) = (*this)(current_row_1_index,k);
4228  }
4229  else if(k > columns_1_index)
4230  {
4231  merged_matrix(current_row_index,k) = (*this)(current_row_1_index,k);
4232  }
4233  }
4234 
4235  break;
4236  }
4237  else if(columns_1[current_row_1_index] > current_index_value)
4238  {
4239  break;
4240  }
4241  }
4242  }
4243 
4244  return merged_matrix;
4245 }
4246 
4247 
4248 template <class T>
4249 Matrix<T> Matrix<T>::left_join(const Matrix<T>& other_matrix, const string& columns_1_name, const string& columns_2_name,
4250  const string& left_header_tag, const string& right_header_tag) const
4251 {
4252  const size_t other_columns_number = other_matrix.get_columns_number();
4253 cout << "other_columns_number: " << other_columns_number << endl;
4254  const size_t columns_1_index = this->get_column_index(columns_1_name);
4255 cout << "columns_1_index: " << columns_1_index << endl;
4256  const size_t columns_2_index = other_matrix.get_column_index(columns_2_name);
4257 cout << "columns_2_index: " << columns_2_index << endl;
4258  const Vector<T> columns_1 = this->get_column(columns_1_index);
4259 cout << "columns_1: " << columns_1 << endl;
4260  const Vector<T> columns_2 = other_matrix.get_column(columns_2_index);
4261 cout << "columns_2: " << columns_2 << endl;
4262 
4263  const size_t columns_1_size = columns_1.size();
4264  const size_t columns_2_size = columns_2.size();
4265 
4266  const Vector<T> header_1 = this->get_header();
4267  const Vector<T> header_2 = other_matrix.get_header();
4268 
4269  Vector<T> merged_header = header_1.delete_index(columns_1_index) + left_header_tag;
4270 
4271  merged_header = merged_header.assemble(header_2.delete_index(columns_2_index) + right_header_tag);
4272 
4273  merged_header = merged_header.insert_element(columns_1_index, columns_1_name);
4274 
4275  Matrix<T> merged_matrix = this->add_columns(other_columns_number-1);
4276 
4277  merged_matrix.set_header(merged_header);
4278 
4279  Vector<size_t> columns_1_sorted_indices = columns_1.sort_ascending_indices();
4280  Vector<size_t> columns_2_sorted_indices = columns_2.sort_ascending_indices();
4281 
4282  size_t columns_2_pointer = 0;
4283 
4284  for(size_t i = 0; i < columns_1_size; i++)
4285  {
4286  const size_t current_row_index = columns_1_sorted_indices[i];
4287 
4288  const T current_index_value = columns_1[current_row_index];
4289 
4290  if(columns_2[columns_2_sorted_indices[columns_2_pointer]] > current_index_value) continue;
4291 
4292  while(columns_2_pointer < columns_2_size)
4293  {
4294  const size_t current_row_2_index = columns_2_sorted_indices[columns_2_pointer];
4295 
4296  if(columns_2[current_row_2_index] < current_index_value)
4297  {
4298  columns_2_pointer++;
4299 
4300  continue;
4301  }
4302  else if(columns_2[current_row_2_index] == current_index_value)
4303  {
4304  for(size_t k = 0; k < other_columns_number; k++)
4305  {
4306  if(k < columns_2_index)
4307  {
4308  merged_matrix(current_row_index,k+columns_number) = other_matrix(current_row_2_index,k);
4309  }
4310  else if(k > columns_2_index)
4311  {
4312  merged_matrix(current_row_index,k+columns_number-1) = other_matrix(current_row_2_index,k);
4313  }
4314  }
4315 
4316  break;
4317  }
4318  else if(columns_2[current_row_2_index] > current_index_value)
4319  {
4320  break;
4321  }
4322  }
4323 
4324  if(columns_2_pointer >= columns_2_size)
4325  {
4326  break;
4327  }
4328  }
4329 
4330  return merged_matrix;
4331 }
4332 
4333 
4334 template <class T>
4335 Matrix<T> Matrix<T>::left_join(const Matrix<T>& other_matrix, const size_t& columns_1_index, const size_t& columns_2_index) const
4336 {
4337  const size_t other_columns_number = other_matrix.get_columns_number();
4338 
4339  const Vector<T> columns_1 = this->get_column(columns_1_index);
4340  const Vector<T> columns_2 = other_matrix.get_column(columns_2_index);
4341 
4342  const size_t columns_1_size = columns_1.size();
4343  const size_t columns_2_size = columns_2.size();
4344 
4345  Matrix<T> merged_matrix = this->add_columns(other_columns_number-1);
4346 
4347  Vector<size_t> columns_1_sorted_indices = columns_1.sort_ascending_indices();
4348  Vector<size_t> columns_2_sorted_indices = columns_2.sort_ascending_indices();
4349 
4350  size_t columns_2_pointer = 0;
4351 
4352  for(size_t i = 0; i < columns_1_size; i++)
4353  {
4354  const size_t current_row_index = columns_1_sorted_indices[i];
4355 
4356  const T current_index_value = columns_1[current_row_index];
4357 
4358  if(columns_2[columns_2_sorted_indices[columns_2_pointer]] > current_index_value) continue;
4359  {
4360  continue;
4361  }
4362 
4363  while(columns_2_pointer < columns_2_size)
4364  {
4365  const size_t current_row_2_index = columns_2_sorted_indices[columns_2_pointer];
4366 
4367  if(columns_2[current_row_2_index] < current_index_value)
4368  {
4369  columns_2_pointer++;
4370 
4371  continue;
4372  }
4373  else if(columns_2[current_row_2_index] == current_index_value)
4374  {
4375  for(size_t k = 0; k < other_columns_number; k++)
4376  {
4377  if(k < columns_2_index)
4378  {
4379  merged_matrix(current_row_index,k+columns_number) = other_matrix(current_row_2_index,k);
4380  }
4381  else if(k > columns_2_index)
4382  {
4383  merged_matrix(current_row_index,k+columns_number-1) = other_matrix(current_row_2_index,k);
4384  }
4385  }
4386 
4387  break;
4388  }
4389  else if(columns_2[current_row_2_index] > current_index_value)
4390  {
4391  break;
4392  }
4393  }
4394 
4395  if(columns_2_pointer >= columns_2_size)
4396  {
4397  break;
4398  }
4399  }
4400 
4401  return merged_matrix;
4402 }
4403 
4404 
4405 template <class T>
4406 Matrix<T> Matrix<T>::left_join(const Matrix<T>& other_matrix, const string& matrix_1_name_1, const string& matrix_1_name_2,const string& matrix_2_name_1,const string& matrix_2_name_2,
4407  const string& left_header_tag, const string& right_header_tag) const
4408 {
4409  const size_t other_columns_number = other_matrix.get_columns_number();
4410 
4411  const size_t matrix_1_columns_1_index = this->get_column_index(matrix_1_name_1);
4412  const size_t matrix_1_columns_2_index = this->get_column_index(matrix_1_name_2);
4413 
4414  const size_t matrix_2_columns_1_index = other_matrix.get_column_index(matrix_2_name_1);
4415  const size_t matrix_2_columns_2_index = other_matrix.get_column_index(matrix_2_name_2);
4416 
4417  const Vector<T> matrix_1_columns_1 = this->get_column(matrix_1_columns_1_index);
4418  const Vector<T> matrix_1_columns_2 = this->get_column(matrix_1_columns_2_index);
4419  const Vector<T> matrix_2_columns_1 = other_matrix.get_column(matrix_2_columns_1_index);
4420  const Vector<T> matrix_2_columns_2 = other_matrix.get_column(matrix_2_columns_2_index);
4421 
4422  const size_t matrix_1_columns_1_size = matrix_1_columns_1.size();
4423  const size_t matrix_1_columns_2_size = matrix_1_columns_2.size();
4424  const size_t matrix_2_columns_1_size = matrix_2_columns_1.size();
4425 
4426  const Vector<T> header_1 = this->get_header();
4427  const Vector<T> header_2 = other_matrix.get_header();
4428 
4429  Vector<T> merged_header = header_1.delete_element(matrix_1_columns_2_index).delete_element(matrix_1_columns_1_index) + left_header_tag;
4430 
4431  merged_header = merged_header.assemble(header_2.delete_element(matrix_2_columns_2_index).delete_element(matrix_2_columns_1_index) + right_header_tag);
4432 
4433  merged_header = merged_header.insert_element(matrix_1_columns_1_index, matrix_1_name_1).insert_element(matrix_1_columns_2_index,matrix_1_name_2);
4434 
4435  Matrix<T> merged_matrix = this->add_columns(other_columns_number-2);
4436 
4437  merged_matrix.set_header(merged_header);
4438 
4439  Vector<size_t> columns_1_sorted_indices = matrix_1_columns_1.sort_ascending_indices();
4440  Vector<size_t> columns_2_sorted_indices = matrix_2_columns_1.sort_ascending_indices();
4441 
4442  size_t columns_2_pointer = 0;
4443 
4444  for(size_t i = 0; i < matrix_1_columns_1_size; i++)
4445  {
4446  const size_t current_row_index = columns_1_sorted_indices[i];
4447 
4448  const T current_index_1_value = matrix_1_columns_1[current_row_index];
4449  const T current_index_2_value = matrix_1_columns_2[current_row_index];
4450 
4451  if(matrix_2_columns_1[columns_2_sorted_indices[columns_2_pointer]] > current_index_1_value) continue;
4452 
4453  while(columns_2_pointer < matrix_1_columns_2_size)
4454  {
4455  const size_t current_row_2_index = columns_2_sorted_indices[columns_2_pointer];
4456 
4457  if(matrix_2_columns_1[current_row_2_index] < current_index_1_value)
4458  {
4459  columns_2_pointer++;
4460 
4461  continue;
4462  }
4463  else if(matrix_2_columns_1[current_row_2_index] == current_index_1_value && stod(matrix_2_columns_2[current_row_2_index]) == stod(current_index_2_value))
4464  {
4465  for(size_t k = 0; k < other_columns_number; k++)
4466  {
4467  if(k < matrix_2_columns_1_index && k < matrix_2_columns_2_index)
4468  {
4469  merged_matrix(current_row_index,k+columns_number) = other_matrix(current_row_2_index,k);
4470  }
4471  else if(k > matrix_2_columns_1_index && k < matrix_2_columns_2_index)
4472  {
4473  merged_matrix(current_row_index,k+columns_number-1) = other_matrix(current_row_2_index,k);
4474  }
4475  else if(k > matrix_2_columns_1_index && k > matrix_2_columns_2_index)
4476  {
4477  merged_matrix(current_row_index,k+columns_number-2) = other_matrix(current_row_2_index,k);
4478  }
4479  }
4480 
4481  break;
4482  }
4483  else if(matrix_2_columns_1[current_row_2_index] == current_index_1_value && stod(matrix_2_columns_2[current_row_2_index]) != stod(current_index_2_value))
4484  {
4485  columns_2_pointer++;
4486 
4487  continue;
4488  }
4489  else if(matrix_2_columns_1[current_row_2_index] > current_index_1_value)
4490  {
4491  break;
4492  }
4493  }
4494 
4495  if(columns_2_pointer >= matrix_2_columns_1_size) break;
4496  }
4497 
4498  return merged_matrix;
4499 }
4500 
4501 
4505 
4506 template <class T>
4507 Matrix<T> Matrix<T>::delete_row(const size_t& row_index) const
4508 {
4509  #ifdef __OPENNN_DEBUG__
4510 
4511  if(row_index > rows_number)
4512  {
4513  ostringstream buffer;
4514 
4515  buffer << "OpenNN Exception: Matrix Template.\n"
4516  << "Matrix<T> delete_row(const size_t&) const.\n"
4517  << "Index of row must be less than number of rows.\n"
4518  << "row index: " << row_index << "rows_number" << rows_number << "\n";
4519 
4520  throw logic_error(buffer.str());
4521  }
4522  else if(rows_number < 2)
4523  {
4524  ostringstream buffer;
4525 
4526  buffer << "OpenNN Exception: Matrix Template.\n"
4527  << "Matrix<T> delete_row(const size_t&) const.\n"
4528  << "Number of rows must be equal or greater than two.\n";
4529 
4530  throw logic_error(buffer.str());
4531  }
4532 
4533  #endif
4534 
4535  Matrix<T> new_matrix(rows_number-1, columns_number);
4536 
4537  for(size_t i = 0; i < row_index; i++)
4538  {
4539  for(size_t j = 0; j < columns_number; j++)
4540  {
4541  new_matrix(i,j) = (*this)(i,j);
4542  }
4543  }
4544 
4545  for(size_t i = row_index+1; i < rows_number; i++)
4546  {
4547  for(size_t j = 0; j < columns_number; j++)
4548  {
4549  new_matrix(i-1,j) = (*this)(i,j);
4550  }
4551  }
4552 
4553  if(!header.empty())
4554  {
4555  new_matrix.set_header(header);
4556  }
4557 
4558  return new_matrix;
4559 }
4560 
4561 
4565 
4566 template <class T>
4568 {
4569  const size_t rows_to_delete_number = rows_to_remove.size();
4570 
4571  if(rows_to_delete_number == 0) return Matrix<T>(*this);
4572 
4573  const size_t rows_to_keep_number = rows_number - rows_to_delete_number;
4574 
4575  Vector<size_t> rows_to_keep(rows_to_keep_number);
4576 
4577  size_t index = 0;
4578 
4579  for(size_t i = 0; i < rows_number; i++)
4580  {
4581  if(!rows_to_remove.contains(i))
4582  {
4583  rows_to_keep[index] = i;
4584 
4585  index++;
4586  }
4587  }
4588 
4589  return get_submatrix_rows(rows_to_keep);
4590 }
4591 
4592 
4596 
4597 template <class T>
4599 {
4600  Vector<T> row(columns_number);
4601 
4602  size_t count = 0;
4603 
4604  for(size_t i = 0; i < rows_number; i++)
4605  {
4606  row = get_row(i);
4607 
4608  if(!row.contains(value))
4609  {
4610  count++;
4611  }
4612  }
4613 
4614  if(count == 0)
4615  {
4616  Matrix<T> copy_matrix(*this);
4617 
4618  return copy_matrix;
4619  }
4620 
4621  Vector<size_t> indices(count);
4622 
4623  size_t index = 0;
4624 
4625  for(size_t i = 0; i < rows_number; i++)
4626  {
4627  row = get_row(i);
4628 
4629  if(!row.contains(value))
4630  {
4631  indices[index] = i;
4632  index++;
4633  }
4634  }
4635 
4636  return get_submatrix_rows(indices);
4637 }
4638 
4639 
4643 
4644 template <class T>
4646 {
4647  Vector<T> column(rows_number);
4648 
4649  size_t count = 0;
4650 
4651  for(size_t i = 0; i < columns_number; i++)
4652  {
4653  column = get_column(i);
4654 
4655  if(!column.contains(value))
4656  {
4657  count++;
4658  }
4659  }
4660 
4661  if(count == 0)
4662  {
4663  Matrix<T> copy_matrix(*this);
4664 
4665  return copy_matrix;
4666  }
4667 
4668  Vector<size_t> indices(count);
4669 
4670  size_t index = 0;
4671 
4672  for(size_t i = 0; i < columns_number; i++)
4673  {
4674  column = get_column(i);
4675 
4676  if(!column.contains(value))
4677  {
4678  indices[index] = i;
4679  index++;
4680  }
4681  }
4682 
4683  return get_submatrix_columns(indices);
4684 }
4685 
4686 
4690 
4691 template <class T>
4693 {
4694  const Vector<size_t> indices = get_columns_indices(value);
4695 
4696  return delete_rows(indices);
4697 }
4698 
4699 
4703 
4704 template <class T>
4705 Matrix<T> Matrix<T>::delete_first_rows(const size_t& number) const
4706 {
4707  const Vector<size_t> indices(number, 1, rows_number-1);
4708 
4709  return get_submatrix_rows(indices);
4710 }
4711 
4712 
4716 
4717 template <class T>
4718 Matrix<T> Matrix<T>::delete_first_columns(const size_t& number) const
4719 {
4720  const Vector<size_t> indices(number, 1, columns_number-1);
4721 
4722  return get_submatrix_columns(indices);
4723 }
4724 
4725 
4728 
4729 template <class T>
4730 Matrix<T> Matrix<T>::get_first_rows(const size_t& number) const
4731 {
4732  const Vector<size_t> indices(0, 1, number-1);
4733 
4734  return get_submatrix_rows(indices);
4735 }
4736 
4737 
4740 
4741 template <class T>
4742 Matrix<T> Matrix<T>::get_first_columns(const size_t& number) const
4743 {
4744  const Vector<size_t> indices(0, 1, number-1);
4745 
4746  return get_submatrix_columns(indices);
4747 }
4748 
4749 
4752 
4753 template <class T>
4754 T Matrix<T>::get_first(const size_t& column_index) const
4755 {
4756  return (*this)(0, column_index);
4757 }
4758 
4759 
4762 
4763 template <class T>
4764 T Matrix<T>::get_first(const string& column_name) const
4765 {
4766  const size_t column_index = get_column_index(column_name);
4767 
4768  return (*this)(0, column_index);
4769 }
4770 
4771 
4774 
4775 template <class T>
4776 T Matrix<T>::get_last(const size_t& column_index) const
4777 {
4778  return (*this)(rows_number-1, column_index);
4779 
4780 }
4781 
4782 
4785 
4786 template <class T>
4787 T Matrix<T>::get_last(const string& column_name) const
4788 {
4789  const size_t column_index = get_column_index(column_name);
4790 
4791  return (*this)(rows_number-1, column_index);
4792 }
4793 
4794 
4798 
4799 template <class T>
4800 Matrix<T> Matrix<T>::delete_last_rows(const size_t& number) const
4801 {
4802  const Vector<size_t> indices(0, 1, rows_number-number-1);
4803 
4804  return get_submatrix_rows(indices);
4805 }
4806 
4807 
4811 
4812 template <class T>
4813 Matrix<T> Matrix<T>::delete_last_columns(const size_t& number) const
4814 {
4815  const Vector<size_t> indices(0, 1, columns_number-number-1);
4816 
4817  return get_submatrix_columns(indices);
4818 }
4819 
4820 
4824 
4825 template <class T>
4826 Matrix<T> Matrix<T>::get_last_columns(const size_t& number) const
4827 {
4828  const size_t columns_number = get_columns_number();
4829 
4830  const Vector<size_t> indices(columns_number-number, 1, columns_number-1);
4831 
4832  return get_submatrix_columns(indices);
4833 }
4834 
4835 
4839 
4840 template <class T>
4841 Matrix<T> Matrix<T>::get_last_rows(const size_t& number) const
4842 {
4843  const size_t rows_number = get_rows_number();
4844 
4845  const Vector<size_t> indices(rows_number-number, 1, rows_number-1);
4846 
4847  return get_submatrix_rows(indices);
4848 }
4849 
4850 
4854 
4855 template <class T>
4856 Matrix<T> Matrix<T>::delete_column(const size_t& column_index) const
4857 {
4858  #ifdef __OPENNN_DEBUG__
4859 
4860  if(column_index >= columns_number)
4861  {
4862  ostringstream buffer;
4863 
4864  buffer << "OpenNN Exception: Matrix Template.\n"
4865  << "Matrix<T> delete_column(const size_t&) const.\n"
4866  << "Index of column must be less than number of columns.\n";
4867 
4868  throw logic_error(buffer.str());
4869  }
4870  else if(columns_number < 2)
4871  {
4872  ostringstream buffer;
4873 
4874  buffer << "OpenNN Exception: Matrix Template.\n"
4875  << "Matrix<T> delete_column(const size_t&) const.\n"
4876  << "Number of columns must be equal or greater than two.\n";
4877 
4878  throw logic_error(buffer.str());
4879  }
4880 
4881  #endif
4882 
4883  Matrix<T> new_matrix(rows_number, columns_number-1);
4884 
4885  for(size_t i = 0; i < rows_number; i++)
4886  {
4887  for(size_t j = 0; j < column_index; j++)
4888  {
4889  new_matrix(i,j) = (*this)(i,j);
4890  }
4891  }
4892 
4893  for(size_t i = 0; i < rows_number; i++)
4894  {
4895  for(size_t j = column_index+1; j < columns_number; j++)
4896  {
4897  new_matrix(i,j-1) = (*this)(i,j);
4898  }
4899  }
4900 
4901  if(!header.empty())
4902  {
4903  const Vector<string> new_header = get_header().delete_index(column_index);
4904 
4905  new_matrix.set_header(new_header);
4906  }
4907 
4908  return new_matrix;
4909 }
4910 
4911 
4915 
4916 template <class T>
4917 Matrix<T> Matrix<T>::delete_column(const string& column_name) const
4918 {
4919  const Vector<size_t> indices = header.get_indices_equal_to(column_name);
4920 
4921  const size_t occurrences_number = indices.size();
4922 
4923  if(occurrences_number == 0)
4924  {
4925  return *this;
4926  }
4927  else if(occurrences_number == 1)
4928  {
4929  return delete_column(indices[0]);
4930  }
4931  else
4932  {
4933  ostringstream buffer;
4934 
4935  buffer << "OpenNN Exception: Matrix Template.\n"
4936  << "void Matrix<T>::delete_column_by_name(const string& column_name).\n"
4937  << "Number of columns with name " << column_name << " is " << indices.size() << ").\n";
4938 
4939  throw logic_error(buffer.str());
4940  }
4941 }
4942 
4943 
4947 
4948 template <class T>
4950 {
4951  if(delete_indices.empty())
4952  {
4953  return Matrix<T>(*this);
4954  }
4955 
4956  Matrix<T> new_data;
4957 
4958  Vector<size_t> keep_indices;
4959 
4960  for(size_t i = 0; i < columns_number; i++)
4961  {
4962  if(!delete_indices.contains(i))
4963  {
4964  keep_indices.push_back(i);
4965  }
4966  }
4967 
4968  const size_t keep_indices_size = keep_indices.size();
4969 
4970  if(keep_indices_size != columns_number)
4971  {
4972  new_data = get_submatrix_columns(keep_indices);
4973 
4974  if(!header.empty()) new_data.set_header(header.get_subvector(keep_indices));
4975  }
4976 
4977  return new_data;
4978 }
4979 
4980 
4984 
4985 template <class T>
4987 {
4988  const Vector<size_t> indices = get_columns_indices(delete_names);
4989 
4990  return delete_columns(indices);
4991 }
4992 
4993 
4997 
4998 template <class T>
5000 {
5001  Vector<size_t> indices;
5002 
5003  for(size_t i = 0; i < columns_number; i++)
5004  {
5005  for(size_t j = 0; j < substrings.size(); j++)
5006  {
5007  if(header[i].find(substrings[j]) != string::npos)
5008  {
5009  indices.push_back(i);
5010 
5011  break;
5012  }
5013  }
5014  }
5015 
5016  return delete_columns(indices);
5017 }
5018 
5019 
5021 
5022 template <class T>
5024 {
5025  Vector<size_t> constant_columns;
5026 
5027  for(size_t i = 0; i < columns_number; i++)
5028  {
5029  if(is_column_constant(i))
5030  {
5031  constant_columns.push_back(i);
5032  }
5033  }
5034 
5035  return constant_columns;
5036 }
5037 
5038 
5041 
5042 template <class T>
5044 {
5045  return delete_columns(get_constant_columns_indices());
5046 }
5047 
5048 
5051 
5052 template <class T>
5054 {
5055  const Vector<size_t> binary_columns = get_binary_columns_indices();
5056 
5057  return delete_columns(binary_columns);
5058 }
5059 
5060 
5063 
5064 template <class T>
5065 Matrix<T> Matrix<T>::delete_binary_columns(const double& minimum_support) const
5066 {
5067  const Vector<size_t> binary_columns = get_binary_columns_indices();
5068 
5069  const size_t binary_columns_number = binary_columns.size();
5070 
5071  Vector<size_t> columns_to_remove;
5072 
5073  for(size_t i = 0; i < binary_columns_number; i++)
5074  {
5075  const double support = get_column(binary_columns[i]).calculate_sum()/static_cast<double>(rows_number);
5076 
5077  if(support < minimum_support) columns_to_remove.push_back(binary_columns[i]);
5078  }
5079 
5080  return delete_columns(columns_to_remove);
5081 }
5082 
5083 
5086 
5087 template <class T>
5089 {
5090  Vector<size_t> constant_rows;
5091 
5092  Vector<T> row;
5093 
5094  for(size_t i = 0; i < rows_number; i++)
5095  {
5096  row = get_row(i);
5097 
5098  if(row.is_constant())
5099  {
5100  constant_rows.push_back(i);
5101  }
5102  }
5103 
5104  return delete_rows(constant_rows);
5105 }
5106 
5107 
5110 
5111 template <class T>
5113 {
5114  #ifdef __OPENNN_DEBUG__
5115 
5116  const size_t other_columns_number = other_matrix.get_columns_number();
5117 
5118  if(other_columns_number != columns_number)
5119  {
5120  ostringstream buffer;
5121 
5122  buffer << "OpenNN Exception: Matrix Template.\n"
5123  << "Matrix<T> assemble_rows(const Matrix<T>&) const method.\n"
5124  << "Number of columns of other matrix (" << other_columns_number << ") must be equal to number of columns of this matrix (" << columns_number << ").\n";
5125 
5126  throw logic_error(buffer.str());
5127  }
5128 
5129  #endif
5130 
5131  const size_t other_rows_number = other_matrix.get_rows_number();
5132 
5133  if(rows_number == 0 && other_rows_number == 0)
5134  {
5135  return Matrix<T>();
5136  }
5137  else if(rows_number == 0)
5138  {
5139  return other_matrix;
5140  }
5141 
5142  Matrix<T> assembly(rows_number + other_rows_number, columns_number);
5143 
5144  for(size_t i = 0; i < rows_number; i++)
5145  {
5146  for(size_t j = 0; j < columns_number; j++)
5147  {
5148  assembly(i,j) = (*this)(i,j);
5149  }
5150  }
5151 
5152  for(size_t i = 0; i < other_rows_number; i++)
5153  {
5154  for(size_t j = 0; j < columns_number; j++)
5155  {
5156  assembly(rows_number+i,j) = other_matrix(i,j);
5157  }
5158  }
5159 
5160  if(!header.empty())
5161  {
5162  assembly.set_header(header);
5163  }
5164  else if(other_matrix.get_header() != "")
5165  {
5166  assembly.set_header(other_matrix.get_header());
5167  }
5168 
5169  return assembly;
5170 }
5171 
5172 
5176 
5177 template <class T>
5178 Matrix<T> Matrix<T>::sort_ascending(const size_t& column_index) const
5179 {
5180  Matrix<T> sorted(rows_number, columns_number);
5181 
5182  const Vector<T> column = get_column(column_index);
5183 
5184  const Vector<size_t> indices = column.sort_ascending_indices();
5185 
5186  size_t index;
5187 
5188  for(size_t i = 0; i < rows_number; i++)
5189  {
5190  index = indices[i];
5191 
5192  for(size_t j = 0; j < columns_number; j++)
5193  {
5194  sorted(i,j) = (*this)(index, j);
5195  }
5196  }
5197 
5198  return sorted;
5199 }
5200 
5201 
5205 
5206 template <class T>
5207 Matrix<T> Matrix<T>::sort_ascending_strings(const size_t& column_index) const
5208 {
5209  Matrix<T> sorted(rows_number, columns_number);
5210 
5211  const Vector<double> column = get_column(column_index).string_to_double();
5212 
5213  const Vector<size_t> indices = column.sort_ascending_indices();
5214 
5215  size_t index;
5216 
5217  for(size_t i = 0; i < rows_number; i++)
5218  {
5219  index = indices[i];
5220 
5221  for(size_t j = 0; j < columns_number; j++)
5222  {
5223  sorted(i,j) = (*this)(index, j);
5224  }
5225  }
5226 
5227  if(!header.empty()) sorted.set_header(header);
5228 
5229  return sorted;
5230 }
5231 
5232 
5236 
5237 template <class T>
5238 Matrix<T> Matrix<T>::sort_descending_strings(const size_t& column_index) const
5239 {
5240  Matrix<T> sorted(rows_number, columns_number);
5241 
5242  const Vector<double> column = get_column(column_index).string_to_double();
5243 
5244  const Vector<size_t> indices = column.sort_descending_indices();
5245 
5246  size_t index;
5247 
5248  for(size_t i = 0; i < rows_number; i++)
5249  {
5250  index = indices[i];
5251 
5252  for(size_t j = 0; j < columns_number; j++)
5253  {
5254  sorted(i,j) = (*this)(index, j);
5255  }
5256  }
5257 
5258  if(!header.empty()) sorted.set_header(header);
5259 
5260  return sorted;
5261 }
5262 
5263 
5264 template <class T>
5266 {
5267  #ifdef __OPENNN_DEBUG__
5268  const size_t rank_size = rank.size();
5269 
5270  if(rows_number != rank_size) {
5271  ostringstream buffer;
5272 
5273  buffer << "OpenNN Exception: Matrix Template.\n"
5274  << "Matrix<T> sort_rank_rows(const Vector<size_t>&) const.\n"
5275  << "Matrix number of rows is " << rows_number << " and rank size is " << rank_size
5276  << " and they must be the same.\n";
5277 
5278  throw logic_error(buffer.str());
5279  }
5280 
5281  #endif
5282 
5283  Matrix<T> sorted_matrix(rows_number,columns_number);
5284 
5285  for(size_t i = 0; i < rows_number; i++)
5286  {
5287  sorted_matrix.set_row(i,this->get_row(rank[i]));
5288  }
5289 
5290  if(!header.empty()) sorted_matrix.set_header(header);
5291 
5292  return sorted_matrix;
5293 }
5294 
5295 
5296 template <class T>
5297 Matrix<T> Matrix<T>::sort_columns(const Vector<size_t>& rank) const
5298 {
5299  #ifdef __OPENNN_DEBUG__
5300 
5301  const size_t rank_size = rank.size();
5302 
5303  if(rows_number != rank_size) {
5304  ostringstream buffer;
5305 
5306  buffer << "OpenNN Exception: Matrix Template.\n"
5307  << "Matrix<T> sort_rank_rows(const Vector<size_t>&) const.\n"
5308  << "Matrix number of rows is " << rows_number << " and rank size is " << rank_size
5309  << " and they must be the same.\n";
5310 
5311  throw logic_error(buffer.str());
5312  }
5313 
5314  #endif
5315 
5316  Matrix<T> sorted_matrix(rows_number,columns_number);
5317 
5318  for(size_t i = 0; i < columns_number; i++)
5319  {
5320  sorted_matrix.set_column(i,this->get_column(rank[i]),this->get_header()[rank[i]]);
5321  }
5322 
5323  sorted_matrix.set_header(header);
5324 
5325  return sorted_matrix;
5326 }
5327 
5328 
5329 template <class T>
5330 Matrix<T> Matrix<T>::sort_columns(const Vector<string>& new_header) const
5331 {
5332  #ifdef __OPENNN_DEBUG__
5333 
5334  if(columns_number != new_header.size()) {
5335  ostringstream buffer;
5336 
5337  buffer << "OpenNN Exception: Matrix Template.\n"
5338  << "Matrix<T> sort_columns(const Vector<string>& new_header) const.\n"
5339  << "New header size doesn't match with columns number.\n";
5340 
5341  throw logic_error(buffer.str());
5342  }
5343 
5344  const size_t count = new_header.count_equal_to(this->get_header());
5345 
5346  if(count != new_header.size()) {
5347  ostringstream buffer;
5348 
5349  buffer << "OpenNN Exception: Matrix Template.\n"
5350  << "Matrix<T> sort_columns(const Vector<string>& new_header) const.\n"
5351  << "Occurrences number doesn't match with columns number\n";
5352 
5353  throw logic_error(buffer.str());
5354  }
5355 
5356  #endif
5357 
5358  Matrix<T> sorted_matrix(rows_number,columns_number);
5359 
5360  for(size_t i = 0; i < new_header.size(); i++)
5361  {
5362  const string current_variable = new_header[i];
5363 
5364  for(size_t j = 0; j < columns_number; j++)
5365  {
5366  const string current_column_name = this->get_header()[j];
5367 
5368  if(current_variable == current_column_name)
5369  {
5370  sorted_matrix.set_column(i,this->get_column(j),current_variable);
5371 
5372  break;
5373  }
5374  }
5375  }
5376 
5377  return sorted_matrix;
5378 }
5379 
5380 
5384 
5385 template <class T>
5386 Matrix<T> Matrix<T>::sort_descending(const size_t& column_index) const
5387 {
5388  Matrix<T> sorted(rows_number, columns_number);
5389 
5390  const Vector<T> column = get_column(column_index);
5391 
5392  const Vector<size_t> indices = column.sort_descending_indices();
5393 
5394  size_t index;
5395 
5396  for(size_t i = 0; i < rows_number; i++)
5397  {
5398  index = indices[i];
5399 
5400  for(size_t j = 0; j < columns_number; j++)
5401  {
5402  sorted(i,j) = (*this)(index, j);
5403  }
5404  }
5405 
5406  return sorted;
5407 }
5408 
5411 
5412 template <class T>
5414 {
5415  #ifdef __OPENNN_DEBUG__
5416 
5417  const size_t other_rows_number = other_matrix.get_rows_number();
5418 
5419  if(other_rows_number != rows_number)
5420  {
5421  ostringstream buffer;
5422 
5423  buffer << "OpenNN Exception: Matrix Template.\n"
5424  << "Matrix<T> assemble_columns(const Matrix<T>&) const method.\n"
5425  << "Number of rows of other matrix (" << other_rows_number << ") must be equal to number of rows of this matrix (" << rows_number << ").\n";
5426 
5427  throw logic_error(buffer.str());
5428  }
5429 
5430  #endif
5431 
5432  const size_t other_columns_number = other_matrix.get_columns_number();
5433 
5434  Matrix<T> assembly(rows_number, columns_number + other_columns_number);
5435 
5436  for(size_t i = 0; i < rows_number; i++)
5437  {
5438  for(size_t j = 0; j < columns_number; j++)
5439  {
5440  assembly(i,j) = (*this)(i,j);
5441  }
5442  for(size_t j = 0; j < other_columns_number; j++)
5443  {
5444  assembly(i,columns_number+j) = other_matrix(i,j);
5445  }
5446  }
5447 
5448  if(!header.empty() && other_matrix.get_header() != "") assembly.set_header(header.assemble(other_matrix.get_header()));
5449 
5450  return assembly;
5451 }
5452 
5453 
5456 
5457 template <class T>
5458 void Matrix<T>::initialize(const T& value)
5459 {
5460  fill(this->begin(),this->end(), value);
5461 }
5462 
5463 
5465 
5466 template <class T>
5468 {
5469  for(size_t i = 0; i < this->size(); i++) {
5470  (*this)[i] = static_cast<T>(i);
5471  }
5472 }
5473 
5474 
5478 
5479 template <class T>
5480 void Matrix<T>::replace(const T& find_what, const T& replace_with)
5481 {
5482  const size_t size = this->size();
5483 
5484  for(size_t i = 0; i < size; i++)
5485  {
5486  if((*this)[i] == find_what)
5487  {
5488  (*this)[i] = replace_with;
5489  }
5490  }
5491 }
5492 
5496 
5497 template <class T>
5498 void Matrix<T>::replace_header(const string& find_what, const string& replace_with)
5499 {
5500  for(size_t i = 0; i < columns_number; i++)
5501  if(header[i] == find_what)
5502  header[i] = replace_with;
5503 }
5504 
5505 
5510 
5511 template <class T>
5512 void Matrix<T>::replace_in_row(const size_t& row_index, const T& find_what, const T& replace_with)
5513 {
5514  for(size_t i = 0; i < columns_number; i++)
5515  {
5516  if((*this)(row_index,i) == find_what)
5517  {
5518  (*this)(row_index,i) = replace_with;
5519  }
5520  }
5521 }
5522 
5523 
5528 
5529 template <class T>
5530 void Matrix<T>::replace_in_column(const size_t& column_index, const T& find_what, const T& replace_with)
5531 {
5532  for(size_t i = 0; i < rows_number; i++)
5533  {
5534  if((*this)(i, column_index) == find_what)
5535  {
5536  (*this)(i, column_index) = replace_with;
5537  }
5538  }
5539 }
5540 
5541 
5546 
5547 template <class T>
5548 void Matrix<T>::replace_in_column(const string& column_name, const T& find_what, const T& replace_with)
5549 {
5550  const size_t column_index = get_column_index(column_name);
5551 
5552  replace_in_column(column_index, find_what, replace_with);
5553 }
5554 
5558 
5559 template <class T>
5560 void Matrix<T>::replace_substring(const string& find_what, const string& replace_with)
5561 {
5562  const size_t size = this->size();
5563 
5564  for(size_t i = 0; i < size; i++)
5565  {
5566  size_t position = 0;
5567 
5568  while((position = (*this)[i].find(find_what, position)) != string::npos)
5569  {
5570  (*this)[i].replace(position, find_what.length(), replace_with);
5571 
5572  position += replace_with.length();
5573  }
5574  }
5575 }
5576 
5577 
5582 
5583 template <class T>
5584 void Matrix<T>::replace_substring(const size_t& column_index, const string& find_what, const string& replace_with)
5585 {
5586  for(size_t i = 0; i < rows_number; i++)
5587  {
5588  size_t position = 0;
5589 
5590  while((position = (*this)(i, column_index).find(find_what, position)) != string::npos)
5591  {
5592  (*this)(i, column_index).replace(position, find_what.length(), replace_with);
5593 
5594  position += replace_with.length();
5595  }
5596  }
5597 }
5598 
5599 
5604 
5605 template <class T>
5606 void Matrix<T>::replace_substring(const string& column_name, const string& find_what, const string& replace_with)
5607 {
5608  const size_t column_index = get_column_index(column_name);
5609 
5610  replace_substring(column_index, find_what, replace_with);
5611 }
5612 
5613 
5617 
5618 template <class T>
5619 void Matrix<T>::replace_contains(const string& find_what, const string& replace_with)
5620 {
5621  const size_t size = this->size();
5622 
5623  for(size_t i = 0; i < size; i++)
5624  {
5625  if((*this)[i].find(find_what) != string::npos)
5626  {
5627  (*this)[i] = replace_with;
5628  }
5629  }
5630 }
5631 
5632 
5637 
5638 template <class T>
5639 void Matrix<T>::replace_contains_in_row(const size_t& row_index, const string& find_what, const string& replace_with)
5640 {
5641  for(size_t i = 0; i < columns_number; i++)
5642  {
5643  if((*this)(row_index, i).find(find_what) != string::npos)
5644  {
5645  (*this)(row_index, i) = replace_with;
5646  }
5647  }
5648 }
5649 
5650 
5655 
5656 template <class T>
5657 void Matrix<T>::replace_column_equal_to(const string& column_name, const T& find_value, const T& replace_value)
5658 {
5659  const size_t column_index = get_column_index(column_name);
5660 
5661  for(size_t i = 0; i < rows_number; i++)
5662  {
5663  if((*this)(i,column_index) == find_value)
5664  {
5665  (*this)(i,column_index) = replace_value;
5666  }
5667  }
5668 }
5669 
5670 
5675 
5676 template <class T>
5677 void Matrix<T>::replace_column_equal_to(const size_t& column_index, const T& find_value, const T& replace_value)
5678 {
5679  for(size_t i = 0; i < rows_number; i++)
5680  {
5681  if((*this)(i,column_index) == find_value)
5682  {
5683  (*this)(i,column_index) = replace_value;
5684  }
5685  }
5686 }
5687 
5688 
5693 
5694 template <class T>
5695 void Matrix<T>::replace_column_not_equal_to(const string& column_name, const T& find_value, const T& replace_value)
5696 {
5697  const size_t column_index = get_column_index(column_name);
5698 
5699  for(size_t i = 0; i < rows_number; i++)
5700  {
5701  if((*this)(i,column_index) != find_value)
5702  {
5703  (*this)(i,column_index) = replace_value;
5704  }
5705  }
5706 }
5707 
5708 
5713 
5714 template <class T>
5715 void Matrix<T>::replace_column_not_equal_to(const string& column_name, const Vector<T>& find_values, const T& replace_value)
5716 {
5717  const size_t column_index = get_column_index(column_name);
5718 
5719  for(size_t i = 0; i < rows_number; i++)
5720  {
5721  if(!find_values.contains((*this)(i,column_index)))
5722  {
5723  (*this)(i,column_index) = replace_value;
5724  }
5725  }
5726 }
5727 
5728 
5729 template <class T>
5730 void Matrix<T>::replace_column_less_than_string(const string& name, const double& value, const T& replace)
5731 {
5732  const size_t column_index = get_column_index(name);
5733 
5734  const Vector<size_t> row_indices = get_column(name).string_to_double().get_indices_less_than(value);
5735 
5736  for(size_t i = 0; i < row_indices.size(); i++)
5737  {
5738  (*this)(row_indices[i], column_index) = replace;
5739  }
5740 }
5741 
5742 
5747 
5748 template <class T>
5749 void Matrix<T>::replace_column_contains(const string& column_name, const string& find_what, const string& replace_with)
5750 {
5751  const size_t column_index = get_column_index(column_name);
5752 
5753  for(size_t i = 0; i < rows_number; i++)
5754  {
5755  if((*this)(i,column_index).find(find_what) != string::npos)
5756  {
5757  (*this)(i,column_index) = replace_with;
5758  }
5759  }
5760 }
5761 
5762 
5766 
5767 template <class T>
5768 size_t Matrix<T>::count_column_contains(const string& column_name, const string& find_what) const
5769 {
5770  const size_t column_index = get_column_index(column_name);
5771 
5772  size_t count = 0;
5773 
5774  for(size_t i = 0; i < rows_number; i++)
5775  {
5776  if((*this)(i,column_index).find(find_what) != string::npos)
5777  {
5778  count++;
5779  }
5780  }
5781 
5782  return count;
5783 }
5784 
5785 
5787 
5788 template <class T>
5790 {
5791  Vector<size_t> occurrences(columns_number, 0.0);
5792 
5793  for(size_t i = 0; i < rows_number; i++)
5794  {
5795  for(size_t j = 0; j < columns_number; j++)
5796  {
5797  if((*this)(i,j) == value) occurrences[j]++;
5798  }
5799  }
5800 
5801  return occurrences;
5802 }
5803 
5804 
5808 
5809 template <class T>
5810 bool Matrix<T>::has_column_value(const size_t& column_index, const T& value) const
5811 {
5812  for(size_t i = 0; i < rows_number; i++)
5813  {
5814  if((*this)(i,column_index) == value)
5815  {
5816  return true;
5817  }
5818  }
5819 
5820  return false;
5821 }
5822 
5823 
5828 
5829 template <class T>
5830 void Matrix<T>::randomize_uniform(const double& minimum, const double& maximum)
5831 {
5832  #ifdef __OPENNN_DEBUG__
5833 
5834  if(minimum > maximum)
5835  {
5836  ostringstream buffer;
5837 
5838  buffer << "OpenNN Exception: Matrix Template.\n"
5839  << "void randomize_uniform(const double&, const double&) const method.\n"
5840  << "Minimum value must be less or equal than maximum value.\n";
5841 
5842  throw logic_error(buffer.str());
5843  }
5844 
5845  #endif
5846 
5847  for(size_t i = 0; i < this->size(); i++)
5848  {
5849  (*this)[i] = static_cast<T>(calculate_random_uniform(minimum, maximum));
5850  }
5851 }
5852 
5853 
5858 
5859 template <class T>
5860 void Matrix<T>::randomize_uniform(const Vector<double>& minimums, const Vector<double>& maximums)
5861 {
5862 
5863 
5864  #ifdef __OPENNN_DEBUG__
5865 
5866  if(minimums.size() != columns_number)
5867  {
5868  ostringstream buffer;
5869 
5870  buffer << "OpenNN Exception: Matrix Template.\n"
5871  << "void randomize_uniform(const Vector<double>&, const Vector<double>&) const method.\n"
5872  << "Size of minimums must be equal to number of columns.\n";
5873 
5874  throw logic_error(buffer.str());
5875  }
5876 
5877  if(maximums.size() != columns_number)
5878  {
5879  ostringstream buffer;
5880 
5881  buffer << "OpenNN Exception: Matrix Template.\n"
5882  << "void randomize_uniform(const Vector<double>&, const Vector<double>&) const method.\n"
5883  << "Size of maximums must be equal to number of columns.\n";
5884 
5885  throw logic_error(buffer.str());
5886  }
5887 
5888  if(minimums > maximums)
5889  {
5890  ostringstream buffer;
5891 
5892  buffer << "OpenNN Exception: Matrix Template.\n"
5893  << "void randomize_uniform(const Vector<double>&, const Vector<double>&) const method.\n"
5894  << "Minimums must be less or equal than maximums.\n";
5895 
5896  throw logic_error(buffer.str());
5897  }
5898 
5899  #endif
5900 
5901  Vector<double> column(rows_number);
5902 
5903  for(size_t i = 0; i < columns_number; i++)
5904  {
5905  column.randomize_uniform(minimums[i], maximums[i]);
5906 
5907  set_column(i, column);
5908  }
5909 }
5910 
5911 
5916 
5917 template <class T>
5918 void Matrix<T>::randomize_uniform(const Matrix<double>& minimum, const Matrix<double>& maximum)
5919 {
5920 
5921 
5922  #ifdef __OPENNN_DEBUG__
5923 
5924  if(minimum > maximum)
5925  {
5926  ostringstream buffer;
5927 
5928  buffer << "OpenNN Exception: Matrix Template.\n"
5929  << "void randomize_uniform(const Matrix<double>&, const Matrix<double>&) const method.\n"
5930  << "Minimum values must be less or equal than their respective maximum values.\n";
5931 
5932  throw logic_error(buffer.str());
5933  }
5934 
5935  #endif
5936 
5937 
5938  for(size_t i = 0; i < this->size(); i++)
5939  {
5940  (*this)[i] = calculate_random_uniform(minimum[i], maximum[i]);
5941  }
5942 }
5943 
5944 
5949 
5950 template <class T>
5951 void Matrix<T>::randomize_normal(const double& mean, const double& standard_deviation)
5952 {
5953 
5954  #ifdef __OPENNN_DEBUG__
5955 
5956  if(standard_deviation < 0.0)
5957  {
5958  ostringstream buffer;
5959 
5960  buffer << "OpenNN Exception: Matrix Template.\n"
5961  << "void randomize_normal(const double&, const double&) method.\n"
5962  << "Standard deviation must be equal or greater than zero.\n";
5963 
5964  throw logic_error(buffer.str());
5965  }
5966 
5967  #endif
5968 
5969  for(size_t i = 0; i < this->size(); i++)
5970  {
5971  (*this)[i] = calculate_random_normal(mean, standard_deviation);
5972  }
5973 }
5974 
5975 
5980 
5981 template <class T>
5982 void Matrix<T>::randomize_normal(const Vector<double>& means, const Vector<double>& standard_deviations)
5983 {
5984 
5985 
5986  #ifdef __OPENNN_DEBUG__
5987 
5988  if(means.size() != columns_number)
5989  {
5990  ostringstream buffer;
5991 
5992  buffer << "OpenNN Exception: Matrix Template.\n"
5993  << "void randomize_normal(const Vector<double>&, const Vector<double>&) const method.\n"
5994  << "Size of means must be equal to number of columns.\n";
5995 
5996  throw logic_error(buffer.str());
5997  }
5998 
5999  if(standard_deviations.size() != columns_number)
6000  {
6001  ostringstream buffer;
6002 
6003  buffer << "OpenNN Exception: Matrix Template.\n"
6004  << "void randomize_normal(const Vector<double>&, const Vector<double>&) const method.\n"
6005  << "Size of standard deviations must be equal to number of columns.\n";
6006 
6007  throw logic_error(buffer.str());
6008  }
6009 
6010  if(means < 0.0)
6011  {
6012  ostringstream buffer;
6013 
6014  buffer << "OpenNN Exception: Matrix Template.\n"
6015  << "void randomize_normal(const Vector<double>&, const Vector<double>&) const method.\n"
6016  << "Means must be less or equal than zero.\n";
6017 
6018  throw logic_error(buffer.str());
6019  }
6020 
6021  #endif
6022 
6023  Vector<double> column(rows_number);
6024 
6025  for(size_t i = 0; i < columns_number; i++)
6026  {
6027  column.randomize_normal(means[i], standard_deviations[i]);
6028 
6029  set_column(i, column);
6030  }
6031 }
6032 
6033 
6038 
6039 template <class T>
6040 void Matrix<T>::randomize_normal(const Matrix<double>& mean, const Matrix<double>& standard_deviation)
6041 {
6042  #ifdef __OPENNN_DEBUG__
6043 
6044  if(standard_deviation < 0.0)
6045  {
6046  ostringstream buffer;
6047 
6048  buffer << "OpenNN Exception: Matrix Template.\n"
6049  << "void randomize_normal(const Matrix<double>&, const Matrix<double>&) const method.\n"
6050  << "Standard deviations must be equal or greater than zero.\n";
6051 
6052  throw logic_error(buffer.str());
6053  }
6054 
6055  #endif
6056 
6057  for(size_t i = 0; i < this->size(); i++)
6058  {
6059  (*this)[i] = calculate_random_uniform(mean[i], standard_deviation[i]);
6060  }
6061 }
6062 
6063 
6066 
6067 template <class T>
6069 {
6070 
6071  #ifdef __OPENNN_DEBUG__
6072 
6073  if(rows_number != columns_number)
6074  {
6075  ostringstream buffer;
6076 
6077  cout << "OpenNN Exception: Matrix Template.\n"
6078  << "initialize_identity() const method.\n"
6079  << "Matrix must be square.\n";
6080 
6081  throw logic_error(buffer.str());
6082  }
6083 
6084  #endif
6085 
6086  this->initialize(0);
6087 
6088  for(size_t i = 0; i < rows_number; i++)
6089  {
6090  (*this)(i,i) = 1;
6091  }
6092 }
6093 
6094 
6097 
6098 template <class T>
6100 {
6101 
6102 
6103  #ifdef __OPENNN_DEBUG__
6104 
6105  if(rows_number != columns_number)
6106  {
6107  ostringstream buffer;
6108 
6109  cout << "OpenNN Exception: Matrix Template.\n"
6110  << "initialize_diagonal(const T&) const method.\n"
6111  << "Matrix must be square.\n";
6112 
6113  throw logic_error(buffer.str());
6114  }
6115 
6116  #endif
6117 
6118  for(size_t i = 0; i < rows_number; i++)
6119  {
6120  for(size_t j = 0; j < columns_number; j++)
6121  {
6122  if(i==j)
6123  {
6124  (*this)(i,j) = value;
6125  }
6126  else
6127  {
6128  (*this)(i,j) = 0;
6129  }
6130  }
6131  }
6132 }
6133 
6134 
6136 
6137 template <class T>
6139 {
6140  T sum = 0;
6141 
6142  for(size_t i = 0; i < this->size(); i++)
6143  {
6144  sum += (*this)[i];
6145  }
6146 
6147  return sum;
6148 }
6149 
6150 
6152 
6153 template <class T>
6155 {
6156  #ifdef __OPENNN_DEBUG__
6157 
6158  if(this->empty())
6159  {
6160  ostringstream buffer;
6161 
6162  cout << "OpenNN Exception: Matrix Template.\n"
6163  << "Vector<T> calculate_rows_sum() const method.\n"
6164  << "Matrix is empty.\n";
6165 
6166  throw logic_error(buffer.str());
6167  }
6168 
6169  #endif
6170 
6171  Vector<T> rows_sum(rows_number, 0);
6172 
6173  for(size_t i = 0; i < rows_number; i++)
6174  {
6175  for(size_t j = 0; j < columns_number; j++)
6176  {
6177  rows_sum[i] += (*this)(i,j);
6178  }
6179  }
6180 
6181  return(rows_sum);
6182 }
6183 
6184 
6186 
6187 template <class T>
6189 {
6190 
6191 
6192  #ifdef __OPENNN_DEBUG__
6193 
6194  if(this->empty())
6195  {
6196  ostringstream buffer;
6197 
6198  cout << "OpenNN Exception: Matrix Template.\n"
6199  << "Vector<T> calculate_columns_sum() const method.\n"
6200  << "Matrix is empty.\n";
6201 
6202  throw logic_error(buffer.str());
6203  }
6204 
6205  #endif
6206 
6207  Vector<T> columns_sum(columns_number, 0);
6208 
6209  for(size_t i = 0; i < rows_number; i++)
6210  {
6211  for(size_t j = 0; j < columns_number; j++)
6212  {
6213  columns_sum[j] += (*this)(i,j);
6214  }
6215  }
6216 
6217  return(columns_sum);
6218 }
6219 
6220 
6223 
6224 template <class T>
6225 T Matrix<T>::calculate_column_sum(const size_t& column_index) const
6226 {
6227  T column_sum = 0;
6228 
6229  for(size_t i = 0; i < rows_number; i++)
6230  {
6231  column_sum += (*this)(i,column_index);
6232  }
6233 
6234  return(column_sum);
6235 }
6236 
6237 
6240 
6241 template <class T>
6242 T Matrix<T>::calculate_row_sum(const size_t& row_index) const
6243 {
6244  T row_sum = 0;
6245 
6246  for(size_t i = 0; i < columns_number; i++)
6247  {
6248  row_sum += (*this)(row_index,i);
6249  }
6250 
6251  return(row_sum);
6252 }
6253 
6254 
6257 
6258 template <class T>
6259 void Matrix<T>::sum_row(const size_t& row_index, const Vector<T>& vector)
6260 {
6261 
6262 
6263  #ifdef __OPENNN_DEBUG__
6264 
6265  if(vector.size() != columns_number)
6266  {
6267  ostringstream buffer;
6268 
6269  cout << "OpenNN Exception: Matrix Template.\n"
6270  << "void sum_row(const size_t&, const Vector<T>&) method.\n"
6271  << "Size of vector must be equal to number of columns.\n";
6272 
6273  throw logic_error(buffer.str());
6274  }
6275 
6276  #endif
6277 
6278  for(size_t j = 0; j < columns_number; j++)
6279  {
6280  (*this)(row_index,j) += vector[j];
6281  }
6282 }
6283 
6284 
6287 
6288 template <class T>
6289 void Matrix<T>::sum_column(const size_t& column_index, const Vector<T>& vector)
6290 {
6291 
6292 
6293  #ifdef __OPENNN_DEBUG__
6294 
6295  if(vector.size() != rows_number)
6296  {
6297  ostringstream buffer;
6298 
6299  cout << "OpenNN Exception: Matrix Template.\n"
6300  << "void sum_column(const size_t&, const Vector<T>&) method.\n"
6301  << "Size of vector must be equal to number of rows.\n";
6302 
6303  throw logic_error(buffer.str());
6304  }
6305 
6306  #endif
6307 
6308  for(size_t i = 0; i < rows_number; i++)
6309  {
6310  (*this)(i,column_index) += vector[i];
6311  }
6312 }
6313 
6314 
6317 
6318 template <class T>
6320 {
6321 
6322 
6323  #ifdef __OPENNN_DEBUG__
6324 
6325  if(vector.size() != columns_number)
6326  {
6327  ostringstream buffer;
6328 
6329  cout << "OpenNN Exception: Matrix Template.\n"
6330  << "void sum_rows(const Vector<T>&) method.\n"
6331  << "Size of vector must be equal to number of columns.\n";
6332 
6333  throw logic_error(buffer.str());
6334  }
6335 
6336  #endif
6337 
6338  Matrix<T> new_matrix(rows_number, columns_number);
6339 
6340  for(size_t i = 0; i < rows_number; i++)
6341  {
6342  for(size_t j = 0; j < columns_number; j++)
6343  {
6344  new_matrix(i,j) = (*this)(i,j) + vector[j];
6345  }
6346  }
6347 
6348  return new_matrix;
6349 }
6350 
6351 
6354 
6355 template <class T>
6357 {
6358 
6359 
6360  #ifdef __OPENNN_DEBUG__
6361 
6362  if(vector.size() != columns_number)
6363  {
6364  ostringstream buffer;
6365 
6366  cout << "OpenNN Exception: Matrix Template.\n"
6367  << "void subtract_rows(const Vector<T>&) method.\n"
6368  << "Size of vector must be equal to number of columns.\n";
6369 
6370  throw logic_error(buffer.str());
6371  }
6372 
6373  #endif
6374 
6375  Matrix<T> new_matrix(rows_number, columns_number);
6376 
6377  for(size_t i = 0; i < rows_number; i++)
6378  {
6379  for(size_t j = 0; j < columns_number; j++)
6380  {
6381  new_matrix(i,j) = (*this)(i,j) - vector[j];
6382  }
6383  }
6384 
6385  return new_matrix;
6386 }
6387 
6388 
6392 
6393 template <class T>
6395 {
6396 
6397 
6398  #ifdef __OPENNN_DEBUG__
6399 
6400  if(vector.size() != columns_number)
6401  {
6402  ostringstream buffer;
6403 
6404  cout << "OpenNN Exception: Matrix Template.\n"
6405  << "void multiply_rows(const Vector<T>&) method.\n"
6406  << "Size of vector must be equal to number of columns.\n";
6407 
6408  throw logic_error(buffer.str());
6409  }
6410 
6411  #endif
6412 
6413  Matrix<T> new_matrix(rows_number, columns_number);
6414 
6415  for(size_t i = 0; i < rows_number; i++)
6416  {
6417  for(size_t j = 0; j < columns_number; j++)
6418  {
6419  new_matrix(i,j) = (*this)(i,j) * vector[j];
6420  }
6421  }
6422 
6423  return new_matrix;
6424 }
6425 
6426 
6429 
6430 template <class T>
6432 {
6433  const size_t points_number = matrix.get_rows_number();
6434 
6435  Vector<Matrix<T>> new_vector_matrix(points_number);
6436 
6437  for(size_t point_number = 0; point_number < points_number; point_number++)
6438  {
6439  new_vector_matrix[point_number].set(rows_number, columns_number, 0.0);
6440 
6441  for(size_t i = 0; i < rows_number; i++)
6442  {
6443  for(size_t j = 0; j < columns_number; j++)
6444  {
6445  new_vector_matrix[point_number](i,j) = (*this)(i,j)*matrix(point_number,j);
6446  }
6447  }
6448  }
6449 
6450  return new_vector_matrix;
6451 }
6452 
6453 
6456 
6457 template <class T>
6459 {
6460 
6461 
6462  #ifdef __OPENNN_DEBUG__
6463 
6464  if(!is_square())
6465  {
6466  ostringstream buffer;
6467 
6468  buffer << "OpenNN Exception: Matrix template.\n"
6469  << "double calculate_trace() const method.\n"
6470  << "Matrix is not square.\n";
6471 
6472  throw logic_error(buffer.str());
6473  }
6474 
6475  #endif
6476 
6477  double trace = 0.0;
6478 
6479  for(size_t i = 0; i < rows_number; i++)
6480  {
6481  trace += (*this)(i,i);
6482  }
6483 
6484  return(trace);
6485 }
6486 
6487 
6489 
6490 template <class T>
6492 {
6493  Vector<double> missing_values(columns_number);
6494 
6495  Vector<T> column(rows_number);
6496 
6497  for(size_t i = 0; i < columns_number; i++)
6498  {
6499  column = get_column(i);
6500 
6501  missing_values[i] = column.count_NAN()*100.0/static_cast<double>(rows_number-1.0);
6502  }
6503 
6504  return missing_values;
6505 }
6506 
6507 
6510 
6511 template <class T>
6513 {
6514  Matrix<size_t> indices;
6515 
6516  Vector<size_t> row(2);
6517 
6518  for(size_t i = 0; i < rows_number; i++)
6519  {
6520  for(size_t j = 0; j < columns_number; j++)
6521  {
6522  if((*this)(i,j) < value && indices.empty())
6523  {
6524  indices.set(1, 2);
6525 
6526  row[0] = i;
6527  row[1] = j;
6528 
6529  indices.set_row(0, row);
6530  }
6531  else if((*this)(i,j) < value)
6532  {
6533  row[0] = i;
6534  row[1] = j;
6535 
6536  indices.append_row(row);
6537  }
6538  }
6539  }
6540 
6541  return indices;
6542 }
6543 
6544 
6547 
6548 template <class T>
6550 {
6551  Matrix<size_t> indices;
6552 
6553  Vector<size_t> row(2);
6554 
6555  for(size_t i = 0; i < rows_number; i++)
6556  {
6557  for(size_t j = 0; j < columns_number; j++)
6558  {
6559  if((*this)(i,j) > value && indices.empty())
6560  {
6561  indices.set(1, 2);
6562 
6563  row[0] = i;
6564  row[1] = j;
6565 
6566  indices.set_row(0, row);
6567  }
6568  else if((*this)(i,j) > value)
6569  {
6570  row[0] = i;
6571  row[1] = j;
6572 
6573  indices.append_row(row);
6574  }
6575  }
6576  }
6577 
6578  return indices;
6579 }
6580 
6581 
6583 
6584 template <class T>
6586 {
6587  Matrix<T> reverse(rows_number,columns_number);
6588 
6589  for(size_t i = 0; i < rows_number; i++)
6590  {
6591  for(size_t j = 0; j < columns_number; j++)
6592  {
6593  reverse(i,j) = (*this)(i, columns_number-j-1);
6594  }
6595  }
6596 
6597  Vector<string> reverse_header(columns_number);
6598 
6599  for(size_t i = 0; i < columns_number; i++)
6600  {
6601  reverse_header[i] = header[columns_number-i-1];
6602  }
6603 
6604  reverse.set_header(reverse_header);
6605 
6606  return reverse;
6607 }
6608 
6609 
6611 
6612 template <class T>
6614 {
6615  Matrix<T> transpose(columns_number, rows_number);
6616 
6617  for(size_t i = 0; i < columns_number; i++)
6618  {
6619  for(size_t j = 0; j < rows_number; j++)
6620  {
6621  transpose(i,j) = (*this)(j,i);
6622  }
6623  }
6624 
6625  return(transpose);
6626 }
6627 
6628 
6631 
6632 template <class T>
6634 {
6635  #ifdef __OPENNN_DEBUG__
6636 
6637  if(rows_number != vector.size())
6638  {
6639  ostringstream buffer;
6640 
6641  buffer << "OpenNN Exception: Matrix Template.\n"
6642  << "divide_rows(const Vector<T>&) method.\n"
6643  << "Size of vector (" << vector.size() << ") must be equal to number of rows (" << rows_number <<").\n";
6644 
6645  throw logic_error(buffer.str());
6646  }
6647 
6648  #endif
6649 
6650  for(size_t i = 0; i < rows_number; i++)
6651  {
6652  for(size_t j = 0; j < columns_number; j++)
6653  {
6654  (*this)(i,j) /= vector[i];
6655  }
6656  }
6657 }
6658 
6659 
6663 
6664 template <class T>
6665 void Matrix<T>::filter(const T& minimum, const T& maximum)
6666 {
6667  for(size_t i = 0; i < this->size(); i++)
6668  {
6669  if((*this)[i] < minimum)(*this)[i] = minimum;
6670 
6671  else if((*this)[i] > maximum)(*this)[i] = maximum;
6672  }
6673 }
6674 
6675 
6678 
6679 template <class T>
6680 Matrix<T> Matrix<T>::operator + (const T& scalar) const
6681 {
6682  Matrix<T> sum(rows_number, columns_number);
6683 
6684  transform(this->begin(), this->end(), sum.begin(), bind2nd(plus<T>(), scalar));
6685 
6686  return sum;
6687 }
6688 
6689 
6692 
6693 template <class T>
6694 Matrix<T> Matrix<T>::operator + (const Matrix<T>& other_matrix) const
6695 {
6696 
6697 
6698  #ifdef __OPENNN_DEBUG__
6699 
6700  const size_t other_rows_number = other_matrix.get_rows_number();
6701  const size_t other_columns_number = other_matrix.get_columns_number();
6702 
6703  if(other_rows_number != rows_number || other_columns_number != columns_number)
6704  {
6705  ostringstream buffer;
6706 
6707  buffer << "OpenNN Exception: Matrix Template.\n"
6708  << "Matrix<T> operator + (const Matrix<T>&) const.\n"
6709  << "Sizes of other matrix (" << other_rows_number << "," << other_columns_number << ") must be the same than sizes of this matrix (" << rows_number << "," << columns_number << ").\n";
6710 
6711  throw logic_error(buffer.str());
6712  }
6713 
6714  #endif
6715 
6716  Matrix<T> sum(rows_number, columns_number);
6717 
6718  transform(this->begin(), this->end(), other_matrix.begin(), sum.begin(), plus<T>());
6719 
6720  return sum;
6721 }
6722 
6723 
6726 
6727 template <class T>
6728 Matrix<T> Matrix<T>::operator -(const T& scalar) const
6729 {
6730  Matrix<T> difference(rows_number, columns_number);
6731 
6732  transform(this->begin(), this->end(), difference.begin(), bind2nd(minus<T>(), scalar));
6733 
6734  return(difference);
6735 }
6736 
6737 
6740 
6741 template <class T>
6742 Matrix<T> Matrix<T>::operator -(const Matrix<T>& other_matrix) const
6743 {
6744  #ifdef __OPENNN_DEBUG__
6745 
6746  const size_t other_rows_number = other_matrix.get_rows_number();
6747  const size_t other_columns_number = other_matrix.get_columns_number();
6748 
6749  if(other_rows_number != rows_number || other_columns_number != columns_number)
6750  {
6751  ostringstream buffer;
6752 
6753  buffer << "OpenNN Exception: Matrix Template.\n"
6754  << "Matrix<T> operator -(const Matrix<T>&) const method.\n"
6755  << "Sizes of other matrix (" << other_rows_number << "," << other_columns_number << ") must be equal to sizes of this matrix ("<< rows_number << "," << columns_number <<").\n";
6756 
6757  throw logic_error(buffer.str());
6758  }
6759 
6760  #endif
6761 
6762  Matrix<T> difference(rows_number, columns_number);
6763 
6764  transform(this->begin(), this->end(), other_matrix.begin(), difference.begin(), minus<T>());
6765 
6766  return(difference);
6767 }
6768 
6769 
6772 
6773 template <class T>
6774 Matrix<T> Matrix<T>::operator *(const T& scalar) const
6775 {
6776  Matrix<T> product(rows_number, columns_number);
6777 
6778  for(size_t i = 0; i < this->size(); i++)
6779  {
6780  product[i] = (*this)[i]*scalar;
6781  }
6782 
6783  return product;
6784 }
6785 
6786 
6789 
6790 template <class T>
6791 Matrix<T> Matrix<T>::operator *(const Matrix<T>& other_matrix) const
6792 {
6793  #ifdef __OPENNN_DEBUG__
6794 
6795  const size_t other_rows_number = other_matrix.get_rows_number();
6796  const size_t other_columns_number = other_matrix.get_columns_number();
6797 
6798  if(other_rows_number != rows_number || other_columns_number != columns_number)
6799  {
6800  ostringstream buffer;
6801 
6802  buffer << "OpenNN Exception: Matrix Template.\n"
6803  << "Matrix<T> operator *(const Matrix<T>&) const method.\n"
6804  << "Sizes of other matrix (" << other_rows_number << "," << other_columns_number << ") must be equal to sizes of this matrix (" << rows_number << "," << columns_number << ").\n";
6805 
6806  throw logic_error(buffer.str());
6807  }
6808 
6809  #endif
6810 
6811  Matrix<T> product(rows_number, columns_number);
6812 
6813  for(size_t i = 0; i < this->size(); i++)
6814  {
6815  product[i] = (*this)[i]*other_matrix[i];
6816  }
6817 
6818  return product;
6819 }
6820 
6821 
6822 template <class T>
6823 Matrix<T> Matrix<T>::operator * (const Tensor<T>& tensor) const
6824 {
6825  #ifdef __OPENNN_DEBUG__
6826 
6827  const size_t other_rows_number = tensor.get_dimension(0);
6828  const size_t other_columns_number = tensor.get_dimension(1);
6829 
6830  if(other_rows_number != rows_number || other_columns_number != columns_number)
6831  {
6832  ostringstream buffer;
6833 
6834  buffer << "OpenNN Exception: Matrix Template.\n"
6835  << "Matrix<T> operator *(const Tensor<T>&) const method.\n"
6836  << "Sizes of tensor (" << other_rows_number << "," << other_columns_number << ") must be equal to sizes of this matrix (" << rows_number << "," << columns_number << ").\n";
6837 
6838  throw logic_error(buffer.str());
6839  }
6840 
6841  #endif
6842 
6843  Matrix<T> product(rows_number, columns_number);
6844 
6845  for(size_t i = 0; i < this->size(); i++)
6846  {
6847  product[i] = (*this)[i]*tensor[i];
6848  }
6849 
6850  return product;
6851 }
6852 
6853 
6856 
6857 template <class T>
6858 Matrix<T> Matrix<T>::operator /(const T& scalar) const
6859 {
6860  Matrix<T> results(rows_number, columns_number);
6861 
6862  for(size_t i = 0; i < results.size(); i++)
6863  {
6864  results[i] = (*this)[i]/scalar;
6865  }
6866 
6867  return results;
6868 }
6869 
6870 
6873 
6874 template <class T>
6876 {
6877  #ifdef __OPENNN_DEBUG__
6878 
6879  const size_t size = vector.size();
6880 
6881  if(size != rows_number)
6882  {
6883  ostringstream buffer;
6884 
6885  buffer << "OpenNN Exception: Matrix Template.\n"
6886  << "Matrix<T> operator /(const Vector<T>&) const.\n"
6887  << "Size of vector must be equal to number of rows.\n";
6888 
6889  throw logic_error(buffer.str());
6890  }
6891 
6892  #endif
6893 
6894  Matrix<T> cocient(rows_number, columns_number);
6895 
6896  for(size_t i = 0; i < rows_number; i++)
6897  {
6898  for(size_t j = 0; j < columns_number; j++)
6899  {
6900  cocient(i,j) = (*this)(i,j)/vector[i];
6901  }
6902  }
6903 
6904  return(cocient);
6905 }
6906 
6907 
6910 
6911 template <class T>
6912 Matrix<T> Matrix<T>::operator /(const Matrix<T>& other_matrix) const
6913 {
6914  #ifdef __OPENNN_DEBUG__
6915 
6916  const size_t other_rows_number = other_matrix.get_rows_number();
6917  const size_t other_columns_number = other_matrix.get_columns_number();
6918 
6919  if(other_rows_number != rows_number || other_columns_number != columns_number)
6920  {
6921  ostringstream buffer;
6922 
6923  buffer << "OpenNN Exception: Matrix Template.\n"
6924  << "Matrix<T> operator /(const Matrix<T>&) const method.\n"
6925  << "Both matrix sizes must be the same.\n";
6926 
6927  throw logic_error(buffer.str());
6928  }
6929 
6930  #endif
6931 
6932  Matrix<T> cocient(rows_number, columns_number);
6933 
6934  for(size_t i = 0; i < rows_number; i++)
6935  {
6936  cocient[i] = (*this)[i]/other_matrix[i];
6937  }
6938 
6939  return(cocient);
6940 }
6941 
6942 
6945 
6946 template <class T>
6947 void Matrix<T>::operator += (const T& value)
6948 {
6949  for(size_t i = 0; i < rows_number; i++)
6950  {
6951  for(size_t j = 0; j < columns_number; j++)
6952  {
6953  (*this)(i,j) += value;
6954  }
6955  }
6956 }
6957 
6958 
6961 
6962 template <class T>
6963 void Matrix<T>::operator += (const Matrix<T>& other_matrix)
6964 {
6965  #ifdef __OPENNN_DEBUG__
6966 
6967  const size_t other_rows_number = other_matrix.get_rows_number();
6968 
6969  if(other_rows_number != rows_number)
6970  {
6971  ostringstream buffer;
6972 
6973  buffer << "OpenNN Exception: Matrix Template.\n"
6974  << "void operator += (const Matrix<T>&).\n"
6975  << "Both numbers of rows must be the same.\n";
6976 
6977  throw logic_error(buffer.str());
6978  }
6979 
6980  const size_t other_columns_number = other_matrix.get_columns_number();
6981 
6982  if(other_columns_number != columns_number)
6983  {
6984  ostringstream buffer;
6985 
6986  buffer << "OpenNN Exception: Matrix Template.\n"
6987  << "void operator += (const Matrix<T>&).\n"
6988  << "Both numbers of columns must be the same.\n";
6989 
6990  throw logic_error(buffer.str());
6991  }
6992 
6993  #endif
6994 
6995  for(size_t i = 0; i < this->size(); i++)
6996  {
6997  (*this)[i] += other_matrix[i];
6998  }
6999 }
7000 
7001 
7004 
7005 template <class T>
7006 void Matrix<T>::operator -= (const T& value)
7007 {
7008  for(size_t i = 0; i < rows_number; i++)
7009  {
7010  for(size_t j = 0; j < columns_number; j++)
7011  {
7012  (*this)(i,j) -= value;
7013  }
7014  }
7015 }
7016 
7017 
7020 
7021 template <class T>
7022 void Matrix<T>::operator -= (const Matrix<T>& other_matrix)
7023 {
7024  #ifdef __OPENNN_DEBUG__
7025 
7026  const size_t other_rows_number = other_matrix.get_rows_number();
7027 
7028  if(other_rows_number != rows_number)
7029  {
7030  ostringstream buffer;
7031 
7032  buffer << "OpenNN Exception: Matrix Template.\n"
7033  << "void operator -= (const Matrix<T>&).\n"
7034  << "Both numbers of rows must be the same.\n";
7035 
7036  throw logic_error(buffer.str());
7037  }
7038 
7039  const size_t other_columns_number = other_matrix.get_columns_number();
7040 
7041  if(other_columns_number != columns_number)
7042  {
7043  ostringstream buffer;
7044 
7045  buffer << "OpenNN Exception: Matrix Template.\n"
7046  << "void operator -= (const Matrix<T>&).\n"
7047  << "Both numbers of columns must be the same.\n";
7048 
7049  throw logic_error(buffer.str());
7050  }
7051 
7052  #endif
7053 
7054  for(size_t i = 0; i < this->size(); i++)
7055  {
7056  (*this)[i] -= other_matrix[i];
7057  }
7058 }
7059 
7060 
7063 
7064 template <class T>
7065 void Matrix<T>::operator *= (const T& value)
7066 {
7067  for(size_t i = 0; i < this->size(); i++)
7068  {
7069  (*this)[i] *= value;
7070  }
7071 }
7072 
7073 
7076 
7077 template <class T>
7078 void Matrix<T>::operator *= (const Matrix<T>& other_matrix)
7079 {
7080  #ifdef __OPENNN_DEBUG__
7081 
7082  const size_t other_rows_number = other_matrix.get_rows_number();
7083 
7084  if(other_rows_number != rows_number)
7085  {
7086  ostringstream buffer;
7087 
7088  buffer << "OpenNN Exception: Matrix Template.\n"
7089  << "void operator *= (const Matrix<T>&).\n"
7090  << "The number of rows in the other matrix (" << other_rows_number << ")"
7091  << " is not equal to the number of rows in this matrix (" << rows_number << ").\n";
7092 
7093  throw logic_error(buffer.str());
7094  }
7095 
7096  #endif
7097 
7098  for(size_t i = 0; i < this->size(); i++)
7099  {
7100  (*this)[i] *= other_matrix[i];
7101  }
7102 }
7103 
7104 
7107 
7108 template <class T>
7109 void Matrix<T>::operator /= (const T& value)
7110 {
7111  for(size_t i = 0; i < this->size(); i++)
7112  {
7113  (*this)[i] /= value;
7114  }
7115 }
7116 
7117 
7120 
7121 template <class T>
7122 void Matrix<T>::operator /= (const Matrix<T>& other_matrix)
7123 {
7124 
7125 
7126  #ifdef __OPENNN_DEBUG__
7127 
7128  const size_t other_rows_number = other_matrix.get_rows_number();
7129 
7130  if(other_rows_number != rows_number)
7131  {
7132  ostringstream buffer;
7133 
7134  buffer << "OpenNN Exception: Matrix Template.\n"
7135  << "void operator /= (const Matrix<T>&).\n"
7136  << "Both numbers of rows must be the same.\n";
7137 
7138  throw logic_error(buffer.str());
7139  }
7140 
7141  const size_t other_columns_number = other_matrix.get_columns_number();
7142 
7143  if(other_columns_number != columns_number)
7144  {
7145  ostringstream buffer;
7146 
7147  buffer << "OpenNN Exception: Matrix Template.\n"
7148  << "void operator /= (const Matrix<T>&).\n"
7149  << "Both numbers of columns must be the same.\n";
7150 
7151  throw logic_error(buffer.str());
7152  }
7153 
7154  #endif
7155 
7156  for(size_t i = 0; i < this->size(); i++)
7157  {
7158  (*this)[i] /= other_matrix[i];
7159  }
7160 }
7161 
7162 
7164 
7165 template <class T>
7166 bool Matrix<T>::empty() const
7167 {
7168  if(rows_number == 0 && columns_number == 0)
7169  {
7170  return true;
7171  }
7172  else
7173  {
7174  return false;
7175  }
7176 }
7177 
7178 
7181 
7182 template <class T>
7184 {
7185  if(rows_number == columns_number)
7186  {
7187  return true;
7188  }
7189  else
7190  {
7191  return false;
7192  }
7193 }
7194 
7195 
7198 
7199 template <class T>
7201 {
7202  #ifdef __OPENNN_DEBUG__
7203 
7204  if(rows_number != columns_number)
7205  {
7206  ostringstream buffer;
7207 
7208  buffer << "OpenNN Exception: Matrix Template.\n"
7209  << "bool is_symmetric() const method.\n"
7210  << "Matrix must be squared.\n";
7211 
7212  throw logic_error(buffer.str());
7213  }
7214 
7215  #endif
7216 
7217  const Matrix<T> transpose = calculate_transpose();
7218 
7219  if((*this) == transpose)
7220  {
7221  return true;
7222  }
7223  else
7224  {
7225  return false;
7226  }
7227 }
7228 
7229 
7232 
7233 template <class T>
7235 {
7236  #ifdef __OPENNN_DEBUG__
7237 
7238  if(rows_number != columns_number)
7239  {
7240  ostringstream buffer;
7241 
7242  buffer << "OpenNN Exception: Matrix Template.\n"
7243  << "bool is_antisymmetric() const method.\n"
7244  << "Matrix must be squared.\n";
7245 
7246  throw logic_error(buffer.str());
7247  }
7248 
7249  #endif
7250 
7251  const Matrix<T> transpose = calculate_transpose();
7252 
7253  if((*this) == transpose*(-1))
7254  {
7255  return true;
7256  }
7257  else
7258  {
7259  return false;
7260  }
7261 }
7262 
7263 
7266 
7267 template <class T>
7269 {
7270  #ifdef __OPENNN_DEBUG__
7271 
7272  if(rows_number != columns_number)
7273  {
7274  ostringstream buffer;
7275 
7276  buffer << "OpenNN Exception: Matrix Template.\n"
7277  << "bool is_diagonal() const method.\n"
7278  << "Matrix must be squared.\n";
7279 
7280  throw logic_error(buffer.str());
7281  }
7282 
7283  #endif
7284 
7285  for(size_t i = 0; i < rows_number; i++)
7286  {
7287  for(size_t j = 0; j < columns_number; j++)
7288  {
7289  if(i != j &&(*this)(i,j) != 0)
7290  {
7291  return false;
7292  }
7293  }
7294  }
7295 
7296  return true;
7297 }
7298 
7299 
7302 
7303 template <class T>
7305 {
7306  #ifdef __OPENNN_DEBUG__
7307 
7308  if(rows_number != columns_number)
7309  {
7310  ostringstream buffer;
7311 
7312  buffer << "OpenNN Exception: Matrix Template.\n"
7313  << "bool is_scalar() const method.\n"
7314  << "Matrix must be squared.\n";
7315 
7316  throw logic_error(buffer.str());
7317  }
7318 
7319  #endif
7320 
7321  return get_diagonal().is_constant();
7322 }
7323 
7324 
7327 
7328 template <class T>
7330 {
7331  #ifdef __OPENNN_DEBUG__
7332 
7333  if(rows_number != columns_number)
7334  {
7335  ostringstream buffer;
7336 
7337  buffer << "OpenNN Exception: Matrix Template.\n"
7338  << "bool is_unity() const method.\n"
7339  << "Matrix must be squared.\n";
7340 
7341  throw logic_error(buffer.str());
7342  }
7343 
7344  #endif
7345 
7346  for(size_t i = 0; i < rows_number; i++)
7347  {
7348  for(size_t j = 0; j < columns_number; j++)
7349  {
7350  if(i != j &&(*this)(i,j) != 0)
7351  {
7352  return false;
7353  }
7354  else if(i == j &&(*this)(i,j) != 1)
7355  {
7356  return false;
7357  }
7358  }
7359  }
7360 
7361  return true;
7362 }
7363 
7364 
7366 
7367 template <class T>
7369 {
7370  for(size_t i = 0; i < this->size(); i++)
7371  {
7372  if((*this)[i] != 0 && (*this)[i] != 1)
7373  {
7374  return false;
7375  }
7376  }
7377 
7378  return true;
7379 }
7380 
7381 
7383 
7384 template <class T>
7385 bool Matrix<T>::is_column_binary(const size_t& j) const
7386 {
7387  #ifdef __OPENNN_DEBUG__
7388 
7389  if(j >= columns_number)
7390  {
7391  ostringstream buffer;
7392 
7393  buffer << "OpenNN Exception: Matrix Template.\n"
7394  << "bool is_column_binary(const size_t) const method method.\n"
7395  << "Index of column(" << j << ") must be less than number of columns("<<columns_number<<").\n";
7396 
7397  throw logic_error(buffer.str());
7398  }
7399 
7400  #endif
7401 
7402  for(size_t i = 0; i < rows_number; i++)
7403  {
7404  if((*this)(i,j) != 0 &&(*this)(i,j) != 1 &&(*this)(i,j) != static_cast<double>(NAN))
7405  {
7406  return false;
7407  }
7408  }
7409 
7410  return true;
7411 }
7412 
7413 
7418 
7419 template <class T>
7420 bool Matrix<T>::compare_rows(const size_t& row_index, const Matrix<T>& other_matrix, const size_t& other_row_index) const
7421 {
7422  for(size_t j = 0; j < columns_number; j++)
7423  {
7424  if((*this)(row_index, j) != other_matrix(other_row_index, j))
7425  {
7426  return false;
7427  }
7428  }
7429 
7430  return true;
7431 }
7432 
7433 
7439 
7440 template <class T> bool Matrix<T>::is_column_constant(const size_t& column_index) const
7441 {
7442  if(columns_number == 0)
7443  {
7444  return false;
7445  }
7446 
7447  const T initial_value = (*this)(0, column_index);
7448 
7449  for(size_t i = 1; i < rows_number; i++)
7450  {
7451  if((*this)(i,column_index) != initial_value)
7452  {
7453  return false;
7454  }
7455  }
7456 
7457  return true;
7458 }
7459 
7460 
7462 
7463 template <class T>
7465 {
7466 
7467  for(size_t i = 0; i < this->size(); i++)
7468  {
7469  if((*this)[i] < 0)
7470  {
7471  return false;
7472  }
7473  }
7474 
7475  return true;
7476 }
7477 
7478 
7483 
7484 template <class T>
7485 Matrix<T> Matrix<T>::filter_column_minimum_maximum(const size_t& column_index, const T& minimum, const T& maximum) const
7486 {
7487  const Vector<T> column = get_column(column_index);
7488 
7489  const size_t new_rows_number = column.count_between(minimum, maximum);
7490 
7491  Matrix<T> new_matrix(new_rows_number, columns_number);
7492 
7493  size_t row_index = 0;
7494 
7495  Vector<T> row(columns_number);
7496 
7497  for(size_t i = 0; i < rows_number; i++)
7498  {
7499  if((*this)(i,column_index) >= minimum && (*this)(i,column_index) <= maximum)
7500  {
7501  row = get_row(i);
7502 
7503  new_matrix.set_row(row_index, row);
7504 
7505  row_index++;
7506  }
7507  }
7508 
7509  return new_matrix;
7510 }
7511 
7512 
7513 template <class T>
7514 Matrix<T> Matrix<T>::filter_column_minimum_maximum(const string& column_name, const T& minimum, const T& maximum) const
7515 {
7516  const size_t column_index = get_column_index(column_name);
7517 
7518  return filter_column_minimum_maximum(column_index, minimum, maximum);
7519 }
7520 
7521 
7522 template <class T>
7523 Matrix<T> Matrix<T>::filter_extreme_values(const size_t& column_index, const double& lower_ratio, const double& upper_ratio) const
7524 {
7525  const size_t lower_index = rows_number*lower_ratio;
7526  const size_t upper_index = rows_number*upper_ratio;
7527 
7528  const Vector<T> column = get_column(column_index).sort_ascending_values();
7529 
7530  const T lower_value = column[lower_index];
7531  const T upper_value = column[upper_index];
7532 
7533 // return filter_minimum_maximum(column_index, lower_value, upper_value);
7534  return Matrix<double>();
7535 }
7536 
7537 
7538 template <class T>
7539 Matrix<T> Matrix<T>::filter_extreme_values(const string& column_name, const double& lower_ratio, const double& upper_ratio) const
7540 {
7541  const size_t column_index = get_column_index(column_name);
7542 
7543  return filter_extreme_values(column_index, lower_ratio, upper_ratio);
7544 }
7545 
7546 
7550 
7551 template <class T>
7552 Matrix<T> Matrix<T>::filter_column_equal_to(const size_t& column_index, const T& value) const
7553 {
7554  const size_t count = count_equal_to(column_index, value);
7555 
7556  if(count == 0) return Matrix<T>();
7557 
7558  const size_t new_rows_number = count;
7559 
7560  Matrix<T> new_matrix(new_rows_number, columns_number);
7561 
7562  size_t row_index = 0;
7563 
7564  Vector<T> row(columns_number);
7565 
7566  for(size_t i = 0; i < rows_number; i++)
7567  {
7568  if((*this)(i,column_index) == value)
7569  {
7570  row = get_row(i);
7571 
7572  new_matrix.set_row(row_index, row);
7573 
7574  row_index++;
7575  }
7576  }
7577 
7578  new_matrix.set_header(header);
7579 
7580  return new_matrix;
7581 }
7582 
7583 
7585 
7586 template <class T>
7587 Matrix<T> Matrix<T>::filter_column_equal_to(const size_t& column_1, const T& value_1,
7588  const size_t& column_2, const T& value_2,
7589  const size_t& column_3, const T& value_3,
7590  const size_t& column_4, const T& value_4) const
7591 {
7592  const size_t count = count_equal_to(column_1, value_1, column_2, value_2, column_3, value_3, column_4, value_4);
7593 
7594  const size_t new_rows_number = count;
7595 
7596  Matrix<T> new_matrix(new_rows_number, columns_number);
7597 
7598  Vector<T> row(columns_number);
7599  size_t row_index = 0;
7600 
7601  for(size_t i = 0; i < rows_number; i++)
7602  {
7603  if((*this)(i,column_1) == value_1
7604  &&(*this)(i,column_2) == value_2
7605  &&(*this)(i,column_3) == value_3
7606  &&(*this)(i,column_4) == value_4)
7607  {
7608  row = get_row(i);
7609 
7610  new_matrix.set_row(row_index, row);
7611 
7612  row_index++;
7613  }
7614  }
7615 
7616  return new_matrix;
7617 }
7618 
7619 
7621 
7622 template <class T>
7623 Matrix<T> Matrix<T>::filter_column_equal_to(const string& column_1_name, const T& value_1,
7624  const string& column_2_name, const T& value_2,
7625  const string& column_3_name, const T& value_3,
7626  const string& column_4_name, const T& value_4) const
7627 {
7628  const size_t column_1_index = get_column_index(column_1_name);
7629  const size_t column_2_index = get_column_index(column_2_name);
7630  const size_t column_3_index = get_column_index(column_3_name);
7631  const size_t column_4_index = get_column_index(column_4_name);
7632 
7633  return(filter_column_equal_to(column_1_index, value_1, column_2_index, value_2, column_3_index, value_3, column_4_index, value_4));
7634 }
7635 
7636 
7640 
7641 template <class T>
7642 Matrix<T> Matrix<T>::filter_column_equal_to(const size_t& column_index, const Vector<T>& values) const
7643 {
7644  const size_t values_size = values.size();
7645 
7646  const size_t count = count_equal_to(column_index, values);
7647 
7648  const size_t new_rows_number = count;
7649 
7650  Matrix<T> new_matrix(new_rows_number, columns_number);
7651 
7652  Vector<T> row(columns_number);
7653 
7654  size_t row_index = 0;
7655 
7656  for(size_t i = 0; i < rows_number; i++)
7657  {
7658  for(size_t j = 0; j < values_size; j++)
7659  {
7660  if((*this)(i,column_index) == values[j])
7661  {
7662  row = get_row(i);
7663 
7664  new_matrix.set_row(row_index, row);
7665 
7666  row_index++;
7667 
7668  break;
7669  }
7670  }
7671  }
7672 
7673  new_matrix.set_header(header);
7674 
7675  return new_matrix;
7676 }
7677 
7678 
7682 
7683 template <class T>
7684 Matrix<T> Matrix<T>::filter_column_not_equal_to(const size_t& column_index, const Vector<T>& values) const
7685 {
7686  const size_t values_size = values.size();
7687 
7688  const size_t new_rows_number = count_not_equal_to(column_index, values);
7689 
7690  Matrix<T> new_matrix(new_rows_number, columns_number);
7691 
7692  size_t row_index = 0;
7693 
7694  Vector<T> row(columns_number);
7695 
7696  for(size_t i = 0; i < rows_number; i++)
7697  {
7698  size_t count = 0;
7699 
7700  for(size_t j = 0; j < values_size; j++)
7701  {
7702  if((*this)(i,column_index) != values[j])
7703  {
7704  count++;
7705  }
7706  }
7707 
7708  if(count == values.size())
7709  {
7710  row = get_row(i);
7711 
7712  new_matrix.set_row(row_index, row);
7713 
7714  row_index++;
7715  }
7716  }
7717 
7718  new_matrix.set_header(header);
7719 
7720  return new_matrix;
7721 }
7722 
7723 
7725 
7726 template <class T>
7727 Matrix<T> Matrix<T>::filter_column_equal_to(const size_t& index_1, const Vector<T>& values_1,
7728  const size_t& index_2, const T& value_2) const
7729 {
7730  const size_t count = count_equal_to(index_1, values_1, index_2, value_2);
7731 
7732  const size_t new_rows_number = count;
7733 
7734  Matrix<T> new_matrix(new_rows_number, columns_number);
7735 
7736  size_t row_index = 0;
7737 
7738  Vector<T> row(columns_number);
7739 
7740  const size_t values_1_size = values_1.size();
7741 
7742  for(size_t i = 0; i < rows_number; i++)
7743  {
7744  if((*this)(i, index_2) == value_2)
7745  {
7746  for(size_t j = 0; j < values_1_size; j++)
7747  {
7748  if((*this)(i, index_1) == values_1[j])
7749  {
7750  row = get_row(i);
7751 
7752  new_matrix.set_row(row_index, row);
7753 
7754  row_index++;
7755 
7756  break;
7757  }
7758  }
7759  }
7760  }
7761 
7762  return new_matrix;
7763 }
7764 
7765 
7767 
7768 template <class T>
7769 Matrix<T> Matrix<T>::filter_column_equal_to(const size_t& column_1_index, const Vector<T>& values_1,
7770  const size_t& column_2_index, const T& value_2,
7771  const size_t& column_3_index, const T& value_3,
7772  const size_t& column_4_index, const T& value_4) const
7773 {
7774  const size_t new_rows_number = count_equal_to(column_1_index, values_1,
7775  column_2_index, value_2,
7776  column_3_index, value_3,
7777  column_4_index, value_4);
7778 
7779  Matrix<T> new_matrix(new_rows_number, columns_number);
7780 
7781  const size_t values_1_size = values_1.size();
7782 
7783  size_t row_index = 0;
7784 
7785  Vector<T> row(columns_number);
7786 
7787  T matrix_element;
7788 
7789  for(size_t i = 0; i < rows_number; i++)
7790  {
7791  if((*this)(i,column_2_index) == value_2
7792  &&(*this)(i,column_3_index) == value_3
7793  &&(*this)(i,column_4_index) == value_4)
7794  {
7795  matrix_element = (*this)(i,column_1_index);
7796 
7797  for(size_t j = 0; j < values_1_size; j++)
7798  {
7799  if(values_1[j] == matrix_element)
7800  {
7801  row = get_row(i);
7802 
7803  new_matrix.set_row(row_index, row);
7804 
7805  row_index++;
7806 
7807  break;
7808  }
7809  }
7810  }
7811  }
7812 
7813  return new_matrix;
7814 }
7815 
7816 
7818 
7819 template <class T>
7820 Matrix<T> Matrix<T>::filter_column_equal_to(const string& column_1, const Vector<T>& values_1,
7821  const string& column_2, const T& value_2,
7822  const string& column_3, const T& value_3,
7823  const string& column_4, const T& value_4) const
7824 {
7825  const size_t column_1_index = get_column_index(column_1);
7826  const size_t column_2_index = get_column_index(column_2);
7827  const size_t column_3_index = get_column_index(column_3);
7828  const size_t column_4_index = get_column_index(column_4);
7829 
7830  return(filter_column_equal_to(column_1_index, values_1, column_2_index, value_2, column_3_index, value_3, column_4_index, value_4));
7831 }
7832 
7833 
7835 
7836 template <class T>
7837 Matrix<T> Matrix<T>::filter_column_equal_to(const string& column_name, const T& value) const
7838 {
7839  const size_t column_index = get_column_index(column_name);
7840 
7841  return(filter_column_equal_to(column_index, value));
7842 }
7843 
7844 
7846 
7847 template <class T>
7848 Matrix<T> Matrix<T>::filter_column_equal_to(const string& column_name, const Vector<T>& values) const
7849 {
7850  const size_t column_index = get_column_index(column_name);
7851 
7852  return(filter_column_equal_to(column_index, values));
7853 }
7854 
7855 
7857 
7858 template <class T>
7859 Matrix<T> Matrix<T>::filter_column_not_equal_to(const string& column_name, const Vector<T>& values) const
7860 {
7861  const size_t column_index = get_column_index(column_name);
7862 
7863  return(filter_column_not_equal_to(column_index, values));
7864 }
7865 
7866 
7868 
7869 template <class T>
7870 Matrix<T> Matrix<T>::filter_column_equal_to(const string& name_1, const Vector<T>& values_1,
7871  const string& name_2, const T& value_2) const
7872 {
7873  const size_t index_1 = get_column_index(name_1);
7874  const size_t index_2 = get_column_index(name_2);
7875 
7876  return(filter_column_equal_to(index_1, values_1, index_2, value_2));
7877 }
7878 
7879 
7881 
7882 template <class T>
7883 Matrix<T> Matrix<T>::filter_column_not_equal_to(const size_t& column_index, const T& value) const
7884 {
7885  const size_t new_rows_number = count_not_equal_to(column_index, value);
7886 
7887  Matrix<T> new_matrix(new_rows_number, columns_number);
7888 
7889  size_t row_index = 0;
7890 
7891  Vector<T> row(columns_number);
7892 
7893  for(size_t i = 0; i < rows_number; i++)
7894  {
7895  if((*this)(i,column_index) != value)
7896  {
7897  row = get_row(i);
7898 
7899  new_matrix.set_row(row_index, row);
7900 
7901  row_index++;
7902  }
7903  }
7904 
7905  new_matrix.set_header(header);
7906 
7907  return new_matrix;
7908 }
7909 
7910 
7912 
7913 template <class T>
7914 Matrix<T> Matrix<T>::filter_column_not_equal_to(const string& column_name, const T& value) const
7915 {
7916  const size_t column_index = get_column_index(column_name);
7917 
7918  return(filter_column_not_equal_to(column_index, value));
7919 }
7920 
7921 
7923 
7924 template <class T>
7925 Matrix<T> Matrix<T>::filter_column_less_than(const size_t& column_index, const T& value) const
7926 {
7927  const Vector<T> column = get_column(column_index);
7928 
7929  size_t new_rows_number = column.count_less_than(value);
7930 
7931  if(new_rows_number == 0)
7932  {
7933  Matrix<T> new_matrix;
7934 
7935  return new_matrix;
7936  }
7937 
7938  Matrix<T> new_matrix(new_rows_number, columns_number);
7939 
7940  size_t row_index = 0;
7941 
7942  Vector<T> row(columns_number);
7943 
7944  for(size_t i = 0; i < rows_number; i++)
7945  {
7946  if((*this)(i,column_index) < value)
7947  {
7948  row = get_row(i);
7949 
7950  new_matrix.set_row(row_index, row);
7951 
7952  row_index++;
7953  }
7954  }
7955 
7956  new_matrix.set_header(header);
7957 
7958  return new_matrix;
7959 }
7960 
7961 
7963 
7964 template <class T>
7965 Matrix<T> Matrix<T>::filter_column_less_than(const string& column_name, const T& value) const
7966 {
7967  const size_t column_index = get_column_index(column_name);
7968 
7969  return(filter_column_less_than(column_index, value));
7970 }
7971 
7972 
7974 
7975 template <class T>
7976 Matrix<T> Matrix<T>::filter_column_greater_than(const size_t& column_index, const T& value) const
7977 {
7978  const Vector<T> column = get_column(column_index);
7979 
7980  const size_t new_rows_number = column.count_greater_than(value);
7981 
7982  if(new_rows_number == 0)
7983  {
7984  Matrix<T> new_matrix;
7985 
7986  return new_matrix;
7987  }
7988 
7989  Matrix<T> new_matrix(new_rows_number, columns_number);
7990 
7991  size_t row_index = 0;
7992 
7993  Vector<T> row(columns_number);
7994 
7995  for(size_t i = 0; i < rows_number; i++)
7996  {
7997  if((*this)(i,column_index) > value)
7998  {
7999  row = get_row(i);
8000 
8001  new_matrix.set_row(row_index, row);
8002 
8003  row_index++;
8004  }
8005  }
8006 
8007  new_matrix.set_header(header);
8008 
8009  return new_matrix;
8010 }
8011 
8012 
8014 
8015 template <class T>
8016 Matrix<T> Matrix<T>::filter_column_greater_than(const string& column_name, const T& value) const
8017 {
8018  const size_t column_index = get_column_index(column_name);
8019 
8020  return(filter_column_greater_than(column_index, value));
8021 }
8022 
8023 
8025 
8026 template <class T>
8027 Matrix<T> Matrix<T>::filter_column_less_than_string(const string& name, const double& value) const
8028 {
8029  const Vector<size_t> indices = get_column(name).string_to_double().get_indices_less_than(value);
8030 
8031  return delete_rows(indices);
8032 }
8033 
8034 
8036 
8037 template <class T>
8038 Matrix<T> Matrix<T>::filter_column_greater_than_string(const string& name, const double& value) const
8039 {
8040  const Vector<size_t> indices = get_column(name).string_to_double().get_indices_greater_than(value);
8041 
8042  return delete_rows(indices);
8043 }
8044 
8045 
8047 
8048 template <class T>
8049 void Matrix<T>::print() const
8050 {
8051  cout << *this << endl;
8052 }
8053 
8054 
8059 
8060 template <class T>
8061 void Matrix<T>::load_csv(const string& file_name, const char& delim, const bool& has_columns_names, const string& missing_label)
8062 {
8063  ifstream file(file_name.c_str());
8064 
8065  if(!file.is_open())
8066  {
8067  ostringstream buffer;
8068 
8069  buffer << "OpenNN Exception: Matrix template.\n"
8070  << "void load_csv(const string&, const char&) method.\n"
8071  << "Cannot open matrix data file: " << file_name << "\n";
8072 
8073  throw logic_error(buffer.str());
8074  }
8075 
8076  if(file.peek() == ifstream::traits_type::eof())
8077  {
8078  set();
8079 
8080  return;
8081  }
8082 
8083  // Set matrix sizes
8084 
8085  string line;
8086 
8087  getline(file, line);
8088 
8089  if(line.empty())
8090  {
8091  set();
8092  }
8093  else
8094  {
8095  istringstream buffer(line);
8096 
8097  string token;
8098 
8099  vector<string> results;
8100 
8101  while(getline(buffer, token, delim))
8102  {
8103  results.push_back(token);
8104  }
8105 
8106  size_t new_columns_number = static_cast<size_t>(results.size());
8107 
8108  size_t new_rows_number = 1;
8109 
8110  while(file.good())
8111  {
8112  getline(file, line);
8113 
8114 // trim(line);
8115 
8116 // OpenNN::erase(line, '"');
8117 
8118  if(!line.empty())
8119  {
8120  new_rows_number++;
8121  }
8122  }
8123 
8124  if(has_columns_names)
8125  {
8126  new_rows_number--;
8127  header.set(results);
8128  }
8129 
8130  set(new_rows_number, new_columns_number);
8131 
8132  if(!has_columns_names)
8133  {
8134  header.set();
8135  }
8136 
8137  // Clear file
8138 
8139  file.clear();
8140  file.seekg(0, ios::beg);
8141 
8142  if(has_columns_names)
8143  {
8144  getline(file, line);
8145 
8146  istringstream header_buffer(line);
8147 
8148  for(size_t j = 0; j < columns_number; j++)
8149  {
8150  string token;
8151 
8152  getline(header_buffer, token, delim);
8153 
8154  header[j] = token;
8155  }
8156  }
8157 
8158  for(size_t i = 0; i < rows_number; i++)
8159  {
8160  getline(file, line);
8161 
8162  istringstream buffer(line);
8163 
8164  for(size_t j = 0; j < columns_number; j++)
8165  {
8166  string token;
8167 
8168  getline(buffer, token, delim);
8169 
8170  if(is_same<T, double>::value)
8171  {
8172  if(token == missing_label) (*this)(i,j) = NAN;
8173  else (*this)(i,j) = stod(token);
8174  }
8175  else if(is_same<T, float>::value)
8176  {
8177  if(token == missing_label) (*this)(i,j) = NAN;
8178  else (*this)(i,j) = stof(token);
8179  }
8180  else if(is_same<T, int>::value)
8181  {
8182  if(token == missing_label) (*this)(i,j) = NAN;
8183  else (*this)(i,j) = stoi(token);
8184  }
8185  else if(is_same<T, long int>::value)
8186  {
8187  if(token == missing_label) (*this)(i,j) = NAN;
8188  else (*this)(i,j) = stol(token);
8189  }
8190  else if(is_same<T, unsigned long>::value)
8191  {
8192  if(token == missing_label) (*this)(i,j) = NAN;
8193  else (*this)(i,j) = stoul(token);
8194  }
8195  else if(is_same<T, size_t>::value)
8196  {
8197  if(token == missing_label) (*this)(i,j) = NAN;
8198  else (*this)(i,j) = stoul(token);
8199  }
8200  else
8201  {
8202  ostringstream buffer;
8203 
8204  buffer << "OpenNN Exception: Matrix template.\n"
8205  << "void load_csv(const string&, const char&) method.\n"
8206  << "Template could not be recognized \n";
8207 
8208  throw logic_error(buffer.str());
8209  }
8210  }
8211  }
8212  }
8213 
8214  file.close();
8215 }
8216 
8217 
8222 
8223 template <class T>
8224 void Matrix<T>::load_csv_string(const string& file_name, const char& delim, const bool& has_columns_names)
8225 {
8226  ifstream file(file_name.c_str());
8227 
8228  if(!file.is_open())
8229  {
8230  ostringstream buffer;
8231 
8232  buffer << "OpenNN Exception: Matrix template.\n"
8233  << "void load_csv(const string&,const char&) method.\n"
8234  << "Cannot open matrix data file: " << file_name << "\n";
8235 
8236  throw logic_error(buffer.str());
8237  }
8238 
8239  if(file.peek() == ifstream::traits_type::eof())
8240  {
8241  set();
8242 
8243  return;
8244  }
8245 
8246  // Set matrix sizes
8247 
8248  string line;
8249 
8250  getline(file, line);
8251 
8252  if(line.empty())
8253  {
8254  set();
8255  }
8256  else
8257  {
8258  istringstream buffer(line);
8259 
8260  string token;
8261 
8262  vector<string> results;
8263 
8264  while(getline(buffer, token, delim))
8265  {
8266  results.push_back(token);
8267  }
8268 
8269  const size_t new_columns_number = static_cast<size_t>(results.size());
8270 
8271  size_t new_rows_number = 1;
8272 
8273  while(file.good())
8274  {
8275  getline(file, line);
8276 
8277  if(!line.empty())
8278  {
8279  new_rows_number++;
8280  }
8281  }
8282 
8283  if(has_columns_names)
8284  {
8285  new_rows_number--;
8286  header.set(results);
8287  }
8288 
8289  set(new_rows_number, new_columns_number);
8290 
8291  if(!has_columns_names)
8292  {
8293  header.set();
8294  }
8295 
8296  // Clear file
8297 
8298  file.clear();
8299  file.seekg(0, ios::beg);
8300 
8301  if(has_columns_names)
8302  {
8303  getline(file, line);
8304 
8305  istringstream header_buffer(line);
8306 
8307  for(size_t j = 0; j < columns_number; j++)
8308  {
8309  string token;
8310 
8311  getline(header_buffer, token, delim);
8312 
8313  header[j] = token;
8314  }
8315  }
8316 
8317  for(size_t i = 0; i < rows_number; i++)
8318  {
8319  getline(file, line);
8320 
8321  istringstream buffer(line);
8322 
8323  for(size_t j = 0; j < columns_number; j++)
8324  {
8325  string token;
8326 
8327  getline(buffer, token, delim);
8328 
8329  (*this)(i,j) = token;
8330 
8331  }
8332  }
8333  }
8334 
8335  file.close();
8336 }
8337 
8338 
8341 
8342 template <class T>
8343 void Matrix<T>::load_binary(const string& file_name)
8344 {
8345  ifstream file;
8346 
8347  file.open(file_name.c_str(), ios::binary);
8348 
8349  if(!file.is_open())
8350  {
8351  ostringstream buffer;
8352 
8353  buffer << "OpenNN Exception: Matrix template.\n"
8354  << "void load_binary(const string&) method.\n"
8355  << "Cannot open binary file: " << file_name << "\n";
8356 
8357  throw logic_error(buffer.str());
8358  }
8359 
8360  streamsize size = sizeof(size_t);
8361 
8362  size_t columns_number;
8363  size_t rows_number;
8364 
8365  file.read(reinterpret_cast<char*>(&columns_number), size);
8366  file.read(reinterpret_cast<char*>(&rows_number), size);
8367 
8368  size = sizeof(T);
8369 
8370  double value;
8371 
8372  this->set(rows_number, columns_number);
8373 
8374  for(size_t i = 0; i < this->size(); i++)
8375  {
8376  file.read(reinterpret_cast<char*>(&value), size);
8377 
8378  (*this)[i] = value;
8379  }
8380 
8381  file.close();
8382 }
8383 
8384 
8387 
8388 template <class T>
8389 void Matrix<T>::save_binary(const string& file_name) const
8390 {
8391  ofstream file(file_name.c_str(), ios::binary);
8392 
8393  if(!file.is_open())
8394  {
8395  ostringstream buffer;
8396 
8397  buffer << "OpenNN Exception: Matrix template." << endl
8398  << "void save(const string) method." << endl
8399  << "Cannot open matrix binary file." << endl;
8400 
8401  throw logic_error(buffer.str());
8402  }
8403 
8404  // Write data
8405 
8406  streamsize size = sizeof(size_t);
8407 
8408  size_t m = columns_number;
8409  size_t n = rows_number;
8410 
8411  file.write(reinterpret_cast<char*>(&m), size);
8412  file.write(reinterpret_cast<char*>(&n), size);
8413 
8414  size = sizeof(double);
8415 
8416  double value;
8417 
8418  for(int i = 0; i < this->size(); i++)
8419  {
8420  value = (*this)[i];
8421 
8422  file.write(reinterpret_cast<char*>(&value), size);
8423  }
8424 
8425  file.close();
8426 }
8427 
8428 
8432 
8433 template <class T>
8434 void Matrix<T>::save_csv(const string& file_name, const char& separator, const Vector<string>& row_names, const string& nameID) const
8435 {
8436  ofstream file(file_name.c_str());
8437 
8438  if(!file.is_open())
8439  {
8440  ostringstream buffer;
8441 
8442  buffer << "OpenNN Exception: Matrix template." << endl
8443  << "void save_csv(const string&, const char&, const Vector<string>&, const Vector<string>&) method." << endl
8444  << "Cannot open matrix data file: " << file_name << endl;
8445 
8446  throw logic_error(buffer.str());
8447  }
8448 
8449  if(row_names.size() != 0 && row_names.size() != rows_number)
8450  {
8451  ostringstream buffer;
8452 
8453  buffer << "OpenNN Exception: Matrix template." << endl
8454  << "void save_csv(const string&, const char&, const Vector<string>&, const Vector<string>&) method." << endl
8455  << "Row names must have size 0 or " << rows_number << "." << endl;
8456 
8457  throw logic_error(buffer.str());
8458  }
8459 
8460  // Write file
8461 
8462  if(!header.empty() && header != "")
8463  {
8464  if(!row_names.empty())
8465  {
8466  file << nameID << separator;
8467  }
8468 
8469  for(size_t j = 0; j < columns_number; j++)
8470  {
8471  file << header[j];
8472 
8473  if(j != columns_number-1)
8474  {
8475  file << separator;
8476  }
8477  }
8478 
8479  file << endl;
8480  }
8481 
8482  file.precision(20);
8483 
8484  for(size_t i = 0; i < rows_number; i++)
8485  {
8486  if(!row_names.empty())
8487  {
8488  file << row_names[i] << separator;
8489  }
8490 
8491  for(size_t j = 0; j < columns_number; j++)
8492  {
8493  file <<(*this)(i,j);
8494 
8495  if(j != columns_number-1)
8496  {
8497  file << separator;
8498  }
8499  }
8500 
8501  file << endl;
8502  }
8503 
8504  file.close();
8505 }
8506 
8507 
8511 
8512 template <class T>
8513 void Matrix<T>::save_json(const string& file_name, const Vector<string>& column_names) const
8514 {
8515  ofstream file(file_name.c_str());
8516 
8517  if(!file.is_open())
8518  {
8519  ostringstream buffer;
8520 
8521  buffer << "OpenNN Exception: Matrix template." << endl
8522  << "void save_json(const string&, const Vector<string>&) method." << endl
8523  << "Cannot open matrix data file." << endl;
8524 
8525  throw logic_error(buffer.str());
8526  }
8527 
8528  if(column_names.size() != 0 && column_names.size() != columns_number)
8529  {
8530  ostringstream buffer;
8531 
8532  buffer << "OpenNN Exception: Matrix template." << endl
8533  << "void save_json(const string&, const Vector<string>&) method." << endl
8534  << "Column names must have size 0 or " << columns_number << "." << endl;
8535 
8536  throw logic_error(buffer.str());
8537  }
8538 
8539  // Write file
8540 
8541  Vector<string> header;
8542 
8543  if(column_names.empty())
8544  {
8545  header.set(columns_number);
8546 
8547  for(size_t i = 0; i < columns_number; i++)
8548  {
8549  header[i] = "variable_" + to_string(i);
8550  }
8551  }
8552  else
8553  {
8554  header = column_names;
8555  }
8556 
8557  file.precision(20);
8558 
8559  file << "{ \"rows_number\": " << rows_number
8560  << ", \"columns_number\": " << columns_number << ", ";
8561 
8562  for(size_t i = 0; i < columns_number; i++)
8563  {
8564  file << "\"" << header[i] << "\": [";
8565 
8566  for(size_t j = 0; j < rows_number; j++)
8567  {
8568  file <<(*this)(j,i);
8569 
8570  if(j != rows_number-1)
8571  {
8572  file << ", ";
8573  }
8574  }
8575 
8576  file << "]";
8577 
8578  if(i != columns_number-1)
8579  {
8580  file << ", ";
8581  }
8582  }
8583 
8584  file << "}";
8585 
8586  // Close file
8587 
8588  file.close();
8589 }
8590 
8591 
8595 
8596 template <class T>
8597 void Matrix<T>::parse(const string& str)
8598 {
8599  if(str.empty())
8600  {
8601  set();
8602  }
8603  else
8604  {
8605  // Set matrix sizes
8606 
8607  istringstream str_buffer(str);
8608 
8609  string line;
8610 
8611  getline(str_buffer, line);
8612 
8613  istringstream line_buffer(line);
8614 
8615  istream_iterator<string> it(line_buffer);
8616  istream_iterator<string> end;
8617 
8618  const vector<string> results(it, end);
8619 
8620  const size_t new_columns_number = static_cast<size_t>(results.size());
8621 
8622  size_t new_rows_number = 1;
8623 
8624  while(str_buffer.good())
8625  {
8626  getline(str_buffer, line);
8627 
8628  if(!line.empty())
8629  {
8630  new_rows_number++;
8631  }
8632  }
8633 
8634  set(new_rows_number, new_columns_number);
8635 
8636  // Clear file
8637 
8638  str_buffer.clear();
8639  str_buffer.seekg(0, ios::beg);
8640 
8641  for(size_t i = 0; i < rows_number; i++)
8642  {
8643  for(size_t j = 0; j < columns_number; j++)
8644  {
8645  str_buffer >>(*this)(i,j);
8646  }
8647  }
8648  }
8649 }
8650 
8651 
8655 
8656 template <class T>
8657 string Matrix<T>::matrix_to_string(const char& separator) const
8658 {
8659  ostringstream buffer;
8660 
8661  if(rows_number > 0 && columns_number > 0)
8662  {
8663  buffer << get_header().vector_to_string(separator);
8664 
8665  for(size_t i = 0; i < rows_number; i++)
8666  {
8667  buffer << "\n"
8668  << get_row(i).vector_to_string(separator);
8669  }
8670  }
8671 
8672  return buffer.str();
8673 }
8674 
8675 
8677 
8678 template <class T>
8680 {
8681  Matrix<size_t> size_t_matrix(rows_number, columns_number);
8682 
8683  const size_t this_size = this->size();
8684 
8685  for(size_t i = 0; i < this_size; i++)
8686  {
8687  size_t_matrix[i] = static_cast<size_t>((*this)[i]);
8688  }
8689 
8690  return(size_t_matrix);
8691 }
8692 
8693 
8695 
8696 template <class T>
8698 {
8699  Matrix<float> new_matrix(rows_number, columns_number);
8700 
8701  const size_t this_size = this->size();
8702 
8703  for(size_t i = 0; i < this_size; i++)
8704  {
8705  new_matrix[i] = static_cast<float>((*this)[i]);
8706  }
8707 
8708  return new_matrix;
8709 }
8710 
8711 
8713 
8714 template <class T>
8716 {
8717  Matrix<double> new_matrix(rows_number, columns_number);
8718 
8719  const size_t this_size = this->size();
8720 
8721  for(size_t i = 0; i < this_size; i++)
8722  {
8723  new_matrix[i] = static_cast<double>((*this)[i]);
8724  }
8725 
8726  return new_matrix;
8727 }
8728 
8729 
8731 
8732 template <class T>
8734 {
8735  Matrix<double> new_matrix(rows_number, columns_number);
8736 
8737  const size_t this_size = this->size();
8738 
8739  for(size_t i = 0; i < this_size; i++)
8740  {
8741  try
8742  {
8743  new_matrix[i] = (*this)[i] ? 1.0 : 0.0;
8744  }
8745  catch(const logic_error&)
8746  {
8747  new_matrix[i] = nan("NA");
8748  }
8749  }
8750 
8751  new_matrix.set_header(header);
8752 
8753  return new_matrix;
8754 }
8755 
8756 
8758 
8759 template <class T>
8761 {
8762  Matrix<double> new_matrix(rows_number, columns_number);
8763 
8764  const size_t this_size = this->size();
8765 
8766  for(size_t i = 0; i < this_size; i++)
8767  {
8768  try
8769  {
8770  new_matrix[i] = stod((*this)[i]);
8771  }
8772  catch(const logic_error&)
8773  {
8774  new_matrix[i] = nan("NA");
8775  }
8776  }
8777 
8778  new_matrix.set_header(header);
8779 
8780  return new_matrix;
8781 }
8782 
8783 
8785 
8786 template <class T>
8788 {
8789  Matrix<size_t> new_matrix(rows_number, columns_number);
8790 
8791  const size_t this_size = this->size();
8792 
8793  for(size_t i = 0; i < this_size; i++)
8794  {
8795  try
8796  {
8797  new_matrix[i] = static_cast<size_t>(stoi((*this)[i]));
8798  }
8799  catch(const logic_error&)
8800  {
8801  new_matrix[i] = numeric_limits<size_t>::max();
8802  }
8803  }
8804 
8805  return new_matrix;
8806 }
8807 
8808 
8810 
8811 template <class T>
8812 Matrix<string> Matrix<T>::to_string_matrix(const size_t& precision) const
8813 {
8814  Matrix<string> string_matrix(rows_number, columns_number);
8815 
8816  ostringstream buffer;
8817 
8818  for(size_t i = 0; i < rows_number; i++)
8819  {
8820  for(size_t j = 0; j < columns_number; j++)
8821  {
8822  buffer.str("");
8823  buffer << setprecision(precision) <<(*this)(i,j);
8824 
8825  string_matrix(i,j) = buffer.str();
8826  }
8827  }
8828 
8829  if(!header.empty()) string_matrix.set_header(header);
8830 
8831  return string_matrix;
8832 }
8833 
8834 
8836 
8837 template <class T>
8839 {
8840  return Matrix<T>(rows_number, columns_number, 0);
8841 }
8842 
8843 
8845 
8846 template <class T>
8848 {
8849  return Matrix<T>(rows_number, columns_number, 1);
8850 }
8851 
8852 
8856 
8857 template <class T>
8858 vector<T> Matrix<T>::to_std_vector() const
8859 {
8860  const vector<T> std_vector(this->begin(),this->end());
8861 
8862  return(std_vector);
8863 }
8864 
8865 
8869 
8870 template <class T>
8872 {
8873  const Vector<T> vector(this->begin(),this->end());
8874 
8875  return vector;
8876 }
8877 
8878 
8882 
8883 template <class T>
8885 {
8886  Vector<Vector<T>> vector_of_vectors(columns_number);
8887 
8888  for(size_t i = 0; i < columns_number; i++)
8889  {
8890  vector_of_vectors[i] = this->get_column(i);
8891  }
8892 
8893  return vector_of_vectors;
8894 }
8895 
8896 
8899 
8900 template <class T>
8902 {
8903  cout << "Rows number: " << rows_number << endl
8904  << "Columns number: " << columns_number << endl;
8905 
8906  cout << "Header:\n" << header << endl;
8907 
8908  if(rows_number > 0)
8909  {
8910  const Vector<T> first_row = get_row(0);
8911 
8912  cout << "Row 0:\n" << first_row << endl;
8913  }
8914 
8915  if(rows_number > 1)
8916  {
8917  const Vector<T> second_row = get_row(1);
8918 
8919  cout << "Row 1:\n" << second_row << endl;
8920  }
8921 
8922  if(rows_number > 3)
8923  {
8924  const Vector<T> row = get_row(rows_number-2);
8925 
8926  cout << "Row " << rows_number-2 << ":\n" << row << endl;
8927  }
8928 
8929  if(rows_number > 2)
8930  {
8931  const Vector<T> last_row = get_row(rows_number-1);
8932 
8933  cout << "Row " << rows_number-1 << ":\n" << last_row << endl;
8934  }
8935 }
8936 
8937 
8941 
8942 template<class T>
8943 istream& operator >>(istream& is, Matrix<T>& m)
8944 {
8945  const size_t rows_number = m.get_rows_number();
8946  const size_t columns_number = m.get_columns_number();
8947 
8948  for(size_t i = 0; i < rows_number; i++)
8949  {
8950  for(size_t j = 0; j < columns_number; j++)
8951  {
8952  is >> m(i,j);
8953  }
8954  }
8955 
8956  return is;
8957 }
8958 
8959 
8963 
8964 template<class T>
8965 ostream& operator <<(ostream& os, const Matrix<T>& m)
8966 {
8967  const size_t rows_number = m.get_rows_number();
8968  const size_t columns_number = m.get_columns_number();
8969 
8970  if(m.get_header() != "") cout << m.get_header() << endl;
8971 
8972  if(rows_number > 0 && columns_number > 0)
8973  {
8974  os << m.get_row(0);
8975 
8976  for(size_t i = 1; i < rows_number; i++)
8977  {
8978  os << "\n"
8979  << m.get_row(i);
8980  }
8981  }
8982 
8983  return os;
8984 }
8985 
8986 
8990 
8991 template<class T>
8992 ostream& operator << (ostream& os, const Matrix<Vector<T>>& m)
8993 {
8994  const size_t rows_number = m.get_rows_number();
8995  const size_t columns_number = m.get_columns_number();
8996 
8997  for(size_t i = 0; i < rows_number; i++)
8998  {
8999  for(size_t j = 0; j < columns_number; j++)
9000  {
9001  os << "subvector_" << i << "_" << j << "\n"
9002  << m(i,j) << endl;
9003  }
9004  }
9005 
9006  return os;
9007 }
9008 
9009 
9013 
9014 template<class T>
9015 ostream& operator << (ostream& os, const Matrix< Matrix<T> >& m)
9016 {
9017  const size_t rows_number = m.get_rows_number();
9018  const size_t columns_number = m.get_columns_number();
9019 
9020  for(size_t i = 0; i < rows_number; i++)
9021  {
9022  for(size_t j = 0; j < columns_number; j++)
9023  {
9024  os << "submatrix_" << i << "_" << j << "\n"
9025  << m(i,j) << endl;
9026  }
9027  }
9028 
9029  return os;
9030 }
9031 
9032 
9033 template <class T>
9034 Matrix<T> Matrix<T>::insert_padding(const size_t& width, const size_t& height) const
9035 {
9036  Matrix<T> input(*this);
9037 
9038  if(!width && !height) return input;
9039 
9040  Matrix<T> zero_padding_matrix(input);
9041 
9042  for(size_t i = 0; i < width; i++)
9043  {
9044  const size_t rows_number = zero_padding_matrix.get_rows_number();
9045 
9046  const Vector<double> zero_vector_rows(rows_number, 0.0);
9047 
9048  zero_padding_matrix = zero_padding_matrix.append_column(zero_vector_rows);
9049 
9050  zero_padding_matrix = zero_padding_matrix.insert_column(0, zero_vector_rows);
9051  }
9052 
9053  for(size_t i = 0; i < height; i++)
9054  {
9055  const size_t columns_number = zero_padding_matrix.get_columns_number();
9056 
9057  const Vector<double> zero_vector_columns(columns_number, 0.0);
9058 
9059  zero_padding_matrix = zero_padding_matrix.append_row(zero_vector_columns);
9060 
9061  zero_padding_matrix = zero_padding_matrix.insert_row(0, zero_vector_columns);
9062  }
9063 
9064  return zero_padding_matrix;
9065 }
9066 
9067 
9071 
9072 template <class T>
9073 Matrix<T> Matrix<T>::to_categorical(const size_t& column_index) const
9074 {
9075  const size_t rows_number = get_rows_number();
9076 
9077  const Vector<T> column = get_column(column_index);
9078 
9079  const Vector<T> categories = column.get_unique_elements();
9080 
9081  const size_t new_columns_number = categories.size();
9082 
9083  categories.sort_ascending_values();
9084 
9085  Matrix<T> new_columns(rows_number,new_columns_number,0);
9086 
9087  for(size_t i = 0 ; i < new_columns_number ; i++)
9088  {
9089  for(size_t j = 0 ; j < rows_number ; j++)
9090  {
9091  if(column[j] == categories[i]) new_columns(j,i) = 1;
9092  }
9093  }
9094 
9095  if (!header.empty())
9096  {
9097  Vector<string> new_header = categories.to_string_vector();
9098 
9099  new_columns.set_header(new_header);
9100  }
9101 
9102  (this)->delete_column(column_index);
9103 
9104  return (this)->insert_matrix(column_index,new_columns);
9105 
9106 }
9107 
9108 
9111 
9112 template <class T>
9114 {
9115  Tensor<T> tensor(rows_number, columns_number);
9116 
9117  for(size_t i = 0; i < this->size(); i++)
9118  {
9119  tensor[i] = (*this)[i];
9120  }
9121 
9122  return tensor;
9123 }
9124 
9129 
9130 template <class T>
9131 Vector< Matrix<T> > Matrix<T>::to_vector_matrix(const size_t& vector_size, const size_t& new_rows_number, const size_t& new_columns_number) const
9132 {
9133  Vector<Matrix<T>> output(vector_size, Matrix<T>(new_rows_number, new_columns_number, 0.0));
9134  Matrix<double> temp = (*this);
9135 
9136  for(size_t i = 0; i < vector_size; i++)
9137  {
9138  output[i] = temp.get_first_rows(new_rows_number);
9139 
9140  temp = temp.delete_first_rows(new_rows_number);
9141  }
9142 
9143  return output;
9144 }
9145 
9146 }
9147 
9148 // end namespace
9149 
9150 #endif
9151 
9152 // OpenNN: Open Neural Networks Library.
9153 // Copyright(C) 2005-2019 Artificial Intelligence Techniques, SL.
9154 //
9155 // This library is free software; you can redistribute it and/or
9156 // modify it under the terms of the GNU Lesser General Public
9157 // License as published by the Free Software Foundation; either
9158 // version 2.1 of the License, or any later version.
9159 //
9160 // This library is distributed in the hope that it will be useful,
9161 // but WITHOUT ANY WARRANTY; without even the implied warranty of
9162 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
9163 // Lesser General Public License for more details.
9164 
9165 // You should have received a copy of the GNU Lesser General Public
9166 // License along with this library; if not, write to the Free Software
9167 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
OpenNN::Vector::delete_index
Vector< T > delete_index(const size_t &) const
Definition: vector.h:3676
OpenNN::Vector::get_unique_elements
Vector< T > get_unique_elements() const
Definition: vector.h:3975
OpenNN::Matrix::set_column
void set_column(const size_t &, const Vector< T > &, const string &="")
Definition: matrix.h:3133
OpenNN::Matrix::delete_first_rows
Matrix< T > delete_first_rows(const size_t &) const
Definition: matrix.h:4705
OpenNN::Matrix::get_rows_number
const size_t & get_rows_number() const
Returns the number of rows in the matrix.
Definition: matrix.h:1287
OpenNN::Matrix::set
void set()
This method set the numbers of rows and columns of the matrix to zero.
Definition: matrix.h:1467
OpenNN::Vector::sort_ascending_values
Vector< T > sort_ascending_values() const
Returns a vector of the elements of this vector sorted by ascending values.
Definition: vector.h:2564
OpenNN::Vector::to_string_vector
Vector< string > to_string_vector() const
Returns a new vector with the elements of this vector converted to string.
Definition: vector.h:4357
OpenNN::Vector::string_to_double
Vector< double > string_to_double() const
Returns a new vector with the elements of this string vector casted to double.
Definition: vector.h:4379
OpenNN::Vector::get_indices_less_than
Vector< size_t > get_indices_less_than(const T &) const
Definition: vector.h:2013
OpenNN::Matrix::get_first_rows
Matrix< T > get_first_rows(const size_t &) const
Definition: matrix.h:4730
OpenNN::Matrix::columns_number
size_t columns_number
Number of columns in the matrix.
Definition: matrix.h:623
OpenNN::Vector::is_constant
bool is_constant(const double &=0.0) const
Definition: vector.h:1231
OpenNN::Matrix::empty
bool empty() const
Returns true if number of rows and columns is zero.
Definition: matrix.h:7166
OpenNN::Vector::calculate_product
T calculate_product() const
Returns the product of the elements of this vector.
Definition: vector.h:2519
OpenNN::Vector::count_less_than
size_t count_less_than(const T &) const
Definition: vector.h:2090
OpenNN::Matrix::get_header
const Vector< string > get_header() const
Returns a string vector with the header.
Definition: matrix.h:1305
OpenNN::Vector::sort_ascending_indices
Vector< size_t > sort_ascending_indices() const
Returns a vector of the indices of this vector sorted by ascending values.
Definition: vector.h:2537
OpenNN::Matrix
This template class defines a matrix for general purpose use.
Definition: matrix.h:42
OpenNN::Matrix::get_row
Vector< T > get_row(const size_t &) const
Definition: matrix.h:2563
OpenNN::Vector::get_indices_equal_to
Vector< size_t > get_indices_equal_to(const T &) const
Definition: vector.h:1978
OpenNN::Matrix::set_header
void set_header(const Vector< string > &)
Definition: matrix.h:1668
OpenNN::Tensor::get_dimension
size_t get_dimension(const size_t &) const
Definition: tensor.h:784
OpenNN::Matrix::get_column_index
size_t get_column_index(const string &) const
Definition: matrix.h:1325
OpenNN::Tensor
This template class defines a tensor for general purpose use.
Definition: tensor.h:37
OpenNN::Vector::count_greater_than
size_t count_greater_than(const T &) const
Definition: vector.h:2068
OpenNN::Vector::get_subvector
Vector< T > get_subvector(const size_t &, const size_t &) const
Definition: vector.h:3240
OpenNN::Vector::count_NAN
size_t count_NAN() const
Returns the number of std NANs that are contained in the vector.
Definition: vector.h:1530
OpenNN::Vector::set
void set()
Sets the size of this vector to zero.
Definition: vector.h:682
OpenNN::Vector::contains
bool contains(const T &) const
Definition: vector.h:1123
OpenNN::Vector::randomize_normal
void randomize_normal(const double &=0.0, const double &=1.0)
Definition: vector.h:932
OpenNN::Vector::get_indices_greater_than
Vector< size_t > get_indices_greater_than(const T &) const
Definition: vector.h:2041
OpenNN::Matrix::rows_number
size_t rows_number
Number of rows in the matrix.
Definition: matrix.h:619
OpenNN::Matrix::get_columns_number
const size_t & get_columns_number() const
Returns the number of columns in the matrix.
Definition: matrix.h:1296
OpenNN::Matrix::append_row
Matrix< T > append_row(const Vector< T > &) const
Definition: matrix.h:3462
OpenNN::Vector::insert_element
Vector< T > insert_element(const size_t &, const T &) const
Definition: vector.h:3627
OpenNN::Matrix::set_row
void set_row(const size_t &, const Vector< T > &)
Definition: matrix.h:3011
OpenNN::Vector::count_between
size_t count_between(const T &, const T &) const
Definition: vector.h:2148
OpenNN::Matrix::header
Vector< string > header
Header with names of columns.
Definition: matrix.h:627
OpenNN::Vector
This template represents an array of any kind of numbers or objects.
Definition: vector.h:54
OpenNN::Vector::randomize_uniform
void randomize_uniform(const T &, const T &)
Definition: vector.h:847
OpenNN::Matrix::get_column
Vector< T > get_column(const size_t &) const
Definition: matrix.h:2663
OpenNN::Vector::assemble
Vector< T > assemble(const Vector< T > &) const
Definition: vector.h:3819
OpenNN::Vector::calculate_sum
T calculate_sum() const
Returns the sum of the elements of this vector.
Definition: vector.h:2458
OpenNN::Vector::sort_descending_indices
Vector< size_t > sort_descending_indices() const
Returns a vector of the indices of this vector sorted by descending values.
Definition: vector.h:2599
OpenNN::Vector::count_equal_to
size_t count_equal_to(const T &) const
Definition: vector.h:1498