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
41namespace 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
52unsigned 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
69unsigned 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
100std::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
111unsigned int FullMatrixFuncs::GetRequiredStorageSize(unsigned int rows,
112 unsigned int columns)
113{
114 return rows * columns;
115}
116
117unsigned 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
126std::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
154 unsigned int columns)
155{
156 ASSERTL0(rows == columns, "Triangular matrices must be square.");
157 return rows * (rows + 1) / 2;
158}
159
160unsigned 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
173std::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
232std::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
282unsigned 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
295std::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
334std::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
362unsigned 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
369unsigned 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)