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