MOAB: Mesh Oriented datABase
(version 5.4.1)
|
00001 /* ***************************************************************** 00002 MESQUITE -- The Mesh Quality Improvement Toolkit 00003 00004 Copyright 2006 Sandia National Laboratories. Developed at the 00005 University of Wisconsin--Madison under SNL contract number 00006 624796. The U.S. Government and the University of Wisconsin 00007 retain certain rights to this software. 00008 00009 This library is free software; you can redistribute it and/or 00010 modify it under the terms of the GNU Lesser General Public 00011 License as published by the Free Software Foundation; either 00012 version 2.1 of the License, or (at your option) any later version. 00013 00014 This library is distributed in the hope that it will be useful, 00015 but WITHOUT ANY WARRANTY; without even the implied warranty of 00016 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00017 Lesser General Public License for more details. 00018 00019 You should have received a copy of the GNU Lesser General Public License 00020 (lgpl.txt) along with this library; if not, write to the Free Software 00021 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00022 00023 (2006) [email protected] 00024 00025 ***************************************************************** */ 00026 00027 /** \file MsqMatrix.hpp 00028 * \brief 00029 * \author Jason Kraftcheck 00030 */ 00031 00032 #ifndef MSQ_MSQ_MATRIX_HPP 00033 #define MSQ_MSQ_MATRIX_HPP 00034 00035 #include "Mesquite.hpp" 00036 00037 #include <string> 00038 #include <istream> 00039 #include <ostream> 00040 #include <sstream> 00041 00042 namespace MBMesquite 00043 { 00044 00045 /**\brief Fixed-size matrix class 00046 * 00047 * This class implements a fixed-size 2-dimensional matrix. 00048 * The actual size is specified with template parameters. 00049 */ 00050 template < unsigned R, unsigned C > 00051 class MsqMatrix 00052 { 00053 protected: 00054 double m[R * C]; 00055 00056 public: 00057 typedef MsqMatrix< R, C > my_type; 00058 00059 enum 00060 { 00061 ROWS = R, 00062 COLS = C 00063 }; 00064 00065 /** Constructor for uninitialized matrix */ 00066 MsqMatrix() {} 00067 /** Initialize diagonal values, zero others */ 00068 MsqMatrix( double v ) 00069 { 00070 diag( v ); 00071 } 00072 /** Initialize to an array of values */ 00073 MsqMatrix( const double* v ) 00074 { 00075 set( v ); 00076 } 00077 /** Initialize from 2D array */ 00078 MsqMatrix( const double v[R][C] ) 00079 { 00080 set( v ); 00081 } 00082 /** Initialize with column vectors */ 00083 MsqMatrix( const MsqMatrix< R, 1 >* c ) 00084 { 00085 set_columns( c ); 00086 } 00087 /** Initialize with row vectors */ 00088 MsqMatrix( const MsqMatrix< 1, C >* r ) 00089 { 00090 set_rows( r ); 00091 } 00092 /** Parse initial values from string */ 00093 MsqMatrix( const char* s ) 00094 { 00095 set( s ); 00096 } 00097 /** Parse initial values from string */ 00098 MsqMatrix( const std::string& s ) 00099 { 00100 set( s ); 00101 } 00102 /** Initialize to the minor of a larger matrix 00103 * This matrix is the passed matrix with the 00104 * specified row and column removed. 00105 */ 00106 MsqMatrix( const MsqMatrix< R + 1, C + 1 >& p_m, unsigned p_r, unsigned p_c ) 00107 { 00108 make_minor( p_m, p_r, p_c ); 00109 } 00110 00111 MsqMatrix< R, C >& operator=( double v ) 00112 { 00113 set( v ); 00114 return *this; 00115 } 00116 MsqMatrix< R, C >& operator=( const double* v ) 00117 { 00118 set( v ); 00119 return *this; 00120 } 00121 MsqMatrix< R, C >& operator=( const char* s ) 00122 { 00123 set( s ); 00124 return *this; 00125 } 00126 MsqMatrix< R, C >& operator=( const std::string& s ) 00127 { 00128 set( s ); 00129 return *this; 00130 } 00131 00132 double& operator()( unsigned r, unsigned c ) 00133 { 00134 return m[r * C + c]; 00135 } 00136 double operator()( unsigned r, unsigned c ) const 00137 { 00138 return m[r * C + c]; 00139 } 00140 double* data() 00141 { 00142 return m; 00143 } 00144 const double* data() const 00145 { 00146 return m; 00147 } 00148 00149 void zero() 00150 { 00151 set( 0.0 ); 00152 } 00153 void identity() 00154 { 00155 diag( 1.0 ); 00156 } 00157 void set( double v ) 00158 { 00159 for( unsigned i = 0; i < R * C; ++i ) 00160 m[i] = v; 00161 } 00162 void set( const double* v ) 00163 { 00164 for( unsigned i = 0; i < R * C; ++i ) 00165 m[i] = v[i]; 00166 } 00167 void set( const double v[R][C] ); 00168 void set( const char* s ) 00169 { 00170 std::istringstream i( s ); 00171 i >> *this; 00172 } 00173 void set( const std::string& s ) 00174 { 00175 set( s.c_str() ); 00176 } 00177 /** Set diagonal value to passed values, others to zero. */ 00178 inline void diag( double v ); 00179 /** Set diagonal values to passed values, others to zero. */ 00180 inline void diag( const double* v ); 00181 /** Set this matrix to the minor of a larger matrix */ 00182 inline void make_minor( const MsqMatrix< R + 1, C + 1 >& m, unsigned r, unsigned c ); 00183 00184 /** *this += transpose(other) */ 00185 inline MsqMatrix< R, C >& assign_add_transpose( const MsqMatrix< C, R >& other ); 00186 /** *this = s*m */ 00187 inline MsqMatrix< R, C >& assign_product( double s, const MsqMatrix< R, C >& m ); 00188 /** *this += s*m */ 00189 inline MsqMatrix< R, C >& assign_add_product( double s, const MsqMatrix< R, C >& m ); 00190 /** multiply each element by the cooresponding element in m */ 00191 inline MsqMatrix< R, C >& assign_multiply_elements( const MsqMatrix< R, C >& m ); 00192 00193 inline MsqMatrix< R, C >& operator+=( const MsqMatrix< R, C >& other ); 00194 inline MsqMatrix< R, C >& operator-=( const MsqMatrix< R, C >& other ); 00195 inline MsqMatrix< R, C >& operator+=( double scalar ); 00196 inline MsqMatrix< R, C >& operator-=( double scalar ); 00197 inline MsqMatrix< R, C >& operator*=( double scalar ); 00198 inline MsqMatrix< R, C >& operator/=( double scalar ); 00199 00200 // MsqMatrix<1,C>& row( unsigned r ) { return *(MsqMatrix<1,C>*)(m+C*r); } 00201 // const MsqMatrix<1,C>& row( unsigned r ) const { return *(MsqMatrix<1,C>*)(m+C*r); } 00202 MsqMatrix< 1, C > row( unsigned r ) const 00203 { 00204 return MsqMatrix< 1, C >( m + C * r ); 00205 } 00206 MsqMatrix< R, 1 > column( unsigned c ) const; 00207 MsqMatrix< 1, R > column_transpose( unsigned c ) const; 00208 00209 void set_row( unsigned r, const MsqMatrix< 1, C >& v ); 00210 void add_row( unsigned r, const MsqMatrix< 1, C >& v ); 00211 void set_row_transpose( unsigned r, const MsqMatrix< C, 1 >& v ); 00212 void set_rows( const MsqMatrix< 1, C >* v ); 00213 void set_column( unsigned c, const MsqMatrix< R, 1 >& v ); 00214 void add_column( unsigned c, const MsqMatrix< R, 1 >& v ); 00215 void set_column_transpose( unsigned c, const MsqMatrix< 1, R >& v ); 00216 void set_columns( const MsqMatrix< R, 1 >* v ); 00217 }; 00218 00219 template <> 00220 class MsqMatrix< 1, 1 > 00221 { 00222 protected: 00223 double m; 00224 00225 public: 00226 typedef MsqMatrix< 1, 1 > my_type; 00227 00228 enum 00229 { 00230 ROWS = 1, 00231 COLS = 1 00232 }; 00233 00234 /** Constructor for uninitialized matrix */ 00235 MsqMatrix() {} 00236 /** Initialize diagonal values, zero others */ 00237 MsqMatrix( double v ) : m( v ) {} 00238 /** Initialize to an array of values */ 00239 MsqMatrix( const double* v ) : m( *v ) {} 00240 /** Parse initial values from string */ 00241 MsqMatrix( const char* s ) 00242 { 00243 set( s ); 00244 } 00245 /** Parse initial values from string */ 00246 MsqMatrix( const std::string& s ) 00247 { 00248 set( s ); 00249 } 00250 /** Initialize to the minor of a larger matrix 00251 * This matrix is the passed matrix with the 00252 * specified row and column removed. 00253 */ 00254 MsqMatrix( const MsqMatrix< 2, 2 >& M, unsigned r, unsigned c ) : m( M( r, c ) ) {} 00255 00256 MsqMatrix< 1, 1 >& operator=( double v ) 00257 { 00258 m = v; 00259 return *this; 00260 } 00261 MsqMatrix< 1, 1 >& operator=( const double* v ) 00262 { 00263 m = *v; 00264 return *this; 00265 } 00266 MsqMatrix< 1, 1 >& operator=( const char* s ) 00267 { 00268 set( s ); 00269 return *this; 00270 } 00271 MsqMatrix< 1, 1 >& operator=( const std::string& s ) 00272 { 00273 set( s ); 00274 return *this; 00275 } 00276 00277 double& operator()( unsigned, unsigned ) 00278 { 00279 return m; 00280 } 00281 double operator()( unsigned, unsigned ) const 00282 { 00283 return m; 00284 } 00285 double* data() 00286 { 00287 return &m; 00288 } 00289 const double* data() const 00290 { 00291 return &m; 00292 } 00293 00294 void zero() 00295 { 00296 m = 0.0; 00297 } 00298 void identity() 00299 { 00300 m = 1.0; 00301 } 00302 void set( double v ) 00303 { 00304 m = v; 00305 } 00306 void set( const double* v ) 00307 { 00308 m = *v; 00309 } 00310 void set( const char* s ) 00311 { 00312 std::istringstream i( s ); 00313 i >> m; 00314 } 00315 void set( const std::string& s ) 00316 { 00317 set( s.c_str() ); 00318 } 00319 /** Set diagonal value to passed values, others to zero. */ 00320 inline void diag( double v ) 00321 { 00322 m = v; 00323 } 00324 /** Set diagonal values to passed values, others to zero. */ 00325 inline void diag( const double* v ) 00326 { 00327 m = *v; 00328 } 00329 /** Set this matrix to the minor of a larger matrix */ 00330 inline void make_minor( const MsqMatrix< 2, 2 >& M, unsigned r, unsigned c ) 00331 { 00332 m = M( r, c ); 00333 } 00334 00335 /** *this += transpose(other) */ 00336 inline MsqMatrix< 1, 1 >& assign_add_transpose( const MsqMatrix< 1, 1 >& other ) 00337 { 00338 m += other.m; 00339 return *this; 00340 } 00341 /** *this = s*m */ 00342 inline MsqMatrix< 1, 1 >& assign_product( double s, const MsqMatrix< 1, 1 >& other ) 00343 { 00344 m = s * other.m; 00345 return *this; 00346 } 00347 /** *this += s*m */ 00348 inline MsqMatrix< 1, 1 >& assign_add_product( double s, const MsqMatrix< 1, 1 >& other ) 00349 { 00350 m += s * other.m; 00351 return *this; 00352 } 00353 /** multiply each element by the cooresponding element in m */ 00354 inline MsqMatrix< 1, 1 >& assign_multiply_elements( const MsqMatrix< 1, 1 >& other ) 00355 { 00356 m *= other.m; 00357 return *this; 00358 } 00359 00360 operator double() const 00361 { 00362 return m; 00363 } 00364 }; 00365 00366 /** \brief Vector is a 1xL Matrix 00367 * 00368 * Define a Vector as a 1xL Matrix 00369 * Add single-index access operators 00370 */ 00371 template < unsigned L > 00372 class MsqVector : public MsqMatrix< L, 1 > 00373 { 00374 public: 00375 MsqVector() {} 00376 MsqVector( double v ) 00377 { 00378 MsqMatrix< L, 1 >::set( v ); 00379 } 00380 MsqVector( const double* v ) 00381 { 00382 MsqMatrix< L, 1 >::set( v ); 00383 } 00384 MsqVector( const char* s ) 00385 { 00386 MsqMatrix< L, 1 >::set( s ); 00387 } 00388 MsqVector( const std::string& s ) 00389 { 00390 MsqMatrix< L, 1 >::set( s ); 00391 } 00392 MsqVector( const MsqMatrix< L, 1 >& pm ) : MsqMatrix< L, 1 >( pm ) {} 00393 00394 double& operator[]( unsigned idx ) 00395 { 00396 return MsqMatrix< L, 1 >::operator()( idx, 0 ); 00397 } 00398 double operator[]( unsigned idx ) const 00399 { 00400 return MsqMatrix< L, 1 >::operator()( idx, 0 ); 00401 } 00402 double& operator()( unsigned idx ) 00403 { 00404 return MsqMatrix< L, 1 >::operator()( idx, 0 ); 00405 } 00406 double operator()( unsigned idx ) const 00407 { 00408 return MsqMatrix< L, 1 >::operator()( idx, 0 ); 00409 } 00410 00411 MsqVector< L >& operator=( const MsqMatrix< L, 1 >& p_m ) 00412 { 00413 MsqMatrix< L, 1 >::operator=( p_m ); 00414 return *this; 00415 } 00416 }; 00417 00418 /**\brief A subclass of MsqMatrix that behaves more like the old Matrix3D class 00419 * 00420 * A MsqMartix that behaves more like the old Matrx3D class. 00421 * * Constructors are different--be careful. 00422 * * Adds operator[] for c-array style access. 00423 */ 00424 template < unsigned R, unsigned C > 00425 class MsqMatrixA : public MsqMatrix< R, C > 00426 { 00427 public: 00428 /** Initialize all elements to zero */ 00429 MsqMatrixA() 00430 { 00431 MsqMatrix< R, C >::set( 0 ); 00432 } 00433 /** Initialize all elements to passed value */ 00434 MsqMatrixA( double v ) 00435 { 00436 MsqMatrix< R, C >::set( v ); 00437 } 00438 MsqMatrixA( const double* v ) 00439 { 00440 MsqMatrix< R, C >::set( v ); 00441 } 00442 MsqMatrixA( const char* s ) 00443 { 00444 MsqMatrix< R, C >::set( s ); 00445 } 00446 MsqMatrixA( const std::string& s ) 00447 { 00448 MsqMatrix< R, C >::set( s ); 00449 } 00450 MsqMatrixA( const MsqMatrix< R, C >& m ) : MsqMatrix< R, C >( m ) {} 00451 MsqMatrixA( const MsqMatrix< R + 1, C + 1 >& m, unsigned r, unsigned c ) 00452 { 00453 MsqMatrix< R, C >::make_minor( m, r, c ); 00454 } 00455 00456 double* operator[]( unsigned idx ) 00457 { 00458 return MsqMatrix< R, C >::m + C * idx; 00459 } 00460 const double* operator[]( unsigned idx ) const 00461 { 00462 return MsqMatrix< R, C >::m + C * idx; 00463 } 00464 00465 MsqMatrixA< R, C >& operator=( const MsqMatrixA< R, C >& m ) 00466 { 00467 MsqMatrixA< R, C >::operator=( m ); 00468 return *this; 00469 } 00470 }; 00471 00472 template < unsigned R, unsigned C > 00473 inline void MsqMatrix< R, C >::set( const double v[R][C] ) 00474 { 00475 for( unsigned r = 0; r < R; ++r ) 00476 for( unsigned c = 0; c < C; ++c ) 00477 operator()( r, c ) = v[r][c]; 00478 } 00479 00480 template < unsigned R, unsigned C > 00481 inline void MsqMatrix< R, C >::diag( double v ) 00482 { 00483 // for (unsigned r = 0; r < R; ++r) 00484 // for (unsigned c = 0; c < C; ++c) 00485 // operator()(r,c) = (r == c) ? v : 0.0; 00486 00487 switch( R ) 00488 { 00489 default: 00490 for( unsigned r = 4; r < R; ++r ) 00491 switch( C ) 00492 { 00493 default: 00494 for( unsigned k = 4; k < C; ++k ) 00495 operator()( r, k ) = r == k ? v : 0.0; 00496 case 4: 00497 operator()( r, 3 ) = 0.0; 00498 case 3: 00499 operator()( r, 2 ) = 0.0; 00500 case 2: 00501 operator()( r, 1 ) = 0.0; 00502 case 1: 00503 operator()( r, 0 ) = 0.0; 00504 } 00505 case 4: 00506 switch( C ) 00507 { 00508 default: 00509 for( unsigned k = 4; k < C; ++k ) 00510 operator()( 3, k ) = 0.0; 00511 case 4: 00512 operator()( 3, 3 ) = v; 00513 case 3: 00514 operator()( 3, 2 ) = 0.0; 00515 case 2: 00516 operator()( 3, 1 ) = 0.0; 00517 case 1: 00518 operator()( 3, 0 ) = 0.0; 00519 } 00520 case 3: 00521 switch( C ) 00522 { 00523 default: 00524 for( unsigned k = 4; k < C; ++k ) 00525 operator()( 2, k ) = 0.0; 00526 case 4: 00527 operator()( 2, 3 ) = 0.0; 00528 case 3: 00529 operator()( 2, 2 ) = v; 00530 case 2: 00531 operator()( 2, 1 ) = 0.0; 00532 case 1: 00533 operator()( 2, 0 ) = 0.0; 00534 } 00535 case 2: 00536 switch( C ) 00537 { 00538 default: 00539 for( unsigned k = 4; k < C; ++k ) 00540 operator()( 1, k ) = 0.0; 00541 case 4: 00542 operator()( 1, 3 ) = 0.0; 00543 case 3: 00544 operator()( 1, 2 ) = 0.0; 00545 case 2: 00546 operator()( 1, 1 ) = v; 00547 case 1: 00548 operator()( 1, 0 ) = 0.0; 00549 } 00550 case 1: 00551 switch( C ) 00552 { 00553 default: 00554 for( unsigned k = 4; k < C; ++k ) 00555 operator()( 0, k ) = 0.0; 00556 case 4: 00557 operator()( 0, 3 ) = 0.0; 00558 case 3: 00559 operator()( 0, 2 ) = 0.0; 00560 case 2: 00561 operator()( 0, 1 ) = 0.0; 00562 case 1: 00563 operator()( 0, 0 ) = v; 00564 } 00565 } 00566 } 00567 00568 template < unsigned R, unsigned C > 00569 inline void MsqMatrix< R, C >::diag( const double* v ) 00570 { 00571 // for (unsigned r = 0; r < R; ++r) 00572 // for (unsigned c = 0; c < C; ++c) 00573 // operator()(r,c) = (r == c) ? v[r] : 0.0; 00574 00575 switch( R ) 00576 { 00577 default: 00578 for( unsigned r = 4; r < R; ++r ) 00579 switch( C ) 00580 { 00581 default: 00582 for( unsigned k = 4; k < C; ++k ) 00583 operator()( r, k ) = r == k ? v[r] : 0.0; 00584 case 4: 00585 operator()( r, 3 ) = 0.0; 00586 case 3: 00587 operator()( r, 2 ) = 0.0; 00588 case 2: 00589 operator()( r, 1 ) = 0.0; 00590 case 1: 00591 operator()( r, 0 ) = 0.0; 00592 } 00593 case 4: 00594 switch( C ) 00595 { 00596 default: 00597 for( unsigned k = 4; k < C; ++k ) 00598 operator()( 3, k ) = 0.0; 00599 case 4: 00600 operator()( 3, 3 ) = v[3]; 00601 case 3: 00602 operator()( 3, 2 ) = 0.0; 00603 case 2: 00604 operator()( 3, 1 ) = 0.0; 00605 case 1: 00606 operator()( 3, 0 ) = 0.0; 00607 } 00608 case 3: 00609 switch( C ) 00610 { 00611 default: 00612 for( unsigned k = 4; k < C; ++k ) 00613 operator()( 2, k ) = 0.0; 00614 case 4: 00615 operator()( 2, 3 ) = 0.0; 00616 case 3: 00617 operator()( 2, 2 ) = v[2]; 00618 case 2: 00619 operator()( 2, 1 ) = 0.0; 00620 case 1: 00621 operator()( 2, 0 ) = 0.0; 00622 } 00623 case 2: 00624 switch( C ) 00625 { 00626 default: 00627 for( unsigned k = 4; k < C; ++k ) 00628 operator()( 1, k ) = 0.0; 00629 case 4: 00630 operator()( 1, 3 ) = 0.0; 00631 case 3: 00632 operator()( 1, 2 ) = 0.0; 00633 case 2: 00634 operator()( 1, 1 ) = v[1]; 00635 case 1: 00636 operator()( 1, 0 ) = 0.0; 00637 } 00638 case 1: 00639 switch( C ) 00640 { 00641 default: 00642 for( unsigned k = 4; k < C; ++k ) 00643 operator()( 0, k ) = 0.0; 00644 case 4: 00645 operator()( 0, 3 ) = 0.0; 00646 case 3: 00647 operator()( 0, 2 ) = 0.0; 00648 case 2: 00649 operator()( 0, 1 ) = 0.0; 00650 case 1: 00651 operator()( 0, 0 ) = v[0]; 00652 } 00653 } 00654 } 00655 00656 /**\brief Extract minor of a matrix and assign to *this 00657 * 00658 * Given a matrix m, a row r and an column c, set *this to 00659 * the matrix that is m with row r and column c deleted. 00660 */ 00661 template < unsigned R, unsigned C > 00662 inline void MsqMatrix< R, C >::make_minor( const MsqMatrix< R + 1, C + 1 >& M, unsigned r, unsigned c ) 00663 { 00664 for( unsigned i = 0; i < r; ++i ) 00665 { 00666 for( unsigned j = 0; j < c; ++j ) 00667 operator()( i, j ) = M( i, j ); 00668 for( unsigned j = c; j < C; ++j ) 00669 operator()( i, j ) = M( i, j + 1 ); 00670 } 00671 for( unsigned i = r; i < R; ++i ) 00672 { 00673 for( unsigned j = 0; j < c; ++j ) 00674 operator()( i, j ) = M( i + 1, j ); 00675 for( unsigned j = c; j < C; ++j ) 00676 operator()( i, j ) = M( i + 1, j + 1 ); 00677 } 00678 } 00679 00680 template < unsigned R, unsigned C > 00681 inline void MsqMatrix< R, C >::set_row( unsigned r, const MsqMatrix< 1, C >& v ) 00682 { 00683 for( unsigned i = 0; i < C; ++i ) 00684 operator()( r, i ) = v( 0, i ); 00685 } 00686 template < unsigned R, unsigned C > 00687 inline void MsqMatrix< R, C >::add_row( unsigned r, const MsqMatrix< 1, C >& v ) 00688 { 00689 for( unsigned i = 0; i < C; ++i ) 00690 operator()( r, i ) += v( 0, i ); 00691 } 00692 template < unsigned R, unsigned C > 00693 inline void MsqMatrix< R, C >::set_row_transpose( unsigned r, const MsqMatrix< C, 1 >& v ) 00694 { 00695 for( unsigned i = 0; i < C; ++i ) 00696 operator()( r, i ) = v( i, 0 ); 00697 } 00698 template < unsigned R, unsigned C > 00699 inline void MsqMatrix< R, C >::set_rows( const MsqMatrix< 1, C >* v ) 00700 { 00701 for( unsigned r = 0; r < R; ++r ) 00702 set_row( r, v[r] ); 00703 } 00704 00705 template < unsigned R, unsigned C > 00706 inline void MsqMatrix< R, C >::set_column( unsigned c, const MsqMatrix< R, 1 >& v ) 00707 { 00708 for( unsigned i = 0; i < R; ++i ) 00709 operator()( i, c ) = v( i, 0 ); 00710 } 00711 template < unsigned R, unsigned C > 00712 inline void MsqMatrix< R, C >::add_column( unsigned c, const MsqMatrix< R, 1 >& v ) 00713 { 00714 for( unsigned i = 0; i < R; ++i ) 00715 operator()( i, c ) += v( i, 0 ); 00716 } 00717 template < unsigned R, unsigned C > 00718 inline void MsqMatrix< R, C >::set_column_transpose( unsigned c, const MsqMatrix< 1, R >& v ) 00719 { 00720 for( unsigned i = 0; i < R; ++i ) 00721 operator()( i, c ) = v( 0, i ); 00722 } 00723 template < unsigned R, unsigned C > 00724 inline void MsqMatrix< R, C >::set_columns( const MsqMatrix< R, 1 >* v ) 00725 { 00726 for( unsigned c = 0; c < C; ++c ) 00727 set_column( c, v[c] ); 00728 } 00729 00730 template < unsigned R, unsigned C > 00731 inline MsqMatrix< R, 1 > MsqMatrix< R, C >::column( unsigned c ) const 00732 { 00733 MsqMatrix< R, 1 > result; 00734 for( unsigned i = 0; i < R; ++i ) 00735 result( i, 0 ) = operator()( i, c ); 00736 return result; 00737 } 00738 00739 template < unsigned R, unsigned C > 00740 inline MsqMatrix< 1, R > MsqMatrix< R, C >::column_transpose( unsigned c ) const 00741 { 00742 MsqMatrix< 1, R > result; 00743 for( unsigned i = 0; i < R; ++i ) 00744 result( 0, i ) = operator()( i, c ); 00745 return result; 00746 } 00747 00748 /**\brief Set a subset of this matrix to some other matrix */ 00749 template < unsigned R1, unsigned C1, unsigned R2, unsigned C2 > 00750 inline void set_region( MsqMatrix< R1, C1 >& d, unsigned r, unsigned c, MsqMatrix< R2, C2 >& s ) 00751 { 00752 const unsigned rmax = r + R2 > R1 ? R1 : r + R2; 00753 const unsigned cmax = c + C2 > C1 ? C1 : c + C2; 00754 for( unsigned i = r; i < rmax; ++i ) 00755 for( unsigned j = c; j < cmax; ++j ) 00756 d( i, j ) = s( i - r, j - c ); 00757 } 00758 00759 template < unsigned R, unsigned C > 00760 inline MsqMatrix< R, C >& MsqMatrix< R, C >::assign_add_transpose( const MsqMatrix< C, R >& other ) 00761 { 00762 for( unsigned r = 0; r < R; ++r ) 00763 for( unsigned c = 0; c < C; ++c ) 00764 operator()( r, c ) += other( c, r ); 00765 return *this; 00766 } 00767 00768 template < unsigned R, unsigned C > 00769 inline MsqMatrix< R, C >& MsqMatrix< R, C >::assign_multiply_elements( const MsqMatrix< R, C >& other ) 00770 { 00771 for( unsigned i = 0; i < R * C; ++i ) 00772 m[i] *= other.data()[i]; 00773 return *this; 00774 } 00775 00776 template < unsigned R, unsigned C > 00777 inline MsqMatrix< R, C >& MsqMatrix< R, C >::assign_product( double s, const MsqMatrix< R, C >& other ) 00778 { 00779 for( unsigned i = 0; i < R * C; ++i ) 00780 m[i] = s * other.data()[i]; 00781 return *this; 00782 } 00783 00784 template < unsigned R, unsigned C > 00785 inline MsqMatrix< R, C >& MsqMatrix< R, C >::assign_add_product( double s, const MsqMatrix< R, C >& other ) 00786 { 00787 for( unsigned i = 0; i < R * C; ++i ) 00788 m[i] += s * other.data()[i]; 00789 return *this; 00790 } 00791 00792 template < unsigned R, unsigned C > 00793 inline MsqMatrix< R, C >& MsqMatrix< R, C >::operator+=( const MsqMatrix< R, C >& other ) 00794 { 00795 for( unsigned i = 0; i < R * C; ++i ) 00796 m[i] += other.data()[i]; 00797 return *this; 00798 } 00799 00800 template < unsigned R, unsigned C > 00801 inline MsqMatrix< R, C >& MsqMatrix< R, C >::operator-=( const MsqMatrix< R, C >& other ) 00802 { 00803 for( unsigned i = 0; i < R * C; ++i ) 00804 m[i] -= other.data()[i]; 00805 return *this; 00806 } 00807 00808 template < unsigned R, unsigned C > 00809 inline MsqMatrix< R, C >& MsqMatrix< R, C >::operator+=( double s ) 00810 { 00811 for( unsigned i = 0; i < R * C; ++i ) 00812 m[i] += s; 00813 return *this; 00814 } 00815 00816 template < unsigned R, unsigned C > 00817 inline MsqMatrix< R, C >& MsqMatrix< R, C >::operator-=( double s ) 00818 { 00819 for( unsigned i = 0; i < R * C; ++i ) 00820 m[i] -= s; 00821 return *this; 00822 } 00823 00824 template < unsigned R, unsigned C > 00825 inline MsqMatrix< R, C >& MsqMatrix< R, C >::operator*=( double s ) 00826 { 00827 for( unsigned i = 0; i < R * C; ++i ) 00828 m[i] *= s; 00829 return *this; 00830 } 00831 00832 template < unsigned R, unsigned C > 00833 inline MsqMatrix< R, C >& MsqMatrix< R, C >::operator/=( double s ) 00834 { 00835 for( unsigned i = 0; i < R * C; ++i ) 00836 m[i] /= s; 00837 return *this; 00838 } 00839 00840 template < unsigned R, unsigned C > 00841 inline MsqMatrix< R, C > operator-( const MsqMatrix< R, C >& m ) 00842 { 00843 MsqMatrix< R, C > result; 00844 for( unsigned i = 0; i < R * C; ++i ) 00845 result.data()[i] = -m.data()[i]; 00846 return result; 00847 } 00848 00849 template < unsigned R, unsigned C > 00850 inline MsqMatrix< R, C > operator+( const MsqMatrix< R, C >& m, double s ) 00851 { 00852 MsqMatrix< R, C > tmp( m ); 00853 tmp += s; 00854 return tmp; 00855 } 00856 00857 template < unsigned R, unsigned C > 00858 inline MsqMatrix< R, C > operator+( double s, const MsqMatrix< R, C >& m ) 00859 { 00860 MsqMatrix< R, C > tmp( m ); 00861 tmp += s; 00862 return tmp; 00863 } 00864 00865 template < unsigned R, unsigned C > 00866 inline MsqMatrix< R, C > operator+( const MsqMatrix< R, C >& A, const MsqMatrix< R, C >& B ) 00867 { 00868 MsqMatrix< R, C > tmp( A ); 00869 tmp += B; 00870 return tmp; 00871 } 00872 00873 template < unsigned R, unsigned C > 00874 inline MsqMatrix< R, C > operator-( const MsqMatrix< R, C >& m, double s ) 00875 { 00876 MsqMatrix< R, C > tmp( m ); 00877 tmp -= s; 00878 return tmp; 00879 } 00880 00881 template < unsigned R, unsigned C > 00882 inline MsqMatrix< R, C > operator-( double s, const MsqMatrix< R, C >& m ) 00883 { 00884 MsqMatrix< R, C > tmp( m ); 00885 tmp -= s; 00886 return tmp; 00887 } 00888 00889 template < unsigned R, unsigned C > 00890 inline MsqMatrix< R, C > operator-( const MsqMatrix< R, C >& A, const MsqMatrix< R, C >& B ) 00891 { 00892 MsqMatrix< R, C > tmp( A ); 00893 tmp -= B; 00894 return tmp; 00895 } 00896 00897 template < unsigned R, unsigned C > 00898 inline MsqMatrix< R, C > operator*( const MsqMatrix< R, C >& m, double s ) 00899 { 00900 MsqMatrix< R, C > tmp( m ); 00901 tmp *= s; 00902 return tmp; 00903 } 00904 00905 template < unsigned R, unsigned C > 00906 inline MsqMatrix< R, C > operator*( double s, const MsqMatrix< R, C >& m ) 00907 { 00908 MsqMatrix< R, C > tmp( m ); 00909 tmp *= s; 00910 return tmp; 00911 } 00912 00913 template < unsigned R, unsigned RC, unsigned C > 00914 inline double multiply_helper_result_val( unsigned r, 00915 unsigned c, 00916 const MsqMatrix< R, RC >& A, 00917 const MsqMatrix< RC, C >& B ) 00918 { 00919 double tmp = A( r, 0 ) * B( 0, c ); 00920 switch( RC ) 00921 { 00922 default: 00923 for( unsigned k = 6; k < RC; ++k ) 00924 tmp += A( r, k ) * B( k, c ); 00925 case 6: 00926 tmp += A( r, 5 ) * B( 5, c ); 00927 case 5: 00928 tmp += A( r, 4 ) * B( 4, c ); 00929 case 4: 00930 tmp += A( r, 3 ) * B( 3, c ); 00931 case 3: 00932 tmp += A( r, 2 ) * B( 2, c ); 00933 case 2: 00934 tmp += A( r, 1 ) * B( 1, c ); 00935 case 1:; 00936 } 00937 return tmp; 00938 } 00939 00940 template < unsigned R, unsigned RC, unsigned C > 00941 inline MsqMatrix< R, C > operator*( const MsqMatrix< R, RC >& A, const MsqMatrix< RC, C >& B ) 00942 { 00943 // MsqMatrix<R,C> result(0.0); 00944 // for (unsigned i = 0; i < R; ++i) 00945 // for (unsigned j = 0; j < C; ++j) 00946 // for (unsigned k = 0; k < RC; ++k) 00947 // result(i,j) += A(i,k) * B(k,j); 00948 00949 MsqMatrix< R, C > result; 00950 for( unsigned r = 0; r < R; ++r ) 00951 for( unsigned c = 0; c < C; ++c ) 00952 result( r, c ) = multiply_helper_result_val( r, c, A, B ); 00953 00954 return result; 00955 } 00956 00957 template < unsigned R, unsigned C > 00958 inline MsqMatrix< R, C > operator/( const MsqMatrix< R, C >& m, double s ) 00959 { 00960 MsqMatrix< R, C > tmp( m ); 00961 tmp /= s; 00962 return tmp; 00963 } 00964 00965 template < unsigned RC > 00966 inline double cofactor( const MsqMatrix< RC, RC >& m, unsigned r, unsigned c ) 00967 { 00968 const double sign[] = { 1.0, -1.0 }; 00969 return sign[( r + c ) % 2] * det( MsqMatrix< RC - 1, RC - 1 >( m, r, c ) ); 00970 } 00971 00972 template < unsigned RC > 00973 inline double det( const MsqMatrix< RC, RC >& m ) 00974 { 00975 double result = 0.0; 00976 for( unsigned i = 0; i < RC; ++i ) 00977 result += m( 0, i ) * cofactor< RC >( m, 0, i ); 00978 return result; 00979 } 00980 00981 // inline 00982 // double det( const MsqMatrix<1,1>& m ) 00983 // { return m(0,0); } 00984 00985 inline double det( const MsqMatrix< 2, 2 >& m ) 00986 { 00987 return m( 0, 0 ) * m( 1, 1 ) - m( 0, 1 ) * m( 1, 0 ); 00988 } 00989 00990 inline double det( const MsqMatrix< 3, 3 >& m ) 00991 { 00992 return m( 0, 0 ) * ( m( 1, 1 ) * m( 2, 2 ) - m( 2, 1 ) * m( 1, 2 ) ) + 00993 m( 0, 1 ) * ( m( 2, 0 ) * m( 1, 2 ) - m( 1, 0 ) * m( 2, 2 ) ) + 00994 m( 0, 2 ) * ( m( 1, 0 ) * m( 2, 1 ) - m( 2, 0 ) * m( 1, 1 ) ); 00995 } 00996 00997 inline MsqMatrix< 2, 2 > adj( const MsqMatrix< 2, 2 >& m ) 00998 { 00999 MsqMatrix< 2, 2 > result; 01000 result( 0, 0 ) = m( 1, 1 ); 01001 result( 0, 1 ) = -m( 0, 1 ); 01002 result( 1, 0 ) = -m( 1, 0 ); 01003 result( 1, 1 ) = m( 0, 0 ); 01004 return result; 01005 } 01006 01007 inline MsqMatrix< 2, 2 > transpose_adj( const MsqMatrix< 2, 2 >& m ) 01008 { 01009 MsqMatrix< 2, 2 > result; 01010 result( 0, 0 ) = m( 1, 1 ); 01011 result( 1, 0 ) = -m( 0, 1 ); 01012 result( 0, 1 ) = -m( 1, 0 ); 01013 result( 1, 1 ) = m( 0, 0 ); 01014 return result; 01015 } 01016 01017 inline MsqMatrix< 3, 3 > adj( const MsqMatrix< 3, 3 >& m ) 01018 { 01019 MsqMatrix< 3, 3 > result; 01020 01021 result( 0, 0 ) = m( 1, 1 ) * m( 2, 2 ) - m( 1, 2 ) * m( 2, 1 ); 01022 result( 0, 1 ) = m( 0, 2 ) * m( 2, 1 ) - m( 0, 1 ) * m( 2, 2 ); 01023 result( 0, 2 ) = m( 0, 1 ) * m( 1, 2 ) - m( 0, 2 ) * m( 1, 1 ); 01024 01025 result( 1, 0 ) = m( 1, 2 ) * m( 2, 0 ) - m( 1, 0 ) * m( 2, 2 ); 01026 result( 1, 1 ) = m( 0, 0 ) * m( 2, 2 ) - m( 0, 2 ) * m( 2, 0 ); 01027 result( 1, 2 ) = m( 0, 2 ) * m( 1, 0 ) - m( 0, 0 ) * m( 1, 2 ); 01028 01029 result( 2, 0 ) = m( 1, 0 ) * m( 2, 1 ) - m( 1, 1 ) * m( 2, 0 ); 01030 result( 2, 1 ) = m( 0, 1 ) * m( 2, 0 ) - m( 0, 0 ) * m( 2, 1 ); 01031 result( 2, 2 ) = m( 0, 0 ) * m( 1, 1 ) - m( 0, 1 ) * m( 1, 0 ); 01032 01033 return result; 01034 } 01035 01036 inline MsqMatrix< 3, 3 > transpose_adj( const MsqMatrix< 3, 3 >& m ) 01037 { 01038 MsqMatrix< 3, 3 > result; 01039 01040 result( 0, 0 ) = m( 1, 1 ) * m( 2, 2 ) - m( 1, 2 ) * m( 2, 1 ); 01041 result( 0, 1 ) = m( 1, 2 ) * m( 2, 0 ) - m( 1, 0 ) * m( 2, 2 ); 01042 result( 0, 2 ) = m( 1, 0 ) * m( 2, 1 ) - m( 1, 1 ) * m( 2, 0 ); 01043 01044 result( 1, 0 ) = m( 0, 2 ) * m( 2, 1 ) - m( 0, 1 ) * m( 2, 2 ); 01045 result( 1, 1 ) = m( 0, 0 ) * m( 2, 2 ) - m( 0, 2 ) * m( 2, 0 ); 01046 result( 1, 2 ) = m( 0, 1 ) * m( 2, 0 ) - m( 0, 0 ) * m( 2, 1 ); 01047 01048 result( 2, 0 ) = m( 0, 1 ) * m( 1, 2 ) - m( 0, 2 ) * m( 1, 1 ); 01049 result( 2, 1 ) = m( 0, 2 ) * m( 1, 0 ) - m( 0, 0 ) * m( 1, 2 ); 01050 result( 2, 2 ) = m( 0, 0 ) * m( 1, 1 ) - m( 0, 1 ) * m( 1, 0 ); 01051 01052 return result; 01053 } 01054 01055 template < unsigned R, unsigned C > 01056 inline MsqMatrix< R, C > inverse( const MsqMatrix< R, C >& m ) 01057 { 01058 return adj( m ) * ( 1.0 / det( m ) ); 01059 } 01060 01061 template < unsigned R, unsigned C > 01062 inline MsqMatrix< R, C > transpose( const MsqMatrix< C, R >& m ) 01063 { 01064 MsqMatrix< R, C > result; 01065 for( unsigned r = 0; r < R; ++r ) 01066 for( unsigned c = 0; c < C; ++c ) 01067 result( r, c ) = m( c, r ); 01068 return result; 01069 } 01070 /* 01071 template <unsigned R> inline 01072 const MsqMatrix<R,1>& transpose( const MsqMatrix<1,R>& m ) 01073 { return *reinterpret_cast<const MsqMatrix<R,1>*>(&m); } 01074 01075 template <unsigned C> inline 01076 const MsqMatrix<1,C>& transpose( const MsqMatrix<C,1>& m ) 01077 { return *reinterpret_cast<const MsqMatrix<1,C>*>(&m); } 01078 */ 01079 template < unsigned RC > 01080 inline double trace( const MsqMatrix< RC, RC >& m ) 01081 { 01082 double result = m( 0, 0 ); 01083 for( unsigned i = 1; i < RC; ++i ) 01084 result += m( i, i ); 01085 return result; 01086 } 01087 01088 template < unsigned R, unsigned C > 01089 inline double sqr_Frobenius( const MsqMatrix< R, C >& m ) 01090 { 01091 double result = *m.data() * *m.data(); 01092 for( unsigned i = 1; i < R * C; ++i ) 01093 result += m.data()[i] * m.data()[i]; 01094 return result; 01095 } 01096 01097 template < unsigned R, unsigned C > 01098 inline double Frobenius( const MsqMatrix< R, C >& m ) 01099 { 01100 return std::sqrt( sqr_Frobenius< R, C >( m ) ); 01101 } 01102 01103 template < unsigned R, unsigned C > 01104 inline bool operator==( const MsqMatrix< R, C >& A, const MsqMatrix< R, C >& B ) 01105 { 01106 for( unsigned i = 0; i < R * C; ++i ) 01107 if( A.data()[i] != B.data()[i] ) return false; 01108 return true; 01109 } 01110 01111 template < unsigned R, unsigned C > 01112 inline bool operator!=( const MsqMatrix< R, C >& A, const MsqMatrix< R, C >& B ) 01113 { 01114 return !( A == B ); 01115 } 01116 01117 template < unsigned R, unsigned C > 01118 inline std::ostream& operator<<( std::ostream& str, const MsqMatrix< R, C >& m ) 01119 { 01120 str << m.data()[0]; 01121 for( unsigned i = 1; i < R * C; ++i ) 01122 str << ' ' << m.data()[i]; 01123 return str; 01124 } 01125 01126 template < unsigned R, unsigned C > 01127 inline std::istream& operator>>( std::istream& str, MsqMatrix< R, C >& m ) 01128 { 01129 for( unsigned i = 0; i < R * C; ++i ) 01130 str >> m.data()[i]; 01131 return str; 01132 } 01133 01134 template < unsigned R > 01135 inline double sqr_length( const MsqMatrix< R, 1 >& v ) 01136 { 01137 return sqr_Frobenius( v ); 01138 } 01139 01140 template < unsigned C > 01141 inline double sqr_length( const MsqMatrix< 1, C >& v ) 01142 { 01143 return sqr_Frobenius( v ); 01144 } 01145 01146 template < unsigned R > 01147 inline double length( const MsqMatrix< R, 1 >& v ) 01148 { 01149 return Frobenius( v ); 01150 } 01151 01152 template < unsigned C > 01153 inline double length( const MsqMatrix< 1, C >& v ) 01154 { 01155 return Frobenius( v ); 01156 } 01157 01158 template < unsigned R, unsigned C > 01159 inline double inner_product( const MsqMatrix< R, C >& m1, const MsqMatrix< R, C >& m2 ) 01160 { 01161 double result = 0.0; 01162 for( unsigned r = 0; r < R; ++r ) 01163 for( unsigned c = 0; c < C; ++c ) 01164 result += m1( r, c ) * m2( r, c ); 01165 return result; 01166 } 01167 01168 template < unsigned R, unsigned C > 01169 inline MsqMatrix< R, C > outer( const MsqMatrix< R, 1 >& v1, const MsqMatrix< C, 1 >& v2 ) 01170 { 01171 MsqMatrix< R, C > result; 01172 for( unsigned r = 0; r < R; ++r ) 01173 for( unsigned c = 0; c < C; ++c ) 01174 result( r, c ) = v1( r, 0 ) * v2( c, 0 ); 01175 return result; 01176 } 01177 01178 template < unsigned R, unsigned C > 01179 inline MsqMatrix< R, C > outer( const MsqMatrix< 1, R >& v1, const MsqMatrix< 1, C >& v2 ) 01180 { 01181 MsqMatrix< R, C > result; 01182 for( unsigned r = 0; r < R; ++r ) 01183 for( unsigned c = 0; c < C; ++c ) 01184 result( r, c ) = v1( 0, r ) * v2( 0, c ); 01185 return result; 01186 } 01187 01188 inline double vector_product( const MsqMatrix< 2, 1 >& v1, const MsqMatrix< 2, 1 >& v2 ) 01189 { 01190 return v1( 0, 0 ) * v2( 1, 0 ) - v1( 1, 0 ) * v2( 0, 0 ); 01191 } 01192 01193 inline double vector_product( const MsqMatrix< 1, 2 >& v1, const MsqMatrix< 1, 2 >& v2 ) 01194 { 01195 return v1( 0, 0 ) * v2( 0, 1 ) - v1( 0, 1 ) * v2( 0, 0 ); 01196 } 01197 01198 inline MsqMatrix< 3, 1 > vector_product( const MsqMatrix< 3, 1 >& a, const MsqMatrix< 3, 1 >& b ) 01199 { 01200 MsqMatrix< 3, 1 > result; 01201 result( 0, 0 ) = a( 1, 0 ) * b( 2, 0 ) - a( 2, 0 ) * b( 1, 0 ); 01202 result( 1, 0 ) = a( 2, 0 ) * b( 0, 0 ) - a( 0, 0 ) * b( 2, 0 ); 01203 result( 2, 0 ) = a( 0, 0 ) * b( 1, 0 ) - a( 1, 0 ) * b( 0, 0 ); 01204 return result; 01205 } 01206 01207 inline MsqMatrix< 1, 3 > vector_product( const MsqMatrix< 1, 3 >& a, const MsqMatrix< 1, 3 >& b ) 01208 { 01209 MsqMatrix< 1, 3 > result; 01210 result( 0, 0 ) = a( 0, 1 ) * b( 0, 2 ) - a( 0, 2 ) * b( 0, 1 ); 01211 result( 0, 1 ) = a( 0, 2 ) * b( 0, 0 ) - a( 0, 0 ) * b( 0, 2 ); 01212 result( 0, 2 ) = a( 0, 0 ) * b( 0, 1 ) - a( 0, 1 ) * b( 0, 0 ); 01213 return result; 01214 } 01215 01216 template < unsigned R, unsigned C > 01217 inline double operator%( const MsqMatrix< R, C >& v1, const MsqMatrix< R, C >& v2 ) 01218 { 01219 return inner_product( v1, v2 ); 01220 } 01221 01222 inline double operator*( const MsqMatrix< 2, 1 >& v1, const MsqMatrix< 2, 1 >& v2 ) 01223 { 01224 return vector_product( v1, v2 ); 01225 } 01226 01227 inline double operator*( const MsqMatrix< 1, 2 >& v1, const MsqMatrix< 1, 2 >& v2 ) 01228 { 01229 return vector_product( v1, v2 ); 01230 } 01231 01232 inline MsqMatrix< 3, 1 > operator*( const MsqMatrix< 3, 1 >& v1, const MsqMatrix< 3, 1 >& v2 ) 01233 { 01234 return vector_product( v1, v2 ); 01235 } 01236 01237 inline MsqMatrix< 1, 3 > operator*( const MsqMatrix< 1, 3 >& v1, const MsqMatrix< 1, 3 >& v2 ) 01238 { 01239 return vector_product( v1, v2 ); 01240 } 01241 01242 /** Compute QR factorization of A */ 01243 inline void QR( const MsqMatrix< 3, 3 >& A, MsqMatrix< 3, 3 >& Q, MsqMatrix< 3, 3 >& R ) 01244 { 01245 Q = A; 01246 01247 R( 0, 0 ) = sqrt( Q( 0, 0 ) * Q( 0, 0 ) + Q( 1, 0 ) * Q( 1, 0 ) + Q( 2, 0 ) * Q( 2, 0 ) ); 01248 double temp_dbl = 1.0 / R( 0, 0 ); 01249 R( 1, 0 ) = 0.0; 01250 R( 2, 0 ) = 0.0; 01251 Q( 0, 0 ) *= temp_dbl; 01252 Q( 1, 0 ) *= temp_dbl; 01253 Q( 2, 0 ) *= temp_dbl; 01254 01255 R( 0, 1 ) = Q( 0, 0 ) * Q( 0, 1 ) + Q( 1, 0 ) * Q( 1, 1 ) + Q( 2, 0 ) * Q( 2, 1 ); 01256 Q( 0, 1 ) -= Q( 0, 0 ) * R( 0, 1 ); 01257 Q( 1, 1 ) -= Q( 1, 0 ) * R( 0, 1 ); 01258 Q( 2, 1 ) -= Q( 2, 0 ) * R( 0, 1 ); 01259 01260 R( 0, 2 ) = Q( 0, 0 ) * Q( 0, 2 ) + Q( 1, 0 ) * Q( 1, 2 ) + Q( 2, 0 ) * Q( 2, 2 ); 01261 Q( 0, 2 ) -= Q( 0, 0 ) * R( 0, 2 ); 01262 Q( 1, 2 ) -= Q( 1, 0 ) * R( 0, 2 ); 01263 Q( 2, 2 ) -= Q( 2, 0 ) * R( 0, 2 ); 01264 01265 R( 1, 1 ) = sqrt( Q( 0, 1 ) * Q( 0, 1 ) + Q( 1, 1 ) * Q( 1, 1 ) + Q( 2, 1 ) * Q( 2, 1 ) ); 01266 temp_dbl = 1.0 / R( 1, 1 ); 01267 R( 2, 1 ) = 0.0; 01268 Q( 0, 1 ) *= temp_dbl; 01269 Q( 1, 1 ) *= temp_dbl; 01270 Q( 2, 1 ) *= temp_dbl; 01271 01272 R( 1, 2 ) = Q( 0, 1 ) * Q( 0, 2 ) + Q( 1, 1 ) * Q( 1, 2 ) + Q( 2, 1 ) * Q( 2, 2 ); 01273 Q( 0, 2 ) -= Q( 0, 1 ) * R( 1, 2 ); 01274 Q( 1, 2 ) -= Q( 1, 1 ) * R( 1, 2 ); 01275 Q( 2, 2 ) -= Q( 2, 1 ) * R( 1, 2 ); 01276 01277 R( 2, 2 ) = sqrt( Q( 0, 2 ) * Q( 0, 2 ) + Q( 1, 2 ) * Q( 1, 2 ) + Q( 2, 2 ) * Q( 2, 2 ) ); 01278 temp_dbl = 1.0 / R( 2, 2 ); 01279 Q( 0, 2 ) *= temp_dbl; 01280 Q( 1, 2 ) *= temp_dbl; 01281 Q( 2, 2 ) *= temp_dbl; 01282 } 01283 01284 /** Compute QR factorization of A */ 01285 inline void QR( const MsqMatrix< 2, 2 >& A, MsqMatrix< 2, 2 >& Q, MsqMatrix< 2, 2 >& R ) 01286 { 01287 R( 0, 0 ) = std::sqrt( A( 0, 0 ) * A( 0, 0 ) + A( 1, 0 ) * A( 1, 0 ) ); 01288 const double r0inv = 1.0 / R( 0, 0 ); 01289 Q( 0, 0 ) = Q( 1, 1 ) = A( 0, 0 ) * r0inv; 01290 Q( 1, 0 ) = A( 1, 0 ) * r0inv; 01291 Q( 0, 1 ) = -Q( 1, 0 ); 01292 R( 0, 1 ) = r0inv * ( A( 0, 0 ) * A( 0, 1 ) + A( 1, 0 ) * A( 1, 1 ) ); 01293 R( 1, 1 ) = r0inv * ( A( 0, 0 ) * A( 1, 1 ) - A( 0, 1 ) * A( 1, 0 ) ); 01294 R( 1, 0 ) = 0.0; 01295 } 01296 01297 } // namespace MBMesquite 01298 01299 #endif