From 5dfb40a26ab0cf4d8a2f5363a48d41dad53c5633 Mon Sep 17 00:00:00 2001 From: Jean-Paul Pelteret Date: Sun, 29 Apr 2018 10:48:42 +0200 Subject: [PATCH] Add more comparators in numbers.h Add a test for the comparators as well --- include/deal.II/base/numbers.h | 192 +++++++++++++++++- .../differentiation/ad/adolc_number_types.cc | 12 ++ tests/base/number_comparators.cc | 51 +++++ tests/base/number_comparators.output | 2 + 4 files changed, 247 insertions(+), 10 deletions(-) create mode 100644 tests/base/number_comparators.cc create mode 100644 tests/base/number_comparators.output diff --git a/include/deal.II/base/numbers.h b/include/deal.II/base/numbers.h index a87894e737..d8c4a01cc7 100644 --- a/include/deal.II/base/numbers.h +++ b/include/deal.II/base/numbers.h @@ -193,10 +193,11 @@ namespace numbers bool is_finite (const std::complex &x); /** - * Return whether two numbers are equal to one another. For intricate data - * types (e.g. some automatically differentiable numbers), this function - * returns only whether the scalar values stored by the input values are - * equal. + * Return whether two numbers are equal to one another. + * + * For intricate data types (e.g. some automatically differentiable numbers), + * this function returns the result of the comparison of scalar values stored + * by the input arguments. * * @note This function expects that @p value_2 is castable to the type * of @p value_1. @@ -206,15 +207,88 @@ namespace numbers values_are_equal (const Number1 &value_1, const Number2 &value_2); /** - * Return whether or not a value is equal to zero. For intricate data - * types (e.g. some automatically differentiable numbers), this function - * returns only whether the scalar value stored by the input value is - * equal to zero. + * Return whether two numbers are not equal to one another. + * + * For intricate data types (e.g. some automatically differentiable numbers), + * this function returns the result of the comparison of scalar values stored + * by the input arguments. + * + * @note This function expects that @p value_2 is castable to the type + * of @p value_1. + */ + template + bool + values_are_not_equal (const Number1 &value_1, const Number2 &value_2); + + /** + * Return whether or not a value is equal to zero. + * + * For intricate data types (e.g. some automatically differentiable numbers), + * this function returns the result of the comparison of scalar values stored + * by the input arguments. */ template bool value_is_zero (const Number &value); + /** + * Return whether @p value_1 is less than that of @p value_2. + * + * For intricate data types (e.g. some automatically differentiable numbers), + * this function returns the result of the comparison of scalar values stored + * by the input arguments. + * + * @note This function expects that @p value_2 is castable to the type + * of @p value_1. + */ + template + bool + value_is_less_than (const Number1 &value_1, const Number2 &value_2); + + /** + * Return whether @p value_1 is less than or equal to that of @p value_2. + * + * For intricate data types (e.g. some automatically differentiable numbers), + * this function returns the result of the comparison of scalar values stored + * by the input arguments. + * + * @note This function expects that @p value_2 is castable to the type + * of @p value_1. + */ + template + bool + value_is_less_than_or_equal_to (const Number1 &value_1, const Number2 &value_2); + + + + /** + * Return whether @p value_1 is greater than that of @p value_2. + * + * For intricate data types (e.g. some automatically differentiable numbers), + * this function returns the result of the comparison of scalar values stored + * by the input arguments. + * + * @note This function expects that @p value_2 is castable to the type + * of @p value_1. + */ + template + bool + value_is_greater_than (const Number1 &value_1, const Number2 &value_2); + + /** + * Return whether @p value_1 is greater than or equal to that of @p value_2. + * + * For intricate data types (e.g. some automatically differentiable numbers), + * this function returns the result of the comparison of scalar values stored + * by the input arguments. + * + * @note This function expects that @p value_2 is castable to the type + * of @p value_1. + */ + template + bool + value_is_greater_than_or_equal_to (const Number1 &value_1, const Number2 &value_2); + /** * A structure that, together with its partial specializations * NumberTraits >, provides traits and member functions @@ -625,23 +699,121 @@ namespace numbers return values_are_equal(value_2, value_1); } + /** + * Return whether @p value_1 is less than that of @p value_2. + * + * For intricate data types (e.g. some automatically differentiable numbers), + * this function returns the result of the comparison of scalar values stored + * by the input arguments. + * + * @note When Adol-C is compiled with the "advanced branching" feature, then + * this specialization is only intended for use in assertions and + * other code paths that do not affect the end result of a computation. + */ + // Defined in differentiation/ad/adolc_number_types.cc + bool + value_is_less_than (const adouble &value_1, + const adouble &value_2); + + + /** + * Return whether @p value_1 is less than that of @p value_2. + * + * For intricate data types (e.g. some automatically differentiable numbers), + * this function returns the result of the comparison of scalar values stored + * by the input arguments. + * + * @note When Adol-C is compiled with the "advanced branching" feature, then + * this specialization is only intended for use in assertions and + * other code paths that do not affect the end result of a computation. + */ + template + bool + value_is_less_than (const adouble &value_1, + const Number &value_2) + { + // Use the specialized definition for two Adol-C taped types + return value_is_less_than(value_1, internal::NumberType::value(value_2)); + } + + + /** + * Return whether @p value_1 is less than that of @p value_2. + * + * For intricate data types (e.g. some automatically differentiable numbers), + * this function returns the result of the comparison of scalar values stored + * by the input arguments. + * + * @note When Adol-C is compiled with the "advanced branching" feature, then + * this specialization is only intended for use in assertions and + * other code paths that do not affect the end result of a computation. + */ + template + bool + value_is_less_than (const Number &value_1, + const adouble &value_2) + { + // Use the specialized definition for two Adol-C taped types + return value_is_less_than(internal::NumberType::value(value_1), value_2); + } + #endif template - bool + inline bool values_are_equal (const Number1 &value_1, const Number2 &value_2) { return (value_1 == internal::NumberType::value(value_2)); } + template + inline bool + values_are_not_equal (const Number1 &value_1, const Number2 &value_2) + { + return !(values_are_equal(value_1,value_2)); + } + + template - bool + inline bool value_is_zero (const Number &value) { return values_are_equal(value, 0.0); } + + + template + inline bool + value_is_less_than (const Number1 &value_1, const Number2 &value_2) + { + return (value_1 < internal::NumberType::value(value_2)); + } + + + template + inline bool + value_is_less_than_or_equal_to (const Number1 &value_1, const Number2 &value_2) + { + return (value_is_less_than(value_1,value_2) || values_are_equal(value_1,value_2)); + } + + + template + bool + value_is_greater_than (const Number1 &value_1, const Number2 &value_2) + { + return !(value_is_less_than_or_equal_to(value_1,value_2)); + } + + + template + inline bool + value_is_greater_than_or_equal_to (const Number1 &value_1, const Number2 &value_2) + { + return !(value_is_less_than(value_1,value_2)); + } } DEAL_II_NAMESPACE_CLOSE diff --git a/source/differentiation/ad/adolc_number_types.cc b/source/differentiation/ad/adolc_number_types.cc index 431ad64219..938813fbcd 100644 --- a/source/differentiation/ad/adolc_number_types.cc +++ b/source/differentiation/ad/adolc_number_types.cc @@ -63,6 +63,18 @@ namespace numbers return dealii::internal::NumberType::value(a == b); }); } + + bool + value_is_less_than (const adouble &value_1, + const adouble &value_2) + { + return internal::adouble_boolean_comparator( + value_1, value_2, + [](const adouble &a,const adouble &b) -> adouble + { + return dealii::internal::NumberType::value(a < b); + }); + } } #endif diff --git a/tests/base/number_comparators.cc b/tests/base/number_comparators.cc new file mode 100644 index 0000000000..15a5bf9efb --- /dev/null +++ b/tests/base/number_comparators.cc @@ -0,0 +1,51 @@ +// --------------------------------------------------------------------- +// +// Copyright (C) 2018 by the deal.II authors +// +// This file is part of the deal.II library. +// +// The deal.II library is free software; you can use it, redistribute +// it, and/or modify it under the terms of the GNU Lesser General +// Public License as published by the Free Software Foundation; either +// version 2.1 of the License, or (at your option) any later version. +// The full text of the license can be found in the file LICENSE at +// the top level of the deal.II distribution. +// +// --------------------------------------------------------------------- + + +// check comparators in numbers namespace + +#include "../tests.h" + +#include + + +template +void check (const Number &a, const Number &b) +{ + AssertThrow((numbers::values_are_equal(a,b)) == (a == b), ExcMessage("Comparator is incorrect.")); + AssertThrow((numbers::values_are_not_equal(a,b)) == (a != b), ExcMessage("Comparator is incorrect.")); + AssertThrow((numbers::value_is_zero(a)) == (a == 0.0), ExcMessage("Comparator is incorrect.")); + AssertThrow((numbers::value_is_zero(b)) == (b == 0.0), ExcMessage("Comparator is incorrect.")); + AssertThrow((numbers::value_is_less_than(a,b)) == (a < b), ExcMessage("Comparator is incorrect.")); + AssertThrow((numbers::value_is_less_than_or_equal_to(a,b)) == (a <= b), ExcMessage("Comparator is incorrect.")); + AssertThrow((numbers::value_is_greater_than(a,b)) == (a > b), ExcMessage("Comparator is incorrect.")); + AssertThrow((numbers::value_is_greater_than_or_equal_to(a,b)) == (a >= b), ExcMessage("Comparator is incorrect.")); +} + + + +int main () +{ + initlog(); + + check (0.0, 2.5); + check (2.5, 1.5); + check (1.5, 1.5); + + deallog << "OK" << std::endl; + + return 0; +} + diff --git a/tests/base/number_comparators.output b/tests/base/number_comparators.output new file mode 100644 index 0000000000..0fd8fc12f0 --- /dev/null +++ b/tests/base/number_comparators.output @@ -0,0 +1,2 @@ + +DEAL::OK -- 2.39.5