diff --git a/matexp.h b/matexp.h index 447b9e9..85aa814 100644 --- a/matexp.h +++ b/matexp.h @@ -53,6 +53,8 @@ return y; //algorithm which minimazes number of multiplications, at the cost of storage +//(block summation, Paterson-Stockmeyer): sum_i s_i (x^m)^i with s_i = sum_{j const T polynom(const T &x, const NRVec &c) { @@ -65,7 +67,7 @@ if(n<=4) return polynom0(x,c); //here the horner scheme is optimal j=10*n; for(i=2;i<=n+1;i++) { - t=i-2+2*(n/i)-(n%i)?0:1; + t=i-2+2*(n/i)-((n%i)?0:1); if(t=m) xpows[m-1]=xpows[m-2]*x; //run the summation loop @@ -85,6 +88,11 @@ T r,s,f; k= -1; for(i=0; i<=n/m;i++) { + if(i>0 && i*m==n) //last block with c[n] only: no multiplication needed + { + LA_traits::axpy(r,f,c[n]); + break; + } for(j=0;j::axpy(s,xpows[j-1],c[k]); //general s+=xpows[j-1]*c[k]; but more efficient for matrices } - if(i==0) {r=s; f=xpows[m-1];} + if(i==0) {r=s; if(n>=m) f=xpows[m-1];} else { r+= s*f; - f=f*xpows[m-1]; + if(i -const T exp(const T &x, bool horner=true, int maxpower= -1, int maxtaylor= -1 ) +const T exp(const T &x, bool horner=false, int maxpower= -1, int maxtaylor= -1 ) { int power; @@ -354,7 +363,7 @@ return r; //make exp(iH) with real H in real arithmetics template -void sincos(T &s, T &c, const T &x, bool horner=true, int maxpower= -1, int maxtaylor= -1 ) +void sincos(T &s, T &c, const T &x, bool horner=false, int maxpower= -1, int maxtaylor= -1 ) { int power;