Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members

tnt_triang.h

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

Generated on Fri Sep 16 11:02:17 2005 for spuc by  doxygen 1.4.4