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