MFEM v4.10.0
Finite element discretization library
Loading...
Searching...
No Matches
densemat.hpp
Go to the documentation of this file.
1// Copyright (c) 2010-2026, Lawrence Livermore National Security, LLC. Produced
2// at the Lawrence Livermore National Laboratory. All Rights reserved. See files
3// LICENSE and NOTICE for details. LLNL-CODE-806117.
4//
5// This file is part of the MFEM library. For more information and source code
6// availability visit https://mfem.org.
7//
8// MFEM is free software; you can redistribute it and/or modify it under the
9// terms of the BSD-3 license. We welcome feedback and contributions, see file
10// CONTRIBUTING.md for details.
11
12#ifndef MFEM_DENSEMAT
13#define MFEM_DENSEMAT
14
15#include "../config/config.hpp"
17#include "matrix.hpp"
18
19namespace mfem
20{
21
22/// Data type dense matrix using column-major storage
23class DenseMatrix : public Matrix
24{
25 friend class DenseTensor;
26 friend class DenseMatrixInverse;
27
28private:
29 Array<real_t> data;
30
31 void Eigensystem(Vector &ev, DenseMatrix *evect = NULL);
32
33 void Eigensystem(DenseMatrix &b, Vector &ev, DenseMatrix *evect = NULL);
34
35 // Auxiliary method used in FNorm2() and FNorm()
36 void FNorm(real_t &scale_factor, real_t &scaled_fnorm2) const;
37
38public:
39 /** Default constructor for DenseMatrix.
40 Sets data = NULL and height = width = 0. */
42
43 /// Creates square matrix of size s.
44 explicit DenseMatrix(int s);
45
46 /// Creates rectangular matrix of size m x n.
47 DenseMatrix(int m, int n);
48
49 /// Creates rectangular matrix equal to the transpose of mat.
50 DenseMatrix(const DenseMatrix &mat, char ch);
51
52 /// Construct a DenseMatrix using an existing data array.
53 /** The DenseMatrix does not assume ownership of the data array, i.e. it will
54 not delete the array. */
55 DenseMatrix(real_t *d, int h, int w)
56 : Matrix(h, w) { UseExternalData(d, h, w); }
57
58 /// Copy constructor (deep copy).
59 DenseMatrix(const DenseMatrix &) = default;
60
61 /// Move constructor.
62 DenseMatrix(DenseMatrix &&) = default;
63
64 /// Copy assignment (deep copy).
65 DenseMatrix &operator=(const DenseMatrix &) = default;
66
67 /// Move assignment.
69
70 /// Create a dense matrix using a braced initializer list
71 /// The inner lists correspond to rows of the matrix
72 template <int M, int N, typename T = real_t>
73 explicit DenseMatrix(const T (&values)[M][N]) : DenseMatrix(M, N)
74 {
75 // DenseMatrix is column-major so copies have to be element-wise
76 for (int i = 0; i < M; i++)
77 {
78 for (int j = 0; j < N; j++)
79 {
80 (*this)(i,j) = values[i][j];
81 }
82 }
83 }
84
85 /// Make the DenseMatrix to reference the given sub-Memory of @a base.
86 /** The DenseMatrix does not assume ownership of the data array, i.e. it will
87 not delete the @a base Memory. */
88 void MakeRef(Memory<real_t> &base, int offset, int h, int w)
89 {
90 data.MakeRef(base, offset, h*w);
91 height = h; width = w;
92 }
93
94 /// Change the data array and the size of the DenseMatrix.
95 /** The DenseMatrix does not assume ownership of the data array, i.e. it will
96 not delete the data array @a d. */
97 void UseExternalData(real_t *d, int h, int w)
98 {
99 data.MakeRef(d, h*w);
100 height = h; width = w;
101 }
102
103 /// Change the data array and the size of the DenseMatrix.
104 /** The DenseMatrix does not assume ownership of the data array, i.e. it will
105 not delete the new array @a d. This method will delete the current data
106 array, if owned. */
107 void Reset(real_t *d, int h, int w)
108 { UseExternalData(d, h, w); }
109
110 /** Clear the data array and the dimensions of the DenseMatrix. This method
111 should not be used with DenseMatrix that owns its current data array. */
112 void ClearExternalData() { data.LoseData(); height = width = 0; }
113
114 /// Delete the matrix data array (if owned) and reset the matrix state.
115 void Clear()
116 { data.DeleteAll(); height = width = 0; }
117
118 /// For backward compatibility define Size to be synonym of Width()
119 int Size() const { return Width(); }
120
121 /// Total size = width*height
122 int TotalSize() const { return width*height; }
123
124 /// Change the size of the DenseMatrix to s x s.
125 void SetSize(int s) { SetSize(s, s); }
126
127 /// Change the size of the DenseMatrix to h x w.
128 void SetSize(int h, int w);
129
130 /// Returns the matrix data array. Warning: this method casts away constness.
131 inline real_t *Data() const
132 { return const_cast<real_t*>((const real_t*)data);}
133
134 /// Returns the matrix data array. Warning: this method casts away constness.
135 inline real_t *GetData() const { return Data(); }
136
137 Memory<real_t> &GetMemory() { return data.GetMemory(); }
138
139 const Memory<real_t> &GetMemory() const { return data.GetMemory(); }
140
141 /// Return the DenseMatrix data (host pointer) ownership flag.
142 inline bool OwnsData() const { return data.OwnsData(); }
143
144 /// Returns reference to a_{ij}.
145 inline real_t &operator()(int i, int j);
146
147 /// Returns constant reference to a_{ij}.
148 inline const real_t &operator()(int i, int j) const;
149
150 /// Matrix inner product: tr(A^t B)
151 real_t operator*(const DenseMatrix &m) const;
152
153 /// Trace of a square matrix
154 real_t Trace() const;
155
156 /// Returns reference to a_{ij}.
157 real_t &Elem(int i, int j) override;
158
159 /// Returns constant reference to a_{ij}.
160 const real_t &Elem(int i, int j) const override;
161
162 /// Matrix vector multiplication.
163 void Mult(const real_t *x, real_t *y) const;
164
165 /// Matrix vector multiplication.
166 void Mult(const real_t *x, Vector &y) const;
167
168 /// Matrix vector multiplication.
169 void Mult(const Vector &x, real_t *y) const;
170
171 /// Matrix vector multiplication.
172 void Mult(const Vector &x, Vector &y) const override;
173
174 /// Absolute-value matrix vector multiplication.
175 void AbsMult(const Vector &x, Vector &y) const override;
176
177 /// Multiply a vector with the transpose matrix.
178 void MultTranspose(const real_t *x, real_t *y) const;
179
180 /// Multiply a vector with the transpose matrix.
181 void MultTranspose(const real_t *x, Vector &y) const;
182
183 /// Multiply a vector with the transpose matrix.
184 void MultTranspose(const Vector &x, real_t *y) const;
185
186 /// Multiply a vector with the transpose matrix.
187 void MultTranspose(const Vector &x, Vector &y) const override;
188
189 /// Multiply a vector with the absolute-value transpose matrix.
190 void AbsMultTranspose(const Vector &x, Vector &y) const override;
191
192 using Operator::Mult;
194
195 /// y += a * A.x
196 void AddMult(const Vector &x, Vector &y, const real_t a = 1.0) const override;
197
198 /// y += a * A^t x
199 void AddMultTranspose(const Vector &x, Vector &y,
200 const real_t a = 1.0) const override;
201
202 /// y += a * A.x
203 void AddMult_a(real_t a, const Vector &x, Vector &y) const;
204
205 /// y += a * A^t x
206 void AddMultTranspose_a(real_t a, const Vector &x, Vector &y) const;
207
208 /// Compute y^t A x
209 real_t InnerProduct(const real_t *x, const real_t *y) const;
210
211 /// LeftScaling this = diag(s) * this
212 void LeftScaling(const Vector & s);
213 /// InvLeftScaling this = diag(1./s) * this
214 void InvLeftScaling(const Vector & s);
215 /// RightScaling: this = this * diag(s);
216 void RightScaling(const Vector & s);
217 /// InvRightScaling: this = this * diag(1./s);
218 void InvRightScaling(const Vector & s);
219 /// SymmetricScaling this = diag(sqrt(s)) * this * diag(sqrt(s))
220 void SymmetricScaling(const Vector & s);
221 /// InvSymmetricScaling this = diag(sqrt(1./s)) * this * diag(sqrt(1./s))
222 void InvSymmetricScaling(const Vector & s);
223
224 /// Compute y^t A x
225 real_t InnerProduct(const Vector &x, const Vector &y) const
226 { return InnerProduct(x.GetData(), y.GetData()); }
227
228 /// Returns a pointer to the inverse matrix.
229 MatrixInverse *Inverse() const override;
230
231 /// Replaces the current matrix with its inverse
232 void Invert();
233
234 /// Replaces the current matrix with its square root inverse
235 void SquareRootInverse();
236
237 /// Replaces the current matrix with its exponential
238 /// (currently only supports 2x2 matrices)
239 void Exponential();
240
241 /// Calculates the determinant of the matrix
242 /// (optimized for 2x2, 3x3, and 4x4 matrices)
243 real_t Det() const;
244
245 real_t Weight() const;
246
247 /** @brief Set the matrix to alpha * A, assuming that A has the same
248 dimensions as the matrix and uses column-major layout. */
249 void Set(real_t alpha, const real_t *A);
250 /// Set the matrix to alpha * A.
251 void Set(real_t alpha, const DenseMatrix &A)
252 {
253 SetSize(A.Height(), A.Width());
254 Set(alpha, A.GetData());
255 }
256
257 /// Adds the matrix A multiplied by the number c to the matrix.
258 void Add(const real_t c, const DenseMatrix &A);
259
260 /// Adds the matrix A multiplied by the number c to the matrix,
261 /// assuming A has the same dimensions and uses column-major layout.
262 void Add(const real_t c, const real_t *A);
263
264 /// Sets the matrix elements equal to constant c
266
267 /// Copy the matrix entries from the given array
268 DenseMatrix &operator=(const real_t *d);
269
270 DenseMatrix &operator+=(const real_t *m);
272
274
276
277 /// (*this) = -(*this)
278 void Neg();
279
280 /// Take the 2-norm of the columns of A and store in v
281 void Norm2(real_t *v) const;
282
283 /// Take the 2-norm of the columns of A and store in v
284 void Norm2(Vector &v) const
285 {
286 MFEM_ASSERT(v.Size() == Width(), "incompatible Vector size!");
287 Norm2(v.GetData());
288 }
289
290 /// Compute the norm ||A|| = max_{ij} |A_{ij}|
291 real_t MaxMaxNorm() const;
292
293 /// Compute the Frobenius norm of the matrix
294 real_t FNorm() const { real_t s, n2; FNorm(s, n2); return s*sqrt(n2); }
295
296 /// Compute the square of the Frobenius norm of the matrix
297 real_t FNorm2() const { real_t s, n2; FNorm(s, n2); return s*s*n2; }
298
299 /// Compute eigenvalues of A x = ev x where A = *this
301 { Eigensystem(ev); }
302
303 /// Compute eigenvalues and eigenvectors of A x = ev x where A = *this
305 { Eigensystem(ev, &evect); }
306
307 /// Compute eigenvalues and eigenvectors of A x = ev x where A = *this
309 { Eigensystem(ev, &evect); }
310
311 /** Compute generalized eigenvalues and eigenvectors of A x = ev B x,
312 where A = *this */
314 { Eigensystem(b, ev); }
315
316 /// Compute generalized eigenvalues of A x = ev B x, where A = *this
318 { Eigensystem(b, ev, &evect); }
319
320 /** Compute generalized eigenvalues and eigenvectors of A x = ev B x,
321 where A = *this */
323 { Eigensystem(b, ev, &evect); }
324
325 void SingularValues(Vector &sv) const;
326 int Rank(real_t tol) const;
327
328 /// Return the i-th singular value (decreasing order) of NxN matrix, N=1,2,3.
329 real_t CalcSingularvalue(const int i) const;
330
331 /** Return the eigenvalues (in increasing order) and eigenvectors of a
332 2x2 or 3x3 symmetric matrix. */
333 void CalcEigenvalues(real_t *lambda, real_t *vec) const;
334
335 void GetRow(int r, Vector &row) const;
336 void GetColumn(int c, Vector &col) const;
337 real_t *GetColumn(int col) { return data + col*height; }
338 const real_t *GetColumn(int col) const { return data + col*height; }
339
340 void GetColumnReference(int c, Vector &col)
341 { col.SetDataAndSize(data + c * height, height); }
342
343 void SetRow(int r, const real_t* row);
344 void SetRow(int r, const Vector &row);
345
346 void SetCol(int c, const real_t* col);
347 void SetCol(int c, const Vector &col);
348
349
350 /// Set all entries of a row to the specified value.
351 void SetRow(int row, real_t value);
352 /// Set all entries of a column to the specified value.
353 void SetCol(int col, real_t value);
354
355 /// Returns the diagonal of the matrix
356 void GetDiag(Vector &d) const;
357 /// Returns the l1 norm of the rows of the matrix v_i = sum_j |a_ij|
358 /// @deprecated Use GetRowl1() instead.
359 MFEM_DEPRECATED void Getl1Diag(Vector &l) const;
360 /// Returns the l1 norm of the rows of the matrix v_i = sum_j |a_ij|
361 void GetRowl1(Vector &l) const;
362 /// Returns the l2norm of the rows of the DenseMatrix
363 void GetRowl2(Vector &l) const;
364 /// Returns the row sums of the DenseMatrix
365 void GetRowSums(Vector &l) const;
366
367 /// Creates n x n diagonal matrix with diagonal elements c
368 void Diag(real_t c, int n);
369 /// Creates n x n diagonal matrix with diagonal given by diag
370 void Diag(real_t *diag, int n);
371
372 /// (*this) = (*this)^t
373 void Transpose();
374 /// (*this) = A^t
375 void Transpose(const DenseMatrix &A);
376 /// (*this) = 1/2 ((*this) + (*this)^t)
377 void Symmetrize();
378
379 void Lump();
380
381 /** Given a DShape matrix (from a scalar FE), stored in *this, returns the
382 CurlShape matrix. If *this is a N by D matrix, then curl is a D*N by
383 D*(D-1)/2 matrix. The size of curl must be set outside. The dimension D
384 can be either 2 or 3. In 2D this computes the scalar-valued curl of a
385 2D vector field */
386 void GradToCurl(DenseMatrix &curl);
387 /** Given a DShape matrix (from a scalar FE), stored in *this, returns the
388 CurlShape matrix. This computes the vector-valued curl of a scalar field.
389 *this is N by 2 matrix and curl is N by 2 matrix as well. */
391 /** Given a DShape matrix (from a scalar FE), stored in *this,
392 returns the DivShape vector. If *this is a N by dim matrix,
393 then div is a dim*N vector. The size of div must be set
394 outside. */
395 void GradToDiv(Vector &div);
396
397 /// Copy rows row1 through row2 from A to *this
398 void CopyRows(const DenseMatrix &A, int row1, int row2);
399 /// Copy columns col1 through col2 from A to *this
400 void CopyCols(const DenseMatrix &A, int col1, int col2);
401 /// Copy the m x n submatrix of A at row/col offsets Aro/Aco to *this
402 void CopyMN(const DenseMatrix &A, int m, int n, int Aro, int Aco);
403 /// Copy matrix A to the location in *this at row_offset, col_offset
404 void CopyMN(const DenseMatrix &A, int row_offset, int col_offset);
405 /// Copy matrix A^t to the location in *this at row_offset, col_offset
406 void CopyMNt(const DenseMatrix &A, int row_offset, int col_offset);
407 /** Copy the m x n submatrix of A at row/col offsets Aro/Aco to *this at
408 row_offset, col_offset */
409 void CopyMN(const DenseMatrix &A, int m, int n, int Aro, int Aco,
410 int row_offset, int col_offset);
411 /// Copy c on the diagonal of size n to *this at row_offset, col_offset
412 void CopyMNDiag(real_t c, int n, int row_offset, int col_offset);
413 /// Copy diag on the diagonal of size n to *this at row_offset, col_offset
414 void CopyMNDiag(real_t *diag, int n, int row_offset, int col_offset);
415 /// Copy All rows and columns except m and n from A
416 void CopyExceptMN(const DenseMatrix &A, int m, int n);
417
418 /// Perform (ro+i,co+j)+=A(i,j) for 0<=i<A.Height, 0<=j<A.Width
419 void AddMatrix(DenseMatrix &A, int ro, int co);
420 /// Perform (ro+i,co+j)+=a*A(i,j) for 0<=i<A.Height, 0<=j<A.Width
421 void AddMatrix(real_t a, const DenseMatrix &A, int ro, int co);
422
423 /** Get the square submatrix which corresponds to the given indices @a idx.
424 Note: the @a A matrix will be resized to accommodate the data */
425 void GetSubMatrix(const Array<int> & idx, DenseMatrix & A) const;
426
427 /** Get the rectangular submatrix which corresponds to the given indices
428 @a idx_i and @a idx_j. Note: the @a A matrix will be resized to
429 accommodate the data */
430 void GetSubMatrix(const Array<int> & idx_i, const Array<int> & idx_j,
431 DenseMatrix & A) const;
432
433 /** Get the square submatrix which corresponds to the range
434 [ @a ibeg, @a iend ). Note: the @a A matrix will be resized
435 to accommodate the data */
436 void GetSubMatrix(int ibeg, int iend, DenseMatrix & A);
437
438 /** Get the square submatrix which corresponds to the range
439 i ∈ [ @a ibeg, @a iend ) and j ∈ [ @a jbeg, @a jend )
440 Note: the @a A matrix will be resized to accommodate the data */
441 void GetSubMatrix(int ibeg, int iend, int jbeg, int jend, DenseMatrix & A);
442
443 /// Set (*this)(idx[i],idx[j]) = A(i,j)
444 void SetSubMatrix(const Array<int> & idx, const DenseMatrix & A);
445
446 /// Set (*this)(idx_i[i],idx_j[j]) = A(i,j)
447 void SetSubMatrix(const Array<int> & idx_i, const Array<int> & idx_j,
448 const DenseMatrix & A);
449
450 /** Set a submatrix of (this) to the given matrix @a A
451 with row and column offset @a ibeg */
452 void SetSubMatrix(int ibeg, const DenseMatrix & A);
453
454 /** Set a submatrix of (this) to the given matrix @a A
455 with row and column offset @a ibeg and @a jbeg respectively */
456 void SetSubMatrix(int ibeg, int jbeg, const DenseMatrix & A);
457
458 /// (*this)(idx[i],idx[j]) += A(i,j)
459 void AddSubMatrix(const Array<int> & idx, const DenseMatrix & A);
460
461 /// (*this)(idx_i[i],idx_j[j]) += A(i,j)
462 void AddSubMatrix(const Array<int> & idx_i, const Array<int> & idx_j,
463 const DenseMatrix & A);
464
465 /** Add the submatrix @a A to this with row and column offset @a ibeg */
466 void AddSubMatrix(int ibeg, const DenseMatrix & A);
467
468 /** Add the submatrix @a A to this with row and column offsets
469 @a ibeg and @a jbeg respectively */
470 void AddSubMatrix(int ibeg, int jbeg, const DenseMatrix & A);
471
472 /// Add the matrix 'data' to the Vector 'v' at the given 'offset'
473 void AddToVector(int offset, Vector &v) const;
474 /// Get the matrix 'data' from the Vector 'v' at the given 'offset'
475 void GetFromVector(int offset, const Vector &v);
476 /** If (dofs[i] < 0 and dofs[j] >= 0) or (dofs[i] >= 0 and dofs[j] < 0)
477 then (*this)(i,j) = -(*this)(i,j). */
478 void AdjustDofDirection(const Array<int> &dofs);
479
480 /** If (row_dofs[i] < 0) xor (col_dofs[j] < 0) then
481 (*this)(i,j) = -(*this)(i,j). This method also converts
482 row_dofs/col_dofs to unsigned indices (d -> -d-1). */
483 void AdjustDofDirection(Array<int> &row_dofs,
484 Array<int> &col_dofs);
485
486 /// Replace small entries, abs(a_ij) <= eps, with zero.
487 void Threshold(real_t eps);
488
489 /** Count the number of entries in the matrix for which isfinite
490 is false, i.e. the entry is a NaN or +/-Inf. */
492
493 /// Prints matrix to stream out.
494 void Print(std::ostream &out = mfem::out, int width_ = 4) const override;
495 void PrintMatlab(std::ostream &out = mfem::out) const override;
496 virtual void PrintMathematica(std::ostream &out = mfem::out) const;
497 /// Prints the transpose matrix to stream out.
498 virtual void PrintT(std::ostream &out = mfem::out, int width_ = 4) const;
499
500 /// Invert and print the numerical conditioning of the inversion.
501 void TestInversion();
502
503 std::size_t MemoryUsage() const { return data.Capacity() * sizeof(real_t); }
504
505 /// Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
506 const real_t *Read(bool on_dev = true) const { return data.Read(on_dev); }
507
508 /// Shortcut for mfem::Read(GetMemory(), TotalSize(), false).
509 const real_t *HostRead() const { return data.HostRead(); }
510
511 /// Shortcut for mfem::Write(GetMemory(), TotalSize(), on_dev).
512 real_t *Write(bool on_dev = true) { return data.Write(on_dev); }
513
514 /// Shortcut for mfem::Write(GetMemory(), TotalSize(), false).
515 real_t *HostWrite() { return data.HostWrite(); }
516
517 /// Shortcut for mfem::ReadWrite(GetMemory(), TotalSize(), on_dev).
518 real_t *ReadWrite(bool on_dev = true) { return data.ReadWrite(on_dev); }
519
520 /// Shortcut for mfem::ReadWrite(GetMemory(), TotalSize(), false).
521 real_t *HostReadWrite() { return data.HostReadWrite(); }
522
523 void Swap(DenseMatrix &other);
524};
525
526/// C = A + alpha*B
527void Add(const DenseMatrix &A, const DenseMatrix &B,
528 real_t alpha, DenseMatrix &C);
529
530/// C = alpha*A + beta*B
531void Add(real_t alpha, const real_t *A,
532 real_t beta, const real_t *B, DenseMatrix &C);
533
534/// C = alpha*A + beta*B
535void Add(real_t alpha, const DenseMatrix &A,
536 real_t beta, const DenseMatrix &B, DenseMatrix &C);
537
538/// @brief Solves the dense linear system, `A * X = B` for `X`
539///
540/// @param [in,out] A the square matrix for the linear system
541/// @param [in,out] X the rhs vector, B, on input, the solution, X, on output.
542/// @param [in] TOL optional fuzzy comparison tolerance. Defaults to 1e-9.
543///
544/// @return status set to true if successful, otherwise, false.
545///
546/// @note This routine may replace the contents of the input Matrix, A, with the
547/// corresponding LU factorization of the matrix. Matrices of size 1x1 and
548/// 2x2 are handled explicitly.
549///
550/// @pre A.IsSquare() == true
551/// @pre X != nullptr
552bool LinearSolve(DenseMatrix& A, real_t* X, real_t TOL = 1.e-9);
553
554/// Matrix matrix multiplication. A = B * C.
555void Mult(const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a);
556
557/// Matrix matrix multiplication. A += B * C.
558void AddMult(const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a);
559
560/// Matrix matrix multiplication. A += alpha * B * C.
561void AddMult_a(real_t alpha, const DenseMatrix &b, const DenseMatrix &c,
562 DenseMatrix &a);
563
564/** Calculate the adjugate of a matrix (for NxN matrices, N=1,2,3) or the matrix
565 adj(A^t.A).A^t for rectangular matrices (2x1, 3x1, or 3x2). This operation
566 is well defined even when the matrix is not full rank. */
567void CalcAdjugate(const DenseMatrix &a, DenseMatrix &adja);
568
569/// Calculate the transposed adjugate of a matrix (for NxN matrices, N=1,2,3)
570void CalcAdjugateTranspose(const DenseMatrix &a, DenseMatrix &adjat);
571
572/** Calculate the inverse of a matrix (for NxN matrices, N=1,2,3) or the
573 left inverse (A^t.A)^{-1}.A^t (for 2x1, 3x1, or 3x2 matrices) */
574void CalcInverse(const DenseMatrix &a, DenseMatrix &inva);
575
576/// Calculate the inverse transpose of a matrix (for NxN matrices, N=1,2,3)
577void CalcInverseTranspose(const DenseMatrix &a, DenseMatrix &inva);
578
579/** For a given Nx(N-1) (N=2,3) matrix J, compute a vector n such that
580 n_k = (-1)^{k+1} det(J_k), k=1,..,N, where J_k is the matrix J with the
581 k-th row removed. Note: J^t.n = 0, det([n|J])=|n|^2=det(J^t.J). */
582void CalcOrtho(const DenseMatrix &J, Vector &n);
583
584/// Calculate the matrix A.At
585void MultAAt(const DenseMatrix &a, DenseMatrix &aat);
586
587/// ADAt = A D A^t, where D is diagonal
588void MultADAt(const DenseMatrix &A, const Vector &D, DenseMatrix &ADAt);
589
590/// ADAt += A D A^t, where D is diagonal
591void AddMultADAt(const DenseMatrix &A, const Vector &D, DenseMatrix &ADAt);
592
593/// Multiply a matrix A with the transpose of a matrix B: A*Bt
594void MultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt);
595
596/// ADBt = A D B^t, where D is diagonal
597void MultADBt(const DenseMatrix &A, const Vector &D,
598 const DenseMatrix &B, DenseMatrix &ADBt);
599
600/// ABt += A * B^t
601void AddMultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt);
602
603/// ADBt = A D B^t, where D is diagonal
604void AddMultADBt(const DenseMatrix &A, const Vector &D,
605 const DenseMatrix &B, DenseMatrix &ADBt);
606
607/// ABt += a * A * B^t
608void AddMult_a_ABt(real_t a, const DenseMatrix &A, const DenseMatrix &B,
609 DenseMatrix &ABt);
610
611/// Multiply the transpose of a matrix A with a matrix B: At*B
612void MultAtB(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &AtB);
613
614/// AtB += A^t * B
615void AddMultAtB(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &AtB);
616
617/// AtB += a * A^t * B
618void AddMult_a_AtB(real_t a, const DenseMatrix &A, const DenseMatrix &B,
619 DenseMatrix &AtB);
620
621/// AAt += a * A * A^t
622void AddMult_a_AAt(real_t a, const DenseMatrix &A, DenseMatrix &AAt);
623
624/// AAt = a * A * A^t
625void Mult_a_AAt(real_t a, const DenseMatrix &A, DenseMatrix &AAt);
626
627/// Make a matrix from a vector V.Vt
628void MultVVt(const Vector &v, DenseMatrix &vvt);
629
630void MultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt);
631
632/// VWt += v w^t
633void AddMultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt);
634
635/// VVt += v v^t
636void AddMultVVt(const Vector &v, DenseMatrix &VWt);
637
638/// VWt += a * v w^t
639void AddMult_a_VWt(const real_t a, const Vector &v, const Vector &w,
640 DenseMatrix &VWt);
641
642/// VVt += a * v v^t
643void AddMult_a_VVt(const real_t a, const Vector &v, DenseMatrix &VVt);
644
645/** Computes matrix P^t * A * P. Note: The @a RAP matrix will be resized
646 to accommodate the data */
647void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix & RAP);
648
649/** Computes the matrix Rt^t * A * P. Note: The @a RAP matrix will be resized
650 to accommodate the data */
651void RAP(const DenseMatrix &Rt, const DenseMatrix &A,
652 const DenseMatrix &P, DenseMatrix & RAP);
653
654/** Abstract class that can compute factorization of external data and perform various
655 operations with the factored data. */
657{
658public:
659
661
663
664 Factors(real_t *data_) : data(data_) { }
665
666 virtual bool Factor(int m, real_t TOL = 0.0)
667 {
668 mfem_error("Factors::Factors(...)");
669 return false;
670 }
671
672 virtual real_t Det(int m) const
673 {
674 mfem_error("Factors::Det(...)");
675 return 0.;
676 }
677
678 virtual void Solve(int m, int n, real_t *X) const
679 {
680 mfem_error("Factors::Solve(...)");
681 }
682
683 virtual void GetInverseMatrix(int m, real_t *X) const
684 {
685 mfem_error("Factors::GetInverseMatrix(...)");
686 }
687
688 virtual ~Factors() {}
689};
690
691
692/** Class that can compute LU factorization of external data and perform various
693 operations with the factored data. */
694class LUFactors : public Factors
695{
696public:
697 int *ipiv;
698 static constexpr int ipiv_base = 1;
699
700 /** With this constructor, the (public) data and ipiv members should be set
701 explicitly before calling class methods. */
703
704 LUFactors(real_t *data_, int *ipiv_) : Factors(data_), ipiv(ipiv_) { }
705
706 /**
707 * @brief Compute the LU factorization of the current matrix
708 *
709 * Factorize the current matrix of size (m x m) overwriting it with the
710 * LU factors. The factorization is such that L.U = P.A, where A is the
711 * original matrix and P is a permutation matrix represented by ipiv.
712 *
713 * @param [in] m size of the square matrix
714 * @param [in] TOL optional fuzzy comparison tolerance. Defaults to 0.0.
715 *
716 * @return status set to true if successful, otherwise, false.
717 */
718 bool Factor(int m, real_t TOL = 0.0) override;
719
720 /** Assuming L.U = P.A factored data of size (m x m), compute |A|
721 from the diagonal values of U and the permutation information. */
722 real_t Det(int m) const override;
723
724 /** Assuming L.U = P.A factored data of size (m x m), compute X <- A X,
725 for a matrix X of size (m x n). */
726 void Mult(int m, int n, real_t *X) const;
727
728 /** Assuming L.U = P.A factored data of size (m x m), compute
729 X <- L^{-1} P X, for a matrix X of size (m x n). */
730 void LSolve(int m, int n, real_t *X) const;
731
732 /** Assuming L.U = P.A factored data of size (m x m), compute
733 X <- U^{-1} X, for a matrix X of size (m x n). */
734 void USolve(int m, int n, real_t *X) const;
735
736 /** Assuming L.U = P.A factored data of size (m x m), compute X <- A^{-1} X,
737 for a matrix X of size (m x n). */
738 void Solve(int m, int n, real_t *X) const override;
739
740 /** Assuming L.U = P.A factored data of size (m x m), compute X <- X A^{-1},
741 for a matrix X of size (n x m). */
742 void RightSolve(int m, int n, real_t *X) const;
743
744 /// Assuming L.U = P.A factored data of size (m x m), compute X <- A^{-1}.
745 void GetInverseMatrix(int m, real_t *X) const override;
746
747 /** Given an (n x m) matrix A21, compute X2 <- X2 - A21 X1, for matrices X1,
748 and X2 of size (m x r) and (n x r), respectively. */
749 static void SubMult(int m, int n, int r, const real_t *A21,
750 const real_t *X1, real_t *X2);
751
752 /** Assuming P.A = L.U factored data of size (m x m), compute the 2x2 block
753 decomposition:
754 | P 0 | | A A12 | = | L 0 | | U U12 |
755 | 0 I | | A21 A22 | | L21 I | | 0 S22 |
756 where A12, A21, and A22 are matrices of size (m x n), (n x m), and
757 (n x n), respectively. The blocks are overwritten as follows:
758 A12 <- U12 = L^{-1} P A12
759 A21 <- L21 = A21 U^{-1}
760 A22 <- S22 = A22 - L21 U12.
761 The block S22 is the Schur complement. */
762 void BlockFactor(int m, int n, real_t *A12, real_t *A21, real_t *A22) const;
763
764 /** Given BlockFactor()'d data, perform the forward block solve for the
765 linear system:
766 | A A12 | | X1 | = | B1 |
767 | A21 A22 | | X2 | | B2 |
768 written in the factored form:
769 | L 0 | | U U12 | | X1 | = | P 0 | | B1 |
770 | L21 I | | 0 S22 | | X2 | | 0 I | | B2 |.
771 The resulting blocks Y1, Y2 solve the system:
772 | L 0 | | Y1 | = | P 0 | | B1 |
773 | L21 I | | Y2 | | 0 I | | B2 |
774 The blocks are overwritten as follows:
775 B1 <- Y1 = L^{-1} P B1
776 B2 <- Y2 = B2 - L21 Y1 = B2 - A21 A^{-1} B1
777 The blocks B1/Y1 and B2/Y2 are of size (m x r) and (n x r), respectively.
778 The Schur complement system is given by: S22 X2 = Y2. */
779 void BlockForwSolve(int m, int n, int r, const real_t *L21,
780 real_t *B1, real_t *B2) const;
781
782 /** Given BlockFactor()'d data, perform the backward block solve in
783 | U U12 | | X1 | = | Y1 |
784 | 0 S22 | | X2 | | Y2 |.
785 The input is the solution block X2 and the block Y1 resulting from
786 BlockForwSolve(). The result block X1 overwrites input block Y1:
787 Y1 <- X1 = U^{-1} (Y1 - U12 X2). */
788 void BlockBackSolve(int m, int n, int r, const real_t *U12,
789 const real_t *X2, real_t *Y1) const;
790};
791
792
793/** Class that can compute Cholesky factorizations of external data of an
794 SPD matrix and perform various operations with the factored data. */
796{
797public:
798
799 /** With this constructor, the (public) data should be set
800 explicitly before calling class methods. */
802
803 CholeskyFactors(real_t *data_) : Factors(data_) { }
804
805 /**
806 * @brief Compute the Cholesky factorization of the current matrix
807 *
808 * Factorize the current matrix of size (m x m) overwriting it with the
809 * Cholesky factors. The factorization is such that LL^t = A, where A is the
810 * original matrix
811 *
812 * @param [in] m size of the square matrix
813 * @param [in] TOL optional fuzzy comparison tolerance. Defaults to 0.0.
814 *
815 * @return status set to true if successful, otherwise, false.
816 */
817 bool Factor(int m, real_t TOL = 0.0) override;
818
819 /** Assuming LL^t = A factored data of size (m x m), compute |A|
820 from the diagonal values of L */
821 real_t Det(int m) const override;
822
823 /** Assuming L.L^t = A factored data of size (m x m), compute X <- L X,
824 for a matrix X of size (m x n). */
825 void LMult(int m, int n, real_t *X) const;
826
827 /** Assuming L.L^t = A factored data of size (m x m), compute X <- L^t X,
828 for a matrix X of size (m x n). */
829 void UMult(int m, int n, real_t *X) const;
830
831 /** Assuming L L^t = A factored data of size (m x m), compute
832 X <- L^{-1} X, for a matrix X of size (m x n). */
833 void LSolve(int m, int n, real_t *X) const;
834
835 /** Assuming L L^t = A factored data of size (m x m), compute
836 X <- L^{-t} X, for a matrix X of size (m x n). */
837 void USolve(int m, int n, real_t *X) const;
838
839 /** Assuming L.L^t = A factored data of size (m x m), compute X <- A^{-1} X,
840 for a matrix X of size (m x n). */
841 void Solve(int m, int n, real_t *X) const override;
842
843 /** Assuming L.L^t = A factored data of size (m x m), compute X <- X A^{-1},
844 for a matrix X of size (n x m). */
845 void RightSolve(int m, int n, real_t *X) const;
846
847 /// Assuming L.L^t = A factored data of size (m x m), compute X <- A^{-1}.
848 void GetInverseMatrix(int m, real_t *X) const override;
849
850};
851
852
853/** Data type for inverse of square dense matrix.
854 Stores matrix factors, i.e., Cholesky factors if the matrix is SPD,
855 LU otherwise. */
857{
858private:
859 const DenseMatrix *a;
860 Factors * factors = nullptr;
861 bool spd = false;
862
863 void Init(int m);
864 bool own_data = false;
865public:
866 /// Default constructor.
867 DenseMatrixInverse(bool spd_=false) : a(NULL), spd(spd_) { Init(0); }
868
869 /** Creates square dense matrix. Computes factorization of mat
870 and stores its factors. */
871 DenseMatrixInverse(const DenseMatrix &mat, bool spd_ = false);
872
873 /// Same as above but does not factorize the matrix.
874 DenseMatrixInverse(const DenseMatrix *mat, bool spd_ = false);
875
876 /// Get the size of the inverse matrix
877 int Size() const { return Width(); }
878
879 /// Factor the current DenseMatrix, *a
880 void Factor();
881
882 /// Factor a new DenseMatrix of the same size
883 void Factor(const DenseMatrix &mat);
884
885 void SetOperator(const Operator &op) override;
886
887 /// Matrix vector multiplication with the inverse of dense matrix.
888 void Mult(const real_t *x, real_t *y) const;
889
890 /// Matrix vector multiplication with the inverse of dense matrix.
891 void Mult(const Vector &x, Vector &y) const override;
892
893 /// Multiply the inverse matrix by another matrix: X = A^{-1} B.
894 void Mult(const DenseMatrix &B, DenseMatrix &X) const;
895
896 /// Multiply the inverse matrix by another matrix: X <- A^{-1} X.
897 void Mult(DenseMatrix &X) const {factors->Solve(width, X.Width(), X.Data());}
898
899 using Operator::Mult;
900
901 /// Compute and return the inverse matrix in Ainv.
902 void GetInverseMatrix(DenseMatrix &Ainv) const;
903
904 /// Compute the determinant of the original DenseMatrix using the LU factors.
905 real_t Det() const { return factors->Det(width); }
906
907 /// Print the numerical conditioning of the inversion: ||A^{-1} A - I||.
908 void TestInversion();
909
910 /// Destroys dense inverse matrix.
911 virtual ~DenseMatrixInverse();
912};
913
914#ifdef MFEM_USE_LAPACK
915
917{
918 DenseMatrix &mat;
919 Vector EVal;
920 DenseMatrix EVect;
921 Vector ev;
922 int n;
923 real_t *work;
924 char jobz, uplo;
925 int lwork, info;
926public:
927
930 void Eval();
931 Vector &Eigenvalues() { return EVal; }
932 DenseMatrix &Eigenvectors() { return EVect; }
933 real_t Eigenvalue(int i) { return EVal(i); }
934 const Vector &Eigenvector(int i)
935 {
936 ev.SetData(EVect.Data() + i * EVect.Height());
937 return ev;
938 }
940};
941
943{
944 DenseMatrix &A;
945 DenseMatrix &B;
946 DenseMatrix A_copy;
947 DenseMatrix B_copy;
948 Vector evalues_r;
949 Vector evalues_i;
950 DenseMatrix Vr;
951 DenseMatrix Vl;
952 int n;
953
954 real_t *alphar;
955 real_t *alphai;
956 real_t *beta;
957 real_t *work;
958 char jobvl, jobvr;
959 int lwork, info;
960
961public:
962
964 bool left_eigen_vectors = false,
965 bool right_eigen_vectors = false);
966 void Eval();
967 Vector &EigenvaluesRealPart() { return evalues_r; }
968 Vector &EigenvaluesImagPart() { return evalues_i; }
969 real_t EigenvalueRealPart(int i) { return evalues_r(i); }
970 real_t EigenvalueImagPart(int i) { return evalues_i(i); }
974};
975
976/**
977 @brief Class for Singular Value Decomposition of a DenseMatrix
978
979 Singular Value Decomposition (SVD) of a DenseMatrix with the use of the DGESVD
980 driver from LAPACK.
981 */
983{
984 DenseMatrix Mc;
985 Vector sv;
986 DenseMatrix U,Vt;
987 int m, n;
988
989#ifdef MFEM_USE_LAPACK
990 real_t *work;
991 char jobu, jobvt;
992 int lwork, info;
993#endif
994
995 void Init();
996public:
997
998 /**
999 @brief Constructor for the DenseMatrixSVD
1000
1001 Constructor for the DenseMatrixSVD with LAPACK. The parameters for the left
1002 and right singular vectors can be chosen according to the parameters for
1003 the LAPACK DGESVD.
1004
1005 @param [in] M matrix to set the size to n=M.Height(), m=M.Width()
1006 @param [in] left_singular_vectors optional parameter to define if first
1007 left singular vectors should be computed
1008 @param [in] right_singular_vectors optional parameter to define if first
1009 right singular vectors should be computed
1010 */
1011 MFEM_DEPRECATED DenseMatrixSVD(DenseMatrix &M,
1012 bool left_singular_vectors=false,
1013 bool right_singular_vectors=false);
1014
1015 /**
1016 @brief Constructor for the DenseMatrixSVD
1017
1018 Constructor for the DenseMatrixSVD with LAPACK. The parameters for the left
1019 and right singular
1020 vectors can be chosen according to the parameters for the LAPACK DGESVD.
1021
1022 @param [in] h height of the matrix
1023 @param [in] w width of the matrix
1024 @param [in] left_singular_vectors optional parameter to define if first
1025 left singular vectors should be computed
1026 @param [in] right_singular_vectors optional parameter to define if first
1027 right singular vectors should be computed
1028 */
1029 MFEM_DEPRECATED DenseMatrixSVD(int h, int w,
1030 bool left_singular_vectors=false,
1031 bool right_singular_vectors=false);
1032
1033 /**
1034 @brief Constructor for the DenseMatrixSVD
1035
1036 Constructor for the DenseMatrixSVD with LAPACK. The parameters for the left
1037 and right singular vectors can be chosen according to the parameters for
1038 the LAPACK DGESVD.
1039
1040 @param [in] M matrix to set the size to n=M.Height(), m=M.Width()
1041 @param [in] left_singular_vectors optional parameter to define which left
1042 singular vectors should be computed
1043 @param [in] right_singular_vectors optional parameter to define which right
1044 singular vectors should be computed
1045
1046 Options for computation of singular vectors:
1047
1048 'A': All singular vectors are computed (default)
1049
1050 'S': The first min(n,m) singular vectors are computed
1051
1052 'N': No singular vectors are computed
1053 */
1055 char left_singular_vectors='A',
1056 char right_singular_vectors='A');
1057
1058 /**
1059 @brief Constructor for the DenseMatrixSVD
1060
1061 Constructor for the DenseMatrixSVD with LAPACK. The parameters for the left
1062 and right singular vectors can be chosen according to the
1063 parameters for the LAPACK DGESVD.
1064
1065 @param [in] h height of the matrix
1066 @param [in] w width of the matrix
1067 @param [in] left_singular_vectors optional parameter to define which left
1068 singular vectors should be computed
1069 @param [in] right_singular_vectors optional parameter to define which right
1070 singular vectors should be computed
1071
1072 Options for computation of singular vectors:
1073
1074 'A': All singular vectors are computed (default)
1075
1076 'S': The first min(n,m) singular vectors are computed
1077
1078 'N': No singular vectors are computed
1079 */
1080 DenseMatrixSVD(int h, int w,
1081 char left_singular_vectors='A',
1082 char right_singular_vectors='A');
1083
1084 /**
1085 @brief Evaluate the SVD
1086
1087 Call of the DGESVD driver from LAPACK for the DenseMatrix M. The singular
1088 vectors are computed according to the setup in the call of the constructor.
1089
1090 @param [in] M DenseMatrix the SVD should be evaluated for
1091 */
1092 void Eval(DenseMatrix &M);
1093
1094 /**
1095 @brief Return singular values
1096
1097 @return sv Vector containing all singular values
1098 */
1099 Vector &Singularvalues() { return sv; }
1100
1101 /**
1102 @brief Return specific singular value
1103
1104 @return sv(i) i-th singular value
1105 */
1106 real_t Singularvalue(int i) { return sv(i); }
1107
1108 /**
1109 @brief Return left singular vectors
1110
1111 @return U DenseMatrix containing left singular vectors
1112 */
1114
1115 /**
1116 @brief Return right singular vectors
1117
1118 @return Vt DenseMatrix containing right singular vectors
1119 */
1122};
1123
1124#endif // if MFEM_USE_LAPACK
1125
1126
1127class Table;
1128
1129/// Rank 3 tensor (array of matrices)
1131{
1132private:
1133 mutable DenseMatrix Mk;
1134 Array<real_t> tdata;
1135 int ni, nj, nk;
1136
1137public:
1138 DenseTensor() : ni(0), nj(0), nk(0) { }
1139
1141 : tdata(other.tdata), ni(other.ni), nj(other.nj), nk(other.nk) { }
1142
1144 : tdata(std::move(other.tdata)), ni(other.ni), nj(other.nj), nk(other.nk)
1145 {
1146 // Reset other; other.tdata is reset in Array<T> move constructror.
1147 other.Mk.ClearExternalData();
1148 other.ni = other.nj = other.nk = 0;
1149 }
1150
1151 DenseTensor(int i, int j, int k) : tdata(i*j*k), ni(i), nj(j), nk(k) { }
1152
1153 DenseTensor(real_t *d, int i, int j, int k)
1154 : tdata(d, i*j*k), ni(i), nj(j), nk(k) { }
1155
1156 DenseTensor(int i, int j, int k, MemoryType mt)
1157 : tdata(i*j*k, mt), ni(i), nj(j), nk(k) { }
1158
1160 {
1161 if (this == &other) { return *this; }
1162 Mk.ClearExternalData();
1163 tdata = other.tdata;
1164 ni = other.ni;
1165 nj = other.nj;
1166 nk = other.nk;
1167 return *this;
1168 }
1169
1171 {
1172 if (this == &other) { return *this; }
1173 Mk.ClearExternalData();
1174 tdata = std::move(other.tdata);
1175 ni = other.ni;
1176 nj = other.nj;
1177 nk = other.nk;
1178
1179 // Reset other; other.tdata is reset in Array<T> move assignment.
1180 other.Mk.ClearExternalData();
1181 other.ni = other.nj = other.nk = 0;
1182
1183 return *this;
1184 }
1185
1186 int SizeI() const { return ni; }
1187 int SizeJ() const { return nj; }
1188 int SizeK() const { return nk; }
1189
1190 int TotalSize() const { return SizeI()*SizeJ()*SizeK(); }
1191
1192 void SetSize(int i, int j, int k, MemoryType mt_ = MemoryType::PRESERVE)
1193 {
1194 const MemoryType mt = mt_ == MemoryType::PRESERVE ?
1195 tdata.GetMemory().GetMemoryType() : mt_;
1196 ni = i;
1197 nj = j;
1198 nk = k;
1199 Mk.ClearExternalData();
1200 tdata.SetSize(i*j*k, mt);
1201 }
1202
1203 void UseExternalData(real_t *ext_data, int i, int j, int k)
1204 {
1205 ni = i;
1206 nj = j;
1207 nk = k;
1208 Mk.ClearExternalData();
1209 tdata.MakeRef(ext_data, i*j*k);
1210 }
1211
1212 /// @brief Reset the DenseTensor to use the given external Memory @a mem and
1213 /// dimensions @a i, @a j, and @a k.
1214 ///
1215 /// If @a own_mem is false, the DenseTensor will not own any of the pointers
1216 /// of @a mem.
1217 ///
1218 /// Note that when @a own_mem is true, the @a mem object can be destroyed
1219 /// immediately by the caller but `mem.Delete()` should NOT be called since
1220 /// the DenseTensor object takes ownership of all pointers owned by @a mem.
1221 void NewMemoryAndSize(const Memory<real_t> &mem, int i, int j, int k,
1222 bool own_mem)
1223 {
1224 ni = i;
1225 nj = j;
1226 nk = k;
1227 Mk.ClearExternalData();
1228 tdata.NewMemoryAndSize(mem, i*j*k, own_mem);
1229 }
1230
1231 /// Sets the tensor elements equal to constant c
1233
1235 {
1236 return operator()(k, Mk);
1237 }
1238 const DenseMatrix &operator()(int k) const
1239 {
1240 return operator()(k, Mk);
1241 }
1243 {
1244 MFEM_ASSERT_INDEX_IN_RANGE(k, 0, SizeK());
1245 buff.UseExternalData(GetData(k), SizeI(), SizeJ());
1246 return buff;
1247 }
1248 const DenseMatrix &operator()(int k, DenseMatrix& buff) const
1249 {
1250 MFEM_ASSERT_INDEX_IN_RANGE(k, 0, SizeK());
1251 buff.UseExternalData(const_cast<real_t*>(GetData(k)), SizeI(), SizeJ());
1252 return buff;
1253 }
1254
1255 real_t &operator()(int i, int j, int k)
1256 {
1257 MFEM_ASSERT_INDEX_IN_RANGE(i, 0, SizeI());
1258 MFEM_ASSERT_INDEX_IN_RANGE(j, 0, SizeJ());
1259 MFEM_ASSERT_INDEX_IN_RANGE(k, 0, SizeK());
1260 return tdata[i+SizeI()*(j+SizeJ()*k)];
1261 }
1262
1263 const real_t &operator()(int i, int j, int k) const
1264 {
1265 MFEM_ASSERT_INDEX_IN_RANGE(i, 0, SizeI());
1266 MFEM_ASSERT_INDEX_IN_RANGE(j, 0, SizeJ());
1267 MFEM_ASSERT_INDEX_IN_RANGE(k, 0, SizeK());
1268 return tdata[i+SizeI()*(j+SizeJ()*k)];
1269 }
1270
1272 {
1273 MFEM_ASSERT_INDEX_IN_RANGE(k, 0, SizeK());
1274 return tdata.GetMemory()+k*ni*nj;
1275 }
1276
1277 const real_t *GetData(int k) const
1278 {
1279 MFEM_ASSERT_INDEX_IN_RANGE(k, 0, SizeK());
1280 return tdata.GetMemory()+k*ni*nj;
1281 }
1282
1283 real_t *Data() { return tdata.GetData(); }
1284
1285 const real_t *Data() const { return tdata.GetData(); }
1286
1287 Memory<real_t> &GetMemory() { return tdata.GetMemory(); }
1288 const Memory<real_t> &GetMemory() const { return tdata.GetMemory(); }
1289
1290 /** Matrix-vector product from unassembled element matrices, assuming both
1291 'x' and 'y' use the same elem_dof table. */
1292 void AddMult(const Table &elem_dof, const Vector &x, Vector &y) const;
1293
1294 void Clear()
1295 { UseExternalData(NULL, 0, 0, 0); }
1296
1297 std::size_t MemoryUsage() const { return tdata.MemoryUsage(); }
1298
1299 /// Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
1300 const real_t *Read(bool on_dev = true) const { return tdata.Read(on_dev); }
1301
1302 /// Shortcut for mfem::Read(GetMemory(), TotalSize(), false).
1303 const real_t *HostRead() const { return tdata.HostRead(); }
1304
1305 /// Shortcut for mfem::Write(GetMemory(), TotalSize(), on_dev).
1306 real_t *Write(bool on_dev = true) { return tdata.Write(on_dev); }
1307
1308 /// Shortcut for mfem::Write(GetMemory(), TotalSize(), false).
1309 real_t *HostWrite() { return tdata.HostWrite(); }
1310
1311 /// Shortcut for mfem::ReadWrite(GetMemory(), TotalSize(), on_dev).
1312 real_t *ReadWrite(bool on_dev = true) { return tdata.ReadWrite(on_dev); }
1313
1314 /// Shortcut for mfem::ReadWrite(GetMemory(), TotalSize(), false).
1315 real_t *HostReadWrite() { return tdata.HostReadWrite(); }
1316
1318 {
1319 mfem::Swap(*this, t);
1320 }
1321};
1322
1323/** @brief Compute the LU factorization of a batch of matrices. Calls
1324 BatchedLinAlg::LUFactor.
1325
1326 Factorize n matrices of size (m x m) stored in a dense tensor overwriting it
1327 with the LU factors. The factorization is such that L.U = Piv.A, where A is
1328 the original matrix and Piv is a permutation matrix represented by P.
1329
1330 @param [in, out] Mlu batch of square matrices - dimension m x m x n.
1331 @param [out] P array storing pivot information - dimension m x n.
1332 @param [in] TOL optional fuzzy comparison tolerance. Defaults to 0.0. */
1333void BatchLUFactor(DenseTensor &Mlu, Array<int> &P, const real_t TOL = 0.0);
1334
1335/** @brief Solve batch linear systems. Calls BatchedLinAlg::LUSolve.
1336
1337 Assuming L.U = P.A for n factored matrices (m x m), compute x <- A x, for n
1338 companion vectors.
1339
1340 @param [in] Mlu batch of LU factors for matrix M - dimension m x m x n.
1341 @param [in] P array storing pivot information - dimension m x n.
1342 @param [in, out] X vector storing right-hand side and then solution -
1343 dimension m x n. */
1344void BatchLUSolve(const DenseTensor &Mlu, const Array<int> &P, Vector &X);
1345
1346#ifdef MFEM_USE_LAPACK
1347void BandedSolve(int KL, int KU, DenseMatrix &AB, DenseMatrix &B,
1348 Array<int> &ipiv);
1349void BandedFactorizedSolve(int KL, int KU, DenseMatrix &AB, DenseMatrix &B,
1350 bool transpose, Array<int> &ipiv);
1351#endif
1352
1353// Inline methods
1354
1355inline real_t &DenseMatrix::operator()(int i, int j)
1356{
1357 MFEM_ASSERT(data && i >= 0 && i < height && j >= 0 && j < width, "");
1358 return data[i+j*height];
1359}
1360
1361inline const real_t &DenseMatrix::operator()(int i, int j) const
1362{
1363 MFEM_ASSERT(data && i >= 0 && i < height && j >= 0 && j < width, "");
1364 return data[i+j*height];
1365}
1366
1367} // namespace mfem
1368
1369#endif
Memory< T > & GetMemory()
Return a reference to the Memory object used by the Array.
Definition array.hpp:164
const T * HostRead() const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), false).
Definition array.hpp:414
T * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), on_dev).
Definition array.hpp:426
void SetSize(int nsize)
Change the logical size of the array, keep existing entries.
Definition array.hpp:869
void LoseData()
NULL-ifies the data.
Definition array.hpp:186
void MakeRef(T *data_, int size_, bool own_data=false)
Make this Array a reference to a pointer.
Definition array.hpp:1082
void DeleteAll()
Delete the whole array.
Definition array.hpp:1062
T * Write(bool on_dev=true)
Shortcut for mfem::Write(a.GetMemory(), a.Size(), on_dev).
Definition array.hpp:418
T * GetData()
Returns the data.
Definition array.hpp:159
bool OwnsData() const
Return true if the data will be deleted by the Array.
Definition array.hpp:180
const T * Read(bool on_dev=true) const
Shortcut for mfem::Read(a.GetMemory(), a.Size(), on_dev).
Definition array.hpp:410
T * HostReadWrite()
Shortcut for mfem::ReadWrite(a.GetMemory(), a.Size(), false).
Definition array.hpp:430
std::size_t MemoryUsage() const
Returns the number of bytes allocated for the array including any reserve.
Definition array.hpp:407
void NewMemoryAndSize(const Memory< T > &mem, int s, bool own_mem)
Reset the Array to use the given external Memory mem and size s.
Definition array.hpp:1114
int Capacity() const
Definition array.hpp:207
T * HostWrite()
Shortcut for mfem::Write(a.GetMemory(), a.Size(), false).
Definition array.hpp:422
void UMult(int m, int n, real_t *X) const
void Solve(int m, int n, real_t *X) const override
void RightSolve(int m, int n, real_t *X) const
CholeskyFactors(real_t *data_)
Definition densemat.hpp:803
void USolve(int m, int n, real_t *X) const
void LSolve(int m, int n, real_t *X) const
bool Factor(int m, real_t TOL=0.0) override
Compute the Cholesky factorization of the current matrix.
void GetInverseMatrix(int m, real_t *X) const override
Assuming L.L^t = A factored data of size (m x m), compute X <- A^{-1}.
void LMult(int m, int n, real_t *X) const
real_t Det(int m) const override
const Vector & Eigenvector(int i)
Definition densemat.hpp:934
DenseMatrixEigensystem(DenseMatrix &m)
DenseMatrix & Eigenvectors()
Definition densemat.hpp:932
DenseMatrixGeneralizedEigensystem(DenseMatrix &a, DenseMatrix &b, bool left_eigen_vectors=false, bool right_eigen_vectors=false)
void TestInversion()
Print the numerical conditioning of the inversion: ||A^{-1} A - I||.
int Size() const
Get the size of the inverse matrix.
Definition densemat.hpp:877
DenseMatrixInverse(bool spd_=false)
Default constructor.
Definition densemat.hpp:867
virtual ~DenseMatrixInverse()
Destroys dense inverse matrix.
void Factor()
Factor the current DenseMatrix, *a.
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication with the inverse of dense matrix.
real_t Det() const
Compute the determinant of the original DenseMatrix using the LU factors.
Definition densemat.hpp:905
void GetInverseMatrix(DenseMatrix &Ainv) const
Compute and return the inverse matrix in Ainv.
void SetOperator(const Operator &op) override
Set/update the solver for the given operator.
void Mult(DenseMatrix &X) const
Multiply the inverse matrix by another matrix: X <- A^{-1} X.
Definition densemat.hpp:897
Class for Singular Value Decomposition of a DenseMatrix.
Definition densemat.hpp:983
Vector & Singularvalues()
Return singular values.
DenseMatrix & RightSingularvectors()
Return right singular vectors.
MFEM_DEPRECATED DenseMatrixSVD(DenseMatrix &M, bool left_singular_vectors=false, bool right_singular_vectors=false)
Constructor for the DenseMatrixSVD.
DenseMatrix & LeftSingularvectors()
Return left singular vectors.
real_t Singularvalue(int i)
Return specific singular value.
void Eval(DenseMatrix &M)
Evaluate the SVD.
Data type dense matrix using column-major storage.
Definition densemat.hpp:24
void GetDiag(Vector &d) const
Returns the diagonal of the matrix.
void CopyMNDiag(real_t c, int n, int row_offset, int col_offset)
Copy c on the diagonal of size n to *this at row_offset, col_offset.
void AddMult_a(real_t a, const Vector &x, Vector &y) const
y += a * A.x
Definition densemat.cpp:241
void GetRowl1(Vector &l) const
Returns the l1 norm of the rows of the matrix v_i = sum_j |a_ij|.
void Mult(const real_t *x, real_t *y) const
Matrix vector multiplication.
Definition densemat.cpp:108
void AddMultTranspose_a(real_t a, const Vector &x, Vector &y) const
y += a * A^t x
Definition densemat.cpp:262
void Set(real_t alpha, const real_t *A)
Set the matrix to alpha * A, assuming that A has the same dimensions as the matrix and uses column-ma...
Definition densemat.cpp:580
void TestInversion()
Invert and print the numerical conditioning of the inversion.
void CopyExceptMN(const DenseMatrix &A, int m, int n)
Copy All rows and columns except m and n from A.
void CopyCols(const DenseMatrix &A, int col1, int col2)
Copy columns col1 through col2 from A to *this.
void MultTranspose(const real_t *x, real_t *y) const
Multiply a vector with the transpose matrix.
Definition densemat.cpp:158
void Transpose()
(*this) = (*this)^t
void AddToVector(int offset, Vector &v) const
Add the matrix 'data' to the Vector 'v' at the given 'offset'.
void Threshold(real_t eps)
Replace small entries, abs(a_ij) <= eps, with zero.
const real_t * HostRead() const
Shortcut for mfem::Read(GetMemory(), TotalSize(), false).
Definition densemat.hpp:509
DenseMatrix(DenseMatrix &&)=default
Move constructor.
void CalcEigenvalues(real_t *lambda, real_t *vec) const
void Eigenvalues(Vector &ev)
Compute eigenvalues of A x = ev x where A = *this.
Definition densemat.hpp:300
int TotalSize() const
Total size = width*height.
Definition densemat.hpp:122
DenseMatrix(real_t *d, int h, int w)
Construct a DenseMatrix using an existing data array.
Definition densemat.hpp:55
real_t * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(GetMemory(), TotalSize(), on_dev).
Definition densemat.hpp:518
void RightScaling(const Vector &s)
RightScaling: this = this * diag(s);.
Definition densemat.cpp:325
void Norm2(Vector &v) const
Take the 2-norm of the columns of A and store in v.
Definition densemat.hpp:284
real_t * HostWrite()
Shortcut for mfem::Write(GetMemory(), TotalSize(), false).
Definition densemat.hpp:515
void SetRow(int r, const real_t *row)
void SymmetricScaling(const Vector &s)
SymmetricScaling this = diag(sqrt(s)) * this * diag(sqrt(s))
Definition densemat.cpp:354
MFEM_DEPRECATED void Getl1Diag(Vector &l) const
void GetColumnReference(int c, Vector &col)
Definition densemat.hpp:340
real_t & operator()(int i, int j)
Returns reference to a_{ij}.
real_t InnerProduct(const real_t *x, const real_t *y) const
Compute y^t A x.
Definition densemat.cpp:281
void Eigenvalues(DenseMatrix &b, Vector &ev, DenseMatrix &evect)
Compute generalized eigenvalues of A x = ev B x, where A = *this.
Definition densemat.hpp:317
real_t * Data() const
Returns the matrix data array. Warning: this method casts away constness.
Definition densemat.hpp:131
const Memory< real_t > & GetMemory() const
Definition densemat.hpp:139
void GetSubMatrix(const Array< int > &idx, DenseMatrix &A) const
real_t * GetData() const
Returns the matrix data array. Warning: this method casts away constness.
Definition densemat.hpp:135
void Eigensystem(DenseMatrix &b, Vector &ev, DenseMatrix &evect)
Definition densemat.hpp:322
void AddMult(const Vector &x, Vector &y, const real_t a=1.0) const override
y += a * A.x
Definition densemat.cpp:194
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition densemat.hpp:125
void Reset(real_t *d, int h, int w)
Change the data array and the size of the DenseMatrix.
Definition densemat.hpp:107
void AdjustDofDirection(const Array< int > &dofs)
void SetCol(int c, const real_t *col)
void ClearExternalData()
Definition densemat.hpp:112
void Symmetrize()
(*this) = 1/2 ((*this) + (*this)^t)
void Invert()
Replaces the current matrix with its inverse.
Definition densemat.cpp:674
void AbsMult(const Vector &x, Vector &y) const override
Absolute-value matrix vector multiplication.
Definition densemat.cpp:135
real_t Weight() const
Definition densemat.cpp:553
void GetRowl2(Vector &l) const
Returns the l2norm of the rows of the DenseMatrix.
DenseMatrix & operator+=(const real_t *m)
Definition densemat.cpp:629
void Neg()
(*this) = -(*this)
Definition densemat.cpp:665
real_t operator*(const DenseMatrix &m) const
Matrix inner product: tr(A^t B)
Definition densemat.cpp:143
void CopyMNt(const DenseMatrix &A, int row_offset, int col_offset)
Copy matrix A^t to the location in *this at row_offset, col_offset.
void AddMultTranspose(const Vector &x, Vector &y, const real_t a=1.0) const override
y += a * A^t x
Definition densemat.cpp:217
void Eigenvalues(Vector &ev, DenseMatrix &evect)
Compute eigenvalues and eigenvectors of A x = ev x where A = *this.
Definition densemat.hpp:304
void AbsMultTranspose(const Vector &x, Vector &y) const override
Multiply a vector with the absolute-value transpose matrix.
Definition densemat.cpp:185
void InvRightScaling(const Vector &s)
InvRightScaling: this = this * diag(1./s);.
Definition densemat.cpp:340
const real_t * GetColumn(int col) const
Definition densemat.hpp:338
void Eigensystem(Vector &ev, DenseMatrix &evect)
Compute eigenvalues and eigenvectors of A x = ev x where A = *this.
Definition densemat.hpp:308
real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(GetMemory(), TotalSize(), on_dev).
Definition densemat.hpp:512
real_t * HostReadWrite()
Shortcut for mfem::ReadWrite(GetMemory(), TotalSize(), false).
Definition densemat.hpp:521
void SingularValues(Vector &sv) const
real_t FNorm() const
Compute the Frobenius norm of the matrix.
Definition densemat.hpp:294
void InvLeftScaling(const Vector &s)
InvLeftScaling this = diag(1./s) * this.
Definition densemat.cpp:312
DenseMatrix(const T(&values)[M][N])
Definition densemat.hpp:73
void SetSubMatrix(const Array< int > &idx, const DenseMatrix &A)
Set (*this)(idx[i],idx[j]) = A(i,j)
virtual void PrintT(std::ostream &out=mfem::out, int width_=4) const
Prints the transpose matrix to stream out.
void AddSubMatrix(const Array< int > &idx, const DenseMatrix &A)
(*this)(idx[i],idx[j]) += A(i,j)
void MakeRef(Memory< real_t > &base, int offset, int h, int w)
Make the DenseMatrix to reference the given sub-Memory of base.
Definition densemat.hpp:88
real_t Trace() const
Trace of a square matrix.
Definition densemat.cpp:409
real_t * GetColumn(int col)
Definition densemat.hpp:337
void Diag(real_t c, int n)
Creates n x n diagonal matrix with diagonal elements c.
void SquareRootInverse()
Replaces the current matrix with its square root inverse.
Definition densemat.cpp:784
virtual void PrintMathematica(std::ostream &out=mfem::out) const
DenseMatrix & operator*=(real_t c)
Definition densemat.cpp:655
void Swap(DenseMatrix &other)
const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
Definition densemat.hpp:506
bool OwnsData() const
Return the DenseMatrix data (host pointer) ownership flag.
Definition densemat.hpp:142
void AddMatrix(DenseMatrix &A, int ro, int co)
Perform (ro+i,co+j)+=A(i,j) for 0<=i.
void GetRowSums(Vector &l) const
Returns the row sums of the DenseMatrix.
real_t & Elem(int i, int j) override
Returns reference to a_{ij}.
Definition densemat.cpp:98
void CopyMN(const DenseMatrix &A, int m, int n, int Aro, int Aco)
Copy the m x n submatrix of A at row/col offsets Aro/Aco to *this.
void InvSymmetricScaling(const Vector &s)
InvSymmetricScaling this = diag(sqrt(1./s)) * this * diag(sqrt(1./s))
Definition densemat.cpp:382
int Rank(real_t tol) const
void UseExternalData(real_t *d, int h, int w)
Change the data array and the size of the DenseMatrix.
Definition densemat.hpp:97
void Add(const real_t c, const DenseMatrix &A)
Adds the matrix A multiplied by the number c to the matrix.
Definition densemat.cpp:589
void PrintMatlab(std::ostream &out=mfem::out) const override
Prints operator in Matlab format.
void Clear()
Delete the matrix data array (if owned) and reset the matrix state.
Definition densemat.hpp:115
void LeftScaling(const Vector &s)
LeftScaling this = diag(s) * this.
Definition densemat.cpp:299
DenseMatrix & operator-=(const DenseMatrix &m)
Definition densemat.cpp:642
real_t InnerProduct(const Vector &x, const Vector &y) const
Compute y^t A x.
Definition densemat.hpp:225
std::size_t MemoryUsage() const
Definition densemat.hpp:503
Memory< real_t > & GetMemory()
Definition densemat.hpp:137
real_t CalcSingularvalue(const int i) const
Return the i-th singular value (decreasing order) of NxN matrix, N=1,2,3.
void GradToCurl(DenseMatrix &curl)
DenseMatrix & operator=(const DenseMatrix &)=default
Copy assignment (deep copy).
void Print(std::ostream &out=mfem::out, int width_=4) const override
Prints matrix to stream out.
void GetColumn(int c, Vector &col) const
void GradToVectorCurl2D(DenseMatrix &curl)
MatrixInverse * Inverse() const override
Returns a pointer to the inverse matrix.
Definition densemat.cpp:428
void Eigenvalues(DenseMatrix &b, Vector &ev)
Definition densemat.hpp:313
real_t MaxMaxNorm() const
Compute the norm ||A|| = max_{ij} |A_{ij}|.
Definition densemat.cpp:842
DenseMatrix(const DenseMatrix &)=default
Copy constructor (deep copy).
void Norm2(real_t *v) const
Take the 2-norm of the columns of A and store in v.
Definition densemat.cpp:829
void GetFromVector(int offset, const Vector &v)
Get the matrix 'data' from the Vector 'v' at the given 'offset'.
int CheckFinite() const
Definition densemat.hpp:491
int Size() const
For backward compatibility define Size to be synonym of Width()
Definition densemat.hpp:119
real_t FNorm2() const
Compute the square of the Frobenius norm of the matrix.
Definition densemat.hpp:297
DenseMatrix & operator=(DenseMatrix &&)=default
Move assignment.
void GetRow(int r, Vector &row) const
void CopyRows(const DenseMatrix &A, int row1, int row2)
Copy rows row1 through row2 from A to *this.
real_t Det() const
Definition densemat.cpp:496
void GradToDiv(Vector &div)
void Set(real_t alpha, const DenseMatrix &A)
Set the matrix to alpha * A.
Definition densemat.hpp:251
Rank 3 tensor (array of matrices)
DenseTensor & operator=(DenseTensor &&other)
DenseTensor(int i, int j, int k, MemoryType mt)
DenseMatrix & operator()(int k, DenseMatrix &buff)
real_t * HostWrite()
Shortcut for mfem::Write(GetMemory(), TotalSize(), false).
DenseTensor(const DenseTensor &other)
DenseTensor & operator=(const DenseTensor &other)
const DenseMatrix & operator()(int k, DenseMatrix &buff) const
void SetSize(int i, int j, int k, MemoryType mt_=MemoryType::PRESERVE)
real_t * GetData(int k)
real_t * HostReadWrite()
Shortcut for mfem::ReadWrite(GetMemory(), TotalSize(), false).
real_t & operator()(int i, int j, int k)
Memory< real_t > & GetMemory()
void UseExternalData(real_t *ext_data, int i, int j, int k)
int SizeJ() const
void AddMult(const Table &elem_dof, const Vector &x, Vector &y) const
int TotalSize() const
DenseTensor(real_t *d, int i, int j, int k)
void NewMemoryAndSize(const Memory< real_t > &mem, int i, int j, int k, bool own_mem)
Reset the DenseTensor to use the given external Memory mem and dimensions i, j, and k.
const real_t * Read(bool on_dev=true) const
Shortcut for mfem::Read( GetMemory(), TotalSize(), on_dev).
const real_t & operator()(int i, int j, int k) const
real_t * Write(bool on_dev=true)
Shortcut for mfem::Write(GetMemory(), TotalSize(), on_dev).
std::size_t MemoryUsage() const
const real_t * Data() const
DenseTensor(int i, int j, int k)
real_t * ReadWrite(bool on_dev=true)
Shortcut for mfem::ReadWrite(GetMemory(), TotalSize(), on_dev).
int SizeI() const
const real_t * HostRead() const
Shortcut for mfem::Read(GetMemory(), TotalSize(), false).
DenseTensor(DenseTensor &&other)
const DenseMatrix & operator()(int k) const
int SizeK() const
void Swap(DenseTensor &t)
const real_t * GetData(int k) const
DenseMatrix & operator()(int k)
const Memory< real_t > & GetMemory() const
virtual void GetInverseMatrix(int m, real_t *X) const
Definition densemat.hpp:683
virtual real_t Det(int m) const
Definition densemat.hpp:672
Factors(real_t *data_)
Definition densemat.hpp:664
virtual void Solve(int m, int n, real_t *X) const
Definition densemat.hpp:678
real_t * data
Definition densemat.hpp:660
virtual ~Factors()
Definition densemat.hpp:688
virtual bool Factor(int m, real_t TOL=0.0)
Definition densemat.hpp:666
A class to initialize the size of a Tensor.
Definition dtensor.hpp:57
void LSolve(int m, int n, real_t *X) const
static void SubMult(int m, int n, int r, const real_t *A21, const real_t *X1, real_t *X2)
bool Factor(int m, real_t TOL=0.0) override
Compute the LU factorization of the current matrix.
void Mult(int m, int n, real_t *X) const
void USolve(int m, int n, real_t *X) const
void BlockFactor(int m, int n, real_t *A12, real_t *A21, real_t *A22) const
real_t Det(int m) const override
void BlockForwSolve(int m, int n, int r, const real_t *L21, real_t *B1, real_t *B2) const
void Solve(int m, int n, real_t *X) const override
void RightSolve(int m, int n, real_t *X) const
LUFactors(real_t *data_, int *ipiv_)
Definition densemat.hpp:704
void BlockBackSolve(int m, int n, int r, const real_t *U12, const real_t *X2, real_t *Y1) const
void GetInverseMatrix(int m, real_t *X) const override
Assuming L.U = P.A factored data of size (m x m), compute X <- A^{-1}.
static constexpr int ipiv_base
Definition densemat.hpp:698
Abstract data type for matrix inverse.
Definition matrix.hpp:63
Abstract data type matrix.
Definition matrix.hpp:28
Class used by MFEM to store pointers to host and/or device memory.
Abstract operator.
Definition operator.hpp:27
int width
Dimension of the input / number of columns in the matrix.
Definition operator.hpp:30
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition operator.hpp:68
int height
Dimension of the output / number of rows in the matrix.
Definition operator.hpp:29
virtual void Mult(const Vector &x, Vector &y) const =0
Operator application: y=A(x).
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition operator.hpp:74
virtual void MultTranspose(const Vector &x, Vector &y) const
Action of the transpose operator: y=A^t(x). The default behavior in class Operator is to generate an ...
Definition operator.hpp:102
Table stores the connectivity of elements of TYPE I to elements of TYPE II. For example,...
Definition table.hpp:43
Vector data type.
Definition vector.hpp:82
void SetDataAndSize(real_t *d, int s)
Set the Vector data and size.
Definition vector.hpp:191
int Size() const
Returns the size of the vector.
Definition vector.hpp:234
real_t * GetData() const
Return a pointer to the beginning of the Vector data.
Definition vector.hpp:243
void SetData(real_t *d)
Definition vector.hpp:184
const real_t alpha
Definition ex15.cpp:369
real_t b
Definition lissajous.cpp:42
real_t a
Definition lissajous.cpp:41
mfem::real_t real_t
void CalcOrtho(const DenseMatrix &J, Vector &n)
void AddMult_a_ABt(real_t a, const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
ABt += a * A * B^t.
void mfem_error(const char *msg)
Definition error.cpp:154
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition table.cpp:505
void BatchLUSolve(const DenseTensor &Mlu, const Array< int > &P, Vector &X)
Solve batch linear systems. Calls BatchedLinAlg::LUSolve.
void AddMult_a(real_t alpha, const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a)
Matrix matrix multiplication. A += alpha * B * C.
void CalcAdjugateTranspose(const DenseMatrix &a, DenseMatrix &adjat)
Calculate the transposed adjugate of a matrix (for NxN matrices, N=1,2,3)
void MultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
void MultADBt(const DenseMatrix &A, const Vector &D, const DenseMatrix &B, DenseMatrix &ADBt)
ADBt = A D B^t, where D is diagonal.
void AddMultVVt(const Vector &v, DenseMatrix &VVt)
VVt += v v^t.
OutStream out(std::cout)
Global stream used by the library for standard output. Initially it uses the same std::streambuf as s...
Definition globals.hpp:66
void MultADAt(const DenseMatrix &A, const Vector &D, DenseMatrix &ADAt)
ADAt = A D A^t, where D is diagonal.
void MultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
Multiply a matrix A with the transpose of a matrix B: A*Bt.
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
void AddMult_a_VWt(const real_t a, const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += a * v w^t.
void RAP(const DenseMatrix &A, const DenseMatrix &P, DenseMatrix &RAP)
void AddMult_a_VVt(const real_t a, const Vector &v, DenseMatrix &VVt)
VVt += a * v v^t.
void BatchLUFactor(DenseTensor &Mlu, Array< int > &P, const real_t TOL)
Compute the LU factorization of a batch of matrices. Calls BatchedLinAlg::LUFactor.
void Swap(T &a, T &b)
Swap objects of type T. The operation is performed using the most specialized swap function from the ...
Definition array.hpp:767
void CalcAdjugate(const DenseMatrix &a, DenseMatrix &adja)
void AddMultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += v w^t.
int CheckFinite(const real_t *v, const int n)
Definition vector.hpp:613
void AddMult_a_AtB(real_t a, const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &AtB)
AtB += a * A^t * B.
void MultVVt(const Vector &v, DenseMatrix &vvt)
Make a matrix from a vector V.Vt.
bool LinearSolve(DenseMatrix &A, real_t *X, real_t TOL)
Solves the dense linear system, A * X = B for X
void AddMultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
ABt += A * B^t.
void AddMult_a_AAt(real_t a, const DenseMatrix &A, DenseMatrix &AAt)
AAt += a * A * A^t.
void MultAAt(const DenseMatrix &a, DenseMatrix &aat)
Calculate the matrix A.At.
void CalcInverseTranspose(const DenseMatrix &a, DenseMatrix &inva)
Calculate the inverse transpose of a matrix (for NxN matrices, N=1,2,3)
void AddMultADBt(const DenseMatrix &A, const Vector &D, const DenseMatrix &B, DenseMatrix &ADBt)
ADBt = A D B^t, where D is diagonal.
ComplexDenseMatrix * MultAtB(const ComplexDenseMatrix &A, const ComplexDenseMatrix &B)
Multiply the complex conjugate transpose of a matrix A with a matrix B. A^H*B.
float real_t
Definition config.hpp:46
void AddMult(const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a)
Matrix matrix multiplication. A += B * C.
void AddMultAtB(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &AtB)
AtB += A^t * B.
MemoryType
Memory types supported by MFEM.
void BandedFactorizedSolve(int KL, int KU, DenseMatrix &AB, DenseMatrix &B, bool transpose, Array< int > &ipiv)
void Mult_a_AAt(real_t a, const DenseMatrix &A, DenseMatrix &AAt)
AAt = a * A * A^t.
void Add(const DenseMatrix &A, const DenseMatrix &B, real_t alpha, DenseMatrix &C)
C = A + alpha*B.
void AddMultADAt(const DenseMatrix &A, const Vector &D, DenseMatrix &ADAt)
ADAt += A D A^t, where D is diagonal.
void BandedSolve(int KL, int KU, DenseMatrix &AB, DenseMatrix &B, Array< int > &ipiv)
STL namespace.