Reference documentation for deal.II version 9.1.0-pre
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.md at
12 // the top level directory of deal.II.
13 //
14 // ---------------------------------------------------------------------
15 
16 #ifndef dealii_numbers_h
17 #define dealii_numbers_h
18 
19 
20 #include <deal.II/base/config.h>
21 
22 #include <deal.II/base/types.h>
23 
24 #include <cmath>
25 #include <complex>
26 #include <cstdlib>
27 
28 #ifdef DEAL_II_WITH_CUDA
29 # include <cuda_runtime_api.h>
30 # define DEAL_II_CUDA_HOST_DEV __host__ __device__
31 #else
32 # define DEAL_II_CUDA_HOST_DEV
33 #endif
34 
35 DEAL_II_NAMESPACE_OPEN
36 
37 // forward declarations to support abs or sqrt operations on VectorizedArray
38 template <typename Number>
39 class VectorizedArray;
40 template <typename T>
41 struct EnableIfScalar;
42 
43 DEAL_II_NAMESPACE_CLOSE
44 
45 // Declare / Import auto-differentiable math functions in(to) standard
46 // namespace before numbers::NumberTraits is defined
47 #ifdef DEAL_II_WITH_ADOLC
48 # include <deal.II/differentiation/ad/adolc_math.h>
49 
50 # include <adolc/adouble.h> // Taped double
51 #endif
52 // Ideally we'd like to #include <deal.II/differentiation/ad/sacado_math.h>
53 // but header indirectly references numbers.h. We therefore simply
54 // import the whole Sacado header at this point to get the math
55 // functions imported into the standard namespace.
56 #ifdef DEAL_II_TRILINOS_WITH_SACADO
57 # include <Sacado.hpp>
58 #endif
59 
60 namespace std
61 {
62  template <typename Number>
63  DEAL_II_ALWAYS_INLINE ::VectorizedArray<Number>
64  sqrt(const ::VectorizedArray<Number> &);
65  template <typename Number>
66  DEAL_II_ALWAYS_INLINE ::VectorizedArray<Number>
67  abs(const ::VectorizedArray<Number> &);
68  template <typename Number>
69  DEAL_II_ALWAYS_INLINE ::VectorizedArray<Number>
70  max(const ::VectorizedArray<Number> &,
71  const ::VectorizedArray<Number> &);
72  template <typename Number>
73  DEAL_II_ALWAYS_INLINE ::VectorizedArray<Number>
74  min(const ::VectorizedArray<Number> &,
75  const ::VectorizedArray<Number> &);
76  template <typename Number>
78  pow(const ::VectorizedArray<Number> &, const Number p);
79  template <typename Number>
81  sin(const ::VectorizedArray<Number> &);
82  template <typename Number>
84  cos(const ::VectorizedArray<Number> &);
85  template <typename Number>
87  tan(const ::VectorizedArray<Number> &);
88  template <typename Number>
90  exp(const ::VectorizedArray<Number> &);
91  template <typename Number>
93  log(const ::VectorizedArray<Number> &);
94 } // namespace std
95 
96 DEAL_II_NAMESPACE_OPEN
97 
113 namespace numbers
114 {
118  static const double E = 2.7182818284590452354;
119 
123  static const double LOG2E = 1.4426950408889634074;
124 
128  static const double LOG10E = 0.43429448190325182765;
129 
133  static const double LN2 = 0.69314718055994530942;
134 
138  static const double LN10 = 2.30258509299404568402;
139 
143  static const double PI = 3.14159265358979323846;
144 
148  static const double PI_2 = 1.57079632679489661923;
149 
153  static const double PI_4 = 0.78539816339744830962;
154 
158  static const double SQRT2 = 1.41421356237309504880;
159 
163  static const double SQRT1_2 = 0.70710678118654752440;
164 
178  DEAL_II_DEPRECATED
179  bool
180  is_nan(const double x);
181 
191  bool
192  is_finite(const double x);
193 
198  bool
199  is_finite(const std::complex<double> &x);
200 
205  bool
206  is_finite(const std::complex<float> &x);
207 
216  bool
217  is_finite(const std::complex<long double> &x);
218 
229  template <typename Number1, typename Number2>
230  bool
231  values_are_equal(const Number1 &value_1, const Number2 &value_2);
232 
243  template <typename Number1, typename Number2>
244  bool
245  values_are_not_equal(const Number1 &value_1, const Number2 &value_2);
246 
254  template <typename Number>
255  bool
256  value_is_zero(const Number &value);
257 
268  template <typename Number1, typename Number2>
269  bool
270  value_is_less_than(const Number1 &value_1, const Number2 &value_2);
271 
282  template <typename Number1, typename Number2>
283  bool
284  value_is_less_than_or_equal_to(const Number1 &value_1,
285  const Number2 &value_2);
286 
287 
288 
299  template <typename Number1, typename Number2>
300  bool
301  value_is_greater_than(const Number1 &value_1, const Number2 &value_2);
302 
313  template <typename Number1, typename Number2>
314  bool
315  value_is_greater_than_or_equal_to(const Number1 &value_1,
316  const Number2 &value_2);
317 
328  template <typename number>
330  {
336  static const bool is_complex = false;
337 
344  using real_type = number;
345 
351  static DEAL_II_CUDA_HOST_DEV const number &
352  conjugate(const number &x);
353 
361  static DEAL_II_CUDA_HOST_DEV real_type
362  abs_square(const number &x);
363 
367  static real_type
368  abs(const number &x);
369  };
370 
371 
378  template <typename number>
379  struct NumberTraits<std::complex<number>>
380  {
386  static const bool is_complex = true;
387 
394  using real_type = number;
395 
399  static std::complex<number>
400  conjugate(const std::complex<number> &x);
401 
408  static real_type
409  abs_square(const std::complex<number> &x);
410 
411 
415  static real_type
416  abs(const std::complex<number> &x);
417  };
418 
419  // --------------- inline and template functions ---------------- //
420 
421  inline bool
422  is_nan(const double x)
423  {
424  return std::isnan(x);
425  }
426 
427  inline bool
428  is_finite(const double x)
429  {
430  return std::isfinite(x);
431  }
432 
433 
434 
435  inline bool
436  is_finite(const std::complex<double> &x)
437  {
438  // Check complex numbers for infinity
439  // by testing real and imaginary part
440  return (is_finite(x.real()) && is_finite(x.imag()));
441  }
442 
443 
444 
445  inline bool
446  is_finite(const std::complex<float> &x)
447  {
448  // Check complex numbers for infinity
449  // by testing real and imaginary part
450  return (is_finite(x.real()) && is_finite(x.imag()));
451  }
452 
453 
454 
455  inline bool
456  is_finite(const std::complex<long double> &x)
457  {
458  // Same for std::complex<long double>
459  return (is_finite(x.real()) && is_finite(x.imag()));
460  }
461 
462 
463  template <typename number>
464  DEAL_II_CUDA_HOST_DEV const number &
466  {
467  return x;
468  }
469 
470 
471 
472  template <typename number>
473  DEAL_II_CUDA_HOST_DEV typename NumberTraits<number>::real_type
475  {
476  return x * x;
477  }
478 
479 
480 
481  template <typename number>
483  NumberTraits<number>::abs(const number &x)
484  {
485  return std::abs(x);
486  }
487 
488 
489 
490  template <typename number>
491  std::complex<number>
492  NumberTraits<std::complex<number>>::conjugate(const std::complex<number> &x)
493  {
494  return std::conj(x);
495  }
496 
497 
498 
499  template <typename number>
501  NumberTraits<std::complex<number>>::abs(const std::complex<number> &x)
502  {
503  return std::abs(x);
504  }
505 
506 
507 
508  template <typename number>
510  NumberTraits<std::complex<number>>::abs_square(const std::complex<number> &x)
511  {
512  return std::norm(x);
513  }
514 
515 } // namespace numbers
516 
517 
518 // Forward declarations
520 {
521  namespace AD
522  {
523  namespace internal
524  {
525  // Defined in differentiation/ad/ad_number_traits.h
526  template <typename T>
527  struct NumberType;
528  } // namespace internal
529 
530  // Defined in differentiation/ad/ad_number_traits.h
531  template <typename NumberType>
532  struct is_ad_number;
533  } // namespace AD
534 } // namespace Differentiation
535 
536 
537 namespace internal
538 {
543  template <typename From, typename To>
545  {
546  // Source: https://stackoverflow.com/a/16944130
547  private:
548  template <typename T>
549  static void f(T);
550 
551  template <typename F, typename T>
552  static constexpr auto
553  test(int) -> decltype(f(static_cast<T>(std::declval<F>())), true)
554  {
555  return true;
556  }
557 
558  template <typename F, typename T>
559  static constexpr auto
560  test(...) -> bool
561  {
562  return false;
563  }
564 
565  public:
566  static bool const value = test<From, To>(0);
567  };
568 
582  template <typename T>
583  struct NumberType
584  {
585  static DEAL_II_CUDA_HOST_DEV const T &
586  value(const T &t)
587  {
588  return t;
589  }
590 
591  // Below are generic functions that allows an overload for any
592  // type U that is transformable to type T. This is particularly
593  // useful when needing to cast exotic number types
594  // (e.g. auto-differentiable or symbolic numbers) to a floating
595  // point one, such as might happen when converting between tensor
596  // types.
597 
598  // Type T is constructible from F.
599  template <typename F>
600  static T
601  value(const F &f,
602  typename std::enable_if<
603  !std::is_same<typename std::decay<T>::type,
604  typename std::decay<F>::type>::value &&
605  std::is_constructible<T, F>::value>::type * = nullptr)
606  {
607  return T(f);
608  }
609 
610  // Type T is explicitly convertible (but not constructible) from F.
611  template <typename F>
612  static T
613  value(const F &f,
614  typename std::enable_if<
615  !std::is_same<typename std::decay<T>::type,
616  typename std::decay<F>::type>::value &&
617  !std::is_constructible<T, F>::value &&
619  {
620  return static_cast<T>(f);
621  }
622 
623  // Sacado doesn't provide any conversion operators, so we have
624  // to extract the value and perform further conversions from there.
625  // To be safe, we extend this to other possible AD numbers that
626  // might fall into the same category.
627  template <typename F>
628  static T
629  value(const F &f,
630  typename std::enable_if<
631  !std::is_same<typename std::decay<T>::type,
632  typename std::decay<F>::type>::value &&
633  !std::is_constructible<T, F>::value &&
636  {
638  }
639  };
640 
641  template <typename T>
642  struct NumberType<std::complex<T>>
643  {
644  static const std::complex<T> &
645  value(const std::complex<T> &t)
646  {
647  return t;
648  }
649 
650  static std::complex<T>
651  value(const T &t)
652  {
653  return std::complex<T>(t);
654  }
655 
656  // Facilitate cast from complex<double> to complex<float>
657  template <typename U>
658  static std::complex<T>
659  value(const std::complex<U> &t)
660  {
661  return std::complex<T>(NumberType<T>::value(t.real()),
662  NumberType<T>::value(t.imag()));
663  }
664  };
665 } // namespace internal
666 
667 namespace numbers
668 {
669 #ifdef DEAL_II_ADOLC_WITH_ADVANCED_BRANCHING
670 
681  // Defined in differentiation/ad/adolc_number_types.cc
682  bool
683  values_are_equal(const adouble &value_1, const adouble &value_2);
684 
685 
696  template <typename Number>
697  bool
698  values_are_equal(const adouble &value_1, const Number &value_2)
699  {
700  // Use the specialized definition for two Adol-C taped types
701  return values_are_equal(value_1,
703  }
704 
705 
716  template <typename Number>
717  bool
718  values_are_equal(const Number &value_1, const adouble &value_2)
719  {
720  // Use the above definition
721  return values_are_equal(value_2, value_1);
722  }
723 
735  // Defined in differentiation/ad/adolc_number_types.cc
736  bool
737  value_is_less_than(const adouble &value_1, const adouble &value_2);
738 
739 
751  template <typename Number>
752  bool
753  value_is_less_than(const adouble &value_1, const Number &value_2)
754  {
755  // Use the specialized definition for two Adol-C taped types
756  return value_is_less_than(value_1,
758  }
759 
760 
772  template <typename Number>
773  bool
774  value_is_less_than(const Number &value_1, const adouble &value_2)
775  {
776  // Use the specialized definition for two Adol-C taped types
777  return value_is_less_than(internal::NumberType<adouble>::value(value_1),
778  value_2);
779  }
780 
781 #endif
782 
783 
784  template <typename Number1, typename Number2>
785  inline bool
786  values_are_equal(const Number1 &value_1, const Number2 &value_2)
787  {
788  return (value_1 == internal::NumberType<Number1>::value(value_2));
789  }
790 
791 
792  template <typename Number1, typename Number2>
793  inline bool
794  values_are_not_equal(const Number1 &value_1, const Number2 &value_2)
795  {
796  return !(values_are_equal(value_1, value_2));
797  }
798 
799 
800  template <typename Number>
801  inline bool
802  value_is_zero(const Number &value)
803  {
804  return values_are_equal(value, 0.0);
805  }
806 
807 
808  template <typename Number1, typename Number2>
809  inline bool
810  value_is_less_than(const Number1 &value_1, const Number2 &value_2)
811  {
812  return (value_1 < internal::NumberType<Number1>::value(value_2));
813  }
814 
815 
816  template <typename Number1, typename Number2>
817  inline bool
818  value_is_less_than_or_equal_to(const Number1 &value_1, const Number2 &value_2)
819  {
820  return (value_is_less_than(value_1, value_2) ||
821  values_are_equal(value_1, value_2));
822  }
823 
824 
825  template <typename Number1, typename Number2>
826  bool
827  value_is_greater_than(const Number1 &value_1, const Number2 &value_2)
828  {
829  return !(value_is_less_than_or_equal_to(value_1, value_2));
830  }
831 
832 
833  template <typename Number1, typename Number2>
834  inline bool
835  value_is_greater_than_or_equal_to(const Number1 &value_1,
836  const Number2 &value_2)
837  {
838  return !(value_is_less_than(value_1, value_2));
839  }
840 } // namespace numbers
841 
842 DEAL_II_NAMESPACE_CLOSE
843 
844 #endif
static const double SQRT2
Definition: numbers.h:158
bool value_is_less_than_or_equal_to(const Number1 &value_1, const Number2 &value_2)
Definition: numbers.h:818
static const double PI_4
Definition: numbers.h:153
bool value_is_zero(const Number &value)
Definition: numbers.h:802
STL namespace.
bool values_are_equal(const Number1 &value_1, const Number2 &value_2)
Definition: numbers.h:786
bool is_finite(const double x)
Definition: numbers.h:428
static const double PI
Definition: numbers.h:143
static const double LN2
Definition: numbers.h:133
static const double E
Definition: numbers.h:118
bool values_are_not_equal(const Number1 &value_1, const Number2 &value_2)
Definition: numbers.h:794
bool is_nan(const double x)
Definition: numbers.h:422
bool value_is_greater_than_or_equal_to(const Number1 &value_1, const Number2 &value_2)
Definition: numbers.h:835
bool value_is_greater_than(const Number1 &value_1, const Number2 &value_2)
Definition: numbers.h:827
bool value_is_less_than(const Number1 &value_1, const Number2 &value_2)
Definition: numbers.h:810
static const double PI_2
Definition: numbers.h:148
T min(const T &t, const MPI_Comm &mpi_communicator)
static const double LN10
Definition: numbers.h:138
static const double LOG2E
Definition: numbers.h:123
static const double SQRT1_2
Definition: numbers.h:163
T max(const T &t, const MPI_Comm &mpi_communicator)
static const double LOG10E
Definition: numbers.h:128