From: bangerth Date: Sat, 3 Nov 2007 23:58:37 +0000 (+0000) Subject: Provide the first few parts of numbers::NumberTraits X-Git-Url: https://gitweb.dealii.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1d50c11688f5948929a643e3e30edf9c7772ede1;p=dealii-svn.git Provide the first few parts of numbers::NumberTraits git-svn-id: https://svn.dealii.org/trunk@15434 0785d39b-7218-0410-832d-ea1e28bc413d --- diff --git a/deal.II/base/include/base/numbers.h b/deal.II/base/include/base/numbers.h index e345a4a638..934885ef2e 100644 --- a/deal.II/base/include/base/numbers.h +++ b/deal.II/base/include/base/numbers.h @@ -145,6 +145,102 @@ namespace numbers * long double. */ bool is_finite (const std::complex x); + + /** + * A structure that, together with its + * partial specializations, provides traits + * and member functions that make it + * possible to write templates that work on + * both real number types and complex + * number types. This template is mostly + * used to implement linear algebra classes + * such as vectors and matrices that work + * for both real and complex numbers. + * + * @author Wolfgang Bangerth, 2007 + */ + template + struct NumberTraits + { + /** + * For this data type, typedef the + * corresponding real type. Since the + * general template is selected for all + * data types that are not + * specializations of std::complex, + * the underlying type must be + * real-values, so the real_type is + * equal to the underlying type. + */ + typedef number real_type; + + /** + * Return the complex-conjugate of the + * given number. Since the general + * template is selected if number is + * not a complex data type, this + * function simply returns the given + * number. + */ + static + const number & conjugate (const number &x); + + /** + * Return the square of the absolute + * value of the given number. Since the + * general template is chosen for types + * not equal to std::complex, this + * function simply returns the square + * of the given number. + */ + static + real_type abs_square (const number &x); + }; + + + /** + * Specialization of the general + * NumberTraits class that provides the + * relevant information if the underlying + * data type is std::complex. + * + * @author Wolfgang Bangerth, 2007 + */ + template + struct NumberTraits > + { + /** + * For this data type, typedef the + * corresponding real type. Since this + * specialization of the template is + * selected for number types + * std::complex, the real type is + * equal to the type used to store the + * two components of the complex + * number. + */ + typedef number real_type; + + /** + * Return the complex-conjugate of the + * given number. + */ + static + std::complex conjugate (const std::complex &x); + + /** + * Return the square of the absolute + * value of the given number. Since + * this specialization of the general + * template is chosen for types equal + * to std::complex, this function + * returns the product of a number and + * its complex conjugate. + */ + static + real_type abs_square (const std::complex &x); + }; + } @@ -159,6 +255,46 @@ namespace numbers namespace deal_II_numbers = numbers; +/* --------------- inline and template functions ---------------- */ +namespace numbers +{ + template + const number & + NumberTraits::conjugate (const number &x) + { + return x; + } + + + + template + typename NumberTraits::real_type + NumberTraits::abs_square (const number &x) + { + return x * x; + } + + + + template + std::complex + NumberTraits >::conjugate (const std::complex &x) + { + return std::conj(x); + } + + + + template + typename NumberTraits >::real_type + NumberTraits >::abs_square (const std::complex &x) + { + return std::norm (x); + } + +} + + DEAL_II_NAMESPACE_CLOSE diff --git a/deal.II/doc/news/changes.h b/deal.II/doc/news/changes.h index efbbc4059c..67ddb23054 100644 --- a/deal.II/doc/news/changes.h +++ b/deal.II/doc/news/changes.h @@ -120,6 +120,12 @@ inconvenience this causes.

base

    +
  1. New: There is now a template numbers::NumberTraits that provides + the means to implement linear algebra and other algorithms for both real + and complex data types. +
    + (WB 2007/11/03) +

  2. New: The DataOutBase class and derived classes can now deal with data that is logically vector-valued, i.e. derived classes can pass down information that some of diff --git a/tests/base/Makefile b/tests/base/Makefile index a9ed4112e9..8b6898977f 100644 --- a/tests/base/Makefile +++ b/tests/base/Makefile @@ -51,7 +51,8 @@ tests_x = geometry_info_* \ functions_* \ function_parser \ utilities_* \ - is_finite + is_finite \ + number_traits_* ifeq ($(enable-multithreading),no) tests_x += threads diff --git a/tests/base/number_traits_complex.cc b/tests/base/number_traits_complex.cc new file mode 100644 index 0000000000..c37530b072 --- /dev/null +++ b/tests/base/number_traits_complex.cc @@ -0,0 +1,62 @@ +//---------------------------- number_traits_complex.cc --------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2005, 2006, 2007 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//---------------------------- number_traits_complex.cc --------------------------- + +// check numbers::NumberTraits for real data types + +#include "../tests.h" +#include +#include +#include +#include +#include + + +template +void check (const number &x) +{ + deallog << "typeid(x).name() = " << typeid(x).name() + << std::endl; + + deallog << "typeid(NumberTraits::real_type).name() = " + << typeid(typename numbers::NumberTraits::real_type).name() + << std::endl; + + deallog << numbers::NumberTraits::conjugate (x) + << std::endl; + + deallog << numbers::NumberTraits::abs_square (x) + << std::endl; +} + + + +int main () +{ + std::ofstream logfile("number_traits_complex/output"); + logfile.precision(3); + deallog.attach(logfile); + deallog.depth_console(0); + deallog.threshold_double(1.e-10); + + check (std::complex(1.5, 2.5)); + check (std::complex(-1.5, -2.5)); + + check (std::complex(1.5, 2.5)); + check (std::complex(-1.5, -2.5)); + + check (std::complex(1.5, 2.5)); + check (std::complex(-1.5, -2.5)); + + return 0; +} + diff --git a/tests/base/number_traits_complex/cmp/generic b/tests/base/number_traits_complex/cmp/generic new file mode 100644 index 0000000000..1802a34257 --- /dev/null +++ b/tests/base/number_traits_complex/cmp/generic @@ -0,0 +1,25 @@ + +DEAL::typeid(x).name() = St7complexIfE +DEAL::typeid(NumberTraits::real_type).name() = f +DEAL::(1.50,-2.50) +DEAL::8.50 +DEAL::typeid(x).name() = St7complexIfE +DEAL::typeid(NumberTraits::real_type).name() = f +DEAL::(-1.50,2.50) +DEAL::8.50 +DEAL::typeid(x).name() = St7complexIdE +DEAL::typeid(NumberTraits::real_type).name() = d +DEAL::(1.50,-2.50) +DEAL::8.50 +DEAL::typeid(x).name() = St7complexIdE +DEAL::typeid(NumberTraits::real_type).name() = d +DEAL::(-1.50,2.50) +DEAL::8.50 +DEAL::typeid(x).name() = St7complexIeE +DEAL::typeid(NumberTraits::real_type).name() = e +DEAL::(1.50,-2.50) +DEAL::8.50 +DEAL::typeid(x).name() = St7complexIeE +DEAL::typeid(NumberTraits::real_type).name() = e +DEAL::(-1.50,2.50) +DEAL::8.50 diff --git a/tests/base/number_traits_real.cc b/tests/base/number_traits_real.cc new file mode 100644 index 0000000000..5d44968af5 --- /dev/null +++ b/tests/base/number_traits_real.cc @@ -0,0 +1,62 @@ +//---------------------------- number_traits_real.cc --------------------------- +// $Id$ +// Version: $Name$ +// +// Copyright (C) 2005, 2006, 2007 by the deal.II authors +// +// This file is subject to QPL and may not be distributed +// without copyright and license information. Please refer +// to the file deal.II/doc/license.html for the text and +// further information on this license. +// +//---------------------------- number_traits_real.cc --------------------------- + +// check numbers::NumberTraits for real data types + +#include "../tests.h" +#include +#include +#include +#include +#include + + +template +void check (const number &x) +{ + deallog << "typeid(x).name() = " << typeid(x).name() + << std::endl; + + deallog << "typeid(NumberTraits::real_type).name() = " + << typeid(typename numbers::NumberTraits::real_type).name() + << std::endl; + + deallog << numbers::NumberTraits::conjugate (x) + << std::endl; + + deallog << numbers::NumberTraits::abs_square (x) + << std::endl; +} + + + +int main () +{ + std::ofstream logfile("number_traits_real/output"); + logfile.precision(3); + deallog.attach(logfile); + deallog.depth_console(0); + deallog.threshold_double(1.e-10); + + check ((float)1.5); + check ((float)-1.5); + + check ((double)1.5); + check ((double)-1.5); + + check ((long double)1.5); + check ((long double)-1.5); + + return 0; +} + diff --git a/tests/base/number_traits_real/cmp/generic b/tests/base/number_traits_real/cmp/generic new file mode 100644 index 0000000000..bfcaccfd64 --- /dev/null +++ b/tests/base/number_traits_real/cmp/generic @@ -0,0 +1,25 @@ + +DEAL::typeid(x).name() = f +DEAL::typeid(NumberTraits::real_type).name() = f +DEAL::1.50 +DEAL::2.25 +DEAL::typeid(x).name() = f +DEAL::typeid(NumberTraits::real_type).name() = f +DEAL::-1.50 +DEAL::2.25 +DEAL::typeid(x).name() = d +DEAL::typeid(NumberTraits::real_type).name() = d +DEAL::1.50 +DEAL::2.25 +DEAL::typeid(x).name() = d +DEAL::typeid(NumberTraits::real_type).name() = d +DEAL::-1.50 +DEAL::2.25 +DEAL::typeid(x).name() = e +DEAL::typeid(NumberTraits::real_type).name() = e +DEAL::1.50 +DEAL::2.25 +DEAL::typeid(x).name() = e +DEAL::typeid(NumberTraits::real_type).name() = e +DEAL::-1.50 +DEAL::2.25