source: Sophya/trunk/SophyaLib/TArray/triangmtx.h@ 3664

Last change on this file since 3664 was 3619, checked in by cmv, 16 years ago

add various #include<> for g++ 4.3 (jaunty 9.04), cmv 05/05/2009

File size: 5.6 KB
Line 
1// This may look like C code, but it is really -*- C++ -*-
2
3#ifndef TRIANGMTX_H_SEEN
4#define TRIANGMTX_H_SEEN
5
6#include <typeinfo>
7#include "ndatablock.h"
8#include "pexceptions.h"
9
10// doit etre mis en dehors du namespace
11/*!
12 \class SOPHYA::TriangularMatrix
13 \ingroup TArray
14 \brief Class for inferior triangular matrix (base class for the class Alm)
15 The inferior triangular matrix is represented in memory as column packed,
16 as illustrated below for a 5x5 triangular matrix.
17 \verbatim
18 5x5 Inf.Triang.Matrix, Size= 15 elements (0 ... 14)
19 | 0 |
20 | 1 5 |
21 | 2 6 9 |
22 | 3 7 10 12 |
23 | 4 8 11 13 14 |
24 \endverbatim
25*/
26
27namespace SOPHYA {
28
29//! Class for inferior triangular matrix (base class for the class Alm)
30template <class T>
31class TriangularMatrix {
32public :
33
34//! Default constructor
35TriangularMatrix()
36 : long_diag_(0)
37{
38}
39
40//! instanciate a triangular matrix from the number of rows
41TriangularMatrix(sa_size_t rowSize)
42 : long_diag_(rowSize)
43{
44 elem_.ReSize((rowSize*(rowSize+1)/2) );
45}
46
47//! Copy constructor (possibility of sharing datas)
48TriangularMatrix(const TriangularMatrix<T>& a, bool share=false)
49 : long_diag_(a.long_diag_) , elem_(a.elem_, share)
50{
51}
52
53//! resize the matrix with a new number of rows
54inline void ReSizeRow(sa_size_t rowSize)
55{
56 long_diag_=(uint_4)rowSize;
57 elem_.ReSize(long_diag_*(long_diag_+1)/2);
58}
59
60TriangularMatrix<T>& SetT(T a)
61 {
62 if (long_diag_ < 1)
63 throw RangeCheckError("TriangularMatrix<T>::SetT(T ) - TriangularMatrix not dimensionned ! ");
64 elem_ = a;
65 return (*this);
66 }
67
68//! () operator : access to elements row \b l and column \b m
69inline T& operator()(sa_size_t l, sa_size_t m)
70 {
71 return elem_(indexOfElement(l,m));
72 }
73
74inline T& operator()(sa_size_t index)
75 {
76 return elem_(index);
77 }
78
79
80//! () operator : access to elements row \b l and column \b m
81inline T const& operator()(sa_size_t l, sa_size_t m) const
82 {
83 return *(elem_.Begin()+ indexOfElement(l,m));
84 }
85
86inline T const& operator()(sa_size_t index) const
87 {
88 return *(elem_.Begin()+ index);
89 }
90
91TriangularMatrix<T>& Set(const TriangularMatrix<T>& a)
92 {
93 if (this != &a)
94 {
95 if (a.Size() < 1)
96 throw RangeCheckError(" TriangularMatrix<T>::Set()- Array a not allocated ! ");
97 }
98 if (Size() < 1) CloneOrShare(a);
99 else CopyElt(a);
100 return(*this);
101 }
102
103inline TriangularMatrix<T>& operator = (const TriangularMatrix<T>& a)
104 {return Set(a);}
105
106TriangularMatrix<T>& CopyElt(const TriangularMatrix<T>& a)
107 {
108 if (Size() < 1)
109 throw RangeCheckError("TriangularMatrix<T>::CopyElt(const TriangularMatrix<T>& ) - Not Allocated Array ! ");
110 if (Size() != a.Size() )
111 throw(SzMismatchError("TriangularMatrix<T>::CopyElt(const TriangularMatrix<T>&) SizeMismatch")) ;
112 long_diag_ = a.long_diag_;
113 sa_size_t k;
114 for (k=0; k< Size(); k++) elem_(k) = a.elem_(k);
115 return(*this);
116 }
117
118void CloneOrShare(const TriangularMatrix<T>& a)
119 {
120 long_diag_ = a.long_diag_;
121 elem_.CloneOrShare(a.elem_);
122 }
123
124
125//! Return number of rows
126inline sa_size_t rowNumber() const {return (int_4)long_diag_;}
127
128//! Return size of the total array
129 inline sa_size_t Size() const {return elem_.Size();}
130
131 inline bool CheckRelativeIndices(sa_size_t l, sa_size_t m) const
132 {
133 if ( l < m )
134 {
135 throw RangeCheckError("TriangularMatrix<T>::CheckRelativeIndices: indices out of range " );
136 }
137 return true;
138 }
139 inline bool CheckAbsoluteIndice(sa_size_t l, sa_size_t m) const
140 {
141 if ( indexOfElement(l,m) >= elem_.Size() )
142 {
143 throw RangeCheckError("TriangularMatrix<T>::CheckAbsoluteIndice: indices out of range " );
144 }
145 }
146 inline bool CheckAbsoluteIndice(sa_size_t ind) const
147 {
148 if ( ind >= elem_.Size() )
149 {
150 throw RangeCheckError("TriangularMatrix<T>::CheckAbsoluteIndice: indices out of range " );
151 }
152 }
153
154 //! ASCII dump of the matrix (set nbLignes=-1) for dumping the complete matrix
155void Print(ostream& os, sa_size_t nbLignes=0) const
156 {
157 os << "TriangularMatrix< " << typeid(T).name()
158 << " > NRow=" << long_diag_ << " NbElem<>0 : " << Size() << endl;
159 if (nbLignes == 0) return;
160 if (nbLignes < 0 ) nbLignes = long_diag_;
161 if (nbLignes > long_diag_ ) nbLignes = long_diag_;
162 for (sa_size_t k=0; k < nbLignes; k++) {
163 os << "L[" << k << "]: " ;
164 for (sa_size_t kc = 0; kc <= k ; kc++)
165 os << " " << elem_(indexOfElement(k,kc));
166 os << endl;
167 }
168 if (nbLignes < long_diag_) os << " ... ... ... " << endl;
169 return;
170 }
171
172inline void Print(sa_size_t nbLignes=0) const { Print(cout, nbLignes); }
173
174
175//! Return the pointer to the first non zero element in column \b j = &(tmmtx(j,j))
176inline const T* columnData(sa_size_t j) const {return elem_.Begin()+(long_diag_*j-j*(j-1)/2) ;}
177
178//! Return the pointer to the first non zero element in column \b j = &(tmmtx(j,j))
179inline T* columnData(sa_size_t j) {return elem_.Begin()+(long_diag_*j-j*(j-1)/2) ;}
180
181//! compute the address of an element in the single array representing the matrix
182inline sa_size_t indexOfElement(sa_size_t i,sa_size_t j) const
183{
184 // return(i*(i+1)/2+j);
185 // the (inferior triangular )matrix is stored column by column
186 return(i+ long_diag_*j-j*(j+1)/2);
187}
188
189private:
190
191sa_size_t long_diag_; //!< size of the square matrix
192NDataBlock<T> elem_; //!< Data block
193
194 };
195
196template <class T>
197inline ostream& operator << (ostream& os, const TriangularMatrix<T>& a)
198 { a.Print(os, 0); return(os); }
199
200} // namespace SOPHYA
201
202#endif
Note: See TracBrowser for help on using the repository browser.