Reference documentation for deal.II version 9.0.0
numbers.h
1 // ---------------------------------------------------------------------
2 //
3 // Copyright (C) 2006 - 2018 by the deal.II authors
4 //
5 // This file is part of the deal.II library.
6 //
7 // The deal.II library is free software; you can use it, redistribute
8 // it, and/or modify it under the terms of the GNU Lesser General
9 // Public License as published by the Free Software Foundation; either
10 // version 2.1 of the License, or (at your option) any later version.
11 // The full text of the license can be found in the file LICENSE at
12 // the top level of the deal.II distribution.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_numbers_h
17 #define dealii_numbers_h
18 
19 
20 #include <deal.II/base/config.h>
21 #include <deal.II/base/types.h>
22 
23 #include <cmath>
24 #include <cstdlib>
25 #include <complex>
26 
27 #ifdef DEAL_II_WITH_CUDA
28 # include <cuda_runtime_api.h>
29 # define DEAL_II_CUDA_HOST_DEV __host__ __device__
30 #else
31 # define DEAL_II_CUDA_HOST_DEV
32 #endif
33 
34 DEAL_II_NAMESPACE_OPEN
35 
36 // forward declarations to support abs or sqrt operations on VectorizedArray
37 template <typename Number> class VectorizedArray;
38 template <typename T> struct EnableIfScalar;
39 
40 DEAL_II_NAMESPACE_CLOSE
41 
42 // Declare / Import auto-differentiable math functions in(to) standard
43 // namespace before numbers::NumberTraits is defined
44 #ifdef DEAL_II_WITH_ADOLC
45 #include <adolc/adouble.h> // Taped double
46 #include <deal.II/differentiation/ad/adolc_math.h>
47 #endif
48 // Ideally we'd like to #include <deal.II/differentiation/ad/sacado_math.h>
49 // but header indirectly references numbers.h. We therefore simply
50 // import the whole Sacado header at this point to get the math
51 // functions imported into the standard namespace.
52 #ifdef DEAL_II_WITH_TRILINOS
53 #include <Sacado.hpp>
54 #endif
55 
56 namespace std
57 {
58  template <typename Number> DEAL_II_ALWAYS_INLINE ::VectorizedArray<Number>
59  sqrt(const ::VectorizedArray<Number> &);
60  template <typename Number> DEAL_II_ALWAYS_INLINE ::VectorizedArray<Number>
61  abs(const ::VectorizedArray<Number> &);
62  template <typename Number> DEAL_II_ALWAYS_INLINE ::VectorizedArray<Number>
63  max(const ::VectorizedArray<Number> &, const ::VectorizedArray<Number> &);
64  template <typename Number> DEAL_II_ALWAYS_INLINE ::VectorizedArray<Number>
65  min (const ::VectorizedArray<Number> &, const ::VectorizedArray<Number> &);
66  template <typename Number> ::VectorizedArray<Number>
67  pow(const ::VectorizedArray<Number> &, const Number p);
68  template <typename Number> ::VectorizedArray<Number>
69  sin(const ::VectorizedArray<Number> &);
70  template <typename Number> ::VectorizedArray<Number>
71  cos(const ::VectorizedArray<Number> &);
72  template <typename Number> ::VectorizedArray<Number>
73  tan(const ::VectorizedArray<Number> &);
74  template <typename Number> ::VectorizedArray<Number>
75  exp(const ::VectorizedArray<Number> &);
76  template <typename Number> ::VectorizedArray<Number>
77  log(const ::VectorizedArray<Number> &);
78 }
79 
80 DEAL_II_NAMESPACE_OPEN
81 
97 namespace numbers
98 {
102  static const double E = 2.7182818284590452354;
103 
107  static const double LOG2E = 1.4426950408889634074;
108 
112  static const double LOG10E = 0.43429448190325182765;
113 
117  static const double LN2 = 0.69314718055994530942;
118 
122  static const double LN10 = 2.30258509299404568402;
123 
127  static const double PI = 3.14159265358979323846;
128 
132  static const double PI_2 = 1.57079632679489661923;
133 
137  static const double PI_4 = 0.78539816339744830962;
138 
142  static const double SQRT2 = 1.41421356237309504880;
143 
147  static const double SQRT1_2 = 0.70710678118654752440;
148 
162  DEAL_II_DEPRECATED
163  bool is_nan (const double x);
164 
174  bool is_finite (const double x);
175 
180  bool is_finite (const std::complex<double> &x);
181 
186  bool is_finite (const std::complex<float> &x);
187 
196  bool is_finite (const std::complex<long double> &x);
197 
208  template <typename Number1,typename Number2>
209  bool
210  values_are_equal (const Number1 &value_1, const Number2 &value_2);
211 
222  template <typename Number1,typename Number2>
223  bool
224  values_are_not_equal (const Number1 &value_1, const Number2 &value_2);
225 
233  template <typename Number>
234  bool
235  value_is_zero (const Number &value);
236 
247  template <typename Number1,typename Number2>
248  bool
249  value_is_less_than (const Number1 &value_1, const Number2 &value_2);
250 
261  template <typename Number1,typename Number2>
262  bool
263  value_is_less_than_or_equal_to (const Number1 &value_1, const Number2 &value_2);
264 
265 
266 
277  template <typename Number1,typename Number2>
278  bool
279  value_is_greater_than (const Number1 &value_1, const Number2 &value_2);
280 
291  template <typename Number1,typename Number2>
292  bool
293  value_is_greater_than_or_equal_to (const Number1 &value_1, const Number2 &value_2);
294 
305  template <typename number>
307  {
313  static const bool is_complex = false;
314 
321  typedef number real_type;
322 
328  static
329  DEAL_II_CUDA_HOST_DEV
330  const number &conjugate (const number &x);
331 
339  static
340  DEAL_II_CUDA_HOST_DEV
341  real_type abs_square (const number &x);
342 
346  static
347  real_type abs (const number &x);
348  };
349 
350 
357  template <typename number>
358  struct NumberTraits<std::complex<number> >
359  {
365  static const bool is_complex = true;
366 
373  typedef number real_type;
374 
378  static
379  std::complex<number> conjugate (const std::complex<number> &x);
380 
387  static
388  real_type abs_square (const std::complex<number> &x);
389 
390 
394  static
395  real_type abs (const std::complex<number> &x);
396  };
397 
398  // --------------- inline and template functions ---------------- //
399 
400  inline bool is_nan (const double x)
401  {
402  return std::isnan(x);
403  }
404 
405  inline bool is_finite (const double x)
406  {
407  return std::isfinite(x);
408  }
409 
410 
411 
412  inline bool is_finite (const std::complex<double> &x)
413  {
414  // Check complex numbers for infinity
415  // by testing real and imaginary part
416  return ( is_finite (x.real())
417  &&
418  is_finite (x.imag()) );
419  }
420 
421 
422 
423  inline bool is_finite (const std::complex<float> &x)
424  {
425  // Check complex numbers for infinity
426  // by testing real and imaginary part
427  return ( is_finite (x.real())
428  &&
429  is_finite (x.imag()) );
430  }
431 
432 
433 
434  inline bool is_finite (const std::complex<long double> &x)
435  {
436  // Same for std::complex<long double>
437  return ( is_finite (x.real())
438  &&
439  is_finite (x.imag()) );
440  }
441 
442 
443  template <typename number>
444  DEAL_II_CUDA_HOST_DEV
445  const number &
447  {
448  return x;
449  }
450 
451 
452 
453  template <typename number>
454  DEAL_II_CUDA_HOST_DEV
457  {
458  return x * x;
459  }
460 
461 
462 
463  template <typename number>
465  NumberTraits<number>::abs (const number &x)
466  {
467  return std::abs(x);
468  }
469 
470 
471 
472  template <typename number>
473  std::complex<number>
474  NumberTraits<std::complex<number> >::conjugate (const std::complex<number> &x)
475  {
476  return std::conj(x);
477  }
478 
479 
480 
481  template <typename number>
482  typename NumberTraits<std::complex<number> >::real_type
483  NumberTraits<std::complex<number> >::abs (const std::complex<number> &x)
484  {
485  return std::abs(x);
486  }
487 
488 
489 
490  template <typename number>
491  typename NumberTraits<std::complex<number> >::real_type
492  NumberTraits<std::complex<number> >::abs_square (const std::complex<number> &x)
493  {
494  return std::norm (x);
495  }
496 
497 }
498 
499 
500 // Forward declarations
502 {
503  namespace AD
504  {
505 
506  namespace internal
507  {
508  // Defined in differentiation/ad/ad_number_traits.h
509  template <typename T>
510  struct NumberType;
511  }
512 
513  // Defined in differentiation/ad/ad_number_traits.h
514  template <typename NumberType>
515  struct is_ad_number;
516  }
517 }
518 
519 
520 namespace internal
521 {
526  template<typename From, typename To>
528  {
529  // Source: https://stackoverflow.com/a/16944130
530  private:
531  template<typename T>
532  static void f(T);
533 
534  template<typename F, typename T>
535  static constexpr auto test(int) ->
536  decltype(f(static_cast<T>(std::declval<F>())),true)
537  {
538  return true;
539  }
540 
541  template<typename F, typename T>
542  static constexpr auto test(...) -> bool
543  {
544  return false;
545  }
546 
547  public:
548 
549  static bool const value = test<From,To>(0);
550  };
551 
562  template <typename T>
563  struct NumberType
564  {
565  static DEAL_II_CUDA_HOST_DEV const T &value (const T &t)
566  {
567  return t;
568  }
569 
570  // Below are generic functions that allows an overload for any
571  // type U that is transformable to type T. This is particularly
572  // useful when needing to cast exotic number types
573  // (e.g. auto-differentiable or symbolic numbers) to a floating
574  // point one, such as might happen when converting between tensor
575  // types.
576 
577  // Type T is constructible from F.
578  template<typename F>
579  static T
580  value (const F &f,
581  typename std::enable_if<
582  !std::is_same<typename std::decay<T>::type,typename std::decay<F>::type>::value &&
583  std::is_constructible<T,F>::value
584  >::type * = nullptr)
585  {
586  return T(f);
587  }
588 
589  // Type T is explicitly convertible (but not constructible) from F.
590  template<typename F>
591  static T
592  value (const F &f,
593  typename std::enable_if<
594  !std::is_same<typename std::decay<T>::type,typename std::decay<F>::type>::value &&
595  !std::is_constructible<T,F>::value &&
597  >::type * = nullptr)
598  {
599  return static_cast<T>(f);
600  }
601 
602  // Sacado doesn't provide any conversion operators, so we have
603  // to extract the value and perform further conversions from there.
604  // To be safe, we extend this to other possible AD numbers that
605  // might fall into the same category.
606  template<typename F>
607  static T
608  value (const F &f,
609  typename std::enable_if<
610  !std::is_same<typename std::decay<T>::type,typename std::decay<F>::type>::value &&
611  !std::is_constructible<T,F>::value &&
614  >::type * = nullptr)
615  {
617  }
618 
619  };
620 
621  template <typename T>
622  struct NumberType<std::complex<T> >
623  {
624  static const std::complex<T> &value (const std::complex<T> &t)
625  {
626  return t;
627  }
628 
629  static std::complex<T> value (const T &t)
630  {
631  return std::complex<T>(t);
632  }
633 
634  // Facilitate cast from complex<double> to complex<float>
635  template <typename U>
636  static std::complex<T> value (const std::complex<U> &t)
637  {
638  return std::complex<T>(
639  NumberType<T>::value(t.real()),
640  NumberType<T>::value(t.imag()));
641  }
642  };
643 }
644 
645 namespace numbers
646 {
647 
648 #ifdef DEAL_II_ADOLC_WITH_ADVANCED_BRANCHING
649 
660  // Defined in differentiation/ad/adolc_number_types.cc
661  bool
662  values_are_equal (const adouble &value_1,
663  const adouble &value_2);
664 
665 
676  template <typename Number>
677  bool
678  values_are_equal (const adouble &value_1,
679  const Number &value_2)
680  {
681  // Use the specialized definition for two Adol-C taped types
682  return values_are_equal(value_1, internal::NumberType<adouble>::value(value_2));
683  }
684 
685 
696  template <typename Number>
697  bool
698  values_are_equal (const Number &value_1,
699  const adouble &value_2)
700  {
701  // Use the above definition
702  return values_are_equal(value_2, value_1);
703  }
704 
716  // Defined in differentiation/ad/adolc_number_types.cc
717  bool
718  value_is_less_than (const adouble &value_1,
719  const adouble &value_2);
720 
721 
733  template <typename Number>
734  bool
735  value_is_less_than (const adouble &value_1,
736  const Number &value_2)
737  {
738  // Use the specialized definition for two Adol-C taped types
740  }
741 
742 
754  template <typename Number>
755  bool
756  value_is_less_than (const Number &value_1,
757  const adouble &value_2)
758  {
759  // Use the specialized definition for two Adol-C taped types
761  }
762 
763 #endif
764 
765 
766  template <typename Number1,typename Number2>
767  inline bool
768  values_are_equal (const Number1 &value_1, const Number2 &value_2)
769  {
770  return (value_1 == internal::NumberType<Number1>::value(value_2));
771  }
772 
773 
774  template <typename Number1,typename Number2>
775  inline bool
776  values_are_not_equal (const Number1 &value_1, const Number2 &value_2)
777  {
778  return !(values_are_equal(value_1,value_2));
779  }
780 
781 
782  template <typename Number>
783  inline bool
784  value_is_zero (const Number &value)
785  {
786  return values_are_equal(value, 0.0);
787  }
788 
789 
790  template <typename Number1,typename Number2>
791  inline bool
792  value_is_less_than (const Number1 &value_1, const Number2 &value_2)
793  {
794  return (value_1 < internal::NumberType<Number1>::value(value_2));
795  }
796 
797 
798  template <typename Number1,typename Number2>
799  inline bool
800  value_is_less_than_or_equal_to (const Number1 &value_1, const Number2 &value_2)
801  {
802  return (value_is_less_than(value_1,value_2) || values_are_equal(value_1,value_2));
803  }
804 
805 
806  template <typename Number1,typename Number2>
807  bool
808  value_is_greater_than (const Number1 &value_1, const Number2 &value_2)
809  {
810  return !(value_is_less_than_or_equal_to(value_1,value_2));
811  }
812 
813 
814  template <typename Number1,typename Number2>
815  inline bool
816  value_is_greater_than_or_equal_to (const Number1 &value_1, const Number2 &value_2)
817  {
818  return !(value_is_less_than(value_1,value_2));
819  }
820 }
821 
822 DEAL_II_NAMESPACE_CLOSE
823 
824 #endif
static const number & conjugate(const number &x)
Definition: numbers.h:446
static const double SQRT2
Definition: numbers.h:142
bool value_is_less_than_or_equal_to(const Number1 &value_1, const Number2 &value_2)
Definition: numbers.h:800
static const double PI_4
Definition: numbers.h:137
bool value_is_zero(const Number &value)
Definition: numbers.h:784
STL namespace.
static real_type abs(const number &x)
Definition: numbers.h:465
bool values_are_equal(const Number1 &value_1, const Number2 &value_2)
Definition: numbers.h:768
bool is_finite(const double x)
Definition: numbers.h:405
static const double PI
Definition: numbers.h:127
static const double LN2
Definition: numbers.h:117
static real_type abs_square(const number &x)
Definition: numbers.h:456
static const double E
Definition: numbers.h:102
bool values_are_not_equal(const Number1 &value_1, const Number2 &value_2)
Definition: numbers.h:776
static const bool is_complex
Definition: numbers.h:313
bool is_nan(const double x)
Definition: numbers.h:400
bool value_is_greater_than_or_equal_to(const Number1 &value_1, const Number2 &value_2)
Definition: numbers.h:816
bool value_is_greater_than(const Number1 &value_1, const Number2 &value_2)
Definition: numbers.h:808
bool value_is_less_than(const Number1 &value_1, const Number2 &value_2)
Definition: numbers.h:792
static const double PI_2
Definition: numbers.h:132
T min(const T &t, const MPI_Comm &mpi_communicator)
static const double LN10
Definition: numbers.h:122
static const double LOG2E
Definition: numbers.h:107
static const double SQRT1_2
Definition: numbers.h:147
T max(const T &t, const MPI_Comm &mpi_communicator)
static const double LOG10E
Definition: numbers.h:112