⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 newmat7.cpp

📁 各种矩阵算法库。支持UpperTriangularMatrix,LowerTriangularMatrix, DiagonalMatrix, SymmetricMatrix, BandMatrix,U
💻 CPP
📖 第 1 页 / 共 2 页
字号:
   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 + -