MFEM  v3.3
Finite element discretization library
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Pages
densemat.hpp
Go to the documentation of this file.
1 // Copyright (c) 2010, Lawrence Livermore National Security, LLC. Produced at
2 // the Lawrence Livermore National Laboratory. LLNL-CODE-443211. All Rights
3 // reserved. See file COPYRIGHT for details.
4 //
5 // This file is part of the MFEM library. For more information and source code
6 // availability see http://mfem.org.
7 //
8 // MFEM is free software; you can redistribute it and/or modify it under the
9 // terms of the GNU Lesser General Public License (as published by the Free
10 // Software Foundation) version 2.1 dated February 1999.
11 
12 #ifndef MFEM_DENSEMAT
13 #define MFEM_DENSEMAT
14 
15 #include "../config/config.hpp"
16 #include "matrix.hpp"
17 
18 namespace mfem
19 {
20 
21 /// Data type dense matrix using column-major storage
22 class DenseMatrix : public Matrix
23 {
24  friend class DenseTensor;
25  friend class DenseMatrixInverse;
26 
27 private:
28  double *data;
29  int capacity; // zero or negative capacity means we do not own the data.
30 
31  void Eigensystem(Vector &ev, DenseMatrix *evect = NULL);
32 
33 public:
34  /** Default constructor for DenseMatrix.
35  Sets data = NULL and height = width = 0. */
36  DenseMatrix();
37 
38  /// Copy constructor
39  DenseMatrix(const DenseMatrix &);
40 
41  /// Creates square matrix of size s.
42  explicit DenseMatrix(int s);
43 
44  /// Creates rectangular matrix of size m x n.
45  DenseMatrix(int m, int n);
46 
47  /// Creates rectangular matrix equal to the transpose of mat.
48  DenseMatrix(const DenseMatrix &mat, char ch);
49 
50  /** Construct a DenseMatrix using existing data array. The DenseMatrix does
51  not assume ownership of the data array, i.e. it will not delete the
52  array. */
53  DenseMatrix(double *d, int h, int w) : Matrix(h, w)
54  { data = d; capacity = -h*w; }
55 
56  /// Change the data array and the size of the DenseMatrix.
57  /** The DenseMatrix does not assume ownership of the data array, i.e. it will
58  not delete the data array @a d. This method should not be used with
59  DenseMatrix that owns its current data array. */
60  void UseExternalData(double *d, int h, int w)
61  { data = d; height = h; width = w; capacity = -h*w; }
62 
63  /// Change the data array and the size of the DenseMatrix.
64  /** The DenseMatrix does not assume ownership of the data array, i.e. it will
65  not delete the new array @a d. This method will delete the current data
66  array, if owned. */
67  void Reset(double *d, int h, int w)
68  { if (OwnsData()) { delete [] data; } UseExternalData(d, h, w); }
69 
70  /** Clear the data array and the dimensions of the DenseMatrix. This method
71  should not be used with DenseMatrix that owns its current data array. */
72  void ClearExternalData() { data = NULL; height = width = 0; capacity = 0; }
73 
74  /// Delete the matrix data array (if owned) and reset the matrix state.
75  void Clear()
76  { if (OwnsData()) { delete [] data; } ClearExternalData(); }
77 
78  /// For backward compatibility define Size to be synonym of Width()
79  int Size() const { return Width(); }
80 
81  /// Change the size of the DenseMatrix to s x s.
82  void SetSize(int s) { SetSize(s, s); }
83 
84  /// Change the size of the DenseMatrix to h x w.
85  void SetSize(int h, int w);
86 
87  /// Returns the matrix data array.
88  inline double *Data() const { return data; }
89  /// Returns the matrix data array.
90  inline double *GetData() const { return data; }
91 
92  inline bool OwnsData() const { return (capacity > 0); }
93 
94  /// Returns reference to a_{ij}.
95  inline double &operator()(int i, int j);
96 
97  /// Returns constant reference to a_{ij}.
98  inline const double &operator()(int i, int j) const;
99 
100  /// Matrix inner product: tr(A^t B)
101  double operator*(const DenseMatrix &m) const;
102 
103  /// Trace of a square matrix
104  double Trace() const;
105 
106  /// Returns reference to a_{ij}.
107  virtual double &Elem(int i, int j);
108 
109  /// Returns constant reference to a_{ij}.
110  virtual const double &Elem(int i, int j) const;
111 
112  /// Matrix vector multiplication.
113  void Mult(const double *x, double *y) const;
114 
115  /// Matrix vector multiplication.
116  virtual void Mult(const Vector &x, Vector &y) const;
117 
118  /// Multiply a vector with the transpose matrix.
119  void MultTranspose(const double *x, double *y) const;
120 
121  /// Multiply a vector with the transpose matrix.
122  virtual void MultTranspose(const Vector &x, Vector &y) const;
123 
124  /// y += A.x
125  void AddMult(const Vector &x, Vector &y) const;
126 
127  /// y += a * A.x
128  void AddMult_a(double a, const Vector &x, Vector &y) const;
129 
130  // y += a * A^t x
131  void AddMultTranspose_a(double a, const Vector &x, Vector &y) const;
132 
133  /// Compute y^t A x
134  double InnerProduct(const double *x, const double *y) const;
135 
136  /// LeftScaling this = diag(s) * this
137  void LeftScaling(const Vector & s);
138  /// InvLeftScaling this = diag(1./s) * this
139  void InvLeftScaling(const Vector & s);
140  /// RightScaling: this = this * diag(s);
141  void RightScaling(const Vector & s);
142  /// InvRightScaling: this = this * diag(1./s);
143  void InvRightScaling(const Vector & s);
144  /// SymmetricScaling this = diag(sqrt(s)) * this * diag(sqrt(s))
145  void SymmetricScaling(const Vector & s);
146  /// InvSymmetricScaling this = diag(sqrt(1./s)) * this * diag(sqrt(1./s))
147  void InvSymmetricScaling(const Vector & s);
148 
149  /// Compute y^t A x
150  double InnerProduct(const Vector &x, const Vector &y) const
151  { return InnerProduct((const double *)x, (const double *)y); }
152 
153  /// Returns a pointer to the inverse matrix.
154  virtual MatrixInverse *Inverse() const;
155 
156  /// Replaces the current matrix with its inverse
157  void Invert();
158 
159  /// Calculates the determinant of the matrix (for 2x2 or 3x3 matrices)
160  double Det() const;
161 
162  double Weight() const;
163 
164  /// Adds the matrix A multiplied by the number c to the matrix
165  void Add(const double c, const DenseMatrix &A);
166 
167  /// Sets the matrix elements equal to constant c
168  DenseMatrix &operator=(double c);
169 
170  /// Copy the matrix entries from the given array
171  DenseMatrix &operator=(const double *d);
172 
173  /// Sets the matrix size and elements equal to those of m
174  DenseMatrix &operator=(const DenseMatrix &m);
175 
177 
179 
180  DenseMatrix &operator*=(double c);
181 
182  /// (*this) = -(*this)
183  void Neg();
184 
185  /// Take the 2-norm of the columns of A and store in v
186  void Norm2(double *v) const;
187 
188  /// Compute the norm ||A|| = max_{ij} |A_{ij}|
189  double MaxMaxNorm() const;
190 
191  /// Compute the Frobenius norm of the matrix
192  double FNorm() const;
193 
194  void Eigenvalues(Vector &ev)
195  { Eigensystem(ev); }
196 
197  void Eigenvalues(Vector &ev, DenseMatrix &evect)
198  { Eigensystem(ev, &evect); }
199 
200  void Eigensystem(Vector &ev, DenseMatrix &evect)
201  { Eigensystem(ev, &evect); }
202 
203  void SingularValues(Vector &sv) const;
204  int Rank(double tol) const;
205 
206  /// Return the i-th singular value (decreasing order) of NxN matrix, N=1,2,3.
207  double CalcSingularvalue(const int i) const;
208 
209  /** Return the eigenvalues (in increasing order) and eigenvectors of a
210  2x2 or 3x3 symmetric matrix. */
211  void CalcEigenvalues(double *lambda, double *vec) const;
212 
213  void GetRow(int r, Vector &row);
214  void GetColumn(int c, Vector &col) const;
215  double *GetColumn(int col) { return data + col*height; }
216 
217  void GetColumnReference(int c, Vector &col)
218  { col.SetDataAndSize(data + c * height, height); }
219 
220  void SetRow(int r, const Vector &row);
221  void SetCol(int c, const Vector &col);
222 
223  /// Set all entries of a row to the specified value.
224  void SetRow(int row, double value);
225  /// Set all entries of a column to the specified value.
226  void SetCol(int col, double value);
227 
228  /// Returns the diagonal of the matrix
229  void GetDiag(Vector &d) const;
230  /// Returns the l1 norm of the rows of the matrix v_i = sum_j |a_ij|
231  void Getl1Diag(Vector &l) const;
232  /// Compute the row sums of the DenseMatrix
233  void GetRowSums(Vector &l) const;
234 
235  /// Creates n x n diagonal matrix with diagonal elements c
236  void Diag(double c, int n);
237  /// Creates n x n diagonal matrix with diagonal given by diag
238  void Diag(double *diag, int n);
239 
240  /// (*this) = (*this)^t
241  void Transpose();
242  /// (*this) = A^t
243  void Transpose(DenseMatrix &A);
244  /// (*this) = 1/2 ((*this) + (*this)^t)
245  void Symmetrize();
246 
247  void Lump();
248 
249  /** Given a DShape matrix (from a scalar FE), stored in *this, returns the
250  CurlShape matrix. If *this is a N by D matrix, then curl is a D*N by
251  D*(D-1)/2 matrix. The size of curl must be set outside. The dimension D
252  can be either 2 or 3. */
253  void GradToCurl(DenseMatrix &curl);
254  /** Given a DShape matrix (from a scalar FE), stored in *this,
255  returns the DivShape vector. If *this is a N by dim matrix,
256  then div is a dim*N vector. The size of div must be set
257  outside. */
258  void GradToDiv(Vector &div);
259 
260  /// Copy rows row1 through row2 from A to *this
261  void CopyRows(const DenseMatrix &A, int row1, int row2);
262  /// Copy columns col1 through col2 from A to *this
263  void CopyCols(const DenseMatrix &A, int col1, int col2);
264  /// Copy the m x n submatrix of A at row/col offsets Aro/Aco to *this
265  void CopyMN(const DenseMatrix &A, int m, int n, int Aro, int Aco);
266  /// Copy matrix A to the location in *this at row_offset, col_offset
267  void CopyMN(const DenseMatrix &A, int row_offset, int col_offset);
268  /// Copy matrix A^t to the location in *this at row_offset, col_offset
269  void CopyMNt(const DenseMatrix &A, int row_offset, int col_offset);
270  /** Copy the m x n submatrix of A at row/col offsets Aro/Aco to *this at
271  row_offset, col_offset */
272  void CopyMN(const DenseMatrix &A, int m, int n, int Aro, int Aco,
273  int row_offset, int col_offset);
274  /// Copy c on the diagonal of size n to *this at row_offset, col_offset
275  void CopyMNDiag(double c, int n, int row_offset, int col_offset);
276  /// Copy diag on the diagonal of size n to *this at row_offset, col_offset
277  void CopyMNDiag(double *diag, int n, int row_offset, int col_offset);
278 
279  /// Perform (ro+i,co+j)+=A(i,j) for 0<=i<A.Height, 0<=j<A.Width
280  void AddMatrix(DenseMatrix &A, int ro, int co);
281  /// Perform (ro+i,co+j)+=a*A(i,j) for 0<=i<A.Height, 0<=j<A.Width
282  void AddMatrix(double a, DenseMatrix &A, int ro, int co);
283 
284  /// Add the matrix 'data' to the Vector 'v' at the given 'offset'
285  void AddToVector(int offset, Vector &v) const;
286  /// Get the matrix 'data' from the Vector 'v' at the given 'offset'
287  void GetFromVector(int offset, const Vector &v);
288  /** If (dofs[i] < 0 and dofs[j] >= 0) or (dofs[i] >= 0 and dofs[j] < 0)
289  then (*this)(i,j) = -(*this)(i,j). */
290  void AdjustDofDirection(Array<int> &dofs);
291 
292  /// Replace small entries, abs(a_ij) <= eps, with zero.
293  void Threshold(double eps);
294 
295  /** Count the number of entries in the matrix for which isfinite
296  is false, i.e. the entry is a NaN or +/-Inf. */
297  int CheckFinite() const { return mfem::CheckFinite(data, height*width); }
298 
299  /// Prints matrix to stream out.
300  virtual void Print(std::ostream &out = std::cout, int width_ = 4) const;
301  virtual void PrintMatlab(std::ostream &out = std::cout) const;
302  /// Prints the transpose matrix to stream out.
303  virtual void PrintT(std::ostream &out = std::cout, int width_ = 4) const;
304 
305  /// Invert and print the numerical conditioning of the inversion.
306  void TestInversion();
307 
308  /// Destroys dense matrix.
309  virtual ~DenseMatrix();
310 };
311 
312 /// C = A + alpha*B
313 void Add(const DenseMatrix &A, const DenseMatrix &B,
314  double alpha, DenseMatrix &C);
315 
316 /// C = alpha*A + beta*B
317 void Add(double alpha, const DenseMatrix &A,
318  double beta, const DenseMatrix &B, DenseMatrix &C);
319 
320 /// Matrix matrix multiplication. A = B * C.
321 void Mult(const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a);
322 
323 /// Matrix matrix multiplication. A += B * C.
324 void AddMult(const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a);
325 
326 /** Calculate the adjugate of a matrix (for NxN matrices, N=1,2,3) or the matrix
327  adj(A^t.A).A^t for rectangular matrices (2x1, 3x1, or 3x2). This operation
328  is well defined even when the matrix is not full rank. */
329 void CalcAdjugate(const DenseMatrix &a, DenseMatrix &adja);
330 
331 /// Calculate the transposed adjugate of a matrix (for NxN matrices, N=1,2,3)
332 void CalcAdjugateTranspose(const DenseMatrix &a, DenseMatrix &adjat);
333 
334 /** Calculate the inverse of a matrix (for NxN matrices, N=1,2,3) or the
335  left inverse (A^t.A)^{-1}.A^t (for 2x1, 3x1, or 3x2 matrices) */
336 void CalcInverse(const DenseMatrix &a, DenseMatrix &inva);
337 
338 /// Calculate the inverse transpose of a matrix (for NxN matrices, N=1,2,3)
339 void CalcInverseTranspose(const DenseMatrix &a, DenseMatrix &inva);
340 
341 /** For a given Nx(N-1) (N=2,3) matrix J, compute a vector n such that
342  n_k = (-1)^{k+1} det(J_k), k=1,..,N, where J_k is the matrix J with the
343  k-th row removed. Note: J^t.n = 0, det([n|J])=|n|^2=det(J^t.J). */
344 void CalcOrtho(const DenseMatrix &J, Vector &n);
345 
346 /// Calculate the matrix A.At
347 void MultAAt(const DenseMatrix &a, DenseMatrix &aat);
348 
349 /// ADAt = A D A^t, where D is diagonal
350 void MultADAt(const DenseMatrix &A, const Vector &D, DenseMatrix &ADAt);
351 
352 /// ADAt += A D A^t, where D is diagonal
353 void AddMultADAt(const DenseMatrix &A, const Vector &D, DenseMatrix &ADAt);
354 
355 /// Multiply a matrix A with the transpose of a matrix B: A*Bt
356 void MultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt);
357 
358 /// ADBt = A D B^t, where D is diagonal
359 void MultADBt(const DenseMatrix &A, const Vector &D,
360  const DenseMatrix &B, DenseMatrix &ADBt);
361 
362 /// ABt += A * B^t
363 void AddMultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt);
364 
365 /// ADBt = A D B^t, where D is diagonal
366 void AddMultADBt(const DenseMatrix &A, const Vector &D,
367  const DenseMatrix &B, DenseMatrix &ADBt);
368 
369 /// ABt += a * A * B^t
370 void AddMult_a_ABt(double a, const DenseMatrix &A, const DenseMatrix &B,
371  DenseMatrix &ABt);
372 
373 /// Multiply the transpose of a matrix A with a matrix B: At*B
374 void MultAtB(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &AtB);
375 
376 /// AAt += a * A * A^t
377 void AddMult_a_AAt(double a, const DenseMatrix &A, DenseMatrix &AAt);
378 
379 /// AAt = a * A * A^t
380 void Mult_a_AAt(double a, const DenseMatrix &A, DenseMatrix &AAt);
381 
382 /// Make a matrix from a vector V.Vt
383 void MultVVt(const Vector &v, DenseMatrix &vvt);
384 
385 void MultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt);
386 
387 /// VWt += v w^t
388 void AddMultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt);
389 
390 /// VWt += a * v w^t
391 void AddMult_a_VWt(const double a, const Vector &v, const Vector &w,
392  DenseMatrix &VWt);
393 
394 /// VVt += a * v v^t
395 void AddMult_a_VVt(const double a, const Vector &v, DenseMatrix &VVt);
396 
397 
398 /** Class that can compute LU factorization of external data and perform various
399  operations with the factored data. */
401 {
402 public:
403  double *data;
404  int *ipiv;
405 #ifdef MFEM_USE_LAPACK
406  static const int ipiv_base = 1;
407 #else
408  static const int ipiv_base = 0;
409 #endif
410 
411  /** With this constructor, the (public) data and ipiv members should be set
412  explicitly before calling class methods. */
413  LUFactors() { }
414 
415  LUFactors(double *data_, int *ipiv_) : data(data_), ipiv(ipiv_) { }
416 
417  /** Factorize the current data of size (m x m) overwriting it with the LU
418  factors. The factorization is such that L.U = P.A, where A is the
419  original matrix and P is a permutation matrix represented by ipiv. */
420  void Factor(int m);
421 
422  /** Assuming L.U = P.A factored data of size (m x m), compute X <- A X,
423  for a matrix X of size (m x n). */
424  void Mult(int m, int n, double *X) const;
425 
426  /** Assuming L.U = P.A factored data of size (m x m), compute
427  X <- L^{-1} P X, for a matrix X of size (m x n). */
428  void LSolve(int m, int n, double *X) const;
429 
430  /** Assuming L.U = P.A factored data of size (m x m), compute
431  X <- U^{-1} X, for a matrix X of size (m x n). */
432  void USolve(int m, int n, double *X) const;
433 
434  /** Assuming L.U = P.A factored data of size (m x m), compute X <- A^{-1} X,
435  for a matrix X of size (m x n). */
436  void Solve(int m, int n, double *X) const;
437 
438  /// Assuming L.U = P.A factored data of size (m x m), compute X <- A^{-1}.
439  void GetInverseMatrix(int m, double *X) const;
440 
441  /** Given an (n x m) matrix A21, compute X2 <- X2 - A21 X1, for matrices X1,
442  and X2 of size (m x r) and (n x r), respectively. */
443  static void SubMult(int m, int n, int r, const double *A21,
444  const double *X1, double *X2);
445 
446  /** Assuming P.A = L.U factored data of size (m x m), compute the 2x2 block
447  decomposition:
448  | P 0 | | A A12 | = | L 0 | | U U12 |
449  | 0 I | | A21 A22 | | L21 I | | 0 S22 |
450  where A12, A21, and A22 are matrices of size (m x n), (n x m), and
451  (n x n), respectively. The blocks are overwritten as follows:
452  A12 <- U12 = L^{-1} P A12
453  A21 <- L21 = A21 U^{-1}
454  A22 <- S22 = A22 - L21 U12.
455  The block S22 is the Schur complement. */
456  void BlockFactor(int m, int n, double *A12, double *A21, double *A22) const;
457 
458  /** Given BlockFactor()'d data, perform the forward block solve for the
459  linear system:
460  | A A12 | | X1 | = | B1 |
461  | A21 A22 | | X2 | | B2 |
462  written in the factored form:
463  | L 0 | | U U12 | | X1 | = | P 0 | | B1 |
464  | L21 I | | 0 S22 | | X2 | | 0 I | | B2 |.
465  The resulting blocks Y1, Y2 solve the system:
466  | L 0 | | Y1 | = | P 0 | | B1 |
467  | L21 I | | Y2 | | 0 I | | B2 |
468  The blocks are overwritten as follows:
469  B1 <- Y1 = L^{-1} P B1
470  B2 <- Y2 = B2 - L21 Y1 = B2 - A21 A^{-1} B1
471  The blocks B1/Y1 and B2/Y2 are of size (m x r) and (n x r), respectively.
472  The Schur complement system is given by: S22 X2 = Y2. */
473  void BlockForwSolve(int m, int n, int r, const double *L21,
474  double *B1, double *B2) const;
475 
476  /** Given BlockFactor()'d data, perform the backward block solve in
477  | U U12 | | X1 | = | Y1 |
478  | 0 S22 | | X2 | | Y2 |.
479  The input is the solution block X2 and the block Y1 resulting from
480  BlockForwSolve(). The result block X1 overwrites input block Y1:
481  Y1 <- X1 = U^{-1} (Y1 - U12 X2). */
482  void BlockBackSolve(int m, int n, int r, const double *U12,
483  const double *X2, double *Y1) const;
484 };
485 
486 
487 /** Data type for inverse of square dense matrix.
488  Stores LU factors */
490 {
491 private:
492  const DenseMatrix *a;
493  LUFactors lu;
494 
495 public:
496  /// Default constructor.
497  DenseMatrixInverse() : a(NULL), lu(NULL, NULL) { }
498 
499  /** Creates square dense matrix. Computes factorization of mat
500  and stores LU factors. */
501  DenseMatrixInverse(const DenseMatrix &mat);
502 
503  /// Same as above but does not factorize the matrix.
504  DenseMatrixInverse(const DenseMatrix *mat);
505 
506  /// Get the size of the inverse matrix
507  int Size() const { return Width(); }
508 
509  /// Factor the current DenseMatrix, *a
510  void Factor();
511 
512  /// Factor a new DenseMatrix of the same size
513  void Factor(const DenseMatrix &mat);
514 
515  virtual void SetOperator(const Operator &op);
516 
517  /// Matrix vector multiplication with the inverse of dense matrix.
518  virtual void Mult(const Vector &x, Vector &y) const;
519 
520  /// Multiply the inverse matrix by another matrix: X = A^{-1} B.
521  void Mult(const DenseMatrix &B, DenseMatrix &X) const;
522 
523  /// Compute and return the inverse matrix in Ainv.
524  void GetInverseMatrix(DenseMatrix &Ainv) const
525  {
526  Ainv.SetSize(width);
527  lu.GetInverseMatrix(width, Ainv.Data());
528  }
529 
530  /// Print the numerical conditioning of the inversion: ||A^{-1} A - I||.
531  void TestInversion();
532 
533  /// Destroys dense inverse matrix.
534  virtual ~DenseMatrixInverse();
535 };
536 
537 
539 {
540  DenseMatrix &mat;
541  Vector EVal;
542  DenseMatrix EVect;
543  Vector ev;
544  int n;
545 
546 #ifdef MFEM_USE_LAPACK
547  double *work;
548  char jobz, uplo;
549  int lwork, info;
550 #endif
551 
552 public:
553 
555  void Eval();
556  Vector &Eigenvalues() { return EVal; }
557  DenseMatrix &Eigenvectors() { return EVect; }
558  double Eigenvalue(int i) { return EVal(i); }
559  const Vector &Eigenvector(int i)
560  {
561  ev.SetData(EVect.Data() + i * EVect.Height());
562  return ev;
563  }
565 };
566 
567 
569 {
570  Vector sv;
571  int m, n;
572 
573 #ifdef MFEM_USE_LAPACK
574  double *work;
575  char jobu, jobvt;
576  int lwork, info;
577 #endif
578 
579  void Init();
580 public:
581 
583  DenseMatrixSVD(int h, int w);
584  void Eval(DenseMatrix &M);
585  Vector &Singularvalues() { return sv; }
586  double Singularvalue(int i) { return sv(i); }
587  ~DenseMatrixSVD();
588 };
589 
590 class Table;
591 
592 /// Rank 3 tensor (array of matrices)
594 {
595 private:
596  DenseMatrix Mk;
597  double *tdata;
598  int nk;
599  bool own_data;
600 
601 public:
603  {
604  nk = 0;
605  tdata = NULL;
606  own_data = true;
607  }
608 
609  DenseTensor(int i, int j, int k)
610  : Mk(NULL, i, j)
611  {
612  nk = k;
613  tdata = new double[i*j*k];
614  own_data = true;
615  }
616 
617  int SizeI() const { return Mk.Height(); }
618  int SizeJ() const { return Mk.Width(); }
619  int SizeK() const { return nk; }
620 
621  void SetSize(int i, int j, int k)
622  {
623  if (own_data) { delete [] tdata; }
624  Mk.UseExternalData(NULL, i, j);
625  nk = k;
626  tdata = new double[i*j*k];
627  own_data = true;
628  }
629 
630  void UseExternalData(double *ext_data, int i, int j, int k)
631  {
632  if (own_data) { delete [] tdata; }
633  Mk.UseExternalData(NULL, i, j);
634  nk = k;
635  tdata = ext_data;
636  own_data = false;
637  }
638 
639  DenseMatrix &operator()(int k) { Mk.data = GetData(k); return Mk; }
640  const DenseMatrix &operator()(int k) const
641  { return const_cast<DenseTensor&>(*this)(k); }
642 
643  double &operator()(int i, int j, int k)
644  { return tdata[i+SizeI()*(j+SizeJ()*k)]; }
645  const double &operator()(int i, int j, int k) const
646  { return tdata[i+SizeI()*(j+SizeJ()*k)]; }
647 
648  double *GetData(int k) { return tdata+k*Mk.Height()*Mk.Width(); }
649 
650  double *Data() { return tdata; }
651 
652  /** Matrix-vector product from unassembled element matrices, assuming both
653  'x' and 'y' use the same elem_dof table. */
654  void AddMult(const Table &elem_dof, const Vector &x, Vector &y) const;
655 
656  void Clear()
657  { UseExternalData(NULL, 0, 0, 0); }
658 
660  {
661  if (own_data) { delete [] tdata; }
662  }
663 };
664 
665 
666 // Inline methods
667 
668 inline double &DenseMatrix::operator()(int i, int j)
669 {
670  MFEM_ASSERT(data && i >= 0 && i < height && j >= 0 && j < width, "");
671  return data[i+j*height];
672 }
673 
674 inline const double &DenseMatrix::operator()(int i, int j) const
675 {
676  MFEM_ASSERT(data && i >= 0 && i < height && j >= 0 && j < width, "");
677  return data[i+j*height];
678 }
679 
680 } // namespace mfem
681 
682 #endif
virtual void PrintT(std::ostream &out=std::cout, int width_=4) const
Prints the transpose matrix to stream out.
Definition: densemat.cpp:2757
int Size() const
For backward compatibility define Size to be synonym of Width()
Definition: densemat.hpp:79
void Symmetrize()
(*this) = 1/2 ((*this) + (*this)^t)
Definition: densemat.cpp:2325
void MultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
Multiply a matrix A with the transpose of a matrix B: A*Bt.
Definition: densemat.cpp:3216
void SymmetricScaling(const Vector &s)
SymmetricScaling this = diag(sqrt(s)) * this * diag(sqrt(s))
Definition: densemat.cpp:341
int CheckFinite(const double *v, const int n)
Definition: vector.hpp:286
void AddMultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += v w^t.
Definition: densemat.cpp:3618
DenseMatrix & operator*=(double c)
Definition: densemat.cpp:537
void GetDiag(Vector &d) const
Returns the diagonal of the matrix.
Definition: densemat.cpp:2217
void UseExternalData(double *ext_data, int i, int j, int k)
Definition: densemat.hpp:630
void MultVWt(const Vector &v, const Vector &w, DenseMatrix &VWt)
Definition: densemat.cpp:3596
DenseMatrix & operator+=(DenseMatrix &m)
Definition: densemat.cpp:512
void InvRightScaling(const Vector &s)
InvRightScaling: this = this * diag(1./s);.
Definition: densemat.cpp:326
const DenseMatrix & operator()(int k) const
Definition: densemat.hpp:640
void Eigenvalues(Vector &ev)
Definition: densemat.hpp:194
void SingularValues(Vector &sv) const
Definition: densemat.cpp:984
DenseMatrix & operator()(int k)
Definition: densemat.hpp:639
double Det() const
Calculates the determinant of the matrix (for 2x2 or 3x3 matrices)
Definition: densemat.cpp:416
void Mult(const Table &A, const Table &B, Table &C)
C = A * B (as boolean matrices)
Definition: table.cpp:468
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Definition: operator.hpp:42
int SizeK() const
Definition: densemat.hpp:619
void BlockFactor(int m, int n, double *A12, double *A21, double *A22) const
Definition: densemat.cpp:3914
void BlockBackSolve(int m, int n, int r, const double *U12, const double *X2, double *Y1) const
Definition: densemat.cpp:3950
double InnerProduct(const double *x, const double *y) const
Compute y^t A x.
Definition: densemat.cpp:271
void CalcAdjugate(const DenseMatrix &a, DenseMatrix &adja)
Definition: densemat.cpp:2902
void AddMult(const Table &elem_dof, const Vector &x, Vector &y) const
Definition: densemat.cpp:4161
void TestInversion()
Invert and print the numerical conditioning of the inversion.
Definition: densemat.cpp:2783
Data type dense matrix using column-major storage.
Definition: densemat.hpp:22
void CopyRows(const DenseMatrix &A, int row1, int row2)
Copy rows row1 through row2 from A to *this.
Definition: densemat.cpp:2436
void SetSize(int i, int j, int k)
Definition: densemat.hpp:621
void Eval(DenseMatrix &M)
Definition: densemat.cpp:4130
Abstract data type for matrix inverse.
Definition: matrix.hpp:58
void AddMult_a_ABt(double a, const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
ABt += a * A * B^t.
Definition: densemat.cpp:3432
void GetInverseMatrix(DenseMatrix &Ainv) const
Compute and return the inverse matrix in Ainv.
Definition: densemat.hpp:524
void Factor(int m)
Definition: densemat.cpp:3686
void Factor()
Factor the current DenseMatrix, *a.
Definition: densemat.cpp:3979
void GetInverseMatrix(int m, double *X) const
Assuming L.U = P.A factored data of size (m x m), compute X &lt;- A^{-1}.
Definition: densemat.cpp:3832
double * GetData() const
Returns the matrix data array.
Definition: densemat.hpp:90
void CalcOrtho(const DenseMatrix &J, Vector &n)
Definition: densemat.cpp:3132
DenseMatrix & operator=(double c)
Sets the matrix elements equal to constant c.
Definition: densemat.cpp:479
void Mult_a_AAt(double a, const DenseMatrix &A, DenseMatrix &AAt)
AAt = a * A * A^t.
Definition: densemat.cpp:3573
static void SubMult(int m, int n, int r, const double *A21, const double *X1, double *X2)
Definition: densemat.cpp:3897
const Vector & Eigenvector(int i)
Definition: densemat.hpp:559
virtual void Mult(const Vector &x, Vector &y) const
Matrix vector multiplication with the inverse of dense matrix.
Definition: densemat.cpp:4012
const double & operator()(int i, int j, int k) const
Definition: densemat.hpp:645
void Add(const DenseMatrix &A, const DenseMatrix &B, double alpha, DenseMatrix &C)
C = A + alpha*B.
Definition: densemat.cpp:2807
double & operator()(int i, int j)
Returns reference to a_{ij}.
Definition: densemat.hpp:668
double Weight() const
Definition: densemat.cpp:443
void USolve(int m, int n, double *X) const
Definition: densemat.cpp:3799
double FNorm() const
Compute the Frobenius norm of the matrix.
Definition: densemat.cpp:707
void MultTranspose(const double *x, double *y) const
Multiply a vector with the transpose matrix.
Definition: densemat.cpp:193
void CalcAdjugateTranspose(const DenseMatrix &a, DenseMatrix &adjat)
Calculate the transposed adjugate of a matrix (for NxN matrices, N=1,2,3)
Definition: densemat.cpp:2974
double & operator()(int i, int j, int k)
Definition: densemat.hpp:643
void AddMult(const DenseMatrix &b, const DenseMatrix &c, DenseMatrix &a)
Matrix matrix multiplication. A += B * C.
Definition: densemat.cpp:2870
double operator*(const DenseMatrix &m) const
Matrix inner product: tr(A^t B)
Definition: densemat.cpp:178
double Singularvalue(int i)
Definition: densemat.hpp:586
void Reset(double *d, int h, int w)
Change the data array and the size of the DenseMatrix.
Definition: densemat.hpp:67
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
Definition: operator.hpp:36
void Add(const double c, const DenseMatrix &A)
Adds the matrix A multiplied by the number c to the matrix.
Definition: densemat.cpp:470
void AddMult_a_VWt(const double a, const Vector &v, const Vector &w, DenseMatrix &VWt)
VWt += a * v w^t.
Definition: densemat.cpp:3639
void InvSymmetricScaling(const Vector &s)
InvSymmetricScaling this = diag(sqrt(1./s)) * this * diag(sqrt(1./s))
Definition: densemat.cpp:367
void BlockForwSolve(int m, int n, int r, const double *L21, double *B1, double *B2) const
Definition: densemat.cpp:3941
DenseMatrixSVD(DenseMatrix &M)
Definition: densemat.cpp:4096
Abstract data type matrix.
Definition: matrix.hpp:27
void Norm2(double *v) const
Take the 2-norm of the columns of A and store in v.
Definition: densemat.cpp:676
void MultADBt(const DenseMatrix &A, const Vector &D, const DenseMatrix &B, DenseMatrix &ADBt)
ADBt = A D B^t, where D is diagonal.
Definition: densemat.cpp:3299
void Invert()
Replaces the current matrix with its inverse.
Definition: densemat.cpp:566
virtual ~DenseMatrixInverse()
Destroys dense inverse matrix.
Definition: densemat.cpp:4035
void LSolve(int m, int n, double *X) const
Definition: densemat.cpp:3774
void LeftScaling(const Vector &s)
LeftScaling this = diag(s) * this.
Definition: densemat.cpp:289
void CopyMNDiag(double c, int n, int row_offset, int col_offset)
Copy c on the diagonal of size n to *this at row_offset, col_offset.
Definition: densemat.cpp:2526
double * GetData(int k)
Definition: densemat.hpp:648
virtual void PrintMatlab(std::ostream &out=std::cout) const
Definition: densemat.cpp:2738
void AddMult_a_VVt(const double a, const Vector &v, DenseMatrix &VVt)
VVt += a * v v^t.
Definition: densemat.cpp:3661
void Neg()
(*this) = -(*this)
Definition: densemat.cpp:547
virtual void Print(std::ostream &out=std::cout, int width_=4) const
Prints matrix to stream out.
Definition: densemat.cpp:2712
virtual void SetOperator(const Operator &op)
Set/update the solver for the given operator.
Definition: densemat.cpp:4005
void Solve(int m, int n, double *X) const
Definition: densemat.cpp:3818
void SetRow(int r, const Vector &row)
Definition: densemat.cpp:2682
void Getl1Diag(Vector &l) const
Returns the l1 norm of the rows of the matrix v_i = sum_j |a_ij|.
Definition: densemat.cpp:2231
void AddToVector(int offset, Vector &v) const
Add the matrix &#39;data&#39; to the Vector &#39;v&#39; at the given &#39;offset&#39;.
Definition: densemat.cpp:2617
void SetData(double *d)
Definition: vector.hpp:80
DenseMatrix & Eigenvectors()
Definition: densemat.hpp:557
void GetColumn(int c, Vector &col) const
Definition: densemat.cpp:2203
void AddMult(const Vector &x, Vector &y) const
y += A.x
Definition: densemat.cpp:216
void Threshold(double eps)
Replace small entries, abs(a_ij) &lt;= eps, with zero.
Definition: densemat.cpp:2698
int SizeI() const
Definition: densemat.hpp:617
void CalcInverse(const DenseMatrix &a, DenseMatrix &inva)
Definition: densemat.cpp:3010
void TestInversion()
Print the numerical conditioning of the inversion: ||A^{-1} A - I||.
Definition: densemat.cpp:4024
double MaxMaxNorm() const
Compute the norm ||A|| = max_{ij} |A_{ij}|.
Definition: densemat.cpp:689
double * Data() const
Returns the matrix data array.
Definition: densemat.hpp:88
void Transpose()
(*this) = (*this)^t
Definition: densemat.cpp:2292
void MultVVt(const Vector &v, DenseMatrix &vvt)
Make a matrix from a vector V.Vt.
Definition: densemat.cpp:3587
double Trace() const
Trace of a square matrix.
Definition: densemat.cpp:392
void AddMultABt(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &ABt)
ABt += A * B^t.
Definition: densemat.cpp:3339
DenseTensor(int i, int j, int k)
Definition: densemat.hpp:609
void ClearExternalData()
Definition: densemat.hpp:72
int CheckFinite() const
Definition: densemat.hpp:297
void MultAAt(const DenseMatrix &a, DenseMatrix &aat)
Calculate the matrix A.At.
Definition: densemat.cpp:3158
void GetColumnReference(int c, Vector &col)
Definition: densemat.hpp:217
void AddMatrix(DenseMatrix &A, int ro, int co)
Perform (ro+i,co+j)+=A(i,j) for 0&lt;=i&lt;A.Height, 0&lt;=j&lt;A.Width.
Definition: densemat.cpp:2557
DenseMatrix(double *d, int h, int w)
Definition: densemat.hpp:53
void Clear()
Delete the matrix data array (if owned) and reset the matrix state.
Definition: densemat.hpp:75
void CalcInverseTranspose(const DenseMatrix &a, DenseMatrix &inva)
Calculate the inverse transpose of a matrix (for NxN matrices, N=1,2,3)
Definition: densemat.cpp:3093
void SetDataAndSize(double *d, int s)
Set the Vector data and size.
Definition: vector.hpp:87
DenseMatrix & operator-=(DenseMatrix &m)
Definition: densemat.cpp:526
void MultADAt(const DenseMatrix &A, const Vector &D, DenseMatrix &ADAt)
ADAt = A D A^t, where D is diagonal.
Definition: densemat.cpp:3200
int height
Dimension of the output / number of rows in the matrix.
Definition: operator.hpp:24
void CopyCols(const DenseMatrix &A, int col1, int col2)
Copy columns col1 through col2 from A to *this.
Definition: densemat.cpp:2447
int SizeJ() const
Definition: densemat.hpp:618
virtual MatrixInverse * Inverse() const
Returns a pointer to the inverse matrix.
Definition: densemat.cpp:411
double * GetColumn(int col)
Definition: densemat.hpp:215
bool OwnsData() const
Definition: densemat.hpp:92
void AddMultADBt(const DenseMatrix &A, const Vector &D, const DenseMatrix &B, DenseMatrix &ADBt)
ADBt = A D B^t, where D is diagonal.
Definition: densemat.cpp:3396
virtual ~DenseMatrix()
Destroys dense matrix.
Definition: densemat.cpp:2797
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.
Definition: densemat.cpp:2483
void Diag(double c, int n)
Creates n x n diagonal matrix with diagonal elements c.
Definition: densemat.cpp:2262
void Mult(int m, int n, double *X) const
Definition: densemat.cpp:3738
static const int ipiv_base
Definition: densemat.hpp:406
void GradToCurl(DenseMatrix &curl)
Definition: densemat.cpp:2356
DenseMatrixInverse()
Default constructor.
Definition: densemat.hpp:497
double CalcSingularvalue(const int i) const
Return the i-th singular value (decreasing order) of NxN matrix, N=1,2,3.
Definition: densemat.cpp:1650
void GetRowSums(Vector &l) const
Compute the row sums of the DenseMatrix.
Definition: densemat.cpp:2248
void GetRow(int r, Vector &row)
Definition: densemat.cpp:2187
void CalcEigenvalues(double *lambda, double *vec) const
Definition: densemat.cpp:1947
void Eigenvalues(Vector &ev, DenseMatrix &evect)
Definition: densemat.hpp:197
DenseMatrixEigensystem(DenseMatrix &m)
Definition: densemat.cpp:4042
int Rank(double tol) const
Definition: densemat.cpp:1023
const double alpha
Definition: ex15.cpp:337
LUFactors(double *data_, int *ipiv_)
Definition: densemat.hpp:415
void AddMult_a(double a, const Vector &x, Vector &y) const
y += a * A.x
Definition: densemat.cpp:234
void RightScaling(const Vector &s)
RightScaling: this = this * diag(s);.
Definition: densemat.cpp:311
void MultAtB(const DenseMatrix &A, const DenseMatrix &B, DenseMatrix &AtB)
Multiply the transpose of a matrix A with a matrix B: At*B.
Definition: densemat.cpp:3491
Vector data type.
Definition: vector.hpp:36
void Mult(const double *x, double *y) const
Matrix vector multiplication.
Definition: densemat.cpp:142
void AddMultTranspose_a(double a, const Vector &x, Vector &y) const
Definition: densemat.cpp:252
void AddMultADAt(const DenseMatrix &A, const Vector &D, DenseMatrix &ADAt)
ADAt += A D A^t, where D is diagonal.
Definition: densemat.cpp:3172
void GetFromVector(int offset, const Vector &v)
Get the matrix &#39;data&#39; from the Vector &#39;v&#39; at the given &#39;offset&#39;.
Definition: densemat.cpp:2628
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.
Definition: densemat.cpp:2458
double * Data()
Definition: densemat.hpp:650
void InvLeftScaling(const Vector &s)
InvLeftScaling this = diag(1./s) * this.
Definition: densemat.cpp:300
void UseExternalData(double *d, int h, int w)
Change the data array and the size of the DenseMatrix.
Definition: densemat.hpp:60
void SetCol(int c, const Vector &col)
Definition: densemat.cpp:2690
void Eigensystem(Vector &ev, DenseMatrix &evect)
Definition: densemat.hpp:200
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
Definition: densemat.hpp:82
Abstract operator.
Definition: operator.hpp:21
int Size() const
Get the size of the inverse matrix.
Definition: densemat.hpp:507
Vector & Singularvalues()
Definition: densemat.hpp:585
Rank 3 tensor (array of matrices)
Definition: densemat.hpp:593
double InnerProduct(const Vector &x, const Vector &y) const
Compute y^t A x.
Definition: densemat.hpp:150
virtual double & Elem(int i, int j)
Returns reference to a_{ij}.
Definition: densemat.cpp:132
void AdjustDofDirection(Array< int > &dofs)
Definition: densemat.cpp:2639
void GradToDiv(Vector &div)
Definition: densemat.cpp:2415
void AddMult_a_AAt(double a, const DenseMatrix &A, DenseMatrix &AAt)
AAt += a * A * A^t.
Definition: densemat.cpp:3548
int width
Dimension of the input / number of columns in the matrix.
Definition: operator.hpp:25
double * data
Definition: densemat.hpp:403