Blender  V2.59
triang.h
Go to the documentation of this file.
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