📄 newmat7.cpp
字号:
Matrix* gm = new Matrix(nr,nc); MatrixErrorNoSpace(gm); Real* s1=gm1->Store(); Real* s2=gm2->Store(); Real* s=gm->Store(); if (ncr) { while (nr--) { Real* s2x = s2; int j = ncr; Real* sx = s; Real f = *s1++; int k = nc; while (k--) *sx++ = f * *s2x++; while (--j) { sx = s; f = *s1++; k = nc; while (k--) *sx++ += f * *s2x++; } s = sx; } } else *gm = 0.0; gm->ReleaseAndDelete(); gm1->tDelete(); gm2->tDelete(); return gm;}static GeneralMatrix* GeneralMult(GeneralMatrix* gm1, GeneralMatrix* gm2, MultipliedMatrix* mm, MatrixType mtx){ if ( Rectangular(gm1->Type(), gm2->Type(), mtx)) return mmMult(gm1, gm2); else { Compare(gm1->Type() * gm2->Type(),mtx); int nr = gm2->Nrows(); int nc = gm2->Ncols(); if (nc <= 5 && nr > nc) return GeneralMult1(gm1, gm2, mm, mtx); else return GeneralMult2(gm1, gm2, mm, mtx); }}#ifdef __GNUG__void SPMatrix::SelectVersion (MatrixType mtx, int& c1, int& c2) const#elsevoid SPMatrix::SelectVersion (MatrixType mtx, bool& c1, bool& c2) const#endif// for determining version of SP routines// will need to modify if further matrix structures are introduced{ MatrixBandWidth bw1 = gm1->BandWidth(); MatrixBandWidth bw2 = gm2->BandWidth(); MatrixBandWidth bwx(-1); if (mtx.IsBand()) bwx = bw1.minimum(bw2); c1 = (mtx == gm1->Type()) && (bwx == bw1); c2 = (mtx == gm2->Type()) && (bwx == bw2);}static GeneralMatrix* GeneralSP(GeneralMatrix* gm1, GeneralMatrix* gm2, SPMatrix* am, MatrixType mtx){ Tracer tr("GeneralSP"); int nr=gm1->Nrows(); int nc=gm1->Ncols(); if (nr!=gm2->Nrows() || nc!=gm2->Ncols()) Throw(IncompatibleDimensionsException(*gm1, *gm2)); Compare(gm1->Type().SP(gm2->Type()),mtx);#ifdef __GNUG__ int c1,c2; am->SelectVersion(mtx,c1,c2);#else bool c1,c2; am->SelectVersion(mtx,c1,c2); // causes problems for g++#endif if (c1 && c2) { if (gm1->reuse()) { REPORT SP(gm1,gm2); gm2->tDelete(); return gm1; } else if (gm2->reuse()) { REPORT SP(gm2,gm1); return gm2; } else { REPORT GeneralMatrix* gmx = gm1->Type().New(nr,nc,am); gmx->ReleaseAndDelete(); SP(gmx,gm1,gm2); return gmx; } } else { if (c1 && gm1->reuse() ) // must have type test first { REPORT SPDS(gm1,gm2); gm2->tDelete(); return gm1; } else if (c2 && gm2->reuse() ) { REPORT SPDS(gm2,gm1); if (!c1) gm1->tDelete(); return gm2; } else { REPORT GeneralMatrix* gmx = mtx.New(nr,nc,am); SPDS(gmx,gm1,gm2); if (!c1) gm1->tDelete(); if (!c2) gm2->tDelete(); gmx->ReleaseAndDelete(); return gmx; } }}static GeneralMatrix* GeneralSolv(GeneralMatrix* gm1, GeneralMatrix* gm2, BaseMatrix* sm, MatrixType mtx){ REPORT Tracer tr("GeneralSolv"); Compare(gm1->Type().i() * gm2->Type(),mtx); int nr = gm1->Nrows(); if (nr != gm1->Ncols()) Throw(NotSquareException(*gm1)); int nc = gm2->Ncols(); if (gm1->Ncols() != gm2->Nrows()) Throw(IncompatibleDimensionsException(*gm1, *gm2)); GeneralMatrix* gmx = mtx.New(nr,nc,sm); MatrixErrorNoSpace(gmx); Real* r = new Real [nr]; MatrixErrorNoSpace(r); MONITOR_REAL_NEW("Make (GenSolv)",nr,r) GeneralMatrix* gms = gm1->MakeSolver(); Try { MatrixColX mcx(gmx, r, StoreOnExit+DirectPart); // copy to and from r // this must be inside Try so mcx is destroyed before gmx MatrixColX mc2(gm2, r, LoadOnEntry); while (nc--) { gms->Solver(mcx, mc2); mcx.Next(); mc2.Next(); } } CatchAll { if (gms) gms->tDelete(); delete gmx; // <-------------------- gm2->tDelete(); MONITOR_REAL_DELETE("Delete (GenSolv)",nr,r) // ATandT version 2.1 gives an internal error delete [] r; ReThrow; } gms->tDelete(); gmx->ReleaseAndDelete(); gm2->tDelete(); MONITOR_REAL_DELETE("Delete (GenSolv)",nr,r) // ATandT version 2.1 gives an internal error delete [] r; return gmx;}// version for inverses - gm2 is identitystatic GeneralMatrix* GeneralSolvI(GeneralMatrix* gm1, BaseMatrix* sm, MatrixType mtx){ REPORT Tracer tr("GeneralSolvI"); Compare(gm1->Type().i(),mtx); int nr = gm1->Nrows(); if (nr != gm1->Ncols()) Throw(NotSquareException(*gm1)); int nc = nr; DiagonalMatrix I(nr); I=1.0; GeneralMatrix* gmx = mtx.New(nr,nc,sm); MatrixErrorNoSpace(gmx); Real* r = new Real [nr]; MatrixErrorNoSpace(r); MONITOR_REAL_NEW("Make (GenSolvI)",nr,r) GeneralMatrix* gms = gm1->MakeSolver(); Try { MatrixColX mcx(gmx, r, StoreOnExit+DirectPart); // copy to and from r // this must be inside Try so mcx is destroyed before gmx MatrixColX mc2(&I, r, LoadOnEntry); while (nc--) { gms->Solver(mcx, mc2); mcx.Next(); mc2.Next(); } } CatchAll { if (gms) gms->tDelete(); delete gmx; MONITOR_REAL_DELETE("Delete (GenSolvI)",nr,r) // ATandT version 2.1 gives an internal error delete [] r; ReThrow; } gms->tDelete(); gmx->ReleaseAndDelete(); MONITOR_REAL_DELETE("Delete (GenSolvI)",nr,r) // ATandT version 2.1 gives an internal error delete [] r; return gmx;}GeneralMatrix* InvertedMatrix::Evaluate(MatrixType mtx){ // Matrix Inversion - use solve routines Tracer tr("InvertedMatrix::Evaluate"); REPORT gm=((BaseMatrix*&)bm)->Evaluate();#ifdef TEMPS_DESTROYED_QUICKLY GeneralMatrix* gmx; Try { gmx = GeneralSolvI(gm,this,mtx); } CatchAll { delete this; ReThrow; } delete this; return gmx;#else return GeneralSolvI(gm,this,mtx);#endif}/*************************** norm functions ****************************/Real BaseMatrix::Norm1() const{ // maximum of sum of absolute values of a column REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate(); int nc = gm->Ncols(); Real value = 0.0; MatrixCol mc(gm, LoadOnEntry); while (nc--) { Real v = mc.SumAbsoluteValue(); if (value < v) value = v; mc.Next(); } gm->tDelete(); return value;}Real BaseMatrix::NormInfinity() const{ // maximum of sum of absolute values of a row REPORT GeneralMatrix* gm = ((BaseMatrix&)*this).Evaluate(); int nr = gm->Nrows(); Real value = 0.0; MatrixRow mr(gm, LoadOnEntry); while (nr--) { Real v = mr.SumAbsoluteValue(); if (value < v) value = v; mr.Next(); } gm->tDelete(); return value;}/********************** Concatenation and stacking *************************/GeneralMatrix* ConcatenatedMatrix::Evaluate(MatrixType mtx){ REPORT Tracer tr("Concatenate");#ifdef TEMPS_DESTROYED_QUICKLY Try { gm2 = ((BaseMatrix*&)bm2)->Evaluate(); gm1 = ((BaseMatrix*&)bm1)->Evaluate(); Compare(gm1->Type() | gm2->Type(),mtx); int nr=gm1->Nrows(); int nc = gm1->Ncols() + gm2->Ncols(); if (nr != gm2->Nrows()) Throw(IncompatibleDimensionsException(*gm1, *gm2)); GeneralMatrix* gmx = mtx.New(nr,nc,this); MatrixRow mr1(gm1, LoadOnEntry); MatrixRow mr2(gm2, LoadOnEntry); MatrixRow mr(gmx, StoreOnExit+DirectPart); while (nr--) { mr.ConCat(mr1,mr2); mr1.Next(); mr2.Next(); mr.Next(); } gmx->ReleaseAndDelete(); gm1->tDelete(); gm2->tDelete(); delete this; return gmx; } CatchAll { delete this; ReThrow; }#ifndef UseExceptions return 0;#endif #else gm2 = ((BaseMatrix*&)bm2)->Evaluate(); gm1 = ((BaseMatrix*&)bm1)->Evaluate(); Compare(gm1->Type() | gm2->Type(),mtx); int nr=gm1->Nrows(); int nc = gm1->Ncols() + gm2->Ncols(); if (nr != gm2->Nrows()) Throw(IncompatibleDimensionsException(*gm1, *gm2)); GeneralMatrix* gmx = mtx.New(nr,nc,this); MatrixRow mr1(gm1, LoadOnEntry); MatrixRow mr2(gm2, LoadOnEntry); MatrixRow mr(gmx, StoreOnExit+DirectPart); while (nr--) { mr.ConCat(mr1,mr2); mr1.Next(); mr2.Next(); mr.Next(); } gmx->ReleaseAndDelete(); gm1->tDelete(); gm2->tDelete(); return gmx;#endif}GeneralMatrix* StackedMatrix::Evaluate(MatrixType mtx){ REPORT Tracer tr("Stack");#ifdef TEMPS_DESTROYED_QUICKLY Try { gm2 = ((BaseMatrix*&)bm2)->Evaluate(); gm1 = ((BaseMatrix*&)bm1)->Evaluate(); Compare(gm1->Type() & gm2->Type(),mtx); int nc=gm1->Ncols(); int nr1 = gm1->Nrows(); int nr2 = gm2->Nrows(); if (nc != gm2->Ncols()) Throw(IncompatibleDimensionsException(*gm1, *gm2)); GeneralMatrix* gmx = mtx.New(nr1+nr2,nc,this); MatrixRow mr1(gm1, LoadOnEntry); MatrixRow mr2(gm2, LoadOnEntry); MatrixRow mr(gmx, StoreOnExit+DirectPart); while (nr1--) { mr.Copy(mr1); mr1.Next(); mr.Next(); } while (nr2--) { mr.Copy(mr2); mr2.Next(); mr.Next(); } gmx->ReleaseAndDelete(); gm1->tDelete(); gm2->tDelete(); delete this; return gmx; } CatchAll { delete this; ReThrow; }#ifndef UseExceptions return 0;#endif#else gm2 = ((BaseMatrix*&)bm2)->Evaluate(); gm1 = ((BaseMatrix*&)bm1)->Evaluate(); Compare(gm1->Type() & gm2->Type(),mtx); int nc=gm1->Ncols(); int nr1 = gm1->Nrows(); int nr2 = gm2->Nrows(); if (nc != gm2->Ncols()) Throw(IncompatibleDimensionsException(*gm1, *gm2)); GeneralMatrix* gmx = mtx.New(nr1+nr2,nc,this); MatrixRow mr1(gm1, LoadOnEntry); MatrixRow mr2(gm2, LoadOnEntry); MatrixRow mr(gmx, StoreOnExit+DirectPart); while (nr1--) { mr.Copy(mr1); mr1.Next(); mr.Next(); } while (nr2--) { mr.Copy(mr2); mr2.Next(); mr.Next(); } gmx->ReleaseAndDelete(); gm1->tDelete(); gm2->tDelete(); return gmx;#endif}// ************************* equality of matrices ******************** //static bool RealEqual(Real* s1, Real* s2, int n){ int i = n >> 2; while (i--) { if (*s1++ != *s2++) return false; if (*s1++ != *s2++) return false; if (*s1++ != *s2++) return false; if (*s1++ != *s2++) return false; } i = n & 3; while (i--) if (*s1++ != *s2++) return false; return true;}static bool intEqual(int* s1, int* s2, int n){ int i = n >> 2; while (i--) { if (*s1++ != *s2++) return false; if (*s1++ != *s2++) return false; if (*s1++ != *s2++) return false; if (*s1++ != *s2++) return false; } i = n & 3; while (i--) if (*s1++ != *s2++) return false; return true;}bool operator==(const BaseMatrix& A, const BaseMatrix& B){ Tracer tr("BaseMatrix =="); REPORT GeneralMatrix* gmA = ((BaseMatrix&)A).Evaluate(); GeneralMatrix* gmB = ((BaseMatrix&)B).Evaluate(); if (gmA == gmB) // same matrix { REPORT gmA->tDelete(); return true; } if ( gmA->Nrows() != gmB->Nrows() || gmA->Ncols() != gmB->Ncols() ) // different dimensions { REPORT gmA->tDelete(); gmB->tDelete(); return false; } // check for CroutMatrix or BandLUMatrix MatrixType AType = gmA->Type(); MatrixType BType = gmB->Type(); if (AType.CannotConvert() || BType.CannotConvert() ) { REPORT bool bx = gmA->IsEqual(*gmB); gmA->tDelete(); gmB->tDelete(); return bx; } // is matrix storage the same // will need to modify if further matrix structures are introduced if (AType == BType && gmA->BandWidth() == gmB->BandWidth()) { // compare store REPORT bool bx = RealEqual(gmA->Store(),gmB->Store(),gmA->Storage()); gmA->tDelete(); gmB->tDelete(); return bx; } // matrix storage different - just subtract REPORT return IsZero(*gmA-*gmB);}bool operator==(const GeneralMatrix& A, const GeneralMatrix& B){ Tracer tr("GeneralMatrix =="); // May or may not call tDeletes REPORT if (&A == &B) // same matrix { REPORT return true; } if ( A.Nrows() != B.Nrows() || A.Ncols() != B.Ncols() ) { REPORT return false; } // different dimensions // check for CroutMatrix or BandLUMatrix MatrixType AType = A.Type(); MatrixType BType = B.Type(); if (AType.CannotConvert() || BType.CannotConvert() ) { REPORT return A.IsEqual(B); } // is matrix storage the same // will need to modify if further matrix structures are introduced if (AType == BType && A.BandWidth() == B.BandWidth()) { REPORT return RealEqual(A.Store(),B.Store(),A.Storage()); } // matrix storage different - just subtract REPORT return IsZero(A-B);}bool GeneralMatrix::IsZero() const{ REPORT Real* s=store; int i = storage >> 2; while (i--) { if (*s++) return false; if (*s++) return false; if (*s++) return false; if (*s++) return false; } i = storage & 3; while (i--) if (*s++) return false; return true;}bool IsZero(const BaseMatrix& A){ Tracer tr("BaseMatrix::IsZero"); REPORT GeneralMatrix* gm1 = 0; bool bx; Try { gm1=((BaseMatrix&)A).Evaluate(); bx = gm1->IsZero(); } CatchAll { if (gm1) gm1->tDelete(); ReThrow; } gm1->tDelete(); return bx;}// IsEqual functions - insist matrices are of same type// as well as equal values to be equalbool GeneralMatrix::IsEqual(const GeneralMatrix& A) const{ Tracer tr("GeneralMatrix IsEqual"); if (A.Type() != Type()) // not same types { REPORT return false; } if (&A == this) // same matrix { REPORT return true; } if (A.nrows != nrows || A.ncols != ncols) // different dimensions { REPORT return false; } // is matrix storage the same - compare store REPORT return RealEqual(A.store,store,storage);}bool CroutMatrix::IsEqual(const GeneralMatrix& A) const{ Tracer tr("CroutMatrix IsEqual"); if (A.Type() != Type()) // not same types { REPORT return false; } if (&A == this) // same matrix { REPORT return true; } if (A.nrows != nrows || A.ncols != ncols) // different dimensions { REPORT return false; } // is matrix storage the same - compare store REPORT return RealEqual(A.store,store,storage) && intEqual(((CroutMatrix&)A).indx, indx, nrows);}bool BandLUMatrix::IsEqual(const GeneralMatrix& A) const{ Tracer tr("BandLUMatrix IsEqual"); if (A.Type() != Type()) // not same types { REPORT return false; } if (&A == this) // same matrix { REPORT return true; } if ( A.Nrows() != nrows || A.Ncols() != ncols || ((BandLUMatrix&)A).m1 != m1 || ((BandLUMatrix&)A).m2 != m2 ) // different dimensions { REPORT return false; } // matrix storage the same - compare store REPORT return RealEqual(A.Store(),store,storage) && RealEqual(((BandLUMatrix&)A).store2,store2,storage2) && intEqual(((BandLUMatrix&)A).indx, indx, nrows);}#ifdef use_namespace}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -