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