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 Matrix<T> Matrix<T>::operator- ()
01609 {
01610 Matrix<T> temp(yDim, xDim);
01611 for(int i=0;i<length;i++)
01612 {
01613 temp.data[i] = - data[i];
01614 }
01615 return temp;
01616 }
01617
01618
01619
01620 template< class T >
01621 inline Matrix<int> Matrix<T>::operator! ()
01622 {
01623 Matrix<int> temp(yDim, xDim);
01624 for(int i=0;i<length;i++)
01625 {
01626 if(data[i] == 0)
01627 {
01628 temp.Data()[i] = 1;
01629 }
01630 else
01631 {
01632 temp.Data()[i] = 0;
01633 }
01634 }
01635 return temp;
01636 }
01637
01638
01640 template< class T >
01641 inline Matrix<T> Matrix<T>::operator~ ()
01642 {
01643 return Matrix<T>::Transpose(*this);
01644 }
01645
01646
01647
01648
01649
01651 template< class T >
01652 inline T& Matrix<T>::Elem(const int i)
01653 {
01654 if(i<0 || i>=length)
01655 {
01656 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01657 Utility::RunTimeError("Index outside bounds!");
01658 }
01659 return data[i];
01660 }
01661
01663 template< class T >
01664 inline T& Matrix<T>::ElemNC(const int i)
01665 {
01666 return data[i];
01667 }
01668
01669
01671 template< class T >
01672 inline T& Matrix<T>::Elem(const int j, const int i)
01673 {
01674 if(i<0 || i>=dims[0] || j<0 || j>=dims[1])
01675 {
01676 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01677 Utility::RunTimeError("Index outside bounds!");
01678 }
01679
01680 return columns[i].data[j];
01681
01682 }
01683
01684
01686 template< class T >
01687 inline T& Matrix<T>::ElemNC(const int j, const int i)
01688 {
01689 return columns[i].data[j];
01690
01691 }
01692
01693
01695 template< class T >
01696 inline T& Matrix<T>::Coor(const int i, const int j)
01697 {
01698 if(i<0 || i>=dims[0] || j<0 || j>=dims[1])
01699 {
01700 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01701 Utility::RunTimeError("Index outside bounds!");
01702 }
01703
01704 return columns[i].data[j];
01705
01706 }
01707
01708
01710 template< class T >
01711 inline T& Matrix<T>::CoorNC(const int i, const int j)
01712 {
01713 return columns[i].data[j];
01714
01715 }
01716
01717
01718
01719
01720
01722 template< class T >
01723 inline T& Matrix<T>::operator() (const int i)
01724 {
01725 if(i<0 || i>=length)
01726 {
01727 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01728 Utility::RunTimeError("Index outside bounds!");
01729 }
01730 return data[i];
01731 }
01732
01734 template< class T >
01735 inline T& Matrix<T>::operator() (const int j, const int i)
01736 {
01737 if(i<0 || i>=xDim || j<0 || j>=yDim)
01738 {
01739 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01740 Utility::RunTimeError("Index outside bounds!");
01741 }
01742
01743 return columns[i].data[j];
01744
01745 }
01746
01747
01749 template< class T >
01750 inline Vector<T>& Matrix<T>::operator[] (const int i)
01751 {
01752 return columns[i];
01753 }
01754
01755
01756
01757
01759
01760
01761
01762
01763
01764
01765
01766
01767
01768
01769
01770
01771
01772
01773
01774
01775
01776
01777
01778
01779
01780
01781
01782
01783
01784
01785
01786
01787
01788
01789
01790
01791
01792
01793
01794
01795
01796 template< class T >
01797 inline SubMatrix<T> Matrix<T>::operator() (const int row1, const int row2, const int col1, const int col2)
01798 {
01799 if(row1<0 || row1>=YDim() || row2<0 || row2>=YDim())
01800 {
01801 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01802 Utility::RunTimeError("Index outside bounds!");
01803 }
01804 if(row1 > row2)
01805 {
01806 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01807 Utility::RunTimeError("Second slice parameter cannot be less than the first parameter!");
01808 }
01809
01810
01811 if(col1<0 || col1>=XDim() || col2<0 || col2>=XDim())
01812 {
01813 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01814 Utility::RunTimeError("Index outside bounds!");
01815 }
01816 if(col1 > col2)
01817 {
01818 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01819 Utility::RunTimeError("Second slice parameter cannot be less than the first parameter!");
01820 }
01821
01822
01823 SubMatrix<T> temp;
01824 temp.xDim = col2-col1+1;
01825 temp.yDim = row2-row1+1;
01826 temp.columns = new (std::nothrow) Vector<T>[temp.xDim];
01827 Utility::CheckPointer(temp.columns);
01828 temp.clean = new (std::nothrow) Cleaner<T>(temp.columns);
01829 Utility::CheckPointer(temp.clean);
01830
01831 for(int j=col1; j<=col2; j++)
01832 {
01833 temp.columns[j-col1].Set(&(columns[j].data[row1]), row2-row1+1);
01834 }
01835
01836 return temp;
01837 }
01838
01839
01840 template< class T >
01841 SubMatrix<T> Matrix<T>::operator() (string str1, string str2)
01842 {
01843 int row1, row2, col1, col2;
01844 vector<string> bounds1 = Utility::Split(str1, ":");
01845 vector<string> bounds2 = Utility::Split(str2, ":");
01846
01847 if(str1 == ":")
01848 {
01849 row1 = 0;
01850 row2 = yDim-1;
01851 }
01852 else if(bounds1.size() == 2)
01853 {
01854 row1 = Utility::ToInt(bounds1[0]);
01855 row2 = Utility::ToInt(bounds1[1]);
01856 }
01857 else
01858 {
01859 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01860 Utility::RunTimeError("Incorrect slice argument. String cannot be parsed!");
01861 }
01862
01863 if(str2 == ":")
01864 {
01865 col1 = 0;
01866 col2 = xDim-1;
01867 }
01868 else if(bounds2.size() == 2)
01869 {
01870 col1 = Utility::ToInt(bounds2[0]);
01871 col2 = Utility::ToInt(bounds2[1]);
01872 }
01873 else
01874 {
01875 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01876 Utility::RunTimeError("Incorrect slice argument. String cannot be parsed!");
01877 }
01878
01879 return this->operator()(row1, row2, col1, col2);
01880
01881 }
01882
01883
01884 template< class T >
01885 Vector<T> Matrix<T>::operator() (string str)
01886 {
01887 Vector<T> temp = (Vector<T>)*this;
01888 return temp(str);
01889 }
01890
01891
01892
01893
01894
01895 template< class T >
01896 Matrix<T>& Matrix<T>::operator+= (Matrix<T>& m)
01897 {
01898 return this->Add(m);
01899 }
01900
01901 template< class T >
01902 Matrix<T>& Matrix<T>::operator-= (Matrix<T>& m)
01903 {
01904 return this->Subtract(m);
01905 }
01906
01907 template< class T >
01908 Matrix<T>& Matrix<T>::operator*= (Matrix<T>& m)
01909 {
01910 return this->Multiply(m);
01911 }
01912
01913 template< class T >
01914 Matrix<T>& Matrix<T>::operator/= (Matrix<T>& m)
01915 {
01916 return this->Divide(m);
01917 }
01918
01919
01920 template< class T >
01921 Matrix<T>& Matrix<T>::operator+= (T v)
01922 {
01923 return this->Add(v);
01924 }
01925
01926 template< class T >
01927 Matrix<T>& Matrix<T>::operator-= (T v)
01928 {
01929 return this->Subtract(v);
01930 }
01931
01932 template< class T >
01933 Matrix<T>& Matrix<T>::operator*= (T v)
01934 {
01935 return this->Multiply(v);
01936 }
01937
01938 template< class T >
01939 Matrix<T>& Matrix<T>::operator/= (T v)
01940 {
01941 return this->Divide(v);
01942 }
01943
01944
01945
01946
01947 template< class T >
01948 Matrix<T>::Matrix(Array<T> &m)
01949 {
01950 ndims = 2;
01951 xDim = 0;
01952 yDim = 0;
01953 data = 0;
01954 columns = 0;
01955
01956 if(m.ndims == 2){
01957 length = m.length;
01958 data = m.data;
01959 xDim = m.XDim();
01960 yDim = m.YDim();
01961
01962 columns = new (std::nothrow) Vector<T>[Columns()];
01963 Utility::CheckPointer(columns);
01964 for(int i=0; i<Columns(); i++)
01965 {
01966 columns[i].Set(&(data[i*Rows()]), Rows());
01967 }
01968 clean = new (std::nothrow) Cleaner<T>(data, columns);
01969 Utility::CheckPointer(clean);
01970
01971 }
01972 else if(m.ndims > 0)
01973 {
01974 length = m.length;
01975 data = m.data;
01976 xDim = 1;
01977 yDim = length;
01978
01979 columns = new (std::nothrow) Vector<T>[1];
01980 Utility::CheckPointer(columns);
01981 columns[0].Set(&(data[0]),length);
01982 clean = new (std::nothrow) Cleaner<T>(data, columns);
01983 Utility::CheckPointer(clean);
01984
01985 if(ndims != 1)
01986 {
01987 Utility::Warning("Array (which was not of dimension 2) is converted to a Nx1 (column) Matrix. Dimensionality information is lost.");
01988 }
01989 }
01990
01991 }
01992
01993
01994 template< class T >
01995 Matrix<T>::Matrix(Vector<T> &v)
01996 {
01997 ndims = 2;
01998
01999 length = v.length;
02000 data = v.data;
02001 xDim = 1;
02002 yDim = length;
02003
02004 columns = new (std::nothrow) Vector<T>[1];
02005 Utility::CheckPointer(columns);
02006 columns[0].Set(&(data[0]),length);
02007 clean = new (std::nothrow) Cleaner<T>(data, columns);
02008 Utility::CheckPointer(clean);
02009
02010 }
02011
02012
02013 template< class T >
02014 Matrix<T>::Matrix(SubMatrix<T> &m)
02015 {
02016 if(m.yDim < 1 || m.xDim < 1)
02017 {
02018 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
02019 Utility::RunTimeError("All Matrix dimensions should be larger than 0!");
02020 }
02021
02022 ndims = 2;
02023 length = m.yDim*m.xDim;
02024 xDim = m.xDim;
02025 yDim = m.yDim;
02026 data = new (std::nothrow) T[length];
02027 Utility::CheckPointer(data);
02028
02029 columns = new (std::nothrow) Vector<T>[xDim];
02030 Utility::CheckPointer(columns);
02031 for(int i=0; i<xDim; i++)
02032 {
02033 columns[i].Set(&(data[i*yDim]), yDim);
02034 }
02035
02036 clean = new (std::nothrow) Cleaner<T>(data, columns);
02037 Utility::CheckPointer(clean);
02038
02039 for(int i=0;i<m.xDim;i++)
02040 {
02041 for(int j=0;j<m.yDim;j++)
02042 {
02043 columns[i].data[j] = m[i][j];
02044 }
02045 }
02046
02047 }
02048
02049
02050
02051
02052
02053 };
02054
02055
02056
02057