Blender V2.61 - r43446

triang.h

Go to the documentation of this file.
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