Sacado Package Browser (Single Doxygen Collection)  Version of the Day
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Sacado_Tay_TaylorImp.hpp
Go to the documentation of this file.
1 // @HEADER
2 // ***********************************************************************
3 //
4 // Sacado Package
5 // Copyright (2006) Sandia Corporation
6 //
7 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
8 // license for use of this work by or on behalf of the U.S. Government.
9 //
10 // This library is free software; you can redistribute it and/or modify
11 // it under the terms of the GNU Lesser General Public License as
12 // published by the Free Software Foundation; either version 2.1 of the
13 // License, or (at your option) any later version.
14 //
15 // This library is distributed in the hope that it will be useful, but
16 // WITHOUT ANY WARRANTY; without even the implied warranty of
17 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 // Lesser General Public License for more details.
19 //
20 // You should have received a copy of the GNU Lesser General Public
21 // License along with this library; if not, write to the Free Software
22 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
23 // USA
24 // Questions? Contact David M. Gay (dmgay@sandia.gov) or Eric T. Phipps
25 // (etphipp@sandia.gov).
26 //
27 // ***********************************************************************
28 // @HEADER
29 
30 // disable clang warnings
31 #if defined (__clang__) && !defined (__INTEL_COMPILER)
32 #pragma clang system_header
33 #endif
34 
35 #include "Sacado_ConfigDefs.h"
37 #include <ostream> // for std::ostream
38 
39 namespace Sacado {
40 namespace Tay {
41 
42 template <typename T>
45  coeff_(NULL), deg_(-1), len_(0)
46 {
47 }
48 
49 template <typename T>
51 TaylorData(const T& x) :
52  coeff_(), deg_(0), len_(1)
53 {
55  coeff_[0] = x;
56 }
57 
58 template <typename T>
60 TaylorData(int d, const T& x) :
61  coeff_(), deg_(d), len_(d+1)
62 {
64  coeff_[0] = x;
65 }
66 
67 template <typename T>
69 TaylorData(int d) :
70  coeff_(), deg_(d), len_(d+1)
71 {
73 }
74 
75 template <typename T>
77 TaylorData(int d, int l) :
78  coeff_(), deg_(d), len_(l)
79 {
81 }
82 
83 template <typename T>
85 TaylorData(const typename Taylor<T>::TaylorData& x) :
86  coeff_(), deg_(x.deg_), len_(x.deg_+1)
87 {
89 }
90 
91 template <typename T>
94 {
95  if (len_ > 0)
97 }
98 
99 template <typename T>
100 typename Taylor<T>::TaylorData&
103 {
104  if (len_ < x.deg_+1) {
106  len_ = x.deg_+1;
107  deg_ = x.deg_;
108  coeff_ = Sacado::ds_array<T>::get_and_fill(x.coeff_, len_);
109  }
110  else {
111  deg_ = x.deg_;
112  Sacado::ds_array<T>::copy(x.coeff_, coeff_, deg_+1);
113  }
114 
115  return *this;
116 }
117 
118 template <typename T>
121  th(new TaylorData)
122 {
123 }
124 
125 template <typename T>
127 Taylor(const T& x) :
128  th(new TaylorData(x))
129 {
130 }
131 
132 template <typename T>
135  th(new TaylorData(value_type(x)))
136 {
137 }
138 
139 template <typename T>
141 Taylor(int d, const T& x) :
142  th(new TaylorData(d, x))
143 {
144 }
145 
146 template <typename T>
148 Taylor(int d) :
149  th(new TaylorData(d))
150 {
151 }
152 
153 template <typename T>
155 Taylor(const Taylor<T>& x) :
156  th(x.th)
157 {
158 }
159 
160 template <typename T>
163 {
164 }
165 
166 template <typename T>
167 void
169 resize(int d, bool keep_coeffs)
170 {
171  if (d+1 > length()) {
173  if (keep_coeffs)
174  Sacado::ds_array<T>::copy(th->coeff_, h->coeff_, th->deg_+1);
175  th = h;
176  }
177  else {
178  th.makeOwnCopy();
179  if (!keep_coeffs)
180  Sacado::ds_array<T>::zero(coeff(), degree()+1);
181  th->deg_ = d;
182  }
183 }
184 
185 template <typename T>
186 void
188 reserve(int d)
189 {
190  if (d+1 > length()) {
191  Sacado::Handle<TaylorData> h(new TaylorData(th->deg_,d+1));
192  Sacado::ds_array<T>::copy(th->coeff_, h->coeff_, th->deg_+1);
193  th = h;
194  }
195 }
196 
197 template <typename T>
198 Taylor<T>&
200 operator=(const T& v)
201 {
202  th.makeOwnCopy();
203 
204  if (th->len_ == 0) {
205  th->len_ = 1;
206  th->deg_ = 0;
207  th->coeff_ = Sacado::ds_array<T>::get_and_fill(th->len_);
208  }
209 
210  th->coeff_[0] = v;
211  Sacado::ds_array<T>::zero(th->coeff_+1, th->deg_);
212 
213  return *this;
214 }
215 
216 template <typename T>
217 Taylor<T>&
220 {
221  return operator=(value_type(v));
222 }
223 
224 template <typename T>
225 Taylor<T>&
228 {
229  th = x.th;
230  return *this;
231 }
232 
233 template <typename T>
234 Taylor<T>
236 operator+() const
237 {
238  return *this;
239 }
240 
241 template <typename T>
242 Taylor<T>
244 operator-() const
245 {
246  Taylor<T> x;
247  x.th->deg_ = th->deg_;
248  x.th->len_ = th->deg_+1;
249  x.th->coeff_ = Sacado::ds_array<T>::get_and_fill(x.th->len_);
250  for (int i=0; i<=th->deg_; i++)
251  x.th->coeff_[i] = -th->coeff_[i];
252 
253  return x;
254 }
255 
256 template <typename T>
257  Taylor<T>&
259 operator+=(const T& v)
260 {
261  th.makeOwnCopy();
262 
263  th->coeff_[0] += v;
264 
265  return *this;
266 }
267 
268 template <typename T>
269 Taylor<T>&
271 operator-=(const T& v)
272 {
273  th.makeOwnCopy();
274 
275  th->coeff_[0] -= v;
276 
277  return *this;
278 }
279 
280 template <typename T>
281 Taylor<T>&
283 operator*=(const T& v)
284 {
285  th.makeOwnCopy();
286 
287  for (int i=0; i<=th->deg_; i++)
288  th->coeff_[i] *= v;
289 
290  return *this;
291 }
292 
293 template <typename T>
294 Taylor<T>&
296 operator/=(const T& v)
297 {
298  th.makeOwnCopy();
299 
300  for (int i=0; i<=th->deg_; i++)
301  th->coeff_[i] /= v;
302 
303  return *this;
304 }
305 
306 template <typename T>
307 Taylor<T>&
310 {
311  th.makeOwnCopy();
312 
313  int d = degree();
314  int xd = x.degree();
315  int dmin = xd < d ? xd : d;
316 
317  int l = xd + 1;
318  bool need_resize = l > length();
319  T* c;
320  if (need_resize) {
322  for (int i=0; i<=d; i++)
323  c[i] = fastAccessCoeff(i);
324  }
325  else
326  c = th->coeff_;
327  T* xc = x.th->coeff_;
328 
329  for (int i=0; i<=dmin; i++)
330  c[i] += xc[i];
331  if (th->deg_ < xd) {
332  for (int i=d+1; i<=xd; i++)
333  c[i] = xc[i];
334  th->deg_ = xd;
335  }
336 
337  if (need_resize) {
338  Sacado::ds_array<T>::destroy_and_release(th->coeff_, th->len_);
339  th->len_ = l;
340  th->coeff_ = c;
341  }
342 
343  return *this;
344 }
345 
346 template <typename T>
347 Taylor<T>&
350 {
351  th.makeOwnCopy();
352 
353  int d = degree();
354  int xd = x.degree();
355  int dmin = xd < d ? xd : d;
356 
357  int l = xd + 1;
358  bool need_resize = l > length();
359  T* c;
360  if (need_resize) {
362  for (int i=0; i<=d; i++)
363  c[i] = fastAccessCoeff(i);
364  }
365  else
366  c = th->coeff_;
367  T* xc = x.th->coeff_;
368 
369  for (int i=0; i<=dmin; i++)
370  c[i] -= xc[i];
371  if (d < xd) {
372  for (int i=d+1; i<=xd; i++)
373  c[i] = -xc[i];
374  th->deg_ = xd;
375  }
376 
377  if (need_resize) {
378  Sacado::ds_array<T>::destroy_and_release(th->coeff_, th->len_);
379  th->len_ = l;
380  th->coeff_ = c;
381  }
382 
383  return *this;
384 }
385 
386 template <typename T>
387 Taylor<T>&
390 {
391  int d = degree();
392  int xd = x.degree();
393 
394 #ifdef SACADO_DEBUG
395  if ((xd != d) && (xd != 0) && (d != 0))
396  throw "Taylor Error: Attempt to assign with incompatible degrees";
397 #endif
398 
399  T* c = th->coeff_;
400  T* xc = x.th->coeff_;
401 
402  if (d > 0 && xd > 0) {
404  T* cc = h->coeff_;
405  T tmp;
406  for (int i=0; i<=d; i++) {
407  tmp = T(0.0);
408  for (int k=0; k<=i; ++k)
409  tmp += c[k]*xc[i-k];
410  cc[i] = tmp;
411  }
412  th = h;
413  }
414  else if (d > 0) {
415  th.makeOwnCopy();
416  for (int i=0; i<=d; i++)
417  c[i] = c[i]*xc[0];
418  }
419  else if (xd >= 0) {
420  if (length() < xd+1) {
422  T* cc = h->coeff_;
423  for (int i=0; i<=xd; i++)
424  cc[i] = c[0]*xc[i];
425  th = h;
426  }
427  else {
428  th.makeOwnCopy();
429  for (int i=d; i>=0; i--)
430  c[i] = c[0]*xc[i];
431  }
432  }
433 
434  return *this;
435 }
436 
437 template <typename T>
438 Taylor<T>&
441 {
442  int d = degree();
443  int xd = x.degree();
444 
445 #ifdef SACADO_DEBUG
446  if ((xd != d) && (xd != 0) && (d != 0))
447  throw "Taylor Error: Attempt to assign with incompatible degrees";
448 #endif
449 
450  T* c = th->coeff_;
451  T* xc = x.th->coeff_;
452 
453  if (d > 0 && xd > 0) {
455  T* cc = h->coeff_;
456  T tmp;
457  for(int i=0; i<=d; i++) {
458  tmp = c[i];
459  for (int k=1; k<=i; ++k)
460  tmp -= xc[k]*cc[i-k];
461  cc[i] = tmp / xc[0];
462  }
463  th = h;
464  }
465  else if (d > 0) {
466  th.makeOwnCopy();
467  for (int i=0; i<=d; i++)
468  c[i] = c[i]/xc[0];
469  }
470  else if (xd >= 0) {
472  T* cc = h->coeff_;
473  T tmp;
474  cc[0] = c[0] / xc[0];
475  for (int i=1; i<=xd; i++) {
476  tmp = T(0.0);
477  for (int k=1; k<=i; ++k)
478  tmp -= xc[k]*cc[i-k];
479  cc[i] = tmp / xc[0];
480  }
481  th = h;
482  }
483 
484  return *this;
485 }
486 
487 template <typename T>
488 void
490 resizeCoeffs(int len)
491 {
492  if (th->coeff_)
493  Sacado::ds_array<T>::destroy_and_release(th->coeff_, th->len_);
494  th->len_ = len;
495  th->coeff_ = Sacado::ds_array<T>::get_and_fill(th->len_);
496 }
497 
498 template <typename T>
499 Taylor<T>
500 operator+(const Base< Taylor<T> >& aa,
501  const Base< Taylor<T> >& bb)
502 {
503  const Taylor<T>& a = aa.derived();
504  const Taylor<T>& b = bb.derived();
505 
506  int da = a.degree();
507  int db = b.degree();
508  int dc = da > db ? da : db;
509 
510 #ifdef SACADO_DEBUG
511  if ((da != db) && (da != 0) && (db != 0))
512  throw "operator+(): Arguments have incompatible degrees!";
513 #endif
514 
515  Taylor<T> c(dc);
516  const T* ca = a.coeff();
517  const T* cb = b.coeff();
518  T* cc = c.coeff();
519 
520  if (da > 0 && db > 0) {
521  for (int i=0; i<=dc; i++)
522  cc[i] = ca[i] + cb[i];
523  }
524  else if (da > 0) {
525  cc[0] = ca[0] + cb[0];
526  for (int i=1; i<=dc; i++)
527  cc[i] = ca[i];
528  }
529  else if (db >= 0) {
530  cc[0] = ca[0] + cb[0];
531  for (int i=1; i<=dc; i++)
532  cc[i] = cb[i];
533  }
534 
535  return c;
536 }
537 
538 template <typename T>
539 Taylor<T>
541  const Base< Taylor<T> >& bb)
542 {
543  const Taylor<T>& b = bb.derived();
544 
545  int dc = b.degree();
546 
547  Taylor<T> c(dc);
548  const T* cb = b.coeff();
549  T* cc = c.coeff();
550 
551  cc[0] = a + cb[0];
552  for (int i=1; i<=dc; i++)
553  cc[i] = cb[i];
554 
555  return c;
556 }
557 
558 template <typename T>
559 Taylor<T>
560 operator+(const Base< Taylor<T> >& aa,
561  const typename Taylor<T>::value_type& b)
562 {
563  const Taylor<T>& a = aa.derived();
564 
565  int dc = a.degree();
566 
567  Taylor<T> c(dc);
568  const T* ca = a.coeff();
569  T* cc = c.coeff();
570 
571  cc[0] = ca[0] + b;
572  for (int i=1; i<=dc; i++)
573  cc[i] = ca[i];
574 
575  return c;
576 }
577 
578 template <typename T>
579 Taylor<T>
580 operator-(const Base< Taylor<T> >& aa,
581  const Base< Taylor<T> >& bb)
582 {
583  const Taylor<T>& a = aa.derived();
584  const Taylor<T>& b = bb.derived();
585 
586  int da = a.degree();
587  int db = b.degree();
588  int dc = da > db ? da : db;
589 
590 #ifdef SACADO_DEBUG
591  if ((da != db) && (da != 0) && (db != 0))
592  throw "operator+(): Arguments have incompatible degrees!";
593 #endif
594 
595  Taylor<T> c(dc);
596  const T* ca = a.coeff();
597  const T* cb = b.coeff();
598  T* cc = c.coeff();
599 
600  if (da > 0 && db > 0) {
601  for (int i=0; i<=dc; i++)
602  cc[i] = ca[i] - cb[i];
603  }
604  else if (da > 0) {
605  cc[0] = ca[0] - cb[0];
606  for (int i=1; i<=dc; i++)
607  cc[i] = ca[i];
608  }
609  else if (db >= 0) {
610  cc[0] = ca[0] - cb[0];
611  for (int i=1; i<=dc; i++)
612  cc[i] = -cb[i];
613  }
614 
615  return c;
616 }
617 
618 template <typename T>
619 Taylor<T>
621  const Base< Taylor<T> >& bb)
622 {
623  const Taylor<T>& b = bb.derived();
624 
625  int dc = b.degree();
626 
627  Taylor<T> c(dc);
628  const T* cb = b.coeff();
629  T* cc = c.coeff();
630 
631  cc[0] = a - cb[0];
632  for (int i=1; i<=dc; i++)
633  cc[i] = -cb[i];
634 
635  return c;
636 }
637 
638 template <typename T>
639 Taylor<T>
640 operator-(const Base< Taylor<T> >& aa,
641  const typename Taylor<T>::value_type& b)
642 {
643  const Taylor<T>& a = aa.derived();
644 
645  int dc = a.degree();
646 
647  Taylor<T> c(dc);
648  const T* ca = a.coeff();
649  T* cc = c.coeff();
650 
651  cc[0] = ca[0] - b;
652  for (int i=1; i<=dc; i++)
653  cc[i] = ca[i];
654 
655  return c;
656 }
657 
658 template <typename T>
659 Taylor<T>
660 operator*(const Base< Taylor<T> >& aa,
661  const Base< Taylor<T> >& bb)
662 {
663  const Taylor<T>& a = aa.derived();
664  const Taylor<T>& b = bb.derived();
665 
666  int da = a.degree();
667  int db = b.degree();
668  int dc = da > db ? da : db;
669 
670 #ifdef SACADO_DEBUG
671  if ((da != db) && (da != 0) && (db != 0))
672  throw "operator+(): Arguments have incompatible degrees!";
673 #endif
674 
675  Taylor<T> c(dc);
676  const T* ca = a.coeff();
677  const T* cb = b.coeff();
678  T* cc = c.coeff();
679 
680  if (da > 0 && db > 0) {
681  T tmp;
682  for (int i=0; i<=dc; i++) {
683  tmp = T(0.0);
684  for (int k=0; k<=i; k++)
685  tmp += ca[k]*cb[i-k];
686  cc[i] = tmp;
687  }
688  }
689  else if (da > 0) {
690  for (int i=0; i<=dc; i++)
691  cc[i] = ca[i]*cb[0];
692  }
693  else if (db >= 0) {
694  for (int i=0; i<=dc; i++)
695  cc[i] = ca[0]*cb[i];
696  }
697 
698  return c;
699 }
700 
701 template <typename T>
702 Taylor<T>
704  const Base< Taylor<T> >& bb)
705 {
706  const Taylor<T>& b = bb.derived();
707 
708  int dc = b.degree();
709 
710  Taylor<T> c(dc);
711  const T* cb = b.coeff();
712  T* cc = c.coeff();
713 
714  for (int i=0; i<=dc; i++)
715  cc[i] = a*cb[i];
716 
717  return c;
718 }
719 
720 template <typename T>
721 Taylor<T>
722 operator*(const Base< Taylor<T> >& aa,
723  const typename Taylor<T>::value_type& b)
724 {
725  const Taylor<T>& a = aa.derived();
726 
727  int dc = a.degree();
728 
729  Taylor<T> c(dc);
730  const T* ca = a.coeff();
731  T* cc = c.coeff();
732 
733  for (int i=0; i<=dc; i++)
734  cc[i] = ca[i]*b;
735 
736  return c;
737 }
738 
739 template <typename T>
740 Taylor<T>
741 operator/(const Base< Taylor<T> >& aa,
742  const Base< Taylor<T> >& bb)
743 {
744  const Taylor<T>& a = aa.derived();
745  const Taylor<T>& b = bb.derived();
746 
747  int da = a.degree();
748  int db = b.degree();
749  int dc = da > db ? da : db;
750 
751 #ifdef SACADO_DEBUG
752  if ((da != db) && (da != 0) && (db != 0))
753  throw "operator+(): Arguments have incompatible degrees!";
754 #endif
755 
756  Taylor<T> c(dc);
757  const T* ca = a.coeff();
758  const T* cb = b.coeff();
759  T* cc = c.coeff();
760 
761  if (da > 0 && db > 0) {
762  T tmp;
763  for (int i=0; i<=dc; i++) {
764  tmp = ca[i];
765  for (int k=0; k<=i; k++)
766  tmp -= cb[k]*cc[i-k];
767  cc[i] = tmp / cb[0];
768  }
769  }
770  else if (da > 0) {
771  for (int i=0; i<=dc; i++)
772  cc[i] = ca[i]/cb[0];
773  }
774  else if (db >= 0) {
775  T tmp;
776  cc[0] = ca[0] / cb[0];
777  for (int i=1; i<=dc; i++) {
778  tmp = T(0.0);
779  for (int k=0; k<=i; k++)
780  tmp -= cb[k]*cc[i-k];
781  cc[i] = tmp / cb[0];
782  }
783  }
784 
785  return c;
786 }
787 
788 template <typename T>
789 Taylor<T>
791  const Base< Taylor<T> >& bb)
792 {
793  const Taylor<T>& b = bb.derived();
794 
795  int dc = b.degree();
796 
797  Taylor<T> c(dc);
798  const T* cb = b.coeff();
799  T* cc = c.coeff();
800 
801  T tmp;
802  cc[0] = a / cb[0];
803  for (int i=1; i<=dc; i++) {
804  tmp = T(0.0);
805  for (int k=0; k<=i; k++)
806  tmp -= cb[k]*cc[i-k];
807  cc[i] = tmp / cb[0];
808  }
809 
810  return c;
811 }
812 
813 template <typename T>
814 Taylor<T>
815 operator/(const Base< Taylor<T> >& aa,
816  const typename Taylor<T>::value_type& b)
817 {
818  const Taylor<T>& a = aa.derived();
819 
820  int dc = a.degree();
821 
822  Taylor<T> c(dc);
823  const T* ca = a.coeff();
824  T* cc = c.coeff();
825 
826  for (int i=0; i<=dc; i++)
827  cc[i] = ca[i]/b;
828 
829  return c;
830 }
831 
832 template <typename T>
833 Taylor<T>
834 exp(const Base< Taylor<T> >& aa)
835 {
836  const Taylor<T>& a = aa.derived();
837  int dc = a.degree();
838 
839  Taylor<T> c(dc);
840  const T* ca = a.coeff();
841  T* cc = c.coeff();
842 
843  T tmp;
844  cc[0] = std::exp(ca[0]);
845  for (int i=1; i<=dc; i++) {
846  tmp = T(0.0);
847  for (int k=1; k<=i; k++)
848  tmp += k*cc[i-k]*ca[k];
849  cc[i] = tmp / i;
850  }
851 
852  return c;
853 }
854 
855 template <typename T>
856 Taylor<T>
857 log(const Base< Taylor<T> >& aa)
858 {
859  const Taylor<T>& a = aa.derived();
860  int dc = a.degree();
861 
862  Taylor<T> c(dc);
863  const T* ca = a.coeff();
864  T* cc = c.coeff();
865 
866  T tmp;
867  cc[0] = std::log(ca[0]);
868  for (int i=1; i<=dc; i++) {
869  tmp = i*ca[i];
870  for (int k=1; k<=i-1; k++)
871  tmp -= k*ca[i-k]*cc[k];
872  cc[i] = tmp / (i*ca[0]);
873  }
874 
875  return c;
876 }
877 
878 template <typename T>
879 Taylor<T>
880 log10(const Base< Taylor<T> >& aa)
881 {
882  const Taylor<T>& a = aa.derived();
883  return log(a) / std::log(10.0);
884 }
885 
886 template <typename T>
887 Taylor<T>
888 sqrt(const Base< Taylor<T> >& aa)
889 {
890  const Taylor<T>& a = aa.derived();
891  int dc = a.degree();
892 
893  Taylor<T> c(dc);
894  const T* ca = a.coeff();
895  T* cc = c.coeff();
896 
897  T tmp;
898  cc[0] = std::sqrt(ca[0]);
899  for (int i=1; i<=dc; i++) {
900  tmp = ca[i];
901  for (int k=1; k<=i-1; k++)
902  tmp -= cc[k]*cc[i-k];
903  cc[i] = tmp / (2.0*cc[0]);
904  }
905 
906  return c;
907 }
908 
909 #ifdef HAVE_SACADO_CXX11
910 template <typename T>
911 Taylor<T>
912 cbrt(const Base< Taylor<T> >& aa)
913 {
914  return pow(aa, typename Taylor<T>::value_type(1.0/3.0));
915 }
916 #endif
917 
918 template <typename T>
919 Taylor<T>
920 pow(const Base< Taylor<T> >& aa,
921  const Base< Taylor<T> >& bb)
922 {
923  const Taylor<T>& a = aa.derived();
924  const Taylor<T>& b = bb.derived();
925  return exp(b*log(a));
926 }
927 
928 template <typename T>
929 Taylor<T>
930 pow(const typename Taylor<T>::value_type& a,
931  const Base< Taylor<T> >& bb)
932 {
933  const Taylor<T>& b = bb.derived();
934  return exp(b*std::log(a));
935 }
936 
937 template <typename T>
938 Taylor<T>
939 pow(const Base< Taylor<T> >& aa,
940  const typename Taylor<T>::value_type& b)
941 {
942  const Taylor<T>& a = aa.derived();
943  return exp(b*log(a));
944 }
945 
946 template <typename T>
947 void
948 sincos(const Base< Taylor<T> >& aa,
949  Taylor<T>& s,
950  Taylor<T>& c)
951 {
952  const Taylor<T>& a = aa.derived();
953  int dc = a.degree();
954  if (s.degree() != dc)
955  s.resize(dc, false);
956  if (c.degree() != dc)
957  c.resize(dc, false);
958 
959  const T* ca = a.coeff();
960  T* cs = s.coeff();
961  T* cc = c.coeff();
962 
963  T tmp1;
964  T tmp2;
965  cs[0] = std::sin(ca[0]);
966  cc[0] = std::cos(ca[0]);
967  for (int i=1; i<=dc; i++) {
968  tmp1 = T(0.0);
969  tmp2 = T(0.0);
970  for (int k=1; k<=i; k++) {
971  tmp1 += k*ca[k]*cc[i-k];
972  tmp2 -= k*ca[k]*cs[i-k];
973  }
974  cs[i] = tmp1 / i;
975  cc[i] = tmp2 / i;
976  }
977 }
978 
979 template <typename T>
980 Taylor<T>
981 sin(const Base< Taylor<T> >& aa)
982 {
983  const Taylor<T>& a = aa.derived();
984  int dc = a.degree();
985  Taylor<T> s(dc);
986  Taylor<T> c(dc);
987  sincos(a, s, c);
988 
989  return s;
990 }
991 
992 template <typename T>
993 Taylor<T>
994 cos(const Base< Taylor<T> >& aa)
995 {
996  const Taylor<T>& a = aa.derived();
997  int dc = a.degree();
998  Taylor<T> s(dc);
999  Taylor<T> c(dc);
1000  sincos(a, s, c);
1001 
1002  return c;
1003 }
1004 
1005 template <typename T>
1006 Taylor<T>
1007 tan(const Base< Taylor<T> >& aa)
1008 {
1009  const Taylor<T>& a = aa.derived();
1010  int dc = a.degree();
1011  Taylor<T> s(dc);
1012  Taylor<T> c(dc);
1013 
1014  sincos(a, s, c);
1015 
1016  return s / c;
1017 }
1018 
1019 template <typename T>
1020 void
1021 sinhcosh(const Base< Taylor<T> >& aa,
1022  Taylor<T>& s,
1023  Taylor<T>& c)
1024 {
1025  const Taylor<T>& a = aa.derived();
1026  int dc = a.degree();
1027  if (s.degree() != dc)
1028  s.resize(dc, false);
1029  if (c.degree() != dc)
1030  c.resize(dc, false);
1031 
1032  const T* ca = a.coeff();
1033  T* cs = s.coeff();
1034  T* cc = c.coeff();
1035 
1036  T tmp1;
1037  T tmp2;
1038  cs[0] = std::sinh(ca[0]);
1039  cc[0] = std::cosh(ca[0]);
1040  for (int i=1; i<=dc; i++) {
1041  tmp1 = T(0.0);
1042  tmp2 = T(0.0);
1043  for (int k=1; k<=i; k++) {
1044  tmp1 += k*ca[k]*cc[i-k];
1045  tmp2 += k*ca[k]*cs[i-k];
1046  }
1047  cs[i] = tmp1 / i;
1048  cc[i] = tmp2 / i;
1049  }
1050 }
1051 
1052 template <typename T>
1053 Taylor<T>
1054 sinh(const Base< Taylor<T> >& aa)
1055 {
1056  const Taylor<T>& a = aa.derived();
1057  int dc = a.degree();
1058  Taylor<T> s(dc);
1059  Taylor<T> c(dc);
1060  sinhcosh(a, s, c);
1061 
1062  return s;
1063 }
1064 
1065 template <typename T>
1066 Taylor<T>
1067 cosh(const Base< Taylor<T> >& aa)
1068 {
1069  const Taylor<T>& a = aa.derived();
1070  int dc = a.degree();
1071  Taylor<T> s(dc);
1072  Taylor<T> c(dc);
1073  sinhcosh(a, s, c);
1074 
1075  return c;
1076 }
1077 
1078 template <typename T>
1079 Taylor<T>
1080 tanh(const Base< Taylor<T> >& aa)
1081 {
1082  const Taylor<T>& a = aa.derived();
1083  int dc = a.degree();
1084  Taylor<T> s(dc);
1085  Taylor<T> c(dc);
1086 
1087  sinhcosh(a, s, c);
1088 
1089  return s / c;
1090 }
1091 
1092 template <typename T>
1093 Taylor<T>
1094 quad(const typename Taylor<T>::value_type& c0,
1095  const Base< Taylor<T> >& aa,
1096  const Base< Taylor<T> >& bb)
1097 {
1098  const Taylor<T>& a = aa.derived();
1099  const Taylor<T>& b = bb.derived();
1100  int dc = a.degree();
1101 
1102  Taylor<T> c(dc);
1103  const T* ca = a.coeff();
1104  const T* cb = b.coeff();
1105  T* cc = c.coeff();
1106 
1107  T tmp;
1108  cc[0] = c0;
1109  for (int i=1; i<=dc; i++) {
1110  tmp = T(0.0);
1111  for (int k=1; k<=i; k++)
1112  tmp += k*ca[k]*cb[i-k];
1113  cc[i] = tmp / i;
1114  }
1115 
1116  return c;
1117 }
1118 
1119 template <typename T>
1120 Taylor<T>
1121 acos(const Base< Taylor<T> >& aa)
1122 {
1123  const Taylor<T>& a = aa.derived();
1124  Taylor<T> b = -1.0 / sqrt(1.0 - a*a);
1125  return quad(std::acos(a.coeff(0)), a, b);
1126 }
1127 
1128 template <typename T>
1129 Taylor<T>
1130 asin(const Base< Taylor<T> >& aa)
1131 {
1132  const Taylor<T>& a = aa.derived();
1133  Taylor<T> b = 1.0 / sqrt(1.0 - a*a);
1134  return quad(std::asin(a.coeff(0)), a, b);
1135 }
1136 
1137 template <typename T>
1138 Taylor<T>
1139 atan(const Base< Taylor<T> >& aa)
1140 {
1141  const Taylor<T>& a = aa.derived();
1142  Taylor<T> b = 1.0 / (1.0 + a*a);
1143  return quad(std::atan(a.coeff(0)), a, b);
1144 }
1145 
1146 template <typename T>
1147 Taylor<T>
1148 atan2(const Base< Taylor<T> >& aa,
1149  const Base< Taylor<T> >& bb)
1150 {
1151  const Taylor<T>& a = aa.derived();
1152  const Taylor<T>& b = bb.derived();
1153 
1154  Taylor<T> c = atan(a/b);
1155  c.fastAccessCoeff(0) = atan2(a.coeff(0),b.coeff(0));
1156  return c;
1157 }
1158 
1159 template <typename T>
1160 Taylor<T>
1162  const Base< Taylor<T> >& bb)
1163 {
1164  const Taylor<T>& b = bb.derived();
1165 
1166  Taylor<T> c = atan(a/b);
1167  c.fastAccessCoeff(0) = atan2(a,b.coeff(0));
1168  return c;
1169 }
1170 
1171 template <typename T>
1172 Taylor<T>
1173 atan2(const Base< Taylor<T> >& aa,
1174  const typename Taylor<T>::value_type& b)
1175 {
1176  const Taylor<T>& a = aa.derived();
1177 
1178  Taylor<T> c = atan(a/b);
1179  c.fastAccessCoeff(0) = atan2(a.coeff(0),b);
1180  return c;
1181 }
1182 
1183 template <typename T>
1184 Taylor<T>
1185 acosh(const Base< Taylor<T> >& aa)
1186 {
1187  const Taylor<T>& a = aa.derived();
1188  Taylor<T> b = -1.0 / sqrt(1.0 - a*a);
1189  return quad(acosh(a.coeff(0)), a, b);
1190 }
1191 
1192 template <typename T>
1193 Taylor<T>
1194 asinh(const Base< Taylor<T> >& aa)
1195 {
1196  const Taylor<T>& a = aa.derived();
1197  Taylor<T> b = 1.0 / sqrt(a*a - 1.0);
1198  return quad(asinh(a.coeff(0)), a, b);
1199 }
1200 
1201 template <typename T>
1202 Taylor<T>
1203 atanh(const Base< Taylor<T> >& aa)
1204 {
1205  const Taylor<T>& a = aa.derived();
1206  Taylor<T> b = 1.0 / (1.0 - a*a);
1207  return quad(atanh(a.coeff(0)), a, b);
1208 }
1209 
1210 template <typename T>
1211 Taylor<T>
1212 fabs(const Base< Taylor<T> >& aa)
1213 {
1214  const Taylor<T>& a = aa.derived();
1215  if (a.coeff(0) >= 0)
1216  return a;
1217  else
1218  return -a;
1219 }
1220 
1221 template <typename T>
1222 Taylor<T>
1223 abs(const Base< Taylor<T> >& aa)
1224 {
1225  const Taylor<T>& a = aa.derived();
1226  if (a.coeff(0) >= 0)
1227  return a;
1228  else
1229  return -a;
1230 }
1231 
1232 template <typename T>
1233 Taylor<T>
1234 max(const Base< Taylor<T> >& aa,
1235  const Base< Taylor<T> >& bb)
1236 {
1237  const Taylor<T>& a = aa.derived();
1238  const Taylor<T>& b = bb.derived();
1239 
1240  if (a.coeff(0) >= b.coeff(0))
1241  return a;
1242  else
1243  return b;
1244 }
1245 
1246 template <typename T>
1247 Taylor<T>
1248 max(const typename Taylor<T>::value_type& a,
1249  const Base< Taylor<T> >& bb)
1250 {
1251  const Taylor<T>& b = bb.derived();
1252 
1253  if (a >= b.coeff(0))
1254  return Taylor<T>(b.degree(), a);
1255  else
1256  return b;
1257 }
1258 
1259 template <typename T>
1260 Taylor<T>
1261 max(const Base< Taylor<T> >& aa,
1262  const typename Taylor<T>::value_type& b)
1263 {
1264  const Taylor<T>& a = aa.derived();
1265 
1266  if (a.coeff(0) >= b)
1267  return a;
1268  else
1269  return Taylor<T>(a.degree(), b);
1270 }
1271 
1272 template <typename T>
1273 Taylor<T>
1274 min(const Base< Taylor<T> >& aa,
1275  const Base< Taylor<T> >& bb)
1276 {
1277  const Taylor<T>& a = aa.derived();
1278  const Taylor<T>& b = bb.derived();
1279 
1280  if (a.coeff(0) <= b.coeff(0))
1281  return a;
1282  else
1283  return b;
1284 }
1285 
1286 template <typename T>
1287 Taylor<T>
1288 min(const typename Taylor<T>::value_type& a,
1289  const Base< Taylor<T> >& bb)
1290 {
1291  const Taylor<T>& b = bb.derived();
1292 
1293  if (a <= b.coeff(0))
1294  return Taylor<T>(b.degree(), a);
1295  else
1296  return b;
1297 }
1298 
1299 template <typename T>
1300 Taylor<T>
1301 min(const Base< Taylor<T> >& aa,
1302  const typename Taylor<T>::value_type& b)
1303 {
1304  const Taylor<T>& a = aa.derived();
1305 
1306  if (a.coeff(0) <= b)
1307  return a;
1308  else
1309  return Taylor<T>(a.degree(), b);
1310 }
1311 
1312 template <typename T>
1313 bool
1315  const Base< Taylor<T> >& bb)
1316 {
1317  const Taylor<T>& a = aa.derived();
1318  const Taylor<T>& b = bb.derived();
1319  return a.coeff(0) == b.coeff(0);
1320 }
1321 
1322 template <typename T>
1323 bool
1325  const Base< Taylor<T> >& bb)
1326 {
1327  const Taylor<T>& b = bb.derived();
1328  return a == b.coeff(0);
1329 }
1330 
1331 template <typename T>
1332 bool
1334  const typename Taylor<T>::value_type& b)
1335 {
1336  const Taylor<T>& a = aa.derived();
1337  return a.coeff(0) == b;
1338 }
1339 
1340 template <typename T>
1341 bool
1343  const Base< Taylor<T> >& bb)
1344 {
1345  const Taylor<T>& a = aa.derived();
1346  const Taylor<T>& b = bb.derived();
1347  return a.coeff(0) != b.coeff(0);
1348 }
1349 
1350 template <typename T>
1351 bool
1353  const Base< Taylor<T> >& bb)
1354 {
1355  const Taylor<T>& b = bb.derived();
1356  return a != b.coeff(0);
1357 }
1358 
1359 template <typename T>
1360 bool
1362  const typename Taylor<T>::value_type& b)
1363 {
1364  const Taylor<T>& a = aa.derived();
1365  return a.coeff(0) != b;
1366 }
1367 
1368 template <typename T>
1369 bool
1370 operator<=(const Base< Taylor<T> >& aa,
1371  const Base< Taylor<T> >& bb)
1372 {
1373  const Taylor<T>& a = aa.derived();
1374  const Taylor<T>& b = bb.derived();
1375  return a.coeff(0) <= b.coeff(0);
1376 }
1377 
1378 template <typename T>
1379 bool
1380 operator<=(const typename Taylor<T>::value_type& a,
1381  const Base< Taylor<T> >& bb)
1382 {
1383  const Taylor<T>& b = bb.derived();
1384  return a <= b.coeff(0);
1385 }
1386 
1387 template <typename T>
1388 bool
1389 operator<=(const Base< Taylor<T> >& aa,
1390  const typename Taylor<T>::value_type& b)
1391 {
1392  const Taylor<T>& a = aa.derived();
1393  return a.coeff(0) <= b;
1394 }
1395 
1396 template <typename T>
1397 bool
1399  const Base< Taylor<T> >& bb)
1400 {
1401  const Taylor<T>& a = aa.derived();
1402  const Taylor<T>& b = bb.derived();
1403  return a.coeff(0) >= b.coeff(0);
1404 }
1405 
1406 template <typename T>
1407 bool
1409  const Base< Taylor<T> >& bb)
1410 {
1411  const Taylor<T>& b = bb.derived();
1412  return a >= b.coeff(0);
1413 }
1414 
1415 template <typename T>
1416 bool
1418  const typename Taylor<T>::value_type& b)
1419 {
1420  const Taylor<T>& a = aa.derived();
1421  return a.coeff(0) >= b;
1422 }
1423 
1424 template <typename T>
1425 bool
1426 operator<(const Base< Taylor<T> >& aa,
1427  const Base< Taylor<T> >& bb)
1428 {
1429  const Taylor<T>& a = aa.derived();
1430  const Taylor<T>& b = bb.derived();
1431  return a.coeff(0) < b.coeff(0);
1432 }
1433 
1434 template <typename T>
1435 bool
1436 operator<(const typename Taylor<T>::value_type& a,
1437  const Base< Taylor<T> >& bb)
1438 {
1439  const Taylor<T>& b = bb.derived();
1440  return a < b.coeff(0);
1441 }
1442 
1443 template <typename T>
1444 bool
1445 operator<(const Base< Taylor<T> >& aa,
1446  const typename Taylor<T>::value_type& b)
1447 {
1448  const Taylor<T>& a = aa.derived();
1449  return a.coeff(0) < b;
1450 }
1451 
1452 template <typename T>
1453 bool
1454 operator>(const Base< Taylor<T> >& aa,
1455  const Base< Taylor<T> >& bb)
1456 {
1457  const Taylor<T>& a = aa.derived();
1458  const Taylor<T>& b = bb.derived();
1459  return a.coeff(0) > b.coeff(0);
1460 }
1461 
1462 template <typename T>
1463 bool
1465  const Base< Taylor<T> >& bb)
1466 {
1467  const Taylor<T>& b = bb.derived();
1468  return a > b.coeff(0);
1469 }
1470 
1471 template <typename T>
1472 bool
1473 operator>(const Base< Taylor<T> >& aa,
1474  const typename Taylor<T>::value_type& b)
1475 {
1476  const Taylor<T>& a = aa.derived();
1477  return a.coeff(0) > b;
1478 }
1479 
1480 template <typename T>
1481 bool toBool(const Taylor<T>& x) {
1482  bool is_zero = true;
1483  for (int i=0; i<=x.degree(); i++)
1484  is_zero = is_zero && (x.coeff(i) == 0.0);
1485  return !is_zero;
1486 }
1487 
1488 template <typename T>
1489 inline bool
1490 operator && (const Base< Taylor<T> >& xx1, const Base< Taylor<T> >& xx2)
1491 {
1492  const Taylor<T>& x1 = xx1.derived();
1493  const Taylor<T>& x2 = xx2.derived();
1494  return toBool(x1) && toBool(x2);
1495 }
1496 
1497 template <typename T>
1498 inline bool
1500  const Base< Taylor<T> >& xx2)
1501 {
1502  const Taylor<T>& x2 = xx2.derived();
1503  return a && toBool(x2);
1504 }
1505 
1506 template <typename T>
1507 inline bool
1509  const typename Taylor<T>::value_type& b)
1510 {
1511  const Taylor<T>& x1 = xx1.derived();
1512  return toBool(x1) && b;
1513 }
1514 
1515 template <typename T>
1516 inline bool
1517 operator || (const Base< Taylor<T> >& xx1, const Base< Taylor<T> >& xx2)
1518 {
1519  const Taylor<T>& x1 = xx1.derived();
1520  const Taylor<T>& x2 = xx2.derived();
1521  return toBool(x1) || toBool(x2);
1522 }
1523 
1524 template <typename T>
1525 inline bool
1527  const Base< Taylor<T> >& xx2)
1528 {
1529  const Taylor<T>& x2 = xx2.derived();
1530  return a || toBool(x2);
1531 }
1532 
1533 template <typename T>
1534 inline bool
1536  const typename Taylor<T>::value_type& b)
1537 {
1538  const Taylor<T>& x1 = xx1.derived();
1539  return toBool(x1) || b;
1540 }
1541 
1542 template <typename T>
1543 std::ostream&
1544 operator << (std::ostream& os, const Base< Taylor<T> >& aa)
1545 {
1546  const Taylor<T>& a = aa.derived();
1547  os << "[ ";
1548 
1549  for (int i=0; i<=a.degree(); i++) {
1550  os << a.coeff(i) << " ";
1551  }
1552 
1553  os << "]";
1554  return os;
1555 }
1556 
1557 } // namespace Tay
1558 } // namespace Sacado
cbrt(expr.val())
Taylor< T > operator+(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
A generic handle class.
ASinExprType< T >::expr_type asin(const Expr< T > &expr)
void resizeCoeffs(int len)
Resize coefficient array to new size.
void resize(int d, bool keep_coeffs)
Resize polynomial to degree d.
void sinhcosh(const Base< Taylor< T > > &a, Taylor< T > &s, Taylor< T > &c)
static KOKKOS_INLINE_FUNCTION void copy(const T *src, T *dest, int sz)
Copy array from src to dest of length sz.
T value_type
Typename of values.
asin(expr.val())
cosh(expr.val())
int deg_
Degree of polynomial.
void makeOwnCopy()
Make handle have its own copy of rep.
Taylor< T > log(const Base< Taylor< T > > &a)
Taylor< T > & operator-=(const T &x)
Subtraction-assignment operator with constant right-hand-side.
Taylor< T > asinh(const Base< Taylor< T > > &a)
TanhExprType< T >::expr_type tanh(const Expr< T > &expr)
PowExprType< Expr< T1 >, Expr< T2 > >::expr_type pow(const Expr< T1 > &expr1, const Expr< T2 > &expr2)
TanExprType< T >::expr_type tan(const Expr< T > &expr)
bool operator>(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
Taylor< T > operator+() const
Unary-plus operator.
int len_
Length of allocated polynomial array.
TaylorData & operator=(const TaylorData &x)
Assignment operator.
Taylor< T > & operator*=(const T &x)
Multiplication-assignment operator with constant right-hand-side.
static KOKKOS_INLINE_FUNCTION void destroy_and_release(T *m, int sz)
Destroy array elements and release memory.
atan(expr.val())
bool operator||(const Base< Taylor< T > > &xx1, const Base< Taylor< T > > &xx2)
Taylor< T > operator/(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
Taylor< T > & operator=(const T &val)
Assignment operator with constant right-hand-side.
ACosExprType< T >::expr_type acos(const Expr< T > &expr)
bool operator>=(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
Base class for Sacado types to control overload resolution.
Definition: Sacado_Base.hpp:46
Taylor< T > sin(const Base< Taylor< T > > &a)
bool operator&&(const Base< Taylor< T > > &xx1, const Base< Taylor< T > > &xx2)
#define T
Definition: Sacado_rad.hpp:573
expr expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c *expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr1 c expr2 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 expr2 expr1 expr2 expr1 expr1 expr1 c
Taylor< T > cos(const Base< Taylor< T > > &a)
T & fastAccessCoeff(int i)
Returns degree i term without bounds checking.
Taylor< T > operator-() const
Unary-minus operator.
static KOKKOS_INLINE_FUNCTION T * get_and_fill(int sz)
Get memory for new array of length sz and fill with zeros.
Taylor< T > quad(const typename Taylor< T >::value_type &c0, const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
Taylor< T > operator*(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
Taylor< T > sinh(const Base< Taylor< T > > &a)
Taylor< T > sqrt(const Base< Taylor< T > > &a)
sqrt(expr.val())
Log10ExprType< T >::expr_type log10(const Expr< T > &expr)
Taylor< T > max(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
sinh(expr.val())
Taylor< T > fabs(const Base< Taylor< T > > &a)
static KOKKOS_INLINE_FUNCTION void zero(T *dest, int sz)
Zero out array dest of length sz.
const T * coeff() const
Returns Taylor coefficient array.
Sacado::Handle< TaylorData > th
ATanExprType< T >::expr_type atan(const Expr< T > &expr)
Taylor< T > abs(const Base< Taylor< T > > &a)
void reserve(int d)
Reserve space for a degree d polynomial.
sin(expr.val())
Taylor< T > atan2(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
Taylor< T > exp(const Base< Taylor< T > > &a)
T * coeff_
Taylor polynomial coefficients.
void sincos(const Base< Taylor< T > > &a, Taylor< T > &s, Taylor< T > &c)
Taylor< T > atanh(const Base< Taylor< T > > &a)
log(expr.val())
Taylor polynomial class.
Taylor< T > cosh(const Base< Taylor< T > > &a)
bool operator==(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
acos(expr.val())
const derived_type & derived() const
Definition: Sacado_Base.hpp:48
Taylor< T > min(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
Taylor< T > operator-(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
exp(expr.val())
Taylor< T > & operator/=(const T &x)
Division-assignment operator with constant right-hand-side.
Taylor< T > acosh(const Base< Taylor< T > > &a)
Taylor< T > & operator+=(const T &x)
Addition-assignment operator with constant right-hand-side.
int degree() const
Returns degree of polynomial.
bool operator!=(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
cos(expr.val())
Taylor()
Default constructor.
bool toBool(const Taylor< T > &x)