int main(void) { int n=400, noisy=0, i,j; int nr=10, ir, TimeSquare=10, algorithm; /* TimeSquare should be larger for large t */ double t=5, *Q, *pi, *space, s; char timestr[96], *AlgStr[2]={"repeated squaring", "eigensolution"}; if((Q=(double*)malloc(n*n*5*sizeof(double))) ==NULL) error2("oom"); pi=Q+n*n; space=pi+n; for(algorithm=0; algorithm<2; algorithm++) { starttime(); SetSeed(1234567); for (i=0; i<n; i++) pi[i]=rndu(); s=sum(pi,n); for (i=0; i<n; i++) pi[i]/=s; for(ir=0; ir<nr; ir++) { printf("Replicate %d/%d ", ir+1,nr); for (i=0; i<n; i++) for (j=0,Q[i*n+i]=0; j<i; j++) Q[i*n+j]=Q[j*n+i] = square(rndu()); for (i=0; i<n; i++) for (j=0; j<n; j++) Q[i*n+j] *= pi[j]; for(i=0,s=0; i<n; i++) { /* rescaling Q so that average rate is 1 */ Q[i*n+i]=0; Q[i*n+i]=-sum(Q+i*n, n); s-=pi[i]*Q[i*n+i]; } if(noisy) { matout(stdout, pi, 1, n); matout(stdout, Q, n, n); } if(algorithm==0) matexp(Q, 1, n, TimeSquare, space); else PMatQRev(Q, pi, 1, n, space); printf("%s, time: %s\n", AlgStr[algorithm], printtime(timestr)); if(noisy) matout(stdout, Q, n, n); } } return (0); }
SEXP R_matexp(SEXP A, SEXP p) { R_INIT; const int n = nrows(A); int i; double *A_cp; SEXP R; newRmat(R, n, n, "dbl"); A_cp = (double *) R_alloc(n*n, sizeof(A_cp)); for (i=0; i<n*n; i++) A_cp[i] = REAL(A)[i]; matexp(n, INT(p), A_cp, REAL(R)); R_END; return R; }