From: Wolfgang Bangerth Date: Thu, 23 Jan 2025 14:00:44 +0000 (-0700) Subject: Better document our mixed complex overloads. X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F18023%2Fhead;p=dealii.git Better document our mixed complex overloads. --- diff --git a/cmake/checks/check_01_cxx_features.cmake b/cmake/checks/check_01_cxx_features.cmake index 06cc409ed2..9b0a65c38c 100644 --- a/cmake/checks/check_01_cxx_features.cmake +++ b/cmake/checks/check_01_cxx_features.cmake @@ -466,8 +466,17 @@ endif() # -# Check whether the standard library provides operator* overloads for mixed -# floating point multiplication of complex and real valued numbers. +# Check whether the standard library provides operator* overloads for +# mixed floating point multiplication of complex and real valued +# numbers. The C++ standard does not say that such overloads should +# exist, and so they shouldn't. In other words, a standards compliant +# compiler will fail this check. +# +# In practice, the absence of these overloads makes it quite difficult +# to write mixed-precision linear algebra functions. To make this less +# of a pain, we declare such overloads ourselves (in namespace dealii) +# unless the compiler already has them (which, as mentioned above, it +# shouldn't). # # - Matthias Maier, 2015 # diff --git a/include/deal.II/base/complex_overloads.h b/include/deal.II/base/complex_overloads.h index 69209bf742..379b67253c 100644 --- a/include/deal.II/base/complex_overloads.h +++ b/include/deal.II/base/complex_overloads.h @@ -28,10 +28,33 @@ struct ProductType; #endif #ifndef DEAL_II_HAVE_COMPLEX_OPERATOR_OVERLOADS + /** * Provide an operator* that operates on mixed complex floating point * types. Annoyingly, the standard library does not provide such an - * operator... + * operator. + * + * @note Because the C++ standard does not provide for mixed-precision complex + * operators, code such as the following does not compile: + * @code + * double factor = 3.141; + * std::complex x(1,2); // =1+2i + * auto z = factor*x; // error + * @endcode + * Because this does not compile, writing mixed-precision complex linear + * algebra libraries is not easily possible without much additional work that + * requires explicit casts. For example, one would have to write the code above + * as follows: + * @code + * double factor = 1.0; + * std::complex x(1,2); // =1+2i + * using P = ProductType>::type; + * auto z = static_cast

(factor) * static_cast

(x); + * @endcode + * This makes much code unreadable. As a consequence, we define the + * necessary overloaded multiplication and division operators for mixed + * complex arithmetic (in namespace `dealii`) to make the code above + * compile without the extra casts. * * @relatesalso ProductType */ @@ -49,7 +72,29 @@ operator*(const std::complex &left, const std::complex &right) /** * Provide an operator/ that operates on mixed complex floating point * types. Annoyingly, the standard library does not provide such an - * operator... + * operator. + * + * @note Because the C++ standard does not provide for mixed-precision complex + * operators, code such as the following does not compile: + * @code + * double factor = 3.141; + * std::complex x(1,2); // =1+2i + * auto z = factor*x; // error + * @endcode + * Because this does not compile, writing mixed-precision complex linear + * algebra libraries is not easily possible without much additional work that + * requires explicit casts. For example, one would have to write the code above + * as follows: + * @code + * double factor = 1.0; + * std::complex x(1,2); // =1+2i + * using P = ProductType>::type; + * auto z = static_cast

(factor) * static_cast

(x); + * @endcode + * This makes much code unreadable. As a consequence, we define the + * necessary overloaded multiplication and division operators for mixed + * complex arithmetic (in namespace `dealii`) to make the code above + * compile without the extra casts. * * @relatesalso ProductType */ @@ -67,7 +112,29 @@ operator/(const std::complex &left, const std::complex &right) /** * Provide an operator* for a scalar multiplication of a complex * floating point type with a different real floating point type. Annoyingly, - * the standard library does not provide such an operator... + * the standard library does not provide such an operator. + * + * @note Because the C++ standard does not provide for mixed-precision complex + * operators, code such as the following does not compile: + * @code + * double factor = 3.141; + * std::complex x(1,2); // =1+2i + * auto z = factor*x; // error + * @endcode + * Because this does not compile, writing mixed-precision complex linear + * algebra libraries is not easily possible without much additional work that + * requires explicit casts. For example, one would have to write the code above + * as follows: + * @code + * double factor = 1.0; + * std::complex x(1,2); // =1+2i + * using P = ProductType>::type; + * auto z = static_cast

(factor) * static_cast

(x); + * @endcode + * This makes much code unreadable. As a consequence, we define the + * necessary overloaded multiplication and division operators for mixed + * complex arithmetic (in namespace `dealii`) to make the code above + * compile without the extra casts. * * @relatesalso ProductType */ @@ -84,7 +151,29 @@ operator*(const std::complex &left, const U &right) /** * Provide an operator/ for a scalar division of a complex * floating point type with a different real floating point type. Annoyingly, - * the standard library does not provide such an operator... + * the standard library does not provide such an operator. + * + * @note Because the C++ standard does not provide for mixed-precision complex + * operators, code such as the following does not compile: + * @code + * double factor = 3.141; + * std::complex x(1,2); // =1+2i + * auto z = factor*x; // error + * @endcode + * Because this does not compile, writing mixed-precision complex linear + * algebra libraries is not easily possible without much additional work that + * requires explicit casts. For example, one would have to write the code above + * as follows: + * @code + * double factor = 1.0; + * std::complex x(1,2); // =1+2i + * using P = ProductType>::type; + * auto z = static_cast

(factor) * static_cast

(x); + * @endcode + * This makes much code unreadable. As a consequence, we define the + * necessary overloaded multiplication and division operators for mixed + * complex arithmetic (in namespace `dealii`) to make the code above + * compile without the extra casts. * * @relatesalso ProductType */ @@ -101,7 +190,29 @@ operator/(const std::complex &left, const U &right) /** * Provide an operator* for a scalar multiplication of a real * floating point type with a different complex floating point type. - * Annoyingly, the standard library does not provide such an operator... + * Annoyingly, the standard library does not provide such an operator. + * + * @note Because the C++ standard does not provide for mixed-precision complex + * operators, code such as the following does not compile: + * @code + * double factor = 3.141; + * std::complex x(1,2); // =1+2i + * auto z = factor*x; // error + * @endcode + * Because this does not compile, writing mixed-precision complex linear + * algebra libraries is not easily possible without much additional work that + * requires explicit casts. For example, one would have to write the code above + * as follows: + * @code + * double factor = 1.0; + * std::complex x(1,2); // =1+2i + * using P = ProductType>::type; + * auto z = static_cast

(factor) * static_cast

(x); + * @endcode + * This makes much code unreadable. As a consequence, we define the + * necessary overloaded multiplication and division operators for mixed + * complex arithmetic (in namespace `dealii`) to make the code above + * compile without the extra casts. * * @relatesalso ProductType */ @@ -118,7 +229,29 @@ operator*(const T &left, const std::complex &right) /** * Provide an operator/ for a scalar division of a real * floating point type with a different complex floating point type. - * Annoyingly, the standard library does not provide such an operator... + * Annoyingly, the standard library does not provide such an operator. + * + * @note Because the C++ standard does not provide for mixed-precision complex + * operators, code such as the following does not compile: + * @code + * double factor = 3.141; + * std::complex x(1,2); // =1+2i + * auto z = factor*x; // error + * @endcode + * Because this does not compile, writing mixed-precision complex linear + * algebra libraries is not easily possible without much additional work that + * requires explicit casts. For example, one would have to write the code above + * as follows: + * @code + * double factor = 1.0; + * std::complex x(1,2); // =1+2i + * using P = ProductType>::type; + * auto z = static_cast

(factor) * static_cast

(x); + * @endcode + * This makes much code unreadable. As a consequence, we define the + * necessary overloaded multiplication and division operators for mixed + * complex arithmetic (in namespace `dealii`) to make the code above + * compile without the extra casts. * * @relatesalso ProductType */ @@ -131,6 +264,8 @@ operator/(const T &left, const std::complex &right) using result_type = typename ProductType>::type; return static_cast(left) / static_cast(right); } + + #endif /* DEAL_II_HAVE_COMPLEX_OPERATOR_OVERLOADS */ DEAL_II_NAMESPACE_CLOSE