00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 
00034 
00035 
00036 
00037 
00038 
00039 
00040 
00041 
00042 
00043 
00044 
00045 
00046 
00047 
00048 
00049 #ifndef SCPPNT_TRIANG_H
00050 #define SCPPNT_TRIANG_H
00051 
00052 #ifdef SCPPNT_NO_DIR_PREFIX
00053 #include "scppnt.h"
00054 #include "scppnt_error.h"
00055 #else
00056 #include "scppnt/scppnt.h"
00057 #include "scppnt/scppnt_error.h"
00058 #endif
00059 
00060 #ifndef SCPPNT_NO_IO
00061 #include <iostream>
00062 #endif
00063 
00064 namespace SCPPNT
00065 {
00066 
00067 
00068   template<class MaTRiX> class LowerTriangularView
00069   {
00070 protected:
00071 
00072     const MaTRiX &A_;
00073     const typename MaTRiX::element_type zero_;
00074 
00075 public:
00076 
00077     typedef typename MaTRiX::const_reference const_reference;
00078     typedef const typename MaTRiX::element_type element_type;
00079     typedef const typename MaTRiX::element_type value_type;
00080     typedef element_type T;
00081 
00082     Subscript dim(Subscript d) const
00083     {
00084       return A_.dim(d);
00085     }
00086     Subscript lbound() const
00087     {
00088       return A_.lbound();
00089     }
00090     Subscript num_rows() const
00091     {
00092       return A_.num_rows();
00093     }
00094     Subscript num_columns() const
00095     {
00096       return A_.num_columns();
00097     }
00098 
00099     
00100 
00101     LowerTriangularView(MaTRiX &A) :
00102       A_(A), zero_(0)
00103     {
00104     }
00105 
00106     inline const_reference get(Subscript i, Subscript j) const
00107     {
00108 #ifdef SCPPNT_BOUNDS_CHECK
00109       if (lbound() > i || i>(A_.num_rows() + lbound() - 1) || lbound > j || j>(A_.num_columns()
00110           + lbound() - 1))
00111         throw BoundsError("LowerTriangularView::get");
00112 #endif
00113       if (i<j)
00114         return zero_;
00115       else
00116         return A_(i, j);
00117     }
00118 
00119     inline const_reference operator()(Subscript i, Subscript j) const
00120     {
00121 #ifdef SCPPNT_BOUNDS_CHECK
00122       if (lbound() > i || i>(A_.num_rows() + lbound() - 1) || lbound > j || j>(A_.num_columns()
00123           + lbound() - 1))
00124         throw BoundsError("LowerTriangularView::operator()");
00125 #endif
00126       if (i<j)
00127         return zero_;
00128       else
00129         return A_(i, j);
00130     }
00131 
00132 #ifdef SCPPNT_USE_REGIONS
00133 
00134     typedef const_Region2D< LowerTriangularView<MaTRiX> >
00135     const_Region;
00136 
00137     const_Region operator()(Index1D &I,
00138         Index1D &J) const
00139     {
00140       return const_Region(*this, I, J);
00141     }
00142 
00143     const_Region operator()(Subscript i1, Subscript i2,
00144         Subscript j1, Subscript j2) const
00145     {
00146       return const_Region(*this, i1, i2, j1, j2);
00147     }
00148 
00149 #endif
00150     
00151 
00152   };
00153 
00154   
00155 
00156 
00157   template<class MaTRiX, class VecToR> VecToR matmult(LowerTriangularView<MaTRiX> &A,
00158       VecToR &x)
00159   {
00160     Subscript M = A.num_rows();
00161     Subscript N = A.num_columns();
00162 
00163     
00164     if (N != x.dim())
00165       throw BoundsError("matmult(LowerTriangularView,Vector)");
00166 
00167     Subscript i, j;
00168     typename MaTRiX::element_type sum=0.0;
00169     VecToR result(M);
00170 
00171     Subscript start = A.lbound();
00172     Subscript Mend = M + A.lbound() -1;
00173 
00174     for (i=start; i<=Mend; i++)
00175     {
00176       sum = 0.0;
00177       for (j=start; j<=i; j++)
00178         sum = sum + A(i, j)*x(j);
00179       result(i) = sum;
00180     }
00181 
00182     return result;
00183   }
00184 
00185 
00186   template<class MaTRiX, class VecToR> inline VecToR operator*(
00187       LowerTriangularView<MaTRiX> &A, VecToR &x)
00188   {
00189     return matmult(A, x);
00190   }
00191 
00192 
00193   template<class MaTRiX> class UnitLowerTriangularView
00194   {
00195 protected:
00196 
00197     const MaTRiX &A_;
00198     const typename MaTRiX::element_type zero;
00199     const typename MaTRiX::element_type one;
00200 
00201 public:
00202 
00203     typedef typename MaTRiX::const_reference const_reference;
00204     typedef typename MaTRiX::element_type element_type;
00205     typedef typename MaTRiX::element_type value_type;
00206     typedef element_type T;
00207 
00208     Subscript lbound() const
00209     {
00210       return 1;
00211     }
00212     Subscript dim(Subscript d) const
00213     {
00214       return A_.dim(d);
00215     }
00216     Subscript num_rows() const
00217     {
00218       return A_.num_rows();
00219     }
00220     Subscript num_columns() const
00221     {
00222       return A_.num_columns();
00223     }
00224 
00225     
00226 
00227     UnitLowerTriangularView(MaTRiX &A) :
00228       A_(A), zero(0), one(1)
00229     {
00230     }
00231 
00232     inline const_reference get(Subscript i, Subscript j) const
00233     {
00234 #ifdef SCPPNT_BOUNDS_CHECK
00235       if (1>i || i>A_.dim(1) || 1>j || j>A_.dim(2) || !(0<=i && i<A_.dim(0) && 0<=j && j<A_.dim(1)))
00236         throw BoundsError("UnitLowerTriangularView::get");
00237 #endif
00238       if (i>j)
00239         return A_(i, j);
00240       else if (i==j)
00241         return one;
00242       else
00243         return zero;
00244     }
00245 
00246     inline const_reference operator()(Subscript i, Subscript j) const
00247     {
00248 #ifdef SCPPNT_BOUNDS_CHECK
00249       if (1>i || i>A_.dim(1) || 1>j || j>A_.dim(2))
00250         throw BoundsError("UnitLowerTriangularView::operator()");
00251 #endif
00252       if (i>j)
00253         return A_(i, j);
00254       else if (i==j)
00255         return one;
00256       else
00257         return zero;
00258     }
00259 
00260 #ifdef SCPPNT_USE_REGIONS
00261     
00262 
00263     typedef const_Region2D< UnitLowerTriangularView<MaTRiX> >
00264     const_Region;
00265 
00266     const_Region operator()(Index1D &I,
00267         Index1D &J) const
00268     {
00269       return const_Region(*this, I, J);
00270     }
00271 
00272     const_Region operator()(Subscript i1, Subscript i2,
00273         Subscript j1, Subscript j2) const
00274     {
00275       return const_Region(*this, i1, i2, j1, j2);
00276     }
00277 #endif
00278     
00279   };
00280 
00281 
00282   template<class MaTRiX> LowerTriangularView<MaTRiX> Lower_triangular_view(
00283   MaTRiX &A)
00284   {
00285     return LowerTriangularView<MaTRiX>(A);
00286   }
00287 
00288 
00289   template<class MaTRiX> UnitLowerTriangularView<MaTRiX> Unit_lower_triangular_view(
00290   MaTRiX &A)
00291   {
00292     return UnitLowerTriangularView<MaTRiX>(A);
00293   }
00294 
00295 
00296   template<class MaTRiX, class VecToR> VecToR matmult(UnitLowerTriangularView<MaTRiX> &A,
00297       VecToR &x)
00298   {
00299     Subscript M = A.num_rows();
00300     Subscript N = A.num_columns();
00301 
00302     
00303     if (N != x.dim())
00304       throw BoundsError("matmult(UnitLowerTriangularView,Vector)");
00305 
00306     Subscript i, j;
00307     typename MaTRiX::element_type sum=0.0;
00308     VecToR result(M);
00309 
00310     Subscript start = A.lbound();
00311     Subscript Mend = M + A.lbound() -1;
00312 
00313     for (i=start; i<=Mend; i++)
00314     {
00315       sum = 0.0;
00316       for (j=start; j<i; j++)
00317         sum = sum + A(i, j)*x(j);
00318       result(i) = sum + x(i);
00319     }
00320 
00321     return result;
00322   }
00323 
00324 
00325   template<class MaTRiX, class VecToR> inline VecToR operator*(
00326       UnitLowerTriangularView<MaTRiX> &A, VecToR &x)
00327   {
00328     return matmult(A, x);
00329   }
00330 
00331   
00332 
00333 
00334 #ifndef SCPPNT_NO_IO
00335 
00336   template<class MaTRiX> std::ostream& operator<<(std::ostream &s,
00337       const LowerTriangularView<MaTRiX>&A)
00338   {
00339     Subscript M=A.num_rows();
00340     Subscript N=A.num_columns();
00341 
00342     s << M << " " << N << std::endl;
00343 
00344     for (Subscript i=1; i<=M; i++)
00345     {
00346       for (Subscript j=1; j<=N; j++)
00347       {
00348         s << A(i, j) << " ";
00349       }
00350       s << std::endl;
00351     }
00352 
00353     return s;
00354   }
00355 
00356 
00357   template<class MaTRiX> std::ostream& operator<<(std::ostream &s,
00358       const UnitLowerTriangularView<MaTRiX>&A)
00359   {
00360     Subscript M=A.num_rows();
00361     Subscript N=A.num_columns();
00362 
00363     s << M << " " << N << std::endl;
00364 
00365     for (Subscript i=1; i<=M; i++)
00366     {
00367       for (Subscript j=1; j<=N; j++)
00368       {
00369         s << A(i, j) << " ";
00370       }
00371       s << std::endl;
00372     }
00373 
00374     return s;
00375   }
00376 
00377 #endif
00378 
00379   
00380 
00381 
00382   template<class MaTRiX> class UpperTriangularView
00383   {
00384 protected:
00385 
00386     MaTRiX &A_;
00387     
00388     typename MaTRiX::element_type zero_;
00389 
00390 public:
00391 
00392     typedef typename MaTRiX::const_reference const_reference;
00393     typedef typename MaTRiX::element_type element_type;
00394     typedef typename MaTRiX::element_type value_type;
00395     typedef element_type T;
00396 
00397     Subscript dim(Subscript d) const
00398     {
00399       return A_.dim(d);
00400     }
00401     Subscript lbound() const
00402     {
00403       return A_.lbound();
00404     }
00405     Subscript num_rows() const
00406     {
00407       return A_.num_rows();
00408     }
00409     Subscript num_columns() const
00410     {
00411       return A_.num_columns();
00412     }
00413 
00414     
00415 
00416     UpperTriangularView(MaTRiX &A) :
00417       A_(A), zero_(0)
00418     {
00419     }
00420 
00421     inline const_reference get(Subscript i, Subscript j) const
00422     {
00423 #ifdef SCPPNT_BOUNDS_CHECK
00424       if (lbound>i || i>(A_.num_rows() + lbound() - 1) || lbound()>j || j>(A_.num_columns()
00425           + lbound() - 1))
00426         throw BoundsError("UpperTriangularView::get");
00427 #endif
00428       if (i>j)
00429         return zero_;
00430       else
00431         return A_(i, j);
00432     }
00433 
00434     inline const_reference operator()(Subscript i, Subscript j) const
00435     {
00436 #ifdef SCPPNT_BOUNDS_CHECK
00437       if (lbound()>i || i>(A_.num_rows() + lbound() - 1) || lbound()>j || j>(A_.num_columns()
00438           + lbound() - 1))
00439         throw BoundsError("UpperTriangularView::operator()");
00440 #endif
00441       if (i>j)
00442         return zero_;
00443       else
00444         return A_(i, j);
00445     }
00446 
00447 #ifdef SCPPNT_USE_REGIONS
00448 
00449     typedef const_Region2D< UpperTriangularView<MaTRiX> >
00450     const_Region;
00451 
00452     const_Region operator()(const Index1D &I,
00453         const Index1D &J) const
00454     {
00455       return const_Region(*this, I, J);
00456     }
00457 
00458     const_Region operator()(Subscript i1, Subscript i2,
00459         Subscript j1, Subscript j2) const
00460     {
00461       return const_Region(*this, i1, i2, j1, j2);
00462     }
00463 
00464 #endif
00465     
00466 
00467   };
00468 
00469   
00470 
00471 
00472   template<class MaTRiX, class VecToR> VecToR matmult(UpperTriangularView<MaTRiX> &A,
00473       VecToR &x)
00474   {
00475     Subscript M = A.num_rows();
00476     Subscript N = A.num_columns();
00477 
00478     
00479     if (N != x.dim())
00480       throw BoundsError("matmult(UpperTriangularView,Vector)");
00481 
00482     Subscript i, j;
00483     typename VecToR::element_type sum=0.0;
00484     VecToR result(M);
00485 
00486     Subscript start = A.lbound();
00487     Subscript Mend = M + A.lbound() -1;
00488 
00489     for (i=start; i<=Mend; i++)
00490     {
00491       sum = 0.0;
00492       for (j=i; j<=N; j++)
00493         sum = sum + A(i, j)*x(j);
00494       result(i) = sum;
00495     }
00496 
00497     return result;
00498   }
00499 
00500 
00501   template<class MaTRiX, class VecToR> inline VecToR operator*(
00502       UpperTriangularView<MaTRiX> &A, VecToR &x)
00503   {
00504     return matmult(A, x);
00505   }
00506 
00507 
00508   template<class MaTRiX> class UnitUpperTriangularView
00509   {
00510 protected:
00511 
00512     const MaTRiX &A_;
00513     const typename MaTRiX::element_type zero;
00514     const typename MaTRiX::element_type one;
00515 
00516 public:
00517 
00518     typedef typename MaTRiX::const_reference const_reference;
00519     typedef typename MaTRiX::element_type element_type;
00520     typedef typename MaTRiX::element_type value_type;
00521     typedef element_type T;
00522 
00523     Subscript lbound() const
00524     {
00525       return 1;
00526     }
00527     Subscript dim(Subscript d) const
00528     {
00529       return A_.dim(d);
00530     }
00531     Subscript num_rows() const
00532     {
00533       return A_.num_rows();
00534     }
00535     Subscript num_columns() const
00536     {
00537       return A_.num_columns();
00538     }
00539 
00540     
00541 
00542     UnitUpperTriangularView(MaTRiX &A) :
00543       A_(A), zero(0), one(1)
00544     {
00545     }
00546 
00547     inline const_reference get(Subscript i, Subscript j) const
00548     {
00549 #ifdef SCPPNT_BOUNDS_CHECK
00550       if (1>i || i>A_.dim(1) || 1>j || j>A_.dim(2) || !(0<=i && i<A_.dim(0) && 0<=j && j<A_.dim(1)))
00551         throw BoundsError("UnitUpperTriangularView::get");
00552 #endif
00553       if (i<j)
00554         return A_(i, j);
00555       else if (i==j)
00556         return one;
00557       else
00558         return zero;
00559     }
00560 
00561     inline const_reference operator()(Subscript i, Subscript j) const
00562     {
00563 #ifdef SCPPNT_BOUNDS_CHECK
00564       if (1>i || i>A_.dim(1) || 1>j || j>A_.dim(2))
00565         throw BoundsError("UnitUpperTriangularView::operator()");
00566 #endif
00567       if (i<j)
00568         return A_(i, j);
00569       else if (i==j)
00570         return one;
00571       else
00572         return zero;
00573     }
00574 
00575 #ifdef SCPPNT_USE_REGIONS
00576     
00577 
00578     typedef const_Region2D< UnitUpperTriangularView<MaTRiX> >
00579     const_Region;
00580 
00581     const_Region operator()(const Index1D &I,
00582         const Index1D &J) const
00583     {
00584       return const_Region(*this, I, J);
00585     }
00586 
00587     const_Region operator()(Subscript i1, Subscript i2,
00588         Subscript j1, Subscript j2) const
00589     {
00590       return const_Region(*this, i1, i2, j1, j2);
00591     }
00592 #endif
00593     
00594   };
00595 
00596 
00597   template<class MaTRiX> UpperTriangularView<MaTRiX> Upper_triangular_view(
00598   MaTRiX &A)
00599   {
00600     return UpperTriangularView<MaTRiX>(A);
00601   }
00602 
00603   
00604   template<class MaTRiX> UnitUpperTriangularView<MaTRiX> Unit_upper_triangular_view(
00605   MaTRiX &A)
00606   {
00607     return UnitUpperTriangularView<MaTRiX>(A);
00608   }
00609 
00610 
00611   template<class MaTRiX, class VecToR> VecToR matmult(UnitUpperTriangularView<MaTRiX> &A,
00612       VecToR &x)
00613   {
00614     Subscript M = A.num_rows();
00615     Subscript N = A.num_columns();
00616 
00617     
00618     if (N != x.dim())
00619       throw BoundsError("matmult(UnitUpperTriangularView,Vector)");
00620 
00621     Subscript i, j;
00622     typename VecToR::element_type sum=0.0;
00623     VecToR result(M);
00624 
00625     Subscript start = A.lbound();
00626     Subscript Mend = M + A.lbound() -1;
00627 
00628     for (i=start; i<=Mend; i++)
00629     {
00630       sum = x(i);
00631       for (j=i+1; j<=N; j++)
00632         sum = sum + A(i, j)*x(j);
00633       result(i) = sum + x(i);
00634     }
00635 
00636     return result;
00637   }
00638 
00639 
00640   template<class MaTRiX, class VecToR> inline VecToR operator*(
00641       UnitUpperTriangularView<MaTRiX> &A, VecToR &x)
00642   {
00643     return matmult(A, x);
00644   }
00645 
00646   
00647 
00648 
00649 #ifndef SCPPNT_NO_IO
00650 
00651 
00652   template<class MaTRiX> std::ostream& operator<<(std::ostream &s,
00653   UpperTriangularView<MaTRiX>&A)
00654   {
00655     Subscript M=A.num_rows();
00656     Subscript N=A.num_columns();
00657 
00658     s << M << " " << N << std::endl;
00659 
00660     for (Subscript i=1; i<=M; i++)
00661     {
00662       for (Subscript j=1; j<=N; j++)
00663       {
00664         s << A(i, j) << " ";
00665       }
00666       s << std::endl;
00667     }
00668 
00669     return s;
00670   }
00671 
00672 
00673   template<class MaTRiX> std::ostream& operator<<(std::ostream &s,
00674   UnitUpperTriangularView<MaTRiX>&A)
00675   {
00676     Subscript M=A.num_rows();
00677     Subscript N=A.num_columns();
00678 
00679     s << M << " " << N << std::endl;
00680 
00681     for (Subscript i=1; i<=M; i++)
00682     {
00683       for (Subscript j=1; j<=N; j++)
00684       {
00685         s << A(i, j) << " ";
00686       }
00687       s << std::endl;
00688     }
00689 
00690     return s;
00691   }
00692 
00693 #endif
00694 
00695 } 
00696 
00697 
00698 #endif 
00699 
00700