CppNoddy  0.92
Loading...
Searching...
No Matches
SparseMatrix.cpp
Go to the documentation of this file.
1/// \file SparseMatrix.cpp
2/// Implementation of a SPARSE matrix as
3/// an STL Vector of SparseVectors, inheriting from Matrix_base.
4
5#include <string>
6#include <complex>
7
8#include <SparseMatrix.h>
9#include <Exceptions.h>
10
11
12namespace CppNoddy {
13
14 template <typename _Type>
15 SparseMatrix<_Type>::SparseMatrix(const std::size_t& rows, const std::size_t& cols)
16 : m_nr(rows), m_nc(cols) {
17 m_matrix.reserve(m_nr);
18 SparseVector<_Type> sparse_row(m_nc);
19 for(std::size_t i = 0; i < m_nr; ++i) {
20 m_matrix.push_back(sparse_row);
21 }
22 }
23
24 template <typename _Type>
25 SparseMatrix<_Type>::SparseMatrix(const SparseMatrix<_Type>& source, const std::vector<std::size_t>& source_rows) :
26 m_nr(source.nrows()), m_nc(source.ncols()) {
27 m_matrix.reserve(m_nr);
28 for(std::size_t i = 0; i < m_nr; ++i) {
29 m_matrix.push_back(source.get_row(source_rows[i]));
30 }
31 }
32
33 template <typename _Type>
35 *this = source;
36 }
37
38 template <typename _Type>
40 if(this == &source)
41 return * this;
42 m_matrix = source.m_matrix;
43 m_nr = source.m_nr;
44 m_nc = source.m_nc;
45 return *this;
46 }
47
48 template <typename _Type>
49 std::size_t SparseMatrix<_Type>::nelts() const {
50 std::size_t num_of_elts(0);
51 for(std::size_t row = 0; row < m_nr; ++row) {
52 num_of_elts += m_matrix[ row ].nelts();
53 }
54 return num_of_elts;
55 }
56
57 template <typename _Type>
58 std::size_t SparseMatrix<_Type>::max_in_col(const std::size_t& col,
59 const std::size_t& row_min, const std::size_t& row_max) const {
60 double maxelt(0.0);
61 // return outside of the array as default
62 std::size_t index = nrows();
63 for(std::size_t row = row_min; row < row_max ; ++row) {
64 // only bother looking up entries of rows with a first
65 // element in a column less than the one we're looking at
66 if(m_matrix[ row ].begin() -> first <= col) {
67 const double elt(std::abs(m_matrix[ row ].get(col)));
68 if(elt >= maxelt) {
69 maxelt = elt;
70 index = row;
71 }
72 }
73 }
74 return index;
75 }
76
77 template <typename _Type>
78 void SparseMatrix<_Type>::scale(const _Type& mult) {
79 for(std::size_t row = 0; row < m_nr; ++row) {
80 m_matrix[ row ] *= mult;
81 }
82 }
83
84 template <typename _Type>
86 double max(0.0);
87 for(std::size_t row = 0; row < m_nr; ++row) {
88 max = std::max(max, m_matrix[ row ].one_norm());
89 }
90 return max;
91 }
92
93 template <typename _Type>
95 double max(0.0);
96 for(std::size_t row = 0; row < m_nr; ++row) {
97 max = std::max(max, m_matrix[ row ].two_norm());
98 }
99 return max;
100 }
101
102 template <typename _Type>
104 double max(0.0);
105 for(std::size_t row = 0; row < m_nr; ++row) {
106 max = std::max(max, m_matrix[ row ].inf_norm());
107 }
108 return max;
109 }
110
111 template <typename _Type>
113 double sum(0.0);
114 for(std::size_t row = 0; row < m_nr; ++row) {
115 sum += m_matrix[ row ].two_norm();
116 }
117 return sum;
118 }
119
120
121#if defined(PETSC_Z)
122 template <>
123 void SparseMatrix<std::complex<double> >::get_row_petsc(PetscInt row,
124 PetscScalar* storage, PetscInt* cols) {
125 citer pos;
126 std::size_t i(0);
127 //
128 // matrix could be singular with an empty row for the mass matrix
129 // of a generalised eigenvalue problem
130 if(m_matrix[row].nelts() > 0) {
131 // start at the begining of this row
132 pos = m_matrix[ row ].begin();
133 do {
134 // for each non-zero elt in the row
135 PetscScalar elt;
136 elt = std::real(pos -> second) + PETSC_i * std::imag(pos -> second);
137 int col(pos -> first);
138 storage[ i ] = elt;
139 // +1 to return FORTRAN indexing
140 cols[ i ] = col;
141 ++pos;
142 ++i;
143 } while(pos != m_matrix[ row ].end());
144 }
145 }
146#endif
147
148#if defined(PETSC_D)
149 template <>
150 void SparseMatrix<std::complex<double> >::get_row_petsc(PetscInt row, PetscScalar* storage, PetscInt* cols) {
151 std::string problem;
152 problem = "The SparseMatrix::get_row_petsc method was called for a SparseMatrix<D_complex>\n";
153 problem += "even though PETSC_ARCH is currently pointing to a double version of the library.\n";
154 throw ExceptionExternal(problem);
155 }
156#endif
157
158
159#if defined(PETSC_D)
160 template <>
161 void SparseMatrix<double >::get_row_petsc(PetscInt row, PetscScalar* storage, PetscInt* cols) {
162 citer pos;
163 std::size_t i(0);
164 //
165 // matrix could be singular with an empty row for the mass matrix
166 // of a generalised eigenvalue problem
167 if(m_matrix[row].nelts() > 0) {
168 // start at the begining of this row
169 pos = m_matrix[ row ].begin();
170 do {
171 // for each non-zero elt in the row
172 PetscScalar elt;
173 elt = pos -> second;
174 int col(pos -> first);
175 storage[ i ] = elt;
176 // +1 to return FORTRAN indexing
177 cols[ i ] = col;
178 ++pos;
179 ++i;
180 } while(pos != m_matrix[ row ].end());
181 }
182 }
183#endif
184
185#if defined(PETSC_Z)
186 template <>
187 void SparseMatrix<double >::get_row_petsc(PetscInt row, PetscScalar* storage, PetscInt* cols) {
188 std::string problem;
189 problem = "The SparseMatrix::get_row_petsc method was called for a SparseMatrix<double>\n";
190 problem += "even though PETSC_ARCH is currently pointing to a complex version of the library.\n";
191 throw ExceptionExternal(problem);
192 }
193#endif
194
195
196 template <typename _Type>
198 std::cout << "SPARSE mtx size = " << m_nr << " x sparse \n";
199 std::cout << "- start matrix \n";
200 for(std::size_t row = 0; row < m_nr; ++row) {
201 std::cout << " row " << row << " : ";
202 m_matrix[ row ].dump();
203 std::cout << " \n";
204 }
205 std::cout << "- end matrix \n";
206 }
207
208 // the versions to be used are:
209 template class SparseMatrix<double>
210 ;
211 template class SparseMatrix<std::complex<double> >
212 ;
213
214} // end namespace
The collection of CppNoddy exceptions.
A matrix class that constructs a SPARSE matrix as an STL Vector of SparseVectors, inheriting from Mat...
A matrix class that constructs a SPARSE matrix as a row major std::vector of SparseVectors.
Definition: SparseMatrix.h:31
void dump() const
Output the contents of the matrix to std::cout.
SparseMatrix & operator=(const SparseMatrix &source)
Assignment operator.
void scale(const _Type &mult)
Scale the matrix by a scalar.
double inf_norm() const
double one_norm() const
Transpose the matrix in place.
double two_norm() const
std::size_t nelts() const
Get the number of (non-zero) elements in the matrix.
SparseMatrix(const std::size_t &rows, const std::size_t &cols)
Construct with a set number of rows.
double frob_norm() const
std::size_t max_in_col(const std::size_t &col, const std::size_t &row_min, const std::size_t &row_max) const
Find the maximum entry in a column – used in the native solver.
An SparseVector class – a sparse vector object.
Definition: SparseVector.h:20
A collection of OO numerical routines aimed at simple (typical) applied problems in continuum mechani...

© 2012

R.E. Hewitt