void HDF5IO::saveMatrix(const std::string& GroupName, const std::string& Name, const ComplexMatrixType& M) { try{ H5::CompType ComplexDataType = this->openCompType("complex"); hsize_t Dims[2] = {hsize_t(M.rows()),hsize_t(M.cols())}; H5::DataSpace dataspace(2,Dims); H5::Group FG = getGroup( GroupName ); try{ H5::Exception::dontPrint(); H5::DataSet dset = FG.openDataSet(Name.c_str()); // dset.extend( Dims );not working dset.write(M.data(), ComplexDataType); } catch ( const H5::GroupIException not_found_error ){ H5::DataSet dset = FG.createDataSet(Name.c_str(), ComplexDataType, dataspace); dset.write(M.data(), ComplexDataType); } catch ( const H5::DataSetIException error ){ error.printError(); RUNTIME_ERROR("HDF5IO::saveComplexMatrix at "); } FG.close(); } catch( const H5::Exception error ){ error.printError(); RUNTIME_ERROR("HDF5IO::saveComplexMatrix at "); } }
template<typename MatrixType> void schur(int size = MatrixType::ColsAtCompileTime) { typedef typename ComplexSchur<MatrixType>::ComplexScalar ComplexScalar; typedef typename ComplexSchur<MatrixType>::ComplexMatrixType ComplexMatrixType; // Test basic functionality: T is triangular and A = U T U* for(int counter = 0; counter < g_repeat; ++counter) { MatrixType A = MatrixType::Random(size, size); ComplexSchur<MatrixType> schurOfA(A); VERIFY_IS_EQUAL(schurOfA.info(), Success); ComplexMatrixType U = schurOfA.matrixU(); ComplexMatrixType T = schurOfA.matrixT(); for(int row = 1; row < size; ++row) { for(int col = 0; col < row; ++col) { VERIFY(T(row,col) == (typename MatrixType::Scalar)0); } } VERIFY_IS_APPROX(A.template cast<ComplexScalar>(), U * T * U.adjoint()); } // Test asserts when not initialized ComplexSchur<MatrixType> csUninitialized; VERIFY_RAISES_ASSERT(csUninitialized.matrixT()); VERIFY_RAISES_ASSERT(csUninitialized.matrixU()); VERIFY_RAISES_ASSERT(csUninitialized.info()); // Test whether compute() and constructor returns same result MatrixType A = MatrixType::Random(size, size); ComplexSchur<MatrixType> cs1; cs1.compute(A); ComplexSchur<MatrixType> cs2(A); VERIFY_IS_EQUAL(cs1.info(), Success); VERIFY_IS_EQUAL(cs2.info(), Success); VERIFY_IS_EQUAL(cs1.matrixT(), cs2.matrixT()); VERIFY_IS_EQUAL(cs1.matrixU(), cs2.matrixU()); // Test computation of only T, not U ComplexSchur<MatrixType> csOnlyT(A, false); VERIFY_IS_EQUAL(csOnlyT.info(), Success); VERIFY_IS_EQUAL(cs1.matrixT(), csOnlyT.matrixT()); VERIFY_RAISES_ASSERT(csOnlyT.matrixU()); if (size > 1) { // Test matrix with NaN A(0,0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN(); ComplexSchur<MatrixType> csNaN(A); VERIFY_IS_EQUAL(csNaN.info(), NoConvergence); } }
void HDF5IO::loadMatrix(const std::string& GroupName, const std::string& Name, ComplexMatrixType& M) { try{ H5::CompType ComplexDataType = this->openCompType("complex"); H5::Group FG = getGroup( GroupName ); H5::DataSet DataSet = FG.openDataSet(Name.c_str()); H5::DataSpace DataSpace = DataSet.getSpace(); if(DataSpace.getSimpleExtentNdims() != 2) throw(H5::DataSpaceIException("HDF5IO::loadMatrix()","A dataspace must be precisely two-dimensional.")); hsize_t Dims[2]; DataSpace.getSimpleExtentDims(Dims); M.resize(Dims[0],Dims[1]); DataSet.read(M.data(), ComplexDataType); FG.close(); } catch( const H5::Exception err ){ RUNTIME_ERROR("HDF5IO::loadComplexMatrix at "); } }
int main(int argc, char const *argv[]) { Eigen::setNbThreads(NumCores); #ifdef MKL mkl_set_num_threads(NumCores); #endif INFO("Eigen3 uses " << Eigen::nbThreads() << " threads."); int L; RealType J12ratio; int OBC; int N; RealType Uin, phi; std::vector<RealType> Vin; LoadParameters( "conf.h5", L, J12ratio, OBC, N, Uin, Vin, phi); HDF5IO file("BSSH.h5"); // const int L = 5; // const bool OBC = true; // const RealType J12ratio = 0.010e0; INFO("Build Lattice - "); std::vector<ComplexType> J; if ( OBC ){ J = std::vector<ComplexType>(L - 1, ComplexType(1.0, 0.0)); for (size_t cnt = 0; cnt < L-1; cnt+=2) { J.at(cnt) *= J12ratio; } } else{ J = std::vector<ComplexType>(L, ComplexType(1.0, 0.0)); for (size_t cnt = 0; cnt < L; cnt+=2) { J.at(cnt) *= J12ratio; } if ( std::abs(phi) > 1.0e-10 ){ J.at(L-1) *= exp( ComplexType(0.0e0, 1.0e0) * phi ); // INFO(exp( ComplexType(0.0e0, 1.0e0) * phi )); } } for ( auto &val : J ){ INFO_NONEWLINE(val << " "); } INFO(""); const std::vector< Node<ComplexType>* > lattice = NN_1D_Chain(L, J, OBC); file.saveNumber("1DChain", "L", L); file.saveNumber("1DChain", "U", Uin); file.saveStdVector("1DChain", "J", J); for ( auto < : lattice ){ if ( !(lt->VerifySite()) ) RUNTIME_ERROR("Wrong lattice setup!"); } INFO("DONE!"); INFO("Build Basis - "); // int N1 = (L+1)/2; Basis B1(L, N); B1.Boson(); // std::vector< std::vector<int> > st = B1.getBStates(); // std::vector< RealType > tg = B1.getBTags(); // for (size_t cnt = 0; cnt < tg.size(); cnt++) { // INFO_NONEWLINE( std::setw(3) << cnt << " - "); // for (auto &j : st.at(cnt)){ // INFO_NONEWLINE(j << " "); // } // INFO("- " << tg.at(cnt)); // } file.saveNumber("1DChain", "N", N); // file.saveStdVector("Basis", "States", st); // file.saveStdVector("Basis", "Tags", tg); INFO("DONE!"); INFO_NONEWLINE("Build Hamiltonian - "); std::vector<Basis> Bases; Bases.push_back(B1); Hamiltonian<ComplexType> ham( Bases ); std::vector< std::vector<ComplexType> > Vloc; std::vector<ComplexType> Vtmp;//(L, 1.0); for ( RealType &val : Vin ){ Vtmp.push_back((ComplexType)val); } Vloc.push_back(Vtmp); std::vector< std::vector<ComplexType> > Uloc; // std::vector<ComplexType> Utmp(L, ComplexType(10.0e0, 0.0e0) ); std::vector<ComplexType> Utmp(L, (ComplexType)Uin); Uloc.push_back(Utmp); ham.BuildLocalHamiltonian(Vloc, Uloc, Bases); ham.BuildHoppingHamiltonian(Bases, lattice); ham.BuildTotalHamiltonian(); INFO("DONE!"); INFO_NONEWLINE("Diagonalize Hamiltonian - "); std::vector<RealType> Val; Hamiltonian<ComplexType>::VectorType Vec; ham.eigh(Val, Vec); INFO("GS energy = " << Val.at(0)); file.saveVector("GS", "EVec", Vec); file.saveStdVector("GS", "EVal", Val); INFO("DONE!"); std::vector<ComplexType> Nbi = Ni( Bases, Vec ); for (auto &n : Nbi ){ INFO( n << " " ); } ComplexMatrixType Nij = NiNj( Bases, Vec ); INFO(Nij); INFO(Nij.diagonal()); file.saveStdVector("Obs", "Nb", Nbi); file.saveMatrix("Obs", "Nij", Nij); return 0; }
void krylov(const ComplexSparseMatrixType &A, ComplexVectorType &Vec, const ComplexType Prefactor, const size_t Kmax) { // INFO(A); const RealType beta_err = 1.0E-12; if (DEBUG) assert( Kmax > 2 ); RealType alpha; RealType beta = 1.0; ComplexMatrixType Vm = ComplexMatrixType::Zero(Vec.size(), Kmax); std::vector<RealType> Alphas; std::vector<RealType> Betas; int cntK = 0; //NOTE: normalized Vec Vec.normalize(); Vm.col(cntK) = Vec; while ( cntK < Kmax ) { ComplexVectorType work = A * Vm.col(cntK); if( cntK > 0 ) work -= beta * Vm.col(cntK-1); ComplexType alpha_c = work.dot( Vm.col(cntK) ); alpha = alpha_c.real(); work -= alpha * Vm.col(cntK); beta = work.norm(); Alphas.push_back(alpha); if( DEBUG > 4 ){ INFO("@ " << cntK << " alpha is " << alpha << " beta is " << beta); } if( beta > beta_err ){ work.normalize(); if( cntK+1 < Kmax ) { Vm.col(cntK+1) = work; Betas.push_back(beta); } cntK++; } else{ cntK++; break; } } if ( DEBUG ) { assert( Alphas.size() == cntK ); assert( Betas.size() == cntK - 1 ); if ( DEBUG > 5 ) { ComplexMatrixType tmpVm = Vm; tmpVm.adjointInPlace(); INFO( "Vm^H * Vm " << std::endl << tmpVm * Vm); } } int Kused = cntK; if ( Kused == 1 ){ /* NOTE: This is a special case that input vector is eigenvector */ Vec = exp(Prefactor * Alphas.at(0)) * Vec; } else{ /* NOTE: The floowing codes use Eigen to solve the tri-diagonal matrix. If we use this, we need the Eigen header in this file. */ // RealMatrixType TriDiag = RealMatrixType::Zero(Kused, Kused); // for (size_t cnt = 0; cnt < Kused; cnt++) { // TriDiag(cnt, cnt) = Alphas.at(cnt); // if (cnt > 0) { // TriDiag(cnt, cnt-1) = Betas.at(cnt - 1); // TriDiag(cnt-1, cnt) = Betas.at(cnt - 1); // } // } // Eigen::SelfAdjointEigenSolver<RealMatrixType> es; // es.compute(TriDiag); // RealVectorType Dvec = es.eigenvalues(); // ComplexMatrixType Dmat = ComplexMatrixType::Zero(Kused, Kused); // for (size_t cnt = 0; cnt < Kused; cnt++) { // Dmat(cnt,cnt) = exp( Prefactor * Dvec(cnt) ); // } // RealMatrixType Kmat = es.eigenvectors(); /* NOTE: The floowing codes use MKL Lapack to solve the tri-diagonal matrix */ RealType* d = &Alphas[0]; RealType* e = &Betas[0]; RealType* z = (RealType*)malloc(Kused * Kused * sizeof(RealType)); RealType* work = (RealType*)malloc(4 * Kused * sizeof(RealType)); int info; //dstev - LAPACK dstev((char*)"V", &Kused, d, e, z, &Kused, work, &info); Eigen::Map<RealMatrixType> Kmat(z, Kused, Kused); Kmat.transposeInPlace(); ComplexMatrixType Dmat = ComplexMatrixType::Zero(Kused, Kused); for (size_t cnt = 0; cnt < Kused; cnt++) { Dmat(cnt,cnt) = exp( Prefactor * d[cnt] ); } if(info != 0){ INFO("Lapack INFO = " << info); RUNTIME_ERROR("Error in Lapack function 'dstev'"); } /* NOTE: After Solving tri-diagonal matrix, we need Kmat and Dmat to proceed further. */ if ( DEBUG > 4 ) { RealMatrixType tmpKmat = Kmat; tmpKmat.transposeInPlace(); INFO( Kmat * Dmat * tmpKmat ); } ComplexMatrixType Otmp = Vm.block(0, 0, Vec.size(), Kused) * Kmat; Vec = ( Otmp * Dmat ) * ( Otmp.adjoint() * Vec ); } }
template<typename MatrixType> void schur(int size = MatrixType::ColsAtCompileTime) { typedef typename ComplexSchur<MatrixType>::ComplexScalar ComplexScalar; typedef typename ComplexSchur<MatrixType>::ComplexMatrixType ComplexMatrixType; // Test basic functionality: T is triangular and A = U T U* for(int counter = 0; counter < g_repeat; ++counter) { MatrixType A = MatrixType::Random(size, size); ComplexSchur<MatrixType> schurOfA(A); VERIFY_IS_EQUAL(schurOfA.info(), Success); ComplexMatrixType U = schurOfA.matrixU(); ComplexMatrixType T = schurOfA.matrixT(); for(int row = 1; row < size; ++row) { for(int col = 0; col < row; ++col) { VERIFY(T(row,col) == (typename MatrixType::Scalar)0); } } VERIFY_IS_APPROX(A.template cast<ComplexScalar>(), U * T * U.adjoint()); } // Test asserts when not initialized ComplexSchur<MatrixType> csUninitialized; VERIFY_RAISES_ASSERT(csUninitialized.matrixT()); VERIFY_RAISES_ASSERT(csUninitialized.matrixU()); VERIFY_RAISES_ASSERT(csUninitialized.info()); // Test whether compute() and constructor returns same result MatrixType A = MatrixType::Random(size, size); ComplexSchur<MatrixType> cs1; cs1.compute(A); ComplexSchur<MatrixType> cs2(A); VERIFY_IS_EQUAL(cs1.info(), Success); VERIFY_IS_EQUAL(cs2.info(), Success); VERIFY_IS_EQUAL(cs1.matrixT(), cs2.matrixT()); VERIFY_IS_EQUAL(cs1.matrixU(), cs2.matrixU()); // Test maximum number of iterations ComplexSchur<MatrixType> cs3; cs3.setMaxIterations(ComplexSchur<MatrixType>::m_maxIterationsPerRow * size).compute(A); VERIFY_IS_EQUAL(cs3.info(), Success); VERIFY_IS_EQUAL(cs3.matrixT(), cs1.matrixT()); VERIFY_IS_EQUAL(cs3.matrixU(), cs1.matrixU()); cs3.setMaxIterations(1).compute(A); VERIFY_IS_EQUAL(cs3.info(), size > 1 ? NoConvergence : Success); VERIFY_IS_EQUAL(cs3.getMaxIterations(), 1); MatrixType Atriangular = A; Atriangular.template triangularView<StrictlyLower>().setZero(); cs3.setMaxIterations(1).compute(Atriangular); // triangular matrices do not need any iterations VERIFY_IS_EQUAL(cs3.info(), Success); VERIFY_IS_EQUAL(cs3.matrixT(), Atriangular.template cast<ComplexScalar>()); VERIFY_IS_EQUAL(cs3.matrixU(), ComplexMatrixType::Identity(size, size)); // Test computation of only T, not U ComplexSchur<MatrixType> csOnlyT(A, false); VERIFY_IS_EQUAL(csOnlyT.info(), Success); VERIFY_IS_EQUAL(cs1.matrixT(), csOnlyT.matrixT()); VERIFY_RAISES_ASSERT(csOnlyT.matrixU()); if (size > 1 && size < 20) { // Test matrix with NaN A(0,0) = std::numeric_limits<typename MatrixType::RealScalar>::quiet_NaN(); ComplexSchur<MatrixType> csNaN(A); VERIFY_IS_EQUAL(csNaN.info(), NoConvergence); } }