@@ -486,14 +486,26 @@ Tpsa<V,N,TYPE> operator / (const T& o1, const Tpsa<V,N,TYPE>& o2) { return o2.in
486
486
487
487
template <unsigned int V, unsigned int N, typename TYPE>
488
488
Tpsa<V,N,TYPE> pow (const Tpsa<V,N,TYPE>& a_, const int n) {
489
- Tpsa<V,N,TYPE> r;
490
- Tpsa<V,N,TYPE> x (a_); x.c [0 ] = 0 ; x /= a_.c [0 ];
491
- int n_ = N < n ? N : n;
492
- for (unsigned int i=0 ; i<=n_; i++) {
493
- r *= 1 + x;
494
- }
495
- r *= std::pow (a_.c [0 ], n);
496
- return r;
489
+ if (n <= N) {
490
+ // simple tpsa multiplication
491
+ Tpsa<V,N,TYPE> r (a_);
492
+ for (unsigned int i=0 ; i<n-1 ; i++) r *= a_;
493
+ return r;
494
+ } else {
495
+ // for more efficient computation when n >~ N,
496
+ // multiplication implemented as N-truncated binomial expansion a0^n*(1 + x/a0)^n, x^(N+1) = 0
497
+ Tpsa<V,N,TYPE> r;
498
+ Tpsa<V,N,TYPE> x (a_); x.c [0 ] = 0 ; x /= a_.c [0 ];
499
+ Tpsa<V,N,TYPE> p (1 );
500
+ TYPE f = 1 ; // binomial coefficient
501
+ for (unsigned int i=0 ; i<=N; i++) {
502
+ r += p * f;
503
+ f *= TYPE (n - i) / (i + 1 );
504
+ p *= x;
505
+ }
506
+ r *= std::pow (a_.c [0 ], n);
507
+ return r;
508
+ };
497
509
}
498
510
499
511
template <unsigned int V, unsigned int N, typename TYPE>
@@ -507,7 +519,7 @@ Tpsa<V,N,TYPE> sqrt(const Tpsa<V,N,TYPE>& a_) {
507
519
Tpsa<V,N,TYPE> r;
508
520
Tpsa<V,N,TYPE> x (a_); x.c [0 ] = 0 ; x /= a_.c [0 ];
509
521
Tpsa<V,N,TYPE> p (1 );
510
- TYPE f = 1 ;
522
+ TYPE f = 1 ;
511
523
for (unsigned int i=0 ; i<=N; i++) {
512
524
r += p * f;
513
525
f *= (0.5 - i)/(i+1 );
0 commit comments