FullMatrix.h

Go to the documentation of this file.
00001 /******************************************************************************
00002 *       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 3      *
00003 *                (c) 2006-2008 MGH, INRIA, USTL, UJF, CNRS                    *
00004 *                                                                             *
00005 * This library is free software; you can redistribute it and/or modify it     *
00006 * under the terms of the GNU Lesser General Public License as published by    *
00007 * the Free Software Foundation; either version 2.1 of the License, or (at     *
00008 * your option) any later version.                                             *
00009 *                                                                             *
00010 * This library is distributed in the hope that it will be useful, but WITHOUT *
00011 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
00012 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
00013 * for more details.                                                           *
00014 *                                                                             *
00015 * You should have received a copy of the GNU Lesser General Public License    *
00016 * along with this library; if not, write to the Free Software Foundation,     *
00017 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301 USA.          *
00018 *******************************************************************************
00019 *                               SOFA :: Modules                               *
00020 *                                                                             *
00021 * Authors: The SOFA Team and external contributors (see Authors.txt)          *
00022 *                                                                             *
00023 * Contact information: contact@sofa-framework.org                             *
00024 ******************************************************************************/
00025 #ifndef SOFA_COMPONENT_LINEARSOLVER_FULLMATRIX_H
00026 #define SOFA_COMPONENT_LINEARSOLVER_FULLMATRIX_H
00027 
00028 #include <sofa/defaulttype/BaseMatrix.h>
00029 #include <sofa/simulation/common/MatrixLinearSolver.h>
00030 #include "FullVector.h"
00031 
00032 #include <map>
00033 
00034 namespace sofa
00035 {
00036 
00037 namespace component
00038 {
00039 
00040 namespace linearsolver
00041 {
00042 
00043 //#define FULLMATRIX_CHECK
00044 //#define FULLMATRIX_VERBOSE
00045 
00046 
00048 template<typename T>
00049 class FullMatrix : public defaulttype::BaseMatrix
00050 {
00051 public:
00052     typedef T Real;
00053     typedef int Index;
00054     typedef FullVector<Real> Line;
00055     class LineConstIterator
00056     {
00057     public:
00058         Index first;
00059         Line second;
00060         LineConstIterator(Real* p, Index i, Index size, Index pitch) : first(i), second(p+i*pitch,size,pitch) { }
00061         const Line& operator*() const { return second; }
00062         const Line* operator->() const { return &second; }
00063         void operator++() { ++first; second.setptr(second.ptr() + second.capacity()); }
00064         void operator++(int) { ++first; second.setptr(second.ptr() + second.capacity()); }
00065         void operator--() { --first; second.setptr(second.ptr() - second.capacity()); }
00066         void operator--(int) { --first; second.setptr(second.ptr() - second.capacity()); }
00067         bool operator==(const LineConstIterator& i) const { return i.second.ptr() == second.ptr(); }
00068         bool operator!=(const LineConstIterator& i) const { return i.second.ptr() != second.ptr(); }
00069     };
00070     class LineIterator : public LineConstIterator
00071     {
00072     public:
00073         LineIterator(Real* p, Index i, Index size, Index pitch) : LineConstIterator(p,i,size,pitch) {}
00074         Line& operator*() { return this->second; }
00075         Line* operator->() { return &this->second; }
00076     };
00077     typedef typename Line::iterator LElementIterator;
00078     typedef typename Line::const_iterator LElementConstIterator;
00079 
00080 protected:
00081     Real* data;
00082     Index nRow,nCol;
00083     Index pitch;
00084     Index allocsize;
00085 
00086 public:
00087 
00088     FullMatrix()
00089     : data(NULL), nRow(0), nCol(0), pitch(0), allocsize(0)
00090     {
00091     }
00092     
00093     FullMatrix(int nbRow, int nbCol)
00094     : data(new T[nbRow*nbCol]), nRow(nbRow), nCol(nbCol), pitch(nbCol), allocsize(nbRow*nbCol)
00095     {
00096     }
00097     
00098     FullMatrix(Real* p, int nbRow, int nbCol)
00099     : data(p), nRow(nbRow), nCol(nbCol), pitch(nbCol), allocsize(-nbRow*nbCol)
00100     {
00101     }
00102     
00103     FullMatrix(Real* p, int nbRow, int nbCol, int pitch)
00104     : data(p), nRow(nbRow), nCol(nbCol), pitch(pitch), allocsize(-nbRow*pitch)
00105     {
00106     }
00107     
00108     ~FullMatrix()
00109     {
00110         if (allocsize>0)
00111             delete data;
00112     }
00113     
00114     Real* ptr() { return data; }
00115     const Real* ptr() const { return data; }
00116 
00117     LineIterator begin() { return LineIterator(data, 0, nCol, pitch); }
00118     LineIterator end()   { return LineIterator(data, nRow, nCol, pitch);   }
00119     LineConstIterator begin() const { return LineConstIterator(data, 0, nCol, pitch); }
00120     LineConstIterator end()   const { return LineConstIterator(data, nRow, nCol, pitch);   }
00121 
00122     //Line operator[](Index i)
00123     //{
00124     //    return Line(data+i*pitch, nCol, pitch);
00125     //}
00126     Real* operator[](Index i)
00127     {
00128         return data+i*pitch;
00129     }
00130     
00131 
00132     //const Line operator[](Index i) const
00133     //{
00134     //    return Line(data+i*pitch, nCol, pitch);
00135     //}
00136     const Real* operator[](Index i) const
00137     {
00138         return data+i*pitch;
00139     }
00140     
00141     void resize(int nbRow, int nbCol)
00142     {
00143 #ifdef FULLMATRIX_VERBOSE
00144         if (nbRow != rowSize() || nbCol != colSize())
00145             std::cout << /*this->Name() << */": resize("<<nbRow<<","<<nbCol<<")"<<std::endl;
00146 #endif
00147         if (nbCol != nCol || nbRow != nRow)
00148         {
00149             if (allocsize < 0)
00150             {
00151                 if (nbRow*nbCol > -allocsize)
00152                 {
00153                     std::cerr << "ERROR: cannot resize preallocated matrix to size ("<<nbRow<<","<<nbCol<<")"<<std::endl;
00154                     return;
00155                 }
00156             }
00157             else
00158             {
00159                 if (nbRow*nbCol > allocsize)
00160                 {
00161                     if (allocsize > 0)
00162                         delete[] data;
00163                     allocsize = nbRow*nbCol;
00164                     data = new Real[allocsize];
00165                 }
00166             }
00167             pitch = nbCol;
00168             nCol = nbCol;
00169             nRow = nbRow;
00170         }
00171         clear();
00172     }
00173 
00174     int rowSize(void) const
00175     {
00176         return nRow;
00177     }
00178 
00179     int colSize(void) const
00180     {
00181         return nCol;
00182     }
00183 
00184     SReal element(int i, int j) const
00185     {
00186 #ifdef FULLMATRIX_CHECK
00187         if ((unsigned)i >= (unsigned)rowSize() || (unsigned)j >= (unsigned)colSize())
00188         {
00189             std::cerr << "ERROR: invalid read access to element ("<<i<<","<<j<<") in "<</*this->Name()<<*/" of size ("<<rowSize()<<","<<colSize()<<")"<<std::endl;
00190             return 0.0;
00191         }
00192 #endif
00193         return data[i*pitch+j];
00194     }
00195 
00196     void set(int i, int j, double v)
00197     {
00198 #ifdef FULLMATRIX_VERBOSE
00199         std::cout << /*this->Name() <<*/ "("<<rowSize()<<","<<colSize()<<"): element("<<i<<","<<j<<") = "<<v<<std::endl;
00200 #endif
00201 #ifdef FULLMATRIX_CHECK
00202         if ((unsigned)i >= (unsigned)rowSize() || (unsigned)j >= (unsigned)colSize())
00203         {
00204             std::cerr << "ERROR: invalid write access to element ("<<i<<","<<j<<") in "<</*this->Name()<<*/" of size ("<<rowSize()<<","<<colSize()<<")"<<std::endl;
00205             return;
00206         }
00207 #endif
00208         data[i*pitch+j] = (Real)v;
00209     }
00210 
00211     void add(int i, int j, double v)
00212     {
00213 #ifdef FULLMATRIX_VERBOSE
00214         std::cout << /*this->Name() << */"("<<rowSize()<<","<<colSize()<<"): element("<<i<<","<<j<<") += "<<v<<std::endl;
00215 #endif
00216 #ifdef FULLMATRIX_CHECK
00217         if ((unsigned)i >= (unsigned)rowSize() || (unsigned)j >= (unsigned)colSize())
00218         {
00219             std::cerr << "ERROR: invalid write access to element ("<<i<<","<<j<<") in "/*<<this->Name()*/<<" of size ("<<rowSize()<<","<<colSize()<<")"<<std::endl;
00220             return;
00221         }
00222 #endif
00223         data[i*pitch+j] += (Real)v;
00224     }
00225 
00226     void clear(int i, int j)
00227     {
00228 #ifdef FULLMATRIX_VERBOSE
00229         std::cout << /*this->Name() <<*/ "("<<rowSize()<<","<<colSize()<<"): element("<<i<<","<<j<<") = 0"<<std::endl;
00230 #endif
00231 #ifdef FULLMATRIX_CHECK
00232         if ((unsigned)i >= (unsigned)rowSize() || (unsigned)j >= (unsigned)colSize())
00233         {
00234             std::cerr << "ERROR: invalid write access to element ("<<i<<","<<j<<") in "<</*this->Name()<<*/" of size ("<<rowSize()<<","<<colSize()<<")"<<std::endl;
00235             return;
00236         }
00237 #endif
00238         data[i*pitch+j] = Real();
00239     }
00240 
00241     void clearRow(int i)
00242     {
00243 #ifdef FULLMATRIX_VERBOSE
00244         std::cout << /*this->Name() <<*/ "("<<rowSize()<<","<<colSize()<<"): row("<<i<<") = 0"<<std::endl;
00245 #endif
00246 #ifdef FULLMATRIX_CHECK
00247         if ((unsigned)i >= (unsigned)rowSize())
00248         {
00249             std::cerr << "ERROR: invalid write access to row "<<i<<" in "<</*this->Name()<<*/" of size ("<<rowSize()<<","<<colSize()<<")"<<std::endl;
00250             return;
00251         }
00252 #endif
00253         for (Index j=0;j<nCol;++j)
00254             data[i*pitch+j] = Real();
00255     }
00256 
00257     void clearCol(int j)
00258     {
00259 #ifdef FULLMATRIX_VERBOSE
00260         std::cout <</* this->Name() << */"("<<rowSize()<<","<<colSize()<<"): col("<<j<<") = 0"<<std::endl;
00261 #endif
00262 #ifdef FULLMATRIX_CHECK
00263         if ((unsigned)j >= (unsigned)colSize())
00264         {
00265             std::cerr << "ERROR: invalid write access to column "<<j<<" in "<</*this->Name()<<*/" of size ("<<rowSize()<<","<<colSize()<<")"<<std::endl;
00266             return;
00267         }
00268 #endif
00269         for (Index i=0;i<nRow;++i)
00270             data[i*pitch+j] = Real();
00271     }
00272 
00273     void clearRowCol(int i)
00274     {
00275 #ifdef FULLMATRIX_VERBOSE
00276         std::cout << /*this->Name() << */"("<<rowSize()<<","<<colSize()<<"): row("<<i<<") = 0 and col("<<i<<") = 0"<<std::endl;
00277 #endif
00278 #ifdef FULLMATRIX_CHECK
00279         if ((unsigned)i >= (unsigned)rowSize() || (unsigned)i >= (unsigned)colSize())
00280         {
00281             std::cerr << "ERROR: invalid write access to row and column "<<i<<" in "<</*this->Name()<<*/" of size ("<<rowSize()<<","<<colSize()<<")"<<std::endl;
00282             return;
00283         }
00284 #endif
00285         clearRow(i);
00286         clearCol(i);
00287     }
00288 
00289     void clear()
00290     {
00291         //if (pitch == nCol)
00292         //    std::fill(data, data+nRow*pitch, Real());
00293         //else
00294             for (Index i=0;i<nRow;++i)
00295                 for (Index j=0;j<nCol;++j)
00296                     data[i*pitch+j] = Real();
00297     }
00298 
00299     template<class Real2>
00300     FullVector<Real2> operator*(const FullVector<Real2>& v) const
00301     {
00302         FullVector<Real2> res(rowSize());
00303         for (Index i=0;i<nRow;++i)
00304         {
00305             Real r = 0;
00306             for (Index j=0;j<nCol;++j)
00307                 r += data[i*pitch+j] * v[j];
00308             res[i] = r;
00309         }
00310         return res;
00311     }
00312 
00313     friend std::ostream& operator << (std::ostream& out, const FullMatrix<T>& v )
00314     {
00315         int nx = v.Ncols();
00316         int ny = v.Nrows();
00317         out << "[";
00318         for (int y=0;y<ny;++y)
00319         {
00320             out << "\n[";
00321             for (int x=0;x<nx;++x)
00322             {
00323                 out << " " << v.element(y,x);
00324             }
00325             out << " ]";
00326         }
00327         out << " ]";
00328         return out;
00329     }
00330 
00331     static const char* Name() { return "FullMatrix"; }
00332 };
00333 
00335 template<typename T>
00336 class LPtrFullMatrix : public FullMatrix<T>
00337 {
00338 protected:
00339     T** ldata;
00340     int lallocsize;
00341 public:
00342     LPtrFullMatrix()
00343     : ldata(NULL), lallocsize(0)
00344     {
00345     }
00346     
00347     void resize(int nbRow, int nbCol)
00348     {
00349         if (nbRow == this->nRow && nbCol == this->nCol)
00350             this->clear();
00351         else
00352         {
00353             this->FullMatrix<T>::resize(nbRow, nbCol);
00354             if (nbRow > lallocsize)
00355             {
00356                 if (lallocsize > 0)
00357                     delete[] ldata;
00358                 ldata = new T*[nbRow];
00359                 lallocsize = nbRow;
00360             }
00361             for (int i=0;i<nbRow;++i)
00362                 ldata[i] = this->data + i*this->pitch;
00363         }
00364     }
00365     
00366     T** lptr() { return ldata; }
00367     const T** lptr() const { return ldata; }
00368     //operator T**() { return ldata; }
00369     //operator const T**() const { return ldata; }
00370 };        
00371 } // namespace linearsolver
00372 
00373 } // namespace component
00374 
00375 } // namespace sofa
00376 
00377 #endif

Generated on Sun Nov 23 03:25:11 2008 for Sofa by  doxygen 1.5.7.1