bool GeneralMatrix::CutIn2_Across(GeneralMatrix& Upper,GeneralMatrix& Lower,int iRow) { int i,j; if (nCol()==0) { Upper.ReSize(0,0); Lower.ReSize(0,0); return TRUE; } if(iRow>nRow()||iRow<0) return FALSE; if(!Upper.ReSize(iRow,nCol(),ERRORVAL)) return FALSE; if(!Lower.ReSize(nRow()-iRow,nCol(),ERRORVAL)) return FALSE; for(i=0;i<iRow;i++) for(j=0;j<nCol();j++) Upper[i][j] = GetElem(i,j); for(i=0;i<Lower.nRow();i++) for(j=0;j<nCol();j++) Lower[i][j] = GetElem(i+iRow,j); return TRUE; }
void GetSubMatrix::operator<<(const BaseMatrix& bmx) { REPORT Tracer tr("SubMatrix(<<)"); GeneralMatrix* gmx = 0; Try { SetUpLHS(); gmx = ((BaseMatrix&)bmx).Evaluate(); if (row_number != gmx->Nrows() || col_number != gmx->Ncols()) Throw(IncompatibleDimensionsException()); MatrixRow mrx(gmx, LoadOnEntry); MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip); // do need LoadOnEntry MatrixRowCol sub; int i = row_number; while (i--) { mr.SubRowCol(sub, col_skip, col_number); // put values in sub sub.Copy(mrx); mr.Next(); mrx.Next(); } gmx->tDelete(); } CatchAll { if (gmx) gmx->tDelete(); ReThrow; } }
void GetSubMatrix::operator-=(const BaseMatrix& bmx) { REPORT Tracer tr("SubMatrix(-=)"); GeneralMatrix* gmx = 0; // MatrixConversionCheck mcc; // Check for loss of info Try { SetUpLHS(); gmx = ((BaseMatrix&)bmx).Evaluate(); if (row_number != gmx->Nrows() || col_number != gmx->Ncols()) Throw(IncompatibleDimensionsException()); MatrixRow mrx(gmx, LoadOnEntry); MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip); // do need LoadOnEntry MatrixRowCol sub; int i = row_number; while (i--) { mr.SubRowCol(sub, col_skip, col_number); // put values in sub sub.Check(mrx); // check for loss of info sub.Sub(mrx); mr.Next(); mrx.Next(); } gmx->tDelete(); #ifdef TEMPS_DESTROYED_QUICKLY delete this; #endif } CatchAll { if (gmx) gmx->tDelete(); #ifdef TEMPS_DESTROYED_QUICKLY delete this; #endif ReThrow; } }
bool GeneralMatrix::CutIn2_Vertical(GeneralMatrix& Left,GeneralMatrix& Right,int iCol) { int i,j; if (nCol()==0) { Left.ReSize(0,0); Right.ReSize(0,0); return TRUE; } if(iCol>nCol()||iCol<0) return FALSE; if(!Left.ReSize(nRow(),iCol,ERRORVAL)) return FALSE; if(!Right.ReSize(nRow(),nCol()-iCol,ERRORVAL)) return FALSE; for(i=0;i<nRow();i++) for(j=0;j<iCol;j++) Left[i][j] = GetElem(i,j); for(i=0;i<nRow();i++) for(j=0;j<Right.nCol();j++) Right[i][j] = GetElem(i,j+iCol); return TRUE; }
void BandMatrix::copyData(const GeneralMatrix& y) { warn_deprecated("BandMatrix::copyData", "To be removed after Cantera 2.2."); m_factored = false; size_t n = sizeof(doublereal) * m_n * (2 *m_kl + m_ku + 1); GeneralMatrix* yyPtr = const_cast<GeneralMatrix*>(&y); (void) memcpy(DATA_PTR(data), yyPtr->ptrColumn(0), n); }
bool GeneralMatrix::Jointer_bottom(GeneralMatrix& other) { if(other.nCol()!=nCol()) return FALSE; if(!AddRows(other.nRow(),ERRORVAL)) return FALSE; return Paste(other,nRow()-other.nRow(),0); }
SymSchurDecomp::SymSchurDecomp(const GeneralMatrix& mata) : lambda(mata.numRows()), q(mata.numRows()) { // check mata is square if (mata.numRows() != mata.numCols()) throw SYLV_MES_EXCEPTION("Matrix is not square in SymSchurDecomp constructor"); // prepare for dsyevr const char* jobz = "V"; const char* range = "A"; const char* uplo = "U"; lapack_int n = mata.numRows(); GeneralMatrix tmpa(mata); double* a = tmpa.base(); lapack_int lda = tmpa.getLD(); double dum; double* vl = &dum; double* vu = &dum; lapack_int idum; lapack_int* il = &idum; lapack_int* iu = &idum; double abstol = 0.0; lapack_int m = n; double* w = lambda.base(); double* z = q.base(); lapack_int ldz = q.getLD(); lapack_int* isuppz = new lapack_int[2*std::max(1,(int) m)]; double tmpwork; lapack_int lwork = -1; lapack_int tmpiwork; lapack_int liwork = -1; lapack_int info; // query for lwork and liwork dsyevr(jobz, range, uplo, &n, a, &lda, vl, vu, il, iu, &abstol, &m, w, z, &ldz, isuppz, &tmpwork, &lwork, &tmpiwork, &liwork, &info); lwork = (int)tmpwork; liwork = tmpiwork; // allocate work arrays double* work = new double[lwork]; lapack_int* iwork = new lapack_int[liwork]; // do the calculation dsyevr(jobz, range, uplo, &n, a, &lda, vl, vu, il, iu, &abstol, &m, w, z, &ldz, isuppz, work, &lwork, iwork, &liwork, &info); if (info < 0) throw SYLV_MES_EXCEPTION("Internal error in SymSchurDecomp constructor"); if (info > 0) throw SYLV_MES_EXCEPTION("Internal LAPACK error in DSYEVR"); delete [] work; delete [] iwork; delete [] isuppz; }
void SortDescending(GeneralMatrix& GM) { Tracer et("QuickSortDescending"); Real* data = GM.Store(); int max = GM.Storage(); if (max > DoSimpleSort) MyQuickSortDescending(data, data + max - 1, 0); InsertionSortDescending(data, max, DoSimpleSort); }
bool GeneralMatrix::Jointer_Right(GeneralMatrix& other) { if(other.nRow()!=nRow()) return FALSE; if(!AddCols(other.nCol(),ERRORVAL)) return FALSE; Paste(other,0,nCol()-other.nCol()); return TRUE; }
GeneralMatrix operator * (double value ,const GeneralMatrix& other) { int i,j; GeneralMatrix result(other); for (i=0;i<other.nRow();i++) for(j=0;j<other.nCol();j++) result[i][j] *= value; return result; }
bool GeneralMatrix::Paste(GeneralMatrix& other,int top,int left) const { int i,j,iRow,iCol; iRow = other.nRow()>(nRow()-top) ? (nRow()-top) : other.nRow(); iCol = other.nCol()>(nCol()-left) ? (nCol()-left): other.nCol(); for(i=0;i<iRow;i++) for(j=0;j<iCol;j++) GetElem(i+top,j+left) = other[i][j]; return TRUE; }
bool GeneralMatrix::Jointer_Diagonal(GeneralMatrix& other,ELEMTYPE Val) { int iCol; iCol = nRow()==0 ? other.nCol()-1 : other.nCol(); if(!AddRows(other.nRow(),Val)) return FALSE; if(!AddCols(iCol,Val)) return FALSE; return Paste(other,nRow()-other.nRow(),nCol()-other.nCol()); }
GeneralMatrix::GeneralMatrix(const GeneralMatrix& other) { pHead = new HeadNode; pHead->nRow = 0; pHead->nCol = 0; pHead->pFirst = NULL; AddRows(other.nRow(),0.0); AddCols(other.nCol()-1,0.0); *this += other; }
ELEMTYPE GeneralMatrix::Distance_E(GeneralMatrix& other) const { int i,j; ELEMTYPE result = ERRORVAL; if(nRow()!=other.nRow()||nCol()!=other.nCol()) return result; for(result=0,i=0;i<nRow();i++) for(j=0;j<nCol();j++) result += pow(GetElem(i,j)-other[i][j],2); return sqrt(result); }
static void MatrixDetails(const GeneralMatrix& A) // write matrix details to Exception buffer { MatrixBandWidth bw = A.BandWidth(); int ubw = bw.upper; int lbw = bw.lower; Exception::AddMessage("MatrixType = "); Exception::AddMessage(A.Type().Value()); Exception::AddMessage(" # Rows = "); Exception::AddInt(A.Nrows()); Exception::AddMessage("; # Cols = "); Exception::AddInt(A.Ncols()); if (lbw >=0) { Exception::AddMessage("; lower BW = "); Exception::AddInt(lbw); } if (ubw >=0) { Exception::AddMessage("; upper BW = "); Exception::AddInt(ubw); } Exception::AddMessage("\n"); }
//---------------------------------------------------------------------- GeneralMatrix GeneralMatrix::operator * (double x) { GeneralMatrix m; m.copyFrom(this); if (!isSparse) { for (int j=0; j<nBlock; j++) m.mat[j] = x*mat[j]; return m; } else { for (int j=0; j<nBlock; j++) m.smat[j] = x*smat[j]; return m; } }
void SymSchurDecomp::getFactor(GeneralMatrix& f) const { if (f.numRows() != q.numRows()) throw SYLV_MES_EXCEPTION("Wrong dimension of factor matrix in SymSchurDecomp::getFactor"); if (f.numRows() != f.numCols()) throw SYLV_MES_EXCEPTION("Factor matrix is not square in SymSchurDecomp::getFactor"); if (! isPositiveSemidefinite()) throw SYLV_MES_EXCEPTION("Symmetric decomposition not positive semidefinite in SymSchurDecomp::getFactor"); f = q; for (int i = 0; i < f.numCols(); i++) { Vector fi(f, i); fi.mult(std::sqrt(lambda[i])); } }
int ResidJacEval::evalJacobian(const doublereal t, const doublereal delta_t, doublereal cj, const doublereal* const y, const doublereal* const ydot, GeneralMatrix& J, doublereal* const resid) { doublereal* const* jac_colPts = J.colPts(); return evalJacobianDP(t, delta_t, cj, y, ydot, jac_colPts, resid); }
void GetSubMatrix::inject(const GeneralMatrix& gmx) { REPORT Tracer tr("SubMatrix(inject)"); SetUpLHS(); if (row_number != gmx.Nrows() || col_number != gmx.Ncols()) Throw(IncompatibleDimensionsException()); MatrixRow mrx((GeneralMatrix*)(&gmx), LoadOnEntry); MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip); // do need LoadOnEntry MatrixRowCol sub; int i = row_number; while (i--) { mr.SubRowCol(sub, col_skip, col_number); // put values in sub sub.Inject(mrx); mr.Next(); mrx.Next(); } }
////////////////////////////////////////////////////////////////////// // 重载运算符==,判断矩阵是否相等 // // 参数: // 1. const GeneralMatrix& other - 用于比较的矩阵 // // 返回值:BOOL 型,两个矩阵相等则为TRUE,否则为FALSE ////////////////////////////////////////////////////////////////////// bool GeneralMatrix::operator==(const GeneralMatrix& other) const { // 首先检查行列数是否相等 if (this->nCol() != other.nCol() || this->nRow() != other.nRow()) return FALSE; for (int i=0; i<nRow(); ++i) { for (int j=0; j<nCol(); ++j) { if (this->GetElem(i,j)!=other.GetElem(i,j)) return FALSE; } } return TRUE; }
GeneralMatrix GeneralMatrix::GetPart(int left,int top,int bottom,int right) const { int i,j; GeneralMatrix result; if(left>right||top>bottom||right>=nCol()||bottom>=nRow()||left<0||top<0||right<0||bottom<0) return result; if(!result.ReSize(bottom-top+1,right-left+1,ERRORVAL)) return result; for(i=0;i<result.nRow();i++) for(j=0;j<result.nCol();j++) result[i][j] = GetElem(i+left,j+top); return result; }
GeneralMatrix* MatrixType::New(int nr, int nc, BaseMatrix* bm) const { // make a new matrix with the given attributes Tracer tr("New"); GeneralMatrix* gm; switch (attribute) { case Valid: if (nc==1) { gm = new ColumnVector(nr); break; } if (nr==1) { gm = new RowVector(nc); break; } gm = new Matrix(nr, nc); break; case Valid+Symmetric: gm = new SymmetricMatrix(nr); break; case Valid+Band: { MatrixBandWidth bw = bm->BandWidth(); gm = new BandMatrix(nr,bw.lower,bw.upper); break; } case Valid+Symmetric+Band: gm = new SymmetricBandMatrix(nr,bm->BandWidth().lower); break; case Valid+Upper: gm = new UpperTriangularMatrix(nr); break; case Valid+Diagonal+Symmetric+Band+Upper+Lower: gm = new DiagonalMatrix(nr); break; case Valid+Band+Upper: gm = new UpperBandMatrix(nr,bm->BandWidth().upper); break; case Valid+Lower: gm = new LowerTriangularMatrix(nr); break; case Valid+Band+Lower: gm = new LowerBandMatrix(nr,bm->BandWidth().lower); break; default: Throw(ProgramException("Invalid matrix type")); } MatrixErrorNoSpace(gm); gm->Protect(); return gm; }
GeneralMatrix GeneralMatrix::operator - (const GeneralMatrix& other) const { int i,j; GeneralMatrix result(*this); if(other.nRow()!=this->nRow()||other.nCol()!=this->nCol()) { for (i=0;i<result.nRow();i++) for (j=0;j<result.nCol();j++) result.GetElemP(i,j)->val = ERRORVAL; return result; } result -= other; return result; }
void GetSubMatrix::operator-=(const BaseMatrix& bmx) { REPORT Tracer tr("SubMatrix(-=)"); GeneralMatrix* gmx = 0; // MatrixConversionCheck mcc; // Check for loss of info Try { SetUpLHS(); gmx = ((BaseMatrix&)bmx).Evaluate(); if (row_number != gmx->Nrows() || col_number != gmx->Ncols()) Throw(IncompatibleDimensionsException()); if (gm->type().is_symmetric() && ( ! gmx->type().is_symmetric() || row_skip != col_skip) ) Throw(ProgramException("Illegal operation on symmetric")); MatrixRow mrx(gmx, LoadOnEntry); MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart, row_skip); // do need LoadOnEntry MatrixRowCol sub; int i = row_number; while (i--) { mr.SubRowCol(sub, col_skip, col_number); // put values in sub sub.Check(mrx); // check for loss of info sub.Sub(mrx); mr.Next(); mrx.Next(); } gmx->tDelete(); } CatchAll { if (gmx) gmx->tDelete(); ReThrow; } }
GeneralMatrix GeneralMatrix::operator * (const GeneralMatrix& other) const { int i,j,k; GeneralMatrix result(this->nRow(),other.nCol()); if(other.nRow()!=this->nCol()) { for (i=0;i<result.nRow();i++) for (j=0;j<result.nCol();j++) result.GetElemP(i,j)->val = ERRORVAL; return result; } for (i=0;i<this->nRow();i++) //矩阵相乘的计算 { for(j=0;j<other.nCol();j++) { for(k = 0; k < other.nRow(); k++) { if ((this->GetElem(i,k)!=0)&&(other.GetElem(k,j)!=0)) { result[i][j] += this->GetElem(i,k) * other.GetElem(k,j); } } } } return result; }
void SqSylvMatrix::multInvLeft2(GeneralMatrix& a, GeneralMatrix& b, double& rcond1, double& rcondinf) const { if (rows != a.numRows() || rows != b.numRows()) { throw SYLV_MES_EXCEPTION("Wrong dimensions for multInvLeft2."); } // PLU factorization Vector inv(data); lapack_int * const ipiv = new lapack_int[rows]; lapack_int info; lapack_int rows2 = rows; dgetrf(&rows2, &rows2, inv.base(), &rows2, ipiv, &info); // solve a lapack_int acols = a.numCols(); double* abase = a.base(); dgetrs("N", &rows2, &acols, inv.base(), &rows2, ipiv, abase, &rows2, &info); // solve b lapack_int bcols = b.numCols(); double* bbase = b.base(); dgetrs("N", &rows2, &bcols, inv.base(), &rows2, ipiv, bbase, &rows2, &info); delete [] ipiv; // condition numbers double* const work = new double[4*rows]; lapack_int* const iwork = new lapack_int[rows]; double norm1 = getNorm1(); dgecon("1", &rows2, inv.base(), &rows2, &norm1, &rcond1, work, iwork, &info); double norminf = getNormInf(); dgecon("I", &rows2, inv.base(), &rows2, &norminf, &rcondinf, work, iwork, &info); delete [] iwork; delete [] work; }
ostream& operator<<(ostream& s, const BaseMatrix& X) { GeneralMatrix* gm = ((BaseMatrix&)X).Evaluate(); operator<<(s, *gm); gm->tDelete(); return s; }
void SylvMatrix::multLeft(int zero_cols, const GeneralMatrix& a, const GeneralMatrix& b) { int off = a.numRows() - a.numCols(); if (off < 0 || a.numRows() != rows || off != zero_cols || rows != b.numRows() || cols != b.numCols()) { throw SYLV_MES_EXCEPTION("Wrong matrix dimensions for multLeft."); } // here we cannot call SylvMatrix::gemm since it would require // another copy of (usually big) b (we are not able to do inplace // submatrix of const GeneralMatrix) if (a.getLD() > 0 && ld > 0) { blas_int mm = a.numRows(); blas_int nn = cols; blas_int kk = a.numCols(); double alpha = 1.0; blas_int lda = a.getLD(); blas_int ldb = ld; double beta = 0.0; blas_int ldc = ld; dgemm("N", "N", &mm, &nn, &kk, &alpha, a.getData().base(), &lda, b.getData().base()+off, &ldb, &beta, data.base(), &ldc); } }
Vector::Vector(int row, GeneralMatrix& m) : len(m.numCols()), s(m.getLD()), data(&(m.get(row, 0))), destroy(false) { }
GeneralMatrix* Matrix::MakeSolver() { REPORT GeneralMatrix* gm = new CroutMatrix(*this); MatrixErrorNoSpace(gm); gm->ReleaseAndDelete(); return gm; }