static void SymLDL_Decompose(SymBandMatrixView<T> A) { TMVAssert(A.uplo() == Lower); TMVAssert(A.ct() == NonConj); TMVAssert(A.issym()); TMVAssert(A.nlo() == 1); const ptrdiff_t N = A.size(); #ifdef XDEBUG Matrix<T> A0(A); //cout<<"SymLDLDecompose:\n"; //cout<<"A = "<<TMV_Text(A)<<" "<<A<<endl; #endif T* Dj = A.ptr(); T* Lj = A.diag(-1).ptr(); if (A.isdm()) { T Ax0 = *Lj; if (*Dj == T(0)) { #ifdef NOTHROW std::cerr<<"Non Posdef HermBandMatrix found\n"; exit(1); #else throw NonPosDefSymBandLDL<T>(A); #endif } *Lj /= *Dj; ++Dj; *Dj -= *Lj * Ax0; ++Lj; } else { ptrdiff_t step = A.diagstep(); for(ptrdiff_t j=0;j<N-1;++j) { T Ax0 = *Lj; if (*Dj == T(0)) { #ifdef NOTHROW std::cerr<<"Non Posdef HermBandMatrix found\n"; exit(1); #else throw NonPosDefSymBandLDL<T>(A); #endif } *Lj /= *Dj; Dj += step; *Dj -= *Lj * Ax0; Lj += step; } } if (*Dj == T(0)) { #ifdef NOTHROW std::cerr<<"Non Posdef HermBandMatrix found\n"; exit(1); #else throw NonPosDefSymBandLDL<T>(A); #endif } #ifdef XDEBUG //cout<<"Done SymLDLDecom\n"; BandMatrix<T> L = A.lowerBand(); L.diag().SetAllTo(T(1)); DiagMatrix<T> D = DiagMatrixViewOf(A.diag()); BandMatrix<T> A2 = L * D * L.transpose(); TMV_RealType(T) normldl = TMV_SQR(Norm(L))*Norm(D); //cout<<"L = "<<L<<endl; //cout<<"D = "<<D<<endl; //cout<<"A2 = "<<A2<<endl; //cout<<"cf. A0 = "<<A0<<endl; if (!(Norm(A2-A0) < 0.001*normldl)) { cerr<<"SymLDLDecomp: A = "<<TMV_Text(A)<<" "<<A0<<endl; cerr<<"Done: A = "<<A<<endl; cerr<<"L = "<<L<<endl; cerr<<"D = "<<D<<endl; cerr<<"LT = "<<L.transpose()<<endl; cerr<<"L*D*LT = "<<A2<<endl; cerr<<"Norm(diff) = "<<Norm(A2-A0); cerr<<" Norm(L)^2*Norm(D) = "<<normldl<<endl; abort(); } #endif }
static void NonLapLDL_Decompose(SymBandMatrixView<T> A) { // For tridiagonal Hermitian band matrices, the sqrt can // become a significant fraction of the calculation. // This is unnecessary if we instead decompose A into L D Lt // where L is unit diagonal. // // In this case, the equations become: // // A = L0 D L0t // // ( A00 Ax0t ) = ( 1 0 ) ( D0 0 ) ( 1 Lx0t ) // ( Ax0 Axx ) = ( Lx0 1 ) ( 0 Dx ) ( 0 1 ) // = ( 1 0 ) ( D0 D0 Lx0t ) // = ( Lx0 1 ) ( 0 Dx ) // // The equations from this are: // // A00 = D0 // Ax0 = Lx0 D0 // Axx = Lx0 D0 Lx0t + Axx' // // where Axx' = Dx is the sub-matrix for the next step. // TMVAssert(A.uplo() == Lower); TMVAssert(A.ct() == NonConj); TMVAssert(A.isherm()); TMVAssert(A.nlo() == 1); const ptrdiff_t N = A.size(); #ifdef XDEBUG Matrix<T> A0(A); //cout<<"LDLDecompose:\n"; //cout<<"A = "<<TMV_Text(A)<<" "<<A<<endl; #endif TMV_RealType(T)* Dj = A.realPart().ptr(); T* Lj = A.diag(-1).ptr(); if (A.isdm()) { for(ptrdiff_t j=0;j<N-1;++j) { T Ax0 = *Lj; if (*Dj == TMV_RealType(T)(0)) { #ifdef NOTHROW std::cerr<<"Non Posdef HermBandMatrix found\n"; exit(1); #else throw NonPosDefHermBandLDL<T>(A); #endif } *Lj /= *Dj; if (isReal(T())) ++Dj; else Dj+=2; *Dj -= TMV_REAL(TMV_CONJ(*Lj) * Ax0); ++Lj; } } else { const ptrdiff_t Dstep = A.diag().realPart().step(); const ptrdiff_t Lstep = A.diag().step(); for(ptrdiff_t j=0;j<N-1;++j) { T Ax0 = *Lj; if (*Dj == TMV_RealType(T)(0)) { #ifdef NOTHROW std::cerr<<"Non Posdef HermBandMatrix found\n"; exit(1); #else throw NonPosDefHermBandLDL<T>(A); #endif } *Lj /= *Dj; Dj += Dstep; *Dj -= TMV_REAL(TMV_CONJ(*Lj) * Ax0); Lj += Lstep; } } if (*Dj == TMV_RealType(T)(0)) { #ifdef NOTHROW std::cerr<<"Non Posdef HermBandMatrix found\n"; exit(1); #else throw NonPosDefHermBandLDL<T>(A); #endif } #ifdef XDEBUG //cout<<"Done LDLDecompose\n"; BandMatrix<T> L = A.lowerBand(); L.diag().SetAllTo(T(1)); DiagMatrix<T> D = DiagMatrixViewOf(A.diag()); BandMatrix<T> A2 = L * D * L.adjoint(); TMV_RealType(T) normldl = TMV_SQR(Norm(L))*Norm(D); //cout<<"Done: A = "<<A<<endl; //cout<<"L = "<<L<<endl; //cout<<"D = "<<D<<endl; //cout<<"A2 = "<<A2<<endl; //cout<<"cf A0 = "<<A0<<endl; if (!(Norm(A2-A0) < 0.001*normldl)) { cerr<<"LDL_Decompose: A = "<<TMV_Text(A)<<" "<<A0<<endl; cerr<<"Done: A = "<<A<<endl; cerr<<"L = "<<L<<endl; cerr<<"D = "<<D<<endl; cerr<<"Lt = "<<L.adjoint()<<endl; cerr<<"L*D*Lt = "<<A2<<endl; cerr<<"Norm(diff) = "<<Norm(A2-A0); cerr<<" Norm(L)^2*Norm(D) = "<<normldl<<endl; abort(); } #endif }