CppNoddy  0.92
Loading...
Searching...
No Matches
DenseMatrix.cpp
Go to the documentation of this file.
1/// \file DenseMatrix.cpp
2/// Implementation of a DENSE matrix as
3/// an Vector of DenseVector.
4
5#include <complex>
6#include <algorithm>
7
8#include <DenseVector.h>
9#include <DenseMatrix.h>
10#include <Exceptions.h>
11#include <Functors.h>
12#include <Utility.h>
13
14namespace CppNoddy {
15
16 template <typename _Type>
18 {}
19
20 template <typename _Type>
21 DenseMatrix<_Type>::DenseMatrix(const std::size_t& rows,
22 const std::size_t& cols,
23 const _Type& fill) :
25 m_nr(rows),
26 m_nc(cols) {
27 // make a row
28 const DenseVector<_Type> row(cols, fill);
29 // reserve the space
30 m_matrix.reserve(rows);
31 for(std::size_t i = 0; i < rows; ++i) {
32 // push require number of rows into the 'matrix'
33 m_matrix.push_back(row);
34 }
35 }
36
37 template <typename _Type>
38 DenseMatrix<_Type>::DenseMatrix(const std::size_t& rows,
39 const std::size_t& cols,
40 const _Type* p) :
42 m_nr(rows),
43 m_nc(cols) {
44 m_matrix.reserve(rows);
45 for(std::size_t i = 0; i < rows; ++i) {
46 m_matrix.push_back(DenseVector<_Type>(cols, &p[ i * cols ]));
47 }
48 }
49
50 template <typename _Type>
52 Sequential_Matrix_base<_Type>() {
53 *this = source;
54 }
55
56 template <typename _Type>
58 {}
59
60 template <typename _Type>
62 if(this == &source)
63 return * this;
64 m_matrix = source.m_matrix;
65 m_nr = source.m_nr;
66 m_nc = source.m_nc;
67 return *this;
68 }
69
70 template <typename _Type>
71 std::size_t DenseMatrix<_Type>::nelts() const {
72 return m_nr * m_nc;
73 }
74
75 template <typename _Type>
77#ifdef PARANOID
78 // check number of columns at least match
79 if((B.nrows() != m_nr) || (B.ncols() != m_nc)) {
80 std::string problem("The DenseMatrix.add has a geometry error.\n");
81 throw ExceptionGeom(problem, m_nr, m_nc, B.nrows(), B.ncols());
82 }
83#endif
84 std::transform(m_matrix.begin(), m_matrix.end(), B.m_matrix.begin(), m_matrix.begin(), std::plus< DenseVector<_Type> >());
85 }
86
87 template <typename _Type>
89#ifdef PARANOID
90 // check number of columns at least match
91 if((B.nrows() != m_nr) || (B.ncols() != m_nc)) {
92 std::string problem("The DenseMatrix.sub has a geometry error.\n");
93 throw ExceptionGeom(problem, m_nr, m_nc, B.nrows(), B.ncols());
94 }
95#endif
96 std::transform(m_matrix.begin(), m_matrix.end(), B.m_matrix.begin(), m_matrix.begin(), std::minus< DenseVector<_Type> >());
97 }
98
99 template <typename _Type>
100 void DenseMatrix<_Type>::scale(const _Type& mult) {
101 std::transform(m_matrix.begin(), m_matrix.end(), m_matrix.begin(), scale_functor< DenseVector<_Type>, _Type >(mult));
102 }
103
104 template <typename _Type>
106 if(nrows() == ncols()) {
107 // square matrix needs no temp object
108 // loop through upper half diagonal of the matrix
109 for(std::size_t i = 0; i < nrows(); ++i) {
110 for(std::size_t j = i + 1; j < ncols(); ++j) {
111 // swap elements
112 std::swap(m_matrix[ i ][ j ], m_matrix[ j ][ i ]);
113 }
114 }
115 } else {
116 std::vector< DenseVector<_Type> > temp;
117 temp.resize(m_nc);
118 for(std::size_t row = 0; row < m_nc; ++row) {
119 temp[ row ].resize(m_nr);
120 }
121 for(std::size_t i = 0; i < nrows(); ++i) {
122 for(std::size_t j = 0; j < ncols(); ++j) {
123 temp[ j ][ i ] = m_matrix[ i ][ j ];
124 }
125 }
126 m_matrix = temp;
127 std::swap(m_nr, m_nc);
128 }
129 }
131 template <typename _Type>
133#ifdef PARANOID
134 // check number of columns at least match
135 if(X.size() != m_nc) {
136 std::string problem("The DenseMatrix.multiply has a geometry error.\n");
137 throw ExceptionGeom(problem, m_nr, m_nc, X.size(), 1);
138 }
139#endif
141 temp.reserve(m_nr);
142 for(std::size_t row = 0; row < m_nr; ++row) {
143 temp.push_back(Utility::dot(m_matrix[ row ], X));
144 }
145 return temp;
147
148 template <typename _Type>
150#ifdef PARANOID
151 // check number of columns at least match
152 if(B.nrows() != m_nc) {
153 std::string problem("The DenseMatrix.multiply has a geometry error.\n");
154 throw ExceptionGeom(problem, m_nr, m_nc, B.nrows(), B.ncols());
156#endif
157 // temporary object for the result
158 DenseMatrix<_Type> C(nrows(), B.ncols(), 0.0);
159 // loops thru the columns in the B matrix
160 for(std::size_t col_in_B = 0; col_in_B < B.ncols(); ++col_in_B) {
161 // set the column in the result to be the matrix-vector
162 // product of (*this).multiply( column in B )
163 C.set_col(col_in_B, multiply(B.get_col(col_in_B)));
164 }
165 return C;
166 }
167
168
169 template <typename _Type>
170 typename std::vector<DenseVector<_Type> >::iterator
171 DenseMatrix<_Type>::max_in_col(const std::size_t& col,
172 row_iter row_min, row_iter row_max) const {
173 row_iter index(row_min);
174 double maxelt(std::abs(*(row_min -> begin())));
175 for(row_iter row = row_min + 1; row != row_max ; ++row) {
176 const double elt(std::abs(*(row -> begin() + col)));
177 if(elt >= maxelt) {
178 maxelt = elt;
179 index = row;
180 }
181 }
182 return index;
183 }
184
185 template <typename _Type>
187 double max(0.0);
188 for(std::size_t row = 0; row < m_nr; ++row) {
189 max = std::max(max, m_matrix[ row ].one_norm());
190 }
191 return max;
192 }
193
194 template <typename _Type>
196 double max(0.0);
197 for(std::size_t row = 0; row < m_nr; ++row) {
198 max = std::max(max, m_matrix[ row ].two_norm());
199 }
200 return max;
201 }
202
203 template <typename _Type>
205 double max(0.0);
206 for(std::size_t row = 0; row < m_nr; ++row) {
207 max = std::max(max, m_matrix[ row ].inf_norm());
208 }
209 return max;
210 }
211
212 template <typename _Type>
214 double sum(0.0);
215 for(std::size_t row = 0; row < m_nr; ++row) {
216 sum += m_matrix[ row ].two_norm();
217 }
218 return sum;
219 }
220
221
222 template <typename _Type>
224 std::cout << "DENSE mtx size = " << nrows() << " x " << ncols() << "; \n";
225 std::cout.precision(3);
226 std::cout << std::fixed;
227 std::cout.setf(std::ios::showpoint);
228 std::cout.setf(std::ios::showpos);
229 //std::cout.setf( std::ios::scientific );
230 std::cout << "- start matrix \n";
231 for(std::size_t i = 0; i < nrows(); ++i) {
232 std::cout << " row " << i << " = ";
233 for(std::size_t j = 0; j < ncols(); ++j) {
234 std::cout << m_matrix[ i ][ j ] << ", ";
236 std::cout << "\n";
237 }
238 std::cout << "- end matrix \n";
239 }
241 template <typename _Type>
242 void DenseMatrix<_Type>::set_col(const std::size_t& col, const DenseVector<_Type>& X) {
243 for(std::size_t row = 0; row < m_nr; ++row) {
244 m_matrix[ row ][ col ] = X[ row ];
246 }
247
248 template <typename _Type>
249 DenseVector<_Type> DenseMatrix<_Type>::get_col(const std::size_t& col) const {
250 DenseVector<_Type> X(m_nr, 0.0);
251 for(std::size_t row = 0; row < m_nr; ++row) {
252 X[ row ] = m_matrix[ row ][ col ];
253 }
254 return X;
255 }
256
257 template <>
258 void DenseMatrix<std::complex<double> >::matrix_to_vector(DenseVector<double> &p, const std::size_t &padding) const {
259 p.reserve(2 * m_nr * m_nc);
260 for(std::size_t row = 0; row < m_nr; ++row) {
261 for(std::size_t col = 0; col < m_nc; ++col) {
262 p.push_back(m_matrix[ row ][ col ].real());
263 p.push_back(m_matrix[ row ][ col ].imag());
264 }
265 for(std::size_t col = 0; col < padding; ++col) {
266 p.push_back(0.0);
267 p.push_back(0.0);
269 }
270 }
271
272
273 template <>
274 void DenseMatrix<double>::matrix_to_vector(DenseVector<double> &p, const std::size_t &padding) const {
275 p.reserve(m_nr * m_nc);
276 for(std::size_t row = 0; row < m_nr; ++row) {
277 for(std::size_t col = 0; col < m_nc; ++col) {
278 p.push_back(m_matrix[ row ][ col ]);
279 }
280 for(std::size_t col = 0; col < padding; ++col) {
281 p.push_back(0.0);
282 }
283 }
284 }
285
286 template <>
289 V.reserve(m_nr * m_nc);
290 for(std::size_t row = 0; row < m_nr; ++row) {
291 for(std::size_t col = 0; col < m_nc; ++col) {
292 V.push_back(m_matrix[ row ][ col ]);
293 }
294 for(std::size_t col = 0; col < padding; ++col) {
295 V.push_back(0.0);
296 }
297 }
298 return V;
299 }
300
301 template <>
302 DenseVector<double> DenseMatrix<std::complex<double> >::matrix_to_vector(const std::size_t &padding) const {
304 V.reserve(2 * m_nr * m_nc);
305 for(std::size_t row = 0; row < m_nr; ++row) {
306 for(std::size_t col = 0; col < m_nc; ++col) {
307 V.push_back(m_matrix[ row ][ col ].real());
308 V.push_back(m_matrix[ row ][ col ].imag());
309 }
310 for(std::size_t col = 0; col < padding; ++col) {
311 V.push_back(0.0);
312 V.push_back(0.0);
313 }
314 }
315 return V;
316 }
317
318
319 // the versions to be used are:
320 template class DenseMatrix<double>
321 ;
322 template class DenseMatrix<std::complex<double> >
323 ;
324
325} // end namespace
@ V
Definition: BVPKarman.cpp:20
A matrix class that constructs a DENSE matrix as an STL Vector of DenseVectors.
Specification for a templated DenseVector class – a dense, dynamic, vector object.
The collection of CppNoddy exceptions.
Some Function Objects that CppNoddy makes use of in algorithms applied to STL containers.
A spec for a collection of utility functions.
A matrix class that constructs a DENSE matrix as a row major std::vector of DenseVectors.
Definition: DenseMatrix.h:25
std::size_t nelts() const
Definition: DenseMatrix.cpp:71
void dump() const
Output the matrix to std::cout.
double one_norm() const
Return the maximum one_norm of all rows.
DenseMatrix & operator=(const DenseMatrix &source)
Assignment operator.
Definition: DenseMatrix.cpp:61
std::size_t nrows() const
Definition: DenseMatrix.h:375
row_iter max_in_col(const std::size_t &col, row_iter row_min, row_iter row_max) const
Find the maximum abs value in a column.
void set_col(const std::size_t &col, const DenseVector< _Type > &x)
Set a column of the matrix.
DenseVector< double > matrix_to_vector(const std::size_t &padding=0) const
Conversion to contiguous data in row major format Inefficient ... the void method is preferred.
std::vector< DenseVector< _Type > >::iterator row_iter
Typedef iterator types.
Definition: DenseMatrix.h:29
DenseVector< _Type > multiply(const DenseVector< _Type > &x) const
Right multiply the matrix by a DENSE vector.
void transpose()
Transpose the matrix.
double frob_norm() const
Return the sum of the two_norm of all rows.
DenseVector< _Type > get_col(const std::size_t &col) const
Get a column of the matrix.
void add(const DenseMatrix< _Type > &b)
Add a DENSE matrix to this object.
Definition: DenseMatrix.cpp:76
double inf_norm() const
Return the maximum inf_norm of all rows.
void scale(const _Type &mult)
Scale all matrix elements by a scalar.
void sub(const DenseMatrix< _Type > &b)
Subtract a DENSE matrix from this object.
Definition: DenseMatrix.cpp:88
DenseMatrix()
Allow empty construction.
Definition: DenseMatrix.cpp:17
double two_norm() const
Rreturn the maximum two_norm of all rows.
std::size_t ncols() const
Definition: DenseMatrix.h:380
An DenseVector class – a dense vector object.
Definition: DenseVector.h:34
void push_back(const _Type &fill)
A pass-thru definition of push_back.
Definition: DenseVector.h:310
void reserve(const std::size_t &n)
Reserve space for the vector.
Definition: DenseVector.h:340
std::size_t size() const
A pass-thru definition to get the size of the vector.
Definition: DenseVector.h:330
An exception class to be thrown when a container of incorrect geometry used in any class/method.
Definition: Exceptions.h:47
A base matrix class for sequential matrices.
A unary pure function object that scales through multiplication.
Definition: Functors.h:74
_Type dot(const DenseVector< _Type > &X, const DenseVector< _Type > &Y)
Templated dot product.
Definition: Utility.h:314
A collection of OO numerical routines aimed at simple (typical) applied problems in continuum mechani...

© 2012

R.E. Hewitt