Matrix.inl

Go to the documentation of this file.
00001 //Copyright (c) 2004-2005, Baris Sumengen
00002 //All rights reserved.
00003 //
00004 // CIMPL Matrix Performance Library
00005 //
00006 //Redistribution and use in source and binary
00007 //forms, with or without modification, are
00008 //permitted provided that the following
00009 //conditions are met:
00010 //
00011 //    * No commercial use is allowed. 
00012 //    This software can only be used
00013 //    for non-commercial purposes. This 
00014 //    distribution is mainly intended for
00015 //    academic research and teaching.
00016 //    * Redistributions of source code must
00017 //    retain the above copyright notice, this
00018 //    list of conditions and the following
00019 //    disclaimer.
00020 //    * Redistributions of binary form must
00021 //    mention the above copyright notice, this
00022 //    list of conditions and the following
00023 //    disclaimer in a clearly visible part 
00024 //    in associated product manual, 
00025 //    readme, and web site of the redistributed 
00026 //    software.
00027 //    * Redistributions in binary form must
00028 //    reproduce the above copyright notice,
00029 //    this list of conditions and the
00030 //    following disclaimer in the
00031 //    documentation and/or other materials
00032 //    provided with the distribution.
00033 //    * The name of Baris Sumengen may not be
00034 //    used to endorse or promote products
00035 //    derived from this software without
00036 //    specific prior written permission.
00037 //
00038 //THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT
00039 //HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
00040 //EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
00041 //NOT LIMITED TO, THE IMPLIED WARRANTIES OF
00042 //MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00043 //PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00044 //CONTRIBUTORS BE LIABLE FOR ANY
00045 //DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00046 //EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00047 //(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
00048 //OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00049 //DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00050 //HOWEVER CAUSED AND ON ANY THEORY OF
00051 //LIABILITY, WHETHER IN CONTRACT, STRICT
00052 //LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
00053 //OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00054 //OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00055 //POSSIBILITY OF SUCH DAMAGE.
00056 
00057 
00058 
00059 // Template Implementation
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 // Boolean Operations...
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 // Boolean Operations with value types...
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 // Elementwise matrix arithmetic
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         //FW: catch division exception instead...
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 // Arithmetic operations between a matrix and a value.
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 // Elementwise matrix arithmetic with "this" matrix
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 // Arithmetic operation between "this" matrix and a value
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 // OPERATORS
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) // Convert to row matrux
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 //Unary operators
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 // Arithmetic operators
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 // TYPE CONVERSIONS
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.