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 template <typename T>
910 Taylor<T>
911 cbrt(const Base< Taylor<T> >& aa)
912 {
913  return pow(aa, typename Taylor<T>::value_type(1.0/3.0));
914 }
915 
916 template <typename T>
917 Taylor<T>
918 pow(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 
926 template <typename T>
927 Taylor<T>
928 pow(const typename Taylor<T>::value_type& a,
929  const Base< Taylor<T> >& bb)
930 {
931  const Taylor<T>& b = bb.derived();
932  return exp(b*std::log(a));
933 }
934 
935 template <typename T>
936 Taylor<T>
937 pow(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 
944 template <typename T>
945 void
946 sincos(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 
977 template <typename T>
978 Taylor<T>
979 sin(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 
990 template <typename T>
991 Taylor<T>
992 cos(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 
1003 template <typename T>
1004 Taylor<T>
1005 tan(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 
1017 template <typename T>
1018 void
1019 sinhcosh(const Base< Taylor<T> >& aa,
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 
1050 template <typename T>
1051 Taylor<T>
1052 sinh(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 
1063 template <typename T>
1064 Taylor<T>
1065 cosh(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 
1076 template <typename T>
1077 Taylor<T>
1078 tanh(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 
1090 template <typename T>
1091 Taylor<T>
1092 quad(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 
1117 template <typename T>
1118 Taylor<T>
1119 acos(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 
1126 template <typename T>
1127 Taylor<T>
1128 asin(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 
1135 template <typename T>
1136 Taylor<T>
1137 atan(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 
1144 template <typename T>
1145 Taylor<T>
1146 atan2(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 
1157 template <typename T>
1158 Taylor<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 
1169 template <typename T>
1170 Taylor<T>
1171 atan2(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 
1181 template <typename T>
1182 Taylor<T>
1183 acosh(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 
1190 template <typename T>
1191 Taylor<T>
1192 asinh(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 
1199 template <typename T>
1200 Taylor<T>
1201 atanh(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 
1208 template <typename T>
1209 Taylor<T>
1210 fabs(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 
1219 template <typename T>
1220 Taylor<T>
1221 abs(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 
1230 template <typename T>
1231 Taylor<T>
1232 max(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 
1244 template <typename T>
1245 Taylor<T>
1246 max(const typename Taylor<T>::value_type& a,
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 
1257 template <typename T>
1258 Taylor<T>
1259 max(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 
1270 template <typename T>
1271 Taylor<T>
1272 min(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 
1284 template <typename T>
1285 Taylor<T>
1286 min(const typename Taylor<T>::value_type& a,
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 
1297 template <typename T>
1298 Taylor<T>
1299 min(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 
1310 template <typename T>
1311 bool
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 
1320 template <typename T>
1321 bool
1323  const Base< Taylor<T> >& bb)
1324 {
1325  const Taylor<T>& b = bb.derived();
1326  return a == b.coeff(0);
1327 }
1328 
1329 template <typename T>
1330 bool
1332  const typename Taylor<T>::value_type& b)
1333 {
1334  const Taylor<T>& a = aa.derived();
1335  return a.coeff(0) == b;
1336 }
1337 
1338 template <typename T>
1339 bool
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 
1348 template <typename T>
1349 bool
1351  const Base< Taylor<T> >& bb)
1352 {
1353  const Taylor<T>& b = bb.derived();
1354  return a != b.coeff(0);
1355 }
1356 
1357 template <typename T>
1358 bool
1360  const typename Taylor<T>::value_type& b)
1361 {
1362  const Taylor<T>& a = aa.derived();
1363  return a.coeff(0) != b;
1364 }
1365 
1366 template <typename T>
1367 bool
1368 operator<=(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 
1376 template <typename T>
1377 bool
1378 operator<=(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 
1385 template <typename T>
1386 bool
1387 operator<=(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 
1394 template <typename T>
1395 bool
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 
1404 template <typename T>
1405 bool
1407  const Base< Taylor<T> >& bb)
1408 {
1409  const Taylor<T>& b = bb.derived();
1410  return a >= b.coeff(0);
1411 }
1412 
1413 template <typename T>
1414 bool
1416  const typename Taylor<T>::value_type& b)
1417 {
1418  const Taylor<T>& a = aa.derived();
1419  return a.coeff(0) >= b;
1420 }
1421 
1422 template <typename T>
1423 bool
1424 operator<(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 
1432 template <typename T>
1433 bool
1434 operator<(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 
1441 template <typename T>
1442 bool
1443 operator<(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 
1450 template <typename T>
1451 bool
1452 operator>(const Base< Taylor<T> >& aa,
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 
1460 template <typename T>
1461 bool
1463  const Base< Taylor<T> >& bb)
1464 {
1465  const Taylor<T>& b = bb.derived();
1466  return a > b.coeff(0);
1467 }
1468 
1469 template <typename T>
1470 bool
1471 operator>(const Base< Taylor<T> >& aa,
1472  const typename Taylor<T>::value_type& b)
1473 {
1474  const Taylor<T>& a = aa.derived();
1475  return a.coeff(0) > b;
1476 }
1477 
1478 template <typename T>
1479 bool 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 
1486 template <typename T>
1487 inline bool
1488 operator && (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 
1495 template <typename T>
1496 inline bool
1498  const Base< Taylor<T> >& xx2)
1499 {
1500  const Taylor<T>& x2 = xx2.derived();
1501  return a && toBool(x2);
1502 }
1503 
1504 template <typename T>
1505 inline bool
1507  const typename Taylor<T>::value_type& b)
1508 {
1509  const Taylor<T>& x1 = xx1.derived();
1510  return toBool(x1) && b;
1511 }
1512 
1513 template <typename T>
1514 inline bool
1515 operator || (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 
1522 template <typename T>
1523 inline bool
1525  const Base< Taylor<T> >& xx2)
1526 {
1527  const Taylor<T>& x2 = xx2.derived();
1528  return a || toBool(x2);
1529 }
1530 
1531 template <typename T>
1532 inline bool
1534  const typename Taylor<T>::value_type& b)
1535 {
1536  const Taylor<T>& x1 = xx1.derived();
1537  return toBool(x1) || b;
1538 }
1539 
1540 template <typename T>
1541 std::ostream&
1542 operator << (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
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)
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)
static SACADO_INLINE_FUNCTION void zero(T *dest, int sz)
Zero out array dest of length sz.
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.
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.
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 > cbrt(const Base< Taylor< T > > &a)
static SACADO_INLINE_FUNCTION void destroy_and_release(T *m, int sz)
Destroy array elements and release memory.
Taylor< T > fabs(const Base< Taylor< T > > &a)
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.
static SACADO_INLINE_FUNCTION void copy(const T *src, T *dest, int sz)
Copy array from src to dest of length sz.
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())
static SACADO_INLINE_FUNCTION T * get_and_fill(int sz)
Get memory for new array of length sz and fill with zeros.
Taylor()
Default constructor.
bool toBool(const Taylor< T > &x)