Skip to content
Snippets Groups Projects
Commit afd9a0c1 authored by Simon Praetorius's avatar Simon Praetorius
Browse files

Provide default definitions of inverse elements

parent bdc6c3a4
No related branches found
No related tags found
No related merge requests found
Pipeline #75679 failed
......@@ -3,5 +3,8 @@
install(FILES
container.hh
field.hh
hashable.hh
identity.hh
inverse.hh
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/dune/common/concepts)
......@@ -6,6 +6,7 @@
#define DUNE_COMMON_CONCEPTS_FIELD_HH
#include <concepts>
#include <functional>
#include <limits>
#include <dune/common/concepts/identity.hh>
......@@ -41,9 +42,25 @@ concept MultiplicativeGroup = requires(G g, std::multiplies<> op)
static_assert(MultiplicativeGroup<Dune::Concept::Archetypes::MultiplicativeGroup<>>);
/**
* \brief The `Field` concept is satisfied by all regular types where addition (+),
* subtraction (-), multiplication (*), and division (/) are defined and behave
* as the corresponding operations in real numbers.
*
* A field is a set of numbers with two operations `+` and `*`, and corresponding
* inverse operations `-` and `/`. Associated to these operations are identity
* element, the zero `0` and one `1` for addition and multiplication, respectively.
* In order to distinguish these numbers, they must be equality comparable. To
* work with these numbers we additionally require that they are semiregular, i.e.,
* default constructible, copyable and movable.
*
* \b Examples:
* - floating-point types like `double`, and `float`
* - complex number types, e.g., `std::complex<double>`
*/
template <class F>
concept Field = std::regular<F> && AdditiveGroup<F> && MultiplicativeGroup<F>
&& std::numeric_limits<F>::is_specialized;
concept Field = std::regular<F> && AdditiveGroup<F> && MultiplicativeGroup<F>;
static_assert(Field<Dune::Concept::Archetypes::Field>);
......
......@@ -10,6 +10,8 @@
#include <concepts>
#include <functional>
#include <dune/common/concepts/identity.hh>
namespace Dune::Concept {
//! Inverse is the inverse element of type `T` of the operation `Op`
......@@ -24,6 +26,26 @@ constexpr auto inverse (T value, Op) noexcept
return Inverse<T,Op>{}(value);
}
template <class T>
requires requires(T value) { -value; }
struct Inverse<T, std::plus<>>
{
T operator() (const T& value) const noexcept
{
return -value;
}
};
template <class T>
requires requires(T value) { identity(value,std::multiplies<>{}) / value; }
struct Inverse<T, std::multiplies<>>
{
T operator() (const T& value) const noexcept
{
return identity(value,std::multiplies<>{}) / value;
}
};
// Overload for floating point types
template <std::floating_point F>
constexpr F inverse (F value, std::plus<>) noexcept
......@@ -54,7 +76,7 @@ struct Inverse<std::complex<F>, std::multiplies<>>
constexpr std::complex<F> operator() (std::complex<F> value) const noexcept
{
assert(value != std::complex<F>(0,0));
return F(1) / value;
return identity(value,std::multiplies<>{}) / value;
}
};
......
......@@ -14,10 +14,30 @@
#include <dune/common/bigunsignedint.hh>
#include <dune/common/fvector.hh>
#include <dune/common/gmpfield.hh>
#include <dune/common/hash.hh>
#include <dune/common/reservedvector.hh>
#include <dune/common/parallel/mpihelper.hh>
template <int precision>
struct Dune::Concept::Identity<Dune::GMPField<precision>, std::plus<>>
{
Dune::GMPField<precision> operator() (const Dune::GMPField<precision>& /*value*/) const noexcept
{
return Dune::GMPField<precision>(0);
}
};
template <int precision>
struct Dune::Concept::Identity<Dune::GMPField<precision>, std::multiplies<>>
{
Dune::GMPField<precision> operator() (const Dune::GMPField<precision>& /*value*/) const noexcept
{
return Dune::GMPField<precision>(1);
}
};
int main (int argc, char **argv)
{
using namespace Dune;
......@@ -41,7 +61,12 @@ int main (int argc, char **argv)
static_assert(not Concept::Container<Dune::FieldVector<double,3>>);
// test Field
static_assert(Concept::Field<float>);
static_assert(Concept::Field<double>);
static_assert(Concept::Field<std::complex<double>>);
#if HAVE_GMP
static_assert(Concept::Field<Dune::GMPField<64>>);
#endif
}
#else // DUNE_ENABLE_CONCEPTS
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment