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 namespace CIMPL
00060 {
00061 
00062 
00063 // Template Implementation
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 //template< class T >
00372 //SubMatrix<T> Matrix<T>::Slice(int row1, int row2, int col1, int col2)
00373 //{
00374 //      if(row1<0 || row1>=YDim() || row2<0 || row2>=YDim())
00375 //      {
00376 //              cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00377 //              Utility::RunTimeError("Index outside bounds!");
00378 //      }
00379 //      if(row1 > row2)
00380 //      {
00381 //              cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00382 //              Utility::RunTimeError("Second slice parameter cannot be less than the first parameter!");
00383 //      }
00384 //
00385 //
00386 //      if(col1<0 || col1>=XDim() || col2<0 || col2>=XDim())
00387 //      {
00388 //              cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00389 //              Utility::RunTimeError("Index outside bounds!");
00390 //      }
00391 //      if(col1 > col2)
00392 //      {
00393 //              cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00394 //              Utility::RunTimeError("Second slice parameter cannot be less than the first parameter!");
00395 //      }
00396 //
00397 //      
00398 //      SubMatrix<T> temp;
00399 //      temp.xDim = col2-col1+1;
00400 //      temp.yDim = row2-row1+1;
00401 //      temp.columns = new (std::nothrow) Vector<T>[temp.xDim];
00402 //      Utility::CheckPointer(temp.columns);
00403 //      temp.clean = new (std::nothrow) Cleaner<T>(temp.columns);
00404 //      Utility::CheckPointer(temp.clean);
00405 //
00406 //      for(int j=col1; j<=col2; j++)
00407 //      {
00408 //              temp.columns[j-col1].Set(&(columns[j].data[row1]),  row2-row1+1);
00409 //      }
00410 //
00411 //      return temp;
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 //template< class T >
00528 //inline Matrix<T>&  Matrix<T>::Rand()
00529 //{
00530 //      if(!RandomGen::Initialized())
00531 //      {
00532 //              RandomGen::Initialize();
00533 //      }
00534 //      for(int i=0;i<length;i++)
00535 //      {
00536 //              data[i] = (T)rand();
00537 //      }
00538 //      return *this;
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 //template< class T >
00557 //Matrix<T> Matrix<T>::Rand(const int rows, const int cols)
00558 //{
00559 //      Matrix<T> m(rows, cols);
00560 //      if(!RandomGen::Initialized())
00561 //      {
00562 //              RandomGen::Initialize();
00563 //      }
00564 //      for(int i=0;i<rows*cols;i++)
00565 //      {
00566 //              m.data[i] = (T)rand();
00567 //      }
00568 //      return m;
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 // Boolean Operations...
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 // Boolean Operations with value types...
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 // Elementwise matrix arithmetic
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                 //FW: catch division exception instead...
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 // Arithmetic operations between a matrix and a value.
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 // Elementwise matrix arithmetic with "this" matrix
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 // Arithmetic operation between "this" matrix and a value
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 // OPERATORS
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) // Convert to row matrux
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 //Unary operators
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 //template< class T >
01760 //inline Matrix<T> Matrix<T>::operator() (const int row1, const int row2, const int col1, const int col2)
01761 //{
01762 //      if(row1<0 || row1>=Rows() || row2<0 || row2>=Rows())
01763 //      {
01764 //              cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01765 //              Utility::RunTimeError("Index outside bounds!");
01766 //      }
01767 //      if(row1 > row2)
01768 //      {
01769 //              cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01770 //              Utility::RunTimeError("Second slice parameter cannot be less than the first parameter!");
01771 //      }
01772 //
01773 //
01774 //      if(col1<0 || col1>=Columns() || col2<0 || col2>=Columns())
01775 //      {
01776 //              cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01777 //              Utility::RunTimeError("Index outside bounds!");
01778 //      }
01779 //      if(col1 > col2)
01780 //      {
01781 //              cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
01782 //              Utility::RunTimeError("Second slice parameter cannot be less than the first parameter!");
01783 //      }
01784 //
01785 //      
01786 //      Matrix<T> temp(row2-row1+1, col2-col1+1);
01787 //      
01788 //      for(int j=col1; j<=col2; j++)
01789 //      {
01790 //              memcpy(temp[ j-col1 ].data, &(columns[j].data[row1]), sizeof(T)*temp.Rows());
01791 //      }
01792 //
01793 //      return temp;
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 // Arithmetic operators
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 // TYPE CONVERSIONS
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 }; //namespace
02054 
02055 
02056 
02057 

Generated on Thu Jan 20 08:43:45 2005 for CIMPL by  doxygen 1.3.9.1