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