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