25 #include <queso/Defines.h>
27 #ifdef QUESO_HAS_TRILINOS
28 #include <queso/TeuchosMatrix.h>
29 #include <queso/TeuchosVector.h>
34 #ifdef QUESO_HAS_TRILINOS
43 TeuchosMatrix::TeuchosMatrix(
44 const BaseEnvironment& env,
55 m_determinant (-INFINITY),
56 m_lnDeterminant(-INFINITY),
61 m_mat.shape(map.NumGlobalElements(),nCols);
67 TeuchosMatrix::TeuchosMatrix(
68 const BaseEnvironment& env,
79 m_determinant (-INFINITY),
80 m_lnDeterminant(-INFINITY),
85 m_mat.shape (map.NumGlobalElements(),map.NumGlobalElements());
88 for (
unsigned int i = 0; i < (
unsigned int) m_mat.numRows(); ++i) {
89 m_mat(i,i) = diagValue;
95 TeuchosMatrix::TeuchosMatrix(
96 const TeuchosVector& v,
99 Matrix (v.env(),v.map()),
106 m_determinant (-INFINITY),
107 m_lnDeterminant(-INFINITY),
112 m_mat.shape (v.sizeLocal(),v.sizeLocal());
115 for (
unsigned int i = 0; i < (
unsigned int) m_mat.numRows(); ++i) {
116 m_mat(i,i) = diagValue;
123 TeuchosMatrix::TeuchosMatrix(
const TeuchosVector& v)
125 Matrix (v.env(),v.map()),
132 m_determinant (-INFINITY),
133 m_lnDeterminant(-INFINITY),
138 m_mat.shape (v.sizeLocal(),v.sizeLocal());
141 unsigned int dim = v.sizeLocal();
143 for (
unsigned int i = 0; i <
dim; ++i) {
150 TeuchosMatrix::TeuchosMatrix(
const TeuchosMatrix& B)
152 Matrix (B.env(),B.map()),
159 m_determinant (-INFINITY),
160 m_lnDeterminant(-INFINITY),
165 m_mat.shape (B.numRowsLocal(),B.numCols());
174 TeuchosMatrix::~TeuchosMatrix()
183 TeuchosMatrix& TeuchosMatrix::operator=(
const TeuchosMatrix& obj)
192 TeuchosMatrix& TeuchosMatrix::operator*=(
double a)
196 iRC = m_mat.scale(a);
203 TeuchosMatrix& TeuchosMatrix::operator/=(
double a)
212 TeuchosMatrix& TeuchosMatrix::operator+=(
const TeuchosMatrix& rhs)
216 unsigned int i,j, nrows=rhs.numRowsLocal(), ncols=rhs.numCols();
218 for(i=0; i< nrows ; i++)
219 for (j = 0; j < ncols; j++)
220 (*
this)(i,j) += rhs(i,j);
227 TeuchosMatrix::operator-=(
const TeuchosMatrix& rhs)
231 unsigned int i,j, nrows=rhs.numRowsLocal(), ncols=rhs.numCols();
233 for(i=0; i< nrows ; i++)
234 for (j = 0; j < ncols; j++)
235 (*
this)(i,j) -= rhs(i,j);
244 double& TeuchosMatrix::operator()(
unsigned int i,
unsigned int j)
247 if ((i >= (
unsigned int) m_mat.numRows()) ||
248 (j >= (
unsigned int) m_mat.numCols())) {
249 std::cerr <<
"In TeuchosMatrix::operator(i,j) (non-const)"
252 <<
", m_mat.numRows() = " << (
unsigned int) m_mat.numRows()
253 <<
", m_mat.numCols() = " << (
unsigned int) m_mat.numCols()
262 const double& TeuchosMatrix::operator()(
unsigned int i,
unsigned int j)
const
274 TeuchosMatrix::numRowsLocal()
const
276 return (
unsigned int) m_mat.numRows();
282 TeuchosMatrix::numRowsGlobal()
const
284 return (
unsigned int) m_mat.numRows();
290 TeuchosMatrix::numCols()
const
292 return (
unsigned int) m_mat.numCols();
298 TeuchosMatrix::values()
300 return m_mat.values();
306 TeuchosMatrix::stride()
308 return m_mat.stride();
315 TeuchosMatrix::max()
const
317 double value = -INFINITY;
319 unsigned int nRows = this->numRowsLocal();
320 unsigned int nCols = this->numCols();
322 for (
unsigned int i = 0; i < nRows; i++) {
323 for (
unsigned int j = 0; j < nCols; j++) {
325 if (aux > value) value = aux;
335 TeuchosMatrix::rank(
double absoluteZeroThreshold,
double relativeZeroThreshold)
const
341 TeuchosVector relativeVec(*m_svdSvec);
342 if (relativeVec[0] > 0.) {
343 relativeVec = (1./relativeVec[0])*relativeVec;
346 unsigned int rankValue = 0;
347 for (
unsigned int i = 0; i < relativeVec.sizeLocal(); ++i) {
348 if (( (*m_svdSvec)[i] >= absoluteZeroThreshold ) &&
349 ( relativeVec [i] >= relativeZeroThreshold )) {
354 if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 3)) {
355 *m_env.subDisplayFile() <<
"In TeuchosMatrix::rank()"
356 <<
": this->numRowsLocal() = " << this->numRowsLocal()
357 <<
", this->numCols() = " << this->numCols()
358 <<
", absoluteZeroThreshold = " << absoluteZeroThreshold
359 <<
", relativeZeroThreshold = " << relativeZeroThreshold
360 <<
", rankValue = " << rankValue
361 <<
", m_svdSvec = " << *m_svdSvec
362 <<
", relativeVec = " << relativeVec
372 TeuchosMatrix::transpose()
const
374 unsigned int nRows = this->numRowsLocal();
375 unsigned int nCols = this->numCols();
379 TeuchosMatrix mat(m_env,m_map,nCols);
380 for (
unsigned int row = 0; row < nRows; ++row) {
381 for (
unsigned int col = 0; col < nCols; ++col) {
382 mat(row,col) = (*this)(col,row);
392 TeuchosMatrix::inverse()
const
394 unsigned int nRows = this->numRowsLocal();
395 unsigned int nCols = this->numCols();
399 if (m_inverse == NULL) {
400 m_inverse =
new TeuchosMatrix(m_env,m_map,nCols);
401 TeuchosVector unitVector(m_env,m_map);
402 unitVector.cwSet(0.);
403 TeuchosVector multVector(m_env,m_map);
404 for (
unsigned int j = 0; j < nCols; ++j) {
405 if (j > 0) unitVector[j-1] = 0.;
407 this->invertMultiply(unitVector, multVector);
408 for (
unsigned int i = 0; i < nRows; ++i) {
409 (*m_inverse)(i,j) = multVector[i];
413 if (m_env.checkingLevel() >= 1) {
414 *m_env.subDisplayFile() <<
"CHECKING In TeuchosMatrix::inverse()"
415 <<
": M.lnDet = " << this->lnDeterminant()
416 <<
", M^{-1}.lnDet = " << m_inverse->lnDeterminant()
419 if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 5)) {
420 *m_env.subDisplayFile() <<
"In TeuchosMatrix::inverse():"
421 <<
"\n M = " << *
this
422 <<
"\n M^{-1} = " << *m_inverse
423 <<
"\n M*M^{-1} = " << (*this)*(*m_inverse)
424 <<
"\n M^{-1}*M = " << (*m_inverse)*(*this)
442 TeuchosMatrix::determinant()
const
444 if (m_determinant == -INFINITY)
446 if(m_LU.numRows() ==0 && m_LU.numCols() ==0)
448 TeuchosVector tmpB(m_env,m_map);
449 TeuchosVector tmpX(m_env,m_map);
450 if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
451 *m_env.subDisplayFile() <<
"In TeuchosMatrix::lnDeterminant()"
452 <<
": before 'this->invertMultiply()'"
455 this->invertMultiply(tmpB,tmpX);
456 if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
457 *m_env.subDisplayFile() <<
"In TeuchosMatrix::lnDeterminant()"
458 <<
": after 'this->invertMultiply()'"
462 if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
463 *m_env.subDisplayFile() <<
"In TeuchosMatrix::lnDeterminant()"
464 <<
": before computing det"
470 for (
int i=0;i<m_LU.numCols();i++) {
472 lnDet += std::log(m_LU(i,i));
476 m_lnDeterminant = lnDet;
478 if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
479 *m_env.subDisplayFile() <<
"In TeuchosMatrix::lnDeterminant()"
480 <<
": after computing det"
485 return m_determinant;
491 TeuchosMatrix::lnDeterminant()
const
493 if (m_lnDeterminant == -INFINITY)
495 if(m_LU.numRows() ==0 && m_LU.numCols() ==0)
497 TeuchosVector tmpB(m_env,m_map);
498 TeuchosVector tmpX(m_env,m_map);
499 if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
500 *m_env.subDisplayFile() <<
"In TeuchosMatrix::lnDeterminant()"
501 <<
": before 'this->invertMultiply()'"
504 this->invertMultiply(tmpB,tmpX);
505 if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
506 *m_env.subDisplayFile() <<
"In TeuchosMatrix::lnDeterminant()"
507 <<
": after 'this->invertMultiply()'"
511 if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
512 *m_env.subDisplayFile() <<
"In TeuchosMatrix::lnDeterminant()"
513 <<
": before computing lnDet"
519 for (
int i=0;i<m_LU.numCols();i++) {
521 lnDet += std::log(m_LU(i,i));
525 m_lnDeterminant = lnDet;
527 if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
528 *m_env.subDisplayFile() <<
"In TeuchosMatrix::lnDeterminant()"
529 <<
": after computing lnDet"
534 return m_lnDeterminant;
541 TeuchosMatrix::normFrob()
const
543 return m_mat.normFrobenius ();
548 TeuchosMatrix::normMax()
const
552 unsigned int nRows = this->numRowsLocal();
553 unsigned int nCols = this->numCols();
555 for (
unsigned int i = 0; i < nRows; i++) {
556 for (
unsigned int j = 0; j < nCols; j++) {
557 aux = fabs((*
this)(i,j));
558 if (aux > value) value = aux;
568 int TeuchosMatrix::chol()
570 int return_success =0 ;
576 Teuchos::LAPACK<int, double> lapack;
586 lapack.POTRF (UPLO, m_mat.numRows(), m_mat.values(), m_mat.stride(), &info);
591 for (
int i=0;i<m_mat.numRows();i++){
592 for (
int j=i+1;j<m_mat.numCols();j++)
593 m_mat(i,j) = m_mat(j,i) ;
597 std::cerr <<
"In TeuchosMtrix::chol()"
598 <<
": INFO = " << info
599 <<
",\n INFO < 0: if INFO = -i, the i-th argument had an illegal value."
600 <<
"\n INFO > 0: if INFO = i, the leading minor of order i is not "
601 <<
" positive definite, and the factorization could not be completed."
608 "TeuchosMatrix::chol()",
609 "matrix is not positive definite",
612 return return_success;
617 TeuchosMatrix::svd(TeuchosMatrix& matU, TeuchosVector& vecS, TeuchosMatrix& matVt)
const
619 unsigned int nRows = this->numRowsLocal();
620 unsigned int nCols = this->numCols();
622 queso_require_msg(!((matU.numRowsLocal() != nRows) || (matU.numCols() != nCols)),
"invalid matU");
626 queso_require_msg(!((matVt.numRowsLocal() != nCols) || (matVt.numCols() != nCols)),
"invalid matVt");
628 int iRC = internalSvd();
639 const TeuchosMatrix& TeuchosMatrix::svdMatU()
const
649 const TeuchosMatrix& TeuchosMatrix::svdMatV()
const
667 TeuchosMatrix::svdSolve(
const TeuchosVector& rhsVec, TeuchosVector& solVec)
const
669 unsigned int nRows = this->numRowsLocal();
670 unsigned int nCols = this->numCols();
677 int iRC = internalSvd();
679 if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 5)) {
680 *m_env.subDisplayFile() <<
"In TeuchosMatrix::svdSolve():"
681 <<
"\n this->numRowsLocal() = " << this->numRowsLocal()
682 <<
", this->numCols() = " << this->numCols()
683 <<
"\n m_svdUmat->numRowsLocal() = " << m_svdUmat->numRowsLocal()
684 <<
", m_svdUmat->numCols() = " << m_svdUmat->numCols()
685 <<
"\n m_svdVmat->numRowsLocal() = " << m_svdVmat->numRowsLocal()
686 <<
", m_svdVmat->numCols() = " << m_svdVmat->numCols()
687 <<
"\n m_svdSvec->sizeLocal() = " << m_svdSvec->sizeLocal()
688 <<
"\n rhsVec.sizeLocal() = " << rhsVec.sizeLocal()
689 <<
"\n solVec.sizeLocal() = " << solVec.sizeLocal()
695 TeuchosMatrix invD = TeuchosMatrix(solVec);
696 TeuchosMatrix auxMatrix = TeuchosMatrix(solVec);
698 for (i=0; i<nRows; i++){
699 invD(i,i) = 1./(m_svdSvec->values()[i]);
708 auxMatrix = invD * svdMatU().transpose();
709 solVec = auxMatrix*rhsVec;
714 TeuchosMatrix* aux_m_svdVTmat =
new TeuchosMatrix(*m_svdVTmat);
717 Teuchos::LAPACK<int, double> lapack;
718 lapack.GESV(nCols, 1, aux_m_svdVTmat->values(), aux_m_svdVTmat->stride(), ipiv, &solVec[0], solVec.sizeLocal(), &info );
727 delete aux_m_svdVTmat;
735 TeuchosMatrix::svdSolve(
const TeuchosMatrix& rhsMat, TeuchosMatrix& solMat)
const
737 unsigned int nRows = this->numRowsLocal();
738 unsigned int nCols = this->numCols();
746 TeuchosVector rhsVec(m_env,rhsMat.map());
747 TeuchosVector solVec(m_env,solMat.map());
749 for (
unsigned int j = 0; j < rhsMat.numCols(); ++j) {
750 rhsVec = rhsMat.getColumn(j);
751 iRC = this->svdSolve(rhsVec, solVec);
753 solMat.setColumn(j,solVec);
765 TeuchosMatrix::multiply(
const TeuchosVector& x)
const
769 TeuchosVector y(m_env,m_map);
778 TeuchosMatrix::invertMultiply(
const TeuchosVector& b)
const
781 TeuchosVector x(m_env,m_map);
783 this->invertMultiply(b,x);
791 TeuchosMatrix::invertMultiply(
const TeuchosVector& b, TeuchosVector& x)
const
797 if (m_LU.numCols() == 0 && m_LU.numRows() == 0)
803 v_pivoting =(
int *) malloc(
sizeof(
int)*m_LU.numCols() );
810 std::cout <<
"In TeuchosMatrix::invertMultiply()"
811 <<
": before LU decomposition, m_LU = ";
812 for (
int i=0;i<3;i++){
813 for (
int j=0;j<3;j++)
814 cout << m_LU(i,j) <<
"\t" ;
820 Teuchos::LAPACK<int, double> lapack;
823 lapack.GETRF( m_LU.numRows(), m_LU.numCols(), m_LU.values(), m_LU.stride(), v_pivoting, &info );
826 std::cerr <<
"In TeuchosMatrix::invertMultiply()"
827 <<
", after lapack.GETRF"
828 <<
": INFO = " << info
829 <<
",\nINFO < 0: if INFO = -i, the i-th argument had an illegal value.\n"
830 <<
"INFO > 0: if INFO = i, U(i,i) is exactly zero. The factorization \n"
831 <<
"has been completed, but the factor U is exactly singular, and division \n"
832 <<
"by zero will occur if it is used to solve a system of equations."
841 std::cout <<
"In TeuchosMatrix::invertMultiply()"
842 <<
": after LU decomposition, m_LU = ";
843 for (
int i=0;i<3;i++){
844 for (
int j=0;j<3;j++)
845 cout << m_LU(i,j) <<
"\t" ;
848 std::cout << std::endl;
851 if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
852 *m_env.subDisplayFile() <<
"In TeuchosMatrix::invertMultiply()"
853 <<
": before 'lapack.GETRS()'"
858 Teuchos::LAPACK<int, double> lapack;
869 lapack.GETRS(TRANS, m_LU.numRows(), NRHS, m_LU.values(), m_LU.stride(), v_pivoting, &x[0],x.sizeLocal(), &info02 );
872 std::cerr <<
"In TeuchosMatrix::invertMultiply()"
873 <<
", after lapack.GETRS - solve LU system"
874 <<
": INFO = " << info02
875 <<
",\nINFO < 0: if INFO = -i, the i-th argument had an illegal value.\n"
879 if ((m_env.subDisplayFile()) && (m_env.displayVerbosity() >= 99)) {
880 *m_env.subDisplayFile() <<
"In TeuchosMatrix::invertMultiply()"
881 <<
", after lapack.GETRS() - solve LU system."
885 TeuchosVector tmpVec(b - (*
this)*x);
886 std::cout <<
"In TeuchosMatrix::invertMultiply()"
887 <<
": ||b - Ax||_2 = " << tmpVec.norm2()
888 <<
": ||b - Ax||_2/||b||_2 = " << tmpVec.norm2()/b.norm2()
896 TeuchosMatrix::invertMultiply(
const TeuchosMatrix& B)
const
898 TeuchosMatrix X(m_env,m_map,B.numCols());
899 this->invertMultiply(B,X);
906 TeuchosMatrix::invertMultiply(
const TeuchosMatrix& B, TeuchosMatrix& X)
const
909 queso_require_msg(!((B.numRowsLocal() != X.numRowsLocal()) || (B.numCols() != X.numCols())),
"Matrices B and X are incompatible");
914 TeuchosVector b(m_env, m_map);
915 TeuchosVector x(m_env, m_map);
917 for(
unsigned int j = 0; j < B.numCols(); ++j ) {
920 x = this->invertMultiply(b);
928 TeuchosMatrix::invertMultiplyForceLU(
const TeuchosVector& b)
const
932 TeuchosVector x(m_env,m_map);
933 this->invertMultiplyForceLU(b,x);
941 TeuchosMatrix::invertMultiplyForceLU(
const TeuchosVector& b, TeuchosVector& x)
const
947 if (m_LU.numCols() == 0 && m_LU.numRows() == 0) {
957 if ( v_pivoting == NULL )
958 v_pivoting =(
int *) malloc(
sizeof(
int)*m_LU.numCols() );
963 Teuchos::LAPACK<int, double> lapack;
966 lapack.GETRF( m_LU.numRows(), m_LU.numCols(), m_LU.values(), m_LU.stride(), v_pivoting, &info );
969 std::cerr <<
"In TeuchosMatrix::invertMultiply()"
970 <<
", after lapack.GETRF"
971 <<
": INFO = " << info
972 <<
",\nINFO < 0: if INFO = -i, the i-th argument had an illegal value.\n"
973 <<
"INFO > 0: if INFO = i, U(i,i) is exactly zero. The factorization \n"
974 <<
"has been completed, but the factor U is exactly singular, and division \n"
975 <<
"by zero will occur if it is used to solve a system of equations."
995 lapack.GETRS(TRANS, m_LU.numRows(), NRHS, m_LU.values(), m_LU.stride(), v_pivoting, &x[0],x.sizeLocal(), &info02 );
998 std::cerr <<
"In TeuchosMatrix::invertMultiply()"
999 <<
", after lapack.GETRS - solve LU system"
1000 <<
": INFO = " << info02
1001 <<
",\nINFO < 0: if INFO = -i, the i-th argument had an illegal value.\n"
1039 TeuchosMatrix::eigen(TeuchosVector& eigenValues, TeuchosMatrix* eigenVectors)
const
1041 unsigned int n = eigenValues.sizeLocal();
1051 Teuchos::SerialDenseMatrix<int,double> copy_m_mat;
1054 Teuchos::LAPACK<int, double> lapack;
1061 WORK =
new double[lwork];
1063 if (eigenVectors == NULL) {
1066 lapack.SYEV(JOBZ, UPLO, copy_m_mat.numRows(), copy_m_mat.values(), copy_m_mat.stride(), &W[0], &WORK[0], lwork, &info);
1068 for (
unsigned int i=0; i< n; i++)
1069 eigenValues[i] = W[i];
1076 lapack.SYEV(JOBZ, UPLO, copy_m_mat.numRows(), copy_m_mat.values(), copy_m_mat.stride(), &W[0], &WORK[0], lwork, &info);
1078 for (
unsigned int i=0; i< n; i++)
1079 eigenValues[i] = W[i];
1081 eigenVectors->m_mat = copy_m_mat;
1085 std::cerr <<
"In TeuchosMtrix::eigen()"
1086 <<
": INFO = " << info
1087 <<
",\n INFO < 0: if INFO = -i, the i-th argument had an illegal value."
1088 <<
"\n INFO > 0: if INFO = i, the algorithm failed to converge; i off-diagonal "
1089 <<
" elements of an intermediate tridiagonal form did not converge to zero."
1097 TeuchosMatrix::largestEigen(
double& eigenValue, TeuchosVector& eigenVector)
const
1099 unsigned int n = eigenVector.sizeLocal();
1102 Teuchos::LAPACK<int, double> lapack;
1105 Teuchos::SerialDenseMatrix<int,double> copy_m_mat;
1115 WORK =
new double[lwork];
1117 lapack.SYEV(JOBZ, UPLO, copy_m_mat.numRows(), copy_m_mat.values(), copy_m_mat.stride(), &W[0], &WORK[0], lwork, &info);
1120 std::cerr <<
"In TeuchosMtrix::largestEigen()"
1121 <<
": INFO = " << info
1122 <<
",\n INFO < 0: if INFO = -i, the i-th argument had an illegal value."
1123 <<
"\n INFO > 0: if INFO = i, the algorithm failed to converge; i off-diagonal "
1124 <<
" elements of an intermediate tridiagonal form did not converge to zero."
1129 eigenValue = W[n-1];
1133 for (
int i=0; i< copy_m_mat.numRows(); i++)
1134 eigenVector[i] = copy_m_mat(i,n-1);
1141 TeuchosMatrix::smallestEigen(
double& eigenValue, TeuchosVector& eigenVector)
const
1143 unsigned int n = eigenVector.sizeLocal();
1146 Teuchos::LAPACK<int, double> lapack;
1149 Teuchos::SerialDenseMatrix<int,double> copy_m_mat;
1159 WORK =
new double[lwork];
1161 lapack.SYEV(JOBZ, UPLO, copy_m_mat.numRows(), copy_m_mat.values(), copy_m_mat.stride(), &W[0], &WORK[0], lwork, &info);
1164 std::cerr <<
"In TeuchosMtrix::smallestEigen()"
1165 <<
": INFO = " << info
1166 <<
",\n INFO < 0: if INFO = -i, the i-th argument had an illegal value."
1167 <<
"\n INFO > 0: if INFO = i, the algorithm failed to converge; i off-diagonal "
1168 <<
" elements of an intermediate tridiagonal form did not converge to zero."
1178 for (
int i=0; i< copy_m_mat.numRows(); i++)
1179 eigenVector[i] = copy_m_mat(i,0);
1189 TeuchosMatrix::cwSet(
double value)
1191 m_mat.putScalar(value);
1198 TeuchosMatrix::cwSet(
unsigned int rowId,
unsigned int colId,
const TeuchosMatrix& mat)
1208 for (
unsigned int i = 0; i < mat.numRowsLocal(); ++i) {
1209 for (
unsigned int j = 0; j < mat.numCols(); ++j) {
1210 (*this)(rowId+i,colId+j) = mat(i,j);
1220 TeuchosMatrix::getColumn(
unsigned int column_num, TeuchosVector& column)
const
1228 const double* temp_ptr ;
1231 temp_ptr = m_mat[column_num];
1234 for (
unsigned int i=0; i< column.sizeLocal();i++)
1235 column[i] = temp_ptr[i];
1242 TeuchosMatrix::getColumn(
unsigned int column_num )
const
1246 TeuchosVector column(m_env, m_map);
1247 this->getColumn( column_num, column );
1255 TeuchosMatrix::setColumn(
unsigned int column_num,
const TeuchosVector& column)
1263 for (
unsigned int i =0; i < column.sizeLocal(); i++)
1264 m_mat(i,column_num) = column[i];
1272 TeuchosMatrix::getRow(
unsigned int row_num, TeuchosVector& row)
const
1280 for (
unsigned int i=0; i< row.sizeLocal();i++)
1281 row[i] = m_mat(row_num,i);
1289 TeuchosMatrix::getRow(
unsigned int row_num )
const
1293 TeuchosVector row(m_env, m_map);
1294 this->getRow( row_num, row );
1301 TeuchosMatrix::setRow (
const unsigned int row_num,
const TeuchosVector& row)
1309 for (
unsigned int i=0; i< row.sizeLocal();i++)
1310 m_mat(row_num,i) = row[i] ;
1318 TeuchosMatrix::zeroLower(
bool includeDiagonal)
1320 unsigned int nRows = this->numRowsLocal();
1321 unsigned int nCols = this->numCols();
1326 if (includeDiagonal) {
1327 for (
unsigned int i = 0; i < nRows; i++) {
1328 for (
unsigned int j = 0; j <= i; j++) {
1334 for (
unsigned int i = 0; i < nRows; i++) {
1335 for (
unsigned int j = 0; j < i; j++) {
1347 TeuchosMatrix::zeroUpper(
bool includeDiagonal)
1349 unsigned int nRows = this->numRowsLocal();
1350 unsigned int nCols = this->numCols();
1355 if (includeDiagonal) {
1356 for (
unsigned int i = 0; i < nRows; i++) {
1357 for (
unsigned int j = i; j < nCols; j++) {
1363 for (
unsigned int i = 0; i < nRows; i++) {
1364 for (
unsigned int j = (i+1); j < nCols; j++) {
1375 TeuchosMatrix::filterSmallValues(
double thresholdValue)
1377 unsigned int nRows = this->numRowsLocal();
1378 unsigned int nCols = this->numCols();
1380 for (
unsigned int i = 0; i < nRows; ++i) {
1381 for (
unsigned int j = 0; j < nCols; ++j) {
1382 double aux = (*this)(i,j);
1384 if ((aux < 0. ) && (-thresholdValue < aux)) {
1387 if ((aux > 0. ) && (thresholdValue > aux)) {
1397 TeuchosMatrix::filterLargeValues(
double thresholdValue)
1399 unsigned int nRows = this->numRowsLocal();
1400 unsigned int nCols = this->numCols();
1402 for (
unsigned int i = 0; i < nRows; ++i) {
1403 for (
unsigned int j = 0; j < nCols; ++j) {
1404 double aux = (*this)(i,j);
1406 if ( (aux < 0. ) && (-thresholdValue > aux))
1409 if ((aux > 0. ) && (thresholdValue < aux))
1420 TeuchosMatrix::fillWithTranspose(
const TeuchosMatrix& mat)
1422 unsigned int nRows = mat.numRowsLocal();
1423 unsigned int nCols = mat.numCols();
1427 for (
unsigned int row = 0; row < nRows; ++row) {
1428 for (
unsigned int col = 0; col < nCols; ++col) {
1429 (*this)(col,row) = mat(row,col);
1439 TeuchosMatrix::fillWithBlocksDiagonally(
const std::vector<const TeuchosMatrix* >& matrices)
1441 unsigned int sumNumRowsLocals = 0;
1442 unsigned int sumNumCols = 0;
1443 for (
unsigned int i = 0; i < matrices.size(); ++i) {
1444 sumNumRowsLocals += matrices[i]->numRowsLocal();
1445 sumNumCols += matrices[i]->numCols();
1450 unsigned int cumulativeRowId = 0;
1451 unsigned int cumulativeColId = 0;
1452 for (
unsigned int i = 0; i < matrices.size(); ++i) {
1453 unsigned int nRows = matrices[i]->numRowsLocal();
1454 unsigned int nCols = matrices[i]->numCols();
1455 for (
unsigned int rowId = 0; rowId < nRows; ++rowId) {
1456 for (
unsigned int colId = 0; colId < nCols; ++colId) {
1457 (*this)(cumulativeRowId + rowId, cumulativeColId + colId) = (*(matrices[i]))(rowId,colId);
1460 cumulativeRowId += nRows;
1461 cumulativeColId += nCols;
1469 TeuchosMatrix::fillWithBlocksDiagonally(
const std::vector<TeuchosMatrix* >& matrices)
1471 unsigned int sumNumRowsLocals = 0;
1472 unsigned int sumNumCols = 0;
1473 for (
unsigned int i = 0; i < matrices.size(); ++i) {
1474 sumNumRowsLocals += matrices[i]->numRowsLocal();
1475 sumNumCols += matrices[i]->numCols();
1480 unsigned int cumulativeRowId = 0;
1481 unsigned int cumulativeColId = 0;
1482 for (
unsigned int i = 0; i < matrices.size(); ++i) {
1483 unsigned int nRows = matrices[i]->numRowsLocal();
1484 unsigned int nCols = matrices[i]->numCols();
1485 for (
unsigned int rowId = 0; rowId < nRows; ++rowId) {
1486 for (
unsigned int colId = 0; colId < nCols; ++colId) {
1487 (*this)(cumulativeRowId + rowId, cumulativeColId + colId) = (*(matrices[i]))(rowId,colId);
1490 cumulativeRowId += nRows;
1491 cumulativeColId += nCols;
1499 TeuchosMatrix::fillWithBlocksHorizontally(
const std::vector<const TeuchosMatrix* >& matrices)
1501 unsigned int sumNumCols = 0;
1502 for (
unsigned int i = 0; i < matrices.size(); ++i) {
1504 sumNumCols += matrices[i]->numCols();
1508 unsigned int cumulativeColId = 0;
1509 for (
unsigned int i = 0; i < matrices.size(); ++i) {
1510 unsigned int nRows = matrices[i]->numRowsLocal();
1511 unsigned int nCols = matrices[i]->numCols();
1512 for (
unsigned int rowId = 0; rowId < nRows; ++rowId) {
1513 for (
unsigned int colId = 0; colId < nCols; ++colId) {
1514 (*this)(rowId, cumulativeColId + colId) = (*(matrices[i]))(rowId,colId);
1517 cumulativeColId += nCols;
1526 TeuchosMatrix::fillWithBlocksHorizontally(
const std::vector<TeuchosMatrix* >& matrices)
1528 unsigned int sumNumCols = 0;
1529 for (
unsigned int i = 0; i < matrices.size(); ++i) {
1531 sumNumCols += matrices[i]->numCols();
1535 unsigned int cumulativeColId = 0;
1536 for (
unsigned int i = 0; i < matrices.size(); ++i) {
1537 unsigned int nRows = matrices[i]->numRowsLocal();
1538 unsigned int nCols = matrices[i]->numCols();
1539 for (
unsigned int rowId = 0; rowId < nRows; ++rowId) {
1540 for (
unsigned int colId = 0; colId < nCols; ++colId) {
1541 (*this)(rowId, cumulativeColId + colId) = (*(matrices[i]))(rowId,colId);
1544 cumulativeColId += nCols;
1553 TeuchosMatrix::fillWithBlocksVertically(
const std::vector<const TeuchosMatrix* >& matrices)
1555 unsigned int sumNumRows = 0;
1556 for (
unsigned int i = 0; i < matrices.size(); ++i) {
1558 sumNumRows += matrices[i]->numRowsLocal();
1562 unsigned int cumulativeRowId = 0;
1563 for (
unsigned int i = 0; i < matrices.size(); ++i) {
1564 unsigned int nRows = matrices[i]->numRowsLocal();
1565 unsigned int nCols = matrices[i]->numCols();
1566 for (
unsigned int rowId = 0; rowId < nRows; ++rowId) {
1567 for (
unsigned int colId = 0; colId < nCols; ++colId) {
1568 (*this)(cumulativeRowId + rowId, colId) = (*(matrices[i]))(rowId,colId);
1571 cumulativeRowId += nRows;
1579 TeuchosMatrix::fillWithBlocksVertically(
const std::vector<TeuchosMatrix* >& matrices)
1581 unsigned int sumNumRows = 0;
1582 for (
unsigned int i = 0; i < matrices.size(); ++i) {
1584 sumNumRows += matrices[i]->numRowsLocal();
1588 unsigned int cumulativeRowId = 0;
1589 for (
unsigned int i = 0; i < matrices.size(); ++i) {
1590 unsigned int nRows = matrices[i]->numRowsLocal();
1591 unsigned int nCols = matrices[i]->numCols();
1592 for (
unsigned int rowId = 0; rowId < nRows; ++rowId) {
1593 for (
unsigned int colId = 0; colId < nCols; ++colId) {
1594 (*this)(cumulativeRowId + rowId, colId) = (*(matrices[i]))(rowId,colId);
1597 cumulativeRowId += nRows;
1605 TeuchosMatrix::fillWithTensorProduct(
const TeuchosMatrix& mat1,
const TeuchosMatrix& mat2)
1607 queso_require_equal_to_msg(this->numRowsLocal(), (mat1.numRowsLocal() * mat2.numRowsLocal()),
"inconsistent local number of rows");
1610 for (
unsigned int rowId1 = 0; rowId1 < mat1.numRowsLocal(); ++rowId1) {
1611 for (
unsigned int colId1 = 0; colId1 < mat1.numCols(); ++colId1) {
1612 double multiplicativeFactor = mat1(rowId1,colId1);
1613 unsigned int targetRowId = rowId1 * mat2.numRowsLocal();
1614 unsigned int targetColId = colId1 * mat2.numCols();
1615 for (
unsigned int rowId2 = 0; rowId2 < mat2.numRowsLocal(); ++rowId2) {
1616 for (
unsigned int colId2 = 0; colId2 < mat2.numCols(); ++colId2) {
1617 (*this)(targetRowId + rowId2, targetColId + colId2) = multiplicativeFactor * mat2(rowId2,colId2);
1628 TeuchosMatrix::fillWithTensorProduct(
const TeuchosMatrix& mat1,
const TeuchosVector& vec2)
1630 queso_require_equal_to_msg(this->numRowsLocal(), (mat1.numRowsLocal() * vec2.sizeLocal()),
"inconsistent local number of rows");
1633 for (
unsigned int rowId1 = 0; rowId1 < mat1.numRowsLocal(); ++rowId1) {
1634 for (
unsigned int colId1 = 0; colId1 < mat1.numCols(); ++colId1) {
1635 double multiplicativeFactor = mat1(rowId1,colId1);
1636 unsigned int targetRowId = rowId1 * vec2.sizeLocal();
1637 unsigned int targetColId = colId1 * 1;
1638 for (
unsigned int rowId2 = 0; rowId2 < vec2.sizeLocal(); ++rowId2) {
1639 for (
unsigned int colId2 = 0; colId2 < 1; ++colId2) {
1640 (*this)(targetRowId + rowId2, targetColId + colId2) = multiplicativeFactor * vec2[rowId2];
1653 TeuchosMatrix::mpiSum(
const MpiComm& comm, TeuchosMatrix& M_global )
const
1657 M_global.numRowsLocal(),
1658 "local and global matrices incompatible");
1661 "local and global matrices incompatible");
1664 int size = M_global.numRowsLocal()*M_global.numCols();
1665 std::vector<double> local( size, 0.0 );
1666 std::vector<double> global( size, 0.0 );
1669 for(
unsigned int i = 0; i < this->numRowsLocal(); i++ ) {
1670 for(
unsigned int j = 0; j < this->numCols(); j++ ) {
1671 k = i + j*M_global.numCols();
1672 local[
k] = (*this)(i,j);
1677 "TeuchosMatrix::mpiSum()",
1678 "failed MPI.Allreduce()");
1680 for(
unsigned int i = 0; i < this->numRowsLocal(); i++ ) {
1681 for(
unsigned int j = 0; j < this->numCols(); j++ ) {
1682 k = i + j*M_global.numCols();
1683 M_global(i,j) = global[
k];
1693 TeuchosMatrix::matlabLinearInterpExtrap(
1694 const TeuchosVector& x1Vec,
1695 const TeuchosMatrix& y1Mat,
1696 const TeuchosVector& x2Vec)
1706 TeuchosVector y1Vec(x1Vec);
1707 TeuchosVector y2Vec(x2Vec);
1708 for (
unsigned int colId = 0; colId < y1Mat.numCols(); ++colId) {
1709 y1Mat.getColumn(colId,y1Vec);
1710 y2Vec.matlabLinearInterpExtrap(x1Vec,y1Vec,x2Vec);
1711 this->setColumn(colId,y2Vec);
1721 TeuchosMatrix::print(std::ostream& os)
const
1723 unsigned int nRows = this->numRowsLocal();
1724 unsigned int nCols = this->numCols();
1726 if (m_printHorizontally) {
1727 for (
unsigned int i = 0; i < nRows; ++i) {
1728 for (
unsigned int j = 0; j < nCols; ++j) {
1732 if (i != (nRows-1)) os <<
"; ";
1737 for (
unsigned int i = 0; i < nRows; ++i) {
1738 for (
unsigned int j = 0; j < nCols; ++j) {
1751 TeuchosMatrix::subReadContents(
1752 const std::string& fileName,
1753 const std::string& fileType,
1754 const std::set<unsigned int>& allowedSubEnvIds)
1760 FilePtrSetStruct filePtrSet;
1761 if (m_env.openInputFile(fileName,
1767 unsigned int nRowsLocal = this->numRowsLocal();
1770 unsigned int idOfMyFirstLine = 1;
1771 unsigned int idOfMyLastLine = nRowsLocal;
1772 unsigned int nCols = this->numCols();
1776 std::string tmpString;
1779 *filePtrSet.ifsVar >> tmpString;
1782 *filePtrSet.ifsVar >> tmpString;
1787 *filePtrSet.ifsVar >> tmpString;
1789 unsigned int posInTmpString = 6;
1792 char nRowsString[tmpString.size()-posInTmpString+1];
1793 unsigned int posInRowsString = 0;
1796 nRowsString[posInRowsString++] = tmpString[posInTmpString++];
1797 }
while (tmpString[posInTmpString] !=
',');
1798 nRowsString[posInRowsString] =
'\0';
1802 char nColsString[tmpString.size()-posInTmpString+1];
1803 unsigned int posInColsString = 0;
1806 nColsString[posInColsString++] = tmpString[posInTmpString++];
1807 }
while (tmpString[posInTmpString] !=
')');
1808 nColsString[posInColsString] =
'\0';
1811 unsigned int numRowsInFile = (
unsigned int) strtod(nRowsString,NULL);
1812 unsigned int numColsInFile = (
unsigned int) strtod(nColsString,NULL);
1813 if (m_env.subDisplayFile()) {
1814 *m_env.subDisplayFile() <<
"In TeuchosMatrix::subReadContents()"
1815 <<
": fullRank " << m_env.fullRank()
1816 <<
", numRowsInFile = " << numRowsInFile
1817 <<
", numColsInFile = " << numColsInFile
1818 <<
", nRowsLocal = " << nRowsLocal
1819 <<
", nCols = " << nCols
1827 queso_require_equal_to_msg(numColsInFile, nCols,
"number of parameters of vec in file is different than number of parameters in this vec object");
1830 unsigned int maxCharsPerLine = 64*nCols;
1832 unsigned int lineId = 0;
1833 while (lineId < idOfMyFirstLine) {
1834 filePtrSet.ifsVar->ignore(maxCharsPerLine,
'\n');
1838 if (m_env.subDisplayFile()) {
1839 *m_env.subDisplayFile() <<
"In TeuchosMatrix::subReadContents()"
1840 <<
": beginning to read input actual data"
1847 *filePtrSet.ifsVar >> tmpString;
1851 *filePtrSet.ifsVar >> tmpString;
1856 std::streampos tmpPos = filePtrSet.ifsVar->tellg();
1857 filePtrSet.ifsVar->seekg(tmpPos+(std::streampos)2);
1859 if (m_env.subDisplayFile()) {
1860 *m_env.subDisplayFile() <<
"In TeuchosMatrix::subReadContents()"
1861 <<
": beginning to read lines with numbers only"
1862 <<
", lineId = " << lineId
1863 <<
", idOfMyFirstLine = " << idOfMyFirstLine
1864 <<
", idOfMyLastLine = " << idOfMyLastLine
1869 while (lineId <= idOfMyLastLine) {
1870 for (
unsigned int j = 0; j < nCols; ++j) {
1871 *filePtrSet.ifsVar >> tmpRead;
1872 (*this)(lineId-idOfMyFirstLine,j) = tmpRead;
1877 m_env.closeFile(filePtrSet,fileType);
1885 TeuchosMatrix::subWriteContents(
1886 const std::string& varNamePrefix,
1887 const std::string& fileName,
1888 const std::string& fileType,
1889 const std::set<unsigned int>& allowedSubEnvIds)
const
1895 FilePtrSetStruct filePtrSet;
1896 if (m_env.openOutputFile(fileName,
1901 unsigned int nRows = this->numRowsLocal();
1902 unsigned int nCols = this->numCols();
1903 *filePtrSet.ofsVar << varNamePrefix <<
"_sub" << m_env.subIdString() <<
" = zeros(" << nRows
1907 *filePtrSet.ofsVar << varNamePrefix <<
"_sub" << m_env.subIdString() <<
" = [";
1909 for (
unsigned int i = 0; i < nRows; ++i) {
1910 for (
unsigned int j = 0; j < nCols; ++j) {
1911 *filePtrSet.ofsVar << (*this)(i,j)
1914 *filePtrSet.ofsVar <<
"\n";
1916 *filePtrSet.ofsVar <<
"];\n";
1918 m_env.closeFile(filePtrSet,fileType);
1935 unsigned int i,j, nrows=src.numRowsLocal(), ncols=src.numCols();
1937 for(i=0; i< nrows ; i++)
1938 for (j = 0; j < ncols; j++)
1939 m_mat(i,j) = src(i,j);
1946 TeuchosMatrix::resetLU()
1948 if (m_LU.numCols() >0 || m_LU.numRows() > 0) {
1975 m_determinant = -INFINITY;
1976 m_lnDeterminant = -INFINITY;
1984 m_isSingular =
false;
1993 TeuchosMatrix::multiply(
const TeuchosVector& x, TeuchosVector& y)
const
1999 unsigned int sizeX = this->numCols();
2000 unsigned int sizeY = this->numRowsLocal();
2001 for (
unsigned int i = 0; i < sizeY; ++i) {
2003 for (
unsigned int j = 0; j < sizeX; ++j) {
2004 value += (*this)(i,j)*x[j];
2015 TeuchosMatrix::internalSvd()
const
2017 if (m_svdColMap == NULL) {
2018 int nRows = (int) this->numRowsLocal();
2019 int nCols = (int) this->numCols();
2022 m_svdColMap =
new Map(this->numCols(),0,this->map().Comm());
2024 m_svdUmat =
new TeuchosMatrix(*
this);
2025 m_svdSvec =
new TeuchosVector(m_env,*m_svdColMap);
2026 m_svdVmat =
new TeuchosMatrix(*m_svdSvec);
2027 m_svdVTmat =
new TeuchosMatrix(*m_svdSvec);
2029 int minRowsCols, maxRowsCols;
2031 if (nRows>=nCols) { minRowsCols = nCols; maxRowsCols = nRows; }
else { minRowsCols = nRows; maxRowsCols = nCols; }
2035 double *
work, *rwork;
2040 lwork = 15*maxRowsCols;
2041 work =
new double[lwork];
2043 int aux1= 5*minRowsCols+7, aux2= 2*maxRowsCols+2*minRowsCols+1;
2046 if (aux1>=aux2) { aux_dim = minRowsCols*aux1; }
else {aux_dim = minRowsCols*aux2; }
2048 rwork =
new double[aux_dim];
2050 Teuchos::LAPACK<int, double> lapack;
2052 lapack.GESVD(jobu,jobvt,m_mat.numRows(),m_mat.numCols(),m_mat.values(),m_mat.stride(),
2053 m_svdSvec->values(),m_svdUmat->values(),m_svdUmat->stride(),m_svdVTmat->values(),
2054 m_svdVTmat->stride(),&work[0],lwork,&rwork[0],&info);
2064 TeuchosMatrix
operator*(
double a,
const TeuchosMatrix& mat)
2066 TeuchosMatrix answer(mat);
2072 TeuchosVector
operator*(
const TeuchosMatrix& mat,
const TeuchosVector& vec)
2078 TeuchosMatrix
operator*(
const TeuchosMatrix& m1,
const TeuchosMatrix& m2)
2081 unsigned int m1Cols = m1.numCols();
2082 unsigned int m2Rows = m2.numRowsLocal();
2083 unsigned int m2Cols = m2.numCols();
2087 TeuchosMatrix mat(m1.env(),m1.map(),m2Cols);
2088 unsigned int commonSize = m1Cols;
2090 for (
unsigned int row1 = 0; row1 < m1Rows; ++row1) {
2091 for (
unsigned int col2 = 0; col2 < m2Cols; ++col2) {
2093 for (
unsigned int k = 0; k < commonSize; ++
k) {
2094 result += m1(row1,k)*m2(k,col2);
2096 mat(row1,col2) = result;
2104 TeuchosMatrix
operator+(
const TeuchosMatrix& m1,
const TeuchosMatrix& m2)
2106 TeuchosMatrix answer(m1);
2112 TeuchosMatrix
operator-(
const TeuchosMatrix& m1,
const TeuchosMatrix& m2)
2114 TeuchosMatrix answer(m1);
2120 TeuchosMatrix
matrixProduct(
const TeuchosVector& v1,
const TeuchosVector& v2)
2122 unsigned int nRows = v1.sizeLocal();
2123 unsigned int nCols = v2.sizeLocal();
2124 TeuchosMatrix answer(v1.env(),v1.map(),nCols);
2126 for (
unsigned int i = 0; i < nRows; ++i) {
2127 double value1 = v1[i];
2128 for (
unsigned int j = 0; j < nCols; ++j) {
2129 answer(i,j) = value1*v2[j];
2137 TeuchosMatrix
leftDiagScaling(
const TeuchosVector& vec,
const TeuchosMatrix& mat)
2139 unsigned int vSize = vec.sizeLocal();
2141 unsigned int mCols = mat.numCols();
2147 TeuchosMatrix answer(mat);
2148 for (
unsigned int i = 0; i < mRows; ++i) {
2149 double vecValue = vec[i];
2150 for (
unsigned int j = 0; j < mCols; ++j) {
2151 answer(i,j) *= vecValue;
2159 TeuchosMatrix
rightDiagScaling(
const TeuchosMatrix& mat,
const TeuchosVector& vec)
2161 unsigned int vSize = vec.sizeLocal();
2163 unsigned int mCols = mat.numCols();
2169 TeuchosMatrix answer(mat);
2170 for (
unsigned int j = 0; j < mCols; ++j) {
2171 double vecValue = vec[j];
2172 for (
unsigned int i = 0; i < mRows; ++i) {
2173 answer(i,j) *= vecValue;
2182 operator<<(std::ostream& os,
const TeuchosMatrix& obj)
2191 #endif // ifdef QUESO_HAS_TRILINOS
GslMatrix operator*(double a, const GslMatrix &mat)
virtual void base_copy(const Matrix &src)
Copies base data from matrix src to this matrix.
GslMatrix leftDiagScaling(const GslVector &vec, const GslMatrix &mat)
#define queso_require_not_equal_to_msg(expr1, expr2, msg)
#define queso_require_less_equal_msg(expr1, expr2, msg)
std::ostream & operator<<(std::ostream &os, const BaseEnvironment &obj)
GslMatrix operator+(const GslMatrix &m1, const GslMatrix &m2)
#define queso_require_equal_to_msg(expr1, expr2, msg)
unsigned int numRowsLocal() const
Returns the local row dimension of this matrix.
const int UQ_MATRIX_IS_NOT_POS_DEFINITE_RC
#define queso_require_msg(asserted, msg)
#define queso_require_less_msg(expr1, expr2, msg)
GslMatrix rightDiagScaling(const GslMatrix &mat, const GslVector &vec)
#define UQ_RC_MACRO(macroIRc, givenRank, where, what, retValue)
GslVector multiply(const GslVector &x) const
This function multiplies this matrix by vector x and returns the resulting vector.
GslMatrix matrixProduct(const GslVector &v1, const GslVector &v2)
GslMatrix operator-(const GslMatrix &m1, const GslMatrix &m2)
#define queso_require_greater_equal_msg(expr1, expr2, msg)
#define queso_require_greater_msg(expr1, expr2, msg)
#define RawValue_MPI_DOUBLE
the intent is to exercise the right to control the distribution of derivative or collective works based on the Library In mere aggregation of another work not based on the Library with the you must alter all the notices that refer to this so that they refer to the ordinary GNU General Public instead of to this it is irreversible for that so the ordinary GNU General Public License applies to all subsequent copies and derivative works made from that copy This option is useful when you wish to copy part of the code of the Library into a program that is not a library You may copy and distribute the which must be distributed under the terms of Sections and above on a medium customarily used for software interchange If distribution of object code is made by offering access to copy from a designated then offering equivalent access to copy the source code from the same place satisfies the requirement to distribute the source even though third parties are not compelled to copy the source along with the object code A program that contains no derivative of any portion of the but is designed to work with the Library by being compiled or linked with is called a work that uses the Library Such a work
and that you are informed that you can do these things To protect your we need to make restrictions that forbid distributors to deny you these rights or to ask you to surrender these rights These restrictions translate to certain responsibilities for you if you distribute copies of the library or if you modify it For if you distribute copies of the whether gratis or for a you must give the recipients all the rights that we gave you You must make sure that receive or can get the source code If you link other code with the you must provide complete object files to the so that they can relink them with the library after making changes to the library and recompiling it And you must show them these terms so they know their rights We protect your rights with a two step which gives you legal permission to copy