00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 namespace CIMPL
00060 {
00061
00062
00063
00064
00065
00066 template< class T >
00067 Matrix<T>::Matrix()
00068 : ndims(2), length(0)
00069 {
00070 data = 0;
00071 xDim = 0;
00072 yDim = 0;
00073 columns = 0;
00074 clean = 0;
00075
00076 }
00077
00078
00079 template< class T >
00080 Matrix<T>::Matrix(const int rows, const int cols)
00081 {
00082 if(rows < 1 || cols < 1)
00083 {
00084 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00085 Utility::RunTimeError("All Matrix dimensions should be larger than 0!");
00086 }
00087
00088 ndims = 2;
00089 length = rows*cols;
00090 xDim = cols;
00091 yDim = rows;
00092 data = new (std::nothrow) T[length];
00093 Utility::CheckPointer(data);
00094
00095 columns = new (std::nothrow) Vector<T>[cols];
00096 Utility::CheckPointer(columns);
00097 for(int i=0; i<cols; i++)
00098 {
00099 columns[i].Set(&(data[i*rows]), rows);
00100 }
00101
00102 clean = new (std::nothrow) Cleaner<T>(data, columns);
00103 Utility::CheckPointer(clean);
00104
00105 }
00106
00107 template< class T >
00108 Matrix<T>::Matrix(const int rows, const int cols, T init)
00109 {
00110 if(rows < 1 || cols < 1)
00111 {
00112 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00113 Utility::RunTimeError("All Matrix dimensions should be larger than 0!");
00114 }
00115
00116 ndims = 2;
00117 length = rows*cols;
00118 xDim = cols;
00119 yDim = rows;
00120 data = new (std::nothrow) T[length];
00121 Utility::CheckPointer(data);
00122
00123 columns = new (std::nothrow) Vector<T>[cols];
00124 Utility::CheckPointer(columns);
00125 for(int i=0; i<cols; i++)
00126 {
00127 columns[i].Set(&(data[i*rows]), rows);
00128 }
00129
00130 clean = new (std::nothrow) Cleaner<T>(data, columns);
00131 Utility::CheckPointer(clean);
00132
00133 for(int i=0;i<length;i++)
00134 {
00135 data[i] = init;
00136 }
00137
00138 }
00139
00140
00141
00142
00143 template< class T >
00144 Matrix<T>::Matrix(string str)
00145 {
00146 if(str.substr(0,1) == "[" && str.substr(str.size()-1,1) == "]")
00147 {
00148 str = str.substr(1,str.size()-2);
00149 vector<string> row_strs = Utility::Split(str, ";");
00150 if(row_strs.size() < 1 )
00151 {
00152 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00153 Utility::RunTimeError("All Matrix dimensions should be larger than 0!");
00154 }
00155 int rsize = (int)row_strs.size();
00156
00157 vector<string> dummy = Utility::Split(row_strs[0]);
00158 if(dummy.size() < 1 )
00159 {
00160 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00161 Utility::RunTimeError("All Matrix dimensions should be larger than 0!");
00162 }
00163 int csize = (int)dummy.size();
00164 ndims = 2;
00165 length = rsize*csize;
00166 xDim = csize;
00167 yDim = rsize;
00168 data = new (std::nothrow) T[length];
00169 Utility::CheckPointer(data);
00170 columns = new (std::nothrow) Vector<T>[csize];
00171 Utility::CheckPointer(columns);
00172 for(int i=0; i<csize; i++)
00173 {
00174 columns[i].Set(&(data[i*rsize]), rsize);
00175 }
00176 clean = new (std::nothrow) Cleaner<T>(data, columns);
00177 Utility::CheckPointer(clean);
00178
00179 for(int i=0; i<rsize; i++)
00180 {
00181 vector<string> elem_strs = Utility::Split(row_strs[i]);
00182 if(elem_strs.size() != xDim )
00183 {
00184 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00185 Utility::RunTimeError("String parse error. Matrix dimensions are not consistent!");
00186 }
00187 for(int j=0; j<csize; j++)
00188 {
00189 columns[j].data[i] = (T)Utility::ToDouble(elem_strs[j]);
00190 }
00191 }
00192 }
00193 else
00194 {
00195 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00196 Utility::RunTimeError("Incorrect initialization. String cannot be parsed!");
00197 }
00198 }
00199
00200
00201
00202
00203
00204 template< class T >
00205 Matrix<T>::Matrix(Matrix<T> &m)
00206 {
00207 ndims = m.ndims;
00208 length = m.length;
00209 xDim = m.xDim;
00210 yDim = m.yDim;
00211
00212 data = m.data;
00213 columns = m.columns;
00214
00215 clean = new (std::nothrow) Cleaner<T>(data, columns);
00216 Utility::CheckPointer(clean);
00217
00218 }
00219
00220
00221
00222 template< class T >
00223 Matrix<T>::~Matrix()
00224 {
00225
00226 if(clean != 0)
00227 {
00228 delete clean;
00229 }
00230 }
00231
00232
00233 template< class T >
00234 void Matrix<T>::Clean()
00235 {
00236 if(clean != 0)
00237 {
00238 delete clean;
00239 data = 0;
00240 columns = 0;
00241 clean = 0;
00242 }
00243 }
00244
00245
00246 template< class T >
00247 void Matrix<T>::Set(const int rows, const int cols, T *_data)
00248 {
00249 if(rows < 1 || cols < 1)
00250 {
00251 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00252 Utility::RunTimeError("All Matrix dimensions should be larger than 0!");
00253 }
00254
00255 ndims = 2;
00256 length = rows*cols;
00257 xDim = cols;
00258 yDim = rows;
00259 data = _data;
00260
00261 columns = new (std::nothrow) Vector<T>[cols];
00262 Utility::CheckPointer(columns);
00263 for(int i=0; i<cols; i++)
00264 {
00265 columns[i].Set(&(data[i*rows]), rows);
00266 }
00267
00268 delete clean;
00269 clean = new (std::nothrow) Cleaner<T>(data, columns);
00270 Utility::CheckPointer(clean);
00271
00272 }
00273
00274 template< class T >
00275 inline const T* Matrix<T>::DataPtr()
00276 {
00277 return data;
00278 }
00279
00280 template< class T >
00281 inline T* Matrix<T>::Data()
00282 {
00283 return data;
00284 }
00285
00286
00287 template< class T >
00288 Matrix<T> Matrix<T>::Clone() const
00289 {
00290 Matrix<T> temp(Rows(), Columns());
00291
00292 memcpy(temp.data, data, sizeof(T)*temp.length);
00293
00294 return temp;
00295 }
00296
00297
00298 template< class T >
00299 void Matrix<T>::SwitchColumns(int i, int j)
00300 {
00301 T *temp_i = columns[i].data;
00302 columns[i].data = columns[j].data;
00303 columns[j].data = temp_i;
00304 }
00305
00306
00307 template< class T >
00308 void Matrix<T>::SyncData2Columns()
00309 {
00310 T* temp_data = new (std::nothrow) T[length];
00311 Utility::CheckPointer(temp_data);
00312
00313 for(int i=0; i<xDim; i++)
00314 {
00315 memcpy(&(temp_data[i*yDim]), columns[i].data, sizeof(T)*yDim);
00316 }
00317 data = temp_data;
00318
00319 columns = new (std::nothrow) Vector<T>[xDim];
00320 Utility::CheckPointer(columns);
00321
00322 for(int i=0; i<xDim; i++)
00323 {
00324 columns[i].data = &(data[i*yDim]);
00325 }
00326
00327 delete clean;
00328 clean = new (std::nothrow) Cleaner<T>(data, columns);
00329 Utility::CheckPointer(clean);
00330 }
00331
00332
00333 template< class T >
00334 Matrix<T> Matrix<T>::Slice(const int row1, const int row2, const int col1, const int col2)
00335 {
00336 if(row1<0 || row1>=Rows() || row2<0 || row2>=Rows())
00337 {
00338 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00339 Utility::RunTimeError("Index outside bounds!");
00340 }
00341 if(row1 > row2)
00342 {
00343 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00344 Utility::RunTimeError("Second slice parameter cannot be less than the first parameter!");
00345 }
00346
00347
00348 if(col1<0 || col1>=Columns() || col2<0 || col2>=Columns())
00349 {
00350 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00351 Utility::RunTimeError("Index outside bounds!");
00352 }
00353 if(col1 > col2)
00354 {
00355 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00356 Utility::RunTimeError("Second slice parameter cannot be less than the first parameter!");
00357 }
00358
00359
00360 Matrix<T> temp(row2-row1+1, col2-col1+1);
00361
00362 for(int j=col1; j<=col2; j++)
00363 {
00364 memcpy(temp[ j-col1 ].data, &(columns[j].data[row1]), sizeof(T)*temp.Rows());
00365 }
00366
00367 return temp;
00368 }
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 template< class T >
00417 Matrix<T> Matrix<T>::Slice(string str1, string str2)
00418 {
00419 int row1, row2, col1, col2;
00420 vector<string> bounds1 = Utility::Split(str1, ":");
00421 vector<string> bounds2 = Utility::Split(str2, ":");
00422
00423 if(str1 == ":")
00424 {
00425 row1 = 0;
00426 row2 = yDim-1;
00427 }
00428 else if(bounds1.size() == 2)
00429 {
00430 row1 = Utility::ToInt(bounds1[0]);
00431 row2 = Utility::ToInt(bounds1[1]);
00432 }
00433 else
00434 {
00435 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00436 Utility::RunTimeError("Incorrect slice argument. String cannot be parsed!");
00437 }
00438
00439 if(str2 == ":")
00440 {
00441 col1 = 0;
00442 col2 = xDim-1;
00443 }
00444 else if(bounds2.size() == 2)
00445 {
00446 col1 = Utility::ToInt(bounds2[0]);
00447 col2 = Utility::ToInt(bounds2[1]);
00448 }
00449 else
00450 {
00451 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00452 Utility::RunTimeError("Incorrect slice argument. String cannot be parsed!");
00453 }
00454
00455 return this->Slice(row1, row2, col1, col2);
00456
00457 }
00458
00459
00460
00461 template< class T >
00462 Vector<T> Matrix<T>::Slice(string str)
00463 {
00464 Vector<T> temp = (Vector<T>)*this;
00465 return temp.Slice(str);
00466 }
00467
00468
00469
00470
00471
00472 template< class T >
00473 inline const int Matrix<T>::Columns() const
00474 {
00475 return xDim;
00476 }
00477
00478 template< class T >
00479 inline const int Matrix<T>::Rows() const
00480 {
00481 return yDim;
00482 }
00483
00484
00485 template< class T >
00486 inline const int Matrix<T>::XDim() const
00487 {
00488 return xDim;
00489 }
00490
00491 template< class T >
00492 inline const int Matrix<T>::YDim() const
00493 {
00494 return yDim;
00495 }
00496
00497
00498
00499
00500 template< class T >
00501 inline const int Matrix<T>::Length() const
00502 {
00503 return length;
00504 }
00505
00506 template< class T >
00507 inline const int Matrix<T>::Numel() const
00508 {
00509 return length;
00510 }
00511
00512 template< class T >
00513 inline const int Matrix<T>::NDims() const
00514 {
00515 return ndims;
00516 }
00517
00518 template< class T >
00519 inline void Matrix<T>::Init(const T init)
00520 {
00521 for(int i=0;i<length;i++)
00522 {
00523 data[i] = init;
00524 }
00525 }
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541 template< class T >
00542 inline Matrix<T>& Matrix<T>::Rand(const double max)
00543 {
00544 if(!RandomGen::Initialized())
00545 {
00546 RandomGen::Initialize();
00547 }
00548 for(int i=0;i<length;i++)
00549 {
00550 data[i] = (T)(rand()/(double)RAND_MAX*max);
00551 }
00552 return *this;
00553 }
00554
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571 template< class T >
00572 Matrix<T> Matrix<T>::Rand(const int rows, const int cols, const double max)
00573 {
00574 Matrix<T> m(rows, cols);
00575 if(!RandomGen::Initialized())
00576 {
00577 RandomGen::Initialize();
00578 }
00579 for(int i=0;i<rows*cols;i++)
00580 {
00581 m.data[i] = (T)(rand()/(double)RAND_MAX*max);
00582 }
00583 return m;
00584 }
00585
00586
00587
00588 template< class T >
00589 void Matrix<T>::ReadFromMatrix(const Matrix<T>& m)
00590 {
00591 if(xDim < m.xDim || yDim < m.yDim)
00592 {
00593 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00594 Utility::RunTimeError("You can't read from a larger Matrix to a smaller Matrix!");
00595 }
00596
00597 for(int i=0;i<m.xDim;i++)
00598 {
00599 for(int j=0;j<m.yDim;j++)
00600 {
00601 columns[i].data[j] = m.columns[i].data[j];
00602 }
00603 }
00604
00605 }
00606
00607 template< class T >
00608 void Matrix<T>::ReadFromMatrix(const Matrix<T>& m, const int rowStart, const int colStart)
00609 {
00610 if(xDim < m.xDim+colStart || yDim < m.yDim+rowStart)
00611 {
00612 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00613 Utility::RunTimeError("You can't read from a larger Matrix (from the copy start point) to a smaller Matrix!");
00614 }
00615
00616 for(int i=0;i<m.xDim;i++)
00617 {
00618 for(int j=0;j<m.yDim;j++)
00619 {
00620 columns[i+colStart].data[j+rowStart] = m.columns[i].data[j];
00621 }
00622 }
00623
00624 }
00625
00626
00627
00628
00629
00630
00631
00632
00633
00634 template< class T >
00635 Matrix<T> Matrix<T>::Cat(int dimension, Matrix<T>& m1, Matrix<T>& m2)
00636 {
00637 Matrix<T> temp;
00638 if(dimension == 1)
00639 {
00640 if(m1.Columns() != m2.Columns())
00641 {
00642 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00643 Utility::RunTimeError("Matrix sizes are not compatible for concatenation!");
00644 }
00645
00646 temp = Matrix<T>(m1.Rows()+m2.Rows(), m1.Columns());
00647 temp.ReadFromMatrix(m1);
00648 temp.ReadFromMatrix(m2, m1.Rows(), 0);
00649
00650 }
00651 else if(dimension == 2)
00652 {
00653 if(m1.Rows() != m2.Rows())
00654 {
00655 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00656 Utility::RunTimeError("Matrix sizes are not compatible for concatenation!");
00657 }
00658
00659 temp = Matrix<T>(m1.Rows(), m1.Columns()+m2.Columns());
00660 temp.ReadFromMatrix(m1);
00661 temp.ReadFromMatrix(m2, 0, m1.Columns());
00662 }
00663 else
00664 {
00665 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00666 Utility::RunTimeError("dimension should be either 1 or 2 for matrices!");
00667 }
00668
00669 return temp;
00670 }
00671
00672 template< class T >
00673 Matrix<T> Matrix<T>::Cat(int dimension, Matrix<T>& m1, Vector<T>& m2)
00674 {
00675 return Matrix<T>::Cat(dimension, m1, (Matrix<T>)m2);
00676 }
00677
00678 template< class T >
00679 Matrix<T> Matrix<T>::Cat(int dimension, Vector<T>& m1, Matrix<T>& m2)
00680 {
00681 return Matrix<T>::Cat(dimension, (Matrix<T>)m1, m2);
00682 }
00683
00684 template< class T >
00685 Matrix<T> Matrix<T>::Cat(int dimension, Vector<T>& m1, Vector<T>& m2)
00686 {
00687 return Matrix<T>::Cat(dimension, (Matrix<T>)m1, (Matrix<T>)m2);
00688 }
00689
00690
00691 template< class T >
00692 Matrix<T> Matrix<T>::Ones(int side)
00693 {
00694 Matrix<T> temp(side,side,1);
00695 return temp;
00696 }
00697
00698
00699 template< class T >
00700 Matrix<T> Matrix<T>::Ones(int rows, int cols)
00701 {
00702 Matrix<T> temp(rows,cols,1);
00703 return temp;
00704 }
00705
00706 template< class T >
00707 Matrix<T> Matrix<T>::Zeros(int side)
00708 {
00709 Matrix<T> temp(side,side,0);
00710 return temp;
00711 }
00712
00713
00714 template< class T >
00715 Matrix<T> Matrix<T>::Zeros(int rows, int cols)
00716 {
00717 Matrix<T> temp(rows,cols,0);
00718 return temp;
00719 }
00720
00721
00722
00723
00724
00725
00726
00727 template< class T >
00728 bool Matrix<T>::IsSquare(Matrix<T>& m)
00729 {
00730 if(m.xDim == m.yDim)
00731 {
00732 return true;
00733 }
00734 else
00735 {
00736 return false;
00737 }
00738 }
00739
00740
00741
00742
00743
00745 template< class T >
00746 bool Matrix<T>::IsM2MCompatible(Matrix<T>& m1, Matrix<T>& m2)
00747 {
00748 if(m1.xDim == m2.yDim)
00749 {
00750 return true;
00751 }
00752 else
00753 {
00754 return false;
00755 }
00756 }
00757
00758
00760 template< class T >
00761 Matrix<T> Matrix<T>::MMultiply(Matrix<T>& m1, Matrix<T>& m2)
00762 {
00763 if(!Matrix<T>::IsM2MCompatible(m1, m2))
00764 {
00765 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00766 Utility::RunTimeError("Matrix sizes are not compatible for matrix multiplication!");
00767 }
00768
00769 Matrix<T> temp(m1.yDim, m2.xDim);
00770 temp.Init(0);
00771 for(int i=0; i<m1.yDim; i++)
00772 {
00773 for(int j=0; j<m2.xDim; j++)
00774 {
00775 for(int k = 0; k<m1.xDim; k++)
00776 {
00777 temp[j][i] += m1[k][i]*m2[j][k];
00778 }
00779 }
00780 }
00781
00782 return temp;
00783 }
00784
00785
00787 template< class T >
00788 Matrix<T> Matrix<T>::MMultiply(Matrix<T>& m1, Vector<T>& m2)
00789 {
00790 if(m1.xDim != m2.length)
00791 {
00792 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00793 Utility::RunTimeError("Matrix sizes are not compatible for matrix multiplication!");
00794 }
00795
00796 Matrix<T> temp(m1.yDim, 1);
00797 temp.Init(0);
00798 for(int i=0; i<m1.yDim; i++)
00799 {
00800 for(int j=0; j<m2.length; j++)
00801 {
00802 temp.data[i] += m1[j][i]*m2[j];
00803 }
00804 }
00805
00806 return temp;
00807 }
00808
00810 template< class T >
00811 Matrix<T> Matrix<T>::MMultiply(Vector<T>& m1, Matrix<T>& m2)
00812 {
00813 if(m2.Rows() != m1.length)
00814 {
00815 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00816 Utility::RunTimeError("Matrix sizes are not compatible for matrix multiplication!");
00817 }
00818
00819 Matrix<T> temp(1, m2.Columns());
00820 temp.Init(0);
00821 for(int i=0; i<m2.Columns(); i++)
00822 {
00823 for(int j=0; j<m1.length; j++)
00824 {
00825 temp.data[i] += m2[i][j]*m1[j];
00826 }
00827 }
00828
00829 return temp;
00830 }
00831
00832
00834 template< class T >
00835 Matrix<T> Matrix<T>::Transpose(Matrix<T>& m)
00836 {
00837 Matrix<T> temp(m.Columns(), m.Rows());
00838 for(int i=0; i<m.Rows(); i++)
00839 {
00840 for(int j=0; j<m.Columns(); j++)
00841 {
00842 temp[i][j] = m[j][i];
00843 }
00844 }
00845 return temp;
00846 }
00847
00848
00850 template< class T >
00851 Matrix<T>& Matrix<T>::Transpose()
00852 {
00853 if(!Matrix<T>::IsSquare(*this))
00854 {
00855 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00856 Utility::RunTimeError("Matrix is not square!");
00857 }
00858
00859 for(int i=0; i<yDim; i++)
00860 {
00861 for(int j=0; j<i; j++)
00862 {
00863 T temp = columns[j][i];
00864 columns[j][i] = columns[i][j];
00865 columns[i][j] = temp;
00866 }
00867 }
00868 return *this;
00869
00870 }
00871
00872
00874 template< class T >
00875 bool Matrix<T>::IsCompatible(Matrix<T>& m1, Matrix<T>& m2)
00876 {
00877 if(m1.xDim != m2.xDim || m1.yDim != m2.yDim)
00878 {
00879 return false;
00880 }
00881 else
00882 {
00883 return true;
00884 }
00885
00886 }
00887
00888
00889
00890
00891
00892
00894 template< class T >
00895 Matrix<int> Matrix<T>::And(Matrix<T>& m1, Matrix<T>& m2)
00896 {
00897 if(!Matrix<T>::IsCompatible(m1, m2))
00898 {
00899 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00900 Utility::RunTimeError("Matrix sizes are not compatible!");
00901 }
00902
00903 Matrix<int> temp(m1.yDim, m1.xDim);
00904 for(int i=0;i<temp.Length();i++)
00905 {
00906 temp.Data()[i] = (m1.data[i] != 0 && m2.data[i] != 0) ? 1 : 0;
00907 }
00908
00909 return temp;
00910 }
00911
00912
00914 template< class T >
00915 Matrix<int> Matrix<T>::Or(Matrix<T>& m1, Matrix<T>& m2)
00916 {
00917 if(!Matrix<T>::IsCompatible(m1, m2))
00918 {
00919 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00920 Utility::RunTimeError("Matrix sizes are not compatible!");
00921 }
00922
00923 Matrix<int> temp(m1.yDim, m1.xDim);
00924 for(int i=0;i<temp.Length();i++)
00925 {
00926 temp.Data()[i] = (m1.data[i] == 0 && m2.data[i] == 0) ? 0 : 1;
00927 }
00928
00929 return temp;
00930 }
00931
00933 template< class T >
00934 Matrix<int> Matrix<T>::Lt(Matrix<T>& m1, Matrix<T>& m2)
00935 {
00936 if(!Matrix<T>::IsCompatible(m1, m2))
00937 {
00938 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00939 Utility::RunTimeError("Matrix sizes are not compatible!");
00940 }
00941
00942 Matrix<int> temp(m1.yDim, m1.xDim);
00943 for(int i=0;i<temp.Length();i++)
00944 {
00945 temp.Data()[i] = (m1.data[i] < m2.data[i]) ? 1 : 0;
00946 }
00947
00948 return temp;
00949 }
00950
00952 template< class T >
00953 Matrix<int> Matrix<T>::Gt(Matrix<T>& m1, Matrix<T>& m2)
00954 {
00955 if(!Matrix<T>::IsCompatible(m1, m2))
00956 {
00957 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00958 Utility::RunTimeError("Matrix sizes are not compatible!");
00959 }
00960
00961 Matrix<int> temp(m1.yDim, m1.xDim);
00962 for(int i=0;i<temp.Length();i++)
00963 {
00964 temp.Data()[i] = (m1.data[i] > m2.data[i]) ? 1 : 0;
00965 }
00966
00967 return temp;
00968 }
00969
00971 template< class T >
00972 Matrix<int> Matrix<T>::Le(Matrix<T>& m1, Matrix<T>& m2)
00973 {
00974 if(!Matrix<T>::IsCompatible(m1, m2))
00975 {
00976 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00977 Utility::RunTimeError("Matrix sizes are not compatible!");
00978 }
00979
00980 Matrix<int> temp(m1.yDim, m1.xDim);
00981 for(int i=0;i<temp.Length();i++)
00982 {
00983 temp.Data()[i] = (m1.data[i] <= m2.data[i]) ? 1 : 0;
00984 }
00985
00986 return temp;
00987 }
00988
00990 template< class T >
00991 Matrix<int> Matrix<T>::Ge(Matrix<T>& m1, Matrix<T>& m2)
00992 {
00993 if(!Matrix<T>::IsCompatible(m1, m2))
00994 {
00995 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00996 Utility::RunTimeError("Matrix sizes are not compatible!");
00997 }
00998
00999 Matrix<int> temp(m1.yDim, m1.xDim);
01000 for(int i=0;i<temp.Length();i++)
01001 {
01002 temp.Data()[i] = (m1.data[i] >= m2.data[i]) ? 1 : 0;
01003 }
01004
01005 return temp;
01006 }
01007
01009 template< class T >
01010 Matrix<int> Matrix<T>::Eq(Matrix<T>& m1, Matrix<T>& m2)
01011 {
01012 if(!Matrix<T>::IsCompatible(m1, m2))
01013 {
01014 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01015 Utility::RunTimeError("Matrix sizes are not compatible!");
01016 }
01017
01018 Matrix<int> temp(m1.yDim, m1.xDim);
01019 for(int i=0;i<temp.Length();i++)
01020 {
01021 temp.Data()[i] = (m1.data[i] == m2.data[i]) ? 1 : 0;
01022 }
01023
01024 return temp;
01025 }
01026
01028 template< class T >
01029 Matrix<int> Matrix<T>::Ne(Matrix<T>& m1, Matrix<T>& m2)
01030 {
01031 if(!Matrix<T>::IsCompatible(m1, m2))
01032 {
01033 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01034 Utility::RunTimeError("Matrix sizes are not compatible!");
01035 }
01036
01037 Matrix<int> temp(m1.yDim, m1.xDim);
01038 for(int i=0;i<temp.Length();i++)
01039 {
01040 temp.Data()[i] = (m1.data[i] != m2.data[i]) ? 1 : 0;
01041 }
01042
01043 return temp;
01044 }
01045
01046
01047
01048
01049
01050
01051
01052
01053
01055 template< class T >
01056 Matrix<int> Matrix<T>::And(Matrix<T>& m1, T v)
01057 {
01058 Matrix<int> temp(m1.yDim, m1.xDim);
01059 for(int i=0;i<temp.Length();i++)
01060 {
01061 temp.Data()[i] = (m1.data[i] != 0 && v != 0) ? 1 : 0;
01062 }
01063
01064 return temp;
01065 }
01066
01067
01069 template< class T >
01070 Matrix<int> Matrix<T>::Or(Matrix<T>& m1, T v)
01071 {
01072 Matrix<int> temp(m1.yDim, m1.xDim);
01073 for(int i=0;i<temp.Length();i++)
01074 {
01075 temp.Data()[i] = (m1.data[i] == 0 && v == 0) ? 0 : 1;
01076 }
01077
01078 return temp;
01079 }
01080
01081
01083 template< class T >
01084 Matrix<int> Matrix<T>::Lt(Matrix<T>& m1, T v)
01085 {
01086 Matrix<int> temp(m1.yDim, m1.xDim);
01087 for(int i=0;i<temp.Length();i++)
01088 {
01089 temp.Data()[i] = (m1.data[i] < v) ? 1 : 0;
01090 }
01091
01092 return temp;
01093 }
01094
01095
01097 template< class T >
01098 Matrix<int> Matrix<T>::Gt(Matrix<T>& m1, T v)
01099 {
01100 Matrix<int> temp(m1.yDim, m1.xDim);
01101 for(int i=0;i<temp.Length();i++)
01102 {
01103 temp.Data()[i] = (m1.data[i] > v) ? 1 : 0;
01104 }
01105
01106 return temp;
01107 }
01108
01109
01111 template< class T >
01112 Matrix<int> Matrix<T>::Le(Matrix<T>& m1, T v)
01113 {
01114 Matrix<int> temp(m1.yDim, m1.xDim);
01115 for(int i=0;i<temp.Length();i++)
01116 {
01117 temp.Data()[i] = (m1.data[i] <= v) ? 1 : 0;
01118 }
01119
01120 return temp;
01121 }
01122
01123
01125 template< class T >
01126 Matrix<int> Matrix<T>::Ge(Matrix<T>& m1, T v)
01127 {
01128 Matrix<int> temp(m1.yDim, m1.xDim);
01129 for(int i=0;i<temp.Length();i++)
01130 {
01131 temp.Data()[i] = (m1.data[i] >= v) ? 1 : 0;
01132 }
01133
01134 return temp;
01135 }
01136
01137
01139 template< class T >
01140 Matrix<int> Matrix<T>::Eq(Matrix<T>& m1, T v)
01141 {
01142 Matrix<int> temp(m1.yDim, m1.xDim);
01143 for(int i=0;i<temp.Length();i++)
01144 {
01145 temp.Data()[i] = (m1.data[i] == v) ? 1 : 0;
01146 }
01147
01148 return temp;
01149 }
01150
01151
01153 template< class T >
01154 Matrix<int> Matrix<T>::Ne(Matrix<T>& m1, T v)
01155 {
01156 Matrix<int> temp(m1.yDim, m1.xDim);
01157 for(int i=0;i<temp.Length();i++)
01158 {
01159 temp.Data()[i] = (m1.data[i] != v) ? 1 : 0;
01160 }
01161
01162 return temp;
01163 }
01164
01165
01166
01167
01168
01169
01170
01171
01172
01173
01174
01175
01176
01177
01178
01179
01180 template< class T >
01181 Matrix<T> Matrix<T>::Add(Matrix<T>& m1, Matrix<T>& m2)
01182 {
01183 if(!Matrix<T>::IsCompatible(m1, m2))
01184 {
01185 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01186 Utility::RunTimeError("Matrix sizes are not compatible!");
01187 }
01188
01189 Matrix<T> temp(m1.yDim, m1.xDim);
01190 for(int i=0;i<temp.length;i++)
01191 {
01192 temp.data[i] = m1.data[i] + m2.data[i];
01193 }
01194
01195 return temp;
01196 }
01197
01198
01199 template< class T >
01200 Matrix<T> Matrix<T>::Subtract(Matrix<T>& m1, Matrix<T>& m2)
01201 {
01202 if(!Matrix<T>::IsCompatible(m1, m2))
01203 {
01204 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01205 Utility::RunTimeError("Matrix sizes are not compatible!");
01206 }
01207
01208 Matrix<T> temp(m1.yDim, m1.xDim);
01209 for(int i=0;i<temp.length;i++)
01210 {
01211 temp.data[i] = m1.data[i] - m2.data[i];
01212 }
01213
01214 return temp;
01215 }
01216
01217 template< class T >
01218 Matrix<T> Matrix<T>::Multiply(Matrix<T>& m1, Matrix<T>& m2)
01219 {
01220 if(!Matrix<T>::IsCompatible(m1, m2))
01221 {
01222 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01223 Utility::RunTimeError("Matrix sizes are not compatible!");
01224 }
01225
01226 Matrix<T> temp(m1.yDim, m1.xDim);
01227 for(int i=0;i<temp.length;i++)
01228 {
01229 temp.data[i] = m1.data[i] * m2.data[i];
01230 }
01231
01232 return temp;
01233 }
01234
01235 template< class T >
01236 Matrix<T> Matrix<T>::Divide(Matrix<T>& m1, Matrix<T>& m2)
01237 {
01238 if(!Matrix<T>::IsCompatible(m1, m2))
01239 {
01240 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01241 Utility::RunTimeError("Matrix sizes are not compatible!");
01242 }
01243
01244 Matrix<T> temp(m1.yDim, m1.xDim);
01245 for(int i=0;i<temp.length;i++)
01246 {
01247
01248 if(m2.data[i] != 0)
01249 {
01250 temp.data[i] = m1.data[i] / m2.data[i];
01251 }
01252 else
01253 {
01254 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01255 Utility::RunTimeError("Divide by zero in matrix division!");
01256 }
01257 }
01258
01259 return temp;
01260 }
01261
01262
01263
01264
01265
01266
01267 template< class T >
01268 Matrix<T> Matrix<T>::Add(Matrix<T>& m1, T v2)
01269 {
01270 Matrix<T> temp(m1.yDim, m1.xDim);
01271 for(int i=0;i<temp.length;i++)
01272 {
01273 temp.data[i] = m1.data[i] + v2;
01274 }
01275 return temp;
01276 }
01277
01278 template< class T >
01279 Matrix<T> Matrix<T>::Subtract(Matrix<T>& m1, T v2)
01280 {
01281 Matrix<T> temp(m1.yDim, m1.xDim);
01282 for(int i=0;i<temp.length;i++)
01283 {
01284 temp.data[i] = m1.data[i] - v2;
01285 }
01286 return temp;
01287 }
01288
01289 template< class T >
01290 Matrix<T> Matrix<T>::Subtract(T v2, Matrix<T>& m1)
01291 {
01292 Matrix<T> temp(m1.yDim, m1.xDim);
01293 for(int i=0;i<temp.length;i++)
01294 {
01295 temp.data[i] = v2 - m1.data[i];
01296 }
01297 return temp;
01298 }
01299
01300
01301 template< class T >
01302 Matrix<T> Matrix<T>::Multiply(Matrix<T>& m1, T v2)
01303 {
01304 Matrix<T> temp(m1.yDim, m1.xDim);
01305 for(int i=0;i<temp.length;i++)
01306 {
01307 temp.data[i] = m1.data[i] * v2;
01308 }
01309 return temp;
01310 }
01311
01312 template< class T >
01313 Matrix<T> Matrix<T>::Divide(Matrix<T>& m1, T v2)
01314 {
01315 if(v2 == 0)
01316 {
01317 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01318 Utility::RunTimeError("Divide by zero in matrix by value division!");
01319 }
01320
01321 Matrix<T> temp(m1.yDim, m1.xDim);
01322 for(int i=0;i<temp.length;i++)
01323 {
01324 temp.data[i] = m1.data[i] / v2;
01325 }
01326 return temp;
01327 }
01328
01329 template< class T >
01330 Matrix<T> Matrix<T>::Divide(T v2, Matrix<T>& m1)
01331 {
01332 Matrix<T> temp(m1.yDim, m1.xDim);
01333 for(int i=0;i<temp.length;i++)
01334 {
01335 if(m1.data[i] != 0)
01336 {
01337 temp.data[i] = v2 / m1.data[i];
01338 }
01339 else
01340 {
01341 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01342 Utility::RunTimeError("Divide by zero in value by matrix division!");
01343 }
01344 }
01345 return temp;
01346 }
01347
01348
01349
01350
01351
01352
01353 template< class T >
01354 Matrix<T>& Matrix<T>::Add(Matrix<T>& m)
01355 {
01356 if(!Matrix<T>::IsCompatible(*this, m))
01357 {
01358 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01359 Utility::RunTimeError("Matrix sizes are not compatible!");
01360 }
01361
01362 for(int i=0;i<this->length;i++)
01363 {
01364 this->data[i] += m.data[i];
01365 }
01366
01367 return *this;
01368 }
01369
01370 template< class T >
01371 Matrix<T>& Matrix<T>::Subtract(Matrix<T>& m)
01372 {
01373 if(!Matrix<T>::IsCompatible(*this, m))
01374 {
01375 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01376 Utility::RunTimeError("Matrix sizes are not compatible!");
01377 }
01378
01379 for(int i=0;i<this->length;i++)
01380 {
01381 this->data[i] -= m.data[i];
01382 }
01383
01384 return *this;
01385 }
01386
01387 template< class T >
01388 Matrix<T>& Matrix<T>::Multiply(Matrix<T>& m)
01389 {
01390 if(!Matrix<T>::IsCompatible(*this, m))
01391 {
01392 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01393 Utility::RunTimeError("Matrix sizes are not compatible!");
01394 }
01395
01396 for(int i=0;i<this->length;i++)
01397 {
01398 this->data[i] *= m.data[i];
01399 }
01400
01401 return *this;
01402 }
01403
01404 template< class T >
01405 Matrix<T>& Matrix<T>::Divide(Matrix<T>& m)
01406 {
01407 if(!Matrix<T>::IsCompatible(*this, m))
01408 {
01409 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01410 Utility::RunTimeError("Matrix sizes are not compatible!");
01411 }
01412
01413 for(int i=0;i<this->length;i++)
01414 {
01415 if(m.data[i] != 0)
01416 {
01417 this->data[i] /= m.data[i];
01418 }
01419 else
01420 {
01421 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01422 Utility::RunTimeError("Divide by zero in matrix division!");
01423 }
01424 }
01425
01426 return *this;
01427 }
01428
01429
01430
01431
01432
01433 template< class T >
01434 Matrix<T>& Matrix<T>::Add(T v)
01435 {
01436 for(int i=0;i<this->length;i++)
01437 {
01438 this->data[i] += v;
01439 }
01440 return *this;
01441 }
01442
01443 template< class T >
01444 Matrix<T>& Matrix<T>::Subtract(T v)
01445 {
01446 for(int i=0;i<this->length;i++)
01447 {
01448 this->data[i] -= v;
01449 }
01450 return *this;
01451 }
01452
01453 template< class T >
01454 Matrix<T>& Matrix<T>::Multiply(T v)
01455 {
01456 for(int i=0;i<this->length;i++)
01457 {
01458 this->data[i] *= v;
01459 }
01460 return *this;
01461 }
01462
01463 template< class T >
01464 Matrix<T>& Matrix<T>::Divide(T v)
01465 {
01466 if(v == 0)
01467 {
01468 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01469 Utility::RunTimeError("Divide by zero in matrix by value division!");
01470 }
01471
01472 for(int i=0;i<this->length;i++)
01473 {
01474 this->data[i] /= v;
01475 }
01476 return *this;
01477 }
01478
01479
01480
01481
01482
01483
01484
01485
01486
01487
01488
01489 template< class T >
01490 Matrix<T>& Matrix<T>::operator= (Matrix<T>& m)
01491 {
01492 ndims = m.ndims;
01493 length = m.length;
01494 xDim = m.xDim;
01495 yDim = m.yDim;
01496 data = m.data;
01497 columns = m.columns;
01498
01499 delete clean;
01500 clean = new (std::nothrow) Cleaner<T>(data, columns);
01501 Utility::CheckPointer(clean);
01502
01503
01504 return *this;
01505 }
01506
01507
01508 template< class T >
01509 Matrix<T>& Matrix<T>::operator= (Array<T>& m)
01510 {
01511 ndims = 2;
01512 xDim = 0;
01513 yDim = 0;
01514 data = 0;
01515 columns = 0;
01516
01517 if(m.ndims == 2){
01518 length = m.length;
01519 data = m.data;
01520 xDim = m.xDim;
01521 yDim = m.yDim;
01522
01523 columns = new (std::nothrow) Vector<T>[Columns()];
01524 Utility::CheckPointer(columns);
01525 for(int i=0; i<Columns(); i++)
01526 {
01527 columns[i].Set(&(data[i*Rows()]), Rows());
01528 }
01529
01530 delete clean;
01531 clean = new (std::nothrow) Cleaner<T>(data, columns);
01532 Utility::CheckPointer(clean);
01533 }
01534 else if(m.ndims > 0)
01535 {
01536 length = m.length;
01537 data = m.data;
01538 xDim = length;
01539 yDim = 1;
01540
01541 columns = new (std::nothrow) Vector<T>[1];
01542 Utility::CheckPointer(columns);
01543 columns[0].Set(&(data[0]),length);
01544
01545 delete clean;
01546 clean = new (std::nothrow) Cleaner<T>(data, columns);
01547 Utility::CheckPointer(clean);
01548
01549 Utility::Warning("Array (not of dimension 2) is converted to row Matrix. dimensionality information is lost.");
01550 }
01551
01552
01553 return *this;
01554 }
01555
01556 template< class T >
01557 Matrix<T>& Matrix<T>::operator= (Vector<T>& m)
01558 {
01559 *this = (Matrix<T>)m;
01560 return *this;
01561 }
01562
01563
01564 template< class T >
01565 Matrix<T>& Matrix<T>::operator= (SubMatrix<T>& m)
01566 {
01567 if(xDim != m.xDim || yDim != m.yDim)
01568 {
01569 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01570 Utility::RunTimeError("All Matrix and SubMatrix dimensions should agree!");
01571 }
01572 for(int i=0;i<m.xDim;i++)
01573 {
01574 for(int j=0;j<m.yDim;j++)
01575 {
01576 columns[i].data[j] = m[i][j];
01577 }
01578 }
01579
01580 return *this;
01581 }
01582
01583
01584
01585 template< class T >
01586 Matrix<T>& Matrix<T>::operator= (string str)
01587 {
01588 Matrix<T> temp(str);
01589 *this = temp;
01590 return *this;
01591 }
01592
01593
01594
01595
01596
01597
01599 template< class T >
01600 inline Matrix<T> Matrix<T>::operator+ ()
01601 {
01602 return *this;
01603 }
01604
01605
01607 template< class T >
01608 inline