Nektar++
MatrixFuncs.cpp
Go to the documentation of this file.
1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // File: MatrixFuncs.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: Matrix functions that depend on storage policy. Putting
32 // methods in these separate classes makes it easier to use them from
33 // normal, scaled, and block matrices.
34 //
35 ///////////////////////////////////////////////////////////////////////////////
36 
37 #include <boost/core/ignore_unused.hpp>
38 
40 
41 namespace Nektar
42 {
43 
44  unsigned int BandedMatrixFuncs::GetRequiredStorageSize(unsigned int totalRows, unsigned int totalColumns,
45  unsigned int subDiags, unsigned int superDiags)
46  {
47  return CalculateNumberOfRows(totalRows, subDiags, superDiags)*totalColumns;
48  }
49 
50  unsigned int BandedMatrixFuncs::CalculateNumberOfDiags(unsigned int totalRows, unsigned int diags)
51  {
52  if( diags != std::numeric_limits<unsigned int>::max() )
53  {
54  return diags;
55  }
56  else if( totalRows > 0 )
57  {
58  return totalRows-1;
59  }
60  else
61  {
62  return 0;
63  }
64  }
65 
66  unsigned int BandedMatrixFuncs::CalculateNumberOfRows(unsigned int totalRows, unsigned int subDiags, unsigned int superDiags)
67  {
68  return CalculateNumberOfDiags(totalRows, subDiags) + CalculateNumberOfDiags(totalRows, superDiags) + 1;
69  }
70 
71  unsigned int BandedMatrixFuncs::CalculateIndex(unsigned int totalRows,
72  unsigned int totalColumns,
73  unsigned int row, unsigned int column,
74  unsigned int sub, unsigned int super)
75  {
76  boost::ignore_unused(totalColumns);
77  if( (column <= row && (row - column) <= CalculateNumberOfDiags(totalRows, sub)) ||
78  (column > row && (column - row) <= CalculateNumberOfDiags(totalRows, super)) )
79  {
80  unsigned int elementRow = CalculateNumberOfDiags(totalRows, super)+row-column;
81  unsigned int elementColumn = column;
82 
83  return elementRow + elementColumn*CalculateNumberOfRows(totalRows, sub, super);
84  }
85  else
86  {
87  return std::numeric_limits<unsigned int>::max();
88  }
89  }
90 
91 
92  std::tuple<unsigned int, unsigned int>
93  BandedMatrixFuncs::Advance(const unsigned int totalRows, const unsigned int totalColumns,
94  const unsigned int curRow, const unsigned int curColumn)
95  {
96  boost::ignore_unused(totalRows, totalColumns);
97  unsigned int nextRow = curRow;
98  unsigned int nextColumn = curColumn;
99 
100  return std::tuple<unsigned int, unsigned int>(nextRow, nextColumn);
101  }
102 
103 
104  unsigned int FullMatrixFuncs::GetRequiredStorageSize(unsigned int rows, unsigned int columns)
105  {
106  return rows*columns;
107  }
108 
109  unsigned int FullMatrixFuncs::CalculateIndex(unsigned int totalRows, unsigned int totalColumns, unsigned int curRow, unsigned int curColumn)
110  {
111  boost::ignore_unused(totalColumns);
112  return curColumn*totalRows + curRow;
113  }
114 
115 
116  std::tuple<unsigned int, unsigned int>
117  FullMatrixFuncs::Advance(const unsigned int totalRows, const unsigned int totalColumns,
118  const unsigned int curRow, const unsigned int curColumn)
119  {
120  unsigned int nextRow = curRow;
121  unsigned int nextColumn = curColumn;
122 
123  if( nextRow < totalRows )
124  {
125  ++nextRow;
126  }
127 
128  if( nextRow >= totalRows )
129  {
130  nextRow = 0;
131  ++nextColumn;
132  }
133 
134  if( nextColumn >= totalColumns )
135  {
136  nextRow = std::numeric_limits<unsigned int>::max();
137  nextColumn = std::numeric_limits<unsigned int>::max();
138  }
139 
140  return std::tuple<unsigned int, unsigned int>(nextRow, nextColumn);
141  }
142 
143 
144  unsigned int TriangularMatrixFuncs::GetRequiredStorageSize(unsigned int rows, unsigned int columns)
145  {
146  ASSERTL0(rows==columns, "Triangular matrices must be square.");
147  return rows*(rows+1)/2;
148  }
149 
150  unsigned int UpperTriangularMatrixFuncs::CalculateIndex(unsigned int curRow, unsigned int curColumn)
151  {
152  if( curRow <= curColumn )
153  {
154  return curRow + curColumn*(curColumn+1)/2;
155  }
156  else
157  {
158  return std::numeric_limits<unsigned int>::max();
159  }
160  }
161 
162  std::tuple<unsigned int, unsigned int>
163  UpperTriangularMatrixFuncs::Advance(const unsigned int totalRows, const unsigned int totalColumns,
164  const unsigned int curRow, const unsigned int curColumn)
165  {
166  boost::ignore_unused(totalRows);
167 
168  ASSERTL1(totalRows == totalColumns, "Triangular matrices must be square.");
169  ASSERTL1(curRow < totalRows, "Attemping to iterate through an element on row " +
170  std::to_string(curRow) + " of a (" +
171  std::to_string(totalRows) + ", " +
172  std::to_string(totalColumns) + " upper triangular matrix.");
173  ASSERTL1(curColumn < totalColumns, "Attemping to iterate through an element on row " +
174  std::to_string(curColumn) + " of a (" +
175  std::to_string(totalRows) + ", " +
176  std::to_string(totalColumns) + " upper triangular matrix.");
177  ASSERTL1(curRow <= curColumn, "Attemping to iterate through element (" +
178  std::to_string(curRow) + ", " +
179  std::to_string(curColumn) + ") of a (" +
180  std::to_string(totalRows) + ", " +
181  std::to_string(totalColumns) + " upper triangular matrix.");
182 
183  unsigned int nextRow = curRow;
184  unsigned int nextColumn = curColumn;
185 
186  if( nextRow <= nextColumn )
187  {
188  ++nextRow;
189  }
190 
191  if( nextRow > nextColumn )
192  {
193  ++nextColumn;
194  nextRow = 0;
195  }
196 
197  if( nextColumn >= totalColumns )
198  {
199  nextRow = std::numeric_limits<unsigned int>::max();
200  nextColumn = std::numeric_limits<unsigned int>::max();
201  }
202 
203  return std::tuple<unsigned int, unsigned int>(nextRow, nextColumn);
204  }
205 
206 
207  unsigned int LowerTriangularMatrixFuncs::CalculateIndex(unsigned int totalColumns, unsigned int curRow, unsigned int curColumn)
208  {
209  if( curRow >= curColumn )
210  {
211  return curRow + (2*totalColumns - curColumn - 1)*(curColumn)/2;
212  }
213  else
214  {
215  return std::numeric_limits<unsigned int>::max();
216  }
217  }
218 
219  std::tuple<unsigned int, unsigned int>
220  LowerTriangularMatrixFuncs::Advance(const unsigned int totalRows, const unsigned int totalColumns,
221  const unsigned int curRow, const unsigned int curColumn,
222  char transpose)
223  {
224  ASSERTL1(totalRows == totalColumns, "Triangular matrices must be square.");
225  ASSERTL1(curRow < totalRows, "Attemping to iterate through an element on row " +
226  std::to_string(curRow) + " of a (" +
227  std::to_string(totalRows) + ", " +
228  std::to_string(totalColumns) + " lower triangular matrix.");
229  ASSERTL1(curColumn < totalColumns, "Attemping to iterate through an element on row " +
230  std::to_string(curColumn) + " of a (" +
231  std::to_string(totalRows) + ", " +
232  std::to_string(totalColumns) + " lower triangular matrix.");
233  ASSERTL1(curRow >= curColumn, "Attemping to iterate through element (" +
234  std::to_string(curRow) + ", " +
235  std::to_string(curColumn) + ") of a (" +
236  std::to_string(totalRows) + ", " +
237  std::to_string(totalColumns) + " lower triangular matrix.");
238 
239  if( transpose == 'T' )
240  {
242  totalColumns, totalRows, curColumn, curRow);
243  }
244 
245  unsigned int nextRow = curRow;
246  unsigned int nextColumn = curColumn;
247 
248  if( nextRow < totalRows )
249  {
250  ++nextRow;
251  }
252 
253  if( nextRow >= totalRows )
254  {
255  ++nextColumn;
256  nextRow = nextColumn;
257  }
258 
259  if( nextColumn >= totalColumns )
260  {
261  nextRow = std::numeric_limits<unsigned int>::max();
262  nextColumn = std::numeric_limits<unsigned int>::max();
263  }
264 
265  return std::tuple<unsigned int, unsigned int>(nextRow, nextColumn);
266  }
267 
268 
269  unsigned int SymmetricMatrixFuncs::CalculateIndex(unsigned int curRow, unsigned int curColumn)
270  {
271  if( curRow <= curColumn )
272  {
273  return curRow + curColumn*(curColumn+1)/2;
274  }
275  else
276  {
277  return curColumn + curRow*(curRow + 1)/2;
278  }
279  }
280 
281  std::tuple<unsigned int, unsigned int>
282  SymmetricMatrixFuncs::Advance(const unsigned int totalRows, const unsigned int totalColumns,
283  const unsigned int curRow, const unsigned int curColumn)
284  {
285  ASSERTL1(totalRows == totalColumns, "Symmetric matrices must be square.");
286  ASSERTL1(curRow < totalRows, "Attemping to iterate through an element on row " +
287  std::to_string(curRow) + " of a (" +
288  std::to_string(totalRows) + ", " +
289  std::to_string(totalColumns) + " symmetric matrix.");
290  ASSERTL1(curColumn < totalColumns, "Attemping to iterate through an element on row " +
291  std::to_string(curColumn) + " of a (" +
292  std::to_string(totalRows) + ", " +
293  std::to_string(totalColumns) + " symmetric matrix.");
294 
295  unsigned int nextRow = curRow;
296  unsigned int nextColumn = curColumn;
297 
298  if( nextRow < totalRows )
299  {
300  ++nextRow;
301  }
302 
303  if( nextRow >= totalRows )
304  {
305  nextRow = 0;
306  ++nextColumn;
307  }
308 
309  if( nextColumn >= totalColumns )
310  {
311  nextRow = std::numeric_limits<unsigned int>::max();
312  nextColumn = std::numeric_limits<unsigned int>::max();
313  }
314 
315  return std::tuple<unsigned int, unsigned int>(nextRow, nextColumn);
316  }
317 
318  std::tuple<unsigned int, unsigned int>
319  DiagonalMatrixFuncs::Advance(const unsigned int totalRows, const unsigned int totalColumns,
320  const unsigned int curRow, const unsigned int curColumn)
321  {
322  boost::ignore_unused(totalColumns);
323 
324  ASSERTL0(curRow == curColumn, "Iteration of a diagonal matrix is only valid along the diagonal.");
325 
326  unsigned int nextRow = curRow;
327  unsigned int nextColumn = curColumn;
328 
329  if( nextRow < totalRows )
330  {
331  ++nextRow;
332  ++nextColumn;
333  }
334 
335  if( nextRow >= totalRows )
336  {
337  nextRow = std::numeric_limits<unsigned int>::max();
338  nextColumn = std::numeric_limits<unsigned int>::max();
339  }
340 
341  return std::tuple<unsigned int, unsigned int>(nextRow, nextColumn);
342  }
343 
344  unsigned int DiagonalMatrixFuncs::GetRequiredStorageSize(unsigned int rows, unsigned int columns)
345  {
346  ASSERTL0(rows==columns, "Diagonal matrices must be square.");
347  return rows;
348  }
349 
350  unsigned int DiagonalMatrixFuncs::CalculateIndex(unsigned int row, unsigned int col)
351  {
352  if( row == col )
353  {
354  return row;
355  }
356  else
357  {
358  return std::numeric_limits<unsigned int>::max();
359  }
360  }
361 
362  unsigned int TriangularBandedMatrixFuncs::GetRequiredStorageSize(unsigned int rows, unsigned int columns,
363  unsigned int nSubSuperDiags)
364  {
365  ASSERTL0(rows==columns, "Triangular matrices must be square.");
366  return (nSubSuperDiags+1)*columns;
367  }
368 
369  unsigned int SymmetricBandedMatrixFuncs::CalculateIndex(unsigned int curRow, unsigned int curColumn,
370  unsigned int nSuperDiags)
371  {
372  if( curRow <= curColumn )
373  {
374  if( (curColumn - curRow) <= nSuperDiags )
375  {
376  unsigned int elementRow = nSuperDiags - (curColumn - curRow);
377  unsigned int elementColumn = curColumn;
378 
379  return elementRow + elementColumn*(nSuperDiags+1);
380  }
381  else
382  {
383  return std::numeric_limits<unsigned int>::max();
384  }
385  }
386  else
387  {
388  return CalculateIndex(curColumn,curRow,nSuperDiags);
389  }
390 
391  }
392 }
393 
#define ASSERTL0(condition, msg)
Definition: ErrorUtil.hpp:216
#define ASSERTL1(condition, msg)
Assert Level 1 – Debugging which is used whether in FULLDEBUG or DEBUG compilation mode....
Definition: ErrorUtil.hpp:250
The above copyright notice and this permission notice shall be included.
Definition: CoupledSolver.h:1
static unsigned int CalculateNumberOfRows(unsigned int totalRows, unsigned int subDiags, unsigned int superDiags)
Definition: MatrixFuncs.cpp:66
static unsigned int CalculateIndex(unsigned int totalRows, unsigned int totalColumns, unsigned int row, unsigned int column, unsigned int sub, unsigned int super)
Definition: MatrixFuncs.cpp:71
static unsigned int CalculateNumberOfDiags(unsigned int totalRows, unsigned int diags)
Definition: MatrixFuncs.cpp:50
static unsigned int GetRequiredStorageSize(unsigned int totalRows, unsigned int totalColumns, unsigned int subDiags, unsigned int superDiags)
Calculates and returns the storage size required.
Definition: MatrixFuncs.cpp:44
static std::tuple< unsigned int, unsigned int > Advance(const unsigned int totalRows, const unsigned int totalColumns, const unsigned int curRow, const unsigned int curColumn)
Definition: MatrixFuncs.cpp:93
static std::tuple< unsigned int, unsigned int > Advance(const unsigned int totalRows, const unsigned int totalColumns, const unsigned int curRow, const unsigned int curColumn)
static unsigned int GetRequiredStorageSize(unsigned int rows, unsigned int columns)
static unsigned int CalculateIndex(unsigned int row, unsigned int col)
static unsigned int GetRequiredStorageSize(unsigned int rows, unsigned int columns)
static std::tuple< unsigned int, unsigned int > Advance(const unsigned int totalRows, const unsigned int totalColumns, const unsigned int curRow, const unsigned int curColumn)
static unsigned int CalculateIndex(unsigned int totalRows, unsigned int totalColumns, unsigned int curRow, unsigned int curColumn)
static std::tuple< unsigned int, unsigned int > Advance(const unsigned int totalRows, const unsigned int totalColumns, const unsigned int curRow, const unsigned int curColumn, char transpose='N')
static unsigned int CalculateIndex(unsigned int totalColumns, unsigned int curRow, unsigned int curColumn)
static unsigned int CalculateIndex(unsigned int curRow, unsigned int curColumn, unsigned int nSuperDiags)
static std::tuple< unsigned int, unsigned int > Advance(const unsigned int totalRows, const unsigned int totalColumns, const unsigned int curRow, const unsigned int curColumn)
static unsigned int CalculateIndex(unsigned int curRow, unsigned int curColumn)
static unsigned int GetRequiredStorageSize(unsigned int rows, unsigned int columns, unsigned int nSubSuperDiags)
static unsigned int GetRequiredStorageSize(unsigned int rows, unsigned int columns)
static std::tuple< unsigned int, unsigned int > Advance(const unsigned int totalRows, const unsigned int totalColumns, const unsigned int curRow, const unsigned int curColumn)
static unsigned int CalculateIndex(unsigned int curRow, unsigned int curColumn)