00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef __MATRIX_H__
00017 #define __MATRIX_H__
00018
00019
00020
00021 #include <iostream>
00022 #include <fstream>
00023 #include <sstream>
00024 #include <cstdlib>
00025 #include <stdexcept>
00026 #include <climits>
00027 #include <cmath>
00028
00029
00030
00031 #include "vector.h"
00032
00033
00034 namespace OpenNN
00035 {
00036
00039
00040 template <class Type>
00041 class Matrix
00042 {
00043
00044 public:
00045
00046
00047
00049
00050 explicit Matrix(void)
00051 {
00052 rows_number = 0;
00053 columns_number = 0;
00054 data = NULL;
00055 }
00056
00057
00061
00062
00063 explicit Matrix(const unsigned int& new_rows_number, const unsigned int& new_columns_number)
00064 {
00065 if(new_rows_number == 0 && new_columns_number == 0)
00066 {
00067 rows_number = 0;
00068 columns_number = 0;
00069 data = NULL;
00070 }
00071 else if(new_rows_number == 0)
00072 {
00073 std::ostringstream buffer;
00074
00075 buffer << "OpenNN Exception: Matrix Template.\n"
00076 << "Constructor Matrix(const unsigned int&, const unsigned int&).\n"
00077 << "Number of rows must be greater than zero.\n";
00078
00079 throw std::logic_error(buffer.str());
00080 }
00081 else if(new_columns_number == 0)
00082 {
00083 std::ostringstream buffer;
00084
00085 buffer << "OpenNN Exception: Matrix Template.\n"
00086 << "Constructor Matrix(const unsigned int&, const unsigned int&).\n"
00087 << "Number of columns must be greater than zero.\n";
00088
00089 throw std::logic_error(buffer.str());
00090 }
00091 else
00092 {
00093 rows_number = new_rows_number;
00094 columns_number = new_columns_number;
00095
00096 data = new Type*[rows_number];
00097 data[0] = new Type[rows_number*columns_number];
00098
00099 for(unsigned int i = 1; i < rows_number; i++)
00100 {
00101 data[i] = data[i-1] + columns_number;
00102 }
00103 }
00104 }
00105
00106
00111
00112 explicit Matrix(const unsigned int& new_rows_number, const unsigned int& new_columns_number, const Type& type)
00113 {
00114 if(new_rows_number == 0 && new_columns_number == 0)
00115 {
00116 rows_number = 0;
00117 columns_number = 0;
00118 data = NULL;
00119 }
00120 else if(new_rows_number == 0)
00121 {
00122 std::ostringstream buffer;
00123
00124 buffer << "OpenNN Exception: Matrix Template.\n"
00125 << "Constructor Matrix(const unsigned int&, const unsigned int&, const Type&).\n"
00126 << "Number of rows must be greater than zero.\n";
00127
00128 throw std::logic_error(buffer.str());
00129 }
00130 else if(new_columns_number == 0)
00131 {
00132 std::ostringstream buffer;
00133
00134 buffer << "OpenNN Exception: Matrix Template.\n"
00135 << "Constructor Matrix(const unsigned int&, const unsigned int&, const Type&).\n"
00136 << "Number of columns must be greater than zero.\n";
00137
00138 throw std::logic_error(buffer.str());
00139 }
00140 else
00141 {
00142
00143
00144 rows_number = new_rows_number;
00145 columns_number = new_columns_number;
00146
00147 data = new Type*[new_rows_number];
00148 data[0] = new Type[rows_number*columns_number];
00149
00150 for(unsigned int i = 1; i < rows_number; i++)
00151 {
00152 data[i] = data[i-1] + columns_number;
00153 }
00154
00155
00156
00157 for(unsigned int i = 0; i < rows_number; i++)
00158 {
00159 for(unsigned int j = 0; j < columns_number; j++)
00160 {
00161 data[i][j] = type;
00162 }
00163 }
00164 }
00165 }
00166
00167
00170
00171 explicit Matrix(const std::string& filename)
00172 {
00173 rows_number = 0;
00174 columns_number = 0;
00175 data = NULL;
00176
00177 load(filename);
00178 }
00179
00180
00183
00184 Matrix(const Matrix& other_matrix)
00185 {
00186 const unsigned int new_rows_number = other_matrix.rows_number;
00187 const unsigned int new_columns_number = other_matrix.columns_number;
00188
00189 data = NULL;
00190
00191 if(new_rows_number == 0 && new_columns_number == 0)
00192 {
00193 rows_number = 0;
00194 columns_number = 0;
00195 data = NULL;
00196 }
00197 else if(new_rows_number == 0)
00198 {
00199 std::ostringstream buffer;
00200
00201 buffer << "OpenNN Exception: Matrix Template.\n"
00202 << "Copy constructor.\n"
00203 << "Number of rows must be greater than zero.\n";
00204
00205 throw std::logic_error(buffer.str());
00206 }
00207 else if(new_columns_number == 0)
00208 {
00209 std::ostringstream buffer;
00210
00211 buffer << "OpenNN Exception: Matrix Template.\n"
00212 << "Copy constructor.\n"
00213 << "Number of columns must be greater than zero.\n";
00214
00215 throw std::logic_error(buffer.str());
00216 }
00217 else
00218 {
00219 rows_number = new_rows_number;
00220 columns_number = new_columns_number;
00221
00222 data = new Type*[rows_number];
00223 data[0] = new Type[rows_number*columns_number];
00224
00225 for(unsigned int i = 1; i < rows_number; i++)
00226 {
00227 data[i] = data[i-1] + columns_number;
00228 }
00229 }
00230
00231 for(unsigned int i = 0; i < rows_number; i++)
00232 {
00233 for(unsigned int j = 0; j < columns_number; j++)
00234 {
00235 data[i][j] = other_matrix[i][j];
00236 }
00237 }
00238 }
00239
00240
00241
00242
00244
00245 ~Matrix(void)
00246 {
00247 if(data != NULL)
00248 {
00249 delete[] (data[0]);
00250 delete[] (data);
00251 }
00252 }
00253
00254
00255
00256
00259
00260 inline Matrix<Type>& operator = (const Matrix<Type>& other_matrix)
00261 {
00262 if(this != &other_matrix)
00263 {
00264 if(rows_number != other_matrix.rows_number || columns_number != other_matrix.columns_number)
00265 {
00266 if(data != NULL)
00267 {
00268 delete[] (data[0]);
00269 delete[] (data);
00270 }
00271
00272 rows_number = other_matrix.rows_number;
00273 columns_number = other_matrix.columns_number;
00274
00275 data = new Type*[rows_number];
00276 data[0] = new Type[rows_number*columns_number];
00277
00278 for(unsigned int i = 1; i < rows_number; i++)
00279 {
00280 data[i] = data[i-1] + columns_number;
00281 }
00282 }
00283
00284 for(unsigned int i = 0; i < rows_number; i++)
00285 {
00286 for(unsigned int j = 0; j < columns_number; j++)
00287 {
00288 data[i][j] = other_matrix[i][j];
00289 }
00290 }
00291 }
00292
00293 return(*this);
00294 }
00295
00296
00297
00298
00300
00301 inline Type* operator [] (const unsigned int& i)
00302 {
00303
00304
00305 #ifdef _DEBUG
00306
00307 if(i >= rows_number)
00308 {
00309 std::ostringstream buffer;
00310
00311 buffer << "OpenNN Exception: Matrix Template.\n"
00312 << "operator [] (unsigned int).\n"
00313 << "Row index (" << i << ") must be less than number of rows (" << rows_number << ").\n";
00314
00315 throw std::logic_error(buffer.str());
00316 }
00317
00318 #endif
00319
00320
00321
00322 return(data[i]);
00323 }
00324
00325
00327
00328 inline const Type* operator [] (const unsigned int& i) const
00329 {
00330
00331
00332 #ifdef _DEBUG
00333
00334 if(i >= rows_number)
00335 {
00336 std::ostringstream buffer;
00337
00338 buffer << "OpenNN Exception: Matrix Template.\n"
00339 << "operator [] (const unsigned int&) const.\n"
00340 << "Row index must be less than number of rows.\n";
00341
00342 throw std::logic_error(buffer.str());
00343 }
00344
00345 #endif
00346
00347
00348
00349 return(data[i]);
00350 }
00351
00352
00353
00354
00358
00359 inline bool operator == (const Matrix<Type>& other_matrix) const
00360 {
00361
00362
00363 #ifdef _DEBUG
00364
00365 const unsigned int other_rows_number = other_matrix.get_rows_number();
00366 const unsigned int other_columns_number = other_matrix.get_columns_number();
00367
00368 if(other_rows_number != rows_number)
00369 {
00370 std::ostringstream buffer;
00371
00372 buffer << "OpenNN Exception: Matrix Template.\n"
00373 << "bool operator == (const Matrix<Type>&) const.\n"
00374 << "Both numbers of rows must be the same.\n";
00375
00376 throw std::logic_error(buffer.str());
00377 }
00378 else if(other_columns_number != columns_number)
00379 {
00380 std::ostringstream buffer;
00381
00382 buffer << "OpenNN Exception: Matrix Template.\n"
00383 << "bool operator == (const Matrix<Type>&) const.\n"
00384 << "Both numbers of columns must be the same.\n";
00385
00386 throw std::logic_error(buffer.str());
00387 }
00388
00389 #endif
00390
00391 for(unsigned int i = 0; i < rows_number; i++)
00392 {
00393 for(unsigned int j = 0; j < columns_number; j++)
00394 {
00395 if(data[i][j] != other_matrix[i][j])
00396 {
00397 return(false);
00398 }
00399 }
00400 }
00401
00402 return(true);
00403 }
00404
00405
00406
00407
00411
00412 inline bool operator == (const Type& value) const
00413 {
00414 for(unsigned int i = 0; i < rows_number; i++)
00415 {
00416 for(unsigned int j = 0; j < columns_number; j++)
00417 {
00418 if(data[i][j] != value)
00419 {
00420 return(false);
00421 }
00422 }
00423 }
00424
00425 return(true);
00426 }
00427
00428
00429
00430
00434
00435 inline bool operator != (const Matrix<Type>& other_matrix) const
00436 {
00437
00438
00439 #ifdef _DEBUG
00440
00441 const unsigned int other_rows_number = other_matrix.get_rows_number();
00442 const unsigned int other_columns_number = other_matrix.get_columns_number();
00443
00444 if(other_rows_number != rows_number)
00445 {
00446 std::ostringstream buffer;
00447
00448 buffer << "OpenNN Exception: Matrix Template.\n"
00449 << "bool operator != (const Matrix<Type>&) const.\n"
00450 << "Both numbers of rows must be the same.\n";
00451
00452 throw std::logic_error(buffer.str());
00453 }
00454 else if(other_columns_number != columns_number)
00455 {
00456 std::ostringstream buffer;
00457
00458 buffer << "OpenNN Exception: Matrix Template.\n"
00459 << "bool operator != (const Matrix<Type>&) const.\n"
00460 << "Both numbers of columns must be the same.\n";
00461
00462 throw std::logic_error(buffer.str());
00463 }
00464
00465 #endif
00466
00467 for(unsigned int i = 0; i < rows_number; i++)
00468 {
00469 for(unsigned int j = 0; j < columns_number; j++)
00470 {
00471 if(data[i][j] != other_matrix[i][j])
00472 {
00473 return(true);
00474 }
00475 }
00476 }
00477
00478 return(false);
00479 }
00480
00481
00482
00483
00487
00488 inline bool operator != (const Type& value) const
00489 {
00490
00491
00492 for(unsigned int i = 0; i < rows_number; i++)
00493 {
00494 for(unsigned int j = 0; j < columns_number; j++)
00495 {
00496 if(data[i][j] != value)
00497 {
00498 return(true);
00499 }
00500 }
00501 }
00502
00503 return(false);
00504 }
00505
00506
00507
00508
00513
00514 inline bool operator > (const Matrix<Type>& other_matrix) const
00515 {
00516
00517
00518 #ifdef _DEBUG
00519
00520 const unsigned int other_rows_number = other_matrix.get_rows_number();
00521 const unsigned int other_columns_number = other_matrix.get_columns_number();
00522
00523 if(other_rows_number != rows_number)
00524 {
00525 std::ostringstream buffer;
00526
00527 buffer << "OpenNN Exception: Matrix Template.\n"
00528 << "bool operator > (const Matrix<Type>&) const.\n"
00529 << "Both numbers of rows must be the same.\n";
00530
00531 throw std::logic_error(buffer.str());
00532 }
00533 else if(other_columns_number != columns_number)
00534 {
00535 std::ostringstream buffer;
00536
00537 buffer << "OpenNN Exception: Matrix Template.\n"
00538 << "bool operator > (const Matrix<Type>&) const.\n"
00539 << "Both numbers of columns must be the same.\n";
00540
00541 throw std::logic_error(buffer.str());
00542 }
00543
00544 #endif
00545
00546 for(unsigned int i = 0; i < rows_number; i++)
00547 {
00548 for(unsigned int j = 0; j < rows_number; j++)
00549 {
00550 if(data[i][j] <= other_matrix[i][j])
00551 {
00552 return(false);
00553 }
00554 }
00555 }
00556
00557 return(true);
00558 }
00559
00560
00561
00562
00566
00567 inline bool operator > (const Type& value) const
00568 {
00569 for(unsigned int i = 0; i < rows_number; i++)
00570 {
00571 for(unsigned int j = 0; j < rows_number; j++)
00572 {
00573 if(data[i][j] <= value)
00574 {
00575 return(false);
00576 }
00577 }
00578 }
00579
00580 return(true);
00581 }
00582
00583
00584
00585
00590
00591 inline bool operator < (const Matrix<Type>& other_matrix) const
00592 {
00593
00594
00595 #ifdef _DEBUG
00596
00597 const unsigned int other_rows_number = other_matrix.get_rows_number();
00598 const unsigned int other_columns_number = other_matrix.get_columns_number();
00599
00600 if(other_rows_number != rows_number)
00601 {
00602 std::ostringstream buffer;
00603
00604 buffer << "OpenNN Exception: Matrix Template.\n"
00605 << "bool operator < (const Matrix<Type>&) const.\n"
00606 << "Both numbers of rows must be the same.\n";
00607
00608 throw std::logic_error(buffer.str());
00609 }
00610 else if(other_columns_number != columns_number)
00611 {
00612 std::ostringstream buffer;
00613
00614 buffer << "OpenNN Exception: Matrix Template.\n"
00615 << "bool operator < (const Matrix<Type>&) const.\n"
00616 << "Both numbers of columns must be the same.\n";
00617
00618 throw std::logic_error(buffer.str());
00619 }
00620
00621 #endif
00622
00623 for(unsigned int i = 0; i < rows_number; i++)
00624 {
00625 for(unsigned int j = 0; j < columns_number; j++)
00626 {
00627 if(data[i][j] >= other_matrix[i][j])
00628 {
00629 return(false);
00630 }
00631 }
00632 }
00633
00634 return(true);
00635 }
00636
00637
00638
00639
00643
00644 inline bool operator < (const Type& value) const
00645 {
00646 for(unsigned int i = 0; i < rows_number; i++)
00647 {
00648 for(unsigned int j = 0; j < columns_number; j++)
00649 {
00650 if(data[i][j] >= value)
00651 {
00652 return(false);
00653 }
00654 }
00655 }
00656
00657 return(true);
00658 }
00659
00660
00661
00662
00667
00668 inline bool operator >= (const Matrix<Type>& other_matrix) const
00669 {
00670
00671
00672 #ifdef _DEBUG
00673
00674 const unsigned int other_rows_number = other_matrix.get_rows_number();
00675 const unsigned int other_columns_number = other_matrix.get_columns_number();
00676
00677 if(other_rows_number != rows_number)
00678 {
00679 std::ostringstream buffer;
00680
00681 buffer << "OpenNN Exception: Matrix Template.\n"
00682 << "bool operator >= (const Matrix<Type>&) const.\n"
00683 << "Both numbers of rows must be the same.\n";
00684
00685 throw std::logic_error(buffer.str());
00686 }
00687 else if(other_columns_number != columns_number)
00688 {
00689 std::ostringstream buffer;
00690
00691 buffer << "OpenNN Exception: Matrix Template.\n"
00692 << "bool operator >= (const Matrix<Type>&) const.\n"
00693 << "Both numbers of columns must be the same.\n";
00694
00695 throw std::logic_error(buffer.str());
00696 }
00697
00698 #endif
00699
00700 for(unsigned int i = 0; i < rows_number; i++)
00701 {
00702 for(unsigned int j = 0; j < columns_number; j++)
00703 {
00704 if(data[i][j] < other_matrix[i][j])
00705 {
00706 return(false);
00707 }
00708 }
00709 }
00710
00711 return(true);
00712 }
00713
00714
00715
00716
00720
00721 inline bool operator >= (const Type& value) const
00722 {
00723 for(unsigned int i = 0; i < rows_number; i++)
00724 {
00725 for(unsigned int j = 0; j < columns_number; j++)
00726 {
00727 if(data[i][j] < value)
00728 {
00729 return(false);
00730 }
00731 }
00732 }
00733
00734 return(true);
00735 }
00736
00737
00738
00739
00744
00745 inline bool operator <= (const Matrix<Type>& other_matrix) const
00746 {
00747
00748
00749 #ifdef _DEBUG
00750
00751 const unsigned int other_rows_number = other_matrix.get_rows_number();
00752 const unsigned int other_columns_number = other_matrix.get_columns_number();
00753
00754 if(other_rows_number != rows_number)
00755 {
00756 std::ostringstream buffer;
00757
00758 buffer << "OpenNN Exception: Matrix Template.\n"
00759 << "bool operator >= (const Matrix<Type>&) const.\n"
00760 << "Both numbers of rows must be the same.\n";
00761
00762 throw std::logic_error(buffer.str());
00763 }
00764 else if(other_columns_number != columns_number)
00765 {
00766 std::ostringstream buffer;
00767
00768 buffer << "OpenNN Exception: Matrix Template.\n"
00769 << "bool operator >= (const Matrix<Type>&) const.\n"
00770 << "Both numbers of columns must be the same.\n";
00771
00772 throw std::logic_error(buffer.str());
00773 }
00774
00775 #endif
00776
00777 for(unsigned int i = 0; i < rows_number; i++)
00778 {
00779 for(unsigned int j = 0; j < columns_number; j++)
00780 {
00781 if(data[i][j] > other_matrix[i][j])
00782 {
00783 return(false);
00784 }
00785 }
00786 }
00787
00788 return(true);
00789 }
00790
00791
00792
00793
00797
00798 inline bool operator <= (const Type& value) const
00799 {
00800 for(unsigned int i = 0; i < rows_number; i++)
00801 {
00802 for(unsigned int j = 0; j < columns_number; j++)
00803 {
00804 if(data[i][j] > value)
00805 {
00806 return(false);
00807 }
00808 }
00809 }
00810
00811 return(true);
00812 }
00813
00814
00815
00816
00817
00818
00820
00821 const unsigned int& get_rows_number(void) const
00822 {
00823 return(rows_number);
00824 }
00825
00826
00827
00828
00830
00831 const unsigned int& get_columns_number(void) const
00832 {
00833 return(columns_number);
00834 }
00835
00836
00837
00838
00840
00841 void set(void)
00842 {
00843 if(data != NULL)
00844 {
00845 delete[] (data[0]);
00846 delete[] (data);
00847 }
00848
00849 rows_number = 0;
00850 columns_number = 0;
00851 data = NULL;
00852 }
00853
00854
00855
00856
00860
00861 void set(const unsigned int& new_rows_number, const unsigned int& new_columns_number)
00862 {
00863
00864
00865 if(new_rows_number == rows_number && new_columns_number == columns_number)
00866 {
00867
00868 }
00869 else if(new_rows_number == 0 && new_columns_number == 0)
00870 {
00871 set();
00872 }
00873 else if(new_rows_number == 0)
00874 {
00875 std::ostringstream buffer;
00876
00877 buffer << "OpenNN Exception: Matrix Template.\n"
00878 << "void set(const unsigned int&, const unsigned int&) method.\n"
00879 << "Number of rows must be greater than zero.\n";
00880
00881 throw std::logic_error(buffer.str());
00882 }
00883 else if(new_columns_number == 0)
00884 {
00885 std::ostringstream buffer;
00886
00887 buffer << "OpenNN Exception: Matrix Template.\n"
00888 << "void set(const unsigned int&, const unsigned int&) method.\n"
00889 << "Number of columns must be greater than zero.\n";
00890
00891 throw std::logic_error(buffer.str());
00892 }
00893 else
00894 {
00895 rows_number = new_rows_number;
00896 columns_number = new_columns_number;
00897
00898 if(data != NULL)
00899 {
00900 delete[] (data[0]);
00901 delete[] (data);
00902 }
00903
00904 data = new Type*[rows_number];
00905 data[0] = new Type[rows_number*columns_number];
00906
00907 for(unsigned int i = 1; i < rows_number; i++)
00908 {
00909 data[i] = data[i-1] + columns_number;
00910 }
00911 }
00912 }
00913
00914
00915
00916
00922
00923 void set(const unsigned int& new_rows_number, const unsigned int& new_columns_number, const Type& value)
00924 {
00925 if(new_rows_number == 0 && new_columns_number == 0)
00926 {
00927 set();
00928 }
00929 else if(new_rows_number == 0)
00930 {
00931 std::ostringstream buffer;
00932
00933 buffer << "OpenNN Exception: Matrix Template.\n"
00934 << "void set(const unsigned int&, const unsigned int&, const Type&) method.\n"
00935 << "Number of rows must be greater than zero.\n";
00936
00937 throw std::logic_error(buffer.str());
00938 }
00939 else if(new_columns_number == 0)
00940 {
00941 std::ostringstream buffer;
00942
00943 buffer << "OpenNN Exception: Matrix Template.\n"
00944 << "void set(const unsigned int&, const unsigned int&, const Type&) method.\n"
00945 << "Number of columns must be greater than zero.\n";
00946
00947 throw std::logic_error(buffer.str());
00948 }
00949 else
00950 {
00951 set(new_rows_number, new_columns_number);
00952 initialize(value);
00953 }
00954 }
00955
00956
00957
00958
00961
00962 void set(const Matrix& other_matrix)
00963 {
00964 }
00965
00966
00967
00968
00971
00972 void set(const std::string& filename)
00973 {
00974 load(filename);
00975 }
00976
00977
00978
00979
00982
00983 void set_identity(const unsigned int& new_size)
00984 {
00985 set(new_size, new_size);
00986 initialize_identity();
00987 }
00988
00989
00990
00991
00994
00995 void set_rows_number(const unsigned int& new_rows_number)
00996 {
00997 if(new_rows_number != rows_number)
00998 {
00999 set(new_rows_number, columns_number);
01000 }
01001 }
01002
01003
01004
01005
01008
01009 void set_columns_number(const unsigned int& new_columns_number)
01010 {
01011 if(new_columns_number != columns_number)
01012 {
01013 set(rows_number, new_columns_number);
01014 }
01015 }
01016
01017
01018
01019
01024
01025 void resize(const unsigned int& new_rows_number, const unsigned int& new_columns_number)
01026 {
01027
01028
01029 if(new_rows_number == rows_number && new_columns_number == columns_number)
01030 {
01031
01032 }
01033 else if(new_rows_number == 0 && new_columns_number == 0)
01034 {
01035 rows_number = 0;
01036 columns_number = 0;
01037
01038 if(data != NULL)
01039 {
01040 delete[] (data[0]);
01041 delete[] (data);
01042 }
01043
01044 data = NULL;
01045 }
01046 else if(new_rows_number == 0)
01047 {
01048 std::ostringstream buffer;
01049
01050 buffer << "OpenNN Exception: Matrix Template.\n"
01051 << "void resize(const unsigned int&, const unsigned int&) method.\n"
01052 << "Number of rows must be greater than zero.\n";
01053
01054 throw std::logic_error(buffer.str());
01055 }
01056 else if(new_columns_number == 0)
01057 {
01058 std::ostringstream buffer;
01059
01060 buffer << "OpenNN Exception: Matrix Template.\n"
01061 << "void resize(const unsigned int&, const unsigned int&) method.\n"
01062 << "Number of columns must be greater than zero.\n";
01063
01064 throw std::logic_error(buffer.str());
01065 }
01066 else
01067 {
01068 if(new_rows_number >= rows_number && new_columns_number >= columns_number)
01069 {
01070 const Matrix<Type> copy(*this);
01071
01072 set(new_rows_number, new_columns_number);
01073
01074 for(unsigned int i = 0; i < copy.get_rows_number(); i++)
01075 {
01076 for(unsigned int j = 0; j < copy.get_columns_number(); j++)
01077 {
01078 data[i][j] = copy[i][j];
01079 }
01080 }
01081 }
01082 else if(new_rows_number >= rows_number && new_columns_number <= columns_number)
01083 {
01084 const Matrix<Type> copy(*this);
01085
01086 set(new_rows_number, new_columns_number);
01087
01088 for(unsigned int i = 0; i < copy.get_rows_number(); i++)
01089 {
01090 for(unsigned int j = 0; j < new_columns_number; j++)
01091 {
01092 data[i][j] = copy[i][j];
01093 }
01094 }
01095 }
01096 else if(new_rows_number <= rows_number && new_columns_number >= columns_number)
01097 {
01098 const Matrix<Type> copy(*this);
01099
01100 set(new_rows_number, new_columns_number);
01101
01102 for(unsigned int i = 0; i < new_rows_number; i++)
01103 {
01104 for(unsigned int j = 0; j < copy.get_columns_number(); j++)
01105 {
01106 data[i][j] = copy[i][j];
01107 }
01108 }
01109 }
01110 else if(new_rows_number <= rows_number && new_columns_number >= columns_number)
01111 {
01112 const Matrix<Type> copy(*this);
01113
01114 set(new_rows_number, new_columns_number);
01115
01116 for(unsigned int i = 0; i < new_rows_number; i++)
01117 {
01118 for(unsigned int j = 0; j < new_columns_number; j++)
01119 {
01120 data[i][j] = copy[i][j];
01121 }
01122 }
01123 }
01124 }
01125 }
01126
01127
01128
01129
01130
01135
01136 void tuck_in(const unsigned int& row_position, const unsigned int& column_position, const Matrix<Type>& other_matrix)
01137 {
01138 const unsigned int other_rows_number = other_matrix.get_rows_number();
01139 const unsigned int other_columns_number = other_matrix.get_columns_number();
01140
01141
01142
01143 #ifdef _DEBUG
01144
01145 if(row_position + other_rows_number > rows_number)
01146 {
01147 std::ostringstream buffer;
01148
01149 buffer << "OpenNN Exception: Matrix Template.\n"
01150 << "void tuck_in(const unsigned int&, const unsigned int&, const Matrix<Type>&) const method.\n"
01151 << "Cannot tuck in matrix.\n";
01152
01153 throw std::logic_error(buffer.str());
01154 }
01155
01156 if(column_position + other_columns_number > columns_number)
01157 {
01158 std::ostringstream buffer;
01159
01160 buffer << "OpenNN Exception: Matrix Template.\n"
01161 << "void tuck_in(const unsigned int&, const unsigned int&, const Matrix<Type>&) const method.\n"
01162 << "Cannot tuck in matrix.\n";
01163
01164 throw std::logic_error(buffer.str());
01165 }
01166
01167 #endif
01168
01169 for(unsigned int i = 0; i < other_rows_number; i++)
01170 {
01171 for(unsigned int j = 0; j < other_columns_number; j++)
01172 {
01173 data[row_position+i][column_position+j] = other_matrix[i][j];
01174 }
01175 }
01176 }
01177
01178
01179
01180
01184
01185 Matrix<Type> arrange_submatrix(const Vector<unsigned int>& row_indices, const Vector<unsigned int>& column_indices) const
01186 {
01187 const unsigned int row_indices_size = row_indices.size();
01188 const unsigned int column_indices_size = column_indices.size();
01189
01190 Matrix<Type> sub_matrix(row_indices_size, column_indices_size);
01191
01192 unsigned int row_index;
01193 unsigned int column_index;
01194
01195 for(unsigned int i = 0; i < row_indices_size; i++)
01196 {
01197 row_index = row_indices[i];
01198
01199 for(unsigned int j = 0; j < column_indices_size; j++)
01200 {
01201 column_index = column_indices[j];
01202
01203 sub_matrix[i][j] = data[row_index][column_index];
01204 }
01205 }
01206
01207 return(sub_matrix);
01208 }
01209
01210
01211
01212
01215
01216 Matrix<Type> arrange_submatrix_rows(const Vector<unsigned int>& row_indices) const
01217 {
01218 const unsigned int row_indices_size = row_indices.size();
01219
01220 Matrix<Type> sub_matrix(row_indices_size, columns_number);
01221
01222 unsigned int row_index;
01223
01224 for(unsigned int i = 0; i < row_indices_size; i++)
01225 {
01226 row_index = row_indices[i];
01227
01228 for(unsigned int j = 0; j < columns_number; j++)
01229 {
01230 sub_matrix[i][j] = data[row_index][j];
01231 }
01232 }
01233
01234 return(sub_matrix);
01235 }
01236
01237
01238
01239
01242
01243 Matrix<Type> arrange_submatrix_columns(const Vector<unsigned int>& column_indices) const
01244 {
01245 const unsigned int column_indices_size = column_indices.size();
01246
01247 Matrix<Type> sub_matrix(rows_number, column_indices_size);
01248
01249 unsigned int column_index;
01250
01251 for(unsigned int i = 0; i < rows_number; i++)
01252 {
01253 for(unsigned int j = 0; j < column_indices_size; j++)
01254 {
01255 column_index = column_indices[j];
01256
01257 sub_matrix[i][j] = data[i][column_index];
01258 }
01259 }
01260
01261 return(sub_matrix);
01262 }
01263
01264
01265
01266
01269
01270 Vector<Type> arrange_row(const unsigned int& i) const
01271 {
01272
01273
01274 #ifdef _DEBUG
01275
01276 if(i >= rows_number)
01277 {
01278 std::ostringstream buffer;
01279
01280 buffer << "OpenNN Exception: Matrix Template.\n"
01281 << "Vector<Type> arrange_row(const unsigned int&) const method.\n"
01282 << "Row index (" << i << ") must be less than number of rows (" << rows_number << ").\n";
01283
01284 throw std::logic_error(buffer.str());
01285 }
01286
01287 #endif
01288
01289 Vector<Type> row(columns_number);
01290
01291 for(unsigned int j = 0; j < columns_number; j++)
01292 {
01293 row[j] = data[i][j];
01294 }
01295
01296 return(row);
01297 }
01298
01299
01300
01301
01305
01306 Vector<Type> arrange_row(const unsigned int& row_index, const Vector<unsigned int>& column_indices) const
01307 {
01308
01309
01310 #ifdef _DEBUG
01311
01312 if(row_index >= rows_number)
01313 {
01314 std::ostringstream buffer;
01315
01316 buffer << "OpenNN Exception: Matrix Template.\n"
01317 << "Vector<Type> arrange_row(const unsigned int&, const Vector<unsigned int>&) const method.\n"
01318 << "Row index (" << row_index << ") must be less than number of rows (" << rows_number << ").\n";
01319
01320 throw std::logic_error(buffer.str());
01321 }
01322
01323 #endif
01324
01325 const unsigned int size = column_indices.size();
01326
01327 Vector<Type> row(size);
01328
01329 for(unsigned int i = 0; i < size; i++)
01330 {
01331 row[i] = data[row_index][column_indices[i]];
01332 }
01333
01334 return(row);
01335 }
01336
01337
01338
01339
01340
01343
01344 Vector<Type> arrange_column(const unsigned int& j) const
01345 {
01346
01347
01348 #ifdef _DEBUG
01349
01350 if(j >= columns_number)
01351 {
01352 std::ostringstream buffer;
01353
01354 buffer << "OpenNN Exception: Matrix Template.\n"
01355 << "Vector<Type> arrange_column(const unsigned int&) const method.\n"
01356 << "Column index (" << j << ") must be less than number of rows (" << columns_number << ").\n";
01357
01358 throw std::logic_error(buffer.str());
01359 }
01360
01361 #endif
01362
01363 Vector<Type> column(rows_number);
01364
01365 for(unsigned int i = 0; i < rows_number; i++)
01366 {
01367 column[i] = data[i][j];
01368 }
01369
01370 return(column);
01371 }
01372
01373
01374
01375
01379
01380 Vector<Type> arrange_column(const unsigned int& column_index, const Vector<unsigned int>& row_indices) const
01381 {
01382
01383
01384 #ifdef _DEBUG
01385
01386 if(column_index >= columns_number)
01387 {
01388 std::ostringstream buffer;
01389
01390 buffer << "OpenNN Exception: Matrix Template.\n"
01391 << "Vector<Type> arrange_column(const unsigned int&) const method.\n"
01392 << "Column index (" << column_index << ") must be less than number of rows (" << columns_number << ").\n";
01393
01394 throw std::logic_error(buffer.str());
01395 }
01396
01397 #endif
01398
01399 const unsigned int size = row_indices.size();
01400
01401 Vector<Type> column(size);
01402
01403 for(unsigned int i = 0; i < size; i++)
01404 {
01405 column[i] = data[row_indices[i]][column_index];
01406 }
01407
01408 return(column);
01409 }
01410
01411
01412
01413
01415
01416 Vector<Type> get_diagonal(void) const
01417 {
01418
01419
01420 #ifdef _DEBUG
01421
01422 if(rows_number != columns_number)
01423 {
01424 std::ostringstream buffer;
01425
01426 buffer << "OpenNN Exception: Matrix Template.\n"
01427 << "Vector<Type> get_diagonal(void) const method.\n"
01428 << "Matrix must be squared.\n";
01429
01430 throw std::logic_error(buffer.str());
01431 }
01432
01433 #endif
01434
01435 Vector<Type> diagonal(rows_number);
01436
01437 for(unsigned int i = 0; i < rows_number; i++)
01438 {
01439 diagonal[i] = data[i][i];
01440 }
01441
01442 return(diagonal);
01443 }
01444
01445
01446
01447
01451
01452 void set_row(const unsigned int& row_index, const Vector<Type>& new_row)
01453 {
01454
01455
01456 #ifdef _DEBUG
01457
01458 if(row_index >= rows_number)
01459 {
01460 std::ostringstream buffer;
01461
01462 buffer << "OpenNN Exception: Matrix Template.\n"
01463 << "set_row(const unsigned int&, const Vector<Type>&) method.\n"
01464 << "Index must be less than number of rows.\n";
01465
01466 throw std::logic_error(buffer.str());
01467 }
01468
01469 unsigned int size = new_row.size();
01470
01471 if(size != columns_number)
01472 {
01473 std::ostringstream buffer;
01474
01475 buffer << "OpenNN Exception: Matrix Template.\n"
01476 << "set_row(const unsigned int&, const Vector<Type>&) method.\n"
01477 << "Size must be equal to number of columns.\n";
01478
01479 throw std::logic_error(buffer.str());
01480 }
01481
01482 #endif
01483
01484
01485
01486 for(unsigned int i = 0; i < columns_number; i++)
01487 {
01488 data[row_index][i] = new_row[i];
01489 }
01490 }
01491
01492
01493
01494
01498
01499 void set_row(const unsigned int& row_index, const Type& value)
01500 {
01501
01502
01503 #ifdef _DEBUG
01504
01505 if(row_index >= rows_number)
01506 {
01507 std::ostringstream buffer;
01508
01509 buffer << "OpenNN Exception: Matrix Template.\n"
01510 << "set_row(const unsigned int&, const Type&) method.\n"
01511 << "Index must be less than number of rows.\n";
01512
01513 throw std::logic_error(buffer.str());
01514 }
01515
01516 #endif
01517
01518
01519
01520 for(unsigned int i = 0; i < columns_number; i++)
01521 {
01522 data[row_index][i] = value;
01523 }
01524 }
01525
01526
01527
01528
01532
01533 void set_column(const unsigned int& column_index, const Vector<Type>& new_column)
01534 {
01535
01536
01537 #ifdef _DEBUG
01538
01539 if(column_index >= columns_number)
01540 {
01541 std::ostringstream buffer;
01542
01543 buffer << "OpenNN Exception: Matrix Template.\n"
01544 << "set_column(const unsigned int&, const Vector<Type>&).\n"
01545 << "Index must be less than number of columns.\n";
01546
01547 throw std::logic_error(buffer.str());
01548 }
01549
01550 const unsigned int size = new_column.size();
01551
01552 if(size != rows_number)
01553 {
01554 std::ostringstream buffer;
01555
01556 buffer << "OpenNN Exception: Matrix Template.\n"
01557 << "set_column(const unsigned int&, const Vector<Type>&).\n"
01558 << "Size must be equal to number of rows.\n";
01559
01560 throw std::logic_error(buffer.str());
01561 }
01562
01563 #endif
01564
01565
01566
01567 for(unsigned int i = 0; i < rows_number; i++)
01568 {
01569 data[i][column_index] = new_column[i];
01570 }
01571 }
01572
01573
01574
01575
01579
01580 void set_column(const unsigned int& column_index, const Type& value)
01581 {
01582
01583
01584 #ifdef _DEBUG
01585
01586 if(column_index >= columns_number)
01587 {
01588 std::ostringstream buffer;
01589
01590 buffer << "OpenNN Exception: Matrix Template.\n"
01591 << "set_column(const unsigned int&, const Type&).\n"
01592 << "Index must be less than number of columns.\n";
01593
01594 throw std::logic_error(buffer.str());
01595 }
01596
01597 #endif
01598
01599
01600
01601 for(unsigned int i = 0; i < rows_number; i++)
01602 {
01603 data[i][column_index] = value;
01604 }
01605 }
01606
01607
01608
01609
01610
01614
01615 void set_diagonal(const Type& new_diagonal)
01616 {
01617
01618
01619 #ifdef _DEBUG
01620
01621 if(rows_number != columns_number)
01622 {
01623 std::ostringstream buffer;
01624
01625 buffer << "OpenNN Exception: Matrix Template.\n"
01626 << "set_diagonal(const Type&).\n"
01627 << "Matrix must be square.\n";
01628
01629 throw std::logic_error(buffer.str());
01630 }
01631
01632 #endif
01633
01634
01635
01636 for(unsigned int i = 0; i < rows_number; i++)
01637 {
01638 data[i][i] = new_diagonal;
01639 }
01640 }
01641
01642
01643
01644
01648
01649 void set_diagonal(const Vector<Type>& new_diagonal)
01650 {
01651
01652
01653 #ifdef _DEBUG
01654
01655 if(rows_number != columns_number)
01656 {
01657 std::ostringstream buffer;
01658
01659 buffer << "OpenNN Exception: Matrix Template.\n"
01660 << "set_diagonal(const Vector<Type>&) const.\n"
01661 << "Matrix must be square.\n";
01662
01663 throw std::logic_error(buffer.str());
01664 }
01665
01666 unsigned int size = new_diagonal.size();
01667
01668 if(size != rows_number)
01669 {
01670 std::ostringstream buffer;
01671
01672 buffer << "OpenNN Exception: Matrix Template.\n"
01673 << "set_diagonal(const Vector<Type>&) const.\n"
01674 << "Size must be equal to number of rows.\n";
01675
01676 throw std::logic_error(buffer.str());
01677 }
01678
01679 #endif
01680
01681
01682
01683 for(unsigned int i = 0; i < rows_number; i++)
01684 {
01685 data[i][i] = new_diagonal[i];
01686 }
01687 }
01688
01689
01690
01691
01697
01698 void initialize_diagonal(const unsigned int& new_size, const Type& new_value)
01699 {
01700 set(new_size, new_size, 0.0);
01701 set_diagonal(new_value);
01702 }
01703
01704
01705
01706
01712
01713 void initialize_diagonal(const unsigned int& new_size, const Vector<Type>& new_values)
01714 {
01715
01716
01717 #ifdef _DEBUG
01718
01719 const unsigned int new_values_size = new_values.size();
01720
01721 if(new_values_size != new_size)
01722 {
01723 std::ostringstream buffer;
01724
01725 buffer << "OpenNN Exception: Matrix Template.\n"
01726 << "initialize_diagonal(const unsigned int&, const unsigned int&) const.\n"
01727 << "Size of new values is not equal to size of square matrix.\n";
01728
01729 throw std::logic_error(buffer.str());
01730 }
01731
01732 #endif
01733
01734 set(new_size, new_size, 0.0);
01735 set_diagonal(new_values);
01736 }
01737
01738
01739
01740
01744
01745 Matrix<Type> sum_diagonal(const Type& new_summing_value) const
01746 {
01747
01748
01749 #ifdef _DEBUG
01750
01751 if(rows_number != columns_number)
01752 {
01753 std::ostringstream buffer;
01754
01755 buffer << "OpenNN Exception: Matrix Template.\n"
01756 << "sum_diagonal(const Type&) const.\n"
01757 << "Matrix must be square.\n";
01758
01759 throw std::logic_error(buffer.str());
01760 }
01761
01762 #endif
01763
01764 Matrix<Type> sum(*this);
01765
01766 for(unsigned int i = 0; i < rows_number; i++)
01767 {
01768 sum[i][i] += new_summing_value;
01769 }
01770
01771 return(sum);
01772 }
01773
01774
01775
01776
01780
01781 Matrix<Type> sum_diagonal(const Vector<Type>& new_summing_values) const
01782 {
01783
01784
01785 #ifdef _DEBUG
01786
01787 if(rows_number != columns_number)
01788 {
01789 std::ostringstream buffer;
01790
01791 buffer << "OpenNN Exception: Matrix Template.\n"
01792 << "sum_diagonal(const Vector<Type>&) const.\n"
01793 << "Matrix must be square.\n";
01794
01795 throw std::logic_error(buffer.str());
01796 }
01797
01798 unsigned int size = new_summing_values.size();
01799
01800 if(size != rows_number)
01801 {
01802 std::ostringstream buffer;
01803
01804 buffer << "OpenNN Exception: Matrix Template.\n"
01805 << "sum_diagonal(const Vector<Type>&) const.\n"
01806 << "Size must be equal to number of rows.\n";
01807
01808 throw std::logic_error(buffer.str());
01809 }
01810
01811 #endif
01812
01813 Matrix<Type> sum(*this);
01814
01815 for(unsigned int i = 0; i < rows_number; i++)
01816 {
01817 data[i][i] += new_summing_values[i];
01818 }
01819
01820 return(sum);
01821 }
01822
01823
01824
01825
01830
01831 void append_row(const Vector<Type>& new_row)
01832 {
01833 #ifdef _DEBUG
01834
01835 unsigned int size = new_row.size();
01836
01837 if(size != columns_number)
01838 {
01839 std::ostringstream buffer;
01840
01841 buffer << "OpenNN Exception: Matrix Template.\n"
01842 << "append_row(const Vector<Type>&) const.\n"
01843 << "Size must be equal to number of columns.\n";
01844
01845 throw std::logic_error(buffer.str());
01846 }
01847
01848 #endif
01849
01850 resize(rows_number+1, columns_number);
01851
01852 set_row(rows_number-1, new_row);
01853 }
01854
01855
01856
01857
01862
01863 void append_column(const Vector<Type>& new_column)
01864 {
01865 #ifdef _DEBUG
01866
01867 const unsigned int size = new_column.size();
01868
01869 if(size != columns_number)
01870 {
01871 std::ostringstream buffer;
01872
01873 buffer << "OpenNN Exception: Matrix Template.\n"
01874 << "append_column(const Vector<Type>&) const.\n"
01875 << "Size must be equal to number of columns.\n";
01876
01877 throw std::logic_error(buffer.str());
01878 }
01879
01880 #endif
01881
01882 resize(rows_number, columns_number+1);
01883
01884 set_column(columns_number-1, new_column);
01885 }
01886
01887
01888
01889
01893
01894 void subtract_row(const unsigned int& row_index)
01895 {
01896 #ifdef _DEBUG
01897
01898 if(row_index >= rows_number)
01899 {
01900 std::ostringstream buffer;
01901
01902 buffer << "OpenNN Exception: Matrix Template.\n"
01903 << "subtract_row(const unsigned int&) const.\n"
01904 << "Index of row must be less than number of rows.\n";
01905
01906 throw std::logic_error(buffer.str());
01907 }
01908 else if(rows_number < 2)
01909 {
01910 std::ostringstream buffer;
01911
01912 buffer << "OpenNN Exception: Matrix Template.\n"
01913 << "subtract_row(const unsigned int&) const.\n"
01914 << "Number of rows must be equal or greater than two.\n";
01915
01916 throw std::logic_error(buffer.str());
01917 }
01918
01919 #endif
01920
01921 Matrix<Type> new_matrix(rows_number-1, columns_number);
01922
01923 for(unsigned int i = 0; i < row_index; i++)
01924 {
01925 for(unsigned int j = 0; j < columns_number; j++)
01926 {
01927 new_matrix[i][j] = data[i][j];
01928 }
01929 }
01930
01931 for(unsigned int i = row_index+1; i < rows_number; i++)
01932 {
01933 for(unsigned int j = 0; j < columns_number; j++)
01934 {
01935 new_matrix[i-1][j] = data[i][j];
01936 }
01937 }
01938
01939 *this = new_matrix;
01940 }
01941
01942
01943
01944
01948
01949 void subtract_column(const unsigned int& column_index)
01950 {
01951 #ifdef _DEBUG
01952
01953 if(column_index >= columns_number)
01954 {
01955 std::ostringstream buffer;
01956
01957 buffer << "OpenNN Exception: Matrix Template.\n"
01958 << "subtract_column(const unsigned int&) const.\n"
01959 << "Index of column must be less than number of columns.\n";
01960
01961 throw std::logic_error(buffer.str());
01962 }
01963 else if(columns_number < 2)
01964 {
01965 std::ostringstream buffer;
01966
01967 buffer << "OpenNN Exception: Matrix Template.\n"
01968 << "subtract_column(const unsigned int&) const.\n"
01969 << "Number of columns must be equal or greater than two.\n";
01970
01971 throw std::logic_error(buffer.str());
01972 }
01973
01974 #endif
01975
01976 Matrix<Type> new_matrix(rows_number, columns_number-1);
01977
01978 for(unsigned int i = 0; i < rows_number; i++)
01979 {
01980 for(unsigned int j = 0; j < column_index; j++)
01981 {
01982 new_matrix[i][j] = data[i][j];
01983 }
01984 }
01985
01986 for(unsigned int i = 0; i < rows_number; i++)
01987 {
01988 for(unsigned int j = column_index+1; j < columns_number; j++)
01989 {
01990 new_matrix[i][j-1] = data[i][j];
01991 }
01992 }
01993
01994 *this = new_matrix;
01995 }
01996
01997
01998
01999
02002
02003 Matrix<Type> get_assembly_columns(const Matrix<Type>& other_matrix) const
02004 {
02005 #ifdef _DEBUG
02006
02007 const unsigned int other_rows_number = other_matrix.get_rows_number();
02008
02009 if(other_rows_number != rows_number)
02010 {
02011 std::ostringstream buffer;
02012
02013 buffer << "OpenNN Exception: Matrix Template.\n"
02014 << "Matrix<Type> get_assembly_columns(const Matrix<Type>&) const method.\n"
02015 << "Number of rows of other matrix (" << other_rows_number << ") must be equal to number of rows of this matrix (" << rows_number << ").\n";
02016
02017 throw std::logic_error(buffer.str());
02018 }
02019
02020 #endif
02021
02022 const unsigned int other_columns_number = other_matrix.get_columns_number();
02023
02024 Matrix<Type> assembly(rows_number, columns_number + other_columns_number);
02025
02026 for(unsigned int i = 0; i < rows_number; i++)
02027 {
02028 for(unsigned int j = 0; j < columns_number; j++)
02029 {
02030 assembly[i][j] = data[i][j];
02031 }
02032 for(unsigned int j = 0; j < other_columns_number; j++)
02033 {
02034 assembly[i][columns_number+j] = other_matrix[i][j];
02035 }
02036 }
02037
02038 return(assembly);
02039 }
02040
02041
02042
02043
02046
02047 void initialize(const Type& value) const
02048 {
02049 for(unsigned int i = 0; i < rows_number; i++)
02050 {
02051 for(unsigned int j = 0; j < columns_number; j++)
02052 {
02053 data[i][j] = value;
02054 }
02055 }
02056 }
02057
02058
02059
02060
02062
02063 void initialize_uniform(void) const
02064 {
02065 for(unsigned int i = 0; i < rows_number; i++)
02066 {
02067 for(unsigned int j = 0; j < columns_number; j++)
02068 {
02069 data[i][j] = calculate_random_uniform(-1.0, 1.0);
02070 }
02071 }
02072 }
02073
02074
02075
02076
02081
02082 void initialize_uniform(const double& minimum, double maximum) const
02083 {
02084
02085
02086 #ifdef _DEBUG
02087
02088 if(minimum > maximum)
02089 {
02090 std::ostringstream buffer;
02091
02092 buffer << "OpenNN Exception: Matrix Template.\n"
02093 << "void initialize_uniform(const double&, const double&) const method.\n"
02094 << "Minimum value must be less or equal than maximum value.\n";
02095
02096 throw std::logic_error(buffer.str());
02097 }
02098
02099 #endif
02100
02101 for(unsigned int i = 0; i < rows_number; i++)
02102 {
02103 for(unsigned int j = 0; j < columns_number; j++)
02104 {
02105 data[i][j] = calculate_random_uniform(minimum, maximum);
02106 }
02107 }
02108 }
02109
02110
02111
02112
02117
02118 void initialize_uniform(const Matrix<double>& minimum, const Matrix<double>& maximum) const
02119 {
02120
02121
02122 #ifdef _DEBUG
02123
02124 if(minimum > maximum)
02125 {
02126 std::ostringstream buffer;
02127
02128 buffer << "OpenNN Exception: Matrix Template.\n"
02129 << "void initialize_uniform(const Matrix<double>&, const Matrix<double>&) const method.\n"
02130 << "Minimum values must be less or equal than their respective maximum values.\n";
02131
02132 throw std::logic_error(buffer.str());
02133 }
02134
02135 #endif
02136
02137 for(unsigned int i = 0; i < rows_number; i++)
02138 {
02139 for(unsigned int j = 0; j < columns_number; j++)
02140 {
02141 data[i][j] = calculate_random_uniform(minimum[i][j], maximum[i][j]);
02142 }
02143 }
02144 }
02145
02146
02147
02148
02151
02152 void initialize_normal(void) const
02153 {
02154 for(unsigned int i = 0; i < rows_number; i++)
02155 {
02156 for(unsigned int j = 0; j < columns_number; j++)
02157 {
02158 data[i][j] = calculate_random_normal(0.0, 1.0);
02159 }
02160 }
02161 }
02162
02163
02164
02165
02170
02171 void initialize_normal(const double& mean, double standard_deviation) const
02172 {
02173
02174
02175 #ifdef _DEBUG
02176
02177 if(standard_deviation < 0.0)
02178 {
02179 std::ostringstream buffer;
02180
02181 buffer << "OpenNN Exception: Matrix Template.\n"
02182 << "void initialize_normal(const double&, const double&) const method.\n"
02183 << "Standard deviation must be equal or greater than zero.\n";
02184
02185 throw std::logic_error(buffer.str());
02186 }
02187
02188 #endif
02189
02190 for(unsigned int i = 0; i < rows_number; i++)
02191 {
02192 for(unsigned int j = 0; j < columns_number; j++)
02193 {
02194 data[i][j] = calculate_random_normal(mean, standard_deviation);
02195 }
02196 }
02197 }
02198
02199
02200
02201
02206
02207 void initialize_normal(const Matrix<double>& mean, const Matrix<double>& standard_deviation) const
02208 {
02209
02210
02211 #ifdef _DEBUG
02212
02213 if(standard_deviation < 0.0)
02214 {
02215 std::ostringstream buffer;
02216
02217 buffer << "OpenNN Exception: Matrix Template.\n"
02218 << "void initialize_normal(const Matrix<double>&, const Matrix<double>&) const method.\n"
02219 << "Standard deviations must be equal or greater than zero.\n";
02220
02221 throw std::logic_error(buffer.str());
02222 }
02223
02224 #endif
02225
02226 for(unsigned int i = 0; i < rows_number; i++)
02227 {
02228 for(unsigned int j = 0; j < columns_number; j++)
02229 {
02230 data[i][j] = calculate_random_uniform(mean[i][j], standard_deviation[i][j]);
02231 }
02232 }
02233 }
02234
02235
02236
02237
02240
02241 void initialize_identity(void) const
02242 {
02243
02244
02245 #ifdef _DEBUG
02246
02247 if(rows_number != columns_number)
02248 {
02249 std::ostringstream buffer;
02250
02251 std::cout << "OpenNN Exception: Matrix Template.\n"
02252 << "initialize_identity(void) const method.\n"
02253 << "Matrix must be square.\n";
02254
02255 throw std::logic_error(buffer.str());
02256 }
02257
02258 #endif
02259
02260 for(unsigned int i = 0; i < rows_number; i++)
02261 {
02262 for(unsigned int j = 0; j < columns_number; j++)
02263 {
02264 if(i==j)
02265 {
02266 data[i][j] = 1;
02267 }
02268 else
02269 {
02270 data[i][j] = 0;
02271 }
02272 }
02273 }
02274 }
02275
02276
02277
02278
02281
02282 void initialize_diagonal(const Type& value) const
02283 {
02284
02285
02286 #ifdef _DEBUG
02287
02288 if(rows_number != columns_number)
02289 {
02290 std::ostringstream buffer;
02291
02292 std::cout << "OpenNN Exception: Matrix Template.\n"
02293 << "initialize_diagonal(const Type&) const method.\n"
02294 << "Matrix must be square.\n";
02295
02296 throw std::logic_error(buffer.str());
02297 }
02298
02299 #endif
02300
02301 for(unsigned int i = 0; i < rows_number; i++)
02302 {
02303 for(unsigned int j = 0; j < columns_number; j++)
02304 {
02305 if(i==j)
02306 {
02307 data[i][j] = value;
02308 }
02309 else
02310 {
02311 data[i][j] = 0;
02312 }
02313 }
02314 }
02315 }
02316
02317
02318
02319
02322
02323 double calculate_trace(void) const
02324 {
02325
02326
02327 #ifdef _DEBUG
02328
02329 if(!is_squared())
02330 {
02331 std::ostringstream buffer;
02332
02333 buffer << "OpenNN Exception: Matrix template.\n"
02334 << "double calculate_trace(void) const method.\n"
02335 << "Matrix is not square.\n";
02336
02337 throw std::logic_error(buffer.str());
02338 }
02339
02340 #endif
02341
02342 double trace = 0.0;
02343
02344 for(unsigned int i = 0; i < rows_number; i++)
02345 {
02346 trace += data[i][i];
02347 }
02348
02349 return(trace);
02350 }
02351
02352
02353
02354
02357
02358 Vector<double> calculate_mean(void) const
02359 {
02360
02361
02362 #ifdef _DEBUG
02363
02364 if(rows_number == 0)
02365 {
02366 std::ostringstream buffer;
02367
02368 buffer << "OpenNN Exception: Matrix template.\n"
02369 << "Vector<double> calculate_mean(void) const method.\n"
02370 << "Number of rows must be greater than one.\n";
02371
02372 throw std::logic_error(buffer.str());
02373 }
02374
02375 #endif
02376
02377
02378
02379 Vector<double> mean(columns_number, 0.0);
02380
02381 for(unsigned int j = 0; j < columns_number; j++)
02382 {
02383 mean[j] = 0.0;
02384
02385 for(unsigned int i = 0; i < rows_number; i++)
02386 {
02387 mean[j] += data[i][j];
02388 }
02389
02390 mean[j] /= (double)rows_number;
02391 }
02392
02393 return(mean);
02394 }
02395
02396
02397
02398
02402
02403 Vector<double> calculate_mean(const Vector<unsigned int>& column_indices) const
02404 {
02405 const unsigned int column_indices_size = column_indices.size();
02406
02407 unsigned int column_index;
02408
02409
02410
02411 Vector<double> mean(column_indices_size, 0.0);
02412
02413 for(unsigned int j = 0; j < column_indices_size; j++)
02414 {
02415 column_index = column_indices[j];
02416
02417 mean[j] = 0.0;
02418
02419 for(unsigned int i = 0; i < rows_number; i++)
02420 {
02421 mean[j] += data[i][column_index];
02422 }
02423
02424 mean[j] /= (double)rows_number;
02425 }
02426
02427 return(mean);
02428 }
02429
02430
02431
02432
02437
02438 Vector<double> calculate_mean(const Vector<unsigned int>& row_indices, const Vector<unsigned int>& column_indices) const
02439 {
02440 const unsigned int row_indices_size = row_indices.size();
02441 const unsigned int column_indices_size = column_indices.size();
02442
02443
02444
02445 #ifdef _DEBUG
02446
02447
02448
02449 if(row_indices_size > rows_number)
02450 {
02451 std::ostringstream buffer;
02452
02453 buffer << "OpenNN Exception: Matrix template.\n"
02454 << "Vector<double> calculate_mean(const Vector<unsigned int>&, const Vector<unsigned int>&) const method.\n"
02455 << "Row indices size must be equal or less than rows number.\n";
02456
02457 throw std::logic_error(buffer.str());
02458 }
02459
02460 for(unsigned int i = 0; i < row_indices_size; i++)
02461 {
02462 if(row_indices[i] >= rows_number)
02463 {
02464 std::ostringstream buffer;
02465
02466 buffer << "OpenNN Exception: Matrix template.\n"
02467 << "Vector<double> calculate_mean(const Vector<unsigned int>&, const Vector<unsigned int>&) const method.\n"
02468 << "Row index " << i << " must be less than rows number.\n";
02469
02470 throw std::logic_error(buffer.str());
02471 }
02472 }
02473
02474 if(row_indices_size == 0)
02475 {
02476 std::ostringstream buffer;
02477
02478 buffer << "OpenNN Exception: Matrix template.\n"
02479 << "Vector<double> calculate_mean(const Vector<unsigned int>&, const Vector<unsigned int>&) const method.\n"
02480 << "Size of row indices must be greater than zero.\n";
02481
02482 throw std::logic_error(buffer.str());
02483 }
02484
02485
02486
02487 if(column_indices_size > columns_number)
02488 {
02489 std::ostringstream buffer;
02490
02491 buffer << "OpenNN Exception: Matrix template.\n"
02492 << "Vector<double> calculate_mean(const Vector<unsigned int>&, const Vector<unsigned int>&) const method.\n"
02493 << "Column indices size must be equal or less than columns number.\n";
02494
02495 throw std::logic_error(buffer.str());
02496 }
02497
02498 for(unsigned int i = 0; i < column_indices_size; i++)
02499 {
02500 if(column_indices[i] >= columns_number)
02501 {
02502 std::ostringstream buffer;
02503
02504 buffer << "OpenNN Exception: Matrix template.\n"
02505 << "Vector<double> calculate_mean(const Vector<unsigned int>&, const Vector<unsigned int>&) const method.\n"
02506 << "Column index " << i << " must be less than columns number.\n";
02507
02508 throw std::logic_error(buffer.str());
02509 }
02510 }
02511
02512 #endif
02513
02514 unsigned int row_index;
02515 unsigned int column_index;
02516
02517
02518
02519 Vector<double> mean(column_indices_size, 0.0);
02520
02521 for(unsigned int j = 0; j < column_indices_size; j++)
02522 {
02523 column_index = column_indices[j];
02524
02525 mean[j] = 0.0;
02526
02527 for(unsigned int i = 0; i < row_indices_size; i++)
02528 {
02529 row_index = row_indices[i];
02530
02531 mean[j] += data[row_index][column_index];
02532 }
02533
02534 mean[j] /= (double)rows_number;
02535 }
02536
02537 return(mean);
02538 }
02539
02540
02541
02542
02546
02547 Vector< Vector<double> > calculate_mean_standard_deviation(void) const
02548 {
02549
02550
02551 #ifdef _DEBUG
02552
02553 if(rows_number == 0)
02554 {
02555 std::ostringstream buffer;
02556
02557 buffer << "OpenNN Exception: Matrix template.\n"
02558 << "Vector<double> calculate_mean_standard_deviation(void) const method.\n"
02559 << "Number of rows must be greater than one.\n";
02560
02561 throw std::logic_error(buffer.str());
02562 }
02563
02564 #endif
02565
02566
02567
02568 Vector<double> mean(columns_number, 0.0);
02569
02570 for(unsigned int j = 0; j < columns_number; j++)
02571 {
02572 mean[j] = 0.0;
02573
02574 for(unsigned int i = 0; i < rows_number; i++)
02575 {
02576 mean[j] += data[i][j];
02577 }
02578
02579 mean[j] /= (double)rows_number;
02580 }
02581
02582
02583
02584 Vector<double> standard_deviation(columns_number, 0.0);
02585
02586 for(unsigned int j = 0; j < columns_number; j++)
02587 {
02588 standard_deviation[j] = 0.0;
02589
02590 for(unsigned int i = 0; i < rows_number; i++)
02591 {
02592 standard_deviation[j] += (data[i][j] - mean[j])*(data[i][j] - mean[j]);
02593 }
02594
02595 standard_deviation[j] = sqrt(standard_deviation[j]/(rows_number-1.0));
02596 }
02597
02598
02599
02600 Vector< Vector<double> > mean_standard_deviation(2);
02601
02602 mean_standard_deviation[0] = mean;
02603 mean_standard_deviation[1] = standard_deviation;
02604
02605 return(mean_standard_deviation);
02606 }
02607
02608
02609
02610
02615
02616 Vector< Vector<double> > calculate_mean_standard_deviation(const Vector<unsigned int>& column_indices) const
02617 {
02618 const unsigned int column_indices_size = column_indices.size();
02619
02620 unsigned int column_index;
02621
02622
02623
02624 Vector<double> mean(column_indices_size, 0.0);
02625
02626 for(unsigned int j = 0; j < column_indices_size; j++)
02627 {
02628 column_index = column_indices[j];
02629
02630 mean[j] = 0.0;
02631
02632 for(unsigned int i = 0; i < rows_number; i++)
02633 {
02634 mean[j] += data[i][column_index];
02635 }
02636
02637 mean[j] /= (double)rows_number;
02638 }
02639
02640
02641
02642 Vector<double> standard_deviation(column_indices_size, 0.0);
02643
02644 for(unsigned int j = 0; j < column_indices_size; j++)
02645 {
02646 column_index = column_indices[j];
02647
02648 standard_deviation[j] = 0.0;
02649
02650 for(unsigned int i = 0; i < rows_number; i++)
02651 {
02652 standard_deviation[j] += (data[i][column_index] - mean[j])*(data[i][column_index] - mean[j]);
02653 }
02654
02655 standard_deviation[j] = sqrt(standard_deviation[j]/(rows_number-1.0));
02656 }
02657
02658
02659
02660 Vector< Vector<double> > mean_standard_deviation(2);
02661
02662 mean_standard_deviation[0] = mean;
02663 mean_standard_deviation[1] = standard_deviation;
02664
02665 return(mean_standard_deviation);
02666 }
02667
02668
02669
02670
02676
02677 Vector< Vector<double> > calculate_mean_standard_deviation(const Vector<unsigned int>& row_indices, const Vector<unsigned int>& column_indices) const
02678 {
02679 const unsigned int row_indices_size = row_indices.size();
02680 const unsigned int column_indices_size = column_indices.size();
02681
02682
02683
02684 #ifdef _DEBUG
02685
02686
02687
02688 if(row_indices_size > rows_number)
02689 {
02690 std::ostringstream buffer;
02691
02692 buffer << "OpenNN Exception: Matrix template.\n"
02693 << "Vector<double> calculate_mean_standard_deviation(const Vector<unsigned int>&, const Vector<unsigned int>&) const method.\n"
02694 << "Row indices size must be equal or less than rows number.\n";
02695
02696 throw std::logic_error(buffer.str());
02697 }
02698
02699 for(unsigned int i = 0; i < row_indices_size; i++)
02700 {
02701 if(row_indices[i] >= rows_number)
02702 {
02703 std::ostringstream buffer;
02704
02705 buffer << "OpenNN Exception: Matrix template.\n"
02706 << "Vector<double> calculate_mean_standard_deviation(const Vector<unsigned int>&, const Vector<unsigned int>&) const method.\n"
02707 << "Row index " << i << " must be less than rows number.\n";
02708
02709 throw std::logic_error(buffer.str());
02710 }
02711 }
02712
02713 if(row_indices_size == 0)
02714 {
02715 std::ostringstream buffer;
02716
02717 buffer << "OpenNN Exception: Matrix template.\n"
02718 << "Vector<double> calculate_mean_standard_deviation(const Vector<unsigned int>&, const Vector<unsigned int>&) const method.\n"
02719 << "Size of row indices must be greater than zero.\n";
02720
02721 throw std::logic_error(buffer.str());
02722 }
02723
02724
02725
02726 if(column_indices_size > columns_number)
02727 {
02728 std::ostringstream buffer;
02729
02730 buffer << "OpenNN Exception: Matrix template.\n"
02731 << "Vector<double> calculate_mean_standard_deviation(const Vector<unsigned int>&, const Vector<unsigned int>&) const method.\n"
02732 << "Column indices size must be equal or less than columns number.\n";
02733
02734 throw std::logic_error(buffer.str());
02735 }
02736
02737 for(unsigned int i = 0; i < column_indices_size; i++)
02738 {
02739 if(column_indices[i] >= columns_number)
02740 {
02741 std::ostringstream buffer;
02742
02743 buffer << "OpenNN Exception: Matrix template.\n"
02744 << "Vector<double> calculate_mean_standard_deviation(const Vector<unsigned int>&, const Vector<unsigned int>&) const method.\n"
02745 << "Column index " << i << " must be less than columns number.\n";
02746
02747 throw std::logic_error(buffer.str());
02748 }
02749 }
02750
02751 #endif
02752
02753 unsigned int row_index;
02754 unsigned int column_index;
02755
02756
02757
02758 Vector<double> mean(column_indices_size, 0.0);
02759
02760 for(unsigned int j = 0; j < column_indices_size; j++)
02761 {
02762 column_index = column_indices[j];
02763
02764 mean[j] = 0.0;
02765
02766 for(unsigned int i = 0; i < row_indices_size; i++)
02767 {
02768 row_index = row_indices[i];
02769
02770 mean[j] += data[row_index][column_index];
02771 }
02772
02773 mean[j] /= (double)rows_number;
02774 }
02775
02776
02777
02778 Vector<double> standard_deviation(column_indices_size, 0.0);
02779
02780 for(unsigned int j = 0; j < column_indices_size; j++)
02781 {
02782 column_index = column_indices[j];
02783
02784 standard_deviation[j] = 0.0;
02785
02786 for(unsigned int i = 0; i < row_indices_size; i++)
02787 {
02788 row_index = row_indices[i];
02789
02790 standard_deviation[j] += (data[row_index][column_index] - mean[j])*(data[row_index][column_index] - mean[j]);
02791 }
02792
02793 standard_deviation[j] = sqrt(standard_deviation[j]/(rows_number-1.0));
02794 }
02795
02796
02797
02798 Vector< Vector<double> > mean_standard_deviation(2);
02799
02800 mean_standard_deviation[0] = mean;
02801 mean_standard_deviation[1] = standard_deviation;
02802
02803 return(mean_standard_deviation);
02804 }
02805
02806
02807
02808
02812
02813 Vector< Vector<Type> > calculate_minimum_maximum(void) const
02814 {
02815 Vector< Vector<Type> > minimum_maximum(2);
02816
02817 Vector<Type> minimum(columns_number, 1.0e99);
02818 Vector<Type> maximum(columns_number, -1.0e99);
02819
02820 for(unsigned int j = 0; j < columns_number; j++)
02821 {
02822 for(unsigned int i = 0; i < rows_number; i++)
02823 {
02824 if(data[i][j] < minimum[j])
02825 {
02826 minimum[j] = data[i][j];
02827 }
02828
02829 if(data[i][j] > maximum[j])
02830 {
02831 maximum[j] = data[i][j];
02832 }
02833 }
02834 }
02835
02836
02837
02838 minimum_maximum[0] = minimum;
02839 minimum_maximum[1] = maximum;
02840
02841 return(minimum_maximum);
02842 }
02843
02844
02845
02846
02851
02852 Vector< Vector<Type> > calculate_minimum_maximum(const Vector<unsigned int>& column_indices) const
02853 {
02854 const unsigned int column_indices_size = column_indices.size();
02855
02856 #ifdef _DEBUG
02857
02858 for(unsigned int i = 0; i < column_indices_size; i++)
02859 {
02860 if(column_indices[i] >= columns_number)
02861 {
02862 std::ostringstream buffer;
02863
02864 buffer << "OpenNN Exception: Matrix template."
02865 << "Vector<Type> calculate_minimum_maximum(const Vector<unsigned int>&) const method.\n"
02866 << "Index of column must be less than number of columns.\n";
02867
02868 throw std::logic_error(buffer.str());
02869 }
02870 }
02871
02872 #endif
02873
02874 unsigned int column_index;
02875
02876 Vector<Type> minimum(column_indices_size, 1.0e99);
02877 Vector<Type> maximum(column_indices_size, -1.0e99);
02878
02879 for(unsigned int j = 0; j < column_indices_size; j++)
02880 {
02881 column_index = column_indices[j];
02882
02883 for(unsigned int i = 0; i < rows_number; i++)
02884 {
02885 if(data[i][column_index] < minimum[j])
02886 {
02887 minimum[j] = data[i][column_index];
02888 }
02889
02890 if(data[i][column_index] > maximum[j])
02891 {
02892 maximum[j] = data[i][column_index];
02893 }
02894 }
02895 }
02896
02897
02898
02899 Vector< Vector<Type> > minimum_maximum(2);
02900
02901 minimum_maximum[0] = minimum;
02902 minimum_maximum[1] = maximum;
02903
02904 return(minimum_maximum);
02905 }
02906
02907
02908
02909
02915
02916 Vector< Vector<Type> > calculate_minimum_maximum(const Vector<unsigned int>& row_indices, const Vector<unsigned int>& column_indices) const
02917 {
02918 const unsigned int row_indices_size = row_indices.size();
02919 const unsigned int column_indices_size = column_indices.size();
02920
02921 Vector<Type> minimum(column_indices_size, 1.0e99);
02922 Vector<Type> maximum(column_indices_size, -1.0e99);
02923
02924 unsigned int row_index;
02925 unsigned int column_index;
02926
02927 for(unsigned int j = 0; j < column_indices_size; j++)
02928 {
02929 column_index = column_indices[j];
02930
02931 for(unsigned int i = 0; i < row_indices_size; i++)
02932 {
02933 row_index = row_indices[i];
02934
02935 if(data[row_index][column_index] < minimum[j])
02936 {
02937 minimum[j] = data[row_index][column_index];
02938 }
02939
02940 if(data[row_index][column_index] > maximum[j])
02941 {
02942 maximum[j] = data[row_index][column_index];
02943 }
02944 }
02945 }
02946
02947
02948
02949 Vector< Vector<Type> > minimum_maximum(2);
02950
02951 minimum_maximum[0] = minimum;
02952 minimum_maximum[1] = maximum;
02953
02954 return(minimum_maximum);
02955 }
02956
02957
02958
02959
02966
02967 Vector< Vector<double> > calculate_statistics(void) const
02968 {
02969
02970
02971 #ifdef _DEBUG
02972
02973 if(rows_number == 0)
02974 {
02975 std::ostringstream buffer;
02976
02977 buffer << "OpenNN Exception: Matrix template.\n"
02978 << "Vector<double> calculate_statistics(void) const method.\n"
02979 << "Number of rows must be greater than one.\n";
02980
02981 throw std::logic_error(buffer.str());
02982 }
02983
02984 #endif
02985
02986 const Vector< Vector<double> > minimum_maximum = calculate_minimum_maximum();
02987 const Vector< Vector<double> > mean_standard_deviation = calculate_mean_standard_deviation();
02988
02989 return(minimum_maximum.get_assembly(mean_standard_deviation));
02990 }
02991
02992
02993
02994
03000
03001 Vector< Vector< Vector<Type> > > calculate_histogram(const unsigned int& bins_number) const
03002 {
03003 Vector< Vector< Vector<Type> > > histogram(columns_number);
03004
03005 Vector<Type> column(rows_number);
03006
03007 for(unsigned int i = 0; i < columns_number; i++)
03008 {
03009 column = arrange_column(i);
03010
03011 histogram[i] = column.calculate_histogram(bins_number);
03012 }
03013
03014 return(histogram);
03015 }
03016
03017
03018
03019
03024
03025 Vector< Vector< Vector<Type> > > calculate_histogram(void) const
03026 {
03027 Vector< Vector< Vector<Type> > > histogram(columns_number);
03028
03029 Vector<Type> column(rows_number);
03030
03031 for(unsigned int i = 0; i < columns_number; i++)
03032 {
03033 column = arrange_column(i);
03034
03035 histogram[i] = column.calculate_histogram();
03036 }
03037
03038 return(histogram);
03039 }
03040
03041
03042
03043
03049
03050 void scale_mean_standard_deviation(const Vector<double>& mean, const Vector<double>& standard_deviation) const
03051 {
03052 #ifdef _DEBUG
03053
03054 const unsigned int mean_size = mean.size();
03055
03056 if(mean_size != columns_number)
03057 {
03058 std::ostringstream buffer;
03059
03060 buffer << "OpenNN Exception: Matrix template."
03061 << "void scale_mean_standard_deviation(const Vector<double>&, const Vector<double>&) const method.\n"
03062 << "Size of mean vector must be equal to number of columns.\n";
03063
03064 throw std::logic_error(buffer.str());
03065 }
03066
03067 unsigned int standard_deviation_size = standard_deviation.size();
03068
03069 if(standard_deviation_size != columns_number)
03070 {
03071 std::ostringstream buffer;
03072
03073 buffer << "OpenNN Exception: Matrix template."
03074 << "void scale_mean_standard_deviation(const Vector<double>&, const Vector<double>&) const method.\n"
03075 << "Size of standard deviation vector must be equal to number of columns.\n";
03076
03077 throw std::logic_error(buffer.str());
03078 }
03079
03080 #endif
03081
03082
03083
03084 for(unsigned int j = 0; j < columns_number; j++)
03085 {
03086 if(standard_deviation[j] < 1e-99)
03087 {
03088 std::cout << "OpenNN Warning: Matrix class.\n"
03089 << "void scale_mean_standard_deviation(const Vector<double>&, const Vector<double>&) const method.\n"
03090 << "Standard deviation of column " << j << " is zero.\n"
03091 << "Those values won't be scaled.\n";
03092
03093 }
03094 else
03095 {
03096 for(unsigned int i = 0; i < rows_number; i++)
03097 {
03098 data[i][j] = (data[i][j] - mean[j])/standard_deviation[j];
03099 }
03100 }
03101 }
03102 }
03103
03104
03105
03106
03112
03113 void scale_minimum_maximum(const Vector<double>& minimum, const Vector<double>& maximum) const
03114 {
03115 #ifdef _DEBUG
03116
03117 const unsigned int minimum_size = minimum.size();
03118
03119 if(minimum_size != columns_number)
03120 {
03121 std::ostringstream buffer;
03122
03123 buffer << "OpenNN Exception: Matrix template."
03124 << "void scale_minimum_maximum(const Vector<double>&, const Vector<double>&) const method.\n"
03125 << "Size of minimum vector must be equal to number of columns.\n";
03126
03127 throw std::logic_error(buffer.str());
03128 }
03129
03130 unsigned int maximum_size = maximum.size();
03131
03132 if(maximum_size != columns_number)
03133 {
03134 std::ostringstream buffer;
03135
03136 buffer << "OpenNN Exception: Matrix template."
03137 << "void scale_minimum_maximum(const Vector<double>&, const Vector<double>&) const method.\n"
03138 << "Size of maximum vector must be equal to number of columns.\n";
03139
03140 throw std::logic_error(buffer.str());
03141 }
03142
03143 #endif
03144
03145
03146
03147 for(unsigned int j = 0; j < columns_number; j++)
03148 {
03149 if(maximum[j] - minimum[j] < 1e-99)
03150 {
03151 std::cout << "OpenNN Warning: Matrix class.\n"
03152 << "void scale_minimum_maximum(const Vector<double>&, const Vector<double>&) const method.\n"
03153 << "Minimum and maximum values of column " << j << " are equal.\n"
03154 << "Those values won't be scaled.\n";
03155
03156
03157 }
03158 else
03159 {
03160 for(unsigned int i = 0; i < rows_number; i++)
03161 {
03162 data[i][j] = 2.0*(data[i][j] - minimum[j])/(maximum[j]-minimum[j])-1.0;
03163 }
03164 }
03165 }
03166 }
03167
03168
03169
03170
03176
03177 void unscale_mean_standard_deviation(const Vector<double>& mean, const Vector<double>& standard_deviation) const
03178 {
03179 #ifdef _DEBUG
03180
03181 const unsigned int mean_size = mean.size();
03182
03183 if(mean_size != columns_number)
03184 {
03185 std::ostringstream buffer;
03186
03187 buffer << "OpenNN Exception: Matrix template."
03188 << "void unscale_mean_standard_deviation(const Vector<double>&, const Vector<double>&) const method.\n"
03189 << "Size of mean vector must be equal to number of columns.\n";
03190
03191 throw std::logic_error(buffer.str());
03192 }
03193
03194 const unsigned int standard_deviation_size = standard_deviation.size();
03195
03196 if(standard_deviation_size != columns_number)
03197 {
03198 std::ostringstream buffer;
03199
03200 buffer << "OpenNN Exception: Matrix template.\n"
03201 << "void unscale_mean_standard_deviation(const Vector<double>&, const Vector<double>&) const method.\n"
03202 << "Size of standard deviation vector must be equal to number of columns.\n";
03203
03204 throw std::logic_error(buffer.str());
03205 }
03206
03207 #endif
03208
03209 for(unsigned int j = 0; j < columns_number; j++)
03210 {
03211 if(standard_deviation[j] < 1e-99)
03212 {
03213 std::cout << "OpenNN Warning: Matrix template.\n"
03214 << "void unscale_mean_standard_deviation(const Vector<double>&, const Vector<double>&) const method.\n"
03215 << "Standard deviation of column variable " << j << " is zero.\n"
03216 << "Those columns won't be scaled.\n";
03217
03218
03219 }
03220 else
03221 {
03222 for(unsigned int i = 0; i < rows_number; i++)
03223 {
03224 data[i][j] = data[i][j]*standard_deviation[j] + mean[j];
03225 }
03226 }
03227 }
03228 }
03229
03230
03231
03232
03238
03239 void unscale_minimum_maximum(const Vector<double>& minimum, const Vector<double>& maximum) const
03240 {
03241 #ifdef _DEBUG
03242
03243 const unsigned int minimum_size = minimum.size();
03244
03245 if(minimum_size != columns_number)
03246 {
03247 std::ostringstream buffer;
03248
03249 buffer << "OpenNN Exception: Matrix template."
03250 << "void unscale_minimum_maximum(const Vector<double>&, const Vector<double>&) const method.\n"
03251 << "Size of minimum vector must be equal to number of columns.\n";
03252
03253 throw std::logic_error(buffer.str());
03254 }
03255
03256 const unsigned int maximum_size = maximum.size();
03257
03258 if(maximum_size != columns_number)
03259 {
03260 std::ostringstream buffer;
03261
03262 buffer << "OpenNN Exception: Matrix template."
03263 << "void unscale_minimum_maximum(const Vector<double>&, const Vector<double>&) const method.\n"
03264 << "Size of maximum vector must be equal to number of columns.\n";
03265
03266 throw std::logic_error(buffer.str());
03267 }
03268
03269 #endif
03270
03271 for(unsigned int j = 0; j < columns_number; j++)
03272 {
03273 if(maximum[j] - minimum[j] < 1e-99)
03274 {
03275 std::cout << "OpenNN Warning: Matrix template.\n"
03276 << "void unscale_minimum_maximum(const Vector<double>&, const Vector<double>&) const method.\n"
03277 << "Minimum and maximum values of column " << j << " are equal.\n"
03278 << "Those columns won't be unscaled.\n";
03279
03280
03281 }
03282 else
03283 {
03284 for(unsigned int i = 0; i < rows_number; i++)
03285 {
03286 data[i][j] = 0.5*(data[i][j] + 1.0)*(maximum[j]-minimum[j]) + minimum[j];
03287 }
03288 }
03289 }
03290 }
03291
03292
03293
03294
03296
03297 Vector<unsigned int> calculate_minimal_indices(void) const
03298 {
03299 Type minimum = data[0][0];
03300 Vector<unsigned int> minimal_indices(2, 0);
03301
03302 for(unsigned int i = 0; i < rows_number; i++)
03303 {
03304 for(unsigned int j = 0; j < columns_number; j++)
03305 {
03306 if(data[i][j] < minimum)
03307 {
03308 minimum = data[i][j];
03309 minimal_indices[0] = i;
03310 minimal_indices[1] = j;
03311 }
03312 }
03313 }
03314
03315 return(minimal_indices);
03316 }
03317
03318
03319
03320
03322
03323 Vector<unsigned int> calculate_maximal_indices(void) const
03324 {
03325 Type maximum = data[0][0];
03326
03327 Vector<unsigned int> maximal_indices(2, 0);
03328
03329 for(unsigned int i = 0; i < rows_number; i++)
03330 {
03331 for(unsigned int j = 0; j < columns_number; j++)
03332 {
03333 if(data[i][j] > maximum)
03334 {
03335 maximum = data[i][j];
03336 maximal_indices[0] = i;
03337 maximal_indices[1] = j;
03338 }
03339 }
03340 }
03341
03342 return(maximal_indices);
03343 }
03344
03345
03346
03347
03352
03353 Vector< Vector<unsigned int> > calculate_minimal_maximal_indices(void) const
03354 {
03355 Type minimum = data[0][0];
03356 Type maximum = data[0][0];
03357
03358 Vector<unsigned int> minimal_indices(2, 0);
03359 Vector<unsigned int> maximal_indices(2, 0);
03360
03361 for(unsigned int i = 0; i < rows_number; i++)
03362 {
03363 for(unsigned int j = 0; j < columns_number; j++)
03364 {
03365 if(data[i][j] < minimum)
03366 {
03367 minimum = data[i][j];
03368 minimal_indices[0] = i;
03369 minimal_indices[1] = j;
03370 }
03371
03372 if(data[i][j] > maximum)
03373 {
03374 maximum = data[i][j];
03375 maximal_indices[0] = i;
03376 maximal_indices[1] = j;
03377 }
03378 }
03379 }
03380
03381 Vector< Vector<unsigned int> > minimal_maximal_indices(2);
03382 minimal_maximal_indices[0] = minimal_indices;
03383 minimal_maximal_indices[1] = maximal_indices;
03384
03385 return(minimal_maximal_indices);
03386 }
03387
03388
03389
03390
03393
03394 double calculate_sum_squared_error(const Matrix<double>& other_matrix) const
03395 {
03396
03397
03398 #ifdef _DEBUG
03399
03400 const unsigned int other_rows_number = other_matrix.get_rows_number();
03401
03402 if(other_rows_number != rows_number)
03403 {
03404 std::ostringstream buffer;
03405
03406 buffer << "OpenNN Exception: Matrix Template.\n"
03407 << "double calculate_sum_squared_error(const Matrix<double>&) const method.\n"
03408 << "Other number of rows must be equal to this number of rows.\n";
03409
03410 throw std::logic_error(buffer.str());
03411 }
03412
03413 const unsigned int other_columns_number = other_matrix.get_columns_number();
03414
03415 if(other_columns_number != columns_number)
03416 {
03417 std::ostringstream buffer;
03418
03419 buffer << "OpenNN Exception: Matrix Template.\n"
03420 << "double calculate_sum_squared_error(const Matrix<double>&) const method.\n"
03421 << "Other number of columns must be equal to this number of columns.\n";
03422
03423 throw std::logic_error(buffer.str());
03424 }
03425
03426 #endif
03427
03428 double sum_squared_error = 0.0;
03429
03430 for(unsigned int i = 0; i < rows_number; i++)
03431 {
03432 for(unsigned int j = 0; j < columns_number; j++)
03433 {
03434 sum_squared_error += (data[i][j] - other_matrix[i][j])*(data[i][j] - other_matrix[i][j]);
03435 }
03436 }
03437
03438 return(sum_squared_error);
03439 }
03440
03441
03442
03443
03447
03448 double calculate_sum_squared_error(const Vector<double>& vector) const
03449 {
03450
03451
03452 #ifdef _DEBUG
03453
03454 const unsigned int size = vector.size();
03455
03456 if(size != columns_number)
03457 {
03458 std::ostringstream buffer;
03459
03460 buffer << "OpenNN Exception: Matrix Template.\n"
03461 << "double calculate_sum_squared_error(const Vector<double>&) const method.\n"
03462 << "Size must be equal to number of columns.\n";
03463
03464 throw std::logic_error(buffer.str());
03465 }
03466
03467 #endif
03468
03469 double sum_squared_error = 0.0;
03470
03471 for(unsigned int i = 0; i < rows_number; i++)
03472 {
03473 for(unsigned int j = 0; j < columns_number; j++)
03474 {
03475 sum_squared_error += (data[i][j] - vector[j])*(data[i][j] - vector[j]);
03476 }
03477 }
03478
03479 return(sum_squared_error);
03480 }
03481
03482
03483
03484
03487
03488 Vector<double> calculate_rows_norm(void) const
03489 {
03490 Vector<Type> rows_norm(rows_number, 0.0);
03491
03492 for(unsigned int i = 0; i < rows_number; i++)
03493 {
03494 for(unsigned int j = 0; j < columns_number; j++)
03495 {
03496 rows_norm[i] += data[i][j]*data[i][j];
03497 }
03498
03499 rows_norm[i] = sqrt(rows_norm[i]);
03500 }
03501
03502 return(rows_norm);
03503 }
03504
03505
03506
03507
03509
03510 Matrix<Type> calculate_absolute_value(void) const
03511 {
03512 Matrix<Type> absolute_value(rows_number, columns_number);
03513
03514 for(unsigned int i = 0; i < rows_number; i++)
03515 {
03516 for(unsigned int j = 0; j < columns_number; j++)
03517 {
03518 if(data[i][j] > 0)
03519 {
03520 absolute_value[i][j] = data[i][j];
03521 }
03522 else
03523 {
03524 absolute_value[i][j] = -data[i][j];
03525 }
03526 }
03527 }
03528
03529 return(absolute_value);
03530 }
03531
03532
03533
03534
03535
03537
03538 Matrix<Type> calculate_transpose(void) const
03539 {
03540 Matrix<Type> transpose(columns_number, rows_number);
03541
03542 for(unsigned int i = 0; i < columns_number; i++)
03543 {
03544 for(unsigned int j = 0; j < rows_number; j++)
03545 {
03546 transpose[i][j] = data[j][i];
03547 }
03548 }
03549
03550 return(transpose);
03551 }
03552
03553
03554
03555
03557
03558 Type calculate_determinant(void) const
03559 {
03560
03561
03562 #ifdef _DEBUG
03563
03564 if(rows_number != columns_number)
03565 {
03566 std::ostringstream buffer;
03567
03568 buffer << "OpenNN Exception: Matrix Template.\n"
03569 << "calculate_determinant(void) const method.\n"
03570 << "Matrix must be square.\n";
03571
03572 throw std::logic_error(buffer.str());
03573 }
03574
03575 #endif
03576
03577 Type determinant = 0;
03578
03579 if(rows_number == 0)
03580 {
03581 std::ostringstream buffer;
03582
03583 buffer << "OpenNN Exception: Matrix Template.\n"
03584 << "calculate_determinant(void) const method.\n"
03585 << "Size of matrix is zero.\n";
03586
03587 throw std::logic_error(buffer.str());
03588 }
03589 else if(rows_number == 1)
03590 {
03591 determinant = data[0][0];
03592 }
03593 else if(rows_number == 2)
03594 {
03595 determinant = data[0][0]*data[1][1] - data[1][0]*data[0][1];
03596 }
03597 else
03598 {
03599 unsigned int sign;
03600
03601 for(unsigned int row_index = 0; row_index < rows_number; row_index++)
03602 {
03603
03604
03605 Matrix<Type> sub_matrix(rows_number-1, columns_number-1);
03606
03607 for(unsigned int i = 1; i < rows_number; i++)
03608 {
03609 unsigned int j2 = 0;
03610
03611 for(unsigned int j = 0; j < columns_number; j++)
03612 {
03613 if(j == row_index)
03614 {
03615 continue;
03616 }
03617
03618 sub_matrix[i-1][j2] = data[i][j];
03619
03620 j2++;
03621 }
03622 }
03623
03624 sign = (unsigned int)(pow(-1.0, row_index+2.0));
03625
03626 determinant += sign*data[0][row_index]*sub_matrix.calculate_determinant();
03627 }
03628 }
03629
03630 return(determinant);
03631 }
03632
03633
03634
03635
03637
03638 Matrix<Type> calculate_cofactor(void) const
03639 {
03640 Matrix<double> cofactor(rows_number, columns_number);
03641
03642 Matrix<double> c(rows_number-1, columns_number-1);
03643
03644 for(unsigned int j = 0; j < rows_number; j++)
03645 {
03646 for(unsigned int i = 0; i < rows_number; i++)
03647 {
03648
03649
03650 unsigned int i1 = 0;
03651
03652 for(unsigned int ii = 0; ii < rows_number; ii++)
03653 {
03654 if(ii == i)
03655 {
03656 continue;
03657 }
03658
03659 unsigned int j1 = 0;
03660
03661 for(unsigned int jj = 0; jj < rows_number; jj++)
03662 {
03663 if(jj == j)
03664 {
03665 continue;
03666 }
03667
03668 c[i1][j1] = data[ii][jj];
03669 j1++;
03670 }
03671 i1++;
03672 }
03673
03674 double determinant = c.calculate_determinant();
03675
03676 cofactor[i][j] = pow(-1.0, i+j+2.0)*determinant;
03677 }
03678 }
03679
03680 return(cofactor);
03681 }
03682
03683
03684
03685
03688
03689 Matrix<Type> calculate_inverse(void) const
03690 {
03691
03692
03693 #ifdef _DEBUG
03694
03695 if(rows_number != columns_number)
03696 {
03697 std::ostringstream buffer;
03698
03699 buffer << "OpenNN Exception: Matrix Template.\n"
03700 << "calculate_inverse(void) const method.\n"
03701 << "Matrix must be square.\n";
03702
03703 throw std::logic_error(buffer.str());
03704 }
03705
03706 #endif
03707
03708 const double determinant = calculate_determinant();
03709
03710 if(determinant == 0.0)
03711 {
03712 std::ostringstream buffer;
03713
03714 buffer << "OpenNN Exception: Matrix Template.\n"
03715 << "calculate_inverse(void) const method.\n"
03716 << "Matrix is singular.\n";
03717
03718 throw std::logic_error(buffer.str());
03719 }
03720
03721
03722
03723 const Matrix<double> cofactor = calculate_cofactor();
03724
03725
03726
03727 const Matrix<double> adjoint = cofactor.calculate_transpose();
03728
03729
03730
03731 const Matrix<double> inverse = adjoint/determinant;
03732
03733 return(inverse);
03734 }
03735
03736
03737
03738
03741
03742 inline Matrix<Type> operator + (const Type& scalar) const
03743 {
03744 Matrix<Type> sum(rows_number, columns_number);
03745
03746 for(unsigned int i = 0; i < rows_number; i++)
03747 {
03748 for(unsigned int j = 0; j < columns_number; j++)
03749 {
03750 sum[i][j] = data[i][j] + scalar;
03751 }
03752 }
03753
03754 return(sum);
03755 }
03756
03757
03758
03759
03762
03763 inline Matrix<Type> operator + (const Vector<Type>& vector) const
03764 {
03765
03766
03767 #ifdef _DEBUG
03768
03769 const unsigned int size = vector.size();
03770
03771 if(size != rows_number)
03772 {
03773 std::ostringstream buffer;
03774
03775 buffer << "OpenNN Exception: Matrix Template.\n"
03776 << "Matrix<Type> operator + (const Vector<Type>&) const.\n"
03777 << "Size of vector must be equal to number of rows.\n";
03778
03779 throw std::logic_error(buffer.str());
03780 }
03781
03782 #endif
03783
03784 Matrix<Type> sum(rows_number, columns_number);
03785
03786 for(unsigned int i = 0; i < rows_number; i++)
03787 {
03788 for(unsigned int j = 0; j < columns_number; j++)
03789 {
03790 sum[i][j] = data[i][j] + vector[i];
03791 }
03792 }
03793
03794 return(sum);
03795 }
03796
03797
03798
03799
03802
03803 inline Matrix<Type> operator + (const Matrix<Type>& other_matrix) const
03804 {
03805
03806
03807 #ifdef _DEBUG
03808
03809 const unsigned int other_rows_number = other_matrix.get_rows_number();
03810 const unsigned int other_columns_number = other_matrix.get_columns_number();
03811
03812 if(other_rows_number != rows_number || other_columns_number != columns_number)
03813 {
03814 std::ostringstream buffer;
03815
03816 buffer << "OpenNN Exception: Matrix Template.\n"
03817 << "Matrix<Type> operator + (const Matrix<Type>&) const.\n"
03818 << "Sizes of other matrix (" << other_rows_number << "," << other_columns_number << ") must be the same than sizes of this matrix (" << rows_number << "," << columns_number << ").\n";
03819
03820 throw std::logic_error(buffer.str());
03821 }
03822
03823 #endif
03824
03825 Matrix<Type> sum(rows_number, columns_number);
03826
03827 for(unsigned int i = 0; i < rows_number; i++)
03828 {
03829 for(unsigned int j = 0; j < columns_number; j++)
03830 {
03831 sum[i][j] = data[i][j] + other_matrix[i][j];
03832 }
03833 }
03834
03835 return(sum);
03836 }
03837
03838
03839
03840
03843
03844 inline Matrix<Type> operator - (const Type& scalar) const
03845 {
03846 Matrix<Type> difference(rows_number, columns_number);
03847
03848 for(unsigned int i = 0; i < rows_number; i++)
03849 {
03850 for(unsigned int j = 0; j < columns_number; j++)
03851 {
03852 difference[i][j] = data[i][j] - scalar;
03853 }
03854 }
03855
03856 return(difference);
03857 }
03858
03859
03860
03861
03864
03865 inline Matrix<Type> operator - (const Vector<Type>& vector) const
03866 {
03867
03868
03869 #ifdef _DEBUG
03870
03871 const unsigned int size = vector.size();
03872
03873 if(size != rows_number)
03874 {
03875 std::ostringstream buffer;
03876
03877 buffer << "OpenNN Exception: Matrix Template.\n"
03878 << "Matrix<Type> operator - (const Vector<Type>&) const.\n"
03879 << "Size of vector must be equal to number of rows.\n";
03880
03881 throw std::logic_error(buffer.str());
03882 }
03883
03884 #endif
03885
03886 Matrix<Type> difference(rows_number, columns_number);
03887
03888 for(unsigned int i = 0; i < rows_number; i++)
03889 {
03890 for(unsigned int j = 0; j < columns_number; j++)
03891 {
03892 difference[i][j] = data[i][j] - vector[i];
03893 }
03894 }
03895
03896 return(difference);
03897 }
03898
03899
03900
03901
03904
03905 inline Matrix<Type> operator - (const Matrix<Type>& other_matrix) const
03906 {
03907
03908
03909 #ifdef _DEBUG
03910
03911 const unsigned int other_rows_number = other_matrix.get_rows_number();
03912 const unsigned int other_columns_number = other_matrix.get_columns_number();
03913
03914 if(other_rows_number != rows_number || other_columns_number != columns_number)
03915 {
03916 std::ostringstream buffer;
03917
03918 buffer << "OpenNN Exception: Matrix Template.\n"
03919 << "Matrix<Type> operator - (const Matrix<Type>&) const method.\n"
03920 << "Sizes of other matrix (" << other_rows_number << "," << other_columns_number << ") must be equal to sizes of this matrix ("<< rows_number << "," << columns_number <<").\n";
03921
03922 throw std::logic_error(buffer.str());
03923 }
03924
03925 #endif
03926
03927 Matrix<Type> difference(rows_number, columns_number);
03928
03929 for(unsigned int i = 0; i < rows_number; i++)
03930 {
03931 for(unsigned int j = 0; j < columns_number; j++)
03932 {
03933 difference[i][j] = data[i][j] - other_matrix[i][j];
03934 }
03935 }
03936
03937 return(difference);
03938 }
03939
03940
03941
03942
03945
03946 inline Matrix<Type> operator * (const Type& scalar) const
03947 {
03948 Matrix<Type> product(rows_number, columns_number);
03949
03950 for(unsigned int i = 0; i < rows_number; i++)
03951 {
03952 for(unsigned int j = 0; j < columns_number; j++)
03953 {
03954 product[i][j] = data[i][j]*scalar;
03955 }
03956 }
03957
03958 return(product);
03959 }
03960
03961
03962
03963
03966
03967 inline Matrix<Type> operator * (const Vector<Type>& vector) const
03968 {
03969
03970
03971 #ifdef _DEBUG
03972
03973 const unsigned int size = vector.size();
03974
03975 if(size != rows_number)
03976 {
03977 std::ostringstream buffer;
03978
03979 buffer << "OpenNN Exception: Matrix Template.\n"
03980 << "Matrix<Type> operator * (const Vector<Type>&) const method.\n"
03981 << "Vector size (" << size << ") must be equal to number of matrix rows (" << rows_number << ").\n";
03982
03983 throw std::logic_error(buffer.str());
03984 }
03985
03986 #endif
03987
03988 Matrix<Type> product(rows_number, columns_number);
03989
03990 for(unsigned int i = 0; i < rows_number; i++)
03991 {
03992 for(unsigned int j = 0; j < columns_number; j++)
03993 {
03994 product[i][j] = data[i][j]*vector[i];
03995 }
03996 }
03997
03998 return(product);
03999 }
04000
04001
04002
04003
04006
04007 inline Matrix<Type> operator * (const Matrix<Type>& other_matrix) const
04008 {
04009
04010
04011 #ifdef _DEBUG
04012
04013 const unsigned int other_rows_number = other_matrix.get_rows_number();
04014 const unsigned int other_columns_number = other_matrix.get_columns_number();
04015
04016 if(other_rows_number != rows_number || other_columns_number != columns_number)
04017 {
04018 std::ostringstream buffer;
04019
04020 buffer << "OpenNN Exception: Matrix Template.\n"
04021 << "Matrix<Type> operator * (const Matrix<Type>&) const method.\n"
04022 << "Sizes of other matrix (" << other_rows_number << "," << other_columns_number << ") must be equal to sizes of this matrix (" << rows_number << "," << columns_number << ").\n";
04023
04024 throw std::logic_error(buffer.str());
04025 }
04026
04027 #endif
04028
04029 Matrix<Type> product(rows_number, columns_number);
04030
04031 for(unsigned int i = 0; i < rows_number; i++)
04032 {
04033 for(unsigned int j = 0; j < columns_number; j++)
04034 {
04035 product[i][j] = data[i][j]*other_matrix[i][j];
04036 }
04037 }
04038
04039 return(product);
04040 }
04041
04042
04043
04044
04047
04048 inline Matrix<Type> operator / (const Type& scalar) const
04049 {
04050 Matrix<Type> cocient(rows_number, columns_number);
04051
04052 for(unsigned int i = 0; i < rows_number; i++)
04053 {
04054 for(unsigned int j = 0; j < columns_number; j++)
04055 {
04056 cocient[i][j] = data[i][j]/scalar;
04057 }
04058 }
04059
04060 return(cocient);
04061 }
04062
04063
04064
04065
04068
04069 inline Matrix<Type> operator / (const Vector<Type>& vector) const
04070 {
04071
04072
04073 #ifdef _DEBUG
04074
04075 const unsigned int size = vector.size();
04076
04077 if(size != columns_number)
04078 {
04079 std::ostringstream buffer;
04080
04081 buffer << "OpenNN Exception: Matrix Template.\n"
04082 << "Matrix<Type> operator / (const Vector<Type>&) const.\n"
04083 << "Size of vector must be equal to number of columns.\n";
04084
04085 throw std::logic_error(buffer.str());
04086 }
04087
04088 #endif
04089
04090 Matrix<Type> cocient(rows_number, columns_number);
04091
04092 for(unsigned int i = 0; i < rows_number; i++)
04093 {
04094 for(unsigned int j = 0; j < columns_number; j++)
04095 {
04096 cocient[i][j] = data[i][j]/vector[j];
04097 }
04098 }
04099
04100 return(cocient);
04101 }
04102
04103
04104
04105
04108
04109 inline Matrix<Type> operator / (const Matrix<Type>& other_matrix) const
04110 {
04111
04112
04113 #ifdef _DEBUG
04114
04115 const unsigned int other_rows_number = other_matrix.get_rows_number();
04116 const unsigned int other_columns_number = other_matrix.get_columns_number();
04117
04118 if(other_rows_number != rows_number || other_columns_number != columns_number)
04119 {
04120 std::ostringstream buffer;
04121
04122 buffer << "OpenNN Exception: Matrix Template.\n"
04123 << "Matrix<Type> operator / (const Matrix<Type>&) const method.\n"
04124 << "Both matrix sizes must be the same.\n";
04125
04126 throw std::logic_error(buffer.str());
04127 }
04128
04129 #endif
04130
04131 Matrix<Type> cocient(rows_number, columns_number);
04132
04133 for(unsigned int i = 0; i < rows_number; i++)
04134 {
04135 for(unsigned int j = 0; j < columns_number; j++)
04136 {
04137 cocient[i][j] = data[i][j]/other_matrix[i][j];
04138 }
04139 }
04140
04141 return(cocient);
04142 }
04143
04144
04145
04146
04149
04150 inline void operator += (const Type& value)
04151 {
04152 for(unsigned int i = 0; i < rows_number; i++)
04153 {
04154 for(unsigned int j = 0; j < columns_number; j++)
04155 {
04156 data[i][j] += value;
04157 }
04158 }
04159 }
04160
04161
04162
04163
04166
04167 inline void operator += (const Matrix<Type>& other_matrix)
04168 {
04169
04170
04171 #ifdef _DEBUG
04172
04173 const unsigned int other_rows_number = other_matrix.get_rows_number();
04174
04175 if(other_rows_number != rows_number)
04176 {
04177 std::ostringstream buffer;
04178
04179 buffer << "OpenNN Exception: Matrix Template.\n"
04180 << "void operator += (const Matrix<Type>&).\n"
04181 << "Both numbers of rows must be the same.\n";
04182
04183 throw std::logic_error(buffer.str());
04184 }
04185
04186 const unsigned int other_columns_number = other_matrix.get_columns_number();
04187
04188 if(other_columns_number != columns_number)
04189 {
04190 std::ostringstream buffer;
04191
04192 buffer << "OpenNN Exception: Matrix Template.\n"
04193 << "void operator += (const Matrix<Type>&).\n"
04194 << "Both numbers of columns must be the same.\n";
04195
04196 throw std::logic_error(buffer.str());
04197 }
04198
04199 #endif
04200
04201 for(unsigned int i = 0; i < rows_number; i++)
04202 {
04203 for(unsigned int j = 0; j < columns_number; j++)
04204 {
04205 data[i][j] += other_matrix[i][j];
04206 }
04207 }
04208 }
04209
04210
04211
04212
04215
04216 inline void operator -= (const Type& value)
04217 {
04218 for(unsigned int i = 0; i < rows_number; i++)
04219 {
04220 for(unsigned int j = 0; j < columns_number; j++)
04221 {
04222 data[i][j] -= value;
04223 }
04224 }
04225 }
04226
04227
04228
04229
04232
04233 inline void operator -= (const Matrix<Type>& other_matrix)
04234 {
04235
04236
04237 #ifdef _DEBUG
04238
04239 const unsigned int other_rows_number = other_matrix.get_rows_number();
04240
04241 if(other_rows_number != rows_number)
04242 {
04243 std::ostringstream buffer;
04244
04245 buffer << "OpenNN Exception: Matrix Template.\n"
04246 << "void operator -= (const Matrix<Type>&).\n"
04247 << "Both numbers of rows must be the same.\n";
04248
04249 throw std::logic_error(buffer.str());
04250 }
04251
04252 const unsigned int other_columns_number = other_matrix.get_columns_number();
04253
04254 if(other_columns_number != columns_number)
04255 {
04256 std::ostringstream buffer;
04257
04258 buffer << "OpenNN Exception: Matrix Template.\n"
04259 << "void operator -= (const Matrix<Type>&).\n"
04260 << "Both numbers of columns must be the same.\n";
04261
04262 throw std::logic_error(buffer.str());
04263 }
04264
04265 #endif
04266
04267 for(unsigned int i = 0; i < rows_number; i++)
04268 {
04269 for(unsigned int j = 0; j < columns_number; j++)
04270 {
04271 data[i][j] -= other_matrix[i][j];
04272 }
04273 }
04274 }
04275
04276
04277
04278
04281
04282 inline void operator *= (const Type& value)
04283 {
04284 for(unsigned int i = 0; i < rows_number; i++)
04285 {
04286 for(unsigned int j = 0; j < columns_number; j++)
04287 {
04288 data[i][j] *= value;
04289 }
04290 }
04291 }
04292
04293
04294
04295
04298
04299 inline void operator *= (const Matrix<Type>& other_matrix)
04300 {
04301
04302
04303 #ifdef _DEBUG
04304
04305 const unsigned int other_rows_number = other_matrix.get_rows_number();
04306
04307 if(other_size != size())
04308 {
04309 std::ostringstream buffer;
04310
04311 buffer << "OpenNN Exception: Matrix Template.\n"
04312 << "void operator *= (const Matrix<Type>&).\n"
04313 << "Both numbers of rows must be the same.\n";
04314
04315 throw std::logic_error(buffer.str());
04316 }
04317
04318 #endif
04319
04320 for(unsigned int i = 0; i < rows_number; i++)
04321 {
04322 for(unsigned int j = 0; j < columns_number; j++)
04323 {
04324 data[i][j] *= other_matrix[i][j];
04325 }
04326 }
04327 }
04328
04329
04330
04331
04334
04335 inline void operator /= (const Type& value)
04336 {
04337 for(unsigned int i = 0; i < rows_number; i++)
04338 {
04339 for(unsigned int j = 0; j < columns_number; j++)
04340 {
04341 data[i][j] /= value;
04342 }
04343 }
04344 }
04345
04346
04347
04348
04351
04352 inline void operator /= (const Matrix<Type>& other_matrix)
04353 {
04354
04355
04356 #ifdef _DEBUG
04357
04358 const unsigned int other_rows_number = other_matrix.get_rows_number();
04359
04360 if(other_rows_number != rows_number)
04361 {
04362 std::ostringstream buffer;
04363
04364 buffer << "OpenNN Exception: Matrix Template.\n"
04365 << "void operator /= (const Matrix<Type>&).\n"
04366 << "Both numbers of rows must be the same.\n";
04367
04368 throw std::logic_error(buffer.str());
04369 }
04370
04371 const unsigned int other_columns_number = other_matrix.get_columns_number();
04372
04373 if(other_columns_number != columns_number)
04374 {
04375 std::ostringstream buffer;
04376
04377 buffer << "OpenNN Exception: Matrix Template.\n"
04378 << "void operator /= (const Matrix<Type>&).\n"
04379 << "Both numbers of columns must be the same.\n";
04380
04381 throw std::logic_error(buffer.str());
04382 }
04383
04384 #endif
04385
04386 for(unsigned int i = 0; i < rows_number; i++)
04387 {
04388 for(unsigned int j = 0; j < columns_number; j++)
04389 {
04390 data[i][j] /= other_matrix[i][j];
04391 }
04392 }
04393 }
04394
04395
04396
04397
04401
04402 Vector<Type> dot(const Vector<Type>& vector) const
04403 {
04404
04405
04406 #ifdef _DEBUG
04407
04408 const unsigned int size = vector.size();
04409
04410 if(size != columns_number)
04411 {
04412 std::ostringstream buffer;
04413
04414 buffer << "OpenNN Exception: Matrix Template.\n"
04415 << "Vector<Type> dot(const Vector<Type>&) const method.\n"
04416 << "Vector size must be equal to matrix number of columns.\n";
04417
04418 throw std::logic_error(buffer.str());
04419 }
04420
04421 #endif
04422
04423
04424
04425 Vector<Type> product(rows_number);
04426
04427 for(unsigned int i = 0; i < rows_number; i++)
04428 {
04429 product[i] = 0;
04430
04431 for(unsigned int j = 0; j < columns_number; j++)
04432 {
04433 product[i] += vector[j]*data[i][j];
04434 }
04435 }
04436
04437 return(product);
04438 }
04439
04440
04441
04442
04446
04447 Matrix<Type> dot(const Matrix<Type>& other_matrix) const
04448 {
04449 unsigned int other_columns_number = other_matrix.get_columns_number();
04450
04451
04452
04453 #ifdef _DEBUG
04454
04455 const unsigned int other_rows_number = other_matrix.get_rows_number();
04456
04457 if(other_rows_number != columns_number)
04458 {
04459 std::ostringstream buffer;
04460
04461 buffer << "OpenNN Exception: Matrix Template.\n"
04462 << "Matrix<Type> dot(const Matrix<Type>&) const method.\n"
04463 << "The number of rows of the other matrix (" << other_rows_number << ") must be equal to the number of columns of this matrix (" << columns_number << ").\n";
04464
04465 throw std::logic_error(buffer.str());
04466 }
04467
04468 #endif
04469
04470 Matrix<Type> product(rows_number, other_columns_number, 0.0);
04471
04472 for(unsigned int i = 0; i < rows_number; i++)
04473 {
04474 for(unsigned int j = 0; j < other_columns_number; j++)
04475 {
04476 for(unsigned int k = 0; k < columns_number; k++)
04477 {
04478 product[i][j] += data[i][k]*other_matrix[k][j];
04479 }
04480 }
04481 }
04482
04483 return(product);
04484 }
04485
04486
04487
04488
04493
04494 Matrix<Type> direct(const Matrix<Type>& other_matrix) const
04495 {
04496 const unsigned int other_rows_number = other_matrix.get_rows_number();
04497 const unsigned int other_columns_number = other_matrix.get_columns_number();
04498
04499 const Matrix<Type> direct(rows_number*other_rows_number, columns_number*other_columns_number);
04500
04501 return(direct);
04502 }
04503
04504
04505
04507
04508 bool empty(void) const
04509 {
04510 if(rows_number == 0 && columns_number == 0)
04511 {
04512 return(true);
04513 }
04514 else
04515 {
04516 return(false);
04517 }
04518
04519 }
04520
04521
04522
04523
04524
04527
04528 bool is_square(void) const
04529 {
04530 if(rows_number == columns_number)
04531 {
04532 return(true);
04533 }
04534 else
04535 {
04536 return(false);
04537 }
04538
04539 }
04540
04541
04542
04543
04546
04547 bool is_symmetric(void) const
04548 {
04549
04550
04551 #ifdef _DEBUG
04552
04553 if(rows_number != columns_number)
04554 {
04555 std::ostringstream buffer;
04556
04557 buffer << "OpenNN Exception: Matrix Template.\n"
04558 << "bool is_symmetric(void) const method.\n"
04559 << "Matrix must be squared.\n";
04560
04561 throw std::logic_error(buffer.str());
04562 }
04563
04564 #endif
04565
04566 const Matrix<Type> transpose = calculate_transpose();
04567
04568 for(unsigned int i = 0; i < rows_number; i++)
04569 {
04570 for(unsigned int j = 0; j < columns_number; j++)
04571 {
04572 if(data[i][j] != transpose[i][j])
04573 {
04574 return(false);
04575 }
04576 }
04577 }
04578
04579 return(true);
04580 }
04581
04582
04583
04584
04587
04588
04589 bool is_antisymmetric(void) const
04590 {
04591
04592
04593 #ifdef _DEBUG
04594
04595 if(rows_number != columns_number)
04596 {
04597 std::ostringstream buffer;
04598
04599 buffer << "OpenNN Exception: Matrix Template.\n"
04600 << "bool is_antisymmetric(void) const method.\n"
04601 << "Matrix must be squared.\n";
04602
04603 throw std::logic_error(buffer.str());
04604 }
04605
04606 #endif
04607
04608 const Matrix<Type> transpose = calculate_transpose();
04609
04610 for(unsigned int i = 0; i < rows_number; i++)
04611 {
04612 for(unsigned int j = 0; j < columns_number; j++)
04613 {
04614 if(i != j && -data[i][j] != transpose[i][j])
04615 {
04616 return(false);
04617 }
04618 }
04619 }
04620
04621 return(true);
04622 }
04623
04624
04625
04626
04629
04630 bool is_diagonal(void) const
04631 {
04632
04633
04634 #ifdef _DEBUG
04635
04636 if(rows_number != columns_number)
04637 {
04638 std::ostringstream buffer;
04639
04640 buffer << "OpenNN Exception: Matrix Template.\n"
04641 << "bool is_diagonal(void) const method.\n"
04642 << "Matrix must be squared.\n";
04643
04644 throw std::logic_error(buffer.str());
04645 }
04646
04647 #endif
04648
04649 for(unsigned int i = 0; i < rows_number; i++)
04650 {
04651 for(unsigned int j = 0; j < columns_number; j++)
04652 {
04653 if(i != j && data[i][j] != 0)
04654 {
04655 return(false);
04656 }
04657 }
04658 }
04659
04660 return(true);
04661 }
04662
04663
04664
04665
04668
04669 bool is_scalar(void) const
04670 {
04671
04672
04673 #ifdef _DEBUG
04674
04675 if(rows_number != columns_number)
04676 {
04677 std::ostringstream buffer;
04678
04679 buffer << "OpenNN Exception: Matrix Template.\n"
04680 << "bool is_scalar(void) const method.\n"
04681 << "Matrix must be squared.\n";
04682
04683 throw std::logic_error(buffer.str());
04684 }
04685
04686 #endif
04687
04688
04689
04690 return(false);
04691 }
04692
04693
04696
04697 bool is_identity(void) const
04698 {
04699
04700
04701 #ifdef _DEBUG
04702
04703 if(rows_number != columns_number)
04704 {
04705 std::ostringstream buffer;
04706
04707 buffer << "OpenNN Exception: Matrix Template.\n"
04708 << "bool is_unity(void) const method.\n"
04709 << "Matrix must be squared.\n";
04710
04711 throw std::logic_error(buffer.str());
04712 }
04713
04714 #endif
04715
04716 for(unsigned int i = 0; i < rows_number; i++)
04717 {
04718 for(unsigned int j = 0; j < columns_number; j++)
04719 {
04720 if(i != j && data[i][j] != 0)
04721 {
04722 return(false);
04723 }
04724 else if(i == j && data[i][j] != 1)
04725 {
04726 return(false);
04727 }
04728 }
04729 }
04730
04731 return(true);
04732 }
04733
04734
04735
04736
04738
04739 void print(void) const
04740 {
04741 std::cout << *this;
04742 }
04743
04744
04745
04746
04750
04751 void load(const std::string& filename)
04752 {
04753 std::ifstream file(filename.c_str());
04754
04755 if(!file.is_open())
04756 {
04757 std::ostringstream buffer;
04758
04759 buffer << "OpenNN Exception: Matrix template.\n"
04760 << "void load(const std::string&) method.\n"
04761 << "Cannot open matrix data file.\n";
04762
04763 throw std::logic_error(buffer.str());
04764 }
04765
04766
04767
04768 std::string line;
04769
04770 std::getline(file, line);
04771
04772 if(line.empty())
04773 {
04774 set();
04775 }
04776 else
04777 {
04778 std::istringstream buffer(line);
04779
04780 std::istream_iterator<std::string> it(buffer);
04781 std::istream_iterator<std::string> end;
04782
04783 const std::vector<std::string> results(it, end);
04784
04785 const unsigned int new_columns_number = results.size();
04786
04787 unsigned int new_rows_number = 1;
04788
04789 while(file.good())
04790 {
04791 getline(file, line);
04792
04793 if(!line.empty())
04794 {
04795 new_rows_number++;
04796 }
04797 }
04798
04799 set(new_rows_number, new_columns_number);
04800
04801
04802
04803 file.clear();
04804 file.seekg(0, std::ios::beg);
04805
04806 for(unsigned int i = 0; i < rows_number; i++)
04807 {
04808 for(unsigned int j = 0; j < columns_number; j++)
04809 {
04810 file >> data[i][j];
04811 }
04812 }
04813 }
04814
04815
04816
04817 file.close();
04818 }
04819
04820
04821
04822
04825
04826 void save(const std::string& filename) const
04827 {
04828 std::ofstream file(filename.c_str());
04829
04830 if(!file.is_open())
04831 {
04832 std::ostringstream buffer;
04833
04834 buffer << "OpenNN Exception: Matrix template." << std::endl
04835 << "void save_data(const char*) method." << std::endl
04836 << "Cannot open matrix data file." << std::endl;
04837
04838 throw std::logic_error(buffer.str());
04839 }
04840
04841
04842
04843 for(unsigned int i = 0; i < rows_number; i++)
04844 {
04845 for(unsigned int j = 0; j < columns_number; j++)
04846 {
04847 file << data[i][j] << " ";
04848 }
04849
04850 file << std::endl;
04851 }
04852
04853
04854
04855 file.close();
04856 }
04857
04858
04859
04860
04864
04865 std::string to_string(void) const
04866 {
04867 std::ostringstream buffer;
04868
04869 buffer << *this;
04870
04871 return(buffer.str());
04872 }
04873
04874
04875
04876
04878
04879 Matrix<std::string> get_string_matrix(void) const
04880 {
04881 Matrix<std::string> string_matrix(rows_number, columns_number);
04882
04883 std::ostringstream buffer;
04884
04885 for(unsigned int i = 0; i < rows_number; i++)
04886 {
04887 for(unsigned int j = 0; j < columns_number; j++)
04888 {
04889 buffer.str("");
04890 buffer << (*this)[i][j];
04891
04892 string_matrix[i] = buffer.str();
04893 }
04894 }
04895
04896 return(string_matrix);
04897 }
04898
04899
04900
04901
04905
04906 Vector<Type> to_vector(void) const
04907 {
04908 Vector<Type> vector(rows_number*columns_number);
04909
04910 unsigned int index = 0;
04911
04912 for(unsigned int i = 0; i < rows_number; i++)
04913 {
04914 for(unsigned int j = 0; j < columns_number; j++)
04915 {
04916 vector[index] = data[i][j];
04917 index++;
04918 }
04919 }
04920
04921 return(vector);
04922 }
04923
04924
04925 private:
04926
04927
04928
04929 unsigned int rows_number;
04930
04932
04933 unsigned int columns_number;
04934
04936
04937 Type** data;
04938
04939
04940
04945
04946 double calculate_random_uniform(const double& minimum, double maximum) const
04947 {
04948 const double random = (double)rand()/(RAND_MAX+1.0);
04949
04950 const double random_uniform = minimum + (maximum-minimum)*random;
04951
04952 return(random_uniform);
04953 }
04954
04955
04956
04957
04962
04963 double calculate_random_normal(const double& mean, double standard_deviation) const
04964 {
04965 double random_uniform_1;
04966
04967 do
04968 {
04969 random_uniform_1 = (double)rand()/(RAND_MAX+1.0);
04970
04971 }while(random_uniform_1 == 0.0);
04972
04973 const double random_uniform_2 = (double)rand()/(RAND_MAX+1.0);
04974
04975
04976
04977 const double pi = 4.0*atan(1.0);
04978
04979 const double random_normal = mean + sqrt(-2.0*log(random_uniform_1))*sin(2.0*pi*random_uniform_2)*standard_deviation;
04980
04981 return(random_normal);
04982 }
04983
04984 };
04985
04986
04990
04991 template<typename Type>
04992 inline std::istream& operator >> (std::istream& is, Matrix<Type>& m)
04993 {
04994 const unsigned int rows_number = m.get_rows_number();
04995 const unsigned int columns_number = m.get_columns_number();
04996
04997 for(unsigned int i = 0; i < rows_number; i++)
04998 {
04999 for(unsigned int j = 0; j < columns_number; j++)
05000 {
05001 is >> m[i][j];
05002 }
05003 }
05004
05005 return(is);
05006 }
05007
05008
05009
05010
05014
05015 template<typename Type>
05016 inline std::ostream& operator << (std::ostream& os, const Matrix<Type>& m)
05017 {
05018 const unsigned int rows_number = m.get_rows_number();
05019 const unsigned int columns_number = m.get_columns_number();
05020
05021 for(unsigned int i = 0; i < rows_number; i++)
05022 {
05023 for(unsigned int j = 0; j < columns_number; j++)
05024 {
05025 os << m[i][j] << " ";
05026 }
05027
05028 os << std::endl;
05029 }
05030
05031 return(os);
05032 }
05033
05034
05035
05036
05037 template<typename Type>
05038 inline std::ostream& operator << (std::ostream& os, const Matrix< Vector<Type> >& m)
05039 {
05040 const unsigned int rows_number = m.get_rows_number();
05041 const unsigned int columns_number = m.get_columns_number();
05042
05043 for(unsigned int i = 0; i < rows_number; i++)
05044 {
05045 for(unsigned int j = 0; j < columns_number; j++)
05046 {
05047 os << "subvector_" << i << "_" << j << "\n"
05048 << m[i][j] << std::endl;
05049 }
05050 }
05051
05052 return(os);
05053 }
05054
05055
05056
05057
05058 template<typename Type>
05059 inline std::ostream& operator << (std::ostream& os, const Matrix< Matrix<Type> >& m)
05060 {
05061 const unsigned int rows_number = m.get_rows_number();
05062 const unsigned int columns_number = m.get_columns_number();
05063
05064 for(unsigned int i = 0; i < rows_number; i++)
05065 {
05066 for(unsigned int j = 0; j < columns_number; j++)
05067 {
05068 os << "submatrix_" << i << "_" << j << "\n"
05069 << m[i][j];
05070 }
05071 }
05072
05073 return(os);
05074 }
05075
05076 }
05077
05078 #endif
05079
05080
05081
05082
05083
05084
05085
05086
05087
05088
05089
05090
05091
05092
05093
05094
05095
05096
05097