📄 newmat7.cpp
字号:
//$$ newmat7.cpp Invert, solve, binary operations// Copyright (C) 1991,2,3,4: R B Davies#include "include.h"#include "newmat.h"#include "newmatrc.h"#ifdef use_namespacenamespace NEWMAT {#endif#ifdef DO_REPORT#define REPORT { static ExeCounter ExeCount(__LINE__,7); ++ExeCount; }#else#define REPORT {}#endif//***************************** solve routines ******************************/GeneralMatrix* GeneralMatrix::MakeSolver(){ REPORT GeneralMatrix* gm = new CroutMatrix(*this); MatrixErrorNoSpace(gm); gm->ReleaseAndDelete(); return gm;}GeneralMatrix* Matrix::MakeSolver(){ REPORT GeneralMatrix* gm = new CroutMatrix(*this); MatrixErrorNoSpace(gm); gm->ReleaseAndDelete(); return gm;}void CroutMatrix::Solver(MatrixColX& mcout, const MatrixColX& mcin){ REPORT int i = mcin.skip; Real* el = mcin.data-i; Real* el1 = el; while (i--) *el++ = 0.0; el += mcin.storage; i = nrows - mcin.skip - mcin.storage; while (i--) *el++ = 0.0; lubksb(el1, mcout.skip);}// Do we need check for entirely zero output?void UpperTriangularMatrix::Solver(MatrixColX& mcout, const MatrixColX& mcin){ REPORT int i = mcin.skip-mcout.skip; Real* elx = mcin.data-i; while (i-- > 0) *elx++ = 0.0; int nr = mcin.skip+mcin.storage; elx = mcin.data+mcin.storage; Real* el = elx; int j = mcout.skip+mcout.storage-nr; int nc = ncols-nr; i = nr-mcout.skip; while (j-- > 0) *elx++ = 0.0; Real* Ael = store + (nr*(2*ncols-nr+1))/2; j = 0; while (i-- > 0) { elx = el; Real sum = 0.0; int jx = j++; Ael -= nc; while (jx--) sum += *(--Ael) * *(--elx); elx--; *elx = (*elx - sum) / *(--Ael); }}void LowerTriangularMatrix::Solver(MatrixColX& mcout, const MatrixColX& mcin){ REPORT int i = mcin.skip-mcout.skip; Real* elx = mcin.data-i; while (i-- > 0) *elx++ = 0.0; int nc = mcin.skip; i = nc+mcin.storage; elx = mcin.data+mcin.storage; int nr = mcout.skip+mcout.storage; int j = nr-i; i = nr-nc; while (j-- > 0) *elx++ = 0.0; Real* el = mcin.data; Real* Ael = store + (nc*(nc+1))/2; j = 0; while (i-- > 0) { elx = el; Real sum = 0.0; int jx = j++; Ael += nc; while (jx--) sum += *Ael++ * *elx++; *elx = (*elx - sum) / *Ael++; }}//******************* carry out binary operations *************************/static GeneralMatrix* GeneralMult(GeneralMatrix*,GeneralMatrix*,MultipliedMatrix*,MatrixType);static GeneralMatrix* GeneralSolv(GeneralMatrix*,GeneralMatrix*,BaseMatrix*,MatrixType);static GeneralMatrix* GeneralSolvI(GeneralMatrix*,BaseMatrix*,MatrixType);static GeneralMatrix* GeneralKP(GeneralMatrix*,GeneralMatrix*,KPMatrix*,MatrixType);GeneralMatrix* MultipliedMatrix::Evaluate(MatrixType mt){ REPORT gm2 = ((BaseMatrix*&)bm2)->Evaluate(); gm2 = gm2->Evaluate(gm2->Type().MultRHS()); // no symmetric on RHS gm1=((BaseMatrix*&)bm1)->Evaluate();#ifdef TEMPS_DESTROYED_QUICKLY GeneralMatrix* gmx; Try { gmx = GeneralMult(gm1, gm2, this, mt); } CatchAll { delete this; ReThrow; } delete this; return gmx;#else return GeneralMult(gm1, gm2, this, mt);#endif}GeneralMatrix* SolvedMatrix::Evaluate(MatrixType mt){ REPORT gm1=((BaseMatrix*&)bm1)->Evaluate(); gm2=((BaseMatrix*&)bm2)->Evaluate();#ifdef TEMPS_DESTROYED_QUICKLY GeneralMatrix* gmx; Try { gmx = GeneralSolv(gm1,gm2,this,mt); } CatchAll { delete this; ReThrow; } delete this; return gmx;#else return GeneralSolv(gm1,gm2,this,mt);#endif}GeneralMatrix* KPMatrix::Evaluate(MatrixType mt){ REPORT gm1=((BaseMatrix*&)bm1)->Evaluate(); gm2=((BaseMatrix*&)bm2)->Evaluate();#ifdef TEMPS_DESTROYED_QUICKLY GeneralMatrix* gmx; Try { gmx = GeneralKP(gm1,gm2,this,mt); } CatchAll { delete this; ReThrow; } delete this; return gmx;#else return GeneralKP(gm1,gm2,this,mt);#endif}// routines for adding or subtracting matrices of identical storage structurestatic void Add(GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2){ REPORT Real* s1=gm1->Store(); Real* s2=gm2->Store(); Real* s=gm->Store(); int i=gm->Storage() >> 2; while (i--) { *s++ = *s1++ + *s2++; *s++ = *s1++ + *s2++; *s++ = *s1++ + *s2++; *s++ = *s1++ + *s2++; } i=gm->Storage() & 3; while (i--) *s++ = *s1++ + *s2++;}static void Add(GeneralMatrix* gm, GeneralMatrix* gm2){ REPORT Real* s2=gm2->Store(); Real* s=gm->Store(); int i=gm->Storage() >> 2; while (i--) { *s++ += *s2++; *s++ += *s2++; *s++ += *s2++; *s++ += *s2++; } i=gm->Storage() & 3; while (i--) *s++ += *s2++;}static void Subtract(GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2){ REPORT Real* s1=gm1->Store(); Real* s2=gm2->Store(); Real* s=gm->Store(); int i=gm->Storage() >> 2; while (i--) { *s++ = *s1++ - *s2++; *s++ = *s1++ - *s2++; *s++ = *s1++ - *s2++; *s++ = *s1++ - *s2++; } i=gm->Storage() & 3; while (i--) *s++ = *s1++ - *s2++;}static void Subtract(GeneralMatrix* gm, GeneralMatrix* gm2){ REPORT Real* s2=gm2->Store(); Real* s=gm->Store(); int i=gm->Storage() >> 2; while (i--) { *s++ -= *s2++; *s++ -= *s2++; *s++ -= *s2++; *s++ -= *s2++; } i=gm->Storage() & 3; while (i--) *s++ -= *s2++;}static void ReverseSubtract(GeneralMatrix* gm, GeneralMatrix* gm2){ REPORT Real* s2=gm2->Store(); Real* s=gm->Store(); int i=gm->Storage() >> 2; while (i--) { *s = *s2++ - *s; s++; *s = *s2++ - *s; s++; *s = *s2++ - *s; s++; *s = *s2++ - *s; s++; } i=gm->Storage() & 3; while (i--) { *s = *s2++ - *s; s++; }}static void SP(GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2){ REPORT Real* s1=gm1->Store(); Real* s2=gm2->Store(); Real* s=gm->Store(); int i=gm->Storage() >> 2; while (i--) { *s++ = *s1++ * *s2++; *s++ = *s1++ * *s2++; *s++ = *s1++ * *s2++; *s++ = *s1++ * *s2++; } i=gm->Storage() & 3; while (i--) *s++ = *s1++ * *s2++;}static void SP(GeneralMatrix* gm, GeneralMatrix* gm2){ REPORT Real* s2=gm2->Store(); Real* s=gm->Store(); int i=gm->Storage() >> 2; while (i--) { *s++ *= *s2++; *s++ *= *s2++; *s++ *= *s2++; *s++ *= *s2++; } i=gm->Storage() & 3; while (i--) *s++ *= *s2++;}// routines for adding or subtracting matrices of different storage structurestatic void AddDS(GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2){ REPORT int nr = gm->Nrows(); MatrixRow mr1(gm1, LoadOnEntry); MatrixRow mr2(gm2, LoadOnEntry); MatrixRow mr(gm, StoreOnExit+DirectPart); while (nr--) { mr.Add(mr1,mr2); mr1.Next(); mr2.Next(); mr.Next(); }}static void AddDS(GeneralMatrix* gm, GeneralMatrix* gm2)// Add into first argument{ REPORT int nr = gm->Nrows(); MatrixRow mr(gm, StoreOnExit+LoadOnEntry+DirectPart); MatrixRow mr2(gm2, LoadOnEntry); while (nr--) { mr.Add(mr2); mr.Next(); mr2.Next(); }}static void SubtractDS (GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2){ REPORT int nr = gm->Nrows(); MatrixRow mr1(gm1, LoadOnEntry); MatrixRow mr2(gm2, LoadOnEntry); MatrixRow mr(gm, StoreOnExit+DirectPart); while (nr--) { mr.Sub(mr1,mr2); mr1.Next(); mr2.Next(); mr.Next(); }}static void SubtractDS(GeneralMatrix* gm, GeneralMatrix* gm2){ REPORT int nr = gm->Nrows(); MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart); MatrixRow mr2(gm2, LoadOnEntry); while (nr--) { mr.Sub(mr2); mr.Next(); mr2.Next(); }}static void ReverseSubtractDS(GeneralMatrix* gm, GeneralMatrix* gm2){ REPORT int nr = gm->Nrows(); MatrixRow mr(gm, LoadOnEntry+StoreOnExit+DirectPart); MatrixRow mr2(gm2, LoadOnEntry); while (nr--) { mr.RevSub(mr2); mr2.Next(); mr.Next(); }}static void SPDS(GeneralMatrix* gm, GeneralMatrix* gm1, GeneralMatrix* gm2){ REPORT int nr = gm->Nrows(); MatrixRow mr1(gm1, LoadOnEntry); MatrixRow mr2(gm2, LoadOnEntry); MatrixRow mr(gm, StoreOnExit+DirectPart); while (nr--) { mr.Multiply(mr1,mr2); mr1.Next(); mr2.Next(); mr.Next(); }}static void SPDS(GeneralMatrix* gm, GeneralMatrix* gm2)// SP into first argument{ REPORT int nr = gm->Nrows(); MatrixRow mr(gm, StoreOnExit+LoadOnEntry+DirectPart); MatrixRow mr2(gm2, LoadOnEntry); while (nr--) { mr.Multiply(mr2); mr.Next(); mr2.Next(); }}static GeneralMatrix* GeneralMult1(GeneralMatrix* gm1, GeneralMatrix* gm2, MultipliedMatrix* mm, MatrixType mtx){ REPORT Tracer tr("GeneralMult1"); int nr=gm1->Nrows(); int nc=gm2->Ncols(); if (gm1->Ncols() !=gm2->Nrows()) Throw(IncompatibleDimensionsException(*gm1, *gm2)); GeneralMatrix* gmx = mtx.New(nr,nc,mm); MatrixCol mcx(gmx, StoreOnExit+DirectPart); MatrixCol mc2(gm2, LoadOnEntry); while (nc--) { MatrixRow mr1(gm1, LoadOnEntry, mcx.Skip()); Real* el = mcx.Data(); // pointer to an element int n = mcx.Storage(); while (n--) { *(el++) = DotProd(mr1,mc2); mr1.Next(); } mc2.Next(); mcx.Next(); } gmx->ReleaseAndDelete(); gm1->tDelete(); gm2->tDelete(); return gmx;}static GeneralMatrix* GeneralMult2(GeneralMatrix* gm1, GeneralMatrix* gm2, MultipliedMatrix* mm, MatrixType mtx){ // version that accesses by row only - not good for thin matrices // or column vectors in right hand term. REPORT Tracer tr("GeneralMult2"); int nr=gm1->Nrows(); int nc=gm2->Ncols(); if (gm1->Ncols() !=gm2->Nrows()) Throw(IncompatibleDimensionsException(*gm1, *gm2)); GeneralMatrix* gmx = mtx.New(nr,nc,mm); MatrixRow mrx(gmx, LoadOnEntry+StoreOnExit+DirectPart); MatrixRow mr1(gm1, LoadOnEntry); while (nr--) { MatrixRow mr2(gm2, LoadOnEntry, mr1.Skip()); Real* el = mr1.Data(); // pointer to an element int n = mr1.Storage(); mrx.Zero(); while (n--) { mrx.AddScaled(mr2, *el++); mr2.Next(); } mr1.Next(); mrx.Next(); } gmx->ReleaseAndDelete(); gm1->tDelete(); gm2->tDelete(); return gmx;}static GeneralMatrix* mmMult(GeneralMatrix* gm1, GeneralMatrix* gm2){ // matrix multiplication for type Matrix only REPORT Tracer tr("MatrixMult"); int nr=gm1->Nrows(); int ncr=gm1->Ncols(); int nc=gm2->Ncols(); if (ncr != gm2->Nrows()) Throw(IncompatibleDimensionsException(*gm1,*gm2)); Matrix* gm = new Matrix(nr,nc); MatrixErrorNoSpace(gm);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -