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

CIMPL 0.1 Code Reference. Copyright © 2004, Baris Sumengen. All rights reserved.