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 
47 
48 using std::max;
49 using std::min;
50 
51 namespace Nektar
52 {
53 
54 template <typename SparseStorageType>
56  const SparseStorageSharedPtr &sparseStoragePtr)
57  : m_mulCallsCounter(0), m_sparseStorage(sparseStoragePtr)
58 {
59 }
60 
61 template <typename SparseStorageType>
63  : m_mulCallsCounter(src.m_mulCallsCounter),
64  m_sparseStorage(src.m_sparseStorage)
65 {
66 }
67 
68 template <typename SparseStorageType>
70 {
71 }
72 
73 template <typename SparseStorageType>
75 {
76  return m_sparseStorage->GetRows();
77 }
78 
79 template <typename SparseStorageType>
81 {
82  return m_sparseStorage->GetColumns();
83 }
84 
85 template <typename SparseStorageType>
87 {
88  return m_sparseStorage->GetNumNonZeroEntries();
89 }
90 
91 template <typename SparseStorageType>
93  SparseStorageType>::GetFillInRatio() const
94 {
95  return m_sparseStorage->GetFillInRatio();
96 }
97 
98 template <typename SparseStorageType>
99 typename boost::call_traits<
100  typename SparseStorageType::DataType>::const_reference
102  unsigned int column) const
103 {
104  return m_sparseStorage->GetValue(row, column);
105 }
106 
107 template <typename SparseStorageType>
108 typename SparseStorageType::const_iterator NekSparseMatrix<
109  SparseStorageType>::begin() const
110 {
111  return m_sparseStorage->begin();
112 }
113 
114 template <typename SparseStorageType>
115 typename SparseStorageType::const_iterator NekSparseMatrix<
116  SparseStorageType>::end() const
117 {
118  return m_sparseStorage->end();
119 }
120 
121 template <typename SparseStorageType>
123  DataVectorType &out)
124 {
125  m_sparseStorage->Multiply(in, out);
126  m_mulCallsCounter++;
127 }
128 
129 template <typename SparseStorageType>
131  DataType *out)
132 {
133  m_sparseStorage->Multiply(in, out);
134  m_mulCallsCounter++;
135 }
136 
137 template <typename SparseStorageType>
139 {
140  return m_sparseStorage->GetMemoryUsage() + sizeof(SparseStorageSharedPtr) +
141  sizeof(unsigned long); // mulCallsCounter
142 }
143 
144 template <typename SparseStorageType>
146 {
147  return m_mulCallsCounter;
148 }
149 
150 template <typename SparseStorageType>
151 const typename SparseStorageType::DataType NekSparseMatrix<
152  SparseStorageType>::GetAvgRowDensity() const
153 {
154  return (DataType)m_sparseStorage->GetNumNonZeroEntries() /
155  (DataType)m_sparseStorage->GetRows();
156 }
157 
158 template <typename SparseStorageType>
160 {
161  int bandwidth = 0;
162 
163  typename SparseStorageType::const_iterator entry = m_sparseStorage->begin();
164 
165  for (; entry != m_sparseStorage->end(); ++entry)
166  {
167  bandwidth = (std::max)(
168  bandwidth,
169  2 * std::abs((int)(entry->first.first - entry->first.second + 1)));
170  }
171  return bandwidth;
172 }
173 
174 template <typename SparseStorageType>
176 {
177  COOMatTypeSharedPtr coo(new COOMatType());
178 
179  typename SparseStorageType::const_iterator entry = m_sparseStorage->begin();
180  for (; entry != m_sparseStorage->end(); entry++)
181  {
182  (*coo)[std::make_pair(entry->first.first, entry->first.second)] =
183  entry->second;
184  }
185  return coo;
186 }
187 
188 // Generates a matrix each element of which is a number of
189 // nonzero entries to block-matrix associated with *this object.
190 // E.g. for unit 6x6 matrix and block size = 2 it will generate
191 // 3x3 matrix with elements 2 along the diagonal.
192 //
193 // The output can be visualised with Python's matplotlib's spy().
194 //
195 template <typename SparseStorageType>
197  std::ostream &out, IndexType blockSize)
198 {
199  const int matRows = m_sparseStorage->GetRows();
200  const int gridRows = matRows / blockSize + (matRows % blockSize > 0);
201  const int gridCols = gridRows;
202 
203  std::vector<std::vector<int>> grid(gridRows);
204  for (int row = 0; row < gridRows; row++)
205  {
206  grid[row].resize(gridCols, 0);
207  }
208 
209  typename SparseStorageType::const_iterator entry = m_sparseStorage->begin();
210  for (; entry != m_sparseStorage->end(); entry++)
211  {
212  const IndexType row = entry->first.first;
213  const IndexType col = entry->first.second;
214  const int gridRow = row / blockSize;
215  const int gridCol = col / blockSize;
216  grid[gridRow][gridCol]++;
217  }
218 
219  for (int row = 0; row < gridRows; row++)
220  {
221  for (int col = 0; col < gridCols; col++)
222  {
223  out << grid[row][col] << " ";
224  }
225  out << std::endl;
226  }
227 }
228 
229 /// Complementary routine to the previous. It generates
230 /// exact non-zero pattern of a given block matrix entry
231 /// to *this object. E.g., for a 6x6 matrix defined as
232 /// A(i,i):=i, A(i,j):=0, block size = 2 and
233 /// blk_row=blk_col=2 it produces 2x2 matrix with 5 and 6
234 /// along the diagonal.
235 template <typename SparseStorageType>
237  std::ostream &out, const IndexType blk_row, const IndexType blk_col,
238  IndexType blockSize)
239 {
240  blockSize = (std::min)(blockSize, m_sparseStorage->GetRows());
241  std::vector<std::vector<int>> grid(blockSize);
242  for (int row = 0; row < blockSize; row++)
243  {
244  grid[row].resize(blockSize, 0);
245  }
246 
247  typename SparseStorageType::const_iterator entry = m_sparseStorage->begin();
248  for (; entry != m_sparseStorage->end(); entry++)
249  {
250  const IndexType row = entry->first.first;
251  const IndexType col = entry->first.second;
252 
253  if (blk_row != row / blockSize)
254  continue;
255  if (blk_col != col / blockSize)
256  continue;
257  grid[row % blockSize][col % blockSize]++;
258  }
259 
260  for (int row = 0; row < blockSize; row++)
261  {
262  for (int col = 0; col < blockSize; col++)
263  {
264  out << grid[row][col] << " ";
265  }
266  out << std::endl;
267  }
268 }
269 
270 // explicit instantiation
272 
273 } // 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...
boost::call_traits< DataType >::const_reference operator()(const IndexType row, const IndexType column) const
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
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:2
std::shared_ptr< COOMatType > COOMatTypeSharedPtr
unsigned int IndexType
std::map< CoordType, NekDouble > COOMatType
scalarT< T > abs(scalarT< T > in)
Definition: scalar.hpp:298