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