00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
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
00044
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
00123
00124
00125
00126 Real* operator[](Index i)
00127 {
00128 return data+i*pitch;
00129 }
00130
00131
00132
00133
00134
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 << ": 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 "<<" 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 << "("<<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 "<<" 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 << "("<<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 "<<" 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 << "("<<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 "<<" 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 << "("<<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 "<<" 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 <<"("<<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 "<<" 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 << "("<<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 "<<" of size ("<<rowSize()<<","<<colSize()<<")"<<std::endl;
00282 return;
00283 }
00284 #endif
00285 clearRow(i);
00286 clearCol(i);
00287 }
00288
00289 void clear()
00290 {
00291
00292
00293
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
00369
00370 };
00371 }
00372
00373 }
00374
00375 }
00376
00377 #endif