12#ifndef TADDENSEMATRIX_H
13#define TADDENSEMATRIX_H
33template<
typename dtype>
44 inline int Height()
const {
return height; }
47 inline int NumRows()
const {
return height; }
50 inline int Width()
const {
return width; }
53 inline int NumCols()
const {
return width; }
66 template<
typename idtype>
69 height = m.GetHeight();
71 const int hw = height * width;
74 idtype *mdata = m.
Data();
75 MFEM_ASSERT(mdata,
"invalid source matrix");
78 for (
int i = 0; i < hw; i++)
96 const int hw = height * width;
100 MFEM_ASSERT(mdata,
"invalid source matrix");
101 data =
new dtype[hw];
103 for (
int i = 0; i < hw; i++)
120 MFEM_ASSERT(
s >= 0,
"invalid DenseMatrix size: " <<
s);
126 data =
new dtype[capacity]();
137 MFEM_ASSERT(m >= 0 && n >= 0,
138 "invalid DenseMatrix size: " << m <<
" x " << n);
144 data =
new dtype[capacity]();
154 height = mat.
Width();
156 capacity = height * width;
159 data =
new dtype[capacity];
161 for (
int i = 0; i < height; i++)
163 for (
int j = 0; j < width; j++)
165 (*this)(i, j) = mat(j, i);
181 MFEM_ASSERT(h >= 0 && w >= 0,
182 "invalid DenseMatrix size: " << h <<
" x " << w);
189 const int hw = h * w;
190 if (hw > std::abs(capacity))
197 data =
new dtype[hw]();
202 inline dtype *
Data()
const {
return data; }
204 inline dtype *
GetData()
const {
return data; }
206 inline bool OwnsData()
const {
return (capacity > 0); }
211 MFEM_ASSERT(data && i >= 0 && i < height && j >= 0 && j < width,
"");
212 return data[i + j * height];
217 MFEM_ASSERT(data && i >= 0 && i < height && j >= 0 && j < width,
"");
218 return data[i + j * height];
221 dtype &
Elem(
int i,
int j) {
return (*
this)(i, j); }
223 const dtype &
Elem(
int i,
int j)
const {
return (*
this)(i, j); }
225 void Mult(
const dtype *x, dtype *y)
const
229 for (
int row = 0; row < height; row++)
237 for (
int row = 0; row < height; row++)
239 y[row] = x_col * d_col[row];
242 for (
int col = 1; col < width; col++)
245 for (
int row = 0; row < height; row++)
247 y[row] += x_col * d_col[row];
255 MFEM_ASSERT(height == y.
Size() && width == x.
Size(),
256 "incompatible dimensions");
258 Mult((
const dtype *) x, (dtype *) y);
264 "incompatible dimensions");
266 const int hw = height * width;
268 for (
int i = 0; i < hw; i++)
270 a += data[i] * m.data[i];
279 for (
int col = 0; col < width; col++)
282 for (
int row = 0; row < height; row++)
284 y_col += x[row] * d_col[row];
294 MFEM_ASSERT(height == x.
Size() && width == y.
Size(),
295 "incompatible dimensions");
306 seed = (int) time(0);
310 srand((
unsigned) seed);
312 for (
int i = 0; i < capacity; i++)
324 seed = (int) time(0);
328 srand((
unsigned) seed);
330 for (
int i = 0; i < std::min(height, width); i++)
342 for (
int i = 0; i < N; i++)
344 data[i] = (dtype) 0.0;
346 for (
int i = 0; i < n; i++)
348 data[i * (n + 1)] = c;
352 template<
typename itype>
358 for (i = 0; i < N; i++)
362 for (i = 0; i < n; i++)
364 data[i * (n + 1)] = (dtype) diag[i];
376 for (i = 0; i <
Height(); i++)
377 for (j = i + 1; j <
Width(); j++)
380 (*this)(i, j) = (*
this)(j, i);
391 template<
typename itype>
396 for (
int i = 0; i <
Height(); i++)
397 for (
int j = 0; j <
Width(); j++)
399 (*this)(i, j) = (dtype) A(j, i);
409 mfem_error(
"DenseMatrix::Symmetrize() : not a square matrix!");
413 for (
int i = 0; i <
Height(); i++)
414 for (
int j = 0; j < i; j++)
416 dtype
a = 0.5 * ((*this)(i, j) + (*
this)(j, i));
417 (*this)(j, i) = (*
this)(i, j) =
a;
423 for (
int i = 0; i <
Height(); i++)
426 for (
int j = 0; j <
Width(); j++)
429 (*this)(i, j) = (dtype) 0.0;
436template<
typename dtype>
441 if (
a.Width() >
a.Height() ||
a.Width() < 1 ||
a.Height() > 3)
445 if (
a.Width() != adja.
Height() ||
a.Height() != adja.
Width())
451 if (
a.Width() <
a.Height())
453 const dtype *d =
a.Data();
454 dtype *ad = adja.
Data();
469 e = d[0] * d[0] + d[1] * d[1] + d[2] * d[2];
470 g = d[3] * d[3] + d[4] * d[4] + d[5] * d[5];
471 f = d[0] * d[3] + d[1] * d[4] + d[2] * d[5];
473 ad[0] = d[0] * g - d[3] *
f;
474 ad[1] = d[3] * e - d[0] *
f;
475 ad[2] = d[1] * g - d[4] *
f;
476 ad[3] = d[4] * e - d[1] *
f;
477 ad[4] = d[2] * g - d[5] *
f;
478 ad[5] = d[5] * e - d[2] *
f;
485 adja(0, 0) = (dtype) 1.0;
487 else if (
a.Width() == 2)
489 adja(0, 0) =
a(1, 1);
490 adja(0, 1) = -
a(0, 1);
491 adja(1, 0) = -
a(1, 0);
492 adja(1, 1) =
a(0, 0);
496 adja(0, 0) =
a(1, 1) *
a(2, 2) -
a(1, 2) *
a(2, 1);
497 adja(0, 1) =
a(0, 2) *
a(2, 1) -
a(0, 1) *
a(2, 2);
498 adja(0, 2) =
a(0, 1) *
a(1, 2) -
a(0, 2) *
a(1, 1);
500 adja(1, 0) =
a(1, 2) *
a(2, 0) -
a(1, 0) *
a(2, 2);
501 adja(1, 1) =
a(0, 0) *
a(2, 2) -
a(0, 2) *
a(2, 0);
502 adja(1, 2) =
a(0, 2) *
a(1, 0) -
a(0, 0) *
a(1, 2);
504 adja(2, 0) =
a(1, 0) *
a(2, 1) -
a(1, 1) *
a(2, 0);
505 adja(2, 1) =
a(0, 1) *
a(2, 0) -
a(0, 0) *
a(2, 1);
506 adja(2, 2) =
a(0, 0) *
a(1, 1) -
a(0, 1) *
a(1, 0);
Data type dense matrix using column-major storage.
real_t * Data() const
Returns the matrix data array.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
Templated dense matrix data type.
TAutoDiffDenseMatrix(int m, int n)
Creates rectangular matrix of size m x n.
dtype * GetData() const
Returns the matrix data array.
void SetSize(int h, int w)
Change the size of the DenseMatrix to h x w.
dtype & Elem(int i, int j)
void RandomizeDiag(int seed)
TAutoDiffDenseMatrix(const TAutoDiffDenseMatrix< idtype > &m)
Copy constructor.
int Height() const
Get the height (size of output) of the Operator. Synonym with NumRows().
void Diag(itype *diag, int n)
Creates n x n diagonal matrix with diagonal given by diag.
TAutoDiffDenseMatrix(const DenseMatrix &m)
Copy constructor using standard DenseMatrix.
int NumCols() const
Get the number of columns (size of input) of the Operator. Synonym with Width().
dtype * Data() const
Returns the matrix data array.
void SetSize(int s)
Change the size of the DenseMatrix to s x s.
void Symmetrize()
(*this) = 1/2 ((*this) + (*this)^t)
int NumRows() const
Get the number of rows (size of output) of the Operator. Synonym with Height().
dtype operator*(const TAutoDiffDenseMatrix< dtype > &m) const
const dtype & Elem(int i, int j) const
void MultTranspose(const dtype *x, dtype *y) const
TAutoDiffDenseMatrix(const TAutoDiffDenseMatrix< dtype > &mat, char ch)
void Diag(dtype c, int n)
Creates n x n diagonal matrix with diagonal elements c.
const dtype & operator()(int i, int j) const
int Width() const
Get the width (size of input) of the Operator. Synonym with NumCols().
void Mult(const dtype *x, dtype *y) const
TAutoDiffDenseMatrix(int s)
Creates square matrix of size s.
void Transpose()
(*this) = (*this)^t
void Transpose(const TAutoDiffDenseMatrix< itype > &A)
(*this) = A^t
void Mult(const TAutoDiffVector< dtype > &x, TAutoDiffVector< dtype > &y) const
void MultTranspose(const TAutoDiffVector< dtype > &x, TAutoDiffVector< dtype > &y) const
dtype & operator()(int i, int j)
Returns reference to a_{ij}.
Templated vector data type.
int Size() const
Returns the size of the vector.
void mfem_error(const char *msg)
real_t rand_real()
Generate a random real_t number in the interval [0,1) using rand().
void CalcAdjugate(const DenseMatrix &a, DenseMatrix &adja)
std::function< real_t(const Vector &)> f(real_t mass_coeff)