SparseMatrix.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 
00064 template< class T >
00065 SparseMatrix<T>::SparseMatrix()
00066         : ndims(2), count(0)
00067 {
00068         xDimStarts = 0;
00069         yDimStarts = 0;
00070 
00071         dims = new (std::nothrow) int[ndims];
00072         Utility::CheckPointer(dims);
00073         for(int j=0;j<ndims;j++)
00074         {
00075                 dims[j] = 0;
00076         }
00077         
00078 }
00079 
00080 
00081 
00082 
00083 template< class T >
00084 SparseMatrix<T>::SparseMatrix(const int xdim, const int ydim)
00085 {
00086         if(xdim < 1 || ydim < 1)
00087         {
00088                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00089                 Utility::RunTimeError("All array dimensions should be larger than 1!");
00090         }
00091 
00092         ndims = 2;
00093         count = 0;
00094         dims = new (std::nothrow) int[ndims];
00095         Utility::CheckPointer(dims);
00096         dims[0] = xdim;
00097         dims[1] = ydim;
00098 
00099         xDimStarts = new (std::nothrow) matrixCellStart<T>[xdim];
00100         Utility::CheckPointer(xDimStarts);
00101         for(int i=0; i<xdim; i++)
00102         {
00103                 xDimStarts[i].listCount = 0;
00104                 xDimStarts[i].first = new (std::nothrow) matrixCell<T>;
00105                 Utility::CheckPointer(xDimStarts[i].first);
00106                 xDimStarts[i].first->xNext = 0;
00107                 xDimStarts[i].first->yNext = 0;
00108         }
00109 
00110         yDimStarts = new (std::nothrow) matrixCellStart<T>[ydim];
00111         Utility::CheckPointer(yDimStarts);
00112         for(int i=0; i<ydim; i++)
00113         {
00114                 yDimStarts[i].listCount = 0;
00115                 yDimStarts[i].first = new (std::nothrow) matrixCell<T>;
00116                 Utility::CheckPointer(yDimStarts[i].first);
00117                 yDimStarts[i].first->xNext = 0;
00118                 yDimStarts[i].first->yNext = 0;
00119         }
00120         
00121         
00122 }
00123 
00124 
00125 
00126 
00127 
00128 
00129 template< class T >
00130 SparseMatrix<T>::~SparseMatrix()
00131 {
00132 
00133         
00134 
00135         for(int i=0; i<XDim(); i++)
00136         {
00137                 matrixCell<T> *temp = xDimStarts[i].first;
00138                 while(temp != 0)
00139                 {
00140                         matrixCell<T> *c = temp->yNext;
00141                         delete temp;
00142                         temp = c;
00143                 }
00144         }
00145         delete [] xDimStarts;
00146         
00147         for(int i=0; i<YDim(); i++)
00148         {
00149                 delete yDimStarts[i].first;
00150         }
00151         delete [] yDimStarts;
00152         delete [] dims;
00153 
00154         
00155 }
00156 
00157 
00158 
00159 
00160 
00161 template< class T >
00162 inline const int SparseMatrix<T>::Columns() const
00163 {
00164         return dims[0];
00165 }
00166 
00167 template< class T >
00168 inline const int SparseMatrix<T>::Rows() const
00169 {
00170         return dims[1];
00171 }
00172 
00173 
00174 template< class T >
00175 inline const int SparseMatrix<T>::XDim() const
00176 {
00177         return dims[0];
00178 }
00179 
00180 template< class T >
00181 inline const int SparseMatrix<T>::YDim() const
00182 {
00183         if(ndims < 2)
00184         {
00185                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00186                 Utility::RunTimeError("YDim(): Number of dimensions is less than 2!");
00187         }
00188         return dims[1];
00189 }
00190 
00191 
00192 
00193 template< class T >
00194 inline const int SparseMatrix<T>::NNZ(void) const
00195 {
00196         return count;
00197 }
00198 
00199 
00200 template< class T >
00201 inline void SparseMatrix<T>::SetValue(const int x, const int y, const T value)
00202 {
00203         if(x<0 || x>=dims[0] || y<0 || y>=dims[1])
00204         {
00205                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00206                 Utility::RunTimeError("Index outside bounds!");
00207         }
00208 
00209         if(value == 0)
00210         {
00211                 bool deleted = DeleteCell(x, y);
00212                 if(deleted)
00213                 {
00214                         xDimStarts[x].listCount--;
00215                         yDimStarts[y].listCount--;
00216                         count--;
00217                 }
00218                 return;
00219         }
00220 
00221 
00222         matrixCell<T> *c = new (std::nothrow) matrixCell<T>;
00223         Utility::CheckPointer(c);
00224         c->value = value;
00225         c->x = x;
00226         c->y = y;
00227         c->xNext = 0;
00228         c->yNext = 0;
00229 
00230         if( xDimStarts[x].listCount > yDimStarts[y].listCount )  // less elements for row scan
00231         {
00232                 bool exists = AddCellYStart(c);
00233                 if(!exists)
00234                 {
00235                         AddCellXStart(c);
00236                         xDimStarts[x].listCount++;
00237                         yDimStarts[y].listCount++;
00238                         count++;
00239                 }
00240         }
00241         else // less elements for column scan
00242         {
00243                 bool exists = AddCellXStart(c);
00244                 if(!exists)
00245                 {
00246                         AddCellYStart(c);
00247                         xDimStarts[x].listCount++;
00248                         yDimStarts[y].listCount++;
00249                         count++;
00250                 }
00251         }
00252 }
00253 
00254 template< class T >
00255 inline T SparseMatrix<T>::GetValue(const int x, const int y)
00256 {
00257         if(x<0 || x>=dims[0] || y<0 || y>=dims[1])
00258         {
00259                 cerr << "Line: " << __LINE__ << " File: " << __FILE__ << endl;
00260                 Utility::RunTimeError("Index outside bounds!");
00261         }
00262 
00263         if( xDimStarts[x].listCount > yDimStarts[y].listCount )  // less elements for row scan
00264         {
00265                 return GetCellYStart(x, y);
00266         }
00267         else // less elements for column scan
00268         {
00269                 return GetCellXStart(x, y);
00270         }
00271 }
00272 
00273 
00274 
00275 
00276 
00277 // OPERATORS
00278 
00279 template< class T >
00280 inline T SparseMatrix<T>::operator() (const int i, const int j)
00281 {
00282         return GetValue(i, j);
00283 }
00284 
00285 
00286 
00287 
00288 
00289 
00290 
00291 
00292 
00293 
00294 
00295 
00296 
00297 
00298 
00300 // PRIVATE
00302 
00303 
00304 
00305 
00306 template< class T >
00307 bool SparseMatrix<T>::AddCellYStart(matrixCell<T> *c)
00308 {
00309         matrixCell<T> *temp = yDimStarts[c->y].first;
00310         while(temp->xNext != 0)
00311         {
00312                 if(temp->xNext->x == c->x)
00313                 {
00314                         temp->xNext->value = c->value;
00315                         delete c;
00316                         return true;
00317                 }
00318                 else if(temp->xNext->x > c->x)
00319                 {
00320                         c->xNext = temp->xNext;
00321                         temp->xNext = c;
00322                         return false;
00323                 }
00324                 
00325                 temp = temp->xNext;
00326         }
00327         
00328         c->xNext = 0;
00329         temp->xNext = c;
00330         return false;
00331 }
00332 
00333 
00334 
00335 template< class T >
00336 bool SparseMatrix<T>::AddCellXStart(matrixCell<T> *c)
00337 {
00338         matrixCell<T> *temp = xDimStarts[c->x].first;
00339         while(temp->yNext != 0)
00340         {
00341                 if(temp->yNext->y == c->y)
00342                 {
00343                         temp->yNext->value = c->value;
00344                         delete c;
00345                         return true;
00346                 }
00347                 else if(temp->yNext->y > c->y)
00348                 {
00349                         c->yNext = temp->yNext;
00350                         temp->yNext = c;
00351                         return false;
00352                 }
00353                 
00354                 temp = temp->yNext;
00355         }
00356         
00357         c->yNext = 0;
00358         temp->yNext = c;
00359         return false;
00360 }
00361 
00362 
00363 template< class T >
00364 T SparseMatrix<T>::GetCellYStart(const int x, const int y)
00365 {
00366         matrixCell<T> *temp = yDimStarts[y].first;
00367         while(temp->xNext != 0)
00368         {
00369                 if(temp->xNext->x == x)
00370                 {
00371                         return temp->xNext->value;
00372                 }
00373                 else if(temp->xNext->x > x)
00374                 {
00375                         return 0;
00376                 }
00377                 
00378                 temp = temp->xNext;
00379         }
00380         
00381         return 0;
00382 }
00383 
00384 template< class T >
00385 T SparseMatrix<T>::GetCellXStart(const int x, const int y)
00386 {
00387         matrixCell<T> *temp = xDimStarts[x].first;
00388         while(temp->yNext != 0)
00389         {
00390                 if(temp->yNext->y == y)
00391                 {
00392                         return temp->yNext->value;
00393                 }
00394                 else if(temp->yNext->y > y)
00395                 {
00396                         return 0;
00397                 }
00398 
00399                 temp = temp->yNext;
00400         }
00401         
00402         return 0;
00403 }
00404 
00405 
00406 template< class T >
00407 bool SparseMatrix<T>::DeleteCell(const int x, const int y)
00408 {
00409         matrixCell<T> *c = 0;
00410         bool deleted = false;
00411         
00412         matrixCell<T> *temp = yDimStarts[y].first;
00413         while(temp->xNext != 0)
00414         {
00415                 if(temp->xNext->x == x)
00416                 {
00417                         c = temp->xNext;
00418                         temp->xNext = c->xNext;
00419                         deleted = true;
00420                         break;
00421                 }
00422                 else if(temp->xNext->x > c->x)
00423                 {
00424                         return false;
00425                 }
00426 
00427                 temp = temp->xNext;
00428         }
00429 
00430         if(deleted == false)
00431         {
00432                 return false;
00433         }
00434 
00435         temp = xDimStarts[x].first;
00436         while(temp->yNext != 0)
00437         {
00438                 if(temp->yNext->y == y)
00439                 {
00440                         c = temp->yNext;
00441                         temp->yNext = c->yNext;
00442                         deleted = true;
00443                         break;
00444                 }
00445                 else if(temp->yNext->y > c->y)
00446                 {
00447                         return false;
00448                 }
00449                 
00450                 temp = temp->yNext;
00451         }
00452         if(deleted == false)
00453         {
00454                 return false;
00455         }
00456 
00457         delete c;
00458         return true;
00459 }
00460 
00461 
00462 
00463 
00464 }; //namespace
00465 
00466 
00467 
00468 
00469 
00470 
00471 

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