std::vector<typename MAT::type> cal_det_as_vector(const O& creation_operators, const O& annihilation_operators, MAT& M, double BETA, const G& F) { typedef typename MAT::type SCALAR; const int size1 = creation_operators.size(); if (size1 == 0) { throw std::runtime_error("size is zero in cal_det_as_vector"); } assert(creation_operators.size() == annihilation_operators.size()); Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> matrix(size1, size1); construct_blas_matrix(matrix, creation_operators, annihilation_operators, BETA, F); Eigen::FullPivLU<Eigen::Matrix<SCALAR, Eigen::Dynamic, Eigen::Dynamic> > lu(matrix); std::vector<SCALAR> results(size1); for (int i = 0; i < size1; ++i) { results[i] = lu.matrixLU()(i,i); } results[0] *= lu.permutationP().determinant()*lu.permutationQ().determinant(); M.destructive_resize(size1, size1); if (size1 > 0) { M.block() = matrix; M.safe_invert(); } return results; }
typename MAT::type det_rat_row_column_up(int flavor_ins, int flavor_rem, double t_ins, double t_rem, int row, int column, const MAT & M, const operator_container_t& creation_operators, const operator_container_t& annihilation_operators, const HYB& F, MAT2& sign_Fs, MAT2& Fe_M, double BETA) { typedef typename MAT::type SCALAR; const double sign=((row+column)%2==0 ? 1 : -1); if (annihilation_operators.size()>0) { operator_container_t::iterator it_c=creation_operators.begin(); operator_container_t::iterator it_a=annihilation_operators.begin(); Eigen::Matrix<SCALAR,Eigen::Dynamic,Eigen::Dynamic> Fe(1,annihilation_operators.size()); if (annihilation_operators.size()!=creation_operators.size()) { throw std::runtime_error("annihilation_operators.size()!=creation_operators.size() in det_rat_row_column_up"); } for (int i=0; i<(int)creation_operators.size(); i++) { Fe(0,i) = interpolate_F(t_rem-it_c->time(), BETA, F[flavor_rem][it_c->flavor()]); sign_Fs(i,0) = sign*interpolate_F(it_a->time()-t_ins, BETA, F[(int)(it_a->flavor())][flavor_ins]); it_c++; it_a++; } Fe_M = Fe*M.block(); return sign*interpolate_F(t_rem-t_ins, BETA, F[flavor_rem][flavor_ins])-(Fe_M*sign_Fs)(0,0); } else { return sign*interpolate_F(t_rem-t_ins, BETA, F[flavor_rem][flavor_ins]); } }
RET cal_det(const O& creation_operators, const O& annihilation_operators, MAT& M, double BETA, const G& F) { typedef typename MAT::type SCALAR; const int size1 = creation_operators.size(); if (size1==0) return RET(1.0); assert(creation_operators.size()==annihilation_operators.size()); Eigen::Matrix<SCALAR,Eigen::Dynamic,Eigen::Dynamic> matrix(size1,size1); construct_blas_matrix(matrix, creation_operators, annihilation_operators, BETA, F); RET det = safe_determinant<RET>(matrix); M.destructive_resize(size1,size1); if (size1>0) { M.block() = matrix; M.safe_invert(); } return det; }
void compute_M_row_column_up(int row, int column, MAT & M, MAT2& sign_Fs, MAT2& Fe_M, typename MAT::type det_rat) { typedef typename MAT::type SCALAR; SCALAR det_rat_inv=1./det_rat; double sign=((row+column)%2==0 ? 1 : -1); Eigen::Matrix<SCALAR,Eigen::Dynamic,Eigen::Dynamic> M_sign_Fs(sign_Fs.size(),1); M_sign_Fs = M.block()*sign_Fs; assert(M.size1()==M.size2()); MAT M_new(M.size1()+1,M.size2()+1); int i_new; int j_new; // element (j,i) M_new(column,row) = sign*det_rat_inv; // row j and column i for (int k=0; k<M.size1(); k++) { i_new = (k<column ? k : k+1); j_new = (k<row ? k : k+1); M_new(i_new,row) = -M_sign_Fs(k)*det_rat_inv; M_new(column,j_new) = -sign*Fe_M(k)*det_rat_inv; } // remaining elements for (int k=0; k<M.size1(); k++) { i_new = (k<column ? k : k+1); for (int l=0; l<M.size1(); l++) { j_new = (l<row ? l : l+1); M_new(i_new, j_new) = M(k,l) + M_sign_Fs(k)*Fe_M(l)*det_rat_inv; } } M_new.swap(M); return; }