14 #ifndef UTL_MATRIX_ND_H
15 #define UTL_MATRIX_ND_H
42 explicit matrix3d(std::istream& is, std::streamsize max = 10)
45 size_t n0 = 0, n1 = 0, n2 = 0;
53 for (
size_t k = 0; k < n2; k++) {
55 for (
size_t i = 0; i < n0; i++) {
57 for (
size_t j = 0; j < n1; j++)
58 is >> this->
elem[n0*(n1*k + j) + i];
74 void resize(
size_t n_1,
size_t n_2,
size_t n_3,
bool forceClear =
false)
76 this->
redim(n_1,n_2,n_3,1,forceClear);
85 memcpy(this->
n,A.
n,
sizeof(A.
n));
94 CHECK_INDEX(
"matrix3d::operator(): First index " ,i1,this->
n[0]);
95 CHECK_INDEX(
"matrix3d::operator(): Second index ",i2,this->
n[1]);
96 CHECK_INDEX(
"matrix3d::operator(): Third index " ,i3,this->
n[2]);
97 return this->
elem[i1-1 + this->
n[0]*((i2-1) + this->
n[1]*(i3-1))];
104 CHECK_INDEX(
"matrix3d::operator(): First index " ,i1,this->
n[0]);
105 CHECK_INDEX(
"matrix3d::operator(): Second index ",i2,this->
n[1]);
106 CHECK_INDEX(
"matrix3d::operator(): Third index " ,i3,this->
n[2]);
107 return this->
elem[i1-1 + this->
n[0]*((i2-1) + this->
n[1]*(i3-1))];
113 CHECK_INDEX(
"matrix3d::getColumn: Second index ",i2,this->
n[1]);
114 CHECK_INDEX(
"matrix3d::getColumn: Third index " ,i3,this->
n[2]);
115 if (this->
n[1] < 2 && this->
n[2] < 2)
return this->
elem;
117 memcpy(col.
ptr(),this->ptr(i2-1+this->n[1]*(i3-1)),col.
size()*
sizeof(T));
122 void fillColumn(
size_t i2,
size_t i3,
const std::vector<T>& data)
124 CHECK_INDEX(
"matrix3d::fillColumn: Second index ",i2,this->
n[1]);
125 CHECK_INDEX(
"matrix3d::fillColumn: Third index " ,i3,this->
n[2]);
126 size_t ndata = this->
n[0] > data.size() ? data.size() : this->
n[0];
127 memcpy(this->
ptr(i2-1+this->
n[1]*(i3-1)),data.data(),ndata*
sizeof(T));
133 CHECK_INDEX(
"matrix3d::trace(): Index ",i1,this->
n[0]);
134 return this->
elem.sum(i1-1,this->
n[0]*(this->
n[1]+1));
161 bool transA =
false,
bool addTo =
false);
179 bool transA,
size_t&
M,
size_t& N,
size_t&
K)
184 if (
K == B.
n[0])
return true;
186 std::cerr <<
"matrix3d::multiply: Incompatible matrices: A("
187 << A.
rows() <<
','<< A.
cols() <<
"), B("
188 << B.
n[0] <<
','<< B.
n[1] <<
','<< B.
n[2] <<
")\n"
189 <<
" when computing C = "
190 << (transA ?
"A^t":
"A") <<
" * B"<< std::endl;
191 ABORT_ON_INDEX_CHECK;
198 size_t&
M,
size_t& N,
size_t&
K)
202 M =
K > 0 ? A.size() /
K : 0;
203 if (
M*
K == A.size() && !A.
empty())
return true;
205 std::cerr <<
"matrix3d::multiply: Incompatible matrices: A(r*c="<< A.size()
206 <<
"), B("<< B.
n[0] <<
","<< B.
n[1] <<
","<< B.
n[2] <<
")\n"
207 <<
" when computing C = A * B"<< std::endl;
208 ABORT_ON_INDEX_CHECK;
216 if (n1 != this->
n[0] || n2 != this->
n[1]) this->
elem.clear();
234 matrix4d(
size_t n_1,
size_t n_2,
size_t n_3,
size_t n_4)
250 void resize(
size_t n_1,
size_t n_2,
size_t n_3,
size_t n_4,
251 bool forceClear =
false)
253 this->
redim(n_1,n_2,n_3,n_4,forceClear);
262 memcpy(this->
n,A.
n,
sizeof(A.
n));
271 CHECK_INDEX(
"matrix4d::operator(): First index " ,i1,this->
n[0]);
272 CHECK_INDEX(
"matrix4d::operator(): Second index ",i2,this->
n[1]);
273 CHECK_INDEX(
"matrix4d::operator(): Third index " ,i3,this->
n[2]);
274 CHECK_INDEX(
"matrix4d::operator(): Fourth index ",i4,this->
n[3]);
275 return this->
elem[i1-1 + this->
n[0]*((i2-1) + this->
n[1]*((i3-1) + this->
n[2]*(i4-1)))];
280 const T&
operator()(
size_t i1,
size_t i2,
size_t i3,
size_t i4)
const
282 CHECK_INDEX(
"matrix4d::operator(): First index " ,i1,this->
n[0]);
283 CHECK_INDEX(
"matrix4d::operator(): Second index ",i2,this->
n[1]);
284 CHECK_INDEX(
"matrix4d::operator(): Third index " ,i3,this->
n[2]);
285 CHECK_INDEX(
"matrix4d::operator(): Fourth index ",i4,this->
n[3]);
286 return this->
elem[i1-1 + this->
n[0]*((i2-1) + this->
n[1]*((i3-1) + this->
n[2]*(i4-1)))];
308 CHECK_INDEX(
"matrix4d::getColumn: Second index ",i2,this->
n[1]);
309 CHECK_INDEX(
"matrix4d::getColumn: Third index " ,i3,this->
n[2]);
310 CHECK_INDEX(
"matrix4d::getColumn: Fourth index ",i4,this->
n[3]);
311 if (this->
n[1] < 2 && this->
n[2] < 2 && this->
n[3] < 2)
return this->
elem;
314 this->ptr(i2-1 + this->n[1]*((i3-1) + this->n[2]*(i4-1))),
315 col.
size()*
sizeof(T));
320 void fillColumn(
size_t i2,
size_t i3,
size_t i4,
const std::vector<T>& data)
322 CHECK_INDEX(
"matrix4d::fillColumn: Second index ",i2,this->
n[1]);
323 CHECK_INDEX(
"matrix4d::fillColumn: Third index " ,i3,this->
n[2]);
324 CHECK_INDEX(
"matrix4d::fillColumn: Fourth index ",i4,this->
n[3]);
325 size_t ndata = this->
n[0] > data.size() ? data.size() : this->
n[0];
326 memcpy(this->
ptr(i2-1 + this->
n[1]*((i3-1)) + this->
n[2]*(i4-1)),
327 data.data(),ndata*
sizeof(T));
334 if (n1 != this->
n[0] || n2 != this->
n[1] || n3 != this->
n[2])
347 const matrix3d<float>& B,
348 bool transA,
bool addTo)
351 if (!this->compatible(A,B,transA,
M,N,
K))
return false;
352 if (!addTo) this->resize(
M,B.n[1],B.n[2]);
354 cblas_sgemm(CblasColMajor,
355 transA ? CblasTrans : CblasNoTrans, CblasNoTrans,
367 const matrix3d<double>& B,
368 bool transA,
bool addTo)
371 if (!this->compatible(A,B,transA,
M,N,
K))
return false;
372 if (!addTo) this->resize(
M,B.n[1],B.n[2]);
374 cblas_dgemm(CblasColMajor,
375 transA ? CblasTrans : CblasNoTrans, CblasNoTrans,
387 const matrix3d<float>& B,
bool addTo)
390 if (!this->compatible(A,B,
M,N,
K))
return false;
391 if (!addTo) this->resize(
M,B.n[1],B.n[2]);
393 cblas_sgemm(CblasColMajor, CblasNoTrans, CblasNoTrans,
405 const matrix3d<double>& B,
bool addTo)
408 if (!this->compatible(A,B,
M,N,
K))
return false;
409 if (!addTo) this->resize(
M,B.n[1],B.n[2]);
411 cblas_dgemm(CblasColMajor, CblasNoTrans, CblasNoTrans,
426 template<
class T>
inline
428 bool transA,
bool addTo)
431 if (!this->compatible(A,B,transA,
M,N,
K))
return false;
432 if (!addTo) this->resize(
M,B.
n[1],B.
n[2],
true);
434 for (
size_t i = 1; i <= this->n[0]; i++)
435 for (
size_t j = 1; j <= this->n[1]; j++)
436 for (
size_t k = 1; k <=
K; k++)
437 for (
size_t l = 1; l <= this->n[2]; l++)
439 this->operator()(i,j,l) += A(k,i)*B(k,j,l);
441 this->operator()(i,j,l) += A(i,k)*B(k,j,l);
446 template<
class T>
inline
451 if (!this->compatible(A,B,
M,N,
K))
return false;
452 if (!addTo) this->resize(
M,B.
n[1],B.
n[2],
true);
454 for (
size_t i = 1; i <= this->n[0]; i++)
455 for (
size_t j = 1; j <= this->n[1]; j++)
456 for (
size_t k = 1; k <=
K; k++)
457 for (
size_t l = 1; l <= this->n[2]; l++)
458 this->
operator()(i,j,l) += A[i-1+
M*(k-1)]*B(k,j,l);
471 return s <<
" (empty)"<< std::endl;
473 s <<
" Dimension: "<< A.
dim(1) <<
" "<< A.
dim(2) <<
" "<< A.
dim(3);
475 const T* Aptr = A.
ptr();
476 for (
size_t k = 0; k < A.
dim(3); k++, Aptr += B.
size())
479 if (k == 0) s <<
"\n";
480 s <<
"i3="<< k+1 <<
":"<< B;
493 return s <<
" (empty)"<< std::endl;
495 s <<
" Dimension: "<< A.
dim(1) <<
" "<< A.
dim(2)
496 <<
" "<< A.
dim(3) <<
" "<< A.
dim(4);
498 const T* Aptr = A.
ptr();
499 for (
size_t k = 0; k < A.
dim(3); k++)
500 for (
size_t l = 0; l < A.
dim(4); l++, Aptr += B.
size())
503 if (k == 0 && l == 0) s <<
"\n";
504 s <<
"i3="<< k+1 <<
", i4="<< l+1 <<
":"<< B;
static SystemMatrix * K
Pointer to coefficient matrix A.
Definition: EigSolver.C:91
static SystemMatrix * M
Pointer to coefficient matrix B.
Definition: EigSolver.C:92
virtual bool empty() const
Checks if the matrix is empty.
Definition: SystemMatrix.h:249
Three-dimensional rectangular matrix with some algebraic operations.
Definition: matrixnd.h:30
matrix3d(size_t n_1, size_t n_2, size_t n_3)
Constructor creating a matrix of dimension .
Definition: matrixnd.h:38
matrix3d(vector< T > &vec)
Constructor using an external vector for matrix element storage.
Definition: matrixnd.h:35
matrix3d< T > & operator=(const matrix3d< T > &A)
Assignment operator.
Definition: matrixnd.h:80
const T & operator()(size_t i1, size_t i2, size_t i3) const
Index-1 based element access.
Definition: matrixnd.h:102
bool compatible(const std::vector< T > &A, const matrix3d< T > &B, size_t &M, size_t &N, size_t &K)
Check dimension compatibility for matrix-matrix multiplication, when the matrix A is represented by a...
Definition: matrixnd.h:197
void resize(size_t n_1, size_t n_2, size_t n_3, bool forceClear=false)
Resize the matrix to dimension .
Definition: matrixnd.h:74
T trace(size_t i1) const
Return the trace of the i1'th sub-matrix.
Definition: matrixnd.h:131
matrix3d< T > & operator-=(const matrix3d< T > &X)
Subtract the given matrix X from *this.
Definition: matrixnd.h:140
virtual void clearIfNrowChanged(size_t n1, size_t n2, size_t)
Clears the content if any of the first two dimensions changed.
Definition: matrixnd.h:214
matrix3d< T > & multiply(T c)
Multiplication of this matrix by a scalar c.
Definition: matrixnd.h:148
void fillColumn(size_t i2, size_t i3, const std::vector< T > &data)
Fill a column of the matrix.
Definition: matrixnd.h:122
virtual ~matrix3d()
Empty destructor.
Definition: matrixnd.h:65
matrix3d()
Constructor creating an empty matrix.
Definition: matrixnd.h:33
matrix3d(std::istream &is, std::streamsize max=10)
Constructor to read a matrix from a stream.
Definition: matrixnd.h:42
matrix3d< T > & add(const matrix3d< T > &X, T alfa=T(1))
Add the given matrix X scaled by alfa to *this.
Definition: matrixnd.h:142
matrix3d< T > & operator+=(const matrix3d< T > &X)
Add the given matrix X to *this.
Definition: matrixnd.h:138
T & operator()(size_t i1, size_t i2, size_t i3)
Index-1 based element access.
Definition: matrixnd.h:92
bool compatible(const matrix< T > &A, const matrix3d< T > &B, bool transA, size_t &M, size_t &N, size_t &K)
Check dimension compatibility for matrix-matrix multiplication.
Definition: matrixnd.h:178
bool multiplyMat(const std::vector< T > &A, const matrix3d< T > &B, bool addTo=false)
Matrix-matrix multiplication.
Definition: matrixnd.h:447
matrix3d(const matrix3d< T > &mat)
Copy constructor.
Definition: matrixnd.h:40
bool multiply(const matrix< T > &A, const matrix3d< T > &B, bool transA=false, bool addTo=false)
Matrix-matrix multiplication.
Definition: matrixnd.h:427
vector< T > getColumn(size_t i2, size_t i3) const
Extract a column from the matrix.
Definition: matrixnd.h:111
Four-dimensional rectangular matrix with some algebraic operations.
Definition: matrixnd.h:226
virtual void clearIfNrowChanged(size_t n1, size_t n2, size_t n3)
Clears the content if any of the first three dimensions changed.
Definition: matrixnd.h:332
matrix4d(size_t n_1, size_t n_2, size_t n_3, size_t n_4)
Constructor creating a matrix of dimension .
Definition: matrixnd.h:234
matrix4d< T > & operator+=(const matrix4d< T > &X)
Add the given matrix X to *this.
Definition: matrixnd.h:290
matrix4d< T > & multiply(T c)
Multiplication of this matrix by a scalar c.
Definition: matrixnd.h:300
matrix4d< T > & operator=(const matrix4d< T > &A)
Assignment operator.
Definition: matrixnd.h:257
T & operator()(size_t i1, size_t i2, size_t i3, size_t i4)
Index-1 based element access.
Definition: matrixnd.h:269
void fillColumn(size_t i2, size_t i3, size_t i4, const std::vector< T > &data)
Fill a column of the matrix.
Definition: matrixnd.h:320
void resize(size_t n_1, size_t n_2, size_t n_3, size_t n_4, bool forceClear=false)
Resize the matrix to dimension .
Definition: matrixnd.h:250
matrix4d()
Constructor creating an empty matrix.
Definition: matrixnd.h:229
virtual ~matrix4d()
Empty destructor.
Definition: matrixnd.h:240
vector< T > getColumn(size_t i2, size_t i3, size_t i4) const
Extract a column from the matrix.
Definition: matrixnd.h:306
matrix4d(vector< T > &vec)
Constructor using an external vector for matrix element storage.
Definition: matrixnd.h:231
matrix4d(const matrix4d< T > &mat)
Copy constructor.
Definition: matrixnd.h:237
matrix4d< T > & add(const matrix4d< T > &X, T alfa=T(1))
Add the given matrix X scaled by alfa to *this.
Definition: matrixnd.h:294
const T & operator()(size_t i1, size_t i2, size_t i3, size_t i4) const
Index-1 based element access.
Definition: matrixnd.h:280
matrix4d< T > & operator-=(const matrix4d< T > &X)
Subtract the given matrix X from *this.
Definition: matrixnd.h:292
Common base class for multi-dimensional (2D and 3D) matrices.
Definition: matrix.h:308
size_t n[4]
Dimension of the matrix.
Definition: matrix.h:440
size_t dim(short int d=1) const
Query dimensions.
Definition: matrix.h:376
matrixBase< T > & add(const matrixBase< T > &A, const T &alfa)
Add the given matrix A scaled by alfa to *this.
Definition: matrix.h:1584
vector< T > & elem
Actual matrix elements, stored column by column.
Definition: matrix.h:441
size_t size() const
Query total matrix size.
Definition: matrix.h:378
T * ptr(size_t c=0)
Access through pointer.
Definition: matrix.h:392
bool empty() const
Check if the matrix is empty.
Definition: matrix.h:380
void redim(size_t n_1, size_t n_2, size_t n_3, size_t n_4, bool forceClear)
Resize the matrix to dimension .
Definition: matrix.h:338
matrixBase< T > & multiply(const T &c)
Multiplication of this matrix by a scalar c.
Definition: matrix.h:1595
Two-dimensional rectangular matrix with some algebraic operations.
Definition: matrix.h:456
size_t cols() const
Query number of matrix columns.
Definition: matrix.h:560
size_t rows() const
Query number of matrix rows.
Definition: matrix.h:558
void fill(const std::vector< T > &v, size_t n, size_t m=0)
Fill the matrix with vector data.
Definition: matrix.h:628
A vector class with some added algebraic operations.
Definition: matrix.h:64
size_t size() const
Size of the vector.
Definition: matrix.h:88
T * ptr()
Access through pointer.
Definition: matrix.h:83
Simple template classes for dense rectangular matrices and vectors.
General utility classes and functions.
Definition: SIMoptions.h:22
std::ostream & operator<<(std::ostream &s, const vector< T > &X)
Print the vector X to the stream s.
Definition: matrix.h:1783