Matrix gamma_exp(const SMatrix& S,const vector<double>& D,double alpha,double beta) { const int n = S.size1(); std::vector<double> DP(n); std::vector<double> DN(n); for(int i=0; i<D.size(); i++) { DP[i] = sqrt(D[i]); DN[i] = 1.0/DP[i]; } SMatrix S2 = S; for(int i=0; i<S2.size1(); i++) for(int j=0; j<=i; j++) S2(i,j) *= DP[i]*DP[j]; Matrix E = gamma_exp(S2,alpha,beta); // E = prod(DN,prod<Matrix>(E,DP)); for(int i=0; i<E.size1(); i++) for(int j=0; j<E.size2(); j++) E(i,j) *= DN[i]*DP[j]; for(int i=0; i<E.size1(); i++) for(int j=0; j<E.size2(); j++) { assert(E(i,j) >= -1.0e-13); if (E(i,j)<0) E(i,j)=0; } return E; }
Matrix exp(const SMatrix& S,const vector<double>& D,double t) { const int n = S.size1(); // compute S2 = D^1/2 * S * D^1/2 std::vector<double> DP(n); std::vector<double> DN(n); for(int i=0; i<D.size(); i++) { DP[i] = sqrt(D[i]); DN[i] = 1.0/DP[i]; } //SMatrix S2 = prod(DP,prod<Matrix>(S,DP)); SMatrix S2 = S; for(int i=0; i<S2.size1(); i++) for(int j=0; j<=i; j++) S2(i,j) *= DP[i]*DP[j]; // compute E = exp(S2) Matrix E = exp(S2,t); for(int i=0; i<E.size1(); i++) for(int j=0; j<E.size2(); j++) E(i,j) *= DN[i]*DP[j]; // Double-check that E(i,j) is always positive for(int i=0; i<E.size1(); i++) for(int j=0; j<E.size2(); j++) { assert(E(i,j) >= -1.0e-13); if (E(i,j)<0) E(i,j)=0; } return E; }