![]() |
TAPs 0.7.7.3
|
00001 /****************************************************************************** 00002 TAPsSparseMatrix_Matrix3x3.cpp 00003 ******************************************************************************/ 00007 /****************************************************************************** 00008 SUKITTI PUNAK (12/22/2009) 00009 UPDATE (04/10/2010) 00010 ******************************************************************************/ 00011 #include "TAPsSparseMatrix_Matrix3x3.hpp" 00012 // Using Inclusion Model (i.e. definitions are included in declarations) 00013 // (this name.cpp is included in name.hpp) 00014 // Each friend is defined directly inside its declaration. 00015 00016 BEGIN_NAMESPACE_TAPs 00017 //============================================================================= 00018 // Constructors 00019 //----------------------------------------------------------------------------- 00020 template <typename T> 00021 SparseMatrix_Matrix3x3<T>::SparseMatrix_Matrix3x3 ( unsigned int numOfRows ) 00022 { 00023 m_Rows.resize( numOfRows ); 00024 } 00025 //----------------------------------------------------------------------------- 00026 template <typename T> 00027 SparseMatrix_Matrix3x3<T>::SparseMatrix_Matrix3x3 ( SparseMatrix_Matrix3x3<T> const &orig ) 00028 { 00029 *this = orig; 00030 } 00031 //----------------------------------------------------------------------------- 00032 template <typename T> 00033 SparseMatrix_Matrix3x3<T>::~SparseMatrix_Matrix3x3 () 00034 {} 00035 //----------------------------------------------------------------------------- 00036 template <typename T> 00037 std::string SparseMatrix_Matrix3x3<T>::StrInfo () const 00038 { 00039 std::ostringstream ss; 00040 ss << "SparseMatrix_Matrix3x3<" << typeid(T).name() << "> has " << m_Rows.size() << " rows:\n"; 00041 std::list< SparseVector_Matrix3x3<T> >::const_iterator it = m_Rows.begin(); 00042 unsigned int r = 0; 00043 00045 //while ( it != m_Rows.end() ) { 00046 // ss << "Row# " << r++ << ":\t" << *it; 00047 // ++it; 00048 //} 00049 00050 // Print in matrix format 00051 it = m_Rows.begin(); 00052 Matrix3x3<T> *M = new Matrix3x3<T>[m_Rows.size()]; 00053 Matrix3x3<T> const *N; 00054 for ( unsigned int i = 0; i < m_Rows.size(); ++i ) { 00055 for ( unsigned int j = 0; j < m_Rows.size(); ++j ) { 00056 if ( N = it->ReturnMatrix3x3( j ) ) { 00057 M[j] = *N; 00058 } 00059 else { 00060 M[j].MakeZero(); 00061 } 00062 } 00063 unsigned int j; 00064 for ( unsigned int r = 0; r < 9; r+=3 ) { 00065 ss << "[ "; 00066 for ( j = 0; j < m_Rows.size()-1; ++j ) { 00067 ss.width(12); 00068 ss << M[j][0+r] << ", "; 00069 ss.width(12); 00070 ss << M[j][1+r] << ", "; 00071 ss.width(12); 00072 ss << M[j][2+r] << ", "; 00073 } 00074 ss.width(12); 00075 ss << M[j][0+r] << ", "; 00076 ss.width(12); 00077 ss << M[j][1+r] << ", "; 00078 ss.width(12); 00079 ss << M[j][2+r]; 00080 ss << " ]\n"; 00081 } 00082 ++it; 00083 } 00084 delete [] M; 00085 00086 return ss.str(); 00087 } 00088 //----------------------------------------------------------------------------- 00089 //============================================================================= 00090 // Assignment Operator 00091 //----------------------------------------------------------------------------- 00092 template <typename T> 00093 SparseMatrix_Matrix3x3<T> & SparseMatrix_Matrix3x3<T>::operator= ( SparseMatrix_Matrix3x3<T> const &orig ) 00094 { 00095 m_Rows = orig.m_Rows; 00096 if ( orig.m_DirectAccessors.size() > 0 ) { 00097 this->SetDirectAccessors(); 00098 } 00099 return *this; 00100 } 00102 //template <typename T> 00103 //SparseMatrix_Matrix3x3<T> & SparseMatrix_Matrix3x3<T>::operator= ( SparseSymmetricMatrix_Matrix3x3<T> &orig ) 00104 //{ 00105 // if ( orig.GetNumOfRows() == 0 ) { 00106 // m_Rows.clear(); 00107 // return *this; 00108 // } 00109 // 00110 // //orig.SetDirectAccessors(); 00111 // 00112 // m_Rows.resize( orig.GetNumOfRows() ); 00113 // for ( unsigned int r = 0; r < GetNumOfRows(); ++r ) { 00114 // } 00115 // 00116 // this->SetDirectAccessors(); 00117 // 00118 // std::list< SparseVector_Matrix3x3_ElementData<T> >::iterator it; 00119 // for ( unsigned int r = 0; r < GetNumOfRows(); ++r ) { 00120 // it = orig.DirectAccess( r )->RefToElements().begin(); 00121 // while ( it != (orig.DirectAccess( r ))->RefToElements().end() ) { 00122 // unsigned int c = it->idx; 00123 // if ( c == r ) { 00124 // this->DirectAccess( r )->Insert( c, it->M ); 00125 // } 00126 // else { 00127 // this->DirectAccess( c )->Insert( c, it->M ); 00128 // this->DirectAccess( r )->Insert( c, it->M ); 00129 // } 00130 // ++it; 00131 // } 00132 // } 00133 // 00134 // this->SetDirectAccessors(); 00135 // 00136 // return *this; 00137 // RESULT IS NOT CORRECT DUE TO THE CHANGING OF STD DATA LOCATION!!! 00138 //} 00139 //----------------------------------------------------------------------------- 00140 template <typename T> 00141 void SparseMatrix_Matrix3x3<T>::SetTo ( SparseMatrix_Matrix3x3<T> const &orig ) 00142 { 00143 assert( m_Rows.size() == orig.m_Rows.size() ); 00144 std::list< SparseVector_Matrix3x3<T> >::const_iterator A = orig.m_Rows.begin(); 00145 std::list< SparseVector_Matrix3x3<T> >::iterator B = m_Rows.begin(); 00146 while ( B != m_Rows.end() ) { 00147 B->SetTo( *A ); 00148 ++A; 00149 ++B; 00150 } 00151 } 00152 //----------------------------------------------------------------------------- 00153 //============================================================================= 00154 00155 //============================================================================= 00156 // Operations 00157 //----------------------------------------------------------------------------- 00158 template <typename T> 00159 void SparseMatrix_Matrix3x3<T>::MulWith ( 00160 std::vector< Vector3<T> > const &I, 00161 std::vector< Vector3<T> > &O 00162 ) const 00163 { 00164 unsigned int r = 0; 00165 std::list< SparseVector_Matrix3x3<T> >::const_iterator it = m_Rows.begin(); 00166 while ( it != m_Rows.end() ) { 00167 O[r] = it->Mul( I ); 00168 ++r; 00169 ++it; 00170 } 00171 } 00172 //----------------------------------------------------------------------------- 00173 template <typename T> 00174 void SparseMatrix_Matrix3x3<T>::MulWith_wSkippedRows ( 00175 std::vector< Vector3<T> > const &I, 00176 std::vector< Vector3<T> > &O, 00177 std::vector< bool > const &rowsFixStatus, 00178 T diagval 00179 ) const 00180 { 00181 unsigned int r = 0; 00182 std::list< SparseVector_Matrix3x3<T> >::const_iterator it = m_Rows.begin(); 00183 while ( it != m_Rows.end() ) { 00184 if ( rowsFixStatus[r] ) { 00185 O[r][0] = diagval * I[r][0]; 00186 O[r][1] = diagval * I[r][1]; 00187 O[r][2] = diagval * I[r][2]; 00188 } 00189 else { 00190 O[r] = it->Mul( I ); 00191 } 00192 ++r; 00193 ++it; 00194 } 00195 } 00196 //----------------------------------------------------------------------------- 00197 template <typename T> 00198 void SparseMatrix_Matrix3x3<T>::MulWith_wSkippedCols ( 00199 std::vector< Vector3<T> > const &I, 00200 std::vector< Vector3<T> > &O, 00201 std::vector< bool > const &colsFixStatus, 00202 T diagval 00203 ) const 00204 { 00205 // Since all diagonal is one therefore, at least O will be I. 00206 for ( unsigned int i = 0; i < I.size(); ++i ) { 00207 O[i].Clear(); 00208 } 00209 unsigned int r = 0; 00210 std::list< SparseVector_Matrix3x3<T> >::const_iterator row = m_Rows.begin(); 00211 while ( row != m_Rows.end() ) { 00212 std::list< SparseVector_Matrix3x3_ElementData<T> >::const_iterator vec = row->RefToElements().begin(); 00213 while ( vec != row->RefToElements().end() ) { 00214 if ( !colsFixStatus[vec->idx] ) { 00215 O[r] += vec->M * I[vec->idx]; 00216 } 00217 else if ( vec->idx == r ) { 00218 O[r][0] += diagval * I[vec->idx][0]; 00219 O[r][1] += diagval * I[vec->idx][1]; 00220 O[r][2] += diagval * I[vec->idx][2]; 00221 } 00222 ++vec; 00223 } 00224 ++r; 00225 ++row; 00226 } 00227 } 00228 //----------------------------------------------------------------------------- 00229 template <typename T> 00230 void SparseMatrix_Matrix3x3<T>::MulWith_wSkippedRowsCols ( 00231 std::vector< Vector3<T> > const &I, 00232 std::vector< Vector3<T> > &O, 00233 std::vector< bool > const &rowscolsFixStatus, 00234 T diagval 00235 ) const 00236 { 00237 // Since all diagonal is one therefore, at least O will be I. 00238 for ( unsigned int i = 0; i < I.size(); ++i ) { 00239 O[i].Clear(); 00240 } 00241 unsigned int r = 0; 00242 std::list< SparseVector_Matrix3x3<T> >::const_iterator row = m_Rows.begin(); 00243 while ( row != m_Rows.end() ) { 00244 if ( !rowscolsFixStatus[r] ) 00245 { 00246 std::list< SparseVector_Matrix3x3_ElementData<T> >::const_iterator vec = row->RefToElements().begin(); 00247 while ( vec != row->RefToElements().end() ) { 00248 if ( !rowscolsFixStatus[vec->idx] ) 00249 { 00250 O[r] += vec->M * I[vec->idx]; 00251 } 00252 ++vec; 00253 } 00254 } 00255 else { 00256 O[r][0] = diagval * I[r][0]; 00257 O[r][1] = diagval * I[r][1]; 00258 O[r][2] = diagval * I[r][2]; 00259 } 00260 ++r; 00261 ++row; 00262 } 00263 } 00264 //----------------------------------------------------------------------------- 00265 template <typename T> 00266 void SparseMatrix_Matrix3x3<T>::ChangeNumOfRows ( unsigned int numOfRows ) 00267 { 00268 m_Rows.resize( numOfRows ); 00269 } 00270 00271 00272 00273 00274 //============================================================================= 00275 // START of Diagonalizes WITH A SPECIFIED VALUE 00276 //----------------------------------------------------------------------------- 00277 template <typename T> 00278 void SparseMatrix_Matrix3x3<T>::DiagonalizeRow ( unsigned int row, T diagonalValue ) 00279 { 00280 std::list< SparseVector_Matrix3x3_ElementData<T> >::iterator data = DirectAccess( row )->RefToElements().begin(); 00281 while ( data != DirectAccess( row )->RefToElements().end() ) { 00282 if ( data->idx == row ) { 00283 data->M.MakeDiagonal( diagonalValue ); 00284 } 00285 else { 00286 data->M.MakeZero(); 00287 } 00288 ++data; 00289 } 00290 } 00291 //----------------------------------------------------------------------------- 00292 template <typename T> 00293 void SparseMatrix_Matrix3x3<T>::DiagonalizeRows ( 00294 std::vector< bool > const & rows, 00295 T diagonalValue = 1 00296 ) 00297 { 00298 for ( unsigned int r = 0; r < rows.size(); ++r ) { 00299 if ( rows[r] ) { 00300 std::list< SparseVector_Matrix3x3_ElementData<T> >::iterator data = DirectAccess( r )->RefToElements().begin(); 00301 while ( data != DirectAccess( r )->RefToElements().end() ) { 00302 if ( data->idx == r ) { 00303 data->M.MakeDiagonal( diagonalValue ); 00304 } 00305 else { 00306 data->M.MakeZero(); 00307 } 00308 ++data; 00309 } 00310 } 00311 } 00312 } 00313 //----------------------------------------------------------------------------- 00314 template <typename T> 00315 void SparseMatrix_Matrix3x3<T>::DiagonalizeRows ( 00316 std::vector< unsigned int > const & rows, 00317 T diagonalValue = 1 00318 ) 00319 { 00320 for ( unsigned int r = 0; r < rows.size(); ++r ) { 00321 std::list< SparseVector_Matrix3x3_ElementData<T> >::iterator data = DirectAccess( rows[r] )->RefToElements().begin(); 00322 while ( data != DirectAccess( rows[r] )->RefToElements().end() ) { 00323 if ( data->idx == rows[r] ) { 00324 data->M.MakeDiagonal( diagonalValue ); 00325 } 00326 else { 00327 data->M.MakeZero(); 00328 } 00329 ++data; 00330 } 00331 } 00332 } 00333 //----------------------------------------------------------------------------- 00334 template <typename T> 00335 void SparseMatrix_Matrix3x3<T>::DiagonalizeCol ( unsigned int col, T diagonalValue ) 00336 { 00337 for ( unsigned int r = 0; r < m_Rows.size(); ++r ) { 00338 std::list< SparseVector_Matrix3x3_ElementData<T> >::iterator data = DirectAccess( r )->RefToElements().begin(); 00339 while ( data != DirectAccess( r )->RefToElements().end() ) { 00340 if ( data->idx == col ) { 00341 if ( data->idx == r ) { 00342 data->M.MakeDiagonal( diagonalValue ); 00343 } 00344 else { 00345 data->M.MakeZero(); 00346 } 00347 } 00348 ++data; 00349 } 00350 } 00351 } 00352 //----------------------------------------------------------------------------- 00353 template <typename T> 00354 void SparseMatrix_Matrix3x3<T>::DiagonalizeCols ( 00355 std::vector< bool > const & cols, 00356 T diagonalValue = 1 00357 ) 00358 { 00359 for ( unsigned int r = 0; r < m_Rows.size(); ++r ) { 00360 std::list< SparseVector_Matrix3x3_ElementData<T> >::iterator data = DirectAccess( r )->RefToElements().begin(); 00361 while ( data != DirectAccess( r )->RefToElements().end() ) { 00362 if ( cols[ data->idx ] ) { 00363 if ( data->idx == r ) { 00364 data->M.MakeDiagonal( diagonalValue ); 00365 } 00366 else { 00367 data->M.MakeZero(); 00368 } 00369 } 00370 ++data; 00371 } 00372 } 00373 } 00374 //----------------------------------------------------------------------------- 00375 template <typename T> 00376 void SparseMatrix_Matrix3x3<T>::DiagonalizeRowCol ( unsigned int rowcol, T diagonalValue ) 00377 { 00378 for ( unsigned int r = 0; r < m_Rows.size(); ++r ) { 00379 std::list< SparseVector_Matrix3x3_ElementData<T> >::iterator data = DirectAccess( r )->RefToElements().begin(); 00380 if ( rowcol == r ) { 00381 while ( data != DirectAccess( r )->RefToElements().end() ) { 00382 if ( data->idx == r ) { 00383 data->M.MakeDiagonal( diagonalValue ); 00384 } 00385 else { 00386 data->M.MakeZero(); 00387 } 00388 ++data; 00389 } 00390 } 00391 else { 00392 while ( data != DirectAccess( r )->RefToElements().end() ) { 00393 if ( data->idx == rowcol ) { 00394 if ( data->idx == r ) { 00395 data->M.MakeDiagonal( diagonalValue ); 00396 } 00397 else { 00398 data->M.MakeZero(); 00399 } 00400 } 00401 ++data; 00402 } 00403 } 00404 } 00405 } 00406 //----------------------------------------------------------------------------- 00407 template <typename T> 00408 void SparseMatrix_Matrix3x3<T>::DiagonalizeRowsCols ( 00409 std::vector< bool > const & rowscols, 00410 T diagonalValue = 1 00411 ) 00412 { 00413 for ( unsigned int r = 0; r < m_Rows.size(); ++r ) { 00414 std::list< SparseVector_Matrix3x3_ElementData<T> >::iterator data = DirectAccess( r )->RefToElements().begin(); 00415 if ( rowscols[r] ) { 00416 while ( data != DirectAccess( r )->RefToElements().end() ) { 00417 if ( data->idx == r ) { 00418 data->M.MakeDiagonal( diagonalValue ); 00419 } 00420 else { 00421 data->M.MakeZero(); 00422 } 00423 ++data; 00424 } 00425 } 00426 else { 00427 while ( data != DirectAccess( r )->RefToElements().end() ) { 00428 if ( rowscols[ data->idx ] ) { 00429 if ( data->idx == r ) { 00430 data->M.MakeDiagonal( diagonalValue ); 00431 } 00432 else { 00433 data->M.MakeZero(); 00434 } 00435 } 00436 ++data; 00437 } 00438 } 00439 } 00440 } 00441 //----------------------------------------------------------------------------- 00442 // END of Diagonalizes WITH A SPECIFIED VALUE 00443 //============================================================================= 00444 00445 00446 00447 00448 //============================================================================= 00449 // START of Diagonalizes 00450 //----------------------------------------------------------------------------- 00451 template <typename T> 00452 void SparseMatrix_Matrix3x3<T>::DiagonalizeRow ( unsigned int row ) 00453 { 00454 std::list< SparseVector_Matrix3x3_ElementData<T> >::iterator data = DirectAccess( row )->RefToElements().begin(); 00455 while ( data != DirectAccess( row )->RefToElements().end() ) { 00456 if ( data->idx == row ) { 00457 data->M[1] = data->M[2] = data->M[3] = 0; 00458 data->M[5] = data->M[6] = data->M[7] = 0; 00459 } 00460 else { 00461 data->M.MakeZero(); 00462 } 00463 ++data; 00464 } 00465 } 00466 //----------------------------------------------------------------------------- 00467 template <typename T> 00468 void SparseMatrix_Matrix3x3<T>::DiagonalizeRows ( 00469 std::vector< bool > const & rows 00470 ) 00471 { 00472 for ( unsigned int r = 0; r < rows.size(); ++r ) { 00473 if ( rows[r] ) { 00474 std::list< SparseVector_Matrix3x3_ElementData<T> >::iterator data = DirectAccess( r )->RefToElements().begin(); 00475 while ( data != DirectAccess( r )->RefToElements().end() ) { 00476 if ( data->idx == r ) { 00477 data->M[1] = data->M[2] = data->M[3] = 0; 00478 data->M[5] = data->M[6] = data->M[7] = 0; 00479 } 00480 else { 00481 data->M.MakeZero(); 00482 } 00483 ++data; 00484 } 00485 } 00486 } 00487 } 00488 //----------------------------------------------------------------------------- 00489 template <typename T> 00490 void SparseMatrix_Matrix3x3<T>::DiagonalizeRows ( 00491 std::vector< unsigned int > const & rows 00492 ) 00493 { 00494 for ( unsigned int r = 0; r < rows.size(); ++r ) { 00495 std::list< SparseVector_Matrix3x3_ElementData<T> >::iterator data = DirectAccess( rows[r] )->RefToElements().begin(); 00496 while ( data != DirectAccess( rows[r] )->RefToElements().end() ) { 00497 if ( data->idx == rows[r] ) { 00498 data->M[1] = data->M[2] = data->M[3] = 0; 00499 data->M[5] = data->M[6] = data->M[7] = 0; 00500 } 00501 else { 00502 data->M.MakeZero(); 00503 } 00504 ++data; 00505 } 00506 } 00507 } 00508 //----------------------------------------------------------------------------- 00509 template <typename T> 00510 void SparseMatrix_Matrix3x3<T>::DiagonalizeCol ( unsigned int col ) 00511 { 00512 for ( unsigned int r = 0; r < m_Rows.size(); ++r ) { 00513 std::list< SparseVector_Matrix3x3_ElementData<T> >::iterator data = DirectAccess( r )->RefToElements().begin(); 00514 while ( data != DirectAccess( r )->RefToElements().end() ) { 00515 if ( data->idx == col ) { 00516 if ( data->idx == r ) { 00517 data->M[1] = data->M[2] = data->M[3] = 0; 00518 data->M[5] = data->M[6] = data->M[7] = 0; 00519 } 00520 else { 00521 data->M.MakeZero(); 00522 } 00523 } 00524 ++data; 00525 } 00526 } 00527 } 00528 //----------------------------------------------------------------------------- 00529 template <typename T> 00530 void SparseMatrix_Matrix3x3<T>::DiagonalizeCols ( 00531 std::vector< bool > const & cols 00532 ) 00533 { 00534 for ( unsigned int r = 0; r < m_Rows.size(); ++r ) { 00535 std::list< SparseVector_Matrix3x3_ElementData<T> >::iterator data = DirectAccess( r )->RefToElements().begin(); 00536 while ( data != DirectAccess( r )->RefToElements().end() ) { 00537 if ( cols[ data->idx ] ) { 00538 if ( data->idx == r ) { 00539 data->M[1] = data->M[2] = data->M[3] = 0; 00540 data->M[5] = data->M[6] = data->M[7] = 0; 00541 } 00542 else { 00543 data->M.MakeZero(); 00544 } 00545 } 00546 ++data; 00547 } 00548 } 00549 } 00550 //----------------------------------------------------------------------------- 00551 template <typename T> 00552 void SparseMatrix_Matrix3x3<T>::DiagonalizeRowCol ( unsigned int rowcol ) 00553 { 00554 for ( unsigned int r = 0; r < m_Rows.size(); ++r ) { 00555 std::list< SparseVector_Matrix3x3_ElementData<T> >::iterator data = DirectAccess( r )->RefToElements().begin(); 00556 if ( rowcol == r ) { 00557 while ( data != DirectAccess( r )->RefToElements().end() ) { 00558 if ( data->idx == r ) { 00559 data->M[1] = data->M[2] = data->M[3] = 0; 00560 data->M[5] = data->M[6] = data->M[7] = 0; 00561 } 00562 else { 00563 data->M.MakeZero(); 00564 } 00565 ++data; 00566 } 00567 } 00568 else { 00569 while ( data != DirectAccess( r )->RefToElements().end() ) { 00570 if ( data->idx == rowcol ) { 00571 if ( data->idx == r ) { 00572 data->M[1] = data->M[2] = data->M[3] = 0; 00573 data->M[5] = data->M[6] = data->M[7] = 0; 00574 } 00575 else { 00576 data->M.MakeZero(); 00577 } 00578 } 00579 ++data; 00580 } 00581 } 00582 } 00583 } 00584 //----------------------------------------------------------------------------- 00585 template <typename T> 00586 void SparseMatrix_Matrix3x3<T>::DiagonalizeRowsCols ( 00587 std::vector< bool > const & rowscols 00588 ) 00589 { 00590 for ( unsigned int r = 0; r < m_Rows.size(); ++r ) { 00591 std::list< SparseVector_Matrix3x3_ElementData<T> >::iterator data = DirectAccess( r )->RefToElements().begin(); 00592 if ( rowscols[r] ) { 00593 while ( data != DirectAccess( r )->RefToElements().end() ) { 00594 if ( data->idx == r ) { 00595 data->M[1] = data->M[2] = data->M[3] = 0; 00596 data->M[5] = data->M[6] = data->M[7] = 0; 00597 } 00598 else { 00599 data->M.MakeZero(); 00600 } 00601 ++data; 00602 } 00603 } 00604 else { 00605 while ( data != DirectAccess( r )->RefToElements().end() ) { 00606 if ( rowscols[ data->idx ] ) { 00607 if ( data->idx == r ) { 00608 data->M[1] = data->M[2] = data->M[3] = 0; 00609 data->M[5] = data->M[6] = data->M[7] = 0; 00610 } 00611 else { 00612 data->M.MakeZero(); 00613 } 00614 } 00615 ++data; 00616 } 00617 } 00618 } 00619 } 00620 //----------------------------------------------------------------------------- 00621 // END of Diagonalizes WITH A SPECIFIED VALUE 00622 //============================================================================= 00623 00624 00625 00626 00627 //----------------------------------------------------------------------------- 00628 template <typename T> 00629 void SparseMatrix_Matrix3x3<T>::SetDirectAccessors () 00630 { 00631 m_DirectAccessors.resize( m_Rows.size() ); 00632 unsigned int n = 0; 00633 std::list< SparseVector_Matrix3x3<T> >::iterator it = m_Rows.begin(); 00634 while ( it != m_Rows.end() ) { 00635 m_DirectAccessors[n++] = &(*it); 00636 ++it; 00637 } 00638 } 00639 //----------------------------------------------------------------------------- 00640 template <typename T> 00641 SparseVector_Matrix3x3<T> * const SparseMatrix_Matrix3x3<T>::DirectAccess ( unsigned int row ) 00642 { 00643 return m_DirectAccessors[row]; 00644 } 00645 //----------------------------------------------------------------------------- 00646 template <typename T> 00647 void SparseMatrix_Matrix3x3<T>::MPCGSolver ( 00648 SparseMatrix_Matrix3x3<T> const &A, 00649 std::vector< Vector3<T> > const &x, 00650 std::vector< Vector3<T> > const &b, 00651 std::vector< Vector3<T> > &x_out, 00652 std::vector< Vector3<T> > const &ft, 00653 std::vector< Vector3<T> > const &P, 00654 int iterationLimit = 100, 00655 T errorThreshold = 1E-10 00656 ) 00657 { 00658 //std::cout << "START MPCGSolver() ------------------------------------------" << std::endl; 00659 00660 unsigned int size = b.size(); 00661 00662 // inputs 00663 // A, x, b, x_out, ft, P 00664 // temps 00665 std::vector< Vector3<T> > v( size ); 00666 T D0, Dold, Dnew, alpha; 00667 std::vector< Vector3<T> > Pinv( size ); 00668 std::vector< Vector3<T> > r( size ); 00669 std::vector< Vector3<T> > s( size ); 00670 std::vector< Vector3<T> > c( size ); 00671 std::vector< Vector3<T> > q( size ); 00672 00673 // x_out = x 00674 // D0 = Filter(b)^T.P.Filter(b) 00675 D0 = 0; 00676 Vector3<T> filterB; 00677 for ( unsigned int i = 0; i < size; ++i ) { 00678 // x_out 00679 x_out[i][0] = x[i][0]; 00680 x_out[i][1] = x[i][1]; 00681 x_out[i][2] = x[i][2]; 00682 // D0 00683 filterB[0] = ft[i][0]*b[i][0]; 00684 filterB[1] = ft[i][1]*b[i][1]; 00685 filterB[2] = ft[i][2]*b[i][2]; 00686 D0 += filterB[0]*filterB[0]*P[i][0] + filterB[1]*filterB[1]*P[i][1] + filterB[2]*filterB[2]*P[i][2]; 00687 } 00688 // r = Filter(b - A.x_out) 00689 // c = Filter(P^{-1}.r) 00690 // Dnew = r^{T}.c 00691 Dnew = 0; 00692 A.MulWith( x_out, v ); // v = A.x_out 00693 00694 // DEBUG 00695 //std::cout << "x_out (from nonsym):\n" << DEBUG_ToStr(x_out) << "\n"; 00696 //std::cout << "v = A.x_out:\n" << DEBUG_ToStr(v) << "\n"; 00697 00698 for ( unsigned int i = 0; i < size; ++i ) { 00699 // r 00700 r[i][0] = b[i][0] - v[i][0]; 00701 r[i][1] = b[i][1] - v[i][1]; 00702 r[i][2] = b[i][2] - v[i][2]; 00703 r[i][0] = ft[i][0]*r[i][0]; 00704 r[i][1] = ft[i][1]*r[i][1]; 00705 r[i][2] = ft[i][2]*r[i][2]; 00706 // c 00707 Pinv[i][0] = T(1) / P[i][0]; 00708 Pinv[i][1] = T(1) / P[i][1]; 00709 Pinv[i][2] = T(1) / P[i][2]; 00710 c[i][0] = Pinv[i][0] * r[i][0]; 00711 c[i][1] = Pinv[i][1] * r[i][1]; 00712 c[i][2] = Pinv[i][2] * r[i][2]; 00713 c[i][0] = ft[i][0]*c[i][0]; 00714 c[i][1] = ft[i][1]*c[i][1]; 00715 c[i][2] = ft[i][2]*c[i][2]; 00716 // Dnew 00717 Dnew += r[i] * c[i]; 00718 } 00719 00720 //D0 = Dnew; 00721 00722 int count = 0; 00723 T err = 1; 00724 T ths = errorThreshold * errorThreshold * D0 * D0; 00725 00726 /* 00727 std::cout << "ft:\n" << DEBUG_ToStr(ft) << "\n"; 00728 std::cout << "P:\n" << DEBUG_ToStr(P) << "\n"; 00729 std::cout << "Pinv:\n" << DEBUG_ToStr(Pinv) << "\n"; 00730 std::cout << "D0:\n" << D0 << "\n"; 00731 std::cout << "x_out:\n" << DEBUG_ToStr(x_out) << "\n"; 00732 std::cout << "r:\n" << DEBUG_ToStr(r) << "\n"; 00733 std::cout << "c:\n" << DEBUG_ToStr(c) << "\n"; 00734 std::cout << "Dnew:\n" << Dnew << "\n"; 00735 00736 std::cout << "count: " << count << ";\t"; 00737 std::cout << "error: " << err << "\n"; 00738 //*/ 00739 00740 while ( err > 0 && count < iterationLimit ) { 00741 00742 // q = Filter(A.c) 00743 // alpha = Dnew / (c^T.q) 00744 T tmp = 0; 00745 A.MulWith( c, v ); // v = A.c 00746 00747 // DEBUG 00748 //std::cout << "c (from nonsym):\n" << DEBUG_ToStr(c) << "\n"; 00749 //std::cout << "v = A.c:\n" << DEBUG_ToStr(v) << "\n"; 00750 00751 for ( unsigned int i = 0; i < size; ++i ) { 00752 // q 00753 q[i][0] = ft[i][0]*v[i][0]; 00754 q[i][1] = ft[i][1]*v[i][1]; 00755 q[i][2] = ft[i][2]*v[i][2]; 00756 // alpha 00757 tmp += c[i]*q[i]; 00758 } 00759 if ( tmp != 0 ) { 00760 alpha = Dnew / tmp; 00761 } 00762 else { 00763 break; 00764 } 00765 // x_out += alpha.c 00766 // r -= alpha.q 00767 // s = P^{-1}.r 00768 for ( unsigned int i = 0; i < size; ++i ) { 00769 // x_out 00770 x_out[i][0] += alpha * c[i][0]; 00771 x_out[i][1] += alpha * c[i][1]; 00772 x_out[i][2] += alpha * c[i][2]; 00773 // r 00774 r[i][0] -= alpha * q[i][0]; 00775 r[i][1] -= alpha * q[i][1]; 00776 r[i][2] -= alpha * q[i][2]; 00777 // s 00778 s[i][0] = Pinv[i][0]*r[i][0]; 00779 s[i][1] = Pinv[i][1]*r[i][1]; 00780 s[i][2] = Pinv[i][2]*r[i][2]; 00781 } 00782 // Dold = Dnew 00783 Dold = Dnew; 00784 // Dnew = r^T.s 00785 Dnew = 0; 00786 for ( unsigned int i = 0; i < size; ++i ) { 00787 Dnew += r[i] * s[i]; 00788 } 00789 // c = Filter( s + (Dnew/Dold)*c ) 00790 tmp = Dnew/Dold; 00791 for ( unsigned int i = 0; i < size; ++i ) { 00792 c[i][0] = s[i][0] + tmp*c[i][0]; 00793 c[i][1] = s[i][1] + tmp*c[i][1]; 00794 c[i][2] = s[i][2] + tmp*c[i][2]; 00795 c[i][0] = ft[i][0]*c[i][0]; 00796 c[i][1] = ft[i][1]*c[i][1]; 00797 c[i][2] = ft[i][2]*c[i][2]; 00798 } 00799 00800 // update values for stop conditions 00801 err = Dnew*Dnew - ths; 00802 ++count; 00803 00804 /* 00805 std::cout << "q:\n" << DEBUG_ToStr(q) << "\n"; 00806 std::cout << "alpha:\n" << alpha << "\n"; 00807 std::cout << "x_out:\n" << DEBUG_ToStr(x_out) << "\n"; 00808 std::cout << "r:\n" << DEBUG_ToStr(r) << "\n"; 00809 std::cout << "s:\n" << DEBUG_ToStr(s) << "\n"; 00810 std::cout << "Dold:\n" << Dold << "\n"; 00811 std::cout << "Dnew:\n" << Dnew << "\n"; 00812 std::cout << "c:\n" << DEBUG_ToStr(c) << "\n"; 00813 00814 std::cout << "count: " << count << ";\t"; 00815 std::cout << "error: " << err << "\n"; 00816 //*/ 00817 } 00818 00819 /* 00820 std::cout << "count: " << count << ";\t"; 00821 std::cout << "error: " << err << "\n"; 00822 std::cout << "A:\n" << A << "\n"; 00823 std::cout << "x:\n" << DEBUG_ToStr(x) << "\n"; 00824 std::cout << "x_out:\n" << DEBUG_ToStr(x_out) << "\n"; 00825 std::cout << "b:\n" << DEBUG_ToStr(b) << "\n"; 00826 A.MulWith( x_out, v ); 00827 std::cout << "v:\n" << DEBUG_ToStr(v) << "\n"; 00828 //*/ 00829 00830 //std::cout << "END MPCGSolver() --------------------------------------------" << std::endl; 00831 } 00832 //----------------------------------------------------------------------------- 00833 //============================================================================= 00834 00835 //----------------------------------------------------------------------------- 00836 //============================================================================= 00837 END_NAMESPACE_TAPs 00838 //34567890123456789012345678901234567890123456789012345678901234567890123456789 00839 //--+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----