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