Nektar++
SparseMatrix.cpp
Go to the documentation of this file.
1///////////////////////////////////////////////////////////////////////////////
2//
3// File: SparseMatrix.cpp
4//
5// For more information, please see: http://www.nektar.info
6//
7// The MIT License
8//
9// Copyright (c) 2006 Division of Applied Mathematics, Brown University (USA),
10// Department of Aeronautics, Imperial College London (UK), and Scientific
11// Computing and Imaging Institute, University of Utah (USA).
12//
13// Permission is hereby granted, free of charge, to any person obtaining a
14// copy of this software and associated documentation files (the "Software"),
15// to deal in the Software without restriction, including without limitation
16// the rights to use, copy, modify, merge, publish, distribute, sublicense,
17// and/or sell copies of the Software, and to permit persons to whom the
18// Software is furnished to do so, subject to the following conditions:
19//
20// The above copyright notice and this permission notice shall be included
21// in all copies or substantial portions of the Software.
22//
23// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
24// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
25// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
26// THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
27// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
28// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
29// DEALINGS IN THE SOFTWARE.
30//
31// Description: Generic sparse matrix class templated by underlying sparse
32// storage format
33//
34///////////////////////////////////////////////////////////////////////////////
35
36#include <algorithm>
37#include <fstream>
38#include <map>
39#include <utility>
40#include <vector>
41
46
47using std::max;
48using std::min;
49
50namespace Nektar
51{
52
53template <typename SparseStorageType>
55 const SparseStorageSharedPtr &sparseStoragePtr)
56 : m_mulCallsCounter(0), m_sparseStorage(sparseStoragePtr)
57{
58}
59
60template <typename SparseStorageType>
62 : m_mulCallsCounter(src.m_mulCallsCounter),
63 m_sparseStorage(src.m_sparseStorage)
64{
65}
66
67template <typename SparseStorageType>
69{
70}
71
72template <typename SparseStorageType>
74{
75 return m_sparseStorage->GetRows();
76}
77
78template <typename SparseStorageType>
80{
81 return m_sparseStorage->GetColumns();
82}
83
84template <typename SparseStorageType>
86{
87 return m_sparseStorage->GetNumNonZeroEntries();
88}
89
90template <typename SparseStorageType>
92 SparseStorageType>::GetFillInRatio() const
93{
94 return m_sparseStorage->GetFillInRatio();
95}
96
97template <typename SparseStorageType>
98typename boost::call_traits<
99 typename SparseStorageType::DataType>::const_reference
101 unsigned int column) const
102{
103 return m_sparseStorage->GetValue(row, column);
104}
105
106template <typename SparseStorageType>
107typename SparseStorageType::const_iterator NekSparseMatrix<
108 SparseStorageType>::begin() const
109{
110 return m_sparseStorage->begin();
111}
112
113template <typename SparseStorageType>
114typename SparseStorageType::const_iterator NekSparseMatrix<
115 SparseStorageType>::end() const
116{
117 return m_sparseStorage->end();
118}
119
120template <typename SparseStorageType>
122 DataVectorType &out)
123{
124 m_sparseStorage->Multiply(in, out);
125 m_mulCallsCounter++;
126}
127
128template <typename SparseStorageType>
130 DataType *out)
131{
132 m_sparseStorage->Multiply(in, out);
133 m_mulCallsCounter++;
134}
135
136template <typename SparseStorageType>
138{
139 return m_sparseStorage->GetMemoryUsage() + sizeof(SparseStorageSharedPtr) +
140 sizeof(unsigned long); // mulCallsCounter
141}
142
143template <typename SparseStorageType>
145{
146 return m_mulCallsCounter;
147}
148
149template <typename SparseStorageType>
150const typename SparseStorageType::DataType NekSparseMatrix<
151 SparseStorageType>::GetAvgRowDensity() const
152{
153 return (DataType)m_sparseStorage->GetNumNonZeroEntries() /
154 (DataType)m_sparseStorage->GetRows();
155}
156
157template <typename SparseStorageType>
159{
160 int bandwidth = 0;
161
162 typename SparseStorageType::const_iterator entry = m_sparseStorage->begin();
163
164 for (; entry != m_sparseStorage->end(); ++entry)
165 {
166 bandwidth = (std::max)(
167 bandwidth,
168 2 * std::abs((int)(entry->first.first - entry->first.second + 1)));
169 }
170 return bandwidth;
171}
172
173template <typename SparseStorageType>
175{
177
178 typename SparseStorageType::const_iterator entry = m_sparseStorage->begin();
179 for (; entry != m_sparseStorage->end(); entry++)
180 {
181 (*coo)[std::make_pair(entry->first.first, entry->first.second)] =
182 entry->second;
183 }
184 return coo;
185}
186
187// Generates a matrix each element of which is a number of
188// nonzero entries to block-matrix associated with *this object.
189// E.g. for unit 6x6 matrix and block size = 2 it will generate
190// 3x3 matrix with elements 2 along the diagonal.
191//
192// The output can be visualised with Python's matplotlib's spy().
193//
194template <typename SparseStorageType>
196 std::ostream &out, IndexType blockSize)
197{
198 const int matRows = m_sparseStorage->GetRows();
199 const int gridRows = matRows / blockSize + (matRows % blockSize > 0);
200 const int gridCols = gridRows;
201
202 std::vector<std::vector<int>> grid(gridRows);
203 for (int row = 0; row < gridRows; row++)
204 {
205 grid[row].resize(gridCols, 0);
206 }
207
208 typename SparseStorageType::const_iterator entry = m_sparseStorage->begin();
209 for (; entry != m_sparseStorage->end(); entry++)
210 {
211 const IndexType row = entry->first.first;
212 const IndexType col = entry->first.second;
213 const int gridRow = row / blockSize;
214 const int gridCol = col / blockSize;
215 grid[gridRow][gridCol]++;
216 }
217
218 for (int row = 0; row < gridRows; row++)
219 {
220 for (int col = 0; col < gridCols; col++)
221 {
222 out << grid[row][col] << " ";
223 }
224 out << std::endl;
225 }
226}
227
228/// Complementary routine to the previous. It generates
229/// exact non-zero pattern of a given block matrix entry
230/// to *this object. E.g., for a 6x6 matrix defined as
231/// A(i,i):=i, A(i,j):=0, block size = 2 and
232/// blk_row=blk_col=2 it produces 2x2 matrix with 5 and 6
233/// along the diagonal.
234template <typename SparseStorageType>
236 std::ostream &out, const IndexType blk_row, const IndexType blk_col,
237 IndexType blockSize)
238{
239 blockSize = (std::min)(blockSize, m_sparseStorage->GetRows());
240 std::vector<std::vector<int>> grid(blockSize);
241 for (int row = 0; row < blockSize; row++)
242 {
243 grid[row].resize(blockSize, 0);
244 }
245
246 typename SparseStorageType::const_iterator entry = m_sparseStorage->begin();
247 for (; entry != m_sparseStorage->end(); entry++)
248 {
249 const IndexType row = entry->first.first;
250 const IndexType col = entry->first.second;
251
252 if (blk_row != row / blockSize)
253 {
254 continue;
255 }
256 if (blk_col != col / blockSize)
257 {
258 continue;
259 }
260 grid[row % blockSize][col % blockSize]++;
261 }
262
263 for (int row = 0; row < blockSize; row++)
264 {
265 for (int col = 0; col < blockSize; col++)
266 {
267 out << grid[row][col] << " ";
268 }
269 out << std::endl;
270 }
271}
272
273// explicit instantiation
275
276} // namespace Nektar
void writeBlockSparsityPatternTo(std::ostream &out, const IndexType blk_row=0, const IndexType blk_col=0, IndexType blockSize=64)
Complementary routine to the previous. It generates exact non-zero pattern of a given block matrix en...
unsigned long GetMulCallsCounter() const
NekSparseMatrix(const SparseStorageSharedPtr &sparseStoragePtr)
void Multiply(const DataVectorType &in, DataVectorType &out)
void writeSparsityPatternTo(std::ostream &out, IndexType blockSize=64)
IndexType GetRows() const
SparseStorageType::const_iterator begin() const
IndexType GetNumNonZeroEntries() const
size_t GetMemoryFootprint() const
SparseStorageType::DataType DataType
std::shared_ptr< SparseStorageType > SparseStorageSharedPtr
const DataType GetFillInRatio() const
COOMatTypeSharedPtr GetCooStorage()
SparseStorageType::const_iterator end() const
IndexType GetColumns() const
boost::call_traits< DataType >::const_reference operator()(const IndexType row, const IndexType column) const
std::shared_ptr< COOMatType > COOMatTypeSharedPtr
unsigned int IndexType
std::map< CoordType, NekDouble > COOMatType
scalarT< T > abs(scalarT< T > in)
Definition: scalar.hpp:298