53 #include<Eigen/Eigenvalues>
61#define _LOOP_MATRIX(r,c) for(Index c=0; c<cols(); c++) for(Index r=0; r<rows(); r++)
65 MatrixXXd::resize(nr,nc);
71 if ( nsize < this->
values.size() ) {
72 this->
values.resize(nsize);
73 }
else if ( nsize > this->
values.size() ) {
74 this->
values.assign(nsize, 0.);
97 if (
rows == this->rows() && columns == this->
cols() ) {
116 for (
Index i = 1; i <= ii; i++ ) {
117 for (
Index j = 1; j <= jj; j++ ) {
118 this->
at(i, j) = old.
at(i, j);
130 for (
auto col : ini) {
132 if ( ret.
rows() != (
Index) col.size() ) {
133 OOFEM_ERROR(
"Initializer list has inconsistent column sizes.");
137 for(
const double& x: col) ret(r++,c)=x;
144FloatMatrix FloatMatrix :: fromCols ( std :: initializer_list< FloatArray >mat )
146 FloatMatrix ret( mat.begin()->giveSize(), (
int ) mat.size() );
148 for (
auto col : mat ) {
150 if ( ret.
rows() != (
Index) col.size() ) {
151 OOFEM_ERROR(
"Columns have inconsistent column sizes.");
154 for(
Index r=0; r<col.size(); r++) ret(r,c)=col(r);
165 OOFEM_ERROR(
"matrix error on rows : %d < 0", (
int)i);
168 OOFEM_ERROR(
"matrix error on columns : %d < 0", (
int)j);
183 std::size_t ii, jj, size = src.
rows();
186 if ( size != loc.
size() ) {
187 OOFEM_ERROR(
"dimensions of 'src' and 'loc' mismatch");
195 for ( std::size_t i = 1; i <= size; i++ ) {
196 if ( ( ii = loc.
at(i) ) ) {
197 for ( std::size_t j = 1; j <= size; j++ ) {
198 if ( ( jj = loc.
at(j) ) ) {
199 this->
at(ii, jj) += src.
at(i, j);
206#ifdef _USE_EIGEN___BROKEN
209 Eigen::Map<const Eigen::ArrayXi> rr(rowind.
givePointer(),rowind.
size());
210 Eigen::Map<const Eigen::ArrayXi> cc(rowind.
givePointer(),rowind.
size());
212 Eigen::VectorXi R=Eigen::VectorXi::LinSpaced(rr.size(), 0, rr.size()-1).array();
213 Eigen::VectorXi C=Eigen::VectorXi::LinSpaced(cc.size(), 0, cc.size()-1).array();
215 (*this)(rr[rr>0]-1,cc[cc>0]-1)=src(R,C);
230 OOFEM_ERROR(
"row dimensions of 'src' and 'rowind' mismatch");
234 OOFEM_ERROR(
"column dimensions of 'src' and 'colind' mismatch");
238 for (
int i = 1; i <= nr; i++ ) {
239 if ( ( ii = rowind.
at(i) ) ) {
240 for (
int j = 1; j <= nc; j++ ) {
241 if ( ( jj = colind.
at(j) ) ) {
242 this->
at(ii, jj) += src.
at(i, j);
250#ifdef _USE_EIGEN___BROKEN
263 OOFEM_ERROR(
"row dimensions of 'src' and 'rowind' mismatch");
267 OOFEM_ERROR(
"column dimensions of 'src' and 'colind' mismatch");
271 for (
int i = 1; i <= nr; i++ ) {
272 if ( ( ii = rowind.
at(i) ) ) {
273 for (
int j = 1; j <= nc; j++ ) {
274 if ( ( jj = colind.
at(j) ) ) {
275 this->
at(jj, ii) += src.
at(i, j);
286void _zeroedIfEmpty(
FloatMatrix& A, Eigen::Index rows, Eigen::Index cols){
if(A.
isNotEmpty())
return; A.setZero(rows,cols); }
287void _ensureRowsCols(FloatMatrix& A, Eigen::Index minRows, Eigen::Index minCols){
if(A.rows()>=minRows && A.cols()>=minCols)
return; A.
resizeWithData(
max(A.rows(),minRows),
max(A.cols(),minCols)); }
291void FloatMatrix :: beTranspositionOf(
const FloatMatrix &src) { *
this=src.transpose(); }
292void FloatMatrix :: beProductOf(
const FloatMatrix &aMatrix,
const FloatMatrix &bMatrix){ *
this=aMatrix*bMatrix; }
293void FloatMatrix :: beTProductOf(
const FloatMatrix &aMatrix,
const FloatMatrix &bMatrix){ *
this=aMatrix.transpose()*bMatrix; }
294void FloatMatrix :: beProductTOf(
const FloatMatrix &aMatrix,
const FloatMatrix &bMatrix){ *
this=aMatrix*bMatrix.transpose(); }
295void FloatMatrix :: addProductOf(
const FloatMatrix &aMatrix,
const FloatMatrix &bMatrix){ *
this+=aMatrix*bMatrix; }
296void FloatMatrix :: addTProductOf(
const FloatMatrix &aMatrix,
const FloatMatrix &bMatrix){ *
this+=aMatrix.transpose()*bMatrix; }
297void FloatMatrix :: beDyadicProductOf(
const FloatArray &vec1,
const FloatArray &vec2){ *
this=vec1*vec2.transpose(); }
298void FloatMatrix :: symmetrized() { *
this = this->selfadjointView<Eigen::Upper>().toDenseMatrix(); }
299void FloatMatrix :: times(
double factor) { (*this)*=factor; }
300void FloatMatrix :: negated() { (*this)*=-1; }
301double FloatMatrix :: computeFrobeniusNorm()
const {
return this->
norm(); }
302double FloatMatrix :: computeNorm(
char p)
const {
303 if(p==
'1')
return this->lpNorm<1>();
307void FloatMatrix::setTSubMatrix(
const FloatMatrix &src,
int sr,
int sc){ this->block(sr-1,sc-1,src.cols(),src.rows())=src.transpose(); }
308void FloatMatrix :: addSubVectorRow(
const FloatArray &src,
int sr,
int sc){
Index sr0=sr-1, sc0=sc-1; _ensureRowsCols(*
this,sr0+1,sc0+src.size()+1); row(sr0).segment(sc0,src.size())=src; }
309void FloatMatrix :: addSubVectorCol(
const FloatArray &src,
int sr,
int sc){
Index sr0=sr-1, sc0=sc-1; _ensureRowsCols(*
this,sr0+src.size()+1,sc0+1); col(sc0).segment(sr0,src.size())=src; }
310void FloatMatrix :: setColumn(
const FloatArray &src,
int c){ this->col(c-1)=src; }
311void FloatMatrix :: copyColumn(
FloatArray &dest,
int c)
const { dest=this->col(c-1); }
313void FloatMatrix :: plusDyadSymmUpper(
const FloatArray &a,
double dV) { _zeroedIfEmpty(*
this,a.size(),a.size()); this->selfadjointView<Eigen::Upper>().rankUpdate(a,dV); }
314void FloatMatrix :: plusProductUnsym(
const FloatMatrix &a,
const FloatMatrix &b,
double dV) { _zeroedIfEmpty(*
this,a.cols(),b.cols()); *
this+=a.transpose()*b*dV; }
315void FloatMatrix :: plusDyadUnsym(
const FloatArray &a,
const FloatArray &b,
double dV) { _zeroedIfEmpty(*
this,a.size(),b.size()); *
this+=a*b.transpose()*dV; }
317bool FloatMatrix :: beInverseOf(
const FloatMatrix &src){
318 Eigen::FullPivLU<Eigen::MatrixXd> lu(src);
320 if(!lu.isInvertible())
return false;
324void FloatMatrix :: beSubMatrixOf(
const FloatMatrix &src,
Index topRow,
Index bottomRow,
Index topCol,
Index bottomCol){ *
this=src.block(topRow-1,topCol-1,bottomRow-topRow+1,bottomCol-topCol+1); }
325void FloatMatrix :: beSubMatrixOf(
const FloatMatrix &src,
const IntArray &indxRow,
const IntArray &indxCol) { *
this=src(indxRow.minusOne(),indxCol.minusOne()); }
328void FloatMatrix :: subtract(
const FloatMatrix &a) {
if(!a.isNotEmpty())
return;
if(!isNotEmpty()){ *
this=-a;
return; } *
this-=a; }
329FloatMatrix FloatMatrix :: fromArray(
const FloatArray &vector,
bool transposed){
if(transposed)
return vector.transpose();
return vector; }
330void FloatMatrix :: zero() { this->setZero(); }
331void FloatMatrix :: beUnitMatrix(){
if(!this->isSquare())
OOFEM_ERROR(
"cannot make unit matrix of %ld by %ld matrix", rows(), cols()); *
this=Eigen::MatrixXd::setIdentity(); }
332double FloatMatrix :: giveDeterminant()
const {
return this->determinant(); }
333void FloatMatrix :: beDiagonal(
const FloatArray &
diag) { *
this=
diag.asDiagonal().toDenseMatrix(); }
334double FloatMatrix :: giveTrace()
const {
return this->
trace(); }
339bool FloatMatrix :: isAllFinite()
const
342 if ( !std::isfinite((*
this)(r,c)) ) {
357 for (
int i = 1; i <= nrows; i++ ) {
358 for (
int j = 1; j <= ncols; j++ ) {
359 this->
at(i, j) = src.
at(j, i);
369 if ( aMatrix.
cols() != bMatrix.
rows() ) {
370 OOFEM_ERROR(
"error in product A*B : dimensions do not match, A(*,%d), B(%d,*)", aMatrix.
cols(), bMatrix.
rows());
374# ifdef __LAPACK_MODULE
375 const int this_nColumns=
cols(), this_nRows=
rows();
376 const int aMatrix_nColumns=aMatrix.
cols(), aMatrix_nRows=aMatrix.
rows();
377 const int bMatrix_nColumns=bMatrix.
cols(), bMatrix_nRows=bMatrix.
rows();
378 double alpha = 1., beta = 0.;
379 dgemm_(
"n",
"n", & this_nRows, & this_nColumns, & aMatrix_nColumns,
381 & beta, this->givePointer(), & this_nRows,
382 aMatrix_nColumns, bMatrix_nColumns, this_nColumns);
384 for (
Index i = 1; i <= aMatrix.
rows(); i++ ) {
385 for (
Index j = 1; j <= bMatrix.
cols(); j++ ) {
387 for (
Index k = 1; k <= aMatrix.
cols(); k++ ) {
388 coeff += aMatrix.
at(i, k) * bMatrix.
at(k, j);
391 this->
at(i, j) = coeff;
402 if ( aMatrix.
rows() != bMatrix.
rows() ) {
403 OOFEM_ERROR(
"error in product A*B : dimensions do not match");
407# ifdef __LAPACK_MODULE
408 double alpha = 1., beta = 0.;
409 const int this_nColumns=
cols(), this_nRows=
rows();
410 const int aMatrix_nColumns=aMatrix.
cols(), aMatrix_nRows=aMatrix.
rows();
411 const int bMatrix_nColumns=bMatrix.
cols(), bMatrix_nRows=bMatrix.
rows();
412 dgemm_(
"t",
"n", & this_nRows, & this_nColumns, & aMatrix_nRows,
414 & beta, this->givePointer(), & this_nRows,
415 aMatrix_nColumns, bMatrix_nColumns, this_nColumns);
417 for (
Index i = 1; i <= aMatrix.
cols(); i++ ) {
418 for (
Index j = 1; j <= bMatrix.
cols(); j++ ) {
420 for (
Index k = 1; k <= aMatrix.
rows(); k++ ) {
421 coeff += aMatrix.
at(k, i) * bMatrix.
at(k, j);
424 this->
at(i, j) = coeff;
435 if ( aMatrix.
cols() != bMatrix.
cols() ) {
436 OOFEM_ERROR(
"error in product A*B : dimensions do not match");
440# ifdef __LAPACK_MODULE
441 const int this_nColumns=
cols(), this_nRows=
rows();
442 const int aMatrix_nColumns=aMatrix.
cols(), aMatrix_nRows=aMatrix.
rows();
443 const int bMatrix_nColumns=bMatrix.
cols(), bMatrix_nRows=bMatrix.
rows();
444 double alpha = 1., beta = 0.;
445 dgemm_(
"n",
"t", & this_nRows, & this_nColumns, & aMatrix_nColumns,
447 & beta, this->givePointer(), & this_nRows,
448 aMatrix_nColumns, bMatrix_nColumns, this_nColumns);
450 for (
Index i = 1; i <= aMatrix.
rows(); i++ ) {
451 for (
Index j = 1; j <= bMatrix.
rows(); j++ ) {
453 for (
Index k = 1; k <= aMatrix.
cols(); k++ ) {
454 coeff += aMatrix.
at(i, k) * bMatrix.
at(j, k);
457 this->
at(i, j) = coeff;
468 if ( aMatrix.
cols() != bMatrix.
rows() ) {
469 OOFEM_ERROR(
"error in product A*B : dimensions do not match");
471 if ( aMatrix.
rows() != this->rows() || bMatrix.
cols() != this->cols() ) {
472 OOFEM_ERROR(
"error in product receiver : dimensions do not match");
476# ifdef __LAPACK_MODULE
477 const int this_nColumns=
cols(), this_nRows=
rows();
478 const int aMatrix_nColumns=aMatrix.
cols(), aMatrix_nRows=aMatrix.
rows();
479 const int bMatrix_nColumns=bMatrix.
cols(), bMatrix_nRows=bMatrix.
rows();
480 double alpha = 1., beta = 1.;
481 dgemm_(
"n",
"n", & this_nRows, & this_nColumns, & aMatrix_nColumns,
483 & beta, this->givePointer(), & this_nRows,
484 aMatrix_nColumns, bMatrix_nColumns, this_nColumns);
486 for (
Index i = 1; i <= aMatrix.
rows(); i++ ) {
487 for (
Index j = 1; j <= bMatrix.
cols(); j++ ) {
489 for (
Index k = 1; k <= aMatrix.
cols(); k++ ) {
490 coeff += aMatrix.
at(i, k) * bMatrix.
at(k, j);
493 this->
at(i, j) += coeff;
503 if ( aMatrix.
rows() != bMatrix.
rows() ) {
504 OOFEM_ERROR(
"error in product A*B : dimensions do not match");
506 if ( aMatrix.
cols() != this->cols() || bMatrix.
cols() != this->rows() ) {
507 OOFEM_ERROR(
"error in product receiver : dimensions do not match");
511# ifdef __LAPACK_MODULE
512 double alpha = 1., beta = 1.;
513 const int this_nColumns=
cols(), this_nRows=
rows();
514 const int aMatrix_nColumns=aMatrix.
cols(), aMatrix_nRows=aMatrix.
rows();
515 const int bMatrix_nColumns=bMatrix.
cols(), bMatrix_nRows=bMatrix.
rows();
516 dgemm_(
"t",
"n", & this_nRows, & this_nColumns, & aMatrix_nRows,
518 & beta, this->givePointer(), & this_nRows,
519 aMatrix_nColumns, bMatrix_nColumns, this_nColumns);
521 for (
Index i = 1; i <= aMatrix.
cols(); i++ ) {
522 for (
Index j = 1; j <= bMatrix.
cols(); j++ ) {
524 for (
Index k = 1; k <= aMatrix.
rows(); k++ ) {
525 coeff += aMatrix.
at(k, i) * bMatrix.
at(k, j);
528 this->
at(i, j) += coeff;
541 for (
int j = 1; j <= n2; j++ ) {
542 for (
int i = 1; i <= n1; i++ ) {
543 this->
at(i, j) = vec1.
at(i) * vec2.
at(j);
549void FloatMatrix :: setSubMatrix(
const FloatMatrix &src,
int sr,
int sc)
556 int nr = sr + srcRows;
557 int nc = sc + srcCols;
560 OOFEM_ERROR(
"Sub matrix doesn't fit inside allocated space.");
565 for (
int j = 0; j < srcCols; j++ ) {
566 for (
int i = 0; i < srcRows; i++ ) {
567 ( * this )( sr + i, sc + j ) = src(i, j);
574void FloatMatrix :: setTSubMatrix(
const FloatMatrix &src,
int sr,
int sc)
581 int nr = sr + srcCols;
582 int nc = sc + srcRows;
584 if ( ( this->giveNumberOfRows() < nr ) || ( this->giveNumberOfColumns() < nc ) ) {
585 OOFEM_ERROR(
"Sub matrix doesn't fit inside allocated space");
590 for (
int i = 0; i < srcCols; i++ ) {
591 for (
int j = 0; j < srcRows; j++ ) {
592 ( * this )( sr + i, sc + j ) = src(j, i);
600void FloatMatrix :: addSubVectorRow(
const FloatArray &src,
int sr,
int sc)
607 int nc = sc + srcCols;
614 for (
int j = 1; j <= srcCols; j++ ) {
615 this->
at(sr, sc + j) += src.
at(j);
622void FloatMatrix :: addSubVectorCol(
const FloatArray &src,
int sr,
int sc)
628 int nr = sr + srcRows;
636 for (
int j = 1; j <= srcRows; j++ ) {
637 this->
at(sr + j, sc) += src.
at(j);
650 for(
int r=0; r<nr; r++) (*
this)(r,c-1)=src(r);
664 for(
int r=0; r<nr; r++) dest(r)=(*this)(r,c-1);
667void FloatMatrix :: plusDyadSymmUpper(
const FloatArray &a,
double dV)
672#ifdef __LAPACK_MODULE
675 const int this_nColumns=
cols(), this_nRows=
rows();
677 this->givePointer(), & this_nRows,
678 sizeA, this_nColumns);
682 this->
at(i, j) += a.
at(i) * a.
at(j) * dV;
699#ifdef __LAPACK_MODULE
700 const int this_nColumns=
cols(), this_nRows=
rows();
701 const int a_nColumns=a.
cols(), a_nRows=a.
rows();
702 const int b_nColumns=b.
cols(), b_nRows=b.
rows();
704 dgemm_(
"t",
"n", & this_nRows, & this_nColumns, & a_nRows,
706 & beta, this->givePointer(), & this_nRows,
707 a_nColumns, b_nColumns, this_nColumns);
713 summ += a.
at(k, i) * b.
at(k, j);
716 this->
at(i, j) += summ * dV;
728#ifdef __LAPACK_MODULE
732 const int this_nColumns=
cols(), this_nRows=
rows();
733 dger_(& sizeA, & sizeB, & dV, a.
givePointer(), & inc,
734 b.
givePointer(), & inc, this->givePointer(), & this_nRows,
735 sizeA, sizeB, this_nColumns);
739 this->
at(i, j) += a.
at(i) * b.
at(j) * dV;
754 for (std::size_t i = 1; i <=
nRows; i++ ) {
755 for (std::size_t j = 1; j <=
nColumns; j++ ) {
756 for (
int k = 1; k <= a_size; k++ ) {
757 for (
int l = 1; l <= b_size; l++ ) {
758 this->
at(i, j) +=
N.at(k,i) * a.
at(k) * b.
at(l) * B.
at(l,j) * dV;
780 int nRows=this->rows();
783 if (fabs(src.
at(1,1)) > 1.e-30) {
784 this->
at(1, 1) = 1. / src.
at(1, 1);
789 }
else if (
nRows == 2 ) {
790 det = src.
at(1, 1) * src.
at(2, 2) - src.
at(1, 2) * src.
at(2, 1);
791 if (fabs(
det)>1.e-30) {
792 this->
at(1, 1) = src.
at(2, 2) /
det;
793 this->
at(2, 1) = -src.
at(2, 1) /
det;
794 this->
at(1, 2) = -src.
at(1, 2) /
det;
795 this->
at(2, 2) = src.
at(1, 1) /
det;
800 }
else if (
nRows == 3 ) {
801 det = src.
at(1, 1) * src.
at(2, 2) * src.
at(3, 3) + src.
at(1, 2) * src.
at(2, 3) * src.
at(3, 1) +
802 src.
at(1, 3) * src.
at(2, 1) * src.
at(3, 2) - src.
at(1, 3) * src.
at(2, 2) * src.
at(3, 1) -
803 src.
at(2, 3) * src.
at(3, 2) * src.
at(1, 1) - src.
at(3, 3) * src.
at(1, 2) * src.
at(2, 1);
804 if (fabs(
det)>1.e-30) {
805 this->
at(1, 1) = ( src.
at(2, 2) * src.
at(3, 3) - src.
at(2, 3) * src.
at(3, 2) ) /
det;
806 this->
at(2, 1) = ( src.
at(2, 3) * src.
at(3, 1) - src.
at(2, 1) * src.
at(3, 3) ) /
det;
807 this->
at(3, 1) = ( src.
at(2, 1) * src.
at(3, 2) - src.
at(2, 2) * src.
at(3, 1) ) /
det;
808 this->
at(1, 2) = ( src.
at(1, 3) * src.
at(3, 2) - src.
at(1, 2) * src.
at(3, 3) ) /
det;
809 this->
at(2, 2) = ( src.
at(1, 1) * src.
at(3, 3) - src.
at(1, 3) * src.
at(3, 1) ) /
det;
810 this->
at(3, 2) = ( src.
at(1, 2) * src.
at(3, 1) - src.
at(1, 1) * src.
at(3, 2) ) /
det;
811 this->
at(1, 3) = ( src.
at(1, 2) * src.
at(2, 3) - src.
at(1, 3) * src.
at(2, 2) ) /
det;
812 this->
at(2, 3) = ( src.
at(1, 3) * src.
at(2, 1) - src.
at(1, 1) * src.
at(2, 3) ) /
det;
813 this->
at(3, 3) = ( src.
at(1, 1) * src.
at(2, 2) - src.
at(1, 2) * src.
at(2, 1) ) /
det;
819 #ifdef __LAPACK_MODULE
820 const int this_nRows=
rows();
833 lwork = this_nRows * this_nRows;
839 }
else if ( info < 0 ) {
850 this->
at(i, i) = 1.0;
856 if ( fabs(piv) < 1.e-30 ) {
857 OOFEM_WARNING(
"pivot (%d,%d) to close to small (< 1.e-20)", i, i);
862 linkomb = tmp.
at(j, i) / tmp.
at(i, i);
864 tmp.
at(j, k) -= tmp.
at(i, k) * linkomb;
868 this->
at(j, k) -= this->
at(i, k) * linkomb;
876 for (
Index j = i - 1; j > 0; j-- ) {
877 linkomb = tmp.
at(j, i) / piv;
878 for (
Index k = i; k > 0; k-- ) {
879 tmp.
at(j, k) -= tmp.
at(i, k) * linkomb;
884 this->
at(j, k) -= this->
at(i, k) * linkomb;
892 this->
at(i, j) /= tmp.
at(i, i);
910 if ( ( topRow < 1 ) || ( bottomRow < 1 ) || ( topCol < 1 ) || ( bottomCol < 1 ) ) {
914 if ( ( src.
rows() < bottomRow ) || ( src.
cols() < bottomCol ) || ( ( bottomRow - topRow ) > src.
rows() ) ||
915 ( ( bottomCol - topCol ) > src.
cols() ) ) {
921 Index topRm1, topCm1;
926 this->
resize(bottomRow - topRm1, bottomCol - topCm1);
927 for (
Index i = topRow; i <= bottomRow; i++ ) {
928 for (
Index j = topCol; j <= bottomCol; j++ ) {
929 this->
at(i - topRm1, j - topCm1) = src.
at(i, j);
953 this->
resize(szRow, szCol);
955 for (
int i = 1; i <= szRow; i++ ) {
956 for (
int j = 1; j <= szCol; j++ ) {
957 this->
at(i, j) = src.
at( indxRow.
at(i), indxCol.
at(j) );
966 if ( aMatrix.
rows() == 0 || aMatrix.
cols() == 0 ) {
971 this->operator = ( aMatrix );
980#ifdef __LAPACK_MODULE
981 int aSize = aMatrix.
rows() * aMatrix.
cols();
984 daxpy_(& aSize, & s, aMatrix.
givePointer(), & inc, this->givePointer(), & inc, aSize, aSize);
995 if ( aMatrix.
rows() == 0 || aMatrix.
cols() == 0 ) {
1000 this->operator = ( aMatrix );
1010#ifdef __LAPACK_MODULE
1011 int aSize = aMatrix.
rows() * aMatrix.
cols();
1013 daxpy_(& aSize, & s, aMatrix.
givePointer(), & inc, this->givePointer(), & inc, aSize, aSize);
1025 this->operator = ( aMatrix );
1035#ifdef __LAPACK_MODULE
1036 int aSize = aMatrix.
rows() * aMatrix.
cols();
1039 daxpy_(& aSize, & s, aMatrix.
givePointer(), & inc, this->givePointer(), & inc, aSize, aSize);
1055 for(
int c=0; c<ret.
cols(); c++) ret(0,c)=vector(c);
1058 for(
int r=0; r<ret.
rows(); r++) ret(r,0)=vector(r);
1064void FloatMatrix :: zero()
1070void FloatMatrix :: beUnitMatrix()
1080 this->
at(i, i) = 1.0;
1085double FloatMatrix :: giveDeterminant() const
1090 OOFEM_ERROR(
"cannot compute the determinant of a non-square %d by %d matrix",
rows(),
cols());
1094 if (
rows() == 1 ) {
1096 }
else if (
rows() == 2 ) {
1098 return m(0,0)*m(1,1)-m(1,0)*m(0,1);
1100 }
else if (
rows() == 3 ) {
1102 m(0,0)*m(1,1)*m(2,2)+m(1,0)*m(2,1)*m(0,2)+m(2,0)*m(0,1)*m(1,2)
1103 -m(0,2)*m(1,1)*m(2,0)-m(1,2)*m(2,1)*m(0,0)-m(2,2)*m(0,1)*m(1,0);
1106 OOFEM_ERROR(
"sorry, cannot compute the determinant of a matrix larger than 3x3");
1113 int n =
diag.giveSize();
1115 for (
int i = 0; i < n; ++i ) {
1116 (*this)(i, i) =
diag[i];
1121double FloatMatrix :: giveTrace()
const
1130 answer += (*this)(k,k);;
1137void FloatMatrix :: symmetrized()
1142 OOFEM_ERROR(
"cannot symmetrize a non-square matrix");
1148 for (
Index j = 1; j < i; j++ ) {
1149 this->
at(i, j) = this->
at(j, i);
1155void FloatMatrix :: times(
double factor)
1164void FloatMatrix :: negated()
1170double FloatMatrix :: computeFrobeniusNorm()
const
1175 return std::sqrt(ret);
1179double FloatMatrix :: computeNorm(
char p)
const
1181 # ifdef __LAPACK_MODULE
1182 const int this_nRows=
rows(), this_nColumns=
cols();
1184 int lda =
max(this_nRows, 1);
1190 double col_sum, max_col = 0.0;
1191 for (
Index j = 1; j <= this->cols(); j++ ) {
1193 for (
Index i = 1; i <= this->rows(); i++ ) {
1194 col_sum += fabs( this->
at(i, j) );
1196 if ( col_sum > max_col ) {
1222void FloatMatrix :: copySubVectorRow(
const FloatArray &src,
int sr,
int sc)
1229 int nc = sc + srcCols;
1236 for (
int j = 1; j <= srcCols; j++ ) {
1237 this->
at(sr, sc + j) = src.
at(j);
1255 #ifdef __LAPACK_MODULE
1256 const int this_nColumns=
cols(), this_nRows=
rows();
1257 const int a_nColumns=a.
cols(), a_nRows=a.
rows();
1258 const int b_nColumns=b.
cols(), b_nRows=b.
rows();
1262 if ( this_nRows < 20 ) {
1264 int s1 = this_nRows / 2;
1265 int s2 = this_nRows - s1;
1267 dgemm_(
"t",
"n", & s1, & s1, & a_nRows, & dV, a.
givePointer(), & a_nRows, b.
givePointer(), & b_nRows, & beta, this->givePointer(), & this_nRows, a_nColumns, b_nColumns, this_nColumns);
1269 dgemm_(
"t",
"n", & this_nRows, & s2, & a_nRows, & dV, a.
givePointer(), & a_nRows, & b.
givePointer() [ s1 * b_nRows ], & b_nRows, & beta, & this->givePointer() [ s1 * this_nRows ], & this_nRows, a_nColumns, b_nColumns, this_nColumns);
1273 int block = ( this_nRows - 1 ) / ( this_nRows / 10 ) + 1;
1276 while ( start < this_nRows ) {
1277 int s = end - start;
1278 dgemm_(
"t",
"n", & end, & s, & a_nRows, & dV, a.
givePointer(), & a_nRows, & b.
givePointer() [ start * b_nRows ], & b_nRows, & beta, & this->givePointer() [ start * this_nRows ],
1279 & this_nRows, a_nColumns, b_nColumns, this_nColumns);
1282 if ( end > this_nRows ) {
1291 for (
Index k = 1; k <= a.
rows(); k++ ) {
1292 summ += a.
at(k, i) * b.
at(k, j);
1295 this->
at(i, j) += summ * dV;
1316#ifdef __LAPACK_MODULE
1318 const int this_nRows=
rows();
1331 double piv, linkomb, help;
1344 int nRows=this->rows();
1347 piv = fabs( mtrx->
at(i, i) );
1350 if ( fabs( mtrx->
at(j, i) ) > piv ) {
1352 piv = fabs( mtrx->
at(j, i) );
1356 if ( piv < 1.e-20 ) {
1361 if ( pivRow != i ) {
1363 help = mtrx->
at(i, j);
1364 mtrx->
at(i, j) = mtrx->
at(pivRow, j);
1365 mtrx->
at(pivRow, j) = help;
1367 help = answer.
at(i);
1368 answer.
at(i) = answer.
at(pivRow);
1369 answer.
at(pivRow) = help;
1373 linkomb = mtrx->
at(j, i) / mtrx->
at(i, i);
1375 mtrx->
at(j, k) -= mtrx->
at(i, k) * linkomb;
1378 answer.
at(j) -= answer.
at(i) * linkomb;
1386 help += mtrx->
at(i, j) * answer.
at(j);
1389 answer.
at(i) = ( answer.
at(i) - help ) / mtrx->
at(i, i);
1414#ifdef __LAPACK_MODULE
1416 const int this_nRows=
rows();
1419 const int answer_nColumns=answer.
cols();
1429 double piv, linkomb, help;
1440 int nRows=this->rows();
1445 piv = fabs( mtrx->
at(i, i) );
1448 if ( fabs( mtrx->
at(j, i) ) > piv ) {
1450 piv = fabs( mtrx->
at(j, i) );
1454 if ( fabs(piv) < 1.e-20 ) {
1459 if ( pivRow != i ) {
1461 help = mtrx->
at(i, j);
1462 mtrx->
at(i, j) = mtrx->
at(pivRow, j);
1463 mtrx->
at(pivRow, j) = help;
1466 for (
Index j = 1; j <= nPs; j++ ) {
1467 help = answer.
at(i, j);
1468 answer.
at(i, j) = answer.
at(pivRow, j);
1469 answer.
at(pivRow, j) = help;
1474 linkomb = mtrx->
at(j, i) / mtrx->
at(i, i);
1476 mtrx->
at(j, k) -= mtrx->
at(i, k) * linkomb;
1479 for (
Index k = 1; k <= nPs; k++ ) {
1480 answer.
at(j, k) -= answer.
at(i, k) * linkomb;
1487 for (
Index k = 1; k <= nPs; k++ ) {
1490 help += mtrx->
at(i, j) * answer.
at(j, k);
1493 answer.
at(i, k) = ( answer.
at(i, k) - help ) / mtrx->
at(i, i);
1501void FloatMatrix :: printYourself() const
1504 printf(
"FloatMatrix with dimensions : %ld %ld\n",
1506 if (
rows() <= 250 &&
cols() <= 250 ) {
1508 for (
Index j = 1; j <=
cols() && j <= 100; ++j ) {
1509 printf(
"%10.3e ", this->
at(i, j) );
1515 printf(
" large matrix : coefficients not printed \n");
1520void FloatMatrix :: printYourselfToFile(
const std::string filename,
const bool showDimensions)
const
1523 std :: ofstream matrixfile (filename);
1524 if (matrixfile.is_open()) {
1526 matrixfile <<
"FloatMatrix with dimensions : " <<
rows() <<
", " <<
cols() <<
"\n";
1527 matrixfile << std::scientific << std::right << std::setprecision(3);
1530 matrixfile << std::setw(10) << this->
at(i, j) <<
"\t";
1542void FloatMatrix :: printYourself(
const std::string &name)
const
1545 printf(
"%s (%ld x %ld): \n", name.c_str(), (
long)
rows(), (
long)
cols());
1546 if (
rows() <= 250 &&
cols() <= 250 ) {
1548 for (
Index j = 1; j <=
cols() && j <= 100; ++j ) {
1549 printf(
"%10.3e ", this->
at(i, j) );
1555 for (
Index i = 1; i <=
rows() && i <= 20; ++i ) {
1556 for (
Index j = 1; j <=
cols() && j <= 10; ++j ) {
1557 printf(
"%10.3e ", this->
at(i, j) );
1559 if (
cols() > 10 ) printf(
" ...");
1562 if (
rows() > 20 ) printf(
" ...\n");
1567void FloatMatrix :: pY() const
1573 printf(
"%20.15e", this->
at(i, j) );
1586void FloatMatrix :: writeCSV(
const std :: string &name)
const
1588 FILE *file = fopen(name.c_str(),
"w");
1591 fprintf(file,
"%10.3e, ", this->
at(i, j) );
1594 fprintf(file,
"\n");
1600void FloatMatrix :: bePinvID()
1606 m(0,0)=m(1,1)=m(2,2)=2/3.;
1607 m(0,1)=m(0,2)=m(1,0)=m(2,0)=m(1,2)=m(2,1)=-1/3.;
1608 m(3,3)=m(4,4)=m(5,5)=1/2.;
1618 if ( mode ==
'n' ) {
1621 }
else if ( mode ==
't' ) {
1636 for (
int i = 0; i < n.
giveSize(); ++i ) {
1637 for (
int j = 0; j < nsd; ++j ) {
1638 ( * this )( j, i * nsd + j ) = n(i);
1650 this->
at(1, 1) = normal(0);
1651 }
else if ( normal.
giveSize() == 2 ) {
1653 this->
at(1, 1) = normal(0);
1654 this->
at(1, 2) = normal(1);
1656 this->
at(2, 1) = normal(1);
1657 this->
at(2, 2) = -normal(0);
1659 }
else if ( normal.
giveSize() == 3 ) {
1662 normal(1), -normal(2), normal(0)
1667 t.
add(-npn, normal);
1672 this->
at(1, 1) = normal.
at(1);
1673 this->
at(1, 2) = normal.
at(2);
1674 this->
at(1, 3) = normal.
at(3);
1676 this->
at(2, 1) = b.
at(1);
1677 this->
at(2, 2) = b.
at(2);
1678 this->
at(2, 3) = b.
at(3);
1680 this->
at(3, 1) = t.
at(1);
1681 this->
at(3, 2) = t.
at(2);
1682 this->
at(3, 3) = t.
at(3);
1701 this->
at(1, 1) = aArray.
at(1);
1702 this->
at(2, 2) = aArray.
at(2);
1703 this->
at(3, 3) = aArray.
at(3);
1704 this->
at(2, 3) = aArray.
at(4);
1705 this->
at(1, 3) = aArray.
at(5);
1706 this->
at(1, 2) = aArray.
at(6);
1707 this->
at(3, 2) = aArray.
at(7);
1708 this->
at(3, 1) = aArray.
at(8);
1709 this->
at(2, 1) = aArray.
at(9);
1710 }
else if ( aArray.
giveSize() == 6 ) {
1711 this->
at(1, 1) = aArray.
at(1);
1712 this->
at(2, 2) = aArray.
at(2);
1713 this->
at(3, 3) = aArray.
at(3);
1714 this->
at(2, 3) = aArray.
at(4);
1715 this->
at(1, 3) = aArray.
at(5);
1716 this->
at(1, 2) = aArray.
at(6);
1717 this->
at(3, 2) = aArray.
at(4);
1718 this->
at(3, 1) = aArray.
at(5);
1719 this->
at(2, 1) = aArray.
at(6);
1723void FloatMatrix :: changeComponentOrder()
1732 if (
rows() == 6 &&
cols() == 6 ) {
1735 std :: swap( this->
at(4, 1), this->
at(6, 1) );
1737 std :: swap( this->
at(4, 2), this->
at(6, 2) );
1739 std :: swap( this->
at(4, 3), this->
at(6, 3) );
1741 std :: swap( this->
at(1, 4), this->
at(1, 6) );
1742 std :: swap( this->
at(2, 4), this->
at(2, 6) );
1743 std :: swap( this->
at(3, 4), this->
at(3, 6) );
1744 std :: swap( this->
at(4, 4), this->
at(6, 6) );
1745 std :: swap( this->
at(5, 4), this->
at(5, 6) );
1746 std :: swap( this->
at(6, 4), this->
at(4, 6) );
1748 std :: swap( this->
at(4, 5), this->
at(6, 5) );
1749 }
else if (
rows() == 9 &&
cols() == 9 ) {
1752 const int abq2oo [ 9 ] = {
1753 1, 2, 3, 6, 5, 4, 7, 9, 8
1757 for (
int i = 1; i <= 9; i++ ) {
1758 for (
int j = 1; j <= 9; j++ ) {
1759 tmp.
at(i, j) = this->
at(abq2oo [ i - 1 ], abq2oo [ j - 1 ]);
1769double FloatMatrix :: computeReciprocalCondition(
char p)
const
1773 OOFEM_ERROR(
"receiver must be square (is %d by %d)", this->rows(), this->cols());
1778# ifdef __LAPACK_MODULE
1779 const int n = this->rows();
1802 inv.beInverseOf(*
this);
1803 return 1.0 / (
inv.computeNorm(p) * anorm );
1806void FloatMatrix :: beMatrixFormOfStress(
const FloatArray &aArray)
1816 this->
at(1, 1) = aArray.
at(1);
1817 this->
at(2, 2) = aArray.
at(2);
1818 this->
at(3, 3) = aArray.
at(3);
1819 this->
at(2, 3) = aArray.
at(4);
1820 this->
at(1, 3) = aArray.
at(5);
1821 this->
at(1, 2) = aArray.
at(6);
1822 this->
at(3, 2) = aArray.
at(7);
1823 this->
at(3, 1) = aArray.
at(8);
1824 this->
at(2, 1) = aArray.
at(9);
1825 }
else if ( aArray.
giveSize() == 6 ) {
1826 this->
at(1, 1) = aArray.
at(1);
1827 this->
at(2, 2) = aArray.
at(2);
1828 this->
at(3, 3) = aArray.
at(3);
1829 this->
at(2, 3) = aArray.
at(4);
1830 this->
at(1, 3) = aArray.
at(5);
1831 this->
at(1, 2) = aArray.
at(6);
1832 this->
at(3, 2) = aArray.
at(4);
1833 this->
at(3, 1) = aArray.
at(5);
1834 this->
at(2, 1) = aArray.
at(6);
1841 #ifdef __LAPACK_MODULE
1842 double abstol = 1.0;
1843 int lda, n, ldz, info, found, lwork;
1856 IntArray ifail(n), iwork(5 * n);
1857 FloatArray work( ( n + 3 ) *n );
1858 lwork = ( n + 3 ) * n;
1861 dsyevx_(
"N",
"I",
"U",
1863 NULL, NULL, & one, & neigs,
1865 work.givePointer(), & lwork, iwork.givePointer(), ifail.givePointer(), & info, 1, 1, 1);
1867 dsyevx_(
"N",
"A",
"U",
1869 NULL, NULL, NULL, NULL,
1871 work.givePointer(), & lwork, iwork.givePointer(), ifail.givePointer(), & info, 1, 1, 1);
1891 if ( !stream.write(
rows()) ) {
1895 if ( !stream.write(
cols()) ) {
1900 if ( !stream.write(this->givePointer(),
rows() *
cols()) ) {
1917 if ( !stream.
read(r) ) {
1921 if ( !stream.
read(c) ) {
1928 if ( !stream.
read(this->givePointer(), r*c) ) {
1944#ifdef _USE_EIGEN__BROKEN
1946 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd>
eig(*
this,nf);
1947 if(
eig.info()!=Eigen::Success)
return false;
1948 v=
eig.eigenvectors();
1949 eval=
eig.eigenvalues();
1955 using std::pow, std::sin, std::cos, std::atan2;
1982 for (
int i = 1; i <= neq; i++ ) {
1983 for (
int j = i + 1; j <= neq; j++ ) {
1985 if ( fabs( this->
at(i, j) - this->
at(j, i) ) > 1.0e-6 ) {
1996 for (
int i = 1; i <= neq; i++ ) {
1997 eval.
at(i) = this->
at(i, i);
2000 double tol = pow(c_b2, nf);
2002 for (
int i = 1; i <= neq; ++i ) {
2003 for (
int j = 1; j <= neq; ++j ) {
2004 sum += fabs( this->
at(i, j) );
2021 for (
int j = 2; j <= neq; ++j ) {
2023 for (
int i = 1; i <= ih; ++i ) {
2024 if ( ( fabs( this->
at(i, j) ) /
sum ) > tol ) {
2025 ssum += fabs( this->
at(i, j) );
2027 double aa = atan2( this->
at(i, j) * 2.0, eval.
at(i) - eval.
at(j) ) / 2.0;
2028 double si = sin(aa);
2029 double co = cos(aa);
2053 for (
int k = 1; k < i; ++k ) {
2054 double tt = this->
at(k, i);
2055 this->
at(k, i) = co * tt + si * this->
at(k, j);
2056 this->at(k, j) = -si * tt + co * this->at(k, j);
2058 v.
at(k, i) = co * tt + si *v.
at(k, j);
2059 v.
at(k, j) = -si * tt + co *v.
at(k, j);
2063 double tt = eval.
at(i);
2064 eval.
at(i) = co * tt + si * this->
at(i, j);
2065 double aij = -si * tt + co *this->at(i, j);
2067 v.
at(i, i) = co * tt + si *v.
at(i, j);
2068 v.
at(i, j) = -si * tt + co *v.
at(i, j);
2070 for (
int k = i + 1; k < j; ++k ) {
2071 double tt = this->at(i, k);
2072 this->at(i, k) = co * tt + si * this->at(k, j);
2073 this->at(k, j) = -si * tt + co * this->at(k, j);
2075 v.
at(k, i) = co * tt + si *v.
at(k, j);
2076 v.
at(k, j) = -si * tt + co *v.
at(k, j);
2080 tt = this->at(i, j);
2081 double aji = co * tt + si *eval.
at(j);
2082 eval.
at(j) = -si * tt + co *eval.
at(j);
2085 v.
at(j, i) = co * tt + si *v.
at(j, j);
2086 v.
at(j, j) = -si * tt + co *v.
at(j, j);
2088 for (
int k = j + 1; k <= neq; ++k ) {
2089 double tt = this->at(i, k);
2090 this->at(i, k) = co * tt + si *this->at(j, k);
2091 this->at(j, k) = -si * tt + co *this->at(j, k);
2093 v.
at(k, i) = co * tt + si *v.
at(k, j);
2094 v.
at(k, j) = -si * tt + co *v.
at(k, j);
2098 eval.
at(i) = co * eval.
at(i) + si * aji;
2099 eval.
at(j) = -si * aij + co *eval.
at(j);
2100 this->at(i, j) = 0.0;
2112 }
while ( fabs(ssum) /
sum > tol );
2115 for (
int i = 1; i <= neq; i++ ) {
2116 for (
int j = i; j <= neq; j++ ) {
2117 this->
at(i, j) = this->
at(j, i);
2128 out << x.
rows() <<
" " << x.
cols() <<
" {";
2131 out <<
" " << x(i, j);
virtual int read(int *data, std::size_t count)=0
Reads count integer values into array pointed by data.
virtual int givePackSizeOfDouble(std::size_t count)=0
virtual int givePackSizeOfSizet(std::size_t count)=0
double dotProduct(const FloatArray &x) const
Index giveSize() const
Returns the size of receiver.
void beProductOf(const FloatMatrix &aMatrix, const FloatArray &anArray)
void beVectorProductOf(const FloatArray &v1, const FloatArray &v2)
void add(const FloatArray &src)
const double * givePointer() const
const double * givePointer() const
bool isAllFinite() const
Returns true if no element is NAN or infinite.
std::size_t nRows
Number of rows.
std ::vector< double > values
Values of matrix stored column wise.
void resizeWithData(Index, Index)
static FloatMatrix fromIniList(std ::initializer_list< std ::initializer_list< double > >)
std::size_t nColumns
Number of columns.
void add(const FloatMatrix &a)
void resize(Index rows, Index cols)
void beProductTOf(const FloatMatrix &a, const FloatMatrix &b)
int giveNumberOfColumns() const
Returns number of columns of receiver.
void beProductOf(const FloatMatrix &a, const FloatMatrix &b)
void setSubMatrix(const FloatMatrix &src, int sr, int sc)
double computeNorm(char p) const
void beTranspositionOf(const FloatMatrix &src)
bool isNotEmpty() const
Tests for empty matrix.
void _resize_internal(int nr, int nc)
double giveDeterminant() const
int giveNumberOfRows() const
Returns number of rows of receiver.
double at(std::size_t i, std::size_t j) const
void subtract(const FloatMatrix &a)
void beTProductOf(const FloatMatrix &a, const FloatMatrix &b)
bool isSquare() const
Returns nonzero if receiver is square matrix.
FloatMatrix(std::size_t n, std::size_t m)
std::vector< int > minusOne() const
const int * givePointer() const
#define OOFEM_WARNING(...)
#define _LOOP_MATRIX(r, c)
FloatArray operator+(const FloatArray &x, const FloatArray &y)
double norm(const FloatArray &x)
FloatArrayF< N > min(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
FloatMatrixF< M, N > transpose(const FloatMatrixF< N, M > &mat)
Constructs transposed matrix.
FloatArray operator-(const FloatArray &x, const FloatArray &y)
FloatArrayF< N > max(const FloatArrayF< N > &a, const FloatArrayF< N > &b)
std::pair< FloatArrayF< N >, FloatMatrixF< N, N > > eig(const FloatMatrixF< N, N > &mat, int nf=9)
FloatArray & operator+=(FloatArray &x, const FloatArray &y)
std::ostream & operator<<(std ::ostream &out, const Dictionary &r)
double det(const FloatMatrixF< 2, 2 > &mat)
Computes the determinant.
double sum(const FloatArray &x)
double rcond(const FloatMatrixF< N, N > &mat, int p=1)
FloatMatrixF< N, N > diag(const FloatArrayF< N > &v)
FloatMatrixF< N, M > zero()
Constructs a zero matrix (this is the default behavior when constructing a matrix,...
FloatArray & operator-=(FloatArray &x, const FloatArray &y)
FloatMatrixF< N, N > inv(const FloatMatrixF< N, N > &mat, double zeropiv=1e-24)
Computes the inverse.
FloatArray operator*(const double &a, const FloatArray &x)
FloatArray & operator*=(FloatArray &x, const double &a)
Vector multiplication by scalar.
@ CIO_IOERR
General IO error.
double trace(const FloatMatrixF< N, N > &mat)