Sacado Package Browser (Single Doxygen Collection) Version of the Day
Loading...
Searching...
No Matches
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
39namespace Sacado {
40namespace Tay {
41
42template <typename T>
44TaylorData() :
45 coeff_(NULL), deg_(-1), len_(0)
46{
47}
48
49template <typename T>
57
58template <typename T>
60TaylorData(int d, const T& x) :
61 coeff_(), deg_(d), len_(d+1)
62{
64 coeff_[0] = x;
65}
66
67template <typename T>
74
75template <typename T>
82
83template <typename T>
85TaylorData(const typename Taylor<T>::TaylorData& x) :
86 coeff_(), deg_(x.deg_), len_(x.deg_+1)
87{
89}
90
91template <typename T>
98
99template <typename T>
100typename Taylor<T>::TaylorData&
102operator=(const typename Taylor<T>::TaylorData& x)
103{
104 if (len_ < x.deg_+1) {
106 len_ = x.deg_+1;
107 deg_ = x.deg_;
109 }
110 else {
111 deg_ = x.deg_;
113 }
114
115 return *this;
116}
117
118template <typename T>
120Taylor() :
121 th(new TaylorData)
122{
123}
124
125template <typename T>
127Taylor(const T& x) :
128 th(new TaylorData(x))
129{
130}
131
132template <typename T>
135 th(new TaylorData(value_type(x)))
136{
137}
138
139template <typename T>
141Taylor(int d, const T& x) :
142 th(new TaylorData(d, x))
143{
144}
145
146template <typename T>
148Taylor(int d) :
149 th(new TaylorData(d))
150{
151}
152
153template <typename T>
155Taylor(const Taylor<T>& x) :
156 th(x.th)
157{
158}
159
160template <typename T>
162~Taylor()
163{
164}
165
166template <typename T>
167void
169resize(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)
181 th->deg_ = d;
182 }
183}
184
185template <typename T>
186void
188reserve(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
197template <typename T>
200operator=(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
216template <typename T>
220{
221 return operator=(value_type(v));
222}
223
224template <typename T>
227operator=(const Taylor<T>& x)
228{
229 th = x.th;
230 return *this;
231}
232
233template <typename T>
236operator+() const
237{
238 return *this;
239}
240
241template <typename T>
244operator-() 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
256template <typename T>
259operator+=(const T& v)
260{
261 th.makeOwnCopy();
262
263 th->coeff_[0] += v;
264
265 return *this;
266}
267
268template <typename T>
271operator-=(const T& v)
272{
273 th.makeOwnCopy();
274
275 th->coeff_[0] -= v;
276
277 return *this;
279
280template <typename T>
283operator*=(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
293template <typename T>
296operator/=(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
306template <typename T>
309operator+=(const Taylor<T>& x)
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) {
339 th->len_ = l;
340 th->coeff_ = c;
341 }
342
343 return *this;
344}
345
346template <typename T>
349operator-=(const Taylor<T>& x)
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) {
379 th->len_ = l;
380 th->coeff_ = c;
381 }
382
383 return *this;
384}
385
386template <typename T>
389operator*=(const Taylor<T>& x)
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
437template <typename T>
440operator/=(const Taylor<T>& x)
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
487template <typename T>
488void
490resizeCoeffs(int len)
491{
492 if (th->coeff_)
494 th->len_ = len;
495 th->coeff_ = Sacado::ds_array<T>::get_and_fill(th->len_);
496}
497
498template <typename T>
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
538template <typename T>
539Taylor<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
558template <typename T>
559Taylor<T>
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
578template <typename T>
579Taylor<T>
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
618template <typename T>
619Taylor<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
638template <typename T>
639Taylor<T>
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
658template <typename T>
659Taylor<T>
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
701template <typename T>
702Taylor<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
720template <typename T>
721Taylor<T>
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
739template <typename T>
740Taylor<T>
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
788template <typename T>
789Taylor<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
813template <typename T>
814Taylor<T>
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
832template <typename T>
833Taylor<T>
834exp(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
855template <typename T>
856Taylor<T>
857log(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
878template <typename T>
879Taylor<T>
880log10(const Base< Taylor<T> >& aa)
881{
882 const Taylor<T>& a = aa.derived();
883 return log(a) / std::log(10.0);
884}
885
886template <typename T>
887Taylor<T>
888sqrt(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
909template <typename T>
910Taylor<T>
911cbrt(const Base< Taylor<T> >& aa)
912{
913 return pow(aa, typename Taylor<T>::value_type(1.0/3.0));
914}
915
916template <typename T>
917Taylor<T>
918pow(const Base< Taylor<T> >& aa,
919 const Base< Taylor<T> >& bb)
920{
921 const Taylor<T>& a = aa.derived();
922 const Taylor<T>& b = bb.derived();
923 return exp(b*log(a));
924}
925
926template <typename T>
927Taylor<T>
929 const Base< Taylor<T> >& bb)
930{
931 const Taylor<T>& b = bb.derived();
932 return exp(b*std::log(a));
933}
934
935template <typename T>
936Taylor<T>
937pow(const Base< Taylor<T> >& aa,
938 const typename Taylor<T>::value_type& b)
939{
940 const Taylor<T>& a = aa.derived();
941 return exp(b*log(a));
942}
943
944template <typename T>
945void
946sincos(const Base< Taylor<T> >& aa,
947 Taylor<T>& s,
948 Taylor<T>& c)
949{
950 const Taylor<T>& a = aa.derived();
951 int dc = a.degree();
952 if (s.degree() != dc)
953 s.resize(dc, false);
954 if (c.degree() != dc)
955 c.resize(dc, false);
956
957 const T* ca = a.coeff();
958 T* cs = s.coeff();
959 T* cc = c.coeff();
960
961 T tmp1;
962 T tmp2;
963 cs[0] = std::sin(ca[0]);
964 cc[0] = std::cos(ca[0]);
965 for (int i=1; i<=dc; i++) {
966 tmp1 = T(0.0);
967 tmp2 = T(0.0);
968 for (int k=1; k<=i; k++) {
969 tmp1 += k*ca[k]*cc[i-k];
970 tmp2 -= k*ca[k]*cs[i-k];
971 }
972 cs[i] = tmp1 / i;
973 cc[i] = tmp2 / i;
974 }
975}
976
977template <typename T>
978Taylor<T>
979sin(const Base< Taylor<T> >& aa)
980{
981 const Taylor<T>& a = aa.derived();
982 int dc = a.degree();
983 Taylor<T> s(dc);
984 Taylor<T> c(dc);
985 sincos(a, s, c);
986
987 return s;
988}
989
990template <typename T>
991Taylor<T>
992cos(const Base< Taylor<T> >& aa)
993{
994 const Taylor<T>& a = aa.derived();
995 int dc = a.degree();
996 Taylor<T> s(dc);
997 Taylor<T> c(dc);
998 sincos(a, s, c);
999
1000 return c;
1001}
1002
1003template <typename T>
1004Taylor<T>
1005tan(const Base< Taylor<T> >& aa)
1006{
1007 const Taylor<T>& a = aa.derived();
1008 int dc = a.degree();
1009 Taylor<T> s(dc);
1010 Taylor<T> c(dc);
1011
1012 sincos(a, s, c);
1013
1014 return s / c;
1015}
1016
1017template <typename T>
1018void
1020 Taylor<T>& s,
1021 Taylor<T>& c)
1022{
1023 const Taylor<T>& a = aa.derived();
1024 int dc = a.degree();
1025 if (s.degree() != dc)
1026 s.resize(dc, false);
1027 if (c.degree() != dc)
1028 c.resize(dc, false);
1029
1030 const T* ca = a.coeff();
1031 T* cs = s.coeff();
1032 T* cc = c.coeff();
1033
1034 T tmp1;
1035 T tmp2;
1036 cs[0] = std::sinh(ca[0]);
1037 cc[0] = std::cosh(ca[0]);
1038 for (int i=1; i<=dc; i++) {
1039 tmp1 = T(0.0);
1040 tmp2 = T(0.0);
1041 for (int k=1; k<=i; k++) {
1042 tmp1 += k*ca[k]*cc[i-k];
1043 tmp2 += k*ca[k]*cs[i-k];
1044 }
1045 cs[i] = tmp1 / i;
1046 cc[i] = tmp2 / i;
1047 }
1048}
1049
1050template <typename T>
1051Taylor<T>
1052sinh(const Base< Taylor<T> >& aa)
1053{
1054 const Taylor<T>& a = aa.derived();
1055 int dc = a.degree();
1056 Taylor<T> s(dc);
1057 Taylor<T> c(dc);
1058 sinhcosh(a, s, c);
1059
1060 return s;
1061}
1062
1063template <typename T>
1064Taylor<T>
1065cosh(const Base< Taylor<T> >& aa)
1066{
1067 const Taylor<T>& a = aa.derived();
1068 int dc = a.degree();
1069 Taylor<T> s(dc);
1070 Taylor<T> c(dc);
1071 sinhcosh(a, s, c);
1072
1073 return c;
1074}
1075
1076template <typename T>
1077Taylor<T>
1078tanh(const Base< Taylor<T> >& aa)
1079{
1080 const Taylor<T>& a = aa.derived();
1081 int dc = a.degree();
1082 Taylor<T> s(dc);
1083 Taylor<T> c(dc);
1084
1085 sinhcosh(a, s, c);
1086
1087 return s / c;
1088}
1089
1090template <typename T>
1091Taylor<T>
1092quad(const typename Taylor<T>::value_type& c0,
1093 const Base< Taylor<T> >& aa,
1094 const Base< Taylor<T> >& bb)
1095{
1096 const Taylor<T>& a = aa.derived();
1097 const Taylor<T>& b = bb.derived();
1098 int dc = a.degree();
1099
1100 Taylor<T> c(dc);
1101 const T* ca = a.coeff();
1102 const T* cb = b.coeff();
1103 T* cc = c.coeff();
1104
1105 T tmp;
1106 cc[0] = c0;
1107 for (int i=1; i<=dc; i++) {
1108 tmp = T(0.0);
1109 for (int k=1; k<=i; k++)
1110 tmp += k*ca[k]*cb[i-k];
1111 cc[i] = tmp / i;
1112 }
1113
1114 return c;
1115}
1116
1117template <typename T>
1118Taylor<T>
1119acos(const Base< Taylor<T> >& aa)
1120{
1121 const Taylor<T>& a = aa.derived();
1122 Taylor<T> b = -1.0 / sqrt(1.0 - a*a);
1123 return quad(std::acos(a.coeff(0)), a, b);
1124}
1125
1126template <typename T>
1127Taylor<T>
1128asin(const Base< Taylor<T> >& aa)
1129{
1130 const Taylor<T>& a = aa.derived();
1131 Taylor<T> b = 1.0 / sqrt(1.0 - a*a);
1132 return quad(std::asin(a.coeff(0)), a, b);
1133}
1134
1135template <typename T>
1136Taylor<T>
1137atan(const Base< Taylor<T> >& aa)
1138{
1139 const Taylor<T>& a = aa.derived();
1140 Taylor<T> b = 1.0 / (1.0 + a*a);
1141 return quad(std::atan(a.coeff(0)), a, b);
1142}
1143
1144template <typename T>
1145Taylor<T>
1146atan2(const Base< Taylor<T> >& aa,
1147 const Base< Taylor<T> >& bb)
1148{
1149 const Taylor<T>& a = aa.derived();
1150 const Taylor<T>& b = bb.derived();
1151
1152 Taylor<T> c = atan(a/b);
1153 c.fastAccessCoeff(0) = atan2(a.coeff(0),b.coeff(0));
1154 return c;
1155}
1156
1157template <typename T>
1158Taylor<T>
1160 const Base< Taylor<T> >& bb)
1161{
1162 const Taylor<T>& b = bb.derived();
1163
1164 Taylor<T> c = atan(a/b);
1165 c.fastAccessCoeff(0) = atan2(a,b.coeff(0));
1166 return c;
1167}
1168
1169template <typename T>
1170Taylor<T>
1171atan2(const Base< Taylor<T> >& aa,
1172 const typename Taylor<T>::value_type& b)
1173{
1174 const Taylor<T>& a = aa.derived();
1175
1176 Taylor<T> c = atan(a/b);
1177 c.fastAccessCoeff(0) = atan2(a.coeff(0),b);
1178 return c;
1179}
1180
1181template <typename T>
1182Taylor<T>
1183acosh(const Base< Taylor<T> >& aa)
1184{
1185 const Taylor<T>& a = aa.derived();
1186 Taylor<T> b = -1.0 / sqrt(1.0 - a*a);
1187 return quad(acosh(a.coeff(0)), a, b);
1188}
1189
1190template <typename T>
1191Taylor<T>
1192asinh(const Base< Taylor<T> >& aa)
1193{
1194 const Taylor<T>& a = aa.derived();
1195 Taylor<T> b = 1.0 / sqrt(a*a - 1.0);
1196 return quad(asinh(a.coeff(0)), a, b);
1197}
1198
1199template <typename T>
1200Taylor<T>
1201atanh(const Base< Taylor<T> >& aa)
1202{
1203 const Taylor<T>& a = aa.derived();
1204 Taylor<T> b = 1.0 / (1.0 - a*a);
1205 return quad(atanh(a.coeff(0)), a, b);
1206}
1207
1208template <typename T>
1209Taylor<T>
1210fabs(const Base< Taylor<T> >& aa)
1211{
1212 const Taylor<T>& a = aa.derived();
1213 if (a.coeff(0) >= 0)
1214 return a;
1215 else
1216 return -a;
1217}
1218
1219template <typename T>
1220Taylor<T>
1221abs(const Base< Taylor<T> >& aa)
1222{
1223 const Taylor<T>& a = aa.derived();
1224 if (a.coeff(0) >= 0)
1225 return a;
1226 else
1227 return -a;
1228}
1229
1230template <typename T>
1231Taylor<T>
1232max(const Base< Taylor<T> >& aa,
1233 const Base< Taylor<T> >& bb)
1234{
1235 const Taylor<T>& a = aa.derived();
1236 const Taylor<T>& b = bb.derived();
1237
1238 if (a.coeff(0) >= b.coeff(0))
1239 return a;
1240 else
1241 return b;
1242}
1243
1244template <typename T>
1245Taylor<T>
1247 const Base< Taylor<T> >& bb)
1248{
1249 const Taylor<T>& b = bb.derived();
1250
1251 if (a >= b.coeff(0))
1252 return Taylor<T>(b.degree(), a);
1253 else
1254 return b;
1255}
1256
1257template <typename T>
1258Taylor<T>
1259max(const Base< Taylor<T> >& aa,
1260 const typename Taylor<T>::value_type& b)
1261{
1262 const Taylor<T>& a = aa.derived();
1263
1264 if (a.coeff(0) >= b)
1265 return a;
1266 else
1267 return Taylor<T>(a.degree(), b);
1268}
1269
1270template <typename T>
1271Taylor<T>
1272min(const Base< Taylor<T> >& aa,
1273 const Base< Taylor<T> >& bb)
1274{
1275 const Taylor<T>& a = aa.derived();
1276 const Taylor<T>& b = bb.derived();
1277
1278 if (a.coeff(0) <= b.coeff(0))
1279 return a;
1280 else
1281 return b;
1282}
1283
1284template <typename T>
1285Taylor<T>
1287 const Base< Taylor<T> >& bb)
1288{
1289 const Taylor<T>& b = bb.derived();
1290
1291 if (a <= b.coeff(0))
1292 return Taylor<T>(b.degree(), a);
1293 else
1294 return b;
1295}
1296
1297template <typename T>
1298Taylor<T>
1299min(const Base< Taylor<T> >& aa,
1300 const typename Taylor<T>::value_type& b)
1301{
1302 const Taylor<T>& a = aa.derived();
1303
1304 if (a.coeff(0) <= b)
1305 return a;
1306 else
1307 return Taylor<T>(a.degree(), b);
1308}
1309
1310template <typename T>
1311bool
1313 const Base< Taylor<T> >& bb)
1314{
1315 const Taylor<T>& a = aa.derived();
1316 const Taylor<T>& b = bb.derived();
1317 return a.coeff(0) == b.coeff(0);
1318}
1319
1320template <typename T>
1321bool
1323 const Base< Taylor<T> >& bb)
1324{
1325 const Taylor<T>& b = bb.derived();
1326 return a == b.coeff(0);
1327}
1328
1329template <typename T>
1330bool
1332 const typename Taylor<T>::value_type& b)
1333{
1334 const Taylor<T>& a = aa.derived();
1335 return a.coeff(0) == b;
1336}
1337
1338template <typename T>
1339bool
1341 const Base< Taylor<T> >& bb)
1342{
1343 const Taylor<T>& a = aa.derived();
1344 const Taylor<T>& b = bb.derived();
1345 return a.coeff(0) != b.coeff(0);
1346}
1347
1348template <typename T>
1349bool
1351 const Base< Taylor<T> >& bb)
1352{
1353 const Taylor<T>& b = bb.derived();
1354 return a != b.coeff(0);
1355}
1356
1357template <typename T>
1358bool
1360 const typename Taylor<T>::value_type& b)
1361{
1362 const Taylor<T>& a = aa.derived();
1363 return a.coeff(0) != b;
1364}
1365
1366template <typename T>
1367bool
1368operator<=(const Base< Taylor<T> >& aa,
1369 const Base< Taylor<T> >& bb)
1370{
1371 const Taylor<T>& a = aa.derived();
1372 const Taylor<T>& b = bb.derived();
1373 return a.coeff(0) <= b.coeff(0);
1374}
1375
1376template <typename T>
1377bool
1378operator<=(const typename Taylor<T>::value_type& a,
1379 const Base< Taylor<T> >& bb)
1380{
1381 const Taylor<T>& b = bb.derived();
1382 return a <= b.coeff(0);
1383}
1384
1385template <typename T>
1386bool
1387operator<=(const Base< Taylor<T> >& aa,
1388 const typename Taylor<T>::value_type& b)
1389{
1390 const Taylor<T>& a = aa.derived();
1391 return a.coeff(0) <= b;
1392}
1393
1394template <typename T>
1395bool
1397 const Base< Taylor<T> >& bb)
1398{
1399 const Taylor<T>& a = aa.derived();
1400 const Taylor<T>& b = bb.derived();
1401 return a.coeff(0) >= b.coeff(0);
1402}
1403
1404template <typename T>
1405bool
1407 const Base< Taylor<T> >& bb)
1408{
1409 const Taylor<T>& b = bb.derived();
1410 return a >= b.coeff(0);
1411}
1412
1413template <typename T>
1414bool
1416 const typename Taylor<T>::value_type& b)
1417{
1418 const Taylor<T>& a = aa.derived();
1419 return a.coeff(0) >= b;
1420}
1421
1422template <typename T>
1423bool
1424operator<(const Base< Taylor<T> >& aa,
1425 const Base< Taylor<T> >& bb)
1426{
1427 const Taylor<T>& a = aa.derived();
1428 const Taylor<T>& b = bb.derived();
1429 return a.coeff(0) < b.coeff(0);
1430}
1431
1432template <typename T>
1433bool
1434operator<(const typename Taylor<T>::value_type& a,
1435 const Base< Taylor<T> >& bb)
1436{
1437 const Taylor<T>& b = bb.derived();
1438 return a < b.coeff(0);
1439}
1440
1441template <typename T>
1442bool
1443operator<(const Base< Taylor<T> >& aa,
1444 const typename Taylor<T>::value_type& b)
1445{
1446 const Taylor<T>& a = aa.derived();
1447 return a.coeff(0) < b;
1448}
1449
1450template <typename T>
1451bool
1453 const Base< Taylor<T> >& bb)
1454{
1455 const Taylor<T>& a = aa.derived();
1456 const Taylor<T>& b = bb.derived();
1457 return a.coeff(0) > b.coeff(0);
1458}
1459
1460template <typename T>
1461bool
1463 const Base< Taylor<T> >& bb)
1464{
1465 const Taylor<T>& b = bb.derived();
1466 return a > b.coeff(0);
1467}
1468
1469template <typename T>
1470bool
1472 const typename Taylor<T>::value_type& b)
1473{
1474 const Taylor<T>& a = aa.derived();
1475 return a.coeff(0) > b;
1476}
1477
1478template <typename T>
1479bool toBool(const Taylor<T>& x) {
1480 bool is_zero = true;
1481 for (int i=0; i<=x.degree(); i++)
1482 is_zero = is_zero && (x.coeff(i) == 0.0);
1483 return !is_zero;
1484}
1485
1486template <typename T>
1487inline bool
1488operator && (const Base< Taylor<T> >& xx1, const Base< Taylor<T> >& xx2)
1489{
1490 const Taylor<T>& x1 = xx1.derived();
1491 const Taylor<T>& x2 = xx2.derived();
1492 return toBool(x1) && toBool(x2);
1493}
1494
1495template <typename T>
1496inline bool
1498 const Base< Taylor<T> >& xx2)
1499{
1500 const Taylor<T>& x2 = xx2.derived();
1501 return a && toBool(x2);
1502}
1503
1504template <typename T>
1505inline bool
1507 const typename Taylor<T>::value_type& b)
1508{
1509 const Taylor<T>& x1 = xx1.derived();
1510 return toBool(x1) && b;
1511}
1512
1513template <typename T>
1514inline bool
1515operator || (const Base< Taylor<T> >& xx1, const Base< Taylor<T> >& xx2)
1516{
1517 const Taylor<T>& x1 = xx1.derived();
1518 const Taylor<T>& x2 = xx2.derived();
1519 return toBool(x1) || toBool(x2);
1520}
1521
1522template <typename T>
1523inline bool
1525 const Base< Taylor<T> >& xx2)
1526{
1527 const Taylor<T>& x2 = xx2.derived();
1528 return a || toBool(x2);
1529}
1530
1531template <typename T>
1532inline bool
1534 const typename Taylor<T>::value_type& b)
1535{
1536 const Taylor<T>& x1 = xx1.derived();
1537 return toBool(x1) || b;
1538}
1539
1540template <typename T>
1541std::ostream&
1542operator << (std::ostream& os, const Base< Taylor<T> >& aa)
1543{
1544 const Taylor<T>& a = aa.derived();
1545 os << "[ ";
1546
1547 for (int i=0; i<=a.degree(); i++) {
1548 os << a.coeff(i) << " ";
1549 }
1550
1551 os << "]";
1552 return os;
1553}
1554
1555} // namespace Tay
1556} // namespace Sacado
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
#define T
A generic handle class.
Taylor polynomial class.
Taylor< T > & operator-=(const T &x)
Subtraction-assignment operator with constant right-hand-side.
Taylor< T > & operator/=(const T &x)
Division-assignment operator with constant right-hand-side.
Sacado::Handle< TaylorData > th
void resizeCoeffs(int len)
Resize coefficient array to new size.
void reserve(int d)
Reserve space for a degree d polynomial.
Taylor< T > & operator=(const T &val)
Assignment operator with constant right-hand-side.
T & fastAccessCoeff(int i)
Returns degree i term without bounds checking.
Taylor< T > & operator+=(const T &x)
Addition-assignment operator with constant right-hand-side.
int degree() const
Returns degree of polynomial.
Taylor< T > & operator*=(const T &x)
Multiplication-assignment operator with constant right-hand-side.
Taylor< T > operator+() const
Unary-plus operator.
T value_type
Typename of values.
int length() const
Return length of array.
Taylor< T > operator-() const
Unary-minus operator.
const T * coeff() const
Returns Taylor coefficient array.
void resize(int d, bool keep_coeffs)
Resize polynomial to degree d.
Taylor()
Default constructor.
Namespace for Taylor polynomial AD classes.
Taylor< T > operator*(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 > max(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
Taylor< T > min(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
ACosExprType< T >::expr_type acos(const Expr< T > &expr)
Taylor< T > cos(const Base< Taylor< T > > &a)
Taylor< T > asinh(const Base< Taylor< T > > &a)
bool operator==(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 > acosh(const Base< Taylor< T > > &a)
Taylor< T > log(const Base< Taylor< T > > &a)
bool operator!=(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
bool operator>=(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
PowExprType< Expr< T1 >, Expr< T2 > >::expr_type pow(const Expr< T1 > &expr1, const Expr< T2 > &expr2)
Taylor< T > operator/(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
Log10ExprType< T >::expr_type log10(const Expr< T > &expr)
void sincos(const Base< Taylor< T > > &a, Taylor< T > &s, Taylor< T > &c)
bool operator&&(const Base< Taylor< T > > &xx1, const Base< Taylor< T > > &xx2)
void sinhcosh(const Base< Taylor< T > > &a, Taylor< T > &s, Taylor< T > &c)
Taylor< T > exp(const Base< Taylor< T > > &a)
Taylor< T > abs(const Base< Taylor< T > > &a)
Taylor< T > atan2(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
bool operator||(const Base< Taylor< T > > &xx1, const Base< Taylor< T > > &xx2)
Taylor< T > sinh(const Base< Taylor< T > > &a)
bool operator>(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
std::ostream & operator<<(std::ostream &os, const Expr< ExprT > &x)
Taylor< T > atanh(const Base< Taylor< T > > &a)
Taylor< T > sin(const Base< Taylor< T > > &a)
Taylor< T > cbrt(const Base< Taylor< T > > &a)
Taylor< T > sqrt(const Base< Taylor< T > > &a)
ATanExprType< T >::expr_type atan(const Expr< T > &expr)
TanhExprType< T >::expr_type tanh(const Expr< T > &expr)
bool operator<=(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
bool toBool(const Taylor< T > &x)
TanExprType< T >::expr_type tan(const Expr< T > &expr)
Taylor< T > cosh(const Base< Taylor< T > > &a)
Taylor< T > quad(const typename Taylor< T >::value_type &c0, const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
Taylor< T > fabs(const Base< Taylor< T > > &a)
ASinExprType< T >::expr_type asin(const Expr< T > &expr)
bool operator<(const Base< Taylor< T > > &a, const Base< Taylor< T > > &b)
ACosExprType< T >::expr_type acos(const Expr< T > &expr)
ATanExprType< T >::expr_type atan(const Expr< T > &expr)
ASinExprType< T >::expr_type asin(const Expr< T > &expr)
Base class for Sacado types to control overload resolution.
const derived_type & derived() const
T * coeff_
Taylor polynomial coefficients.
TaylorData & operator=(const TaylorData &x)
Assignment operator.
int len_
Length of allocated polynomial array.
static SACADO_INLINE_FUNCTION T * get_and_fill(int sz)
Get memory for new array of length sz and fill with zeros.
static SACADO_INLINE_FUNCTION void destroy_and_release(T *m, int sz)
Destroy array elements and release memory.
static SACADO_INLINE_FUNCTION void zero(T *dest, int sz)
Zero out array dest of length sz.
static SACADO_INLINE_FUNCTION void copy(const T *src, T *dest, int sz)
Copy array from src to dest of length sz.