|
Blender
V2.59
|
00001 00005 /* 00006 00007 * 00008 * Template Numerical Toolkit (TNT): Linear Algebra Module 00009 * 00010 * Mathematical and Computational Sciences Division 00011 * National Institute of Technology, 00012 * Gaithersburg, MD USA 00013 * 00014 * 00015 * This software was developed at the National Institute of Standards and 00016 * Technology (NIST) by employees of the Federal Government in the course 00017 * of their official duties. Pursuant to title 17 Section 105 of the 00018 * United States Code, this software is not subject to copyright protection 00019 * and is in the public domain. The Template Numerical Toolkit (TNT) is 00020 * an experimental system. NIST assumes no responsibility whatsoever for 00021 * its use by other parties, and makes no guarantees, expressed or implied, 00022 * about its quality, reliability, or any other characteristic. 00023 * 00024 * BETA VERSION INCOMPLETE AND SUBJECT TO CHANGE 00025 * see http://math.nist.gov/tnt for latest updates. 00026 * 00027 */ 00028 00029 00030 00031 // Triangular Matrices (Views and Adpators) 00032 00033 #ifndef TRIANG_H 00034 #define TRIANG_H 00035 00036 // default to use lower-triangular portions of arrays 00037 // for symmetric matrices. 00038 00039 namespace TNT 00040 { 00041 00042 template <class MaTRiX> 00043 class LowerTriangularView 00044 { 00045 protected: 00046 00047 00048 const MaTRiX &A_; 00049 const typename MaTRiX::element_type zero_; 00050 00051 public: 00052 00053 00054 typedef typename MaTRiX::const_reference const_reference; 00055 typedef const typename MaTRiX::element_type element_type; 00056 typedef const typename MaTRiX::element_type value_type; 00057 typedef element_type T; 00058 00059 Subscript dim(Subscript d) const { return A_.dim(d); } 00060 Subscript lbound() const { return A_.lbound(); } 00061 Subscript num_rows() const { return A_.num_rows(); } 00062 Subscript num_cols() const { return A_.num_cols(); } 00063 00064 00065 // constructors 00066 00067 LowerTriangularView(/*const*/ MaTRiX &A) : A_(A), zero_(0) {} 00068 00069 00070 inline const_reference get(Subscript i, Subscript j) const 00071 { 00072 #ifdef TNT_BOUNDS_CHECK 00073 assert(lbound()<=i); 00074 assert(i<=A_.num_rows() + lbound() - 1); 00075 assert(lbound()<=j); 00076 assert(j<=A_.num_cols() + lbound() - 1); 00077 #endif 00078 if (i<j) 00079 return zero_; 00080 else 00081 return A_(i,j); 00082 } 00083 00084 00085 inline const_reference operator() (Subscript i, Subscript j) const 00086 { 00087 #ifdef TNT_BOUNDS_CHECK 00088 assert(lbound()<=i); 00089 assert(i<=A_.num_rows() + lbound() - 1); 00090 assert(lbound()<=j); 00091 assert(j<=A_.num_cols() + lbound() - 1); 00092 #endif 00093 if (i<j) 00094 return zero_; 00095 else 00096 return A_(i,j); 00097 } 00098 00099 #ifdef TNT_USE_REGIONS 00100 00101 typedef const_Region2D< LowerTriangularView<MaTRiX> > 00102 const_Region; 00103 00104 const_Region operator()(/*const*/ Index1D &I, 00105 /*const*/ Index1D &J) const 00106 { 00107 return const_Region(*this, I, J); 00108 } 00109 00110 const_Region operator()(Subscript i1, Subscript i2, 00111 Subscript j1, Subscript j2) const 00112 { 00113 return const_Region(*this, i1, i2, j1, j2); 00114 } 00115 00116 00117 00118 #endif 00119 // TNT_USE_REGIONS 00120 00121 }; 00122 00123 00124 /* *********** Lower_triangular_view() algorithms ****************** */ 00125 00126 template <class MaTRiX, class VecToR> 00127 VecToR matmult(/*const*/ LowerTriangularView<MaTRiX> &A, VecToR &x) 00128 { 00129 Subscript M = A.num_rows(); 00130 Subscript N = A.num_cols(); 00131 00132 assert(N == x.dim()); 00133 00134 Subscript i, j; 00135 typename MaTRiX::element_type sum=0.0; 00136 VecToR result(M); 00137 00138 Subscript start = A.lbound(); 00139 Subscript Mend = M + A.lbound() -1 ; 00140 00141 for (i=start; i<=Mend; i++) 00142 { 00143 sum = 0.0; 00144 for (j=start; j<=i; j++) 00145 sum = sum + A(i,j)*x(j); 00146 result(i) = sum; 00147 } 00148 00149 return result; 00150 } 00151 00152 template <class MaTRiX, class VecToR> 00153 inline VecToR operator*(/*const*/ LowerTriangularView<MaTRiX> &A, VecToR &x) 00154 { 00155 return matmult(A,x); 00156 } 00157 00158 template <class MaTRiX> 00159 class UnitLowerTriangularView 00160 { 00161 protected: 00162 00163 const MaTRiX &A_; 00164 const typename MaTRiX::element_type zero; 00165 const typename MaTRiX::element_type one; 00166 00167 public: 00168 00169 typedef typename MaTRiX::const_reference const_reference; 00170 typedef typename MaTRiX::element_type element_type; 00171 typedef typename MaTRiX::element_type value_type; 00172 typedef element_type T; 00173 00174 Subscript lbound() const { return 1; } 00175 Subscript dim(Subscript d) const { return A_.dim(d); } 00176 Subscript num_rows() const { return A_.num_rows(); } 00177 Subscript num_cols() const { return A_.num_cols(); } 00178 00179 00180 // constructors 00181 00182 UnitLowerTriangularView(/*const*/ MaTRiX &A) : A_(A), zero(0), one(1) {} 00183 00184 00185 inline const_reference get(Subscript i, Subscript j) const 00186 { 00187 #ifdef TNT_BOUNDS_CHECK 00188 assert(1<=i); 00189 assert(i<=A_.dim(1)); 00190 assert(1<=j); 00191 assert(j<=A_.dim(2)); 00192 assert(0<=i && i<A_.dim(0) && 0<=j && j<A_.dim(1)); 00193 #endif 00194 if (i>j) 00195 return A_(i,j); 00196 else if (i==j) 00197 return one; 00198 else 00199 return zero; 00200 } 00201 00202 00203 inline const_reference operator() (Subscript i, Subscript j) const 00204 { 00205 #ifdef TNT_BOUNDS_CHECK 00206 assert(1<=i); 00207 assert(i<=A_.dim(1)); 00208 assert(1<=j); 00209 assert(j<=A_.dim(2)); 00210 #endif 00211 if (i>j) 00212 return A_(i,j); 00213 else if (i==j) 00214 return one; 00215 else 00216 return zero; 00217 } 00218 00219 00220 #ifdef TNT_USE_REGIONS 00221 // These are the "index-aware" features 00222 00223 typedef const_Region2D< UnitLowerTriangularView<MaTRiX> > 00224 const_Region; 00225 00226 const_Region operator()(/*const*/ Index1D &I, 00227 /*const*/ Index1D &J) const 00228 { 00229 return const_Region(*this, I, J); 00230 } 00231 00232 const_Region operator()(Subscript i1, Subscript i2, 00233 Subscript j1, Subscript j2) const 00234 { 00235 return const_Region(*this, i1, i2, j1, j2); 00236 } 00237 #endif 00238 // TNT_USE_REGIONS 00239 }; 00240 00241 template <class MaTRiX> 00242 LowerTriangularView<MaTRiX> Lower_triangular_view( 00243 /*const*/ MaTRiX &A) 00244 { 00245 return LowerTriangularView<MaTRiX>(A); 00246 } 00247 00248 00249 template <class MaTRiX> 00250 UnitLowerTriangularView<MaTRiX> Unit_lower_triangular_view( 00251 /*const*/ MaTRiX &A) 00252 { 00253 return UnitLowerTriangularView<MaTRiX>(A); 00254 } 00255 00256 template <class MaTRiX, class VecToR> 00257 VecToR matmult(/*const*/ UnitLowerTriangularView<MaTRiX> &A, VecToR &x) 00258 { 00259 Subscript M = A.num_rows(); 00260 Subscript N = A.num_cols(); 00261 00262 assert(N == x.dim()); 00263 00264 Subscript i, j; 00265 typename MaTRiX::element_type sum=0.0; 00266 VecToR result(M); 00267 00268 Subscript start = A.lbound(); 00269 Subscript Mend = M + A.lbound() -1 ; 00270 00271 for (i=start; i<=Mend; i++) 00272 { 00273 sum = 0.0; 00274 for (j=start; j<i; j++) 00275 sum = sum + A(i,j)*x(j); 00276 result(i) = sum + x(i); 00277 } 00278 00279 return result; 00280 } 00281 00282 template <class MaTRiX, class VecToR> 00283 inline VecToR operator*(/*const*/ UnitLowerTriangularView<MaTRiX> &A, VecToR &x) 00284 { 00285 return matmult(A,x); 00286 } 00287 00288 00289 //********************** Algorithms ************************************* 00290 00291 00292 00293 template <class MaTRiX> 00294 std::ostream& operator<<(std::ostream &s, const LowerTriangularView<MaTRiX>&A) 00295 { 00296 Subscript M=A.num_rows(); 00297 Subscript N=A.num_cols(); 00298 00299 s << M << " " << N << endl; 00300 00301 for (Subscript i=1; i<=M; i++) 00302 { 00303 for (Subscript j=1; j<=N; j++) 00304 { 00305 s << A(i,j) << " "; 00306 } 00307 s << endl; 00308 } 00309 00310 00311 return s; 00312 } 00313 00314 template <class MaTRiX> 00315 std::ostream& operator<<(std::ostream &s, 00316 const UnitLowerTriangularView<MaTRiX>&A) 00317 { 00318 Subscript M=A.num_rows(); 00319 Subscript N=A.num_cols(); 00320 00321 s << M << " " << N << endl; 00322 00323 for (Subscript i=1; i<=M; i++) 00324 { 00325 for (Subscript j=1; j<=N; j++) 00326 { 00327 s << A(i,j) << " "; 00328 } 00329 s << endl; 00330 } 00331 00332 00333 return s; 00334 } 00335 00336 00337 00338 // ******************* Upper Triangular Section ************************** 00339 00340 template <class MaTRiX> 00341 class UpperTriangularView 00342 { 00343 protected: 00344 00345 00346 /*const*/ MaTRiX &A_; 00347 /*const*/ typename MaTRiX::element_type zero_; 00348 00349 public: 00350 00351 00352 typedef typename MaTRiX::const_reference const_reference; 00353 typedef /*const*/ typename MaTRiX::element_type element_type; 00354 typedef /*const*/ typename MaTRiX::element_type value_type; 00355 typedef element_type T; 00356 00357 Subscript dim(Subscript d) const { return A_.dim(d); } 00358 Subscript lbound() const { return A_.lbound(); } 00359 Subscript num_rows() const { return A_.num_rows(); } 00360 Subscript num_cols() const { return A_.num_cols(); } 00361 00362 00363 // constructors 00364 00365 UpperTriangularView(/*const*/ MaTRiX &A) : A_(A), zero_(0) {} 00366 00367 00368 inline const_reference get(Subscript i, Subscript j) const 00369 { 00370 #ifdef TNT_BOUNDS_CHECK 00371 assert(lbound()<=i); 00372 assert(i<=A_.num_rows() + lbound() - 1); 00373 assert(lbound()<=j); 00374 assert(j<=A_.num_cols() + lbound() - 1); 00375 #endif 00376 if (i>j) 00377 return zero_; 00378 else 00379 return A_(i,j); 00380 } 00381 00382 00383 inline const_reference operator() (Subscript i, Subscript j) const 00384 { 00385 #ifdef TNT_BOUNDS_CHECK 00386 assert(lbound()<=i); 00387 assert(i<=A_.num_rows() + lbound() - 1); 00388 assert(lbound()<=j); 00389 assert(j<=A_.num_cols() + lbound() - 1); 00390 #endif 00391 if (i>j) 00392 return zero_; 00393 else 00394 return A_(i,j); 00395 } 00396 00397 #ifdef TNT_USE_REGIONS 00398 00399 typedef const_Region2D< UpperTriangularView<MaTRiX> > 00400 const_Region; 00401 00402 const_Region operator()(const Index1D &I, 00403 const Index1D &J) const 00404 { 00405 return const_Region(*this, I, J); 00406 } 00407 00408 const_Region operator()(Subscript i1, Subscript i2, 00409 Subscript j1, Subscript j2) const 00410 { 00411 return const_Region(*this, i1, i2, j1, j2); 00412 } 00413 00414 00415 00416 #endif 00417 // TNT_USE_REGIONS 00418 00419 }; 00420 00421 00422 /* *********** Upper_triangular_view() algorithms ****************** */ 00423 00424 template <class MaTRiX, class VecToR> 00425 VecToR matmult(/*const*/ UpperTriangularView<MaTRiX> &A, VecToR &x) 00426 { 00427 Subscript M = A.num_rows(); 00428 Subscript N = A.num_cols(); 00429 00430 assert(N == x.dim()); 00431 00432 Subscript i, j; 00433 typename VecToR::element_type sum=0.0; 00434 VecToR result(M); 00435 00436 Subscript start = A.lbound(); 00437 Subscript Mend = M + A.lbound() -1 ; 00438 00439 for (i=start; i<=Mend; i++) 00440 { 00441 sum = 0.0; 00442 for (j=i; j<=N; j++) 00443 sum = sum + A(i,j)*x(j); 00444 result(i) = sum; 00445 } 00446 00447 return result; 00448 } 00449 00450 template <class MaTRiX, class VecToR> 00451 inline VecToR operator*(/*const*/ UpperTriangularView<MaTRiX> &A, VecToR &x) 00452 { 00453 return matmult(A,x); 00454 } 00455 00456 template <class MaTRiX> 00457 class UnitUpperTriangularView 00458 { 00459 protected: 00460 00461 const MaTRiX &A_; 00462 const typename MaTRiX::element_type zero; 00463 const typename MaTRiX::element_type one; 00464 00465 public: 00466 00467 typedef typename MaTRiX::const_reference const_reference; 00468 typedef typename MaTRiX::element_type element_type; 00469 typedef typename MaTRiX::element_type value_type; 00470 typedef element_type T; 00471 00472 Subscript lbound() const { return 1; } 00473 Subscript dim(Subscript d) const { return A_.dim(d); } 00474 Subscript num_rows() const { return A_.num_rows(); } 00475 Subscript num_cols() const { return A_.num_cols(); } 00476 00477 00478 // constructors 00479 00480 UnitUpperTriangularView(/*const*/ MaTRiX &A) : A_(A), zero(0), one(1) {} 00481 00482 00483 inline const_reference get(Subscript i, Subscript j) const 00484 { 00485 #ifdef TNT_BOUNDS_CHECK 00486 assert(1<=i); 00487 assert(i<=A_.dim(1)); 00488 assert(1<=j); 00489 assert(j<=A_.dim(2)); 00490 assert(0<=i && i<A_.dim(0) && 0<=j && j<A_.dim(1)); 00491 #endif 00492 if (i<j) 00493 return A_(i,j); 00494 else if (i==j) 00495 return one; 00496 else 00497 return zero; 00498 } 00499 00500 00501 inline const_reference operator() (Subscript i, Subscript j) const 00502 { 00503 #ifdef TNT_BOUNDS_CHECK 00504 assert(1<=i); 00505 assert(i<=A_.dim(1)); 00506 assert(1<=j); 00507 assert(j<=A_.dim(2)); 00508 #endif 00509 if (i<j) 00510 return A_(i,j); 00511 else if (i==j) 00512 return one; 00513 else 00514 return zero; 00515 } 00516 00517 00518 #ifdef TNT_USE_REGIONS 00519 // These are the "index-aware" features 00520 00521 typedef const_Region2D< UnitUpperTriangularView<MaTRiX> > 00522 const_Region; 00523 00524 const_Region operator()(const Index1D &I, 00525 const Index1D &J) const 00526 { 00527 return const_Region(*this, I, J); 00528 } 00529 00530 const_Region operator()(Subscript i1, Subscript i2, 00531 Subscript j1, Subscript j2) const 00532 { 00533 return const_Region(*this, i1, i2, j1, j2); 00534 } 00535 #endif 00536 // TNT_USE_REGIONS 00537 }; 00538 00539 template <class MaTRiX> 00540 UpperTriangularView<MaTRiX> Upper_triangular_view( 00541 /*const*/ MaTRiX &A) 00542 { 00543 return UpperTriangularView<MaTRiX>(A); 00544 } 00545 00546 00547 template <class MaTRiX> 00548 UnitUpperTriangularView<MaTRiX> Unit_upper_triangular_view( 00549 /*const*/ MaTRiX &A) 00550 { 00551 return UnitUpperTriangularView<MaTRiX>(A); 00552 } 00553 00554 template <class MaTRiX, class VecToR> 00555 VecToR matmult(/*const*/ UnitUpperTriangularView<MaTRiX> &A, VecToR &x) 00556 { 00557 Subscript M = A.num_rows(); 00558 Subscript N = A.num_cols(); 00559 00560 assert(N == x.dim()); 00561 00562 Subscript i, j; 00563 typename VecToR::element_type sum=0.0; 00564 VecToR result(M); 00565 00566 Subscript start = A.lbound(); 00567 Subscript Mend = M + A.lbound() -1 ; 00568 00569 for (i=start; i<=Mend; i++) 00570 { 00571 sum = x(i); 00572 for (j=i+1; j<=N; j++) 00573 sum = sum + A(i,j)*x(j); 00574 result(i) = sum + x(i); 00575 } 00576 00577 return result; 00578 } 00579 00580 template <class MaTRiX, class VecToR> 00581 inline VecToR operator*(/*const*/ UnitUpperTriangularView<MaTRiX> &A, VecToR &x) 00582 { 00583 return matmult(A,x); 00584 } 00585 00586 00587 //********************** Algorithms ************************************* 00588 00589 00590 00591 template <class MaTRiX> 00592 std::ostream& operator<<(std::ostream &s, 00593 /*const*/ UpperTriangularView<MaTRiX>&A) 00594 { 00595 Subscript M=A.num_rows(); 00596 Subscript N=A.num_cols(); 00597 00598 s << M << " " << N << endl; 00599 00600 for (Subscript i=1; i<=M; i++) 00601 { 00602 for (Subscript j=1; j<=N; j++) 00603 { 00604 s << A(i,j) << " "; 00605 } 00606 s << endl; 00607 } 00608 00609 00610 return s; 00611 } 00612 00613 template <class MaTRiX> 00614 std::ostream& operator<<(std::ostream &s, 00615 /*const*/ UnitUpperTriangularView<MaTRiX>&A) 00616 { 00617 Subscript M=A.num_rows(); 00618 Subscript N=A.num_cols(); 00619 00620 s << M << " " << N << endl; 00621 00622 for (Subscript i=1; i<=M; i++) 00623 { 00624 for (Subscript j=1; j<=N; j++) 00625 { 00626 s << A(i,j) << " "; 00627 } 00628 s << endl; 00629 } 00630 00631 00632 return s; 00633 } 00634 00635 } // namespace TNT 00636 00637 #endif //TRIANG_H 00638