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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include <float.h>
00043
00044
00045 namespace pcl
00046 {
00047 namespace poisson
00048 {
00050
00053
00055 template<class T> int SparseMatrix<T>::UseAlloc=0;
00056 template<class T> Allocator<MatrixEntry<T> > SparseMatrix<T>::AllocatorMatrixEntry;
00057 template<class T> int SparseMatrix<T>::UseAllocator(void){return UseAlloc;}
00058 template<class T>
00059 void SparseMatrix<T>::SetAllocator(const int& blockSize){
00060 if(blockSize>0){
00061 UseAlloc=1;
00062 AllocatorMatrixEntry.set(blockSize);
00063 }
00064 else{UseAlloc=0;}
00065 }
00067
00069
00071 template<class T>
00072 SparseMatrix<T>::SparseMatrix () : rows (0), rowSizes (NULL), m_ppElements (NULL)
00073 {
00074 }
00075
00077 template<class T>
00078 SparseMatrix<T>::SparseMatrix (int rows) : rows (rows), rowSizes (NULL), m_ppElements (NULL)
00079 {
00080 Resize (rows);
00081 }
00082
00084 template<class T>
00085 SparseMatrix<T>::SparseMatrix (const SparseMatrix& M) :
00086 rows (M.rows), rowSizes (M.rowSizes), m_ppElements (M.m_ppElements)
00087 {
00088 Resize (M.rows);
00089 for (int i = 0; i < rows; i++)
00090 {
00091 SetRowSize (i, M.rowSizes[i]);
00092 for (int j = 0; j < rowSizes[i]; j++)
00093 m_ppElements[i][j] = M.m_ppElements[i][j];
00094 }
00095 }
00096
00098 template<class T> int
00099 SparseMatrix<T>::Entries ()
00100 {
00101 int e = 0;
00102 for (int i = 0; i < rows; i++)
00103 e += int (rowSizes[i]);
00104
00105 return (e);
00106 }
00107
00109 template<class T>
00110 SparseMatrix<T>& SparseMatrix<T>::operator = (const SparseMatrix<T>& M)
00111 {
00112 Resize(M.rows);
00113 for (int i=0; i<rows; i++){
00114 SetRowSize(i,M.rowSizes[i]);
00115 for (int j=0; j<rowSizes[i]; j++){m_ppElements[i][j]=M.m_ppElements[i][j];}
00116 }
00117 return *this;
00118 }
00119
00121 template<class T>
00122 SparseMatrix<T>::~SparseMatrix(){Resize(0);}
00123
00125 template<class T> void
00126 SparseMatrix<T>::Resize (int r)
00127 {
00128 int i;
00129 if(rows>0){
00130 if(!UseAlloc){for(i=0;i<rows;i++){if(rowSizes[i]){free(m_ppElements[i]);}}}
00131 free(m_ppElements);
00132 free(rowSizes);
00133 }
00134 rows=r;
00135 if (r)
00136 {
00137 rowSizes = reinterpret_cast<int*> (malloc (sizeof (int) * r));
00138
00139 memset (rowSizes, 0, sizeof (int) * r);
00140
00141 m_ppElements = reinterpret_cast<MatrixEntry<T>**> (malloc (sizeof (MatrixEntry<T>*) * r));
00142 }
00143 }
00144
00146 template<class T> void
00147 SparseMatrix<T>::SetRowSize (int row, int count)
00148 {
00149 if (row >= 0 && row < rows)
00150 {
00151 if (UseAlloc)
00152 m_ppElements[row] = AllocatorMatrixEntry.newElements (count);
00153 else
00154 {
00155 if (rowSizes[row])
00156 free (m_ppElements[row]);
00157 if (count > 0)
00158 m_ppElements[row] = reinterpret_cast<MatrixEntry<T>*> (malloc (sizeof (MatrixEntry<T>) * count));
00159 }
00160 rowSizes[row] = count;
00161 }
00162 }
00163
00165 template<class T> void
00166 SparseMatrix<T>::SetZero ()
00167 {
00168 Resize (this->m_N, this->m_M);
00169 }
00170
00172 template<class T> void
00173 SparseMatrix<T>::SetIdentity ()
00174 {
00175 SetZero();
00176 for(int ij=0; ij < Min( this->Rows(), this->Columns() ); ij++)
00177 (*this)(ij,ij) = T(1);
00178 }
00179
00181 template<class T> SparseMatrix<T>
00182 SparseMatrix<T>::operator * (const T& V) const
00183 {
00184 SparseMatrix<T> M(*this);
00185 M *= V;
00186 return M;
00187 }
00188
00190 template<class T> SparseMatrix<T>&
00191 SparseMatrix<T>::operator *= (const T& V)
00192 {
00193 for (int i=0; i<this->Rows(); i++)
00194 {
00195 for(int ii=0;ii<m_ppElements[i].size();i++){m_ppElements[i][ii].Value*=V;}
00196 }
00197 return *this;
00198 }
00199
00201 template<class T> SparseMatrix<T>
00202 SparseMatrix<T>::Multiply( const SparseMatrix<T>& M ) const
00203 {
00204 SparseMatrix<T> R( this->Rows(), M.Columns() );
00205 for(int i=0; i<R.Rows(); i++){
00206 for(int ii=0;ii<m_ppElements[i].size();ii++){
00207 int N=m_ppElements[i][ii].N;
00208 T Value=m_ppElements[i][ii].Value;
00209 for(int jj=0;jj<M.m_ppElements[N].size();jj++){
00210 R(i,M.m_ppElements[N][jj].N) += Value * M.m_ppElements[N][jj].Value;
00211 }
00212 }
00213 }
00214 return R;
00215 }
00216
00218 template<class T> template<class T2> Vector<T2>
00219 SparseMatrix<T>::Multiply( const Vector<T2>& V ) const
00220 {
00221 Vector<T2> R( rows );
00222
00223 for (int i=0; i<rows; i++)
00224 {
00225 T2 temp=T2();
00226 for(int ii=0;ii<rowSizes[i];ii++){
00227 temp+=m_ppElements[i][ii].Value * V.m_pV[m_ppElements[i][ii].N];
00228 }
00229 R(i)=temp;
00230 }
00231 return R;
00232 }
00233
00235 template<class T> template<class T2> void
00236 SparseMatrix<T>::Multiply( const Vector<T2>& In,Vector<T2>& Out) const
00237 {
00238 for (int i=0; i<rows; i++){
00239 T2 temp=T2();
00240 for(int j=0;j<rowSizes[i];j++){temp+=m_ppElements[i][j].Value * In.m_pV[m_ppElements[i][j].N];}
00241 Out.m_pV[i]=temp;
00242 }
00243 }
00244
00246 template<class T> SparseMatrix<T>
00247 SparseMatrix<T>::operator * (const SparseMatrix<T>& M) const
00248 {
00249 return (Multiply (M));
00250 }
00251
00253 template<class T> template<class T2> Vector<T2>
00254 SparseMatrix<T>::operator * (const Vector<T2>& V) const
00255 {
00256 return (Multiply (V));
00257 }
00258
00260 template<class T>
00261 SparseMatrix<T> SparseMatrix<T>::Transpose() const
00262 {
00263 SparseMatrix<T> M( this->Columns(), this->Rows() );
00264
00265 for (int i=0; i<this->Rows(); i++)
00266 {
00267 for(int ii=0;ii<m_ppElements[i].size();ii++){
00268 M(m_ppElements[i][ii].N,i) = m_ppElements[i][ii].Value;
00269 }
00270 }
00271 return M;
00272 }
00273
00275 template<class T> template<class T2> int
00276 SparseMatrix<T>::SolveSymmetric(const SparseMatrix<T>& M,const Vector<T2>& b,const int& iters,Vector<T2>& solution,const T2 eps,const int& reset)
00277 {
00278 Vector<T2> d,r,Md;
00279 T2 alpha,beta,rDotR;
00280 Md.Resize(b.Dimensions());
00281 if(reset){
00282 solution.Resize(b.Dimensions());
00283 solution.SetZero();
00284 }
00285 d=r=b-M.Multiply(solution);
00286 rDotR=r.Dot(r);
00287 if(b.Dot(b)<=eps){
00288 solution.SetZero();
00289 return 0;
00290 }
00291
00292 int i;
00293 for(i=0;i<iters;i++){
00294 T2 temp;
00295 M.Multiply(d,Md);
00296 temp=d.Dot(Md);
00297 if(temp<=eps){break;}
00298 alpha=rDotR/temp;
00299 r.SubtractScaled(Md,alpha);
00300 temp=r.Dot(r);
00301 if(temp/b.Dot(b)<=eps){break;}
00302 beta=temp/rDotR;
00303 solution.AddScaled(d,alpha);
00304 if(beta<=eps){break;}
00305 rDotR=temp;
00306 Vector<T2>::Add(d,beta,r,d);
00307 }
00308 return i;
00309 }
00310
00312
00313 template<class T> int
00314 SparseMatrix<T>::Solve(const SparseMatrix<T>& M,const Vector<T>& b,const int& iters,Vector<T>& solution,const T eps)
00315 {
00316 SparseMatrix mTranspose=M.Transpose();
00317 Vector<T> bb=mTranspose*b;
00318 Vector<T> d,r,Md;
00319 T alpha,beta,rDotR;
00320 int i;
00321
00322 solution.Resize(M.Columns());
00323 solution.SetZero();
00324
00325 d=r=bb;
00326 rDotR=r.Dot(r);
00327
00328 for(i=0;i<iters && rDotR>eps;i++){
00329 T temp;
00330 Md=mTranspose*(M*d);
00331 alpha=rDotR/d.Dot(Md);
00332 solution+=d*alpha;
00333 r-=Md*alpha;
00334 temp=r.Dot(r);
00335 beta=temp/rDotR;
00336 rDotR=temp;
00337 d=r+d*beta;
00338 }
00339 return i;
00340 }
00341
00343
00346
00348 template<class T,int Dim> int SparseNMatrix<T,Dim>::UseAlloc=0;
00349 template<class T,int Dim> Allocator<NMatrixEntry<T,Dim> > SparseNMatrix<T,Dim>::AllocatorNMatrixEntry;
00350 template<class T,int Dim> int SparseNMatrix<T,Dim>::UseAllocator(void){return UseAlloc;}
00351
00353 template<class T,int Dim> void
00354 SparseNMatrix<T,Dim>::SetAllocator (const int& blockSize)
00355 {
00356 if (blockSize>0)
00357 {
00358 UseAlloc = 1;
00359 AllocatorNMatrixEntry.set (blockSize);
00360 }
00361 else
00362 UseAlloc = 0;
00363 }
00365
00367
00369 template<class T,int Dim>
00370 SparseNMatrix<T,Dim>::SparseNMatrix () : rows (0), rowSizes (NULL), m_ppElements (NULL)
00371 {
00372 }
00373
00375 template<class T,int Dim>
00376 SparseNMatrix<T,Dim>::SparseNMatrix (int rows) : rows (rows), rowSizes (NULL), m_ppElements (NULL)
00377 {
00378 Resize (rows);
00379 }
00380
00382 template<class T,int Dim>
00383 SparseNMatrix<T,Dim>::SparseNMatrix( const SparseNMatrix& M )
00384 {
00385 Resize (M.rows);
00386 for (int i = 0; i < rows; i++)
00387 {
00388 SetRowSize (i, M.rowSizes[i]);
00389 for (int j = 0; j < rowSizes[i]; j++)
00390 m_ppElements[i][j] = M.m_ppElements[i][j];
00391 }
00392 }
00393
00395 template<class T,int Dim> int
00396 SparseNMatrix<T,Dim>::Entries ()
00397 {
00398 int e = 0;
00399 for(int i = 0; i < rows; i++)
00400 e+=int (rowSizes[i]);
00401 return (e);
00402 }
00404 template<class T,int Dim>
00405 SparseNMatrix<T,Dim>& SparseNMatrix<T,Dim>::operator = (const SparseNMatrix<T,Dim>& M)
00406 {
00407 Resize(M.rows);
00408 for (int i = 0; i < rows; i++)
00409 {
00410 SetRowSize (i, M.rowSizes[i]);
00411 for (int j = 0; j < rowSizes[i]; j++)
00412 m_ppElements[i][j] = M.m_ppElements[i][j];
00413 }
00414 return (*this);
00415 }
00416
00418 template<class T,int Dim>
00419 SparseNMatrix<T,Dim>::~SparseNMatrix ()
00420 {
00421 Resize (0);
00422 }
00423
00425 template<class T,int Dim> void
00426 SparseNMatrix<T,Dim>::Resize (int r)
00427 {
00428 int i;
00429 if (rows > 0)
00430 {
00431 if (!UseAlloc)
00432 for (i = 0; i < rows; i++)
00433 if (rowSizes[i])
00434 free (m_ppElements[i]);
00435 free (m_ppElements);
00436 free (rowSizes);
00437 }
00438 rows = r;
00439 if (r)
00440 {
00441 rowSizes = reinterpret_cast<int*> (malloc (sizeof (int) *r));
00442 memset (rowSizes, 0, sizeof (int) * r);
00443 m_ppElements = reinterpret_cast<NMatrixEntry<T,Dim>**> (malloc (sizeof (NMatrixEntry<T,Dim>*) * r));
00444 }
00445 }
00446
00448 template<class T,int Dim> void
00449 SparseNMatrix<T,Dim>::SetRowSize (int row,int count)
00450 {
00451 if (row >= 0 && row < rows)
00452 {
00453 if (UseAlloc)
00454 m_ppElements[row] = AllocatorNMatrixEntry.newElements (count);
00455 else
00456 {
00457 if (rowSizes[row])
00458 free (m_ppElements[row]);
00459 if (count>0)
00460 m_ppElements[row] = reinterpret_cast<NMatrixEntry<T,Dim>*> (malloc (sizeof (NMatrixEntry<T,Dim>) * count));
00461 }
00462 rowSizes[row]=count;
00463 }
00464 }
00465
00467 template<class T,int Dim>
00468 SparseNMatrix<T,Dim> SparseNMatrix<T,Dim>::operator * (const T& V) const
00469 {
00470 SparseNMatrix<T,Dim> M (*this);
00471 M *= V;
00472 return (M);
00473 }
00474
00476 template<class T,int Dim>
00477 SparseNMatrix<T,Dim>& SparseNMatrix<T,Dim>::operator *= (const T& V)
00478 {
00479 for (int i = 0; i < this->Rows (); i++)
00480 for (int ii = 0; ii < m_ppElements[i].size (); i++)
00481 for (int jj = 0; jj < Dim; jj++)
00482 m_ppElements[i][ii].Value[jj] *= V;
00483 return (*this);
00484 }
00485
00487 template<class T,int Dim> template<class T2>
00488 NVector<T2,Dim> SparseNMatrix<T,Dim>::operator * (const Vector<T2>& V) const
00489 {
00490 NVector<T2,Dim> R (rows);
00491
00492 for (int i = 0; i < rows; i++)
00493 {
00494 T2 temp[Dim];
00495 for (int ii = 0; ii < Dim; ii++)
00496 temp[ii] = T2 ();
00497 for (int ii = 0; ii < rowSizes[i]; ii++)
00498 for (int jj = 0; jj < Dim; jj++)
00499 temp[jj] += m_ppElements[i][ii].Value[jj] * V.m_pV[m_ppElements[i][jj].N];
00500 for (int ii = 0; ii < Dim; ii++)
00501 R[i][ii] = temp[ii];
00502 }
00503 return (R);
00504 }
00505
00507 template<class T,int Dim> template<class T2> Vector<T2>
00508 SparseNMatrix<T,Dim>::operator * (const NVector<T2,Dim>& V) const
00509 {
00510 Vector<T2> R (rows);
00511
00512 for (int i=0; i<rows; i++)
00513 {
00514 T2 temp ();
00515 for (int ii = 0; ii < rowSizes[i]; ii++)
00516 {
00517 for (int jj = 0; jj < Dim; jj++)
00518 {
00519 temp += m_ppElements[i][ii].Value[jj] * V.m_pV[m_ppElements[i][ii].N][jj];
00520 }
00521 }
00522 R(i) =temp;
00523 }
00524 return (R);
00525 }
00526
00528
00531 template<class T> template<class T2> Vector<T2>
00532 SparseSymmetricMatrix<T>::operator * (const Vector<T2>& V) const
00533 {
00534 return (Multiply (V));
00535 }
00536
00538 template<class T> template<class T2> Vector<T2>
00539 SparseSymmetricMatrix<T>::Multiply (const Vector<T2>& V) const
00540 {
00541 Vector<T2> R (this->rows);
00542
00543 for (int i = 0; i < this->rows; i++)
00544 {
00545 for (int ii = 0; ii < this->rowSizes[i]; ii++)
00546 {
00547 int j = this->m_ppElements[i][ii].N;
00548 R(i) += this->m_ppElements[i][ii].Value * V.m_pV[j];
00549 R(j) += this->m_ppElements[i][ii].Value * V.m_pV[i];
00550 }
00551 }
00552 return (R);
00553 }
00554
00556 template<class T> template<class T2> void
00557 SparseSymmetricMatrix<T>::Multiply (const Vector<T2>& In,Vector<T2>& Out) const
00558 {
00559 Out.SetZero ();
00560 for (int i = 0; i < this->rows; i++)
00561 {
00562 MatrixEntry<T>* temp = this->m_ppElements[i];
00563 T2& in1 = In.m_pV[i];
00564 T2& out1 = Out.m_pV[i];
00565 int rs = this->rowSizes[i];
00566 for (int ii = 0; ii <rs; ii++)
00567 {
00568 MatrixEntry<T>& temp2 = temp[ii];
00569 int j = temp2.N;
00570 T2 v = temp2.Value;
00571 out1 += v * In.m_pV[j];
00572 Out.m_pV[j] += v * in1;
00573 }
00574 }
00575 }
00576
00578 template<class T> template<class T2> int
00579 SparseSymmetricMatrix<T>::Solve (
00580 const SparseSymmetricMatrix<T>& M,
00581 const Vector<T2>& b,
00582 const int& iters,
00583 Vector<T2>& solution,
00584 const T2 eps,
00585 const int& reset)
00586 {
00587 Vector<T2> d, r, Md;
00588 T2 alpha,beta,rDotR,bDotB;
00589 Md.Resize (b.Dimensions ());
00590 if (reset)
00591 {
00592 solution.Resize (b.Dimensions ());
00593 solution.SetZero ();
00594 }
00595 d = r = b - M.Multiply (solution);
00596 rDotR = r.Dot (r);
00597 bDotB = b.Dot (b);
00598 if (b.Dot (b) <= eps)
00599 {
00600 solution.SetZero ();
00601 return (0);
00602 }
00603 int i;
00604 for (i = 0; i < iters; i++)
00605 {
00606 T2 temp;
00607 M.Multiply (d, Md);
00608 temp = d.Dot (Md);
00609 if (fabs (temp) <= eps)
00610 break;
00611 alpha = rDotR / temp;
00612
00613 r.SubtractScaled (Md, alpha);
00614 temp = r.Dot (r);
00615
00616 if (temp / bDotB <= eps)
00617 break;
00618
00619 beta = temp / rDotR;
00620 solution.AddScaled (d, alpha);
00621 if (beta<=eps)
00622 break;
00623 rDotR = temp;
00624 Vector<T2>::Add (d, beta, r, d);
00625 }
00626 return i;
00627 }
00628
00630 template<class T> template<class T2> int
00631 SparseSymmetricMatrix<T>::Solve (
00632 const SparseSymmetricMatrix<T>& M,
00633 const Vector<T>& diagonal,
00634 const Vector<T2>& b,
00635 const int& iters,
00636 Vector<T2>& solution,
00637 const T2 eps,
00638 const int& reset)
00639 {
00640 Vector<T2> d, r, Md;
00641
00642 if (reset)
00643 {
00644 solution.Resize (b.Dimensions ());
00645 solution.SetZero ();
00646 }
00647 Md.Resize (M.rows);
00648 for (int i = 0; i <iters; i++)
00649 {
00650 M.Multiply (solution, Md);
00651 r = b - Md;
00652 for (int j = 0; j < int (M.rows); j++)
00653 solution[j] += r[j] / diagonal[j];
00654 }
00655 return (iters);
00656 }
00657 }
00658 }