diff --git a/src/TNL/Assert.h b/src/TNL/Assert.h index df862956219ac03e1d1e1fa27e1c67a0e1035ad5..dc4ba7cf439d4ea25576d75fd1605c4400f6fa23 100644 --- a/src/TNL/Assert.h +++ b/src/TNL/Assert.h @@ -376,6 +376,12 @@ TNL_IMPL_CMP_HELPER_( GT, > ); #define __TNL_PRETTY_FUNCTION __PRETTY_FUNCTION__ #endif +// On Linux, __STRING is defined in glibc's sys/cdefs.h, but there is no such +// header on Windows and possibly other platforms. +#ifndef __STRING + #define __STRING(arg) #arg +#endif + // Internal macro to compose the string representing the assertion. // We can't do it easily at runtime, because we have to support assertions // in CUDA kernels, which can't use std::string objects. Instead, we do it diff --git a/src/TNL/Config/ParameterContainer.h b/src/TNL/Config/ParameterContainer.h index 734db27f512a11124ef512b55ce578301d4c790c..79a50e151063cd9b5358add30422d713e40a0cc8 100644 --- a/src/TNL/Config/ParameterContainer.h +++ b/src/TNL/Config/ParameterContainer.h @@ -82,7 +82,7 @@ public: } /** - * \brief Checks whether the parameter \e name already exists in ParameterContainer. + * \brief Checks if the ParameterContainer contains a parameter specified by its name. * * \param name Name of the parameter. */ @@ -95,6 +95,19 @@ public: return false; } + /** + * \brief Checks whether the ParameterContainer contains all specified parameter names. + * + * \param name Name of the parameter. + */ + bool checkParameters( std::initializer_list< String > names ) const + { + for( auto name : names ) + if( ! checkParameter( name ) ) + return false; + return true; + } + /** * \brief Assigns new \e value to the parameter \e name. * diff --git a/src/TNL/Containers/DistributedVector.h b/src/TNL/Containers/DistributedVector.h index db4e46e68616244399e85fa7903ebe53a1e30585..be9ff657f1cd3c8ad49bf6af8a0aa09fc9242c6a 100644 --- a/src/TNL/Containers/DistributedVector.h +++ b/src/TNL/Containers/DistributedVector.h @@ -134,8 +134,15 @@ public: void scan( IndexType begin = 0, IndexType end = 0 ); }; +// Enable expression templates for DistributedVector +namespace Expressions { + template< typename Real, typename Device, typename Index, typename Communicator > + struct HasEnabledDistributedExpressionTemplates< DistributedVector< Real, Device, Index, Communicator > > + : std::true_type + {}; +} // namespace Expressions + } // namespace Containers } // namespace TNL #include <TNL/Containers/DistributedVector.hpp> -#include <TNL/Containers/DistributedVectorExpressions.h> diff --git a/src/TNL/Containers/DistributedVectorExpressions.h b/src/TNL/Containers/DistributedVectorExpressions.h deleted file mode 100644 index 0d6d73e670eb2c745d6b4158da8cb8ec1ab165a7..0000000000000000000000000000000000000000 --- a/src/TNL/Containers/DistributedVectorExpressions.h +++ /dev/null @@ -1,936 +0,0 @@ -/*************************************************************************** - DistributedVectorExpressions.h - description - ------------------- - begin : Jul 1, 2019 - copyright : (C) 2019 by Tomas Oberhuber et al. - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#pragma once -#ifndef DOXYGEN_ONLY - -#include <TNL/Containers/Expressions/DistributedExpressionTemplates.h> - -#include "DistributedVector.h" - -namespace TNL { -namespace Containers { - -//// -// Addition -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator+( const DistributedVector< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, ET, Expressions::Addition >( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator+( const ET& a, const DistributedVector< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< ET, std::decay_t<decltype(b)>, Expressions::Addition >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator+( const DistributedVector< Real1, Device, Index, Communicator >& a, const DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Expressions::Addition >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator+( const DistributedVectorView< Real1, Device, Index, Communicator >& a, const DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Expressions::Addition >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator+( const DistributedVector< Real1, Device, Index, Communicator >& a, const DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Expressions::Addition >( a, b ); -} - -//// -// Subtraction -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator-( const DistributedVector< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, ET, Expressions::Subtraction >( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator-( const ET& a, const DistributedVector< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< ET, std::decay_t<decltype(b)>, Expressions::Subtraction >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator-( const DistributedVector< Real1, Device, Index, Communicator >& a, const DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Expressions::Subtraction >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator-( const DistributedVectorView< Real1, Device, Index, Communicator >& a, const DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Expressions::Subtraction >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator-( const DistributedVector< Real1, Device, Index, Communicator >& a, const DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Expressions::Subtraction >( a, b ); -} - -//// -// Multiplication -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator*( const DistributedVector< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, ET, Expressions::Multiplication >( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator*( const ET& a, const DistributedVector< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< ET, std::decay_t<decltype(b)>, Expressions::Multiplication >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator*( const DistributedVector< Real1, Device, Index, Communicator >& a, const DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Expressions::Multiplication >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator*( const DistributedVectorView< Real1, Device, Index, Communicator >& a, const DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Expressions::Multiplication >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator*( const DistributedVector< Real1, Device, Index, Communicator >& a, const DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Expressions::Multiplication >( a, b ); -} - -//// -// Division -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator/( const DistributedVector< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, ET, Expressions::Division >( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator/( const ET& a, const DistributedVector< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< ET, std::decay_t<decltype(b)>, Expressions::Division >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator/( const DistributedVector< Real1, Device, Index, Communicator >& a, const DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Expressions::Division >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator/( const DistributedVectorView< Real1, Device, Index, Communicator >& a, const DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Expressions::Division >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator/( const DistributedVector< Real1, Device, Index, Communicator >& a, const DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Expressions::Division >( a, b ); -} - -//// -// Comparison operations - operator == -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator==( const DistributedVector< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, ET >::EQ( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator==( const ET& a, const DistributedVector< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< ET, std::decay_t<decltype(b)> >::EQ( a, b ); -} - -template< typename Real1, typename Real2, typename Device1, typename Device2, typename Index, typename Communicator > -bool -operator==( const DistributedVector< Real1, Device1, Index, Communicator >& a, const DistributedVector< Real2, Device2, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); -} - -template< typename Real1, typename Real2, typename Device1, typename Device2, typename Index, typename Communicator > -bool -operator==( const DistributedVectorView< Real1, Device1, Index, Communicator >& a, const DistributedVector< Real2, Device2, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); -} - -template< typename Real1, typename Real2, typename Device1, typename Device2, typename Index, typename Communicator > -bool -operator==( const DistributedVector< Real1, Device1, Index, Communicator >& a, const DistributedVectorView< Real2, Device2, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); -} - -//// -// Comparison operations - operator != -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator!=( const DistributedVector< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, ET >::NE( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator!=( const ET& a, const DistributedVector< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< ET, std::decay_t<decltype(b)> >::NE( a, b ); -} - -template< typename Real1, typename Real2, typename Device1, typename Device2, typename Index, typename Communicator > -bool -operator!=( const DistributedVector< Real1, Device1, Index, Communicator >& a, const DistributedVector< Real2, Device2, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); -} - -template< typename Real1, typename Real2, typename Device1, typename Device2, typename Index, typename Communicator > -bool -operator!=( const DistributedVectorView< Real1, Device1, Index, Communicator >& a, const DistributedVector< Real2, Device2, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); -} - -template< typename Real1, typename Real2, typename Device1, typename Device2, typename Index, typename Communicator > -bool -operator!=( const DistributedVector< Real1, Device1, Index, Communicator >& a, const DistributedVectorView< Real2, Device2, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); -} - -//// -// Comparison operations - operator < -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator<( const DistributedVector< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, ET >::LT( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator<( const ET& a, const DistributedVector< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< ET, std::decay_t<decltype(b)> >::LT( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -bool -operator<( const DistributedVector< Real1, Device, Index, Communicator >& a, const DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -bool -operator<( const DistributedVectorView< Real1, Device, Index, Communicator >& a, const DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -bool -operator<( const DistributedVector< Real1, Device, Index, Communicator >& a, const DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); -} - -//// -// Comparison operations - operator <= -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator<=( const DistributedVector< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, ET >::LE( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator<=( const ET& a, const DistributedVector< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< ET, std::decay_t<decltype(b)> >::LE( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -bool -operator<=( const DistributedVector< Real1, Device, Index, Communicator >& a, const DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -bool -operator<=( const DistributedVectorView< Real1, Device, Index, Communicator >& a, const DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -bool -operator<=( const DistributedVector< Real1, Device, Index, Communicator >& a, const DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -//// -// Comparison operations - operator > -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator>( const DistributedVector< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, ET >::GT( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator>( const ET& a, const DistributedVector< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< ET, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -bool -operator>( const DistributedVector< Real1, Device, Index, Communicator >& a, const DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -bool -operator>( const DistributedVectorView< Real1, Device, Index, Communicator >& a, const DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -bool -operator>( const DistributedVector< Real1, Device, Index, Communicator >& a, const DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -//// -// Comparison operations - operator >= -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator>=( const DistributedVector< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, ET >::GE( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator>=( const ET& a, const DistributedVector< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< ET, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -bool -operator>=( const DistributedVector< Real1, Device, Index, Communicator >& a, const DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -bool -operator>=( const DistributedVectorView< Real1, Device, Index, Communicator >& a, const DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -bool -operator>=( const DistributedVector< Real1, Device, Index, Communicator >& a, const DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -//// -// Minus -template< typename Real, typename Device, typename Index, typename Communicator > -auto -operator-( const DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Expressions::Minus >( a ); -} - -//// -// Scalar product -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -Real -operator,( const DistributedVector< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedExpressionSum( a * b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -Real -operator,( const ET& a, const DistributedVector< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedExpressionSum( a * b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator,( const DistributedVector< Real1, Device, Index, Communicator >& a, const DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedExpressionSum( a * b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator,( const DistributedVectorView< Real1, Device, Index, Communicator >& a, const DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedExpressionSum( a * b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator,( const DistributedVector< Real1, Device, Index, Communicator >& a, const DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedExpressionSum( a * b ); -} - -} //namespace Containers - -//// -// All functions are supposed to be in namespace TNL - -//// -// Min -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -min( const Containers::DistributedVector< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, ET, Containers::Expressions::Min >( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -min( const ET& a, const Containers::DistributedVector< Real, Device, Index, Communicator >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< ET, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -min( const Containers::DistributedVector< Real1, Device, Index, Communicator >& a, const Containers::DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -min( const Containers::DistributedVectorView< Real1, Device, Index, Communicator >& a, const Containers::DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -min( const Containers::DistributedVector< Real1, Device, Index, Communicator >& a, const Containers::DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -//// -// Max -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -max( const Containers::DistributedVector< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, ET, Containers::Expressions::Max >( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -max( const ET& a, const Containers::DistributedVector< Real, Device, Index, Communicator >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< ET, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -max( const Containers::DistributedVector< Real1, Device, Index, Communicator >& a, const Containers::DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -max( const Containers::DistributedVectorView< Real1, Device, Index, Communicator >& a, const Containers::DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -max( const Containers::DistributedVector< Real1, Device, Index, Communicator >& a, const Containers::DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -//// -// Dot product - the same as scalar product, just for convenience -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -dot( const Containers::DistributedVector< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return (a, b); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -dot( const ET& a, const Containers::DistributedVector< Real, Device, Index, Communicator >& b ) -{ - return (a, b); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -dot( const Containers::DistributedVector< Real1, Device, Index, Communicator >& a, const Containers::DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return (a, b); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -dot( const Containers::DistributedVectorView< Real1, Device, Index, Communicator >& a, const Containers::DistributedVector< Real2, Device, Index, Communicator >& b ) -{ - return (a, b); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -dot( const Containers::DistributedVector< Real1, Device, Index, Communicator >& a, const Containers::DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return (a, b); -} - - -//// -// Abs -template< typename Real, typename Device, typename Index, typename Communicator > -auto -abs( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Abs >( a ); -} - -//// -// Power -template< typename Real, typename Device, typename Index, typename Communicator, typename ExpType > -auto -pow( const Containers::DistributedVector< Real, Device, Index, Communicator >& a, const ExpType& exp ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, ExpType, Containers::Expressions::Pow >( a, exp ); -} - -//// -// Exp -template< typename Real, typename Device, typename Index, typename Communicator > -auto -exp( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Exp >( a ); -} - -//// -// Sqrt -template< typename Real, typename Device, typename Index, typename Communicator > -auto -sqrt( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sqrt >( a ); -} - -//// -// Cbrt -template< typename Real, typename Device, typename Index, typename Communicator > -auto -cbrt( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cbrt >( a ); -} - -//// -// Log -template< typename Real, typename Device, typename Index, typename Communicator > -auto -log( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log >( a ); -} - -//// -// Log10 -template< typename Real, typename Device, typename Index, typename Communicator > -auto -log10( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log10 >( a ); -} - -//// -// Log2 -template< typename Real, typename Device, typename Index, typename Communicator > -auto -log2( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log2 >( a ); -} - -//// -// Sine -template< typename Real, typename Device, typename Index, typename Communicator > -auto -sin( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sin >( a ); -} - -//// -// Cosine -template< typename Real, typename Device, typename Index, typename Communicator > -auto -cos( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cos >( a ); -} - -//// -// Tangent -template< typename Real, typename Device, typename Index, typename Communicator > -auto -tan( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Tan >( a ); -} - -//// -// Asin -template< typename Real, typename Device, typename Index, typename Communicator > -auto -asin( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Asin >( a ); -} - -//// -// Acos -template< typename Real, typename Device, typename Index, typename Communicator > -auto -acos( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Acos >( a ); -} - -//// -// Atan -template< typename Real, typename Device, typename Index, typename Communicator > -auto -atan( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Atan >( a ); -} - -//// -// Sinh -template< typename Real, typename Device, typename Index, typename Communicator > -auto -sinh( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sinh >( a ); -} - -//// -// Cosh -template< typename Real, typename Device, typename Index, typename Communicator > -auto -cosh( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cosh >( a ); -} - -//// -// Tanh -template< typename Real, typename Device, typename Index, typename Communicator > -auto -tanh( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Tanh >( a ); -} - -//// -// Asinh -template< typename Real, typename Device, typename Index, typename Communicator > -auto -asinh( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Asinh >( a ); -} - -//// -// Acosh -template< typename Real, typename Device, typename Index, typename Communicator > -auto -acosh( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Acosh >( a ); -} - -//// -// Atanh -template< typename Real, typename Device, typename Index, typename Communicator > -auto -atanh( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Atanh >( a ); -} - -//// -// Floor -template< typename Real, typename Device, typename Index, typename Communicator > -auto -floor( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Floor >( a ); -} - -//// -// Ceil -template< typename Real, typename Device, typename Index, typename Communicator > -auto -ceil( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Ceil >( a ); -} - -//// -// Sign -template< typename Real, typename Device, typename Index, typename Communicator > -auto -sign( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sign >( a ); -} - -//// -// Cast -template< typename ResultType, typename Real, typename Device, typename Index, typename Communicator, - // workaround: templated type alias cannot be declared at block level - template<typename> class Operation = Containers::Expressions::Cast< ResultType >::template Operation > -auto -cast( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Operation >( a ); -} - -//// -// Vertical operations - min -template< typename Real, - typename Device, - typename Index, typename Communicator > -Real -min( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionMin( a ); -} - -template< typename Real, - typename Device, - typename Index, typename Communicator > -std::pair< Index, std::decay_t< Real > > -argMin( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionArgMin( a ); -} - -template< typename Real, - typename Device, - typename Index, typename Communicator > -Real -max( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionMax( a ); -} - -template< typename Real, - typename Device, - typename Index, typename Communicator > -std::pair< Index, std::decay_t< Real > > -argMax( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionArgMax( a ); -} - -template< typename Real, - typename Device, - typename Index, typename Communicator > -auto -sum( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionSum( a ); -} - -template< typename Real, - typename Device, - typename Index, typename Communicator > -auto -maxNorm( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return max( abs( a ) ); -} - -template< typename Real, - typename Device, - typename Index, typename Communicator > -auto -l1Norm( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionL1Norm( a ); -} - -template< typename Real, - typename Device, - typename Index, typename Communicator > -auto -l2Norm( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return TNL::sqrt( Containers::Expressions::DistributedExpressionL2Norm( a ) ); -} - -template< typename Real, - typename Device, - typename Index, typename Communicator, - typename Real2 > -auto -lpNorm( const Containers::DistributedVector< Real, Device, Index, Communicator >& a, const Real2& p ) -// since (1.0 / p) has type double, TNL::pow returns double --> double -{ - if( p == 1.0 ) - return l1Norm( a ); - if( p == 2.0 ) - return l2Norm( a ); - return TNL::pow( Containers::Expressions::DistributedExpressionLpNorm( a, p ), 1.0 / p ); -} - -template< typename Real, - typename Device, - typename Index, typename Communicator > -auto -product( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionProduct( a ); -} - -template< typename Real, - typename Device, - typename Index, typename Communicator > -auto -logicalOr( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionLogicalOr( a ); -} - -template< typename Real, - typename Device, - typename Index, typename Communicator > -auto -binaryOr( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionBinaryOr( a ); -} - -template< typename Real, - typename Device, - typename Index, typename Communicator > -auto -logicalAnd( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionLogicalAnd( a ); -} - -template< typename Real, - typename Device, - typename Index, typename Communicator > -auto -binaryAnd( const Containers::DistributedVector< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionBinaryAnd( a ); -} - -} // namespace TNL -#endif // DOXYGEN_ONLY diff --git a/src/TNL/Containers/DistributedVectorView.h b/src/TNL/Containers/DistributedVectorView.h index 70452c50d17b8a08004a3ad162005154eb228ba8..72bc7588120d0527f6d4505a231fe37b33ba2dce 100644 --- a/src/TNL/Containers/DistributedVectorView.h +++ b/src/TNL/Containers/DistributedVectorView.h @@ -13,6 +13,7 @@ #pragma once #include <TNL/Containers/DistributedArrayView.h> +#include <TNL/Containers/Expressions/DistributedExpressionTemplates.h> #include <TNL/Containers/VectorView.h> namespace TNL { @@ -137,8 +138,15 @@ public: void scan( IndexType begin = 0, IndexType end = 0 ); }; +// Enable expression templates for DistributedVector +namespace Expressions { + template< typename Real, typename Device, typename Index, typename Communicator > + struct HasEnabledDistributedExpressionTemplates< DistributedVectorView< Real, Device, Index, Communicator > > + : std::true_type + {}; +} // namespace Expressions + } // namespace Containers } // namespace TNL #include <TNL/Containers/DistributedVectorView.hpp> -#include <TNL/Containers/DistributedVectorViewExpressions.h> diff --git a/src/TNL/Containers/DistributedVectorViewExpressions.h b/src/TNL/Containers/DistributedVectorViewExpressions.h deleted file mode 100644 index 27936df1021412705a0728c38e0ed2b82b73231b..0000000000000000000000000000000000000000 --- a/src/TNL/Containers/DistributedVectorViewExpressions.h +++ /dev/null @@ -1,718 +0,0 @@ -/*************************************************************************** - DistributedVectorViewExpressions.h - description - ------------------- - begin : Jun 28, 2019 - copyright : (C) 2019 by Tomas Oberhuber et al. - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#pragma once -#ifndef DOXYGEN_ONLY - -#include <TNL/Containers/Expressions/DistributedExpressionTemplates.h> -#include <TNL/Exceptions/NotImplementedError.h> - -#include "DistributedVectorView.h" - -namespace TNL { -namespace Containers { - -//// -// Addition -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator+( const DistributedVectorView< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, ET, Expressions::Addition >( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator+( const ET& a, const DistributedVectorView< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< ET, std::decay_t<decltype(b)>, Expressions::Addition >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator+( const DistributedVectorView< Real1, Device, Index, Communicator >& a, const DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Expressions::Addition >( a, b ); -} - -//// -// Subtraction -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator-( const DistributedVectorView< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, ET, Expressions::Subtraction >( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator-( const ET& a, const DistributedVectorView< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< ET, std::decay_t<decltype(b)>, Expressions::Subtraction >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator-( const DistributedVectorView< Real1, Device, Index, Communicator >& a, const DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Expressions::Subtraction >( a, b ); -} - -//// -// Multiplication -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator*( const DistributedVectorView< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, ET, Expressions::Multiplication >( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator*( const ET& a, const DistributedVectorView< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< ET, std::decay_t<decltype(b)>, Expressions::Multiplication >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator*( const DistributedVectorView< Real1, Device, Index, Communicator >& a, const DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Expressions::Multiplication >( a, b ); -} - -//// -// Division -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator/( const DistributedVectorView< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, ET, Expressions::Division >( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator/( const ET& a, const DistributedVectorView< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< ET, std::decay_t<decltype(b)>, Expressions::Division >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator/( const DistributedVectorView< Real1, Device, Index, Communicator >& a, const DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Expressions::Division >( a, b ); -} - -//// -// Comparison operations - operator == -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator==( const DistributedVectorView< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, ET >::EQ( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator==( const ET& a, const DistributedVectorView< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< ET, std::decay_t<decltype(b)> >::EQ( a, b ); -} - -template< typename Real1, typename Real2, typename Device1, typename Device2, typename Index, typename Communicator > -bool -operator==( const DistributedVectorView< Real1, Device1, Index, Communicator >& a, const DistributedVectorView< Real2, Device2, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); -} - -//// -// Comparison operations - operator != -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator!=( const DistributedVectorView< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, ET >::NE( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator!=( const ET& a, const DistributedVectorView< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< ET, std::decay_t<decltype(b)> >::NE( a, b ); -} - -template< typename Real1, typename Real2, typename Device1, typename Device2, typename Index, typename Communicator > -bool -operator!=( const DistributedVectorView< Real1, Device1, Index, Communicator >& a, const DistributedVectorView< Real2, Device2, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); -} - -//// -// Comparison operations - operator < -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator<( const DistributedVectorView< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, ET >::LT( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator<( const ET& a, const DistributedVectorView< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< ET, std::decay_t<decltype(b)> >::LT( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -bool -operator<( const DistributedVectorView< Real1, Device, Index, Communicator >& a, const DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); -} - -//// -// Comparison operations - operator <= -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator<=( const DistributedVectorView< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, ET >::LE( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator<=( const ET& a, const DistributedVectorView< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< ET, std::decay_t<decltype(b)> >::LE( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -bool -operator<=( const DistributedVectorView< Real1, Device, Index, Communicator >& a, const DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -//// -// Comparison operations - operator > -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator>( const DistributedVectorView< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, ET >::GT( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator>( const ET& a, const DistributedVectorView< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< ET, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -bool -operator>( const DistributedVectorView< Real1, Device, Index, Communicator >& a, const DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -//// -// Comparison operations - operator >= -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator>=( const DistributedVectorView< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, ET >::GE( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator>=( const ET& a, const DistributedVectorView< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< ET, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -bool -operator>=( const DistributedVectorView< Real1, Device, Index, Communicator >& a, const DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -//// -// Minus -template< typename Real, typename Device, typename Index, typename Communicator > -auto -operator-( const DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Expressions::Minus >( a ); -} - -//// -// Scalar product -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator,( const DistributedVectorView< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Expressions::DistributedExpressionSum( a * b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator,( const ET& a, const DistributedVectorView< Real, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedExpressionSum( a * b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -operator,( const DistributedVectorView< Real1, Device, Index, Communicator >& a, const DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Expressions::DistributedExpressionSum( a * b ); -} - -} // namespace Containers - -//// -// All functions are supposed to be in namespace TNL - -//// -// Min -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -min( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, ET, Containers::Expressions::Min >( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -min( const ET& a, const Containers::DistributedVectorView< Real, Device, Index, Communicator >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< ET, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -min( const Containers::DistributedVectorView< Real1, Device, Index, Communicator >& a, const Containers::DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -//// -// Max -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -max( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, ET, Containers::Expressions::Max >( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -max( const ET& a, const Containers::DistributedVectorView< Real, Device, Index, Communicator >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< ET, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Communicator > -auto -max( const Containers::DistributedVectorView< Real1, Device, Index, Communicator >& a, const Containers::DistributedVectorView< Real2, Device, Index, Communicator >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -//// -// Dot product - the same as scalar product, just for convenience -template< typename Real, typename Device, typename Index, typename Communicator, typename ET, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -dot( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a, const ET& b ) -{ - return (a, b); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Communicator, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -dot( const ET& a, const Containers::DistributedVectorView< Real, Device, Index, Communicator >& b ) -{ - return (a, b); -} - -template< typename Real1, typename Real2, typename Device, typename Index1, typename Index2, typename Communicator > -auto -dot( const Containers::DistributedVectorView< Real1, Device, Index1, Communicator >& a, const Containers::DistributedVectorView< Real2, Device, Index2, Communicator >& b ) -{ - return (a, b); -} - -//// -// Abs -template< typename Real, typename Device, typename Index, typename Communicator > -auto -abs( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Abs >( a ); -} - - -//// -// Power -template< typename Real, typename Device, typename Index, typename Communicator, typename ExpType > -auto -pow( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a, const ExpType& exp ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< Containers::DistributedVectorView< Real, Device, Index, Communicator >, ExpType, Containers::Expressions::Pow >( a, exp ); -} - -//// -// Exp -template< typename Real, typename Device, typename Index, typename Communicator > -auto -exp( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Exp >( a ); -} - -//// -// Sqrt -template< typename Real, typename Device, typename Index, typename Communicator > -auto -sqrt( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sqrt >( a ); -} - -//// -// Cbrt -template< typename Real, typename Device, typename Index, typename Communicator > -auto -cbrt( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cbrt >( a ); -} - -//// -// Log -template< typename Real, typename Device, typename Index, typename Communicator > -auto -log( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log >( a ); -} - -//// -// Log10 -template< typename Real, typename Device, typename Index, typename Communicator > -auto -log10( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log10 >( a ); -} - -//// -// Log2 -template< typename Real, typename Device, typename Index, typename Communicator > -auto -log2( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log2 >( a ); -} - -//// -// Sine -template< typename Real, typename Device, typename Index, typename Communicator > -auto -sin( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sin >( a ); -} - -//// -// Cosine -template< typename Real, typename Device, typename Index, typename Communicator > -auto -cos( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cos >( a ); -} - -//// -// Tangent -template< typename Real, typename Device, typename Index, typename Communicator > -auto -tan( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Tan >( a ); -} - -//// -// Asin -template< typename Real, typename Device, typename Index, typename Communicator > -auto -asin( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Asin >( a ); -} - -//// -// Acos -template< typename Real, typename Device, typename Index, typename Communicator > -auto -acos( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Acos >( a ); -} - -//// -// Atan -template< typename Real, typename Device, typename Index, typename Communicator > -auto -atan( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Atan >( a ); -} - -//// -// Sinh -template< typename Real, typename Device, typename Index, typename Communicator > -auto -sinh( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sinh >( a ); -} - -//// -// Cosh -template< typename Real, typename Device, typename Index, typename Communicator > -auto -cosh( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cosh >( a ); -} - -//// -// Tanh -template< typename Real, typename Device, typename Index, typename Communicator > -auto -tanh( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Tanh >( a ); -} - -//// -// Asinh -template< typename Real, typename Device, typename Index, typename Communicator > -auto -asinh( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Asinh >( a ); -} - -//// -// Acosh -template< typename Real, typename Device, typename Index, typename Communicator > -auto -acosh( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Acosh >( a ); -} - -//// -// Atanh -template< typename Real, typename Device, typename Index, typename Communicator > -auto -atanh( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Atanh >( a ); -} - -//// -// Floor -template< typename Real, typename Device, typename Index, typename Communicator > -auto -floor( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Floor >( a ); -} - -//// -// Ceil -template< typename Real, typename Device, typename Index, typename Communicator > -auto -ceil( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Ceil >( a ); -} - -//// -// Sign -template< typename Real, typename Device, typename Index, typename Communicator > -auto -sign( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sign >( a ); -} - -//// -// Cast -template< typename ResultType, typename Real, typename Device, typename Index, typename Communicator, - // workaround: templated type alias cannot be declared at block level - template<typename> class Operation = Containers::Expressions::Cast< ResultType >::template Operation > -auto -cast( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Operation >( a ); -} - -//// -// Vertical operations - min -template< typename Real, typename Device, typename Index, typename Communicator > -Real -min( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionMin( a ); -} - -template< typename Real, typename Device, typename Index, typename Communicator > -std::pair< Index, std::decay_t< Real > > -argMin( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionArgMin( a ); -} - -template< typename Real, typename Device, typename Index, typename Communicator > -Real -max( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionMax( a ); -} - -template< typename Real, typename Device, typename Index, typename Communicator > -std::pair< Index, std::decay_t< Real > > -argMax( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionArgMax( a ); -} - -template< typename Real, typename Device, typename Index, typename Communicator > -auto -sum( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionSum( a ); -} - -template< typename Real, - typename Device, - typename Index, typename Communicator > -auto -maxNorm( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return max( abs( a ) ); -} - -template< typename Real, - typename Device, - typename Index, typename Communicator > -auto -l1Norm( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionL1Norm( a ); -} - -template< typename Real, - typename Device, - typename Index, typename Communicator > -auto -l2Norm( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return TNL::sqrt( Containers::Expressions::DistributedExpressionL2Norm( a ) ); -} - -template< typename Real, typename Device, typename Index, typename Communicator, typename Real2 > -auto -lpNorm( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a, const Real2& p ) -// since (1.0 / p) has type double, TNL::pow returns double --> double -{ - if( p == 1.0 ) - return l1Norm( a ); - if( p == 2.0 ) - return l2Norm( a ); - return TNL::pow( Containers::Expressions::DistributedExpressionLpNorm( a, p ), 1.0 / p ); -} - -template< typename Real, typename Device, typename Index, typename Communicator > -auto -product( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionProduct( a ); -} - -template< typename Real, typename Device, typename Index, typename Communicator > -auto -logicalOr( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionLogicalOr( a ); -} - -template< typename Real, typename Device, typename Index, typename Communicator > -auto -binaryOr( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionBinaryOr( a ); -} - -template< typename Real, typename Device, typename Index, typename Communicator > -auto -logicalAnd( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionLogicalAnd( a ); -} - -template< typename Real, typename Device, typename Index, typename Communicator > -auto -binaryAnd( const Containers::DistributedVectorView< Real, Device, Index, Communicator >& a ) -{ - return Containers::Expressions::DistributedExpressionBinaryAnd( a ); -} - -} // namespace TNL -#endif // DOXYGEN_ONLY diff --git a/src/TNL/Containers/Expressions/Comparison.h b/src/TNL/Containers/Expressions/Comparison.h index 98e39ad8c561240f2ac0522844dd362059ebf710..40b823a1840e6b5d5458f18bbf3e2e9341b2403c 100644 --- a/src/TNL/Containers/Expressions/Comparison.h +++ b/src/TNL/Containers/Expressions/Comparison.h @@ -25,13 +25,14 @@ namespace Expressions { // Non-static comparison template< typename T1, typename T2, - ExpressionVariableType T1Type = ExpressionVariableTypeGetter< T1 >::value, - ExpressionVariableType T2Type = ExpressionVariableTypeGetter< T2 >::value > + ExpressionVariableType T1Type = getExpressionVariableType< T1, T2 >(), + ExpressionVariableType T2Type = getExpressionVariableType< T2, T1 >() > struct Comparison; template< typename T1, typename T2, - bool BothAreVectors = IsArrayType< T1 >::value && IsArrayType< T2 >::value > + bool BothAreNonstaticVectors = IsArrayType< T1 >::value && IsArrayType< T2 >::value && + ! IsStaticArrayType< T1 >::value && ! IsStaticArrayType< T2 >::value > struct VectorComparison; // If both operands are vectors we compare them using array operations. @@ -64,7 +65,9 @@ struct VectorComparison< T1, T2, false > using DeviceType = typename T1::DeviceType; using IndexType = typename T1::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a[ i ] == b[ i ]; }; + const auto view_a = a.getConstView(); + const auto view_b = b.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return view_a[ i ] == view_b[ i ]; }; return Algorithms::Reduction< DeviceType >::reduce( a.getSize(), std::logical_and<>{}, fetch, true ); } }; @@ -94,7 +97,9 @@ struct Comparison< T1, T2, VectorExpressionVariable, VectorExpressionVariable > using DeviceType = typename T1::DeviceType; using IndexType = typename T1::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a[ i ] > b[ i ]; }; + const auto view_a = a.getConstView(); + const auto view_b = b.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return view_a[ i ] > view_b[ i ]; }; return Algorithms::Reduction< DeviceType >::reduce( a.getSize(), std::logical_and<>{}, fetch, true ); } @@ -107,7 +112,9 @@ struct Comparison< T1, T2, VectorExpressionVariable, VectorExpressionVariable > using DeviceType = typename T1::DeviceType; using IndexType = typename T1::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a[ i ] >= b[ i ]; }; + const auto view_a = a.getConstView(); + const auto view_b = b.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return view_a[ i ] >= view_b[ i ]; }; return Algorithms::Reduction< DeviceType >::reduce( a.getSize(), std::logical_and<>{}, fetch, true ); } @@ -120,7 +127,9 @@ struct Comparison< T1, T2, VectorExpressionVariable, VectorExpressionVariable > using DeviceType = typename T1::DeviceType; using IndexType = typename T1::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a[ i ] < b[ i ]; }; + const auto view_a = a.getConstView(); + const auto view_b = b.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return view_a[ i ] < view_b[ i ]; }; return Algorithms::Reduction< DeviceType >::reduce( a.getSize(), std::logical_and<>{}, fetch, true ); } @@ -133,7 +142,9 @@ struct Comparison< T1, T2, VectorExpressionVariable, VectorExpressionVariable > using DeviceType = typename T1::DeviceType; using IndexType = typename T1::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a[ i ] <= b[ i ]; }; + const auto view_a = a.getConstView(); + const auto view_b = b.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return view_a[ i ] <= view_b[ i ]; }; return Algorithms::Reduction< DeviceType >::reduce( a.getSize(), std::logical_and<>{}, fetch, true ); } }; @@ -149,7 +160,8 @@ struct Comparison< T1, T2, ArithmeticVariable, VectorExpressionVariable > using DeviceType = typename T2::DeviceType; using IndexType = typename T2::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a == b[ i ]; }; + const auto view_b = b.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a == view_b[ i ]; }; return Algorithms::Reduction< DeviceType >::reduce( b.getSize(), std::logical_and<>{}, fetch, true ); } @@ -163,7 +175,8 @@ struct Comparison< T1, T2, ArithmeticVariable, VectorExpressionVariable > using DeviceType = typename T2::DeviceType; using IndexType = typename T2::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a > b[ i ]; }; + const auto view_b = b.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a > view_b[ i ]; }; return Algorithms::Reduction< DeviceType >::reduce( b.getSize(), std::logical_and<>{}, fetch, true ); } @@ -172,7 +185,8 @@ struct Comparison< T1, T2, ArithmeticVariable, VectorExpressionVariable > using DeviceType = typename T2::DeviceType; using IndexType = typename T2::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a >= b[ i ]; }; + const auto view_b = b.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a >= view_b[ i ]; }; return Algorithms::Reduction< DeviceType >::reduce( b.getSize(), std::logical_and<>{}, fetch, true ); } @@ -181,7 +195,8 @@ struct Comparison< T1, T2, ArithmeticVariable, VectorExpressionVariable > using DeviceType = typename T2::DeviceType; using IndexType = typename T2::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a < b[ i ]; }; + const auto view_b = b.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a < view_b[ i ]; }; return Algorithms::Reduction< DeviceType >::reduce( b.getSize(), std::logical_and<>{}, fetch, true ); } @@ -190,7 +205,8 @@ struct Comparison< T1, T2, ArithmeticVariable, VectorExpressionVariable > using DeviceType = typename T2::DeviceType; using IndexType = typename T2::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a <= b[ i ]; }; + const auto view_b = b.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a <= view_b[ i ]; }; return Algorithms::Reduction< DeviceType >::reduce( b.getSize(), std::logical_and<>{}, fetch, true ); } }; @@ -206,7 +222,8 @@ struct Comparison< T1, T2, VectorExpressionVariable, ArithmeticVariable > using DeviceType = typename T1::DeviceType; using IndexType = typename T1::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a[ i ] == b; }; + const auto view_a = a.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return view_a[ i ] == b; }; return Algorithms::Reduction< DeviceType >::reduce( a.getSize(), std::logical_and<>{}, fetch, true ); } @@ -220,7 +237,8 @@ struct Comparison< T1, T2, VectorExpressionVariable, ArithmeticVariable > using DeviceType = typename T1::DeviceType; using IndexType = typename T1::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a[ i ] > b; }; + const auto view_a = a.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return view_a[ i ] > b; }; return Algorithms::Reduction< DeviceType >::reduce( a.getSize(), std::logical_and<>{}, fetch, true ); } @@ -229,7 +247,8 @@ struct Comparison< T1, T2, VectorExpressionVariable, ArithmeticVariable > using DeviceType = typename T1::DeviceType; using IndexType = typename T1::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a[ i ] >= b; }; + const auto view_a = a.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return view_a[ i ] >= b; }; return Algorithms::Reduction< DeviceType >::reduce( a.getSize(), std::logical_and<>{}, fetch, true ); } @@ -238,7 +257,8 @@ struct Comparison< T1, T2, VectorExpressionVariable, ArithmeticVariable > using DeviceType = typename T1::DeviceType; using IndexType = typename T1::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a[ i ] < b; }; + const auto view_a = a.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return view_a[ i ] < b; }; return Algorithms::Reduction< DeviceType >::reduce( a.getSize(), std::logical_and<>{}, fetch, true ); } @@ -247,7 +267,8 @@ struct Comparison< T1, T2, VectorExpressionVariable, ArithmeticVariable > using DeviceType = typename T1::DeviceType; using IndexType = typename T1::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return a[ i ] <= b; }; + const auto view_a = a.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) -> bool { return view_a[ i ] <= b; }; return Algorithms::Reduction< DeviceType >::reduce( a.getSize(), std::logical_and<>{}, fetch, true ); } }; diff --git a/src/TNL/Containers/Expressions/DistributedComparison.h b/src/TNL/Containers/Expressions/DistributedComparison.h index b5e0e96a9d756f55edb7bf15652ad1d0d34bc5d6..4cecc92bb9b3823db92df893c289c0233d26bb14 100644 --- a/src/TNL/Containers/Expressions/DistributedComparison.h +++ b/src/TNL/Containers/Expressions/DistributedComparison.h @@ -21,8 +21,8 @@ namespace Expressions { // Non-static comparison template< typename T1, typename T2, - ExpressionVariableType T1Type = ExpressionVariableTypeGetter< T1 >::value, - ExpressionVariableType T2Type = ExpressionVariableTypeGetter< T2 >::value > + ExpressionVariableType T1Type = getExpressionVariableType< T1, T2 >(), + ExpressionVariableType T2Type = getExpressionVariableType< T2, T1 >() > struct DistributedComparison; ///// diff --git a/src/TNL/Containers/Expressions/DistributedExpressionTemplates.h b/src/TNL/Containers/Expressions/DistributedExpressionTemplates.h index 355689039884e8e05caff040e232ffbcf26119ba..1802dcc9553e81c7b31c0e792d6d368a4e743c8d 100644 --- a/src/TNL/Containers/Expressions/DistributedExpressionTemplates.h +++ b/src/TNL/Containers/Expressions/DistributedExpressionTemplates.h @@ -22,15 +22,12 @@ namespace Expressions { //// // Distributed unary expression template template< typename T1, - template< typename > class Operation, - ExpressionVariableType T1Type = ExpressionVariableTypeGetter< T1 >::value > -struct DistributedUnaryExpressionTemplate -{}; + typename Operation > +struct DistributedUnaryExpressionTemplate; template< typename T1, - template< typename > class Operation, - ExpressionVariableType T1Type > -struct IsExpressionTemplate< DistributedUnaryExpressionTemplate< T1, Operation, T1Type > > + typename Operation > +struct HasEnabledDistributedExpressionTemplates< DistributedUnaryExpressionTemplate< T1, Operation > > : std::true_type {}; @@ -38,28 +35,27 @@ struct IsExpressionTemplate< DistributedUnaryExpressionTemplate< T1, Operation, // Distributed binary expression template template< typename T1, typename T2, - template< typename, typename > class Operation, - ExpressionVariableType T1Type = ExpressionVariableTypeGetter< T1 >::value, - ExpressionVariableType T2Type = ExpressionVariableTypeGetter< T2 >::value > + typename Operation, + ExpressionVariableType T1Type = getExpressionVariableType< T1, T2 >(), + ExpressionVariableType T2Type = getExpressionVariableType< T2, T1 >() > struct DistributedBinaryExpressionTemplate {}; template< typename T1, typename T2, - template< typename, typename > class Operation, + typename Operation, ExpressionVariableType T1Type, ExpressionVariableType T2Type > -struct IsExpressionTemplate< DistributedBinaryExpressionTemplate< T1, T2, Operation, T1Type, T2Type > > +struct HasEnabledDistributedExpressionTemplates< DistributedBinaryExpressionTemplate< T1, T2, Operation, T1Type, T2Type > > : std::true_type {}; template< typename T1, typename T2, - template< typename, typename > class Operation > + typename Operation > struct DistributedBinaryExpressionTemplate< T1, T2, Operation, VectorExpressionVariable, VectorExpressionVariable > { - using RealType = decltype( Operation< typename T1::RealType, typename T2::RealType >:: - evaluate( std::declval<T1>()[0], std::declval<T2>()[0] ) ); + using RealType = decltype( Operation::evaluate( std::declval<T1>()[0], std::declval<T2>()[0] ) ); using DeviceType = typename T1::DeviceType; using IndexType = typename T1::IndexType; using CommunicatorType = typename T1::CommunicatorType; @@ -69,10 +65,12 @@ struct DistributedBinaryExpressionTemplate< T1, T2, Operation, VectorExpressionV typename T2::ConstLocalViewType, Operation >; + static_assert( HasEnabledDistributedExpressionTemplates< T1 >::value, + "Invalid operand in distributed binary expression templates - distributed expression templates are not enabled for the left operand." ); + static_assert( HasEnabledDistributedExpressionTemplates< T2 >::value, + "Invalid operand in distributed binary expression templates - distributed expression templates are not enabled for the right operand." ); static_assert( std::is_same< typename T1::DeviceType, typename T2::DeviceType >::value, "Attempt to mix operands which have different DeviceType." ); - static_assert( IsStaticArrayType< T1 >::value == IsStaticArrayType< T2 >::value, - "Attempt to mix static and non-static operands in binary expression templates." ); DistributedBinaryExpressionTemplate( const T1& a, const T2& b ) : op1( a ), op2( b ) @@ -124,11 +122,10 @@ protected: template< typename T1, typename T2, - template< typename, typename > class Operation > + typename Operation > struct DistributedBinaryExpressionTemplate< T1, T2, Operation, VectorExpressionVariable, ArithmeticVariable > { - using RealType = decltype( Operation< typename T1::RealType, T2 >:: - evaluate( std::declval<T1>()[0], std::declval<T2>() ) ); + using RealType = decltype( Operation::evaluate( std::declval<T1>()[0], std::declval<T2>() ) ); using DeviceType = typename T1::DeviceType; using IndexType = typename T1::IndexType; using CommunicatorType = typename T1::CommunicatorType; @@ -136,6 +133,9 @@ struct DistributedBinaryExpressionTemplate< T1, T2, Operation, VectorExpressionV using LocalRangeType = typename T1::LocalRangeType; using ConstLocalViewType = BinaryExpressionTemplate< typename T1::ConstLocalViewType, T2, Operation >; + static_assert( HasEnabledDistributedExpressionTemplates< T1 >::value, + "Invalid operand in distributed binary expression templates - distributed expression templates are not enabled for the left operand." ); + DistributedBinaryExpressionTemplate( const T1& a, const T2& b ) : op1( a ), op2( b ) {} @@ -178,11 +178,10 @@ protected: template< typename T1, typename T2, - template< typename, typename > class Operation > + typename Operation > struct DistributedBinaryExpressionTemplate< T1, T2, Operation, ArithmeticVariable, VectorExpressionVariable > { - using RealType = decltype( Operation< T1, typename T2::RealType >:: - evaluate( std::declval<T1>(), std::declval<T2>()[0] ) ); + using RealType = decltype( Operation::evaluate( std::declval<T1>(), std::declval<T2>()[0] ) ); using DeviceType = typename T2::DeviceType; using IndexType = typename T2::IndexType; using CommunicatorType = typename T2::CommunicatorType; @@ -190,6 +189,9 @@ struct DistributedBinaryExpressionTemplate< T1, T2, Operation, ArithmeticVariabl using LocalRangeType = typename T2::LocalRangeType; using ConstLocalViewType = BinaryExpressionTemplate< T1, typename T2::ConstLocalViewType, Operation >; + static_assert( HasEnabledDistributedExpressionTemplates< T2 >::value, + "Invalid operand in distributed binary expression templates - distributed expression templates are not enabled for the right operand." ); + DistributedBinaryExpressionTemplate( const T1& a, const T2& b ) : op1( a ), op2( b ) {} @@ -233,11 +235,10 @@ protected: //// // Distributed unary expression template template< typename T1, - template< typename > class Operation > -struct DistributedUnaryExpressionTemplate< T1, Operation, VectorExpressionVariable > + typename Operation > +struct DistributedUnaryExpressionTemplate { - using RealType = decltype( Operation< typename T1::RealType >:: - evaluate( std::declval<T1>()[0] ) ); + using RealType = decltype( Operation::evaluate( std::declval<T1>()[0] ) ); using DeviceType = typename T1::DeviceType; using IndexType = typename T1::IndexType; using CommunicatorType = typename T1::CommunicatorType; @@ -245,6 +246,9 @@ struct DistributedUnaryExpressionTemplate< T1, Operation, VectorExpressionVariab using LocalRangeType = typename T1::LocalRangeType; using ConstLocalViewType = UnaryExpressionTemplate< typename T1::ConstLocalViewType, Operation >; + static_assert( HasEnabledDistributedExpressionTemplates< T1 >::value, + "Invalid operand in distributed unary expression templates - distributed expression templates are not enabled for the operand." ); + DistributedUnaryExpressionTemplate( const T1& a ) : operand( a ) {} @@ -284,1916 +288,656 @@ protected: const T1& operand; }; -//// -// Output stream -template< typename T1, - typename T2, - template< typename, typename > class Operation > -std::ostream& operator<<( std::ostream& str, const DistributedBinaryExpressionTemplate< T1, T2, Operation >& expression ) -{ - str << "[ "; - for( int i = 0; i < expression.getSize() - 1; i++ ) - str << expression.getElement( i ) << ", "; - str << expression.getElement( expression.getSize() - 1 ) << " ]"; - return str; -} - -template< typename T, - template< typename > class Operation > -std::ostream& operator<<( std::ostream& str, const DistributedUnaryExpressionTemplate< T, Operation >& expression ) -{ - str << "[ "; - for( int i = 0; i < expression.getSize() - 1; i++ ) - str << expression.getElement( i ) << ", "; - str << expression.getElement( expression.getSize() - 1 ) << " ]"; - return str; -} - -//// -// Operators are supposed to be in the same namespace as the expression templates - #ifndef DOXYGEN_ONLY //// // Binary expressions addition -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +template< typename ET1, typename ET2, + typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void > auto -operator+( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) +operator+( const ET1& a, const ET2& b ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return DistributedBinaryExpressionTemplate< ET1, ET2, Addition >( a, b ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Binary expression subtraction +template< typename ET1, typename ET2, + typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void > auto -operator+( const DistributedBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +operator-( const ET1& a, const ET2& b ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return DistributedBinaryExpressionTemplate< ET1, ET2, Subtraction >( a, b ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Binary expression multiplication +template< typename ET1, typename ET2, + typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void > auto -operator+( const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const DistributedBinaryExpressionTemplate< T1, T2, Operation >& b ) +operator*( const ET1& a, const ET2& b ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return DistributedBinaryExpressionTemplate< ET1, ET2, Multiplication >( a, b ); } -template< typename T1, - template< typename > class Operation > +//// +// Binary expression division +template< typename ET1, typename ET2, + typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void > auto -operator+( const DistributedUnaryExpressionTemplate< T1, Operation >& a, - const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& b ) +operator/( const ET1& a, const ET2& b ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return DistributedBinaryExpressionTemplate< ET1, ET2, Division >( a, b ); } -template< typename T1, - template< typename > class Operation > -auto -operator+( const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& a, - const DistributedUnaryExpressionTemplate< T1, Operation >& b ) +//// +// Comparison operator == +template< typename ET1, typename ET2, + typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void > +bool +operator==( const ET1& a, const ET2& b ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return DistributedComparison< ET1, ET2 >::EQ( a, b ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -operator+( const DistributedUnaryExpressionTemplate< L1, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) +//// +// Comparison operator != +template< typename ET1, typename ET2, + typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void > +bool +operator!=( const ET1& a, const ET2& b ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return DistributedComparison< ET1, ET2 >::NE( a, b ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -operator+( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedUnaryExpressionTemplate< R1,ROperation >& b ) +//// +// Comparison operator < +template< typename ET1, typename ET2, + typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void > +bool +operator<( const ET1& a, const ET2& b ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return DistributedComparison< ET1, ET2 >::LT( a, b ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -operator+( const DistributedUnaryExpressionTemplate< L1,LOperation >& a, - const DistributedUnaryExpressionTemplate< R1,ROperation >& b ) +//// +// Comparison operator <= +template< typename ET1, typename ET2, + typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void > +bool +operator<=( const ET1& a, const ET2& b ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return DistributedComparison< ET1, ET2 >::LE( a, b ); } //// -// Binary expression subtraction -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -operator-( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) +// Comparison operator > +template< typename ET1, typename ET2, + typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void > +bool +operator>( const ET1& a, const ET2& b ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return DistributedComparison< ET1, ET2 >::GT( a, b ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > -auto -operator-( const DistributedBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +//// +// Comparison operator >= +template< typename ET1, typename ET2, + typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void > +bool +operator>=( const ET1& a, const ET2& b ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return DistributedComparison< ET1, ET2 >::GE( a, b ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Scalar product +template< typename ET1, typename ET2, + typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void > auto -operator-( const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const DistributedBinaryExpressionTemplate< T1, T2, Operation >& b ) +operator,( const ET1& a, const ET2& b ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return DistributedExpressionSum( a * b ); } -template< typename T1, - template< typename > class Operation > +template< typename ET1, typename ET2, + typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void > auto -operator-( const DistributedUnaryExpressionTemplate< T1, Operation >& a, - const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& b ) +dot( const ET1& a, const ET2& b ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return (a, b); } -template< typename T1, - template< typename > class Operation > +//// +// Unary expression minus +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > auto -operator-( const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& a, - const DistributedUnaryExpressionTemplate< T1, Operation >& b ) +operator-( const ET1& a ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Minus >( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +//// +// Binary expression min +template< typename ET1, typename ET2, + typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void > auto -operator-( const DistributedUnaryExpressionTemplate< L1, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) +min( const ET1& a, const ET2& b ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return DistributedBinaryExpressionTemplate< ET1, ET2, Min >( a, b ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Binary expression max +template< typename ET1, typename ET2, + typename..., typename = EnableIfDistributedBinaryExpression_t< ET1, ET2 >, typename = void, typename = void > auto -operator-( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedUnaryExpressionTemplate< R1,ROperation >& b ) +max( const ET1& a, const ET2& b ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return DistributedBinaryExpressionTemplate< ET1, ET2, Max >( a, b ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Abs +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > auto -operator-( const DistributedUnaryExpressionTemplate< L1,LOperation >& a, - const DistributedUnaryExpressionTemplate< R1,ROperation >& b ) +abs( const ET1& a ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Abs >( a ); } //// -// Binary expression multiplication -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +// Pow +template< typename ET1, typename Real, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > auto -operator*( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) +pow( const ET1& a, const Real& exp ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return DistributedBinaryExpressionTemplate< ET1, Real, Pow >( a, exp ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Exp +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > auto -operator*( const DistributedBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +exp( const ET1& a ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Exp >( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Sqrt +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > auto -operator*( const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const DistributedBinaryExpressionTemplate< T1, T2, Operation >& b ) +sqrt( const ET1& a ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Sqrt >( a ); } -template< typename T1, - template< typename > class Operation > +//// +// Cbrt +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > auto -operator*( const DistributedUnaryExpressionTemplate< T1, Operation >& a, - const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& b ) +cbrt( const ET1& a ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Cbrt >( a ); } -template< typename T1, - template< typename > class Operation > +//// +// Log +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > auto -operator*( const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& a, - const DistributedUnaryExpressionTemplate< T1, Operation >& b ) +log( const ET1& a ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Log >( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +//// +// Log10 +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > auto -operator*( const DistributedUnaryExpressionTemplate< L1, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) +log10( const ET1& a ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Log10 >( a ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Log2 +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > auto -operator*( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedUnaryExpressionTemplate< R1, ROperation >& b ) +log2( const ET1& a ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Log2 >( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Sin +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > auto -operator*( const DistributedUnaryExpressionTemplate< L1,LOperation >& a, - const DistributedUnaryExpressionTemplate< R1,ROperation >& b ) +sin( const ET1& a ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Sin >( a ); } //// -// Binary expression division -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +// Cos +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > auto -operator/( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) +cos( const ET1& a ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Cos >( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Tan +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > auto -operator/( const DistributedBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +tan( const ET1& a ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Tan >( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Asin +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > auto -operator/( const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const DistributedBinaryExpressionTemplate< T1, T2, Operation >& b ) +asin( const ET1& a ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Asin >( a ); } -template< typename T1, - template< typename > class Operation > +//// +// Acos +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > auto -operator/( const DistributedUnaryExpressionTemplate< T1, Operation >& a, - const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& b ) +acos( const ET1& a ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Acos >( a ); } -template< typename T1, - template< typename > class Operation > +//// +// Atan +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > auto -operator/( const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& a, - const DistributedUnaryExpressionTemplate< T1, Operation >& b ) +atan( const ET1& a ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Atan >( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +//// +// Sinh +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > auto -operator/( const DistributedUnaryExpressionTemplate< L1, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) +sinh( const ET1& a ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Sinh >( a ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Cosh +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > auto -operator/( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedUnaryExpressionTemplate< R1,ROperation >& b ) +cosh( const ET1& a ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Cosh >( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Tanh +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > auto -operator/( const DistributedUnaryExpressionTemplate< L1,LOperation >& a, - const DistributedUnaryExpressionTemplate< R1,ROperation >& b ) +tanh( const ET1& a ) { - return DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Tanh >( a ); } //// -// Comparison operator == -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator==( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator==( const DistributedBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); -} - -template< typename T1, - template< typename > class Operation > -bool -operator==( const DistributedUnaryExpressionTemplate< T1, Operation >& a, - const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& b ) +// Asinh +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +asinh( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Asinh >( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator==( const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const DistributedBinaryExpressionTemplate< T1, T2, Operation >& b ) +//// +// Acosh +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +acosh( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Acosh >( a ); } -template< typename T1, - template< typename > class Operation > -bool -operator==( const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& a, - const DistributedUnaryExpressionTemplate< T1, Operation >& b ) +//// +// Atanh +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +atanh( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Atanh >( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator==( const DistributedUnaryExpressionTemplate< L1, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) +//// +// Floor +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +floor( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Floor >( a ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -bool -operator==( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedUnaryExpressionTemplate< R1,ROperation >& b ) +//// +// Ceil +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +ceil( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Ceil >( a ); } //// -// Comparison operator != -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator!=( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) +// Sign +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +sign( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return DistributedUnaryExpressionTemplate< ET1, Sign >( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator!=( const DistributedBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +//// +// Cast +template< typename ResultType, + typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, + // workaround: templated type alias cannot be declared at block level + typename CastOperation = typename Cast< ResultType >::Operation, + typename = void, typename = void > +auto +cast( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return DistributedUnaryExpressionTemplate< ET1, CastOperation >( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -bool -operator!=( const DistributedUnaryExpressionTemplate< L1, LOperation >& a, - const DistributedUnaryExpressionTemplate< R1, ROperation >& b ) +//// +// Vertical operations +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +min( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return DistributedExpressionMin( a ); } -template< typename T1, - template< typename > class Operation > -bool -operator!=( const DistributedUnaryExpressionTemplate< T1, Operation >& a, - const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& b ) +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +argMin( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return DistributedExpressionArgMin( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator!=( const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const DistributedBinaryExpressionTemplate< T1, T2, Operation >& b ) +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +max( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return DistributedExpressionMax( a ); } -template< typename T1, - template< typename > class Operation > -bool -operator!=( const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& a, - const DistributedUnaryExpressionTemplate< T1, Operation >& b ) +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +argMax( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return DistributedExpressionArgMax( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator!=( const DistributedUnaryExpressionTemplate< L1, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +sum( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return DistributedExpressionSum( a ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -bool -operator!=( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedUnaryExpressionTemplate< R1,ROperation >& b ) +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +maxNorm( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return max( abs( a ) ); } -//// -// Comparison operator < -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator<( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +l1Norm( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + return sum( abs( a ) ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator<( const DistributedBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +l2Norm( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + using TNL::sqrt; + return sqrt( sum( a * a ) ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -bool -operator<( const DistributedUnaryExpressionTemplate< L1, LOperation >& a, - const DistributedUnaryExpressionTemplate< R1, ROperation >& b ) +template< typename ET1, + typename Real, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +lpNorm( const ET1& a, const Real& p ) +// since (1.0 / p) has type double, TNL::pow returns double +-> double { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + if( p == 1.0 ) + return l1Norm( a ); + if( p == 2.0 ) + return l2Norm( a ); + using TNL::pow; + return pow( sum( pow( abs( a ), p ) ), 1.0 / p ); } -template< typename T1, - template< typename > class Operation > -bool -operator<( const DistributedUnaryExpressionTemplate< T1, Operation >& a, - const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& b ) +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +product( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + return DistributedExpressionProduct( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator<( const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const DistributedBinaryExpressionTemplate< T1, T2, Operation >& b ) +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +logicalOr( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + return DistributedExpressionLogicalOr( a ); } -template< typename T1, - template< typename > class Operation > -bool -operator<( const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& a, - const DistributedUnaryExpressionTemplate< T1, Operation >& b ) +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +logicalAnd( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + return DistributedExpressionLogicalAnd( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator<( const DistributedUnaryExpressionTemplate< L1, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +binaryOr( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + return DistributedExpressionBinaryOr( a ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -bool -operator<( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedUnaryExpressionTemplate< R1,ROperation >& b ) +template< typename ET1, + typename..., typename = EnableIfDistributedUnaryExpression_t< ET1 >, typename = void, typename = void > +auto +binaryAnd( const ET1& a ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + return DistributedExpressionBinaryAnd( a ); } //// -// Comparison operator <= -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator<=( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - +// Output stream template< typename T1, typename T2, - template< typename, typename > class Operation > -bool -operator<=( const DistributedBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) + typename Operation > +std::ostream& operator<<( std::ostream& str, const DistributedBinaryExpressionTemplate< T1, T2, Operation >& expression ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); + str << "[ "; + for( int i = 0; i < expression.getSize() - 1; i++ ) + str << expression.getElement( i ) << ", "; + str << expression.getElement( expression.getSize() - 1 ) << " ]"; + return str; } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -bool -operator<=( const DistributedUnaryExpressionTemplate< L1, LOperation >& a, - const DistributedUnaryExpressionTemplate< R1, ROperation >& b ) +template< typename T, + typename Operation > +std::ostream& operator<<( std::ostream& str, const DistributedUnaryExpressionTemplate< T, Operation >& expression ) { - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -template< typename T1, - template< typename > class Operation > -bool -operator<=( const DistributedUnaryExpressionTemplate< T1, Operation >& a, - const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator<=( const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const DistributedBinaryExpressionTemplate< T1, T2, Operation >& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -template< typename T1, - template< typename > class Operation > -bool -operator<=( const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& a, - const DistributedUnaryExpressionTemplate< T1, Operation >& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator<=( const DistributedUnaryExpressionTemplate< L1, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -bool -operator<=( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedUnaryExpressionTemplate< R1,ROperation >& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -//// -// Comparison operator > -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator>( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator>( const DistributedBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename T1, - template< typename > class Operation > -bool -operator>( const DistributedUnaryExpressionTemplate< T1, Operation >& a, - const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator>( const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const DistributedBinaryExpressionTemplate< T1, T2, Operation >& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename T1, - template< typename > class Operation > -bool -operator>( const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& a, - const DistributedUnaryExpressionTemplate< T1, Operation >& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator>( const DistributedUnaryExpressionTemplate< L1, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -bool -operator>( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedUnaryExpressionTemplate< R1,ROperation >& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -//// -// Comparison operator >= -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator>=( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator>=( const DistributedBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename T1, - template< typename > class Operation > -bool -operator>=( const DistributedUnaryExpressionTemplate< T1, Operation >& a, - const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator>=( const typename DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const DistributedBinaryExpressionTemplate< T1, T2, Operation >& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename T1, - template< typename > class Operation > -bool -operator>=( const typename DistributedUnaryExpressionTemplate< T1, Operation >::RealType& a, - const DistributedUnaryExpressionTemplate< T1, Operation >& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator>=( const DistributedUnaryExpressionTemplate< L1, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -bool -operator>=( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedUnaryExpressionTemplate< R1,ROperation >& b ) -{ - return DistributedComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -//// -// Unary operations - -//// -// Minus -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -operator-( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Minus >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -operator-( const DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Minus >( a ); -} - -//// -// Scalar product -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -operator,( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return DistributedExpressionSum( a * b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -operator,( const DistributedUnaryExpressionTemplate< L1, LOperation >& a, - const DistributedUnaryExpressionTemplate< R1, ROperation >& b ) -{ - return DistributedExpressionSum( a * b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -operator,( const DistributedUnaryExpressionTemplate< L1, LOperation >& a, - const DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return DistributedExpressionSum( a * b ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -operator,( const DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const DistributedUnaryExpressionTemplate< R1,ROperation >& b ) -{ - return DistributedExpressionSum( a * b ); + str << "[ "; + for( int i = 0; i < expression.getSize() - 1; i++ ) + str << expression.getElement( i ) << ", "; + str << expression.getElement( expression.getSize() - 1 ) << " ]"; + return str; } #endif // DOXYGEN_ONLY } // namespace Expressions -} // namespace Containers - -//// -// All operations are supposed to be in namespace TNL - -#ifndef DOXYGEN_ONLY - -//// -// Binary expression min -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -min( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const Containers::Expressions::DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -auto -min( const Containers::Expressions::DistributedBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename Containers::Expressions::DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -auto -min( const typename Containers::Expressions::DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const Containers::Expressions::DistributedBinaryExpressionTemplate< T1, T2, Operation >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename T1, - template< typename > class Operation > -auto -min( const Containers::Expressions::DistributedUnaryExpressionTemplate< T1, Operation >& a, - const typename Containers::Expressions::DistributedUnaryExpressionTemplate< T1, Operation >::RealType& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename T1, - template< typename > class Operation > -auto -min( const typename Containers::Expressions::DistributedUnaryExpressionTemplate< T1, Operation >::RealType& a, - const Containers::Expressions::DistributedUnaryExpressionTemplate< T1, Operation >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -min( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a, - const typename Containers::Expressions::DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -min( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const Containers::Expressions::DistributedUnaryExpressionTemplate< R1,ROperation >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -min( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1,LOperation >& a, - const Containers::Expressions::DistributedUnaryExpressionTemplate< R1,ROperation >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -//// -// Binary expression max -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -max( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const Containers::Expressions::DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -auto -max( const Containers::Expressions::DistributedBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename Containers::Expressions::DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -auto -max( const typename Containers::Expressions::DistributedBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const Containers::Expressions::DistributedBinaryExpressionTemplate< T1, T2, Operation >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename T1, - template< typename > class Operation > -auto -max( const Containers::Expressions::DistributedUnaryExpressionTemplate< T1, Operation >& a, - const typename Containers::Expressions::DistributedUnaryExpressionTemplate< T1, Operation >::RealType& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename T1, - template< typename > class Operation > -auto -max( const typename Containers::Expressions::DistributedUnaryExpressionTemplate< T1, Operation >::RealType& a, - const Containers::Expressions::DistributedUnaryExpressionTemplate< T1, Operation >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -max( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a, - const Containers::Expressions::DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -max( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const Containers::Expressions::DistributedUnaryExpressionTemplate< R1,ROperation >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -max( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1,LOperation >& a, - const Containers::Expressions::DistributedUnaryExpressionTemplate< R1,ROperation >& b ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -//// -// Abs -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -abs( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Abs >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -abs( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Abs >( a ); -} - -//// -// Pow -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename Real > -auto -pow( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, const Real& exp ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, Real, Containers::Expressions::Pow >( a, exp ); -} - -template< typename L1, - template< typename > class LOperation, - typename Real > -auto -pow( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a, const Real& exp ) -{ - return Containers::Expressions::DistributedBinaryExpressionTemplate< std::decay_t<decltype(a)>, Real, Containers::Expressions::Pow >( a, exp ); -} - -//// -// Exp -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -exp( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Exp >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -exp( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Exp >( a ); -} - -//// -// Sqrt -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -sqrt( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sqrt >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -sqrt( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sqrt >( a ); -} -//// -// Cbrt -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -cbrt( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cbrt >( a ); -} +// Make all operators visible in the TNL::Containers namespace to be considered +// even for DistributedVector and DistributedVectorView +using Expressions::operator+; +using Expressions::operator-; +using Expressions::operator*; +using Expressions::operator/; +using Expressions::operator,; +using Expressions::operator==; +using Expressions::operator!=; +using Expressions::operator<; +using Expressions::operator<=; +using Expressions::operator>; +using Expressions::operator>=; + +// Make all functions visible in the TNL::Containers namespace +using Expressions::dot; +using Expressions::min; +using Expressions::max; +using Expressions::abs; +using Expressions::pow; +using Expressions::exp; +using Expressions::sqrt; +using Expressions::cbrt; +using Expressions::log; +using Expressions::log10; +using Expressions::log2; +using Expressions::sin; +using Expressions::cos; +using Expressions::tan; +using Expressions::asin; +using Expressions::acos; +using Expressions::atan; +using Expressions::sinh; +using Expressions::cosh; +using Expressions::tanh; +using Expressions::asinh; +using Expressions::acosh; +using Expressions::atanh; +using Expressions::floor; +using Expressions::ceil; +using Expressions::sign; +using Expressions::cast; +using Expressions::argMin; +using Expressions::argMax; +using Expressions::sum; +using Expressions::maxNorm; +using Expressions::l1Norm; +using Expressions::l2Norm; +using Expressions::lpNorm; +using Expressions::product; +using Expressions::logicalAnd; +using Expressions::logicalOr; +using Expressions::binaryAnd; +using Expressions::binaryOr; -template< typename L1, - template< typename > class LOperation > -auto -cbrt( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cbrt >( a ); -} - -//// -// Log -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -log( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -log( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log >( a ); -} - -//// -// Log10 -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -log10( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log10 >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -log10( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log10 >( a ); -} - -//// -// Log2 -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -log2( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log2 >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -log2( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log2 >( a ); -} - -//// -// Sin -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -sin( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sin >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -sin( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sin >( a ); -} - -//// -// Cos -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -cos( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cos >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -cos( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cos >( a ); -} - -//// -// Tan -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -tan( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Tan >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -tan( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Tan >( a ); -} - -//// -// Asin -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -asin( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Asin >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -asin( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Asin >( a ); -} - -//// -// Acos -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -acos( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Acos >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -acos( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Acos >( a ); -} - -//// -// Atan -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -atan( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Atan >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -atan( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Atan >( a ); -} - -//// -// Sinh -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -sinh( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sinh >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -sinh( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sinh >( a ); -} - -//// -// Cosh -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -cosh( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cosh >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -cosh( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cosh >( a ); -} - -//// -// Tanh -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -tanh( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Tanh >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -tanh( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Tanh >( a ); -} - -//// -// Asinh -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -asinh( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Asinh >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -asinh( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Asinh >( a ); -} - -//// -// Acosh -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -acosh( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Acosh >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -acosh( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Acosh >( a ); -} - -//// -// Atanh -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -atanh( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Atanh >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -atanh( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Atanh >( a ); -} - -//// -// Floor -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -floor( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Floor >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -floor( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Floor >( a ); -} - -//// -// Ceil -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -ceil( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Ceil >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -ceil( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Ceil >( a ); -} - -//// -// Sign -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -sign( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sign >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -sign( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sign >( a ); -} - -//// -// Cast -template< typename ResultType, - typename L1, - typename L2, - template< typename, typename > class LOperation, - // workaround: templated type alias cannot be declared at block level - template<typename> class CastOperation = Containers::Expressions::Cast< ResultType >::template Operation > -auto -cast( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, CastOperation >( a ); -} - -template< typename ResultType, - typename L1, - template< typename > class LOperation, - // workaround: templated type alias cannot be declared at block level - template<typename> class CastOperation = Containers::Expressions::Cast< ResultType >::template Operation > -auto -cast( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::DistributedUnaryExpressionTemplate< std::decay_t<decltype(a)>, CastOperation >( a ); -} - -//// -// Vertical operations - min -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -min( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return DistributedExpressionMin( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -min( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return DistributedExpressionMin( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -argMin( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return DistributedExpressionArgMin( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -argMin( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return DistributedExpressionArgMin( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -max( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return DistributedExpressionMax( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -max( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return DistributedExpressionMax( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -argMax( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return DistributedExpressionArgMax( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -argMax( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return DistributedExpressionArgMax( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -sum( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return DistributedExpressionSum( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -sum( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return DistributedExpressionSum( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -maxNorm( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return max( abs( a ) ); -} - -template< typename L1, - template< typename > class LOperation > -auto -maxNorm( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return max( abs( a ) ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -l1Norm( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return DistributedExpressionL1Norm( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -l1Norm( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return DistributedExpressionL1Norm( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -l2Norm( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return TNL::sqrt( DistributedExpressionL2Norm( a ) ); -} - -template< typename L1, - template< typename > class LOperation > -auto -l2Norm( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return TNL::sqrt( DistributedExpressionL2Norm( a ) ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename Real > -auto -lpNorm( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, const Real& p ) -// since (1.0 / p) has type double, TNL::pow returns double --> double -{ - if( p == 1.0 ) - return l1Norm( a ); - if( p == 2.0 ) - return l2Norm( a ); - return TNL::pow( DistributedExpressionLpNorm( a, p ), 1.0 / p ); -} - -template< typename L1, - template< typename > class LOperation, - typename Real > -auto -lpNorm( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a, const Real& p ) -// since (1.0 / p) has type double, TNL::pow returns double --> double -{ - if( p == 1.0 ) - return l1Norm( a ); - if( p == 2.0 ) - return l2Norm( a ); - return TNL::pow( DistributedExpressionLpNorm( a, p ), 1.0 / p ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -product( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return DistributedExpressionProduct( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -product( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return DistributedExpressionProduct( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -logicalOr( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return DistributedExpressionLogicalOr( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -logicalOr( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return DistributedExpressionLogicalOr( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -logicalAnd( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return DistributedExpressionLogicalAnd( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -logicalAnd( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return DistributedExpressionLogicalAnd( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -binaryOr( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return DistributedExpressionBinaryOr( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -binaryOr( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return DistributedExpressionBinaryOr( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -binaryAnd( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return DistributedExpressionBinaryAnd( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -binaryAnd( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return DistributedExpressionBinaryAnd( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -dot( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const Containers::Expressions::DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return (a, b); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -dot( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a, - const Containers::Expressions::DistributedUnaryExpressionTemplate< R1, ROperation >& b ) -{ - return (a, b); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -dot( const Containers::Expressions::DistributedUnaryExpressionTemplate< L1, LOperation >& a, - const Containers::Expressions::DistributedBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return (a, b); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -dot( const Containers::Expressions::DistributedBinaryExpressionTemplate< L1, L2, LOperation >& a, - const Containers::Expressions::DistributedUnaryExpressionTemplate< R1, ROperation >& b ) -{ - return (a, b); -} - -#endif // DOXYGEN_ONLY +} // namespace Containers +// Make all functions visible in the main TNL namespace +using Containers::dot; +using Containers::min; +using Containers::max; +using Containers::abs; +using Containers::pow; +using Containers::exp; +using Containers::sqrt; +using Containers::cbrt; +using Containers::log; +using Containers::log10; +using Containers::log2; +using Containers::sin; +using Containers::cos; +using Containers::tan; +using Containers::asin; +using Containers::acos; +using Containers::atan; +using Containers::sinh; +using Containers::cosh; +using Containers::tanh; +using Containers::asinh; +using Containers::acosh; +using Containers::atanh; +using Containers::floor; +using Containers::ceil; +using Containers::sign; +using Containers::cast; +using Containers::argMin; +using Containers::argMax; +using Containers::sum; +using Containers::maxNorm; +using Containers::l1Norm; +using Containers::l2Norm; +using Containers::lpNorm; +using Containers::product; +using Containers::logicalAnd; +using Containers::logicalOr; +using Containers::binaryAnd; +using Containers::binaryOr; //// // Evaluation with reduction template< typename Vector, typename T1, typename T2, - template< typename, typename > class Operation, + typename Operation, typename Reduction, typename Result > Result evaluateAndReduce( Vector& lhs, @@ -2212,7 +956,7 @@ Result evaluateAndReduce( Vector& lhs, template< typename Vector, typename T1, - template< typename > class Operation, + typename Operation, typename Reduction, typename Result > Result evaluateAndReduce( Vector& lhs, @@ -2234,7 +978,7 @@ Result evaluateAndReduce( Vector& lhs, template< typename Vector, typename T1, typename T2, - template< typename, typename > class Operation, + typename Operation, typename Reduction, typename Result > Result addAndReduce( Vector& lhs, @@ -2257,7 +1001,7 @@ Result addAndReduce( Vector& lhs, template< typename Vector, typename T1, - template< typename > class Operation, + typename Operation, typename Reduction, typename Result > Result addAndReduce( Vector& lhs, @@ -2283,7 +1027,7 @@ Result addAndReduce( Vector& lhs, template< typename Vector, typename T1, typename T2, - template< typename, typename > class Operation, + typename Operation, typename Reduction, typename Result > Result addAndReduceAbs( Vector& lhs, @@ -2306,7 +1050,7 @@ Result addAndReduceAbs( Vector& lhs, template< typename Vector, typename T1, - template< typename > class Operation, + typename Operation, typename Reduction, typename Result > Result addAndReduceAbs( Vector& lhs, diff --git a/src/TNL/Containers/Expressions/DistributedVerticalOperations.h b/src/TNL/Containers/Expressions/DistributedVerticalOperations.h index 43940417bb0aa7fa97afe17e4fee3e4ce703a819..178a5c03c50a36ff9c62e35e38a4a0aa68860532 100644 --- a/src/TNL/Containers/Expressions/DistributedVerticalOperations.h +++ b/src/TNL/Containers/Expressions/DistributedVerticalOperations.h @@ -148,51 +148,6 @@ auto DistributedExpressionSum( const Expression& expression ) -> std::decay_t< d return result; } -template< typename Expression > -auto DistributedExpressionL1Norm( const Expression& expression ) -> std::decay_t< decltype( expression[0] ) > -{ - using ResultType = std::decay_t< decltype( expression[0] ) >; - using IndexType = typename Expression::IndexType; - using CommunicatorType = typename Expression::CommunicatorType; - - ResultType result = 0; - if( expression.getCommunicationGroup() != CommunicatorType::NullGroup ) { - const ResultType localResult = ExpressionL1Norm( expression.getConstLocalView() ); - CommunicatorType::Allreduce( &localResult, &result, 1, MPI_SUM, expression.getCommunicationGroup() ); - } - return result; -} - -template< typename Expression > -auto DistributedExpressionL2Norm( const Expression& expression ) -> std::decay_t< decltype( expression[0] * expression[0] ) > -{ - using ResultType = std::decay_t< decltype( expression[0] * expression[0] ) >; - using IndexType = typename Expression::IndexType; - using CommunicatorType = typename Expression::CommunicatorType; - - ResultType result = 0; - if( expression.getCommunicationGroup() != CommunicatorType::NullGroup ) { - const ResultType localResult = ExpressionL2Norm( expression.getConstLocalView() ); - CommunicatorType::Allreduce( &localResult, &result, 1, MPI_SUM, expression.getCommunicationGroup() ); - } - return result; -} - -template< typename Expression, typename Real > -auto DistributedExpressionLpNorm( const Expression& expression, const Real& p ) -> std::decay_t< decltype( TNL::pow( expression[0], p ) ) > -{ - using ResultType = std::decay_t< decltype( TNL::pow( expression[0], p ) ) >; - using IndexType = typename Expression::IndexType; - using CommunicatorType = typename Expression::CommunicatorType; - - ResultType result = 0; - if( expression.getCommunicationGroup() != CommunicatorType::NullGroup ) { - const ResultType localResult = ExpressionLpNorm( expression.getConstLocalView(), p ); - CommunicatorType::Allreduce( &localResult, &result, 1, MPI_SUM, expression.getCommunicationGroup() ); - } - return result; -} - template< typename Expression > auto DistributedExpressionProduct( const Expression& expression ) -> std::decay_t< decltype( expression[0] * expression[0] ) > { diff --git a/src/TNL/Containers/Expressions/ExpressionTemplates.h b/src/TNL/Containers/Expressions/ExpressionTemplates.h index a0980baf6cf8ee751444df7d27205dfa9260f593..eb9684cafe77f659456e2b930c0ff13daab4f429 100644 --- a/src/TNL/Containers/Expressions/ExpressionTemplates.h +++ b/src/TNL/Containers/Expressions/ExpressionTemplates.h @@ -24,57 +24,54 @@ namespace TNL { namespace Containers { namespace Expressions { -//// -// Non-static unary expression template template< typename T1, - template< typename > class Operation, - ExpressionVariableType T1Type = ExpressionVariableTypeGetter< T1 >::value > -struct UnaryExpressionTemplate -{}; + typename Operation > +struct UnaryExpressionTemplate; template< typename T1, - template< typename > class Operation, - ExpressionVariableType T1Type > -struct IsExpressionTemplate< UnaryExpressionTemplate< T1, Operation, T1Type > > + typename Operation > +struct HasEnabledExpressionTemplates< UnaryExpressionTemplate< T1, Operation > > : std::true_type {}; -//// -// Non-static binary expression template template< typename T1, typename T2, - template< typename, typename > class Operation, - ExpressionVariableType T1Type = ExpressionVariableTypeGetter< T1 >::value, - ExpressionVariableType T2Type = ExpressionVariableTypeGetter< T2 >::value > -struct BinaryExpressionTemplate -{}; + typename Operation, + ExpressionVariableType T1Type = getExpressionVariableType< T1, T2 >(), + ExpressionVariableType T2Type = getExpressionVariableType< T2, T1 >() > +struct BinaryExpressionTemplate; template< typename T1, typename T2, - template< typename, typename > class Operation, + typename Operation, ExpressionVariableType T1Type, ExpressionVariableType T2Type > -struct IsExpressionTemplate< BinaryExpressionTemplate< T1, T2, Operation, T1Type, T2Type > > +struct HasEnabledExpressionTemplates< BinaryExpressionTemplate< T1, T2, Operation, T1Type, T2Type > > : std::true_type {}; + +//// +// Non-static binary expression template template< typename T1, typename T2, - template< typename, typename > class Operation > + typename Operation > struct BinaryExpressionTemplate< T1, T2, Operation, VectorExpressionVariable, VectorExpressionVariable > { - using RealType = decltype( Operation< typename T1::RealType, typename T2::RealType >:: - evaluate( std::declval<T1>()[0], std::declval<T2>()[0] ) ); + using RealType = decltype( Operation::evaluate( std::declval<T1>()[0], std::declval<T2>()[0] ) ); using DeviceType = typename T1::DeviceType; using IndexType = typename T1::IndexType; + using ConstViewType = BinaryExpressionTemplate; + static_assert( HasEnabledExpressionTemplates< T1 >::value, + "Invalid operand in binary expression templates - expression templates are not enabled for the left operand." ); + static_assert( HasEnabledExpressionTemplates< T2 >::value, + "Invalid operand in binary expression templates - expression templates are not enabled for the right operand." ); static_assert( std::is_same< typename T1::DeviceType, typename T2::DeviceType >::value, "Attempt to mix operands which have different DeviceType." ); - static_assert( IsStaticArrayType< T1 >::value == IsStaticArrayType< T2 >::value, - "Attempt to mix static and non-static operands in binary expression templates." ); BinaryExpressionTemplate( const T1& a, const T2& b ) - : op1( a ), op2( b ) + : op1( a.getConstView() ), op2( b.getConstView() ) { TNL_ASSERT_EQ( op1.getSize(), op2.getSize(), "Attempt to mix operands with different sizes." ); @@ -82,13 +79,13 @@ struct BinaryExpressionTemplate< T1, T2, Operation, VectorExpressionVariable, Ve RealType getElement( const IndexType i ) const { - return Operation< typename T1::RealType, typename T2::RealType >::evaluate( op1.getElement( i ), op2.getElement( i ) ); + return Operation::evaluate( op1.getElement( i ), op2.getElement( i ) ); } __cuda_callable__ RealType operator[]( const IndexType i ) const { - return Operation< typename T1::RealType, typename T2::RealType >::evaluate( op1[ i ], op2[ i ] ); + return Operation::evaluate( op1[ i ], op2[ i ] ); } __cuda_callable__ @@ -97,33 +94,41 @@ struct BinaryExpressionTemplate< T1, T2, Operation, VectorExpressionVariable, Ve return op1.getSize(); } + ConstViewType getConstView() const + { + return *this; + } + protected: - const T1 op1; - const T2 op2; + const typename T1::ConstViewType op1; + const typename T2::ConstViewType op2; }; template< typename T1, typename T2, - template< typename, typename > class Operation > + typename Operation > struct BinaryExpressionTemplate< T1, T2, Operation, VectorExpressionVariable, ArithmeticVariable > { - using RealType = decltype( Operation< typename T1::RealType, T2 >:: - evaluate( std::declval<T1>()[0], std::declval<T2>() ) ); + using RealType = decltype( Operation::evaluate( std::declval<T1>()[0], std::declval<T2>() ) ); using DeviceType = typename T1::DeviceType; using IndexType = typename T1::IndexType; + using ConstViewType = BinaryExpressionTemplate; + + static_assert( HasEnabledExpressionTemplates< T1 >::value, + "Invalid operand in binary expression templates - expression templates are not enabled for the left operand." ); BinaryExpressionTemplate( const T1& a, const T2& b ) - : op1( a ), op2( b ) {} + : op1( a.getConstView() ), op2( b ) {} RealType getElement( const IndexType i ) const { - return Operation< typename T1::RealType, T2 >::evaluate( op1.getElement( i ), op2 ); + return Operation::evaluate( op1.getElement( i ), op2 ); } __cuda_callable__ RealType operator[]( const IndexType i ) const { - return Operation< typename T1::RealType, T2 >::evaluate( op1[ i ], op2 ); + return Operation::evaluate( op1[ i ], op2 ); } __cuda_callable__ @@ -132,33 +137,41 @@ struct BinaryExpressionTemplate< T1, T2, Operation, VectorExpressionVariable, Ar return op1.getSize(); } + ConstViewType getConstView() const + { + return *this; + } + protected: - const T1 op1; + const typename T1::ConstViewType op1; const T2 op2; }; template< typename T1, typename T2, - template< typename, typename > class Operation > + typename Operation > struct BinaryExpressionTemplate< T1, T2, Operation, ArithmeticVariable, VectorExpressionVariable > { - using RealType = decltype( Operation< T1, typename T2::RealType >:: - evaluate( std::declval<T1>(), std::declval<T2>()[0] ) ); + using RealType = decltype( Operation::evaluate( std::declval<T1>(), std::declval<T2>()[0] ) ); using DeviceType = typename T2::DeviceType; using IndexType = typename T2::IndexType; + using ConstViewType = BinaryExpressionTemplate; + + static_assert( HasEnabledExpressionTemplates< T2 >::value, + "Invalid operand in binary expression templates - expression templates are not enabled for the right operand." ); BinaryExpressionTemplate( const T1& a, const T2& b ) - : op1( a ), op2( b ) {} + : op1( a ), op2( b.getConstView() ) {} RealType getElement( const IndexType i ) const { - return Operation< T1, typename T2::RealType >::evaluate( op1, op2.getElement( i ) ); + return Operation::evaluate( op1, op2.getElement( i ) ); } __cuda_callable__ RealType operator[]( const IndexType i ) const { - return Operation< T1, typename T2::RealType >::evaluate( op1, op2[ i ] ); + return Operation::evaluate( op1, op2[ i ] ); } __cuda_callable__ @@ -167,34 +180,42 @@ struct BinaryExpressionTemplate< T1, T2, Operation, ArithmeticVariable, VectorEx return op2.getSize(); } + ConstViewType getConstView() const + { + return *this; + } + protected: const T1 op1; - const T2 op2; + const typename T2::ConstViewType op2; }; //// // Non-static unary expression template template< typename T1, - template< typename > class Operation > -struct UnaryExpressionTemplate< T1, Operation, VectorExpressionVariable > + typename Operation > +struct UnaryExpressionTemplate { - using RealType = decltype( Operation< typename T1::RealType >:: - evaluate( std::declval<T1>()[0] ) ); + using RealType = decltype( Operation::evaluate( std::declval<T1>()[0] ) ); using DeviceType = typename T1::DeviceType; using IndexType = typename T1::IndexType; + using ConstViewType = UnaryExpressionTemplate; + + static_assert( HasEnabledExpressionTemplates< T1 >::value, + "Invalid operand in unary expression templates - expression templates are not enabled for the operand." ); UnaryExpressionTemplate( const T1& a ) - : operand( a ) {} + : operand( a.getConstView() ) {} RealType getElement( const IndexType i ) const { - return Operation< typename T1::RealType >::evaluate( operand.getElement( i ) ); + return Operation::evaluate( operand.getElement( i ) ); } __cuda_callable__ RealType operator[]( const IndexType i ) const { - return Operation< typename T1::RealType >::evaluate( operand[ i ] ); + return Operation::evaluate( operand[ i ] ); } __cuda_callable__ @@ -203,1920 +224,665 @@ struct UnaryExpressionTemplate< T1, Operation, VectorExpressionVariable > return operand.getSize(); } + ConstViewType getConstView() const + { + return *this; + } + protected: - const T1 operand; + const typename T1::ConstViewType operand; }; -//// -// Output stream -template< typename T1, - typename T2, - template< typename, typename > class Operation > -std::ostream& operator<<( std::ostream& str, const BinaryExpressionTemplate< T1, T2, Operation >& expression ) -{ - str << "[ "; - for( int i = 0; i < expression.getSize() - 1; i++ ) - str << expression.getElement( i ) << ", "; - str << expression.getElement( expression.getSize() - 1 ) << " ]"; - return str; -} - -template< typename T, - template< typename > class Operation > -std::ostream& operator<<( std::ostream& str, const UnaryExpressionTemplate< T, Operation >& expression ) -{ - str << "[ "; - for( int i = 0; i < expression.getSize() - 1; i++ ) - str << expression.getElement( i ) << ", "; - str << expression.getElement( expression.getSize() - 1 ) << " ]"; - return str; -} - -//// -// Operators are supposed to be in the same namespace as the expression templates - #ifndef DOXYGEN_ONLY //// // Binary expressions addition -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +template< typename ET1, typename ET2, + typename..., typename = EnableIfBinaryExpression_t< ET1, ET2 >, typename = void > auto -operator+( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) +operator+( const ET1& a, const ET2& b ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return BinaryExpressionTemplate< ET1, ET2, Addition >( a, b ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Binary expression subtraction +template< typename ET1, typename ET2, + typename..., typename = EnableIfBinaryExpression_t< ET1, ET2 >, typename = void > auto -operator+( const BinaryExpressionTemplate< T1, T2, Operation >& a, - const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +operator-( const ET1& a, const ET2& b ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return BinaryExpressionTemplate< ET1, ET2, Subtraction >( a, b ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Binary expression multiplication +template< typename ET1, typename ET2, + typename..., typename = EnableIfBinaryExpression_t< ET1, ET2 >, typename = void > auto -operator+( const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const BinaryExpressionTemplate< T1, T2, Operation >& b ) +operator*( const ET1& a, const ET2& b ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return BinaryExpressionTemplate< ET1, ET2, Multiplication >( a, b ); } -template< typename T1, - template< typename > class Operation > +//// +// Binary expression division +template< typename ET1, typename ET2, + typename..., typename = EnableIfBinaryExpression_t< ET1, ET2 >, typename = void > auto -operator+( const UnaryExpressionTemplate< T1, Operation >& a, - const typename UnaryExpressionTemplate< T1, Operation >::RealType& b ) +operator/( const ET1& a, const ET2& b ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return BinaryExpressionTemplate< ET1, ET2, Division >( a, b ); } -template< typename T1, - template< typename > class Operation > -auto -operator+( const typename UnaryExpressionTemplate< T1, Operation >::RealType& a, - const UnaryExpressionTemplate< T1, Operation >& b ) +//// +// Comparison operator == +template< typename ET1, typename ET2, + typename..., typename = EnableIfBinaryExpression_t< ET1, ET2 >, typename = void > +bool +operator==( const ET1& a, const ET2& b ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return Comparison< ET1, ET2 >::EQ( a, b ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -operator+( const UnaryExpressionTemplate< L1, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) +//// +// Comparison operator != +template< typename ET1, typename ET2, + typename..., typename = EnableIfBinaryExpression_t< ET1, ET2 >, typename = void > +bool +operator!=( const ET1& a, const ET2& b ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return Comparison< ET1, ET2 >::NE( a, b ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -operator+( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const UnaryExpressionTemplate< R1,ROperation >& b ) +//// +// Comparison operator < +template< typename ET1, typename ET2, + typename..., typename = EnableIfBinaryExpression_t< ET1, ET2 >, typename = void > +bool +operator<( const ET1& a, const ET2& b ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return Comparison< ET1, ET2 >::LT( a, b ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -operator+( const UnaryExpressionTemplate< L1,LOperation >& a, - const UnaryExpressionTemplate< R1,ROperation >& b ) +//// +// Comparison operator <= +template< typename ET1, typename ET2, + typename..., typename = EnableIfBinaryExpression_t< ET1, ET2 >, typename = void > +bool +operator<=( const ET1& a, const ET2& b ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return Comparison< ET1, ET2 >::LE( a, b ); } //// -// Binary expression subtraction -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -operator-( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) +// Comparison operator > +template< typename ET1, typename ET2, + typename..., typename = EnableIfBinaryExpression_t< ET1, ET2 >, typename = void > +bool +operator>( const ET1& a, const ET2& b ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return Comparison< ET1, ET2 >::GT( a, b ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > -auto -operator-( const BinaryExpressionTemplate< T1, T2, Operation >& a, - const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +//// +// Comparison operator >= +template< typename ET1, typename ET2, + typename..., typename = EnableIfBinaryExpression_t< ET1, ET2 >, typename = void > +bool +operator>=( const ET1& a, const ET2& b ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return Comparison< ET1, ET2 >::GE( a, b ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Scalar product +template< typename ET1, typename ET2, + typename..., typename = EnableIfBinaryExpression_t< ET1, ET2 >, typename = void > auto -operator-( const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const BinaryExpressionTemplate< T1, T2, Operation >& b ) +operator,( const ET1& a, const ET2& b ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return ExpressionSum( a * b ); } -template< typename T1, - template< typename > class Operation > +template< typename ET1, typename ET2, + typename..., typename = EnableIfBinaryExpression_t< ET1, ET2 >, typename = void > auto -operator-( const UnaryExpressionTemplate< T1, Operation >& a, - const typename UnaryExpressionTemplate< T1, Operation >::RealType& b ) +dot( const ET1& a, const ET2& b ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return (a, b); } -template< typename T1, - template< typename > class Operation > +//// +// Unary expression minus +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > auto -operator-( const typename UnaryExpressionTemplate< T1, Operation >::RealType& a, - const UnaryExpressionTemplate< T1, Operation >& b ) +operator-( const ET1& a ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return UnaryExpressionTemplate< ET1, Minus >( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +//// +// Binary expression min +template< typename ET1, typename ET2, + typename..., typename = EnableIfBinaryExpression_t< ET1, ET2 >, typename = void > auto -operator-( const UnaryExpressionTemplate< L1, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) +min( const ET1& a, const ET2& b ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return BinaryExpressionTemplate< ET1, ET2, Min >( a, b ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Binary expression max +template< typename ET1, typename ET2, + typename..., typename = EnableIfBinaryExpression_t< ET1, ET2 >, typename = void > auto -operator-( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const UnaryExpressionTemplate< R1,ROperation >& b ) +max( const ET1& a, const ET2& b ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return BinaryExpressionTemplate< ET1, ET2, Max >( a, b ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Abs +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > auto -operator-( const UnaryExpressionTemplate< L1,LOperation >& a, - const UnaryExpressionTemplate< R1,ROperation >& b ) +abs( const ET1& a ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return UnaryExpressionTemplate< ET1, Abs >( a ); } //// -// Binary expression multiplication -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +// Pow +template< typename ET1, typename Real, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > auto -operator*( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) +pow( const ET1& a, const Real& exp ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return BinaryExpressionTemplate< ET1, Real, Pow >( a, exp ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Exp +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > auto -operator*( const BinaryExpressionTemplate< T1, T2, Operation >& a, - const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +exp( const ET1& a ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return UnaryExpressionTemplate< ET1, Exp >( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Sqrt +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > auto -operator*( const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const BinaryExpressionTemplate< T1, T2, Operation >& b ) +sqrt( const ET1& a ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return UnaryExpressionTemplate< ET1, Sqrt >( a ); } -template< typename T1, - template< typename > class Operation > +//// +// Cbrt +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > auto -operator*( const UnaryExpressionTemplate< T1, Operation >& a, - const typename UnaryExpressionTemplate< T1, Operation >::RealType& b ) +cbrt( const ET1& a ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return UnaryExpressionTemplate< ET1, Cbrt >( a ); } -template< typename T1, - template< typename > class Operation > +//// +// Log +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > auto -operator*( const typename UnaryExpressionTemplate< T1, Operation >::RealType& a, - const UnaryExpressionTemplate< T1, Operation >& b ) +log( const ET1& a ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return UnaryExpressionTemplate< ET1, Log >( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +//// +// Log10 +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > auto -operator*( const UnaryExpressionTemplate< L1, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) +log10( const ET1& a ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return UnaryExpressionTemplate< ET1, Log10 >( a ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Log2 +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > auto -operator*( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const UnaryExpressionTemplate< R1, ROperation >& b ) +log2( const ET1& a ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return UnaryExpressionTemplate< ET1, Log2 >( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Sin +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > auto -operator*( const UnaryExpressionTemplate< L1,LOperation >& a, - const UnaryExpressionTemplate< R1,ROperation >& b ) +sin( const ET1& a ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return UnaryExpressionTemplate< ET1, Sin >( a ); } //// -// Binary expression division -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +// Cos +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > auto -operator/( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) +cos( const ET1& a ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return UnaryExpressionTemplate< ET1, Cos >( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Tan +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > auto -operator/( const BinaryExpressionTemplate< T1, T2, Operation >& a, - const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +tan( const ET1& a ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return UnaryExpressionTemplate< ET1, Tan >( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Asin +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > auto -operator/( const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const BinaryExpressionTemplate< T1, T2, Operation >& b ) +asin( const ET1& a ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return UnaryExpressionTemplate< ET1, Asin >( a ); } -template< typename T1, - template< typename > class Operation > +//// +// Acos +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > auto -operator/( const UnaryExpressionTemplate< T1, Operation >& a, - const typename UnaryExpressionTemplate< T1, Operation >::RealType& b ) +acos( const ET1& a ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return UnaryExpressionTemplate< ET1, Acos >( a ); } -template< typename T1, - template< typename > class Operation > +//// +// Atan +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > auto -operator/( const typename UnaryExpressionTemplate< T1, Operation >::RealType& a, - const UnaryExpressionTemplate< T1, Operation >& b ) +atan( const ET1& a ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return UnaryExpressionTemplate< ET1, Atan >( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +//// +// Sinh +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > auto -operator/( const UnaryExpressionTemplate< L1, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) +sinh( const ET1& a ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return UnaryExpressionTemplate< ET1, Sinh >( a ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Cosh +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > auto -operator/( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const UnaryExpressionTemplate< R1,ROperation >& b ) +cosh( const ET1& a ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return UnaryExpressionTemplate< ET1, Cosh >( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Tanh +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > auto -operator/( const UnaryExpressionTemplate< L1,LOperation >& a, - const UnaryExpressionTemplate< R1,ROperation >& b ) +tanh( const ET1& a ) { - return BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return UnaryExpressionTemplate< ET1, Tanh >( a ); } //// -// Comparison operator == -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator==( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator==( const BinaryExpressionTemplate< T1, T2, Operation >& a, - const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +// Asinh +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +asinh( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); + return UnaryExpressionTemplate< ET1, Asinh >( a ); } -template< typename T1, - template< typename > class Operation > -bool -operator==( const UnaryExpressionTemplate< T1, Operation >& a, - const typename UnaryExpressionTemplate< T1, Operation >::RealType& b ) +//// +// Acosh +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +acosh( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); + return UnaryExpressionTemplate< ET1, Acosh >( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator==( const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const BinaryExpressionTemplate< T1, T2, Operation >& b ) +//// +// Atanh +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +atanh( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); + return UnaryExpressionTemplate< ET1, Atanh >( a ); } -template< typename T1, - template< typename > class Operation > -bool -operator==( const typename UnaryExpressionTemplate< T1, Operation >::RealType& a, - const UnaryExpressionTemplate< T1, Operation >& b ) +//// +// Floor +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +floor( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); + return UnaryExpressionTemplate< ET1, Floor >( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator==( const UnaryExpressionTemplate< L1, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) +//// +// Ceil +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +ceil( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); + return UnaryExpressionTemplate< ET1, Ceil >( a ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -bool -operator==( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const UnaryExpressionTemplate< R1,ROperation >& b ) +//// +// Sign +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +sign( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); + return UnaryExpressionTemplate< ET1, Sign >( a ); } //// -// Comparison operator != -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator!=( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) +// Cast +template< typename ResultType, + typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, + // workaround: templated type alias cannot be declared at block level + typename CastOperation = typename Cast< ResultType >::Operation, + typename = void > +auto +cast( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return UnaryExpressionTemplate< ET1, CastOperation >( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator!=( const BinaryExpressionTemplate< T1, T2, Operation >& a, - const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +//// +// Vertical operations +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +min( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return ExpressionMin( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -bool -operator!=( const UnaryExpressionTemplate< L1, LOperation >& a, - const UnaryExpressionTemplate< R1, ROperation >& b ) +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +argMin( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return ExpressionArgMin( a ); } -template< typename T1, - template< typename > class Operation > -bool -operator!=( const UnaryExpressionTemplate< T1, Operation >& a, - const typename UnaryExpressionTemplate< T1, Operation >::RealType& b ) +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +max( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return ExpressionMax( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator!=( const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const BinaryExpressionTemplate< T1, T2, Operation >& b ) +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +argMax( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return ExpressionArgMax( a ); } -template< typename T1, - template< typename > class Operation > -bool -operator!=( const typename UnaryExpressionTemplate< T1, Operation >::RealType& a, - const UnaryExpressionTemplate< T1, Operation >& b ) +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +sum( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return ExpressionSum( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator!=( const UnaryExpressionTemplate< L1, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +maxNorm( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return max( abs( a ) ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -bool -operator!=( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const UnaryExpressionTemplate< R1,ROperation >& b ) +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +l1Norm( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return sum( abs( a ) ); } -//// -// Comparison operator < -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator<( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +l2Norm( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + using TNL::sqrt; + return sqrt( sum( a * a ) ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator<( const BinaryExpressionTemplate< T1, T2, Operation >& a, - const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +template< typename ET1, + typename Real, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +lpNorm( const ET1& a, const Real& p ) +// since (1.0 / p) has type double, TNL::pow returns double +-> double { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + if( p == 1.0 ) + return l1Norm( a ); + if( p == 2.0 ) + return l2Norm( a ); + using TNL::pow; + return pow( sum( pow( abs( a ), p ) ), 1.0 / p ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -bool -operator<( const UnaryExpressionTemplate< L1, LOperation >& a, - const UnaryExpressionTemplate< R1, ROperation >& b ) +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +product( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + return ExpressionProduct( a ); } -template< typename T1, - template< typename > class Operation > -bool -operator<( const UnaryExpressionTemplate< T1, Operation >& a, - const typename UnaryExpressionTemplate< T1, Operation >::RealType& b ) +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +logicalAnd( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + return ExpressionLogicalAnd( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator<( const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const BinaryExpressionTemplate< T1, T2, Operation >& b ) +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +logicalOr( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + return ExpressionLogicalOr( a ); } -template< typename T1, - template< typename > class Operation > -bool -operator<( const typename UnaryExpressionTemplate< T1, Operation >::RealType& a, - const UnaryExpressionTemplate< T1, Operation >& b ) +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +binaryAnd( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + return ExpressionBinaryAnd( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator<( const UnaryExpressionTemplate< L1, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) +template< typename ET1, + typename..., typename = EnableIfUnaryExpression_t< ET1 >, typename = void > +auto +binaryOr( const ET1& a ) { - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + return ExpressionBinaryOr( a ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -bool -operator<( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const UnaryExpressionTemplate< R1,ROperation >& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); -} +#endif // DOXYGEN_ONLY //// -// Comparison operator <= -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator<=( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator<=( const BinaryExpressionTemplate< T1, T2, Operation >& a, - const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -bool -operator<=( const UnaryExpressionTemplate< L1, LOperation >& a, - const UnaryExpressionTemplate< R1, ROperation >& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -template< typename T1, - template< typename > class Operation > -bool -operator<=( const UnaryExpressionTemplate< T1, Operation >& a, - const typename UnaryExpressionTemplate< T1, Operation >::RealType& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator<=( const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const BinaryExpressionTemplate< T1, T2, Operation >& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -template< typename T1, - template< typename > class Operation > -bool -operator<=( const typename UnaryExpressionTemplate< T1, Operation >::RealType& a, - const UnaryExpressionTemplate< T1, Operation >& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator<=( const UnaryExpressionTemplate< L1, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -bool -operator<=( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const UnaryExpressionTemplate< R1,ROperation >& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -//// -// Comparison operator > -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator>( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator>( const BinaryExpressionTemplate< T1, T2, Operation >& a, - const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename T1, - template< typename > class Operation > -bool -operator>( const UnaryExpressionTemplate< T1, Operation >& a, - const typename UnaryExpressionTemplate< T1, Operation >::RealType& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator>( const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const BinaryExpressionTemplate< T1, T2, Operation >& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename T1, - template< typename > class Operation > -bool -operator>( const typename UnaryExpressionTemplate< T1, Operation >::RealType& a, - const UnaryExpressionTemplate< T1, Operation >& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator>( const UnaryExpressionTemplate< L1, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -bool -operator>( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const UnaryExpressionTemplate< R1,ROperation >& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -//// -// Comparison operator >= -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator>=( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -bool -operator>=( const BinaryExpressionTemplate< T1, T2, Operation >& a, - const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename T1, - template< typename > class Operation > -bool -operator>=( const UnaryExpressionTemplate< T1, Operation >& a, - const typename UnaryExpressionTemplate< T1, Operation >::RealType& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - +// Output stream template< typename T1, typename T2, - template< typename, typename > class Operation > -bool -operator>=( const typename BinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const BinaryExpressionTemplate< T1, T2, Operation >& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename T1, - template< typename > class Operation > -bool -operator>=( const typename UnaryExpressionTemplate< T1, Operation >::RealType& a, - const UnaryExpressionTemplate< T1, Operation >& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -bool -operator>=( const UnaryExpressionTemplate< L1, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -bool -operator>=( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const UnaryExpressionTemplate< R1,ROperation >& b ) -{ - return Comparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -//// -// Unary operations - -//// -// Minus -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -operator-( const BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return UnaryExpressionTemplate< std::decay_t<decltype(a)>, Minus >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -operator-( const UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return UnaryExpressionTemplate< std::decay_t<decltype(a)>, Minus >( a ); -} - -//// -// Scalar product -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -operator,( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return ExpressionSum( a * b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -operator,( const UnaryExpressionTemplate< L1, LOperation >& a, - const UnaryExpressionTemplate< R1, ROperation >& b ) -{ - return ExpressionSum( a * b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -operator,( const UnaryExpressionTemplate< L1, LOperation >& a, - const BinaryExpressionTemplate< R1, R2, ROperation >& b ) + typename Operation > +std::ostream& operator<<( std::ostream& str, const BinaryExpressionTemplate< T1, T2, Operation >& expression ) { - return ExpressionSum( a * b ); + str << "[ "; + for( int i = 0; i < expression.getSize() - 1; i++ ) + str << expression.getElement( i ) << ", "; + str << expression.getElement( expression.getSize() - 1 ) << " ]"; + return str; } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -operator,( const BinaryExpressionTemplate< L1, L2, LOperation >& a, - const UnaryExpressionTemplate< R1,ROperation >& b ) +template< typename T, + typename Operation > +std::ostream& operator<<( std::ostream& str, const UnaryExpressionTemplate< T, Operation >& expression ) { - return ExpressionSum( a * b ); + str << "[ "; + for( int i = 0; i < expression.getSize() - 1; i++ ) + str << expression.getElement( i ) << ", "; + str << expression.getElement( expression.getSize() - 1 ) << " ]"; + return str; } -#endif // DOXYGEN_ONLY - } // namespace Expressions -} // namespace Containers - -//// -// All operations are supposed to be in namespace TNL - -#ifndef DOXYGEN_ONLY - -//// -// Binary expression min -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -min( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a, - const Containers::Expressions::BinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -auto -min( const Containers::Expressions::BinaryExpressionTemplate< T1, T2, Operation >& a, - const typename Containers::Expressions::BinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -auto -min( const typename Containers::Expressions::BinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const Containers::Expressions::BinaryExpressionTemplate< T1, T2, Operation >& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename T1, - template< typename > class Operation > -auto -min( const Containers::Expressions::UnaryExpressionTemplate< T1, Operation >& a, - const typename Containers::Expressions::UnaryExpressionTemplate< T1, Operation >::RealType& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename T1, - template< typename > class Operation > -auto -min( const typename Containers::Expressions::UnaryExpressionTemplate< T1, Operation >::RealType& a, - const Containers::Expressions::UnaryExpressionTemplate< T1, Operation >& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -min( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a, - const typename Containers::Expressions::BinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -min( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a, - const Containers::Expressions::UnaryExpressionTemplate< R1,ROperation >& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -min( const Containers::Expressions::UnaryExpressionTemplate< L1,LOperation >& a, - const Containers::Expressions::UnaryExpressionTemplate< R1,ROperation >& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -//// -// Binary expression max -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -max( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a, - const Containers::Expressions::BinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -auto -max( const Containers::Expressions::BinaryExpressionTemplate< T1, T2, Operation >& a, - const typename Containers::Expressions::BinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -auto -max( const typename Containers::Expressions::BinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const Containers::Expressions::BinaryExpressionTemplate< T1, T2, Operation >& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename T1, - template< typename > class Operation > -auto -max( const Containers::Expressions::UnaryExpressionTemplate< T1, Operation >& a, - const typename Containers::Expressions::UnaryExpressionTemplate< T1, Operation >::RealType& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename T1, - template< typename > class Operation > -auto -max( const typename Containers::Expressions::UnaryExpressionTemplate< T1, Operation >::RealType& a, - const Containers::Expressions::UnaryExpressionTemplate< T1, Operation >& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -max( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a, - const Containers::Expressions::BinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -max( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a, - const Containers::Expressions::UnaryExpressionTemplate< R1,ROperation >& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -max( const Containers::Expressions::UnaryExpressionTemplate< L1,LOperation >& a, - const Containers::Expressions::UnaryExpressionTemplate< R1,ROperation >& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -//// -// Abs -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -abs( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Abs >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -abs( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Abs >( a ); -} - -//// -// Pow -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename Real > -auto -pow( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a, const Real& exp ) -{ - return Containers::Expressions::BinaryExpressionTemplate< std::decay_t<decltype(a)>, Real, Containers::Expressions::Pow >( a, exp ); -} -template< typename L1, - template< typename > class LOperation, - typename Real > -auto -pow( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a, const Real& exp ) -{ - return Containers::Expressions::BinaryExpressionTemplate< std::decay_t<decltype(a)>, Real, Containers::Expressions::Pow >( a, exp ); -} +// Make all operators visible in the TNL::Containers namespace to be considered +// even for Vector and VectorView +using Expressions::operator+; +using Expressions::operator-; +using Expressions::operator*; +using Expressions::operator/; +using Expressions::operator,; +using Expressions::operator==; +using Expressions::operator!=; +using Expressions::operator<; +using Expressions::operator<=; +using Expressions::operator>; +using Expressions::operator>=; + +// Make all functions visible in the TNL::Containers namespace +using Expressions::dot; +using Expressions::min; +using Expressions::max; +using Expressions::abs; +using Expressions::pow; +using Expressions::exp; +using Expressions::sqrt; +using Expressions::cbrt; +using Expressions::log; +using Expressions::log10; +using Expressions::log2; +using Expressions::sin; +using Expressions::cos; +using Expressions::tan; +using Expressions::asin; +using Expressions::acos; +using Expressions::atan; +using Expressions::sinh; +using Expressions::cosh; +using Expressions::tanh; +using Expressions::asinh; +using Expressions::acosh; +using Expressions::atanh; +using Expressions::floor; +using Expressions::ceil; +using Expressions::sign; +using Expressions::cast; +using Expressions::argMin; +using Expressions::argMax; +using Expressions::sum; +using Expressions::maxNorm; +using Expressions::l1Norm; +using Expressions::l2Norm; +using Expressions::lpNorm; +using Expressions::product; +using Expressions::logicalAnd; +using Expressions::logicalOr; +using Expressions::binaryAnd; +using Expressions::binaryOr; -//// -// Exp -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -exp( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Exp >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -exp( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Exp >( a ); -} - -//// -// Sqrt -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -sqrt( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sqrt >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -sqrt( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sqrt >( a ); -} - -//// -// Cbrt -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -cbrt( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cbrt >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -cbrt( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cbrt >( a ); -} - -//// -// Log -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -log( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -log( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log >( a ); -} - -//// -// Log10 -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -log10( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log10 >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -log10( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log10 >( a ); -} - -//// -// Log2 -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -log2( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log2 >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -log2( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log2 >( a ); -} - -//// -// Sin -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -sin( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sin >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -sin( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sin >( a ); -} - -//// -// Cos -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -cos( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cos >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -cos( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cos >( a ); -} - -//// -// Tan -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -tan( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Tan >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -tan( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Tan >( a ); -} - -//// -// Asin -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -asin( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Asin >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -asin( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Asin >( a ); -} - -//// -// Acos -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -acos( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Acos >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -acos( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Acos >( a ); -} - -//// -// Atan -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -atan( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Atan >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -atan( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Atan >( a ); -} - -//// -// Sinh -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -sinh( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sinh >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -sinh( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sinh >( a ); -} - -//// -// Cosh -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -cosh( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cosh >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -cosh( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cosh >( a ); -} - -//// -// Tanh -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -tanh( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Tanh >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -tanh( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Tanh >( a ); -} - -//// -// Asinh -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -asinh( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Asinh >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -asinh( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Asinh >( a ); -} - -//// -// Acosh -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -acosh( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Acosh >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -acosh( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Acosh >( a ); -} - -//// -// Atanh -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -atanh( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Atanh >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -atanh( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Atanh >( a ); -} - -//// -// Floor -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -floor( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Floor >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -floor( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Floor >( a ); -} - -//// -// Ceil -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -ceil( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Ceil >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -ceil( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Ceil >( a ); -} - -//// -// Sign -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -sign( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sign >( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -sign( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sign >( a ); -} - -//// -// Cast -template< typename ResultType, - typename L1, - typename L2, - template< typename, typename > class LOperation, - // workaround: templated type alias cannot be declared at block level - template<typename> class CastOperation = Containers::Expressions::Cast< ResultType >::template Operation > -auto -cast( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, CastOperation >( a ); -} - -template< typename ResultType, - typename L1, - template< typename > class LOperation, - // workaround: templated type alias cannot be declared at block level - template<typename> class CastOperation = Containers::Expressions::Cast< ResultType >::template Operation > -auto -cast( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, CastOperation >( a ); -} - -//// -// Vertical operations - min -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -min( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return ExpressionMin( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -min( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return ExpressionMin( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -argMin( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return ExpressionArgMin( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -argMin( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return ExpressionArgMin( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -max( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return ExpressionMax( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -max( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return ExpressionMax( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -argMax( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return ExpressionArgMax( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -argMax( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return ExpressionArgMax( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -sum( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return ExpressionSum( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -sum( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return ExpressionSum( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -maxNorm( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return max( abs( a ) ); -} - -template< typename L1, - template< typename > class LOperation > -auto -maxNorm( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return max( abs( a ) ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -l1Norm( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return ExpressionL1Norm( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -l1Norm( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return ExpressionL1Norm( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -l2Norm( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return TNL::sqrt( ExpressionL2Norm( a ) ); -} - -template< typename L1, - template< typename > class LOperation > -auto -l2Norm( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return TNL::sqrt( ExpressionL2Norm( a ) ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename Real > -auto -lpNorm( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a, const Real& p ) -// since (1.0 / p) has type double, TNL::pow returns double --> double -{ - if( p == 1.0 ) - return l1Norm( a ); - if( p == 2.0 ) - return l2Norm( a ); - return TNL::pow( ExpressionLpNorm( a, p ), 1.0 / p ); -} - -template< typename L1, - template< typename > class LOperation, - typename Real > -auto -lpNorm( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a, const Real& p ) -// since (1.0 / p) has type double, TNL::pow returns double --> double -{ - if( p == 1.0 ) - return l1Norm( a ); - if( p == 2.0 ) - return l2Norm( a ); - return TNL::pow( ExpressionLpNorm( a, p ), 1.0 / p ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -product( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return ExpressionProduct( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -product( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return ExpressionProduct( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -logicalOr( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return ExpressionLogicalOr( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -logicalOr( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return ExpressionLogicalOr( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -logicalAnd( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return ExpressionLogicalAnd( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -logicalAnd( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return ExpressionLogicalAnd( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -binaryOr( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return ExpressionBinaryOr( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -binaryOr( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return ExpressionBinaryOr( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -binaryAnd( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return ExpressionBinaryAnd( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -binaryAnd( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a ) -{ - return ExpressionBinaryAnd( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -dot( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a, - const Containers::Expressions::BinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return (a, b); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -dot( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a, - const Containers::Expressions::UnaryExpressionTemplate< R1, ROperation >& b ) -{ - return (a, b); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -auto -dot( const Containers::Expressions::UnaryExpressionTemplate< L1, LOperation >& a, - const Containers::Expressions::BinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return (a, b); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -auto -dot( const Containers::Expressions::BinaryExpressionTemplate< L1, L2, LOperation >& a, - const Containers::Expressions::UnaryExpressionTemplate< R1, ROperation >& b ) -{ - return (a, b); -} - -#endif // DOXYGEN_ONLY +} // namespace Containers +// Make all functions visible in the main TNL namespace +using Containers::dot; +using Containers::min; +using Containers::max; +using Containers::abs; +using Containers::pow; +using Containers::exp; +using Containers::sqrt; +using Containers::cbrt; +using Containers::log; +using Containers::log10; +using Containers::log2; +using Containers::sin; +using Containers::cos; +using Containers::tan; +using Containers::asin; +using Containers::acos; +using Containers::atan; +using Containers::sinh; +using Containers::cosh; +using Containers::tanh; +using Containers::asinh; +using Containers::acosh; +using Containers::atanh; +using Containers::floor; +using Containers::ceil; +using Containers::sign; +using Containers::cast; +using Containers::argMin; +using Containers::argMax; +using Containers::sum; +using Containers::maxNorm; +using Containers::l1Norm; +using Containers::l2Norm; +using Containers::lpNorm; +using Containers::product; +using Containers::logicalAnd; +using Containers::logicalOr; +using Containers::binaryAnd; +using Containers::binaryOr; //// // Evaluation with reduction template< typename Vector, typename T1, typename T2, - template< typename, typename > class Operation, + typename Operation, typename Reduction, typename Result > Result evaluateAndReduce( Vector& lhs, @@ -2135,7 +901,7 @@ Result evaluateAndReduce( Vector& lhs, template< typename Vector, typename T1, - template< typename > class Operation, + typename Operation, typename Reduction, typename Result > Result evaluateAndReduce( Vector& lhs, @@ -2157,7 +923,7 @@ Result evaluateAndReduce( Vector& lhs, template< typename Vector, typename T1, typename T2, - template< typename, typename > class Operation, + typename Operation, typename Reduction, typename Result > Result addAndReduce( Vector& lhs, @@ -2180,7 +946,7 @@ Result addAndReduce( Vector& lhs, template< typename Vector, typename T1, - template< typename > class Operation, + typename Operation, typename Reduction, typename Result > Result addAndReduce( Vector& lhs, @@ -2206,7 +972,7 @@ Result addAndReduce( Vector& lhs, template< typename Vector, typename T1, typename T2, - template< typename, typename > class Operation, + typename Operation, typename Reduction, typename Result > Result addAndReduceAbs( Vector& lhs, @@ -2229,7 +995,7 @@ Result addAndReduceAbs( Vector& lhs, template< typename Vector, typename T1, - template< typename > class Operation, + typename Operation, typename Reduction, typename Result > Result addAndReduceAbs( Vector& lhs, diff --git a/src/TNL/Containers/Expressions/ExpressionVariableType.h b/src/TNL/Containers/Expressions/ExpressionVariableType.h index ad9ab830ed30f1cbfc4f2701140ffb1efcb819e7..2095a4352c9874f6315f01dbaf475be2f1a66006 100644 --- a/src/TNL/Containers/Expressions/ExpressionVariableType.h +++ b/src/TNL/Containers/Expressions/ExpressionVariableType.h @@ -10,8 +10,7 @@ #pragma once -#include <TNL/TypeTraits.h> -#include <TNL/Devices/Host.h> +#include <TNL/Containers/Expressions/TypeTraits.h> namespace TNL { namespace Containers { @@ -19,41 +18,24 @@ namespace Expressions { enum ExpressionVariableType { ArithmeticVariable, VectorExpressionVariable, OtherVariable }; -template< typename T, - bool IsArithmetic = std::is_arithmetic< T >::value, - bool IsVector = HasSubscriptOperator< T >::value > -struct ExpressionVariableTypeGetter +template< typename T, typename V = T > +constexpr ExpressionVariableType +getExpressionVariableType() { - static constexpr ExpressionVariableType value = OtherVariable; -}; - -template< typename T > -struct ExpressionVariableTypeGetter< T, true, false > -{ - static constexpr ExpressionVariableType value = ArithmeticVariable; -}; - -template< typename T > -struct ExpressionVariableTypeGetter< T, false, true > -{ - static constexpr ExpressionVariableType value = VectorExpressionVariable; -}; - -//// -// Non-static expression templates might be passed on GPU, for example. In this -// case, we cannot store ET operands using references but we need to make copies. -template< typename T, - typename Device > -struct OperandType -{ - using type = std::add_const_t< std::remove_reference_t< T > >; -}; - -template< typename T > -struct OperandType< T, Devices::Host > -{ - using type = std::add_const_t< std::add_lvalue_reference_t< T > >; -}; + if( std::is_arithmetic< std::decay_t< T > >::value ) + return ArithmeticVariable; + // vectors must be considered as an arithmetic type when used as RealType in another vector + if( IsArithmeticSubtype< T, V >::value ) + return ArithmeticVariable; + if( HasEnabledExpressionTemplates< T >::value || + HasEnabledStaticExpressionTemplates< T >::value || + HasEnabledDistributedExpressionTemplates< T >::value + ) + return VectorExpressionVariable; + if( IsArrayType< T >::value || IsStaticArrayType< T >::value ) + return VectorExpressionVariable; + return OtherVariable; +} } // namespace Expressions } // namespace Containers diff --git a/src/TNL/Containers/Expressions/HorizontalOperations.h b/src/TNL/Containers/Expressions/HorizontalOperations.h index 4bfe6a0146fde1f3ac52a2e2175ea56f422ad56c..cb49f7d47f35a85a35d3d8a51abb362cf793f899 100644 --- a/src/TNL/Containers/Expressions/HorizontalOperations.h +++ b/src/TNL/Containers/Expressions/HorizontalOperations.h @@ -16,9 +16,9 @@ namespace TNL { namespace Containers { namespace Expressions { -template< typename T1, typename T2 > struct Addition { + template< typename T1, typename T2 > __cuda_callable__ static auto evaluate( const T1& a, const T2& b ) -> decltype( a + b ) { @@ -26,9 +26,9 @@ struct Addition } }; -template< typename T1, typename T2 > struct Subtraction { + template< typename T1, typename T2 > __cuda_callable__ static auto evaluate( const T1& a, const T2& b ) -> decltype( a - b ) { @@ -36,9 +36,9 @@ struct Subtraction } }; -template< typename T1, typename T2 > struct Multiplication { + template< typename T1, typename T2 > __cuda_callable__ static auto evaluate( const T1& a, const T2& b ) -> decltype( a * b ) { @@ -46,9 +46,9 @@ struct Multiplication } }; -template< typename T1, typename T2 > struct Division { + template< typename T1, typename T2 > __cuda_callable__ static auto evaluate( const T1& a, const T2& b ) -> decltype( a / b ) { @@ -56,272 +56,272 @@ struct Division } }; -template< typename T1, typename T2 > struct Min { + template< typename T1, typename T2 > __cuda_callable__ - static auto evaluate( const T1& a, const T2& b ) -> decltype( TNL::min( a , b ) ) + static auto evaluate( const T1& a, const T2& b ) -> decltype( min( a , b ) ) { - return TNL::min( a, b ); + return min( a, b ); } }; -template< typename T1, typename T2 > struct Max { + template< typename T1, typename T2 > __cuda_callable__ - static auto evaluate( const T1& a, const T2& b ) -> decltype( TNL::max( a, b ) ) + static auto evaluate( const T1& a, const T2& b ) -> decltype( max( a, b ) ) { - return TNL::max( a, b ); + return max( a, b ); } }; -template< typename T1 > struct Minus { + template< typename T1 > __cuda_callable__ - static T1 evaluate( const T1& a ) + static auto evaluate( const T1& a ) -> decltype( -a ) { return -a; } }; -template< typename T1 > struct Abs { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::abs( a ) ) + static auto evaluate( const T1& a ) -> decltype( abs( a ) ) { - return TNL::abs( a ); + return abs( a ); } }; -template< typename T1, typename T2 > struct Pow { + template< typename T1, typename T2 > __cuda_callable__ - static auto evaluate( const T1& a, const T2& exp ) -> decltype( TNL::pow( a, exp ) ) + static auto evaluate( const T1& a, const T2& exp ) -> decltype( pow( a, exp ) ) { - return TNL::pow( a, exp ); + return pow( a, exp ); } }; -template< typename T1 > struct Exp { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::exp( a ) ) + static auto evaluate( const T1& a ) -> decltype( exp( a ) ) { - return TNL::exp( a ); + return exp( a ); } }; -template< typename T1 > struct Sqrt { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::sqrt( a ) ) + static auto evaluate( const T1& a ) -> decltype( sqrt( a ) ) { - return TNL::sqrt( a ); + return sqrt( a ); } }; -template< typename T1 > struct Cbrt { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::cbrt( a ) ) + static auto evaluate( const T1& a ) -> decltype( cbrt( a ) ) { - return TNL::cbrt( a ); + return cbrt( a ); } }; -template< typename T1 > struct Log { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::log( a ) ) + static auto evaluate( const T1& a ) -> decltype( log( a ) ) { - return TNL::log( a ); + return log( a ); } }; -template< typename T1 > struct Log10 { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::log10( a ) ) + static auto evaluate( const T1& a ) -> decltype( log10( a ) ) { - return TNL::log10( a ); + return log10( a ); } }; -template< typename T1 > struct Log2 { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::log2( a ) ) + static auto evaluate( const T1& a ) -> decltype( log2( a ) ) { - return TNL::log2( a ); + return log2( a ); } }; -template< typename T1 > struct Sin { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::sin( a ) ) + static auto evaluate( const T1& a ) -> decltype( sin( a ) ) { - return TNL::sin( a ); + return sin( a ); } }; -template< typename T1 > struct Cos { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::cos( a ) ) + static auto evaluate( const T1& a ) -> decltype( cos( a ) ) { - return TNL::cos( a ); + return cos( a ); } }; -template< typename T1 > struct Tan { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::tan( a ) ) + static auto evaluate( const T1& a ) -> decltype( tan( a ) ) { - return TNL::tan( a ); + return tan( a ); } }; -template< typename T1 > struct Asin { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::asin( a ) ) + static auto evaluate( const T1& a ) -> decltype( asin( a ) ) { - return TNL::asin( a ); + return asin( a ); } }; -template< typename T1 > struct Acos { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::acos( a ) ) + static auto evaluate( const T1& a ) -> decltype( acos( a ) ) { - return TNL::acos( a ); + return acos( a ); } }; -template< typename T1 > struct Atan { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::atan( a ) ) + static auto evaluate( const T1& a ) -> decltype( atan( a ) ) { - return TNL::atan( a ); + return atan( a ); } }; -template< typename T1 > struct Sinh { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::sinh( a ) ) + static auto evaluate( const T1& a ) -> decltype( sinh( a ) ) { - return TNL::sinh( a ); + return sinh( a ); } }; -template< typename T1 > struct Cosh { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::cosh( a ) ) + static auto evaluate( const T1& a ) -> decltype( cosh( a ) ) { - return TNL::cosh( a ); + return cosh( a ); } }; -template< typename T1 > struct Tanh { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::tanh( a ) ) + static auto evaluate( const T1& a ) -> decltype( tanh( a ) ) { - return TNL::tanh( a ); + return tanh( a ); } }; -template< typename T1 > struct Asinh { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::asinh( a ) ) + static auto evaluate( const T1& a ) -> decltype( asinh( a ) ) { - return TNL::asinh( a ); + return asinh( a ); } }; -template< typename T1 > struct Acosh { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::acosh( a ) ) + static auto evaluate( const T1& a ) -> decltype( acosh( a ) ) { - return TNL::acosh( a ); + return acosh( a ); } }; -template< typename T1 > struct Atanh { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::atanh( a ) ) + static auto evaluate( const T1& a ) -> decltype( atanh( a ) ) { - return TNL::atanh( a ); + return atanh( a ); } }; -template< typename T1 > struct Floor { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::floor( a ) ) + static auto evaluate( const T1& a ) -> decltype( floor( a ) ) { - return TNL::floor( a ); + return floor( a ); } }; -template< typename T1 > struct Ceil { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::ceil( a ) ) + static auto evaluate( const T1& a ) -> decltype( ceil( a ) ) { - return TNL::ceil( a ); + return ceil( a ); } }; -template< typename T1 > struct Sign { + template< typename T1 > __cuda_callable__ - static auto evaluate( const T1& a ) -> decltype( TNL::sign( a ) ) + static auto evaluate( const T1& a ) -> decltype( sign( a ) ) { - return TNL::sign( a ); + return sign( a ); } }; template< typename ResultType > struct Cast { - template< typename T1 > struct Operation { + template< typename T1 > __cuda_callable__ static auto evaluate( const T1& a ) -> ResultType { diff --git a/src/TNL/Containers/Expressions/StaticComparison.h b/src/TNL/Containers/Expressions/StaticComparison.h index d12f1c12bdd0a5a4f63f1e3f507141d675f34706..af1bf17baf52579c7a586173215e7051069e3fff 100644 --- a/src/TNL/Containers/Expressions/StaticComparison.h +++ b/src/TNL/Containers/Expressions/StaticComparison.h @@ -19,8 +19,8 @@ namespace Expressions { template< typename T1, typename T2, - ExpressionVariableType T1Type = ExpressionVariableTypeGetter< T1 >::value, - ExpressionVariableType T2Type = ExpressionVariableTypeGetter< T2 >::value > + ExpressionVariableType T1Type = getExpressionVariableType< T1, T2 >(), + ExpressionVariableType T2Type = getExpressionVariableType< T2, T1 >() > struct StaticComparison; ///// diff --git a/src/TNL/Containers/Expressions/StaticExpressionTemplates.h b/src/TNL/Containers/Expressions/StaticExpressionTemplates.h index d08f2b02b76fe0c47b1ac4d141a6d6f9d85b5586..89e13d7f129fc56f9bb361cf8656f8be13a3b3ea 100644 --- a/src/TNL/Containers/Expressions/StaticExpressionTemplates.h +++ b/src/TNL/Containers/Expressions/StaticExpressionTemplates.h @@ -25,32 +25,28 @@ namespace Containers { namespace Expressions { template< typename T1, - template< typename > class Operation, - ExpressionVariableType T1Type = ExpressionVariableTypeGetter< T1 >::value > -struct StaticUnaryExpressionTemplate -{}; + typename Operation > +struct StaticUnaryExpressionTemplate; template< typename T1, - template< typename > class Operation, - ExpressionVariableType T1Type > -struct IsExpressionTemplate< StaticUnaryExpressionTemplate< T1, Operation, T1Type > > + typename Operation > +struct HasEnabledStaticExpressionTemplates< StaticUnaryExpressionTemplate< T1, Operation > > : std::true_type {}; template< typename T1, typename T2, - template< typename, typename > class Operation, - ExpressionVariableType T1Type = ExpressionVariableTypeGetter< T1 >::value, - ExpressionVariableType T2Type = ExpressionVariableTypeGetter< T2 >::value > -struct StaticBinaryExpressionTemplate -{}; + typename Operation, + ExpressionVariableType T1Type = getExpressionVariableType< T1, T2 >(), + ExpressionVariableType T2Type = getExpressionVariableType< T2, T1 >() > +struct StaticBinaryExpressionTemplate; template< typename T1, typename T2, - template< typename, typename > class Operation, + typename Operation, ExpressionVariableType T1Type, ExpressionVariableType T2Type > -struct IsExpressionTemplate< StaticBinaryExpressionTemplate< T1, T2, Operation, T1Type, T2Type > > +struct HasEnabledStaticExpressionTemplates< StaticBinaryExpressionTemplate< T1, T2, Operation, T1Type, T2Type > > : std::true_type {}; @@ -59,16 +55,20 @@ struct IsExpressionTemplate< StaticBinaryExpressionTemplate< T1, T2, Operation, // Static binary expression template template< typename T1, typename T2, - template< typename, typename > class Operation > + typename Operation > struct StaticBinaryExpressionTemplate< T1, T2, Operation, VectorExpressionVariable, VectorExpressionVariable > { - using RealType = decltype( Operation< typename T1::RealType, typename T2::RealType >:: - evaluate( std::declval<T1>()[0], std::declval<T2>()[0] ) ); + using VectorOperandType = T1; + using RealType = decltype( Operation::evaluate( std::declval<T1>()[0], std::declval<T2>()[0] ) ); static_assert( IsStaticArrayType< T1 >::value, "Left-hand side operand of static expression is not static, i.e. based on static vector." ); static_assert( IsStaticArrayType< T2 >::value, "Right-hand side operand of static expression is not static, i.e. based on static vector." ); + static_assert( HasEnabledStaticExpressionTemplates< T1 >::value, + "Invalid operand in static binary expression templates - static expression templates are not enabled for the left operand." ); + static_assert( HasEnabledStaticExpressionTemplates< T2 >::value, + "Invalid operand in static binary expression templates - static expression templates are not enabled for the right operand." ); static_assert( T1::getSize() == T2::getSize(), "Attempt to mix static operands with different sizes." ); @@ -81,7 +81,7 @@ struct StaticBinaryExpressionTemplate< T1, T2, Operation, VectorExpressionVariab __cuda_callable__ RealType operator[]( const int i ) const { - return Operation< typename T1::RealType, typename T2::RealType >::evaluate( op1[ i ], op2[ i ] ); + return Operation::evaluate( op1[ i ], op2[ i ] ); } __cuda_callable__ @@ -109,14 +109,16 @@ protected: template< typename T1, typename T2, - template< typename, typename > class Operation > + typename Operation > struct StaticBinaryExpressionTemplate< T1, T2, Operation, VectorExpressionVariable, ArithmeticVariable > { + using VectorOperandType = T1; + using RealType = decltype( Operation::evaluate( std::declval<T1>()[0], std::declval<T2>() ) ); + static_assert( IsStaticArrayType< T1 >::value, "Left-hand side operand of static expression is not static, i.e. based on static vector." ); - - using RealType = decltype( Operation< typename T1::RealType, T2 >:: - evaluate( std::declval<T1>()[0], std::declval<T2>() ) ); + static_assert( HasEnabledStaticExpressionTemplates< T1 >::value, + "Invalid operand in static binary expression templates - static expression templates are not enabled for the left operand." ); static constexpr int getSize() { return T1::getSize(); }; @@ -127,7 +129,7 @@ struct StaticBinaryExpressionTemplate< T1, T2, Operation, VectorExpressionVariab __cuda_callable__ RealType operator[]( const int i ) const { - return Operation< typename T1::RealType, T2 >::evaluate( op1[ i ], op2 ); + return Operation::evaluate( op1[ i ], op2 ); } __cuda_callable__ @@ -150,19 +152,21 @@ struct StaticBinaryExpressionTemplate< T1, T2, Operation, VectorExpressionVariab protected: const T1& op1; - const T2& op2; + const T2 op2; }; template< typename T1, typename T2, - template< typename, typename > class Operation > + typename Operation > struct StaticBinaryExpressionTemplate< T1, T2, Operation, ArithmeticVariable, VectorExpressionVariable > { + using VectorOperandType = T2; + using RealType = decltype( Operation::evaluate( std::declval<T1>(), std::declval<T2>()[0] ) ); + static_assert( IsStaticArrayType< T2 >::value, "Right-hand side operand of static expression is not static, i.e. based on static vector." ); - - using RealType = decltype( Operation< T1, typename T2::RealType >:: - evaluate( std::declval<T1>(), std::declval<T2>()[0] ) ); + static_assert( HasEnabledStaticExpressionTemplates< T2 >::value, + "Invalid operand in static binary expression templates - static expression templates are not enabled for the right operand." ); static constexpr int getSize() { return T2::getSize(); }; @@ -173,7 +177,7 @@ struct StaticBinaryExpressionTemplate< T1, T2, Operation, ArithmeticVariable, Ve __cuda_callable__ RealType operator[]( const int i ) const { - return Operation< T1, typename T2::RealType >::evaluate( op1, op2[ i ] ); + return Operation::evaluate( op1, op2[ i ] ); } __cuda_callable__ @@ -195,18 +199,23 @@ struct StaticBinaryExpressionTemplate< T1, T2, Operation, ArithmeticVariable, Ve } protected: - const T1& op1; + const T1 op1; const T2& op2; }; //// // Static unary expression template template< typename T1, - template< typename > class Operation > -struct StaticUnaryExpressionTemplate< T1, Operation, VectorExpressionVariable > + typename Operation > +struct StaticUnaryExpressionTemplate { - using RealType = decltype( Operation< typename T1::RealType >:: - evaluate( std::declval<T1>()[0] ) ); + using VectorOperandType = T1; + using RealType = decltype( Operation::evaluate( std::declval<T1>()[0] ) ); + + static_assert( IsStaticArrayType< T1 >::value, + "The operand of static expression is not static, i.e. based on static vector." ); + static_assert( HasEnabledStaticExpressionTemplates< T1 >::value, + "Invalid operand in static unary expression templates - static expression templates are not enabled for the operand." ); static constexpr int getSize() { return T1::getSize(); }; @@ -217,7 +226,7 @@ struct StaticUnaryExpressionTemplate< T1, Operation, VectorExpressionVariable > __cuda_callable__ RealType operator[]( const int i ) const { - return Operation< typename T1::RealType >::evaluate( operand[ i ] ); + return Operation::evaluate( operand[ i ] ); } __cuda_callable__ @@ -246,2043 +255,705 @@ protected: //// // Binary expressions addition -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +template< typename ET1, typename ET2, + typename..., typename = EnableIfStaticBinaryExpression_t< ET1, ET2 > > __cuda_callable__ auto -operator+( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) +operator+( const ET1& a, const ET2& b ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return StaticBinaryExpressionTemplate< ET1, ET2, Addition >( a, b ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Binary expression subtraction +template< typename ET1, typename ET2, + typename..., typename = EnableIfStaticBinaryExpression_t< ET1, ET2 > > __cuda_callable__ auto -operator+( const StaticBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +operator-( const ET1& a, const ET2& b ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return StaticBinaryExpressionTemplate< ET1, ET2, Subtraction >( a, b ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Binary expression multiplication +template< typename ET1, typename ET2, + typename..., typename = EnableIfStaticBinaryExpression_t< ET1, ET2 > > __cuda_callable__ auto -operator+( const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const StaticBinaryExpressionTemplate< T1, T2, Operation >& b ) +operator*( const ET1& a, const ET2& b ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return StaticBinaryExpressionTemplate< ET1, ET2, Multiplication >( a, b ); } -template< typename T1, - template< typename > class Operation > +//// +// Binary expression division +template< typename ET1, typename ET2, + typename..., typename = EnableIfStaticBinaryExpression_t< ET1, ET2 > > __cuda_callable__ auto -operator+( const StaticUnaryExpressionTemplate< T1, Operation >& a, - const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& b ) +operator/( const ET1& a, const ET2& b ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return StaticBinaryExpressionTemplate< ET1, ET2, Division >( a, b ); } -template< typename T1, - template< typename > class Operation > +//// +// Comparison operator == +template< typename ET1, typename ET2, + typename..., typename = EnableIfStaticBinaryExpression_t< ET1, ET2 > > __cuda_callable__ -auto -operator+( const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& a, - const StaticUnaryExpressionTemplate< T1, Operation >& b ) +bool +operator==( const ET1& a, const ET2& b ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return StaticComparison< ET1, ET2 >::EQ( a, b ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +//// +// Comparison operator != +template< typename ET1, typename ET2, + typename..., typename = EnableIfStaticBinaryExpression_t< ET1, ET2 > > __cuda_callable__ -auto -operator+( const StaticUnaryExpressionTemplate< L1, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) +bool +operator!=( const ET1& a, const ET2& b ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return StaticComparison< ET1, ET2 >::NE( a, b ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Comparison operator < +template< typename ET1, typename ET2, + typename..., typename = EnableIfStaticBinaryExpression_t< ET1, ET2 > > __cuda_callable__ -auto -operator+( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticUnaryExpressionTemplate< R1, ROperation >& b ) +bool +operator<( const ET1& a, const ET2& b ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return StaticComparison< ET1, ET2 >::LT( a, b ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Comparison operator <= +template< typename ET1, typename ET2, + typename..., typename = EnableIfStaticBinaryExpression_t< ET1, ET2 > > __cuda_callable__ -auto -operator+( const StaticUnaryExpressionTemplate< L1,LOperation >& a, - const StaticUnaryExpressionTemplate< R1,ROperation >& b ) +bool +operator<=( const ET1& a, const ET2& b ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Addition >( a, b ); + return StaticComparison< ET1, ET2 >::LE( a, b ); } //// -// Binary expression subtraction -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +// Comparison operator > +template< typename ET1, typename ET2, + typename..., typename = EnableIfStaticBinaryExpression_t< ET1, ET2 > > __cuda_callable__ -auto -operator-( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) +bool +operator>( const ET1& a, const ET2& b ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return StaticComparison< ET1, ET2 >::GT( a, b ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Comparison operator >= +template< typename ET1, typename ET2, + typename..., typename = EnableIfStaticBinaryExpression_t< ET1, ET2 > > __cuda_callable__ -auto -operator-( const StaticBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +bool +operator>=( const ET1& a, const ET2& b ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return Expressions::StaticComparison< ET1, ET2 >::GE( a, b ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Scalar product +template< typename ET1, typename ET2, + typename..., typename = EnableIfStaticBinaryExpression_t< ET1, ET2 > > __cuda_callable__ auto -operator-( const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const StaticBinaryExpressionTemplate< T1, T2, Operation >& b ) +operator,( const ET1& a, const ET2& b ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return StaticExpressionSum( a * b ); } -template< typename T1, - template< typename > class Operation > +template< typename ET1, typename ET2, + typename..., typename = EnableIfStaticBinaryExpression_t< ET1, ET2 > > __cuda_callable__ auto -operator-( const StaticUnaryExpressionTemplate< T1, Operation >& a, - const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& b ) +dot( const ET1& a, const ET2& b ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return (a, b); } -template< typename T1, - template< typename > class Operation > +//// +// Unary expression minus +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ auto -operator-( const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& a, - const StaticUnaryExpressionTemplate< T1, Operation >& b ) +operator-( const ET1& a ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return StaticUnaryExpressionTemplate< ET1, Minus >( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +//// +// Binary expression min +template< typename ET1, typename ET2, + typename..., typename = EnableIfStaticBinaryExpression_t< ET1, ET2 > > __cuda_callable__ auto -operator-( const StaticUnaryExpressionTemplate< L1, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) +min( const ET1& a, const ET2& b ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return StaticBinaryExpressionTemplate< ET1, ET2, Min >( a, b ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Binary expression max +template< typename ET1, typename ET2, + typename..., typename = EnableIfStaticBinaryExpression_t< ET1, ET2 > > __cuda_callable__ auto -operator-( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticUnaryExpressionTemplate< R1,ROperation >& b ) +max( const ET1& a, const ET2& b ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return StaticBinaryExpressionTemplate< ET1, ET2, Max >( a, b ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Abs +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ auto -operator-( const StaticUnaryExpressionTemplate< L1,LOperation >& a, - const StaticUnaryExpressionTemplate< R1,ROperation >& b ) +abs( const ET1& a ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Subtraction >( a, b ); + return StaticUnaryExpressionTemplate< ET1, Abs >( a ); } //// -// Binary expression multiplication -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +// Pow +template< typename ET1, typename Real, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ auto -operator*( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) +pow( const ET1& a, const Real& exp ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return StaticBinaryExpressionTemplate< ET1, Real, Pow >( a, exp ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Exp +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ auto -operator*( const StaticBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +exp( const ET1& a ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return StaticUnaryExpressionTemplate< ET1, Exp >( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Sqrt +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ auto -operator*( const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const StaticBinaryExpressionTemplate< T1, T2, Operation >& b ) +sqrt( const ET1& a ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return StaticUnaryExpressionTemplate< ET1, Sqrt >( a ); } -template< typename T1, - template< typename > class Operation > +//// +// Cbrt +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ auto -operator*( const StaticUnaryExpressionTemplate< T1, Operation >& a, - const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& b ) +cbrt( const ET1& a ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return StaticUnaryExpressionTemplate< ET1, Cbrt >( a ); } -template< typename T1, - template< typename > class Operation > +//// +// Log +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ auto -operator*( const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& a, - const StaticUnaryExpressionTemplate< T1, Operation >& b ) +log( const ET1& a ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return StaticUnaryExpressionTemplate< ET1, Log >( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +//// +// Log10 +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ auto -operator*( const StaticUnaryExpressionTemplate< L1, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) +log10( const ET1& a ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return StaticUnaryExpressionTemplate< ET1, Log10 >( a ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Log2 +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ auto -operator*( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticUnaryExpressionTemplate< R1, ROperation >& b ) +log2( const ET1& a ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return StaticUnaryExpressionTemplate< ET1, Log2 >( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Sin +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ auto -operator*( const StaticUnaryExpressionTemplate< L1,LOperation >& a, - const StaticUnaryExpressionTemplate< R1,ROperation >& b ) +sin( const ET1& a ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Multiplication >( a, b ); + return StaticUnaryExpressionTemplate< ET1, Sin >( a ); } //// -// Binary expression division -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +// Cos +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ auto -operator/( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) +cos( const ET1& a ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return StaticUnaryExpressionTemplate< ET1, Cos >( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Tan +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ auto -operator/( const StaticBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +tan( const ET1& a ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return StaticUnaryExpressionTemplate< ET1, Tan >( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Asin +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ auto -operator/( const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const StaticBinaryExpressionTemplate< T1, T2, Operation >& b ) +asin( const ET1& a ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return StaticUnaryExpressionTemplate< ET1, Asin >( a ); } -template< typename T1, - template< typename > class Operation > +//// +// Acos +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ auto -operator/( const StaticUnaryExpressionTemplate< T1, Operation >& a, - const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& b ) +acos( const ET1& a ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return StaticUnaryExpressionTemplate< ET1, Acos >( a ); } -template< typename T1, - template< typename > class Operation > +//// +// Atan +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ auto -operator/( const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& a, - const StaticUnaryExpressionTemplate< T1, Operation >& b ) +atan( const ET1& a ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return StaticUnaryExpressionTemplate< ET1, Atan >( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +//// +// Sinh +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ auto -operator/( const StaticUnaryExpressionTemplate< L1, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) +sinh( const ET1& a ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return StaticUnaryExpressionTemplate< ET1, Sinh >( a ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Cosh +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ auto -operator/( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticUnaryExpressionTemplate< R1,ROperation >& b ) +cosh( const ET1& a ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return StaticUnaryExpressionTemplate< ET1, Cosh >( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Tanh +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ auto -operator/( const StaticUnaryExpressionTemplate< L1,LOperation >& a, - const StaticUnaryExpressionTemplate< R1,ROperation >& b ) +tanh( const ET1& a ) { - return StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Division >( a, b ); + return StaticUnaryExpressionTemplate< ET1, Tanh >( a ); } //// -// Comparison operator == -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -__cuda_callable__ -bool -operator==( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > +// Asinh +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator==( const StaticBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +auto +asinh( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); + return StaticUnaryExpressionTemplate< ET1, Asinh >( a ); } -template< typename T1, - template< typename > class Operation > +//// +// Acosh +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator==( const StaticUnaryExpressionTemplate< T1, Operation >& a, - const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& b ) +auto +acosh( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); + return StaticUnaryExpressionTemplate< ET1, Acosh >( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Atanh +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator==( const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const StaticBinaryExpressionTemplate< T1, T2, Operation >& b ) +auto +atanh( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); + return StaticUnaryExpressionTemplate< ET1, Atanh >( a ); } -template< typename T1, - template< typename > class Operation > +//// +// Floor +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator==( const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& a, - const StaticUnaryExpressionTemplate< T1, Operation >& b ) +auto +floor( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); + return StaticUnaryExpressionTemplate< ET1, Floor >( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +//// +// Ceil +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator==( const StaticUnaryExpressionTemplate< L1, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) +auto +ceil( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); + return StaticUnaryExpressionTemplate< ET1, Ceil >( a ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > +//// +// Sign +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator==( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticUnaryExpressionTemplate< R1,ROperation >& b ) +auto +sign( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::EQ( a, b ); + return StaticUnaryExpressionTemplate< ET1, Sign >( a ); } //// -// Comparison operator != -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +// Cast +template< typename ResultType, + typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 >, + // workaround: templated type alias cannot be declared at block level + typename CastOperation = typename Cast< ResultType >::Operation > __cuda_callable__ -bool -operator!=( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) +auto +cast( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return StaticUnaryExpressionTemplate< ET1, CastOperation >( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +//// +// Vertical operations +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator!=( const StaticBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +auto +min( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return StaticExpressionMin( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator!=( const StaticUnaryExpressionTemplate< L1, LOperation >& a, - const StaticUnaryExpressionTemplate< R1, ROperation >& b ) +auto +argMin( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return StaticExpressionArgMin( a ); } -template< typename T1, - template< typename > class Operation > +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator!=( const StaticUnaryExpressionTemplate< T1, Operation >& a, - const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& b ) +auto +max( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return StaticExpressionMax( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator!=( const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const StaticBinaryExpressionTemplate< T1, T2, Operation >& b ) +auto +argMax( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return StaticExpressionArgMax( a ); } -template< typename T1, - template< typename > class Operation > +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator!=( const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& a, - const StaticUnaryExpressionTemplate< T1, Operation >& b ) +auto +sum( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return StaticExpressionSum( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator!=( const StaticUnaryExpressionTemplate< L1, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) +auto +maxNorm( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return max( abs( a ) ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator!=( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticUnaryExpressionTemplate< R1,ROperation >& b ) +auto +l1Norm( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::NE( a, b ); + return sum( abs( a ) ); } -//// -// Comparison operator < -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator<( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) +auto +l2Norm( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + using TNL::sqrt; + return sqrt( sum( a * a ) ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +template< typename ET1, + typename Real, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator<( const StaticBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) +auto +lpNorm( const ET1& a, const Real& p ) +// since (1.0 / p) has type double, TNL::pow returns double +-> double +//-> RemoveET< decltype(pow( StaticExpressionLpNorm( a, p ), 1.0 / p )) > { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + if( p == 1.0 ) + return l1Norm( a ); + if( p == 2.0 ) + return l2Norm( a ); + using TNL::pow; + return pow( sum( pow( abs( a ), p ) ), 1.0 / p ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator<( const StaticUnaryExpressionTemplate< L1, LOperation >& a, - const StaticUnaryExpressionTemplate< R1, ROperation >& b ) +auto +product( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + return StaticExpressionProduct( a ); } -template< typename T1, - template< typename > class Operation > +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator<( const StaticUnaryExpressionTemplate< T1, Operation >& a, - const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& b ) +auto +logicalAnd( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + return StaticExpressionLogicalAnd( a ); } -template< typename T1, - typename T2, - template< typename, typename > class Operation > +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator<( const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const StaticBinaryExpressionTemplate< T1, T2, Operation >& b ) +auto +logicalOr( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + return StaticExpressionLogicalOr( a ); } -template< typename T1, - template< typename > class Operation > +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator<( const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& a, - const StaticUnaryExpressionTemplate< T1, Operation >& b ) +auto +binaryAnd( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + return StaticExpressionBinaryAnd( a ); } -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > +template< typename ET1, + typename..., typename = EnableIfStaticUnaryExpression_t< ET1 > > __cuda_callable__ -bool -operator<( const StaticUnaryExpressionTemplate< L1, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) +auto +binaryOr( const ET1& a ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); + return StaticExpressionBinaryOr( a ); } -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -__cuda_callable__ -bool -operator<( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticUnaryExpressionTemplate< R1,ROperation >& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LT( a, b ); -} +#endif // DOXYGEN_ONLY //// -// Comparison operator <= -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -__cuda_callable__ -bool -operator<=( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - +// Output stream template< typename T1, typename T2, - template< typename, typename > class Operation > -__cuda_callable__ -bool -operator<=( const StaticBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) + typename Operation > +std::ostream& operator<<( std::ostream& str, const StaticBinaryExpressionTemplate< T1, T2, Operation >& expression ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); + str << "[ "; + for( int i = 0; i < expression.getSize() - 1; i++ ) + str << expression[ i ] << ", "; + str << expression[ expression.getSize() - 1 ] << " ]"; + return str; } -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -__cuda_callable__ -bool -operator<=( const StaticUnaryExpressionTemplate< L1, LOperation >& a, - const StaticUnaryExpressionTemplate< R1, ROperation >& b ) +template< typename T, + typename Operation > +std::ostream& operator<<( std::ostream& str, const StaticUnaryExpressionTemplate< T, Operation >& expression ) { - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); + str << "[ "; + for( int i = 0; i < expression.getSize() - 1; i++ ) + str << expression[ i ] << ", "; + str << expression[ expression.getSize() - 1 ] << " ]"; + return str; } -template< typename T1, - template< typename > class Operation > -__cuda_callable__ -bool -operator<=( const StaticUnaryExpressionTemplate< T1, Operation >& a, - const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} +} // namespace Expressions -template< typename T1, - typename T2, - template< typename, typename > class Operation > -__cuda_callable__ -bool -operator<=( const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const StaticBinaryExpressionTemplate< T1, T2, Operation >& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} +// Make all operators visible in the TNL::Containers namespace to be considered +// even for StaticVector +using Expressions::operator+; +using Expressions::operator-; +using Expressions::operator*; +using Expressions::operator/; +using Expressions::operator,; +using Expressions::operator==; +using Expressions::operator!=; +using Expressions::operator<; +using Expressions::operator<=; +using Expressions::operator>; +using Expressions::operator>=; + +// Make all functions visible in the TNL::Containers namespace +using Expressions::dot; +using Expressions::min; +using Expressions::max; +using Expressions::abs; +using Expressions::pow; +using Expressions::exp; +using Expressions::sqrt; +using Expressions::cbrt; +using Expressions::log; +using Expressions::log10; +using Expressions::log2; +using Expressions::sin; +using Expressions::cos; +using Expressions::tan; +using Expressions::asin; +using Expressions::acos; +using Expressions::atan; +using Expressions::sinh; +using Expressions::cosh; +using Expressions::tanh; +using Expressions::asinh; +using Expressions::acosh; +using Expressions::atanh; +using Expressions::floor; +using Expressions::ceil; +using Expressions::sign; +using Expressions::cast; +using Expressions::argMin; +using Expressions::argMax; +using Expressions::sum; +using Expressions::maxNorm; +using Expressions::l1Norm; +using Expressions::l2Norm; +using Expressions::lpNorm; +using Expressions::product; +using Expressions::logicalAnd; +using Expressions::logicalOr; +using Expressions::binaryAnd; +using Expressions::binaryOr; -template< typename T1, - template< typename > class Operation > -__cuda_callable__ -bool -operator<=( const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& a, - const StaticUnaryExpressionTemplate< T1, Operation >& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} +} // namespace Containers -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -__cuda_callable__ -bool -operator<=( const StaticUnaryExpressionTemplate< L1, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -__cuda_callable__ -bool -operator<=( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticUnaryExpressionTemplate< R1,ROperation >& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::LE( a, b ); -} - -//// -// Comparison operator > -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -__cuda_callable__ -bool -operator>( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -__cuda_callable__ -bool -operator>( const StaticBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename T1, - template< typename > class Operation > -__cuda_callable__ -bool -operator>( const StaticUnaryExpressionTemplate< T1, Operation >& a, - const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -__cuda_callable__ -bool -operator>( const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const StaticBinaryExpressionTemplate< T1, T2, Operation >& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename T1, - template< typename > class Operation > -__cuda_callable__ -bool -operator>( const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& a, - const StaticUnaryExpressionTemplate< T1, Operation >& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -__cuda_callable__ -bool -operator>( const StaticUnaryExpressionTemplate< L1, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -__cuda_callable__ -bool -operator>( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticUnaryExpressionTemplate< R1,ROperation >& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GT( a, b ); -} - -//// -// Comparison operator >= -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -__cuda_callable__ -bool -operator>=( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -__cuda_callable__ -bool -operator>=( const StaticBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename T1, - template< typename > class Operation > -__cuda_callable__ -bool -operator>=( const StaticUnaryExpressionTemplate< T1, Operation >& a, - const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -__cuda_callable__ -bool -operator>=( const typename StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const StaticBinaryExpressionTemplate< T1, T2, Operation >& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename T1, - template< typename > class Operation > -__cuda_callable__ -bool -operator>=( const typename StaticUnaryExpressionTemplate< T1, Operation >::RealType& a, - const StaticUnaryExpressionTemplate< T1, Operation >& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -__cuda_callable__ -bool -operator>=( const StaticUnaryExpressionTemplate< L1, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -__cuda_callable__ -bool -operator>=( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticUnaryExpressionTemplate< R1,ROperation >& b ) -{ - return StaticComparison< std::decay_t<decltype(a)>, std::decay_t<decltype(b)> >::GE( a, b ); -} - -//// -// Unary operations - -//// -// Minus -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -operator-( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Minus >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -operator-( const StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Minus >( a ); -} - -//// -// Scalar product -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -__cuda_callable__ -auto -operator,( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return StaticExpressionSum( a * b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -__cuda_callable__ -auto -operator,( const StaticUnaryExpressionTemplate< L1, LOperation >& a, - const StaticUnaryExpressionTemplate< R1, ROperation >& b ) -{ - return StaticExpressionSum( a * b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -__cuda_callable__ -auto -operator,( const StaticUnaryExpressionTemplate< L1, LOperation >& a, - const StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return StaticExpressionSum( a * b ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -__cuda_callable__ -auto -operator,( const StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const StaticUnaryExpressionTemplate< R1,ROperation >& b ) -{ - return StaticExpressionSum( a * b ); -} - -#endif // DOXYGEN_ONLY - -//// -// Output stream -template< typename T1, - typename T2, - template< typename, typename > class Operation > -std::ostream& operator<<( std::ostream& str, const StaticBinaryExpressionTemplate< T1, T2, Operation >& expression ) -{ - str << "[ "; - for( int i = 0; i < expression.getSize() - 1; i++ ) - str << expression[ i ] << ", "; - str << expression[ expression.getSize() - 1 ] << " ]"; - return str; -} - -template< typename T, - template< typename > class Operation > -std::ostream& operator<<( std::ostream& str, const StaticUnaryExpressionTemplate< T, Operation >& expression ) -{ - str << "[ "; - for( int i = 0; i < expression.getSize() - 1; i++ ) - str << expression[ i ] << ", "; - str << expression[ expression.getSize() - 1 ] << " ]"; - return str; -} - -} // namespace Expressions -} // namespace Containers - -//// -// All operations are supposed to be in namespace TNL - -#ifndef DOXYGEN_ONLY - -//// -// Binary expression min -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -__cuda_callable__ -auto -min( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const Containers::Expressions::StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -__cuda_callable__ -auto -min( const Containers::Expressions::StaticBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename Containers::Expressions::StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -__cuda_callable__ -auto -min( const typename Containers::Expressions::StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const Containers::Expressions::StaticBinaryExpressionTemplate< T1, T2, Operation >& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename T1, - template< typename > class Operation > -__cuda_callable__ -auto -min( const Containers::Expressions::StaticUnaryExpressionTemplate< T1, Operation >& a, - const typename Containers::Expressions::StaticUnaryExpressionTemplate< T1, Operation >::RealType& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename T1, - template< typename > class Operation > -__cuda_callable__ -auto -min( const typename Containers::Expressions::StaticUnaryExpressionTemplate< T1, Operation >::RealType& a, - const Containers::Expressions::StaticUnaryExpressionTemplate< T1, Operation >& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -__cuda_callable__ -auto -min( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a, - const Containers::Expressions::StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -__cuda_callable__ -auto -min( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const Containers::Expressions::StaticUnaryExpressionTemplate< R1,ROperation >& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -__cuda_callable__ -auto -min( const Containers::Expressions::StaticUnaryExpressionTemplate< L1,LOperation >& a, - const Containers::Expressions::StaticUnaryExpressionTemplate< R1,ROperation >& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Min >( a, b ); -} - -//// -// Binary expression max -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -__cuda_callable__ -auto -max( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const Containers::Expressions::StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -__cuda_callable__ -auto -max( const Containers::Expressions::StaticBinaryExpressionTemplate< T1, T2, Operation >& a, - const typename Containers::Expressions::StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename T1, - typename T2, - template< typename, typename > class Operation > -__cuda_callable__ -auto -max( const typename Containers::Expressions::StaticBinaryExpressionTemplate< T1, T2, Operation >::RealType& a, - const Containers::Expressions::StaticBinaryExpressionTemplate< T1, T2, Operation >& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename T1, - template< typename > class Operation > -__cuda_callable__ -auto -max( const Containers::Expressions::StaticUnaryExpressionTemplate< T1, Operation >& a, - const typename Containers::Expressions::StaticUnaryExpressionTemplate< T1, Operation >::RealType& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename T1, - template< typename > class Operation > -__cuda_callable__ -auto -max( const typename Containers::Expressions::StaticUnaryExpressionTemplate< T1, Operation >::RealType& a, - const Containers::Expressions::StaticUnaryExpressionTemplate< T1, Operation >& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -__cuda_callable__ -auto -max( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a, - const Containers::Expressions::StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -__cuda_callable__ -auto -max( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const Containers::Expressions::StaticUnaryExpressionTemplate< R1,ROperation >& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -__cuda_callable__ -auto -max( const Containers::Expressions::StaticUnaryExpressionTemplate< L1,LOperation >& a, - const Containers::Expressions::StaticUnaryExpressionTemplate< R1,ROperation >& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, std::decay_t<decltype(b)>, Containers::Expressions::Max >( a, b ); -} - -//// -// Abs -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -abs( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Abs >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -abs( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Abs >( a ); -} - -//// -// Pow -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename Real > -__cuda_callable__ -auto -pow( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, const Real& exp ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, Real, Containers::Expressions::Pow >( a, exp ); -} - -template< typename L1, - template< typename > class LOperation, - typename Real > -__cuda_callable__ -auto -pow( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a, const Real& exp ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< std::decay_t<decltype(a)>, Real, Containers::Expressions::Pow >( a, exp ); -} - -//// -// Exp -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -exp( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Exp >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -exp( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Exp >( a ); -} - -//// -// Sqrt -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -sqrt( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sqrt >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -sqrt( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sqrt >( a ); -} - -//// -// Cbrt -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -cbrt( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cbrt >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -cbrt( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cbrt >( a ); -} - -//// -// Log -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -log( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -log( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log >( a ); -} - -//// -// Log10 -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -log10( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log10 >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -log10( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log10 >( a ); -} - -//// -// Log2 -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -log2( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log2 >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -log2( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Log2 >( a ); -} - -//// -// Sin -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -sin( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sin >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -sin( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sin >( a ); -} - -//// -// Cos -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -cos( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cos >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -cos( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cos >( a ); -} - -//// -// Tan -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -tan( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Tan >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -tan( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Tan >( a ); -} - -//// -// Asin -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -asin( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Asin >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -asin( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Asin >( a ); -} - -//// -// Acos -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -acos( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Acos >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -acos( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Acos >( a ); -} - -//// -// Atan -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -atan( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Atan >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -atan( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Atan >( a ); -} - -//// -// Sinh -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -sinh( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sinh >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -sinh( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sinh >( a ); -} - -//// -// Cosh -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -cosh( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cosh >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -cosh( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Cosh >( a ); -} - -//// -// Tanh -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -tanh( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Tanh >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -tanh( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Tanh >( a ); -} - -//// -// Asinh -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -asinh( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Asinh >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -asinh( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Asinh >( a ); -} - -//// -// Acosh -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -acosh( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Acosh >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -acosh( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Acosh >( a ); -} - -//// -// Atanh -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -atanh( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Atanh >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -atanh( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Atanh >( a ); -} - -//// -// Floor -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -floor( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Floor >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -floor( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Floor >( a ); -} - -//// -// Ceil -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -ceil( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Ceil >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -ceil( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Ceil >( a ); -} - -//// -// Sign -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -sign( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sign >( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -sign( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Containers::Expressions::Sign >( a ); -} - -//// -// Cast -template< typename ResultType, - typename L1, - typename L2, - template< typename, typename > class LOperation, - // workaround: templated type alias cannot be declared at block level - template<typename> class CastOperation = Containers::Expressions::Cast< ResultType >::template Operation > -__cuda_callable__ -auto -cast( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, CastOperation >( a ); -} - -template< typename ResultType, - typename L1, - template< typename > class LOperation, - // workaround: templated type alias cannot be declared at block level - template<typename> class CastOperation = Containers::Expressions::Cast< ResultType >::template Operation > -__cuda_callable__ -auto -cast( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, CastOperation >( a ); -} - -//// -// Vertical operations - min -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -min( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return StaticExpressionMin( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -min( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return StaticExpressionMin( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -argMin( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return StaticExpressionArgMin( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -argMin( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return StaticExpressionArgMin( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -max( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return StaticExpressionMax( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -max( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return StaticExpressionMax( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -argMax( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return StaticExpressionArgMax( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -argMax( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return StaticExpressionArgMax( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -sum( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return StaticExpressionSum( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -sum( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return StaticExpressionSum( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -maxNorm( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return max( abs( a ) ); -} - -template< typename L1, - template< typename > class LOperation > -auto -maxNorm( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return max( abs( a ) ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -l1Norm( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return StaticExpressionL1Norm( a ); -} - -template< typename L1, - template< typename > class LOperation > -auto -l1Norm( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return StaticExpressionL1Norm( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -auto -l2Norm( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return TNL::sqrt( StaticExpressionL2Norm( a ) ); -} - -template< typename L1, - template< typename > class LOperation > -auto -l2Norm( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return TNL::sqrt( StaticExpressionL2Norm( a ) ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename Real > -__cuda_callable__ -auto -lpNorm( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, const Real& p ) -// since (1.0 / p) has type double, TNL::pow returns double --> double -{ - if( p == 1.0 ) - return l1Norm( a ); - if( p == 2.0 ) - return l2Norm( a ); - return TNL::pow( StaticExpressionLpNorm( a, p ), 1.0 / p ); -} - -template< typename L1, - template< typename > class LOperation, - typename Real > -__cuda_callable__ -auto -lpNorm( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a, const Real& p ) -// since (1.0 / p) has type double, TNL::pow returns double --> double -{ - if( p == 1.0 ) - return l1Norm( a ); - if( p == 2.0 ) - return l2Norm( a ); - return TNL::pow( StaticExpressionLpNorm( a, p ), 1.0 / p ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -product( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return StaticExpressionProduct( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -product( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return StaticExpressionProduct( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -logicalOr( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return StaticExpressionLogicalOr( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -logicalOr( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return StaticExpressionLogicalOr( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation > -__cuda_callable__ -auto -binaryOr( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a ) -{ - return StaticExpressionBinaryOr( a ); -} - -template< typename L1, - template< typename > class LOperation > -__cuda_callable__ -auto -binaryOr( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a ) -{ - return StaticExpressionBinaryOr( a ); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -__cuda_callable__ -auto -dot( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const Containers::Expressions::StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return (a, b); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - template< typename > class ROperation > -__cuda_callable__ -auto -dot( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a, - const Containers::Expressions::StaticUnaryExpressionTemplate< R1, ROperation >& b ) -{ - return (a, b); -} - -template< typename L1, - template< typename > class LOperation, - typename R1, - typename R2, - template< typename, typename > class ROperation > -__cuda_callable__ -auto -dot( const Containers::Expressions::StaticUnaryExpressionTemplate< L1, LOperation >& a, - const Containers::Expressions::StaticBinaryExpressionTemplate< R1, R2, ROperation >& b ) -{ - return (a, b); -} - -template< typename L1, - typename L2, - template< typename, typename > class LOperation, - typename R1, - template< typename > class ROperation > -__cuda_callable__ -auto -dot( const Containers::Expressions::StaticBinaryExpressionTemplate< L1, L2, LOperation >& a, - const Containers::Expressions::StaticUnaryExpressionTemplate< R1,ROperation >& b ) -{ - return (a, b); -} - -#endif // DOXYGEN_ONLY +// Make all functions visible in the main TNL namespace +using Containers::dot; +using Containers::min; +using Containers::max; +using Containers::abs; +using Containers::pow; +using Containers::exp; +using Containers::sqrt; +using Containers::cbrt; +using Containers::log; +using Containers::log10; +using Containers::log2; +using Containers::sin; +using Containers::cos; +using Containers::tan; +using Containers::asin; +using Containers::acos; +using Containers::atan; +using Containers::sinh; +using Containers::cosh; +using Containers::tanh; +using Containers::asinh; +using Containers::acosh; +using Containers::atanh; +using Containers::floor; +using Containers::ceil; +using Containers::sign; +using Containers::cast; +using Containers::argMin; +using Containers::argMax; +using Containers::sum; +using Containers::maxNorm; +using Containers::l1Norm; +using Containers::l2Norm; +using Containers::lpNorm; +using Containers::product; +using Containers::logicalAnd; +using Containers::logicalOr; +using Containers::binaryAnd; +using Containers::binaryOr; //// // Evaluation with reduction template< typename Vector, typename T1, typename T2, - template< typename, typename > class Operation, + typename Operation, typename Reduction, typename Result > __cuda_callable__ @@ -2299,7 +970,7 @@ Result evaluateAndReduce( Vector& lhs, template< typename Vector, typename T1, - template< typename > class Operation, + typename Operation, typename Reduction, typename Result > __cuda_callable__ @@ -2319,7 +990,7 @@ Result evaluateAndReduce( Vector& lhs, template< typename Vector, typename T1, typename T2, - template< typename, typename > class Operation, + typename Operation, typename Reduction, typename Result > __cuda_callable__ @@ -2339,7 +1010,7 @@ Result addAndReduce( Vector& lhs, template< typename Vector, typename T1, - template< typename > class Operation, + typename Operation, typename Reduction, typename Result > __cuda_callable__ @@ -2362,7 +1033,7 @@ Result addAndReduce( Vector& lhs, template< typename Vector, typename T1, typename T2, - template< typename, typename > class Operation, + typename Operation, typename Reduction, typename Result > __cuda_callable__ @@ -2382,7 +1053,7 @@ Result addAndReduceAbs( Vector& lhs, template< typename Vector, typename T1, - template< typename > class Operation, + typename Operation, typename Reduction, typename Result > __cuda_callable__ diff --git a/src/TNL/Containers/Expressions/StaticVerticalOperations.h b/src/TNL/Containers/Expressions/StaticVerticalOperations.h index 7c8477f4d8068373ce99b0366192d15bc1ea6b03..7deec166d95b6f05e6ac50c8d1e1494dfd2b5e97 100644 --- a/src/TNL/Containers/Expressions/StaticVerticalOperations.h +++ b/src/TNL/Containers/Expressions/StaticVerticalOperations.h @@ -11,6 +11,7 @@ #pragma once #include <TNL/Math.h> +#include <TNL/Containers/Expressions/TypeTraits.h> //// // By vertical operations we mean those applied across vector elements or @@ -24,9 +25,10 @@ template< typename Expression > __cuda_callable__ auto StaticExpressionMin( const Expression& expression ) { - auto aux = expression[ 0 ]; + using ResultType = RemoveET< typename Expression::RealType >; + ResultType aux = expression[ 0 ]; for( int i = 1; i < expression.getSize(); i++ ) - aux = TNL::min( aux, expression[ i ] ); + aux = min( aux, expression[ i ] ); return aux; } @@ -34,8 +36,9 @@ template< typename Expression > __cuda_callable__ auto StaticExpressionArgMin( const Expression& expression ) { + using ResultType = RemoveET< typename Expression::RealType >; int arg = 0; - auto value = expression[ 0 ]; + ResultType value = expression[ 0 ]; for( int i = 1; i < expression.getSize(); i++ ) { if( expression[ i ] < value ) @@ -51,9 +54,10 @@ template< typename Expression > __cuda_callable__ auto StaticExpressionMax( const Expression& expression ) { - auto aux = expression[ 0 ]; + using ResultType = RemoveET< typename Expression::RealType >; + ResultType aux = expression[ 0 ]; for( int i = 1; i < expression.getSize(); i++ ) - aux = TNL::max( aux, expression[ i ] ); + aux = max( aux, expression[ i ] ); return aux; } @@ -61,8 +65,9 @@ template< typename Expression > __cuda_callable__ auto StaticExpressionArgMax( const Expression& expression ) { + using ResultType = RemoveET< typename Expression::RealType >; int arg = 0; - auto value = expression[ 0 ]; + ResultType value = expression[ 0 ]; for( int i = 1; i < expression.getSize(); i++ ) { if( expression[ i ] > value ) @@ -78,47 +83,19 @@ template< typename Expression > __cuda_callable__ auto StaticExpressionSum( const Expression& expression ) { - auto aux = expression[ 0 ]; + using ResultType = RemoveET< typename Expression::RealType >; + ResultType aux = expression[ 0 ]; for( int i = 1; i < expression.getSize(); i++ ) aux += expression[ i ]; return aux; } -template< typename Expression > -__cuda_callable__ -auto StaticExpressionL1Norm( const Expression& expression ) -{ - auto aux = TNL::abs( expression[ 0 ] ); - for( int i = 1; i < expression.getSize(); i++ ) - aux += TNL::abs( expression[ i ] ); - return aux; -} - -template< typename Expression > -__cuda_callable__ -auto StaticExpressionL2Norm( const Expression& expression ) -{ - auto aux = expression[ 0 ] * expression[ 0 ]; - for( int i = 1; i < expression.getSize(); i++ ) - aux += expression[ i ] * expression[ i ]; - return aux; -} - -template< typename Expression, typename Real > -__cuda_callable__ -auto StaticExpressionLpNorm( const Expression& expression, const Real& p ) -{ - auto aux = TNL::pow( TNL::abs( expression[ 0 ] ), p ); - for( int i = 1; i < expression.getSize(); i++ ) - aux += TNL::pow( TNL::abs( expression[ i ] ), p ); - return aux; -} - template< typename Expression > __cuda_callable__ auto StaticExpressionProduct( const Expression& expression ) { - auto aux = expression[ 0 ]; + using ResultType = RemoveET< typename Expression::RealType >; + ResultType aux = expression[ 0 ]; for( int i = 1; i < expression.getSize(); i++ ) aux *= expression[ i ]; return aux; diff --git a/src/TNL/Containers/Expressions/TypeTraits.h b/src/TNL/Containers/Expressions/TypeTraits.h index 606bb337aeb3438fdce861b54e949376652b8616..1024bb4653ecd28aa577494395520991c50f7e42 100644 --- a/src/TNL/Containers/Expressions/TypeTraits.h +++ b/src/TNL/Containers/Expressions/TypeTraits.h @@ -10,23 +10,115 @@ #pragma once -#include <type_traits> +#include <TNL/TypeTraits.h> namespace TNL { namespace Containers { namespace Expressions { +// trait classes used for the enabling of expression templates template< typename T > -struct IsExpressionTemplate : std::false_type +struct HasEnabledExpressionTemplates : std::false_type {}; template< typename T > -struct IsNumericExpression -: std::integral_constant< bool, - std::is_arithmetic< T >::value || - IsExpressionTemplate< T >::value > +struct HasEnabledStaticExpressionTemplates : std::false_type {}; +template< typename T > +struct HasEnabledDistributedExpressionTemplates : std::false_type +{}; + + +// type aliases for enabling specific operators and functions using SFINAE +template< typename ET1 > +using EnableIfStaticUnaryExpression_t = std::enable_if_t< + HasEnabledStaticExpressionTemplates< ET1 >::value >; + +template< typename ET1, typename ET2 > +using EnableIfStaticBinaryExpression_t = std::enable_if_t< + HasEnabledStaticExpressionTemplates< ET1 >::value || + HasEnabledStaticExpressionTemplates< ET2 >::value >; + +template< typename ET1 > +using EnableIfUnaryExpression_t = std::enable_if_t< + HasEnabledExpressionTemplates< ET1 >::value >; + +template< typename ET1, typename ET2 > +using EnableIfBinaryExpression_t = std::enable_if_t< + // we need to avoid ambiguity with operators defined in Array (e.g. Array::operator==) + // so the first operand must not be Array + ( + HasAddAssignmentOperator< ET1 >::value || + HasEnabledExpressionTemplates< ET1 >::value || + std::is_arithmetic< ET1 >::value + ) && + ( + HasEnabledExpressionTemplates< ET2 >::value || + HasEnabledExpressionTemplates< ET1 >::value + ) >; + +template< typename ET1 > +using EnableIfDistributedUnaryExpression_t = std::enable_if_t< + HasEnabledDistributedExpressionTemplates< ET1 >::value >; + +template< typename ET1, typename ET2 > +using EnableIfDistributedBinaryExpression_t = std::enable_if_t< + // we need to avoid ambiguity with operators defined in Array (e.g. Array::operator==) + // so the first operand must not be Array + ( + HasAddAssignmentOperator< ET1 >::value || + HasEnabledDistributedExpressionTemplates< ET1 >::value || + std::is_arithmetic< ET1 >::value + ) && + ( + HasEnabledDistributedExpressionTemplates< ET2 >::value || + HasEnabledDistributedExpressionTemplates< ET1 >::value + ) >; + + +// helper trait class for proper classification of expression operands using getExpressionVariableType +template< typename T, typename V, + bool enabled = IsVectorType< V >::value > +struct IsArithmeticSubtype +: public std::integral_constant< bool, + // TODO: use std::is_assignable? + std::is_same< T, typename V::RealType >::value > +{}; + +template< typename T > +struct IsArithmeticSubtype< T, T, true > +: public std::false_type +{}; + +template< typename T > +struct IsArithmeticSubtype< T, T, false > +: public std::false_type +{}; + +template< typename T, typename V > +struct IsArithmeticSubtype< T, V, false > +: public std::is_arithmetic< T > +{}; + + +// helper trait class (used in unit tests) +template< typename R, bool enabled = ! HasEnabledStaticExpressionTemplates< R >::value > +struct RemoveExpressionTemplate +{ + using type = R; +}; + +template< typename R > +struct RemoveExpressionTemplate< R, false > +{ +// using type = StaticVector< R::getSize(), typename RemoveExpressionTemplate< typename R::RealType >::type >; + using type = typename RemoveExpressionTemplate< typename R::VectorOperandType >::type; +}; + +template< typename R > +using RemoveET = typename RemoveExpressionTemplate< R >::type; + } // namespace Expressions } // namespace Containers } // namespace TNL diff --git a/src/TNL/Containers/Expressions/VerticalOperations.h b/src/TNL/Containers/Expressions/VerticalOperations.h index 84d362e8aab01b704cdefac44ae0d7e0e6a7150d..f9e184e03a326b99853136e2e6e74c0916588ed8 100644 --- a/src/TNL/Containers/Expressions/VerticalOperations.h +++ b/src/TNL/Containers/Expressions/VerticalOperations.h @@ -31,7 +31,8 @@ auto ExpressionMin( const Expression& expression ) -> std::decay_t< decltype( ex using ResultType = std::decay_t< decltype( expression[0] ) >; using IndexType = typename Expression::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) { return expression[ i ]; }; + const auto view = expression.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) { return view[ i ]; }; auto reduction = [] __cuda_callable__ ( const ResultType& a, const ResultType& b ) { return TNL::min( a, b ); }; return Algorithms::Reduction< typename Expression::DeviceType >::reduce( expression.getSize(), reduction, fetch, std::numeric_limits< ResultType >::max() ); } @@ -43,7 +44,8 @@ auto ExpressionArgMin( const Expression& expression ) using ResultType = std::decay_t< decltype( expression[0] ) >; using IndexType = typename Expression::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) { return expression[ i ]; }; + const auto view = expression.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) { return view[ i ]; }; auto reduction = [] __cuda_callable__ ( IndexType& aIdx, const IndexType& bIdx, ResultType& a, const ResultType& b ) { if( a > b ) { a = b; @@ -61,7 +63,8 @@ auto ExpressionMax( const Expression& expression ) -> std::decay_t< decltype( ex using ResultType = std::decay_t< decltype( expression[0] ) >; using IndexType = typename Expression::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) { return expression[ i ]; }; + const auto view = expression.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) { return view[ i ]; }; auto reduction = [] __cuda_callable__ ( const ResultType& a, const ResultType& b ) { return TNL::max( a, b ); }; return Algorithms::Reduction< typename Expression::DeviceType >::reduce( expression.getSize(), reduction, fetch, std::numeric_limits< ResultType >::lowest() ); } @@ -73,7 +76,8 @@ auto ExpressionArgMax( const Expression& expression ) using ResultType = std::decay_t< decltype( expression[0] ) >; using IndexType = typename Expression::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) { return expression[ i ]; }; + const auto view = expression.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) { return view[ i ]; }; auto reduction = [] __cuda_callable__ ( IndexType& aIdx, const IndexType& bIdx, ResultType& a, const ResultType& b ) { if( a < b ) { a = b; @@ -91,37 +95,8 @@ auto ExpressionSum( const Expression& expression ) -> std::decay_t< decltype( ex using ResultType = std::decay_t< decltype( expression[0] + expression[0] ) >; using IndexType = typename Expression::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) { return expression[ i ]; }; - return Algorithms::Reduction< typename Expression::DeviceType >::reduce( expression.getSize(), std::plus<>{}, fetch, (ResultType) 0 ); -} - -template< typename Expression > -auto ExpressionL1Norm( const Expression& expression ) -> std::decay_t< decltype( expression[0] + expression[0] ) > -{ - using ResultType = std::decay_t< decltype( expression[0] + expression[0] ) >; - using IndexType = typename Expression::IndexType; - - auto fetch = [=] __cuda_callable__ ( IndexType i ) { return TNL::abs( expression[ i ] ); }; - return Algorithms::Reduction< typename Expression::DeviceType >::reduce( expression.getSize(), std::plus<>{}, fetch, (ResultType) 0 ); -} - -template< typename Expression > -auto ExpressionL2Norm( const Expression& expression ) -> std::decay_t< decltype( expression[0] * expression[0] ) > -{ - using ResultType = std::decay_t< decltype( expression[0] * expression[0] ) >; - using IndexType = typename Expression::IndexType; - - auto fetch = [=] __cuda_callable__ ( IndexType i ) { return expression[ i ] * expression[ i ]; }; - return Algorithms::Reduction< typename Expression::DeviceType >::reduce( expression.getSize(), std::plus<>{}, fetch, (ResultType) 0 ); -} - -template< typename Expression, typename Real > -auto ExpressionLpNorm( const Expression& expression, const Real& p ) -> std::decay_t< decltype( TNL::pow( expression[0], p ) ) > -{ - using ResultType = std::decay_t< decltype( TNL::pow( expression[0], p ) ) >; - using IndexType = typename Expression::IndexType; - - auto fetch = [=] __cuda_callable__ ( IndexType i ) { return TNL::pow( TNL::abs( expression[ i ] ), p ); }; + const auto view = expression.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) { return view[ i ]; }; return Algorithms::Reduction< typename Expression::DeviceType >::reduce( expression.getSize(), std::plus<>{}, fetch, (ResultType) 0 ); } @@ -131,7 +106,8 @@ auto ExpressionProduct( const Expression& expression ) -> std::decay_t< decltype using ResultType = std::decay_t< decltype( expression[0] * expression[0] ) >; using IndexType = typename Expression::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) { return expression[ i ]; }; + const auto view = expression.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) { return view[ i ]; }; return Algorithms::Reduction< typename Expression::DeviceType >::reduce( expression.getSize(), std::multiplies<>{}, fetch, (ResultType) 1 ); } @@ -141,7 +117,8 @@ auto ExpressionLogicalAnd( const Expression& expression ) -> std::decay_t< declt using ResultType = std::decay_t< decltype( expression[0] && expression[0] ) >; using IndexType = typename Expression::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) { return expression[ i ]; }; + const auto view = expression.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) { return view[ i ]; }; return Algorithms::Reduction< typename Expression::DeviceType >::reduce( expression.getSize(), std::logical_and<>{}, fetch, std::numeric_limits< ResultType >::max() ); } @@ -151,7 +128,8 @@ auto ExpressionLogicalOr( const Expression& expression ) -> std::decay_t< declty using ResultType = std::decay_t< decltype( expression[0] || expression[0] ) >; using IndexType = typename Expression::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) { return expression[ i ]; }; + const auto view = expression.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) { return view[ i ]; }; return Algorithms::Reduction< typename Expression::DeviceType >::reduce( expression.getSize(), std::logical_or<>{}, fetch, (ResultType) 0 ); } @@ -161,7 +139,8 @@ auto ExpressionBinaryAnd( const Expression& expression ) -> std::decay_t< declty using ResultType = std::decay_t< decltype( expression[0] & expression[0] ) >; using IndexType = typename Expression::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) { return expression[ i ]; }; + const auto view = expression.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) { return view[ i ]; }; return Algorithms::Reduction< typename Expression::DeviceType >::reduce( expression.getSize(), std::bit_and<>{}, fetch, std::numeric_limits< ResultType >::max() ); } @@ -171,7 +150,8 @@ auto ExpressionBinaryOr( const Expression& expression ) -> std::decay_t< decltyp using ResultType = std::decay_t< decltype( expression[0] | expression[0] ) >; using IndexType = typename Expression::IndexType; - auto fetch = [=] __cuda_callable__ ( IndexType i ) { return expression[ i ]; }; + const auto view = expression.getConstView(); + auto fetch = [=] __cuda_callable__ ( IndexType i ) { return view[ i ]; }; return Algorithms::Reduction< typename Expression::DeviceType >::reduce( expression.getSize(), std::bit_or<>{}, fetch, (ResultType) 0 ); } diff --git a/src/TNL/Containers/StaticArray.hpp b/src/TNL/Containers/StaticArray.hpp index c1ac8e62a7a2e8257d0824c36d7f4caaa443e661..c6af2e4edc7c0bed8347ac47403eb2a6644baad2 100644 --- a/src/TNL/Containers/StaticArray.hpp +++ b/src/TNL/Containers/StaticArray.hpp @@ -102,21 +102,21 @@ template< int Size, typename Value > __cuda_callable__ StaticArray< Size, Value >::StaticArray( const Value v[ Size ] ) { - Algorithms::StaticFor< 0, Size >::exec( detail::AssignArrayFunctor{}, data, v ); + Algorithms::StaticFor< 0, Size >::exec( detail::AssignArrayFunctor{}, getData(), v ); } template< int Size, typename Value > __cuda_callable__ StaticArray< Size, Value >::StaticArray( const Value& v ) { - Algorithms::StaticFor< 0, Size >::exec( detail::AssignValueFunctor{}, data, v ); + Algorithms::StaticFor< 0, Size >::exec( detail::AssignValueFunctor{}, getData(), v ); } template< int Size, typename Value > __cuda_callable__ StaticArray< Size, Value >::StaticArray( const StaticArray< Size, Value >& v ) { - Algorithms::StaticFor< 0, Size >::exec( detail::AssignArrayFunctor{}, data, v.getData() ); + Algorithms::StaticFor< 0, Size >::exec( detail::AssignArrayFunctor{}, getData(), v.getData() ); } template< int Size, typename Value > @@ -228,7 +228,7 @@ template< int Size, typename Value > __cuda_callable__ StaticArray< Size, Value >& StaticArray< Size, Value >::operator=( const StaticArray< Size, Value >& array ) { - Algorithms::StaticFor< 0, Size >::exec( detail::AssignArrayFunctor{}, data, array.getData() ); + Algorithms::StaticFor< 0, Size >::exec( detail::AssignArrayFunctor{}, getData(), array.getData() ); return *this; } @@ -264,7 +264,7 @@ StaticArray< Size, Value >:: operator StaticArray< Size, OtherValue >() const { StaticArray< Size, OtherValue > aux; - Algorithms::StaticFor< 0, Size >::exec( detail::AssignArrayFunctor{}, aux.getData(), data ); + Algorithms::StaticFor< 0, Size >::exec( detail::AssignArrayFunctor{}, aux.getData(), getData() ); return aux; } @@ -272,27 +272,27 @@ template< int Size, typename Value > __cuda_callable__ void StaticArray< Size, Value >::setValue( const ValueType& val ) { - Algorithms::StaticFor< 0, Size >::exec( detail::AssignValueFunctor{}, data, val ); + Algorithms::StaticFor< 0, Size >::exec( detail::AssignValueFunctor{}, getData(), val ); } template< int Size, typename Value > bool StaticArray< Size, Value >::save( File& file ) const { - file.save( data, Size ); + file.save( getData(), Size ); return true; } template< int Size, typename Value > bool StaticArray< Size, Value >::load( File& file) { - file.load( data, Size ); + file.load( getData(), Size ); return true; } template< int Size, typename Value > void StaticArray< Size, Value >::sort() { - detail::StaticArraySort< Size - 1, 0, Value >::exec( data ); + detail::StaticArraySort< Size - 1, 0, Value >::exec( getData() ); } template< int Size, typename Value > diff --git a/src/TNL/Containers/StaticVector.h b/src/TNL/Containers/StaticVector.h index 2fe136ac951d4c02bb339e4c0edcee43f3c3b7d8..86726a4d3bafa0264501be5b1394974eda977642 100644 --- a/src/TNL/Containers/StaticVector.h +++ b/src/TNL/Containers/StaticVector.h @@ -73,7 +73,7 @@ public: */ template< typename T1, typename T2, - template< typename, typename > class Operation > + typename Operation > __cuda_callable__ StaticVector( const Expressions::StaticBinaryExpressionTemplate< T1, T2, Operation >& expr ); @@ -83,7 +83,7 @@ public: * \param expr is unary expression */ template< typename T, - template< typename > class Operation > + typename Operation > __cuda_callable__ StaticVector( const Expressions::StaticUnaryExpressionTemplate< T, Operation >& expr ); @@ -172,11 +172,18 @@ public: operator StaticVector< Size, OtherReal >() const; }; +// Enable expression templates for StaticVector +namespace Expressions { + template< int Size, typename Real > + struct HasEnabledStaticExpressionTemplates< StaticVector< Size, Real > > + : std::true_type + {}; +} // namespace Expressions + } // namespace Containers } // namespace TNL #include <TNL/Containers/StaticVector.hpp> -#include <TNL/Containers/StaticVectorExpressions.h> // TODO: move to some other source file namespace TNL { diff --git a/src/TNL/Containers/StaticVector.hpp b/src/TNL/Containers/StaticVector.hpp index dc97eeea99b5d551e11beb7543e5f0822f79fad4..4a1b41b2198d114bfe31fed16b3d04f37cf3ad5d 100644 --- a/src/TNL/Containers/StaticVector.hpp +++ b/src/TNL/Containers/StaticVector.hpp @@ -19,7 +19,7 @@ namespace Containers { template< int Size, typename Real > template< typename T1, typename T2, - template< typename, typename > class Operation > + typename Operation > __cuda_callable__ StaticVector< Size, Real >::StaticVector( const Expressions::StaticBinaryExpressionTemplate< T1, T2, Operation >& expr ) { @@ -29,7 +29,7 @@ StaticVector< Size, Real >::StaticVector( const Expressions::StaticBinaryExpress template< int Size, typename Real > template< typename T, - template< typename > class Operation > + typename Operation > __cuda_callable__ StaticVector< Size, Real >::StaticVector( const Expressions::StaticUnaryExpressionTemplate< T, Operation >& expr ) { diff --git a/src/TNL/Containers/StaticVectorExpressions.h b/src/TNL/Containers/StaticVectorExpressions.h deleted file mode 100644 index fdaf7cf70fb5a894bce285bac7f4bc6a359ab878..0000000000000000000000000000000000000000 --- a/src/TNL/Containers/StaticVectorExpressions.h +++ /dev/null @@ -1,774 +0,0 @@ -/*************************************************************************** - StaticVectorExpressions.h - description - ------------------- - begin : Apr 19, 2019 - copyright : (C) 2019 by Tomas Oberhuber - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#pragma once -#ifndef DOXYGEN_ONLY - -#include <TNL/Containers/Expressions/StaticExpressionTemplates.h> - -#include "StaticVector.h" - -namespace TNL { -namespace Containers { -// operators must be defined in the same namespace as the first operand, otherwise -// they may not be considered by the compiler (e.g. inside pybind11's macros) -// namespace Containers { Overriden operators should be in namespace TNL - -//// -// Addition -template< int Size, typename Real, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -auto -operator+( const StaticVector< Size, Real >& a, const ET& b ) -{ - return Expressions::StaticBinaryExpressionTemplate< StaticVector< Size, Real >, ET, Expressions::Addition >( a, b ); -} - -template< typename ET, int Size, typename Real, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -auto -operator+( const ET& a, const StaticVector< Size, Real >& b ) -{ - return Expressions::StaticBinaryExpressionTemplate< ET, StaticVector< Size, Real >, Expressions::Addition >( a, b ); -} - -template< int Size, typename Real1, typename Real2 > -__cuda_callable__ -auto -operator+( const StaticVector< Size, Real1 >& a, const StaticVector< Size, Real2 >& b ) -{ - return Expressions::StaticBinaryExpressionTemplate< StaticVector< Size, Real1 >, StaticVector< Size, Real2 >, Expressions::Addition >( a, b ); -} - -//// -// Subtraction -template< int Size, typename Real, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -auto -operator-( const StaticVector< Size, Real >& a, const ET& b ) -{ - return Expressions::StaticBinaryExpressionTemplate< StaticVector< Size, Real >, ET, Expressions::Subtraction >( a, b ); -} - -template< typename ET, int Size, typename Real, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -auto -operator-( const ET& a, const StaticVector< Size, Real >& b ) -{ - return Expressions::StaticBinaryExpressionTemplate< ET, StaticVector< Size, Real >, Expressions::Subtraction >( a, b ); -} - -template< int Size, typename Real1, typename Real2 > -__cuda_callable__ -auto -operator-( const StaticVector< Size, Real1 >& a, const StaticVector< Size, Real2 >& b ) -{ - return Expressions::StaticBinaryExpressionTemplate< StaticVector< Size, Real1 >, StaticVector< Size, Real2 >, Expressions::Subtraction >( a, b ); -} - -//// -// Multiplication -template< int Size, typename Real, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -auto -operator*( const StaticVector< Size, Real >& a, const ET& b ) -{ - return Expressions::StaticBinaryExpressionTemplate< StaticVector< Size, Real >, ET, Expressions::Multiplication >( a, b ); -} - -template< typename ET, int Size, typename Real, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -auto -operator*( const ET& a, const StaticVector< Size, Real >& b ) -{ - return Expressions::StaticBinaryExpressionTemplate< ET, StaticVector< Size, Real >, Expressions::Multiplication >( a, b ); -} - -template< int Size, typename Real1, typename Real2 > -__cuda_callable__ -auto -operator*( const StaticVector< Size, Real1 >& a, const StaticVector< Size, Real2 >& b ) -{ - return Expressions::StaticBinaryExpressionTemplate< StaticVector< Size, Real1 >, StaticVector< Size, Real2 >, Expressions::Multiplication >( a, b ); -} - -//// -// Division -template< int Size, typename Real, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -auto -operator/( const StaticVector< Size, Real >& a, const ET& b ) -{ - return Expressions::StaticBinaryExpressionTemplate< StaticVector< Size, Real >, ET, Expressions::Division >( a, b ); -} - -template< typename ET, int Size, typename Real, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -auto -operator/( const ET& a, const StaticVector< Size, Real >& b ) -{ - return Expressions::StaticBinaryExpressionTemplate< ET, StaticVector< Size, Real >, Expressions::Division >( a, b ); -} - -template< int Size, typename Real1, typename Real2 > -__cuda_callable__ -auto -operator/( const StaticVector< Size, Real1 >& a, const StaticVector< Size, Real2 >& b ) -{ - return Expressions::StaticBinaryExpressionTemplate< StaticVector< Size, Real1 >, StaticVector< Size, Real2 >, Expressions::Division >( a, b ); -} - -//// -// Comparison operations - operator == -template< int Size, typename Real, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -bool operator==( const StaticVector< Size, Real >& a, const ET& b ) -{ - return Expressions::StaticComparison< StaticVector< Size, Real >, ET >::EQ( a, b ); -} - -template< typename ET, int Size, typename Real, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -bool operator==( const ET& a, const StaticVector< Size, Real >& b ) -{ - return Expressions::StaticComparison< ET, StaticVector< Size, Real > >::EQ( a, b ); -} - -template< int Size, typename Real1, typename Real2 > -__cuda_callable__ -bool operator==( const StaticVector< Size, Real1 >& a, const StaticVector< Size, Real2 >& b ) -{ - return Expressions::StaticComparison< StaticVector< Size, Real1 >, StaticVector< Size, Real2 > >::EQ( a, b ); -} - -//// -// Comparison operations - operator != -template< int Size, typename Real, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -bool operator!=( const StaticVector< Size, Real >& a, const ET& b ) -{ - return Expressions::StaticComparison< StaticVector< Size, Real >, ET >::NE( a, b ); -} - -template< typename ET, int Size, typename Real, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -bool operator!=( const ET& a, const StaticVector< Size, Real >& b ) -{ - return Expressions::StaticComparison< ET, StaticVector< Size, Real > >::NE( a, b ); -} - -template< int Size, typename Real1, typename Real2 > -__cuda_callable__ -bool operator!=( const StaticVector< Size, Real1 >& a, const StaticVector< Size, Real2 >& b ) -{ - return Expressions::StaticComparison< StaticVector< Size, Real1 >, StaticVector< Size, Real2 > >::NE( a, b ); -} - -//// -// Comparison operations - operator < -template< int Size, typename Real, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -bool operator<( const StaticVector< Size, Real >& a, const ET& b ) -{ - return Expressions::StaticComparison< StaticVector< Size, Real >, ET >::LT( a, b ); -} - -template< typename ET, int Size, typename Real, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -bool operator<( const ET& a, const StaticVector< Size, Real >& b ) -{ - return Expressions::StaticComparison< ET, StaticVector< Size, Real > >::LT( a, b ); -} - -template< int Size, typename Real1, typename Real2 > -__cuda_callable__ -bool operator<( const StaticVector< Size, Real1 >& a, const StaticVector< Size, Real2 >& b ) -{ - return Expressions::StaticComparison< StaticVector< Size, Real1 >, StaticVector< Size, Real2 > >::LT( a, b ); -} - -//// -// Comparison operations - operator <= -template< int Size, typename Real, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -bool operator<=( const StaticVector< Size, Real >& a, const ET& b ) -{ - return Expressions::StaticComparison< StaticVector< Size, Real >, ET >::LE( a, b ); -} - -template< typename ET, int Size, typename Real, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -bool operator<=( const ET& a, const StaticVector< Size, Real >& b ) -{ - return Expressions::StaticComparison< ET, StaticVector< Size, Real > >::LE( a, b ); -} - -template< int Size, typename Real1, typename Real2 > -__cuda_callable__ -bool operator<=( const StaticVector< Size, Real1 >& a, const StaticVector< Size, Real2 >& b ) -{ - return Expressions::StaticComparison< StaticVector< Size, Real1 >, StaticVector< Size, Real2 > >::LE( a, b ); -} - -//// -// Comparison operations - operator > -template< int Size, typename Real, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -bool operator>( const StaticVector< Size, Real >& a, const ET& b ) -{ - return Expressions::StaticComparison< StaticVector< Size, Real >, ET >::GT( a, b ); -} - -template< typename ET, int Size, typename Real, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -bool operator>( const ET& a, const StaticVector< Size, Real >& b ) -{ - return Expressions::StaticComparison< ET, StaticVector< Size, Real > >::GT( a, b ); -} - -template< int Size, typename Real1, typename Real2 > -__cuda_callable__ -bool operator>( const StaticVector< Size, Real1 >& a, const StaticVector< Size, Real2 >& b ) -{ - return Expressions::StaticComparison< StaticVector< Size, Real1 >, StaticVector< Size, Real2 > >::GT( a, b ); -} - -//// -// Comparison operations - operator >= -template< int Size, typename Real, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -bool operator>=( const StaticVector< Size, Real >& a, const ET& b ) -{ - return Expressions::StaticComparison< StaticVector< Size, Real >, ET >::GE( a, b ); -} - -template< typename ET, int Size, typename Real, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -bool operator>=( const ET& a, const StaticVector< Size, Real >& b ) -{ - return Expressions::StaticComparison< ET, StaticVector< Size, Real > >::GE( a, b ); -} - -template< int Size, typename Real1, typename Real2 > -__cuda_callable__ -bool operator>=( const StaticVector< Size, Real1 >& a, const StaticVector< Size, Real2 >& b ) -{ - return Expressions::StaticComparison< StaticVector< Size, Real1 >, StaticVector< Size, Real2 > >::GE( a, b ); -} - -//// -// Minus -template< int Size, typename Real > -__cuda_callable__ -auto -operator-( const StaticVector< Size, Real >& a ) -{ - return Expressions::StaticUnaryExpressionTemplate< StaticVector< Size, Real >, Expressions::Minus >( a ); -} - -//// -// Scalar product -template< int Size, typename Real, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -auto -operator,( const StaticVector< Size, Real >& a, const ET& b ) -{ - return Containers::Expressions::StaticExpressionSum( a * b ); -} - -template< typename ET, int Size, typename Real, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -auto -operator,( const ET& a, const StaticVector< Size, Real >& b ) -{ - return Containers::Expressions::StaticExpressionSum( a * b ); -} - -template< typename Real1, int Size, typename Real2 > -__cuda_callable__ -auto -operator,( const StaticVector< Size, Real1 >& a, const StaticVector< Size, Real2 >& b ) -{ - return Containers::Expressions::StaticExpressionSum( a * b ); -} - -} // namespace Containers - -//// -// Min -template< int Size, typename Real, typename ET, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -auto -min( const Containers::StaticVector< Size, Real >& a, const ET& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< Containers::StaticVector< Size, Real >, ET, Containers::Expressions::Min >( a, b ); -} - -template< typename ET, int Size, typename Real, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -auto -min( const ET& a, const Containers::StaticVector< Size, Real >& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< ET, Containers::StaticVector< Size, Real >, Containers::Expressions::Min >( a, b ); -} - -template< int Size, typename Real1, typename Real2 > -__cuda_callable__ -auto -min( const Containers::StaticVector< Size, Real1 >& a, const Containers::StaticVector< Size, Real2 >& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< Containers::StaticVector< Size, Real1 >, Containers::StaticVector< Size, Real2 >, Containers::Expressions::Min >( a, b ); -} - -//// -// Max -template< int Size, typename Real, typename ET, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -auto -max( const Containers::StaticVector< Size, Real >& a, const ET& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< Containers::StaticVector< Size, Real >, ET, Containers::Expressions::Max >( a, b ); -} - -template< typename ET, int Size, typename Real, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -auto -max( const ET& a, const Containers::StaticVector< Size, Real >& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< ET, Containers::StaticVector< Size, Real >, Containers::Expressions::Max >( a, b ); -} - -template< int Size, typename Real1, typename Real2 > -__cuda_callable__ -auto -max( const Containers::StaticVector< Size, Real1 >& a, const Containers::StaticVector< Size, Real2 >& b ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< Containers::StaticVector< Size, Real1 >, Containers::StaticVector< Size, Real2 >, Containers::Expressions::Max >( a, b ); -} - -//// -// Dot product - the same as scalar product, just for convenience -template< int Size, typename Real, typename ET, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -auto -dot( const Containers::StaticVector< Size, Real >& a, const ET& b ) -{ - return (a, b); -} - -template< typename ET, int Size, typename Real, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -__cuda_callable__ -auto -dot( const ET& a, const Containers::StaticVector< Size, Real >& b ) -{ - return (a, b); -} - -template< typename Real1, int Size, typename Real2 > -__cuda_callable__ -auto -dot( const Containers::StaticVector< Size, Real1 >& a, const Containers::StaticVector< Size, Real2 >& b ) -{ - return (a, b); -} - - -//// -// Abs -template< int Size, typename Real > -__cuda_callable__ -auto -abs( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Abs >( a ); -} - -//// -// Power -template< int Size, typename Real, typename ExpType > -__cuda_callable__ -auto -pow( const Containers::StaticVector< Size, Real >& a, const ExpType& exp ) -{ - return Containers::Expressions::StaticBinaryExpressionTemplate< Containers::StaticVector< Size, Real >, ExpType, Containers::Expressions::Pow >( a, exp ); -} - -//// -// Exp -template< int Size, typename Real > -__cuda_callable__ -auto -exp( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Exp >( a ); -} - -//// -// Sqrt -template< int Size, typename Real > -__cuda_callable__ -auto -sqrt( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Sqrt >( a ); -} - -//// -// Cbrt -template< int Size, typename Real > -__cuda_callable__ -auto -cbrt( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Cbrt >( a ); -} - -//// -// Log -template< int Size, typename Real > -__cuda_callable__ -auto -log( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Log >( a ); -} - -//// -// Log10 -template< int Size, typename Real > -__cuda_callable__ -auto -log10( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Log10 >( a ); -} - -//// -// Log2 -template< int Size, typename Real > -__cuda_callable__ -auto -log2( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Log2 >( a ); -} - -//// -// Sine -template< int Size, typename Real > -__cuda_callable__ -auto -sin( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Sin >( a ); -} - -//// -// Cosine -template< int Size, typename Real > -__cuda_callable__ -auto -cos( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Cos >( a ); -} - -//// -// Tangent -template< int Size, typename Real > -__cuda_callable__ -auto -tan( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Tan >( a ); -} - -//// -// Asin -template< int Size, typename Real > -__cuda_callable__ -auto -asin( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Asin >( a ); -} - -//// -// Acos -template< int Size, typename Real > -__cuda_callable__ -auto -acos( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Acos >( a ); -} - -//// -// Atan -template< int Size, typename Real > -__cuda_callable__ -auto -atan( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Atan >( a ); -} - -//// -// Sinh -template< int Size, typename Real > -__cuda_callable__ -auto -sinh( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Sinh >( a ); -} - -//// -// Cosh -template< int Size, typename Real > -__cuda_callable__ -auto -cosh( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Cosh >( a ); -} - -//// -// Tanh -template< int Size, typename Real > -__cuda_callable__ -auto -tanh( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Tanh >( a ); -} - -//// -// Asinh -template< int Size, typename Real > -__cuda_callable__ -auto -asinh( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Asinh >( a ); -} - -//// -// Acosh -template< int Size, typename Real > -__cuda_callable__ -auto -acosh( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Acosh >( a ); -} - -//// -// Atanh -template< int Size, typename Real > -__cuda_callable__ -auto -atanh( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Atanh >( a ); -} - -//// -// Floor -template< int Size, typename Real > -__cuda_callable__ -auto -floor( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Floor >( a ); -} - -//// -// Ceil -template< int Size, typename Real > -__cuda_callable__ -auto -ceil( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Ceil >( a ); -} - -//// -// Sign -template< int Size, typename Real > -__cuda_callable__ -auto -sign( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< Containers::StaticVector< Size, Real >, Containers::Expressions::Sign >( a ); -} - -//// -// Cast -template< typename ResultType, int Size, typename Real, - // workaround: templated type alias cannot be declared at block level - template<typename> class Operation = Containers::Expressions::Cast< ResultType >::template Operation > -auto -__cuda_callable__ -cast( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticUnaryExpressionTemplate< std::decay_t<decltype(a)>, Operation >( a ); -} - -//// -// Vertical operations - min -template< int Size, typename Real > -__cuda_callable__ -auto -min( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticExpressionMin( a ); -} - -template< int Size, typename Real > -__cuda_callable__ -std::pair< int, Real > -argMin( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticExpressionArgMin( a ); -} - -template< int Size, typename Real > -__cuda_callable__ -auto -max( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticExpressionMax( a ); -} - -template< int Size, typename Real > -__cuda_callable__ -std::pair< int, Real > -argMax( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticExpressionArgMax( a ); -} - -template< int Size, typename Real > -__cuda_callable__ -auto -sum( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticExpressionSum( a ); -} - -template< int Size, typename Real > -__cuda_callable__ -auto -maxNorm( const Containers::StaticVector< Size, Real >& a ) -{ - return max( abs( a ) ); -} - -template< int Size, typename Real > -__cuda_callable__ -auto -l1Norm( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticExpressionL1Norm( a ); -} - -template< int Size, typename Real > -__cuda_callable__ -auto -l2Norm( const Containers::StaticVector< Size, Real >& a ) -{ - return TNL::sqrt( Containers::Expressions::StaticExpressionL2Norm( a ) ); -} - -template< int Size, typename Real, typename Real2 > -__cuda_callable__ -auto -lpNorm( const Containers::StaticVector< Size, Real >& a, const Real2& p ) -// since (1.0 / p) has type double, TNL::pow returns double --> double -{ - if( p == 1.0 ) - return l1Norm( a ); - if( p == 2.0 ) - return l2Norm( a ); - return TNL::pow( Containers::Expressions::StaticExpressionLpNorm( a, p ), 1.0 / p ); -} - -template< int Size, typename Real > -__cuda_callable__ -auto -product( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticExpressionProduct( a ); -} - -template< int Size, typename Real > -__cuda_callable__ -auto -logicalOr( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticExpressionLogicalOr( a ); -} - -template< int Size, typename Real > -__cuda_callable__ -auto -binaryOr( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticExpressionBinaryOr( a ); -} - -template< int Size, typename Real > -__cuda_callable__ -auto -logicalAnd( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticExpressionLogicalAnd( a ); -} - -template< int Size, typename Real > -__cuda_callable__ -auto -binaryAnd( const Containers::StaticVector< Size, Real >& a ) -{ - return Containers::Expressions::StaticExpressionBinaryAnd( a ); -} - -} // namespace TNL -#endif // DOXYGEN_ONLY diff --git a/src/TNL/Containers/Vector.h b/src/TNL/Containers/Vector.h index 6bec6932115b03a47696de90a7a560c31762c4a2..259081052c1d0c1241f190cdad4002f98b3bf2d0 100644 --- a/src/TNL/Containers/Vector.h +++ b/src/TNL/Containers/Vector.h @@ -174,7 +174,7 @@ public: */ template< typename VectorExpression, typename..., - typename = std::enable_if_t< Expressions::IsExpressionTemplate< VectorExpression >::value > > + typename = std::enable_if_t< Expressions::HasEnabledExpressionTemplates< VectorExpression >::value && ! IsArrayType< VectorExpression >::value > > Vector& operator=( const VectorExpression& expression ); /** @@ -326,8 +326,15 @@ public: void segmentedScan( const VectorExpression& expression, FlagsArray& flags, IndexType begin = 0, IndexType end = 0 ); }; +// Enable expression templates for Vector +namespace Expressions { + template< typename Real, typename Device, typename Index, typename Allocator > + struct HasEnabledExpressionTemplates< Vector< Real, Device, Index, Allocator > > + : std::true_type + {}; +} // namespace Expressions + } // namespace Containers } // namespace TNL #include <TNL/Containers/Vector.hpp> -#include <TNL/Containers/VectorExpressions.h> diff --git a/src/TNL/Containers/VectorExpressions.h b/src/TNL/Containers/VectorExpressions.h deleted file mode 100644 index 83d682e8bd50d38a7d16bf1b8895cb624aa021a2..0000000000000000000000000000000000000000 --- a/src/TNL/Containers/VectorExpressions.h +++ /dev/null @@ -1,1098 +0,0 @@ -/*************************************************************************** - VectorExpressions.h - description - ------------------- - begin : Jun 27, 2019 - copyright : (C) 2019 by Tomas Oberhuber et al. - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#pragma once - -#include <TNL/Containers/Expressions/ExpressionTemplates.h> - -#include "Vector.h" - -namespace TNL { -namespace Containers { - -/** - * \brief Addition of vector and vector expression. - * @param a - * @param b - * @return - */ -template< typename Real, typename Device, typename Index, typename Allocator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator+( const Vector< Real, Device, Index, Allocator >& a, const ET& b ) -{ - using ConstView = typename Vector< Real, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ConstView, ET, Expressions::Addition >( a.getConstView(), b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Allocator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator+( const ET& a, const Vector< Real, Device, Index, Allocator >& b ) -{ - using ConstView = typename Vector< Real, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ET, ConstView, Expressions::Addition >( a, b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -operator+( const Vector< Real1, Device, Index, Allocator >& a, const Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename Vector< Real2, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ConstView1, ConstView2, Expressions::Addition >( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -operator+( const VectorView< Real1, Device, Index >& a, const Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename Vector< Real2, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ConstView1, ConstView2, Expressions::Addition >( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -operator+( const Vector< Real1, Device, Index, Allocator >& a, const VectorView< Real2, Device, Index >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename Vector< Real2, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ConstView1, ConstView2, Expressions::Addition >( a.getConstView(), b.getConstView() ); -} - -//// -// Subtraction -template< typename Real, typename Device, typename Index, typename Allocator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator-( const Vector< Real, Device, Index, Allocator >& a, const ET& b ) -{ - using ConstView = typename Vector< Real, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ConstView, ET, Expressions::Subtraction >( a.getConstView(), b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Allocator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator-( const ET& a, const Vector< Real, Device, Index, Allocator >& b ) -{ - using ConstView = typename Vector< Real, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ET, ConstView, Expressions::Subtraction >( a, b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -operator-( const Vector< Real1, Device, Index, Allocator >& a, const Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename Vector< Real2, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ConstView1, ConstView2, Expressions::Subtraction >( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -operator-( const VectorView< Real1, Device, Index >& a, const Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename Vector< Real2, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ConstView1, ConstView2, Expressions::Subtraction >( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -operator-( const Vector< Real1, Device, Index, Allocator >& a, const VectorView< Real2, Device, Index >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename Vector< Real2, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ConstView1, ConstView2, Expressions::Subtraction >( a.getConstView(), b.getConstView() ); -} - -//// -// Multiplication -template< typename Real, typename Device, typename Index, typename Allocator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator*( const Vector< Real, Device, Index, Allocator >& a, const ET& b ) -{ - using ConstView = typename Vector< Real, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ConstView, ET, Expressions::Multiplication >( a.getConstView(), b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Allocator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator*( const ET& a, const Vector< Real, Device, Index, Allocator >& b ) -{ - using ConstView = typename Vector< Real, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ET, ConstView, Expressions::Multiplication >( a, b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -operator*( const Vector< Real1, Device, Index, Allocator >& a, const Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename Vector< Real2, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ConstView1, ConstView2, Expressions::Multiplication >( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -operator*( const VectorView< Real1, Device, Index >& a, const Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename Vector< Real2, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ConstView1, ConstView2, Expressions::Multiplication >( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -operator*( const Vector< Real1, Device, Index, Allocator >& a, const VectorView< Real2, Device, Index >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename Vector< Real2, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ConstView1, ConstView2, Expressions::Multiplication >( a.getConstView(), b.getConstView() ); -} - -//// -// Division -template< typename Real, typename Device, typename Index, typename Allocator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator/( const Vector< Real, Device, Index, Allocator >& a, const ET& b ) -{ - using ConstView = typename Vector< Real, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ConstView, ET, Expressions::Division >( a.getConstView(), b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Allocator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator/( const ET& a, const Vector< Real, Device, Index, Allocator >& b ) -{ - using ConstView = typename Vector< Real, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ET, ConstView, Expressions::Division >( a, b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -operator/( const Vector< Real1, Device, Index, Allocator >& a, const Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename Vector< Real2, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ConstView1, ConstView2, Expressions::Division >( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -operator/( const VectorView< Real1, Device, Index >& a, const Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename Vector< Real2, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ConstView1, ConstView2, Expressions::Division >( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -operator/( const Vector< Real1, Device, Index, Allocator >& a, const VectorView< Real2, Device, Index >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename Vector< Real2, Device, Index, Allocator >::ConstViewType; - return Expressions::BinaryExpressionTemplate< ConstView1, ConstView2, Expressions::Division >( a.getConstView(), b.getConstView() ); -} - -//// -// Comparison operations - operator == -template< typename Real, typename Device, typename Index, typename Allocator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator==( const Vector< Real, Device, Index, Allocator >& a, const ET& b ) -{ - using ConstView = typename VectorView< Real, Device, Index >::ConstViewType; - return Expressions::Comparison< ConstView, ET >::EQ( a.getConstView(), b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Allocator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator==( const ET& a, const Vector< Real, Device, Index, Allocator >& b ) -{ - using ConstView = typename VectorView< Real, Device, Index >::ConstViewType; - return Expressions::Comparison< ET, ConstView >::EQ( a, b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device1, typename Device2, typename Index, typename Allocator > -bool -operator==( const Vector< Real1, Device1, Index, Allocator >& a, const Vector< Real2, Device2, Index, Allocator >& b ) -{ - using ConstView1 = typename Vector< Real1, Device1, Index, Allocator >::ConstViewType; - using ConstView2 = typename Vector< Real2, Device2, Index, Allocator >::ConstViewType; - return Expressions::Comparison< ConstView1, ConstView2 >::EQ( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device1, typename Device2, typename Index, typename Allocator > -bool -operator==( const VectorView< Real1, Device1, Index >& a, const Vector< Real2, Device2, Index, Allocator >& b ) -{ - using ConstView1 = VectorView< Real1, Device1, Index >; - using ConstView2 = typename Vector< Real2, Device2, Index, Allocator >::ConstViewType; - return Expressions::Comparison< ConstView1, ConstView2 >::EQ( a, b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device1, typename Device2, typename Index, typename Allocator > -bool -operator==( const Vector< Real1, Device1, Index, Allocator >& a, const VectorView< Real2, Device2, Index >& b ) -{ - using ConstView1 = typename Vector< Real1, Device1, Index, Allocator >::ConstViewType; - using ConstView2 = VectorView< Real2, Device2, Index >; - return Expressions::Comparison< ConstView1, ConstView2 >::EQ( a.getConstView(), b ); -} - -//// -// Comparison operations - operator != -template< typename Real, typename Device, typename Index, typename Allocator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator!=( const Vector< Real, Device, Index, Allocator >& a, const ET& b ) -{ - using ConstView = typename VectorView< Real, Device, Index >::ConstViewType; - return Expressions::Comparison< ConstView, ET >::NE( a.getConstView(), b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Allocator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator!=( const ET& a, const Vector< Real, Device, Index, Allocator >& b ) -{ - using ConstView = typename VectorView< Real, Device, Index >::ConstViewType; - return Expressions::Comparison< ET, ConstView >::NE( a, b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device1, typename Device2, typename Index, typename Allocator > -bool -operator!=( const Vector< Real1, Device1, Index, Allocator >& a, const Vector< Real2, Device2, Index, Allocator >& b ) -{ - return ! (a == b); -} - -template< typename Real1, typename Real2, typename Device1, typename Device2, typename Index, typename Allocator > -bool -operator!=( const VectorView< Real1, Device1, Index >& a, const Vector< Real2, Device2, Index, Allocator >& b ) -{ - return ! (a == b); -} - -template< typename Real1, typename Real2, typename Device1, typename Device2, typename Index, typename Allocator > -bool -operator!=( const Vector< Real1, Device1, Index, Allocator >& a, const VectorView< Real2, Device2, Index >& b ) -{ - return ! (a == b); -} - -//// -// Comparison operations - operator < -template< typename Real, typename Device, typename Index, typename Allocator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator<( const Vector< Real, Device, Index, Allocator >& a, const ET& b ) -{ - using ConstView = typename VectorView< Real, Device, Index >::ConstViewType; - return Expressions::Comparison< ConstView, ET >::LT( a.getConstView(), b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Allocator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator<( const ET& a, const Vector< Real, Device, Index, Allocator >& b ) -{ - using ConstView = typename VectorView< Real, Device, Index >::ConstViewType; - return Expressions::Comparison< ET, ConstView >::LT( a, b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -bool -operator<( const Vector< Real1, Device, Index, Allocator >& a, const Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename VectorView< Real2, Device, Index >::ConstViewType; - return Expressions::Comparison< ConstView1, ConstView2 >::LT( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -bool -operator<( const VectorView< Real1, Device, Index >& a, const Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename VectorView< Real2, Device, Index >::ConstViewType; - return Expressions::Comparison< ConstView1, ConstView2 >::LT( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -bool -operator<( const Vector< Real1, Device, Index, Allocator >& a, const VectorView< Real2, Device, Index >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename VectorView< Real2, Device, Index >::ConstViewType; - return Expressions::Comparison< ConstView1, ConstView2 >::LT( a.getConstView(), b.getConstView() ); -} - -//// -// Comparison operations - operator <= -template< typename Real, typename Device, typename Index, typename Allocator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator<=( const Vector< Real, Device, Index, Allocator >& a, const ET& b ) -{ - using ConstView = typename VectorView< Real, Device, Index >::ConstViewType; - return Expressions::Comparison< ConstView, ET >::LE( a.getConstView(), b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Allocator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator<=( const ET& a, const Vector< Real, Device, Index, Allocator >& b ) -{ - using ConstView = typename VectorView< Real, Device, Index >::ConstViewType; - return Expressions::Comparison< ET, ConstView >::LE( a, b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -bool -operator<=( const Vector< Real1, Device, Index, Allocator >& a, const Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename VectorView< Real2, Device, Index >::ConstViewType; - return Expressions::Comparison< ConstView1, ConstView2 >::LE( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -bool -operator<=( const VectorView< Real1, Device, Index >& a, const Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename VectorView< Real2, Device, Index >::ConstViewType; - return Expressions::Comparison< ConstView1, ConstView2 >::LE( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -bool -operator<=( const Vector< Real1, Device, Index, Allocator >& a, const VectorView< Real2, Device, Index >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename VectorView< Real2, Device, Index >::ConstViewType; - return Expressions::Comparison< ConstView1, ConstView2 >::LE( a.getConstView(), b.getConstView() ); -} - -//// -// Comparison operations - operator > -template< typename Real, typename Device, typename Index, typename Allocator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator>( const Vector< Real, Device, Index, Allocator >& a, const ET& b ) -{ - using ConstView = typename VectorView< Real, Device, Index >::ConstViewType; - return Expressions::Comparison< ConstView, ET >::GT( a.getConstView(), b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Allocator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator>( const ET& a, const Vector< Real, Device, Index, Allocator >& b ) -{ - using ConstView = typename VectorView< Real, Device, Index >::ConstViewType; - return Expressions::Comparison< ET, ConstView >::GT( a, b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -bool -operator>( const Vector< Real1, Device, Index, Allocator >& a, const Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename VectorView< Real2, Device, Index >::ConstViewType; - return Expressions::Comparison< ConstView1, ConstView2 >::GT( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -bool -operator>( const VectorView< Real1, Device, Index >& a, const Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename VectorView< Real2, Device, Index >::ConstViewType; - return Expressions::Comparison< ConstView1, ConstView2 >::GT( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -bool -operator>( const Vector< Real1, Device, Index, Allocator >& a, const VectorView< Real2, Device, Index >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename VectorView< Real2, Device, Index >::ConstViewType; - return Expressions::Comparison< ConstView1, ConstView2 >::GT( a.getConstView(), b.getConstView() ); -} - -//// -// Comparison operations - operator >= -template< typename Real, typename Device, typename Index, typename Allocator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator>=( const Vector< Real, Device, Index, Allocator >& a, const ET& b ) -{ - using ConstView = typename VectorView< Real, Device, Index >::ConstViewType; - return Expressions::Comparison< ConstView, ET >::GE( a.getConstView(), b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Allocator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator>=( const ET& a, const Vector< Real, Device, Index, Allocator >& b ) -{ - using ConstView = typename VectorView< Real, Device, Index >::ConstViewType; - return Expressions::Comparison< ET, ConstView >::GE( a, b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -bool -operator>=( const Vector< Real1, Device, Index, Allocator >& a, const Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename VectorView< Real2, Device, Index >::ConstViewType; - return Expressions::Comparison< ConstView1, ConstView2 >::GE( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -bool -operator>=( const VectorView< Real1, Device, Index >& a, const Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename VectorView< Real2, Device, Index >::ConstViewType; - return Expressions::Comparison< ConstView1, ConstView2 >::GE( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -bool -operator>=( const Vector< Real1, Device, Index, Allocator >& a, const VectorView< Real2, Device, Index >& b ) -{ - using ConstView1 = typename Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename VectorView< Real2, Device, Index >::ConstViewType; - return Expressions::Comparison< ConstView1, ConstView2 >::GE( a.getConstView(), b.getConstView() ); -} - -//// -// Minus -template< typename Real, typename Device, typename Index, typename Allocator > -auto -operator-( const Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Vector< Real, Device, Index, Allocator >::ConstViewType; - return Expressions::UnaryExpressionTemplate< ConstView, Expressions::Minus >( a.getConstView() ); -} - -//// -// Scalar product -#ifdef DOXYGEN_ONLY -/** - * \brief Computes scalar product of two vectors or vector expressions. Equivalent to \ref TNL::dot. - * - * @param a input vector or vector expression - * @param b input vector or vector expression - * @return scalar product of \e a and \e b. - */ -template< typename ET1, typename ET2 > -Real -operator,( const ET1& a, const ET2& b ) {} -#else - -template< typename Real, typename Device, typename Index, typename Allocator, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -Real -operator,( const Vector< Real, Device, Index, Allocator >& a, const ET& b ) -{ - return Expressions::ExpressionSum( a.getConstView() * b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Allocator, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -Real -operator,( const ET& a, const Vector< Real, Device, Index, Allocator >& b ) -{ - return Expressions::ExpressionSum( a * b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -operator,( const Vector< Real1, Device, Index, Allocator >& a, const Vector< Real2, Device, Index, Allocator >& b ) -{ - return Expressions::ExpressionSum( a.getConstView() * b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -operator,( const VectorView< Real1, Device, Index >& a, const Vector< Real2, Device, Index, Allocator >& b ) -{ - return Expressions::ExpressionSum( a.getConstView() * b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -operator,( const Vector< Real1, Device, Index, Allocator >& a, const VectorView< Real2, Device, Index >& b ) -{ - return Expressions::ExpressionSum( a.getConstView() * b.getConstView() ); -} -#endif // DOXYGEN_ONLY - -} //namespace Containers - -//// -// All functions are supposed to be in namespace TNL - -//// -// Min -template< typename Real, typename Device, typename Index, typename Allocator, typename ET, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -min( const Containers::Vector< Real, Device, Index, Allocator >& a, const ET& b ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::BinaryExpressionTemplate< ConstView, ET, Containers::Expressions::Min >( a.getConstView(), b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Allocator, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -min( const ET& a, const Containers::Vector< Real, Device, Index, Allocator >& b ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::BinaryExpressionTemplate< ET, ConstView, Containers::Expressions::Min >( a, b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -min( const Containers::Vector< Real1, Device, Index, Allocator >& a, const Containers::Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Containers::Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename Containers::Vector< Real2, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::BinaryExpressionTemplate< ConstView1, ConstView2, Containers::Expressions::Min >( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -min( const Containers::VectorView< Real1, Device, Index >& a, const Containers::Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Containers::Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename Containers::Vector< Real2, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::BinaryExpressionTemplate< ConstView1, ConstView2, Containers::Expressions::Min >( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -min( const Containers::Vector< Real1, Device, Index, Allocator >& a, const Containers::VectorView< Real2, Device, Index >& b ) -{ - using ConstView1 = typename Containers::Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename Containers::Vector< Real2, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::BinaryExpressionTemplate< ConstView1, ConstView2, Containers::Expressions::Min >( a.getConstView(), b.getConstView() ); -} - -//// -// Max -template< typename Real, typename Device, typename Index, typename Allocator, typename ET, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -max( const Containers::Vector< Real, Device, Index, Allocator >& a, const ET& b ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::BinaryExpressionTemplate< ConstView, ET, Containers::Expressions::Max >( a.getConstView(), b ); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Allocator, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -max( const ET& a, const Containers::Vector< Real, Device, Index, Allocator >& b ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::BinaryExpressionTemplate< ET, ConstView, Containers::Expressions::Max >( a, b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -max( const Containers::Vector< Real1, Device, Index, Allocator >& a, const Containers::Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Containers::Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename Containers::Vector< Real2, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::BinaryExpressionTemplate< ConstView1, ConstView2, Containers::Expressions::Max >( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -max( const Containers::VectorView< Real1, Device, Index >& a, const Containers::Vector< Real2, Device, Index, Allocator >& b ) -{ - using ConstView1 = typename Containers::Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename Containers::Vector< Real2, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::BinaryExpressionTemplate< ConstView1, ConstView2, Containers::Expressions::Max >( a.getConstView(), b.getConstView() ); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -max( const Containers::Vector< Real1, Device, Index, Allocator >& a, const Containers::VectorView< Real2, Device, Index >& b ) -{ - using ConstView1 = typename Containers::Vector< Real1, Device, Index, Allocator >::ConstViewType; - using ConstView2 = typename Containers::Vector< Real2, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::BinaryExpressionTemplate< ConstView1, ConstView2, Containers::Expressions::Max >( a.getConstView(), b.getConstView() ); -} - -//// -// Dot product - the same as scalar product, just for convenience -#ifdef DOXYGEN_ONLY -/** - * \brief Computes scalar product of vector and vector expression. Equivalent to \ref TNL::Containers::operator,. - * - * @param a input vector - * @param b input vector expression - * @return scalar product of vector and vector expression - */ -template< typename ET1, typename ET2 > -auto -dot( const ET1& a, const ET2& b ) {} -#else - -template< typename Real, typename Device, typename Index, typename Allocator, typename ET, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -dot( const Containers::Vector< Real, Device, Index, Allocator >& a, const ET& b ) -{ - return (a, b); -} - -template< typename ET, typename Real, typename Device, typename Index, typename Allocator, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -dot( const ET& a, const Containers::Vector< Real, Device, Index, Allocator >& b ) -{ - return (a, b); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -dot( const Containers::Vector< Real1, Device, Index, Allocator >& a, const Containers::Vector< Real2, Device, Index, Allocator >& b ) -{ - return (a, b); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -dot( const Containers::VectorView< Real1, Device, Index >& a, const Containers::Vector< Real2, Device, Index, Allocator >& b ) -{ - return (a, b); -} - -template< typename Real1, typename Real2, typename Device, typename Index, typename Allocator > -auto -dot( const Containers::Vector< Real1, Device, Index, Allocator >& a, const Containers::VectorView< Real2, Device, Index >& b ) -{ - return (a, b); -} -#endif // DOXYGEN_ONLY - - -//// -// Abs -template< typename Real, typename Device, typename Index, typename Allocator > -auto -abs( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Abs >( a.getConstView() ); -} - -//// -// Power -template< typename Real, typename Device, typename Index, typename Allocator, typename ExpType > -auto -pow( const Containers::Vector< Real, Device, Index, Allocator >& a, const ExpType& exp ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::BinaryExpressionTemplate< ConstView, ExpType, Containers::Expressions::Pow >( a.getConstView(), exp ); -} - -//// -// Exp -template< typename Real, typename Device, typename Index, typename Allocator > -auto -exp( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Exp >( a.getConstView() ); -} - -//// -// Sqrt -template< typename Real, typename Device, typename Index, typename Allocator > -auto -sqrt( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Sqrt >( a.getConstView() ); -} - -//// -// Cbrt -template< typename Real, typename Device, typename Index, typename Allocator > -auto -cbrt( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Cbrt >( a.getConstView() ); -} - -//// -// Log -template< typename Real, typename Device, typename Index, typename Allocator > -auto -log( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Log >( a.getConstView() ); -} - -//// -// Log10 -template< typename Real, typename Device, typename Index, typename Allocator > -auto -log10( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Log10 >( a.getConstView() ); -} - -//// -// Log2 -template< typename Real, typename Device, typename Index, typename Allocator > -auto -log2( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Log2 >( a.getConstView() ); -} - -//// -// Sine -template< typename Real, typename Device, typename Index, typename Allocator > -auto -sin( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Sin >( a.getConstView() ); -} - -//// -// Cosine -template< typename Real, typename Device, typename Index, typename Allocator > -auto -cos( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Cos >( a.getConstView() ); -} - -//// -// Tangent -template< typename Real, typename Device, typename Index, typename Allocator > -auto -tan( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Tan >( a.getConstView() ); -} - -//// -// Asin -template< typename Real, typename Device, typename Index, typename Allocator > -auto -asin( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Asin >( a.getConstView() ); -} - -//// -// Acos -template< typename Real, typename Device, typename Index, typename Allocator > -auto -acos( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Acos >( a.getConstView() ); -} - -//// -// Atan -template< typename Real, typename Device, typename Index, typename Allocator > -auto -atan( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Atan >( a.getConstView() ); -} - -//// -// Sinh -template< typename Real, typename Device, typename Index, typename Allocator > -auto -sinh( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Sinh >( a.getConstView() ); -} - -//// -// Cosh -template< typename Real, typename Device, typename Index, typename Allocator > -auto -cosh( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Cosh >( a.getConstView() ); -} - -//// -// Tanh -template< typename Real, typename Device, typename Index, typename Allocator > -auto -tanh( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Tanh >( a.getConstView() ); -} - -//// -// Asinh -template< typename Real, typename Device, typename Index, typename Allocator > -auto -asinh( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Asinh >( a.getConstView() ); -} - -//// -// Acosh -template< typename Real, typename Device, typename Index, typename Allocator > -auto -acosh( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Acosh >( a.getConstView() ); -} - -//// -// Atanh -template< typename Real, typename Device, typename Index, typename Allocator > -auto -atanh( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Atanh >( a.getConstView() ); -} - -//// -// Floor -template< typename Real, typename Device, typename Index, typename Allocator > -auto -floor( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Floor >( a.getConstView() ); -} - -//// -// Ceil -template< typename Real, typename Device, typename Index, typename Allocator > -auto -ceil( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Ceil >( a.getConstView() ); -} - -//// -// Sign -template< typename Real, typename Device, typename Index, typename Allocator > -auto -sign( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - using ConstView = typename Containers::Vector< Real, Device, Index, Allocator >::ConstViewType; - return Containers::Expressions::UnaryExpressionTemplate< ConstView, Containers::Expressions::Sign >( a.getConstView() ); -} - -//// -// Cast -template< typename ResultType, typename Real, typename Device, typename Index, typename Allocator, - // workaround: templated type alias cannot be declared at block level - template<typename> class Operation = Containers::Expressions::Cast< ResultType >::template Operation > -auto -cast( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< decltype(a.getConstView()), Operation >( a.getConstView() ); -} - -//// -// Vertical operations - min -template< typename Real, - typename Device, - typename Index, typename Allocator > -Real -min( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - return Containers::Expressions::ExpressionMin( a.getConstView() ); -} - -template< typename Real, - typename Device, - typename Index, typename Allocator > -std::pair< Index, std::decay_t< Real > > -argMin( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - return Containers::Expressions::ExpressionArgMin( a.getConstView() ); -} - -template< typename Real, - typename Device, - typename Index, typename Allocator > -Real -max( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - return Containers::Expressions::ExpressionMax( a.getConstView() ); -} - -template< typename Real, - typename Device, - typename Index, typename Allocator > -std::pair< Index, std::decay_t< Real > > -argMax( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - return Containers::Expressions::ExpressionArgMax( a.getConstView() ); -} - -/** - * \brief Computes sum of all vector elements. - * - * @param a input vector - * @return sum of all vector elements - */ -template< typename Real, - typename Device, - typename Index, typename Allocator > -auto -sum( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - return Containers::Expressions::ExpressionSum( a.getConstView() ); -} - -/** - * \brief Computes maximum norm of a vector. - * \anchor TNL__maxNorm - * - * @param a input vector - * @return maximum norm - */ -template< typename Real, - typename Device, - typename Index, typename Allocator > -auto -maxNorm( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - return max( abs( a ) ); -} - -template< typename Real, - typename Device, - typename Index, typename Allocator > -auto -l1Norm( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - return Containers::Expressions::ExpressionL1Norm( a.getConstView() ); -} - -template< typename Real, - typename Device, - typename Index, typename Allocator > -auto -l2Norm( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - return TNL::sqrt( Containers::Expressions::ExpressionL2Norm( a.getConstView() ) ); -} - -template< typename Real, - typename Device, - typename Index, typename Allocator, - typename Real2 > -auto -lpNorm( const Containers::Vector< Real, Device, Index, Allocator >& a, const Real2& p ) -// since (1.0 / p) has type double, TNL::pow returns double --> double -{ - if( p == 1.0 ) - return l1Norm( a ); - if( p == 2.0 ) - return l2Norm( a ); - return TNL::pow( Containers::Expressions::ExpressionLpNorm( a.getConstView(), p ), 1.0 / p ); -} - -/** - * \brief Computes product of all vector elements. - * @param a - * @return - */ -template< typename Real, - typename Device, - typename Index, typename Allocator > -auto -product( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - return Containers::Expressions::ExpressionProduct( a.getConstView() ); -} - -template< typename Real, - typename Device, - typename Index, typename Allocator > -auto -logicalOr( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - return Containers::Expressions::ExpressionLogicalOr( a.getConstView() ); -} - -template< typename Real, - typename Device, - typename Index, typename Allocator > -auto -binaryOr( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - return Containers::Expressions::ExpressionBinaryOr( a.getConstView() ); -} - -template< typename Real, - typename Device, - typename Index, typename Allocator > -auto -logicalAnd( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - return Containers::Expressions::ExpressionLogicalAnd( a.getConstView() ); -} - -template< typename Real, - typename Device, - typename Index, typename Allocator > -auto -binaryAnd( const Containers::Vector< Real, Device, Index, Allocator >& a ) -{ - return Containers::Expressions::ExpressionBinaryAnd( a.getConstView() ); -} - -} // namespace TNL diff --git a/src/TNL/Containers/VectorView.h b/src/TNL/Containers/VectorView.h index 1a144ea5cde79951ee059f386859322eba18cf57..4c5262d30f4ec904d176da1a33313ad94d64cd0f 100644 --- a/src/TNL/Containers/VectorView.h +++ b/src/TNL/Containers/VectorView.h @@ -138,7 +138,7 @@ public: */ template< typename VectorExpression, typename..., - typename = std::enable_if_t< Expressions::IsExpressionTemplate< VectorExpression >::value > > + typename = std::enable_if_t< Expressions::HasEnabledExpressionTemplates< VectorExpression >::value && ! IsArrayType< VectorExpression >::value > > VectorView& operator=( const VectorExpression& expression ); /** @@ -294,8 +294,15 @@ public: void segmentedScan( const VectorExpression& expression, FlagsArray& flags, IndexType begin = 0, IndexType end = 0 ); }; +// Enable expression templates for VectorView +namespace Expressions { + template< typename Real, typename Device, typename Index > + struct HasEnabledExpressionTemplates< VectorView< Real, Device, Index > > + : std::true_type + {}; +} // namespace Expressions + } // namespace Containers } // namespace TNL #include <TNL/Containers/VectorView.hpp> -#include <TNL/Containers/VectorViewExpressions.h> diff --git a/src/TNL/Containers/VectorViewExpressions.h b/src/TNL/Containers/VectorViewExpressions.h deleted file mode 100644 index 6168b54066d74ac5151e40ed1100116353759556..0000000000000000000000000000000000000000 --- a/src/TNL/Containers/VectorViewExpressions.h +++ /dev/null @@ -1,740 +0,0 @@ -/*************************************************************************** - VectorViewExpressions.h - description - ------------------- - begin : Apr 27, 2019 - copyright : (C) 2019 by Tomas Oberhuber et al. - email : tomas.oberhuber@fjfi.cvut.cz - ***************************************************************************/ - -/* See Copyright Notice in tnl/Copyright */ - -#pragma once -#ifndef DOXYGEN_ONLY - -#include <TNL/Containers/Expressions/ExpressionTemplates.h> - -#include "VectorView.h" - -namespace TNL { -namespace Containers { - -//// -// Addition -template< typename Real, typename Device, typename Index, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator+( const VectorView< Real, Device, Index >& a, const ET& b ) -{ - return Expressions::BinaryExpressionTemplate< VectorView< Real, Device, Index >, ET, Expressions::Addition >( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator+( const ET& a, const VectorView< Real, Device, Index >& b ) -{ - return Expressions::BinaryExpressionTemplate< ET, VectorView< Real, Device, Index >, Expressions::Addition >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index > -auto -operator+( const VectorView< Real1, Device, Index >& a, const VectorView< Real2, Device, Index >& b ) -{ - return Expressions::BinaryExpressionTemplate< VectorView< Real1, Device, Index >, VectorView< Real2, Device, Index >, Expressions::Addition >( a, b ); -} - -//// -// Subtraction -template< typename Real, typename Device, typename Index, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator-( const VectorView< Real, Device, Index >& a, const ET& b ) -{ - return Expressions::BinaryExpressionTemplate< VectorView< Real, Device, Index >, ET, Expressions::Subtraction >( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator-( const ET& a, const VectorView< Real, Device, Index >& b ) -{ - return Expressions::BinaryExpressionTemplate< ET, VectorView< Real, Device, Index >, Expressions::Subtraction >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index > -auto -operator-( const VectorView< Real1, Device, Index >& a, const VectorView< Real2, Device, Index >& b ) -{ - return Expressions::BinaryExpressionTemplate< VectorView< Real1, Device, Index >, VectorView< Real2, Device, Index >, Expressions::Subtraction >( a, b ); -} - -//// -// Multiplication -template< typename Real, typename Device, typename Index, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator*( const VectorView< Real, Device, Index >& a, const ET& b ) -{ - return Expressions::BinaryExpressionTemplate< VectorView< Real, Device, Index >, ET, Expressions::Multiplication >( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator*( const ET& a, const VectorView< Real, Device, Index >& b ) -{ - return Expressions::BinaryExpressionTemplate< ET, VectorView< Real, Device, Index >, Expressions::Multiplication >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index > -auto -operator*( const VectorView< Real1, Device, Index >& a, const VectorView< Real2, Device, Index >& b ) -{ - return Expressions::BinaryExpressionTemplate< VectorView< Real1, Device, Index >, VectorView< Real2, Device, Index >, Expressions::Multiplication >( a, b ); -} - -//// -// Division -template< typename Real, typename Device, typename Index, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator/( const VectorView< Real, Device, Index >& a, const ET& b ) -{ - return Expressions::BinaryExpressionTemplate< VectorView< Real, Device, Index >, ET, Expressions::Division >( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator/( const ET& a, const VectorView< Real, Device, Index >& b ) -{ - return Expressions::BinaryExpressionTemplate< ET, VectorView< Real, Device, Index >, Expressions::Division >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index > -auto -operator/( const VectorView< Real1, Device, Index >& a, const VectorView< Real2, Device, Index >& b ) -{ - return Expressions::BinaryExpressionTemplate< VectorView< Real1, Device, Index >, VectorView< Real2, Device, Index >, Expressions::Division >( a, b ); -} - -//// -// Comparison operations - operator == -template< typename Real, typename Device, typename Index, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator==( const VectorView< Real, Device, Index >& a, const ET& b ) -{ - return Expressions::Comparison< VectorView< Real, Device, Index >, ET >::EQ( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator==( const ET& a, const VectorView< Real, Device, Index >& b ) -{ - return Expressions::Comparison< ET, VectorView< Real, Device, Index > >::EQ( a, b ); -} - -template< typename Real1, typename Real2, typename Device1, typename Device2, typename Index > -bool -operator==( const VectorView< Real1, Device1, Index >& a, const VectorView< Real2, Device2, Index >& b ) -{ - return Expressions::Comparison< VectorView< Real1, Device1, Index >, VectorView< Real2, Device2, Index > >::EQ( a, b ); -} - -//// -// Comparison operations - operator != -template< typename Real, typename Device, typename Index, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator!=( const VectorView< Real, Device, Index >& a, const ET& b ) -{ - return Expressions::Comparison< VectorView< Real, Device, Index >, ET >::NE( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator!=( const ET& a, const VectorView< Real, Device, Index >& b ) -{ - return Expressions::Comparison< ET, VectorView< Real, Device, Index > >::NE( a, b ); -} - -template< typename Real1, typename Real2, typename Device1, typename Device2, typename Index > -bool -operator!=( const VectorView< Real1, Device1, Index >& a, const VectorView< Real2, Device2, Index >& b ) -{ - return ! (a == b); -} - -//// -// Comparison operations - operator < -template< typename Real, typename Device, typename Index, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator<( const VectorView< Real, Device, Index >& a, const ET& b ) -{ - return Expressions::Comparison< VectorView< Real, Device, Index >, ET >::LT( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator<( const ET& a, const VectorView< Real, Device, Index >& b ) -{ - return Expressions::Comparison< ET, VectorView< Real, Device, Index > >::LT( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index > -bool -operator<( const VectorView< Real1, Device, Index >& a, const VectorView< Real2, Device, Index >& b ) -{ - return Expressions::Comparison< VectorView< Real1, Device, Index >, VectorView< Real2, Device, Index > >::LT( a, b ); -} - -//// -// Comparison operations - operator <= -template< typename Real, typename Device, typename Index, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator<=( const VectorView< Real, Device, Index >& a, const ET& b ) -{ - return Expressions::Comparison< VectorView< Real, Device, Index >, ET >::LE( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator<=( const ET& a, const VectorView< Real, Device, Index >& b ) -{ - return Expressions::Comparison< ET, VectorView< Real, Device, Index > >::LE( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index > -bool -operator<=( const VectorView< Real1, Device, Index >& a, const VectorView< Real2, Device, Index >& b ) -{ - return Expressions::Comparison< VectorView< Real1, Device, Index >, VectorView< Real2, Device, Index > >::LE( a, b ); -} - -//// -// Comparison operations - operator > -template< typename Real, typename Device, typename Index, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator>( const VectorView< Real, Device, Index >& a, const ET& b ) -{ - return Expressions::Comparison< VectorView< Real, Device, Index >, ET >::GT( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator>( const ET& a, const VectorView< Real, Device, Index >& b ) -{ - return Expressions::Comparison< ET, VectorView< Real, Device, Index > >::GT( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index > -bool -operator>( const VectorView< Real1, Device, Index >& a, const VectorView< Real2, Device, Index >& b ) -{ - return Expressions::Comparison< VectorView< Real1, Device, Index >, VectorView< Real2, Device, Index > >::GT( a, b ); -} - -//// -// Comparison operations - operator >= -template< typename Real, typename Device, typename Index, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator>=( const VectorView< Real, Device, Index >& a, const ET& b ) -{ - return Expressions::Comparison< VectorView< Real, Device, Index >, ET >::GE( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -bool -operator>=( const ET& a, const VectorView< Real, Device, Index >& b ) -{ - return Expressions::Comparison< ET, VectorView< Real, Device, Index > >::GE( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index > -bool -operator>=( const VectorView< Real1, Device, Index >& a, const VectorView< Real2, Device, Index >& b ) -{ - return Expressions::Comparison< VectorView< Real1, Device, Index >, VectorView< Real2, Device, Index > >::GE( a, b ); -} - -//// -// Minus -template< typename Real, typename Device, typename Index > -auto -operator-( const VectorView< Real, Device, Index >& a ) -{ - return Expressions::UnaryExpressionTemplate< VectorView< Real, Device, Index >, Expressions::Minus >( a ); -} - -//// -// Scalar product -template< typename Real, typename Device, typename Index, typename ET, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator,( const VectorView< Real, Device, Index >& a, const ET& b ) -{ - return Expressions::ExpressionSum( a * b ); -} - -template< typename ET, typename Real, typename Device, typename Index, - typename..., typename = std::enable_if_t< Expressions::IsNumericExpression<ET>::value > > -auto -operator,( const ET& a, const VectorView< Real, Device, Index >& b ) -{ - return Expressions::ExpressionSum( a * b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index > -auto -operator,( const VectorView< Real1, Device, Index >& a, const VectorView< Real2, Device, Index >& b ) -{ - return Expressions::ExpressionSum( a * b ); -} - -} // namespace Containers - -//// -// All functions are supposed to be in namespace TNL - -//// -// Min -template< typename Real, typename Device, typename Index, typename ET, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -min( const Containers::VectorView< Real, Device, Index >& a, const ET& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, ET, Containers::Expressions::Min >( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -min( const ET& a, const Containers::VectorView< Real, Device, Index >& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< ET, Containers::VectorView< Real, Device, Index >, Containers::Expressions::Min >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index > -auto -min( const Containers::VectorView< Real1, Device, Index >& a, const Containers::VectorView< Real2, Device, Index >& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real1, Device, Index >, Containers::VectorView< Real2, Device, Index >, Containers::Expressions::Min >( a, b ); -} - -//// -// Max -template< typename Real, typename Device, typename Index, typename ET, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -max( const Containers::VectorView< Real, Device, Index >& a, const ET& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, ET, Containers::Expressions::Max >( a, b ); -} - -template< typename ET, typename Real, typename Device, typename Index, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -max( const ET& a, const Containers::VectorView< Real, Device, Index >& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< ET, Containers::VectorView< Real, Device, Index >, Containers::Expressions::Max >( a, b ); -} - -template< typename Real1, typename Real2, typename Device, typename Index > -auto -max( const Containers::VectorView< Real1, Device, Index >& a, const Containers::VectorView< Real2, Device, Index >& b ) -{ - return Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real1, Device, Index >, Containers::VectorView< Real2, Device, Index >, Containers::Expressions::Max >( a, b ); -} - -//// -// Dot product - the same as scalar product, just for convenience -template< typename Real, typename Device, typename Index, typename ET, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -dot( const Containers::VectorView< Real, Device, Index >& a, const ET& b ) -{ - return (a, b); -} - -template< typename ET, typename Real, typename Device, typename Index, - typename..., typename = std::enable_if_t< Containers::Expressions::IsNumericExpression<ET>::value > > -auto -dot( const ET& a, const Containers::VectorView< Real, Device, Index >& b ) -{ - return (a, b); -} - -template< typename Real1, typename Real2, typename Device, typename Index1, typename Index2 > -auto -dot( const Containers::VectorView< Real1, Device, Index1 >& a, const Containers::VectorView< Real2, Device, Index2 >& b ) -{ - return (a, b); -} - - -//// -// Abs -template< typename Real, typename Device, typename Index > -auto -abs( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Abs >( a ); -} - -//// -// Power -template< typename Real, typename Device, typename Index, typename ExpType > -auto -pow( const Containers::VectorView< Real, Device, Index >& a, const ExpType& exp ) -{ - return Containers::Expressions::BinaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, ExpType, Containers::Expressions::Pow >( a, exp ); -} - -//// -// Exp -template< typename Real, typename Device, typename Index > -auto -exp( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Exp >( a ); -} - -//// -// Sqrt -template< typename Real, typename Device, typename Index > -auto -sqrt( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Sqrt >( a ); -} - -//// -// Cbrt -template< typename Real, typename Device, typename Index > -auto -cbrt( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Cbrt >( a ); -} - -//// -// Log -template< typename Real, typename Device, typename Index > -auto -log( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Log >( a ); -} - -//// -// Log10 -template< typename Real, typename Device, typename Index > -auto -log10( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Log10 >( a ); -} - -//// -// Log2 -template< typename Real, typename Device, typename Index > -auto -log2( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Log2 >( a ); -} - -//// -// Sine -template< typename Real, typename Device, typename Index > -auto -sin( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Sin >( a ); -} - -//// -// Cosine -template< typename Real, typename Device, typename Index > -auto -cos( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Cos >( a ); -} - -//// -// Tangent -template< typename Real, typename Device, typename Index > -auto -tan( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Tan >( a ); -} - -//// -// Asin -template< typename Real, typename Device, typename Index > -auto -asin( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Asin >( a ); -} - -//// -// Acos -template< typename Real, typename Device, typename Index > -auto -acos( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Acos >( a ); -} - -//// -// Atan -template< typename Real, typename Device, typename Index > -auto -atan( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Atan >( a ); -} - -//// -// Sinh -template< typename Real, typename Device, typename Index > -auto -sinh( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Sinh >( a ); -} - -//// -// Cosh -template< typename Real, typename Device, typename Index > -auto -cosh( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Cosh >( a ); -} - -//// -// Tanh -template< typename Real, typename Device, typename Index > -auto -tanh( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Tanh >( a ); -} - -//// -// Asinh -template< typename Real, typename Device, typename Index > -auto -asinh( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Asinh >( a ); -} - -//// -// Acosh -template< typename Real, typename Device, typename Index > -auto -acosh( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Acosh >( a ); -} - -//// -// Atanh -template< typename Real, typename Device, typename Index > -auto -atanh( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Atanh >( a ); -} - -//// -// Floor -template< typename Real, typename Device, typename Index > -auto -floor( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Floor >( a ); -} - -//// -// Ceil -template< typename Real, typename Device, typename Index > -auto -ceil( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Ceil >( a ); -} - -//// -// Sign -template< typename Real, typename Device, typename Index > -auto -sign( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< Containers::VectorView< Real, Device, Index >, Containers::Expressions::Sign >( a ); -} - -//// -// Cast -template< typename ResultType, typename Real, typename Device, typename Index, - // workaround: templated type alias cannot be declared at block level - template<typename> class Operation = Containers::Expressions::Cast< ResultType >::template Operation > -auto -cast( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::UnaryExpressionTemplate< std::decay_t<decltype(a)>, Operation >( a ); -} - -//// -// Vertical operations - min -template< typename Real, - typename Device, - typename Index > -Real -min( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::ExpressionMin( a ); -} - -template< typename Real, - typename Device, - typename Index > -std::pair< Index, std::decay_t< Real > > -argMin( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::ExpressionArgMin( a ); -} - -template< typename Real, - typename Device, - typename Index > -Real -max( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::ExpressionMax( a ); -} - -template< typename Real, - typename Device, - typename Index > -std::pair< Index, std::decay_t< Real > > -argMax( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::ExpressionArgMax( a ); -} - -template< typename Real, - typename Device, - typename Index > -auto -sum( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::ExpressionSum( a ); -} - -template< typename Real, - typename Device, - typename Index > -auto -maxNorm( const Containers::VectorView< Real, Device, Index >& a ) -{ - return max( abs( a ) ); -} - -template< typename Real, - typename Device, - typename Index > -auto -l1Norm( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::ExpressionL1Norm( a ); -} - -template< typename Real, - typename Device, - typename Index > -auto -l2Norm( const Containers::VectorView< Real, Device, Index >& a ) -{ - return TNL::sqrt( Containers::Expressions::ExpressionL2Norm( a ) ); -} - -template< typename Real, - typename Device, - typename Index, - typename Real2 > -auto -lpNorm( const Containers::VectorView< Real, Device, Index >& a, const Real2& p ) -// since (1.0 / p) has type double, TNL::pow returns double --> double -{ - if( p == 1.0 ) - return l1Norm( a ); - if( p == 2.0 ) - return l2Norm( a ); - return TNL::pow( Containers::Expressions::ExpressionLpNorm( a, p ), 1.0 / p ); -} - -template< typename Real, - typename Device, - typename Index > -auto -product( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::ExpressionProduct( a ); -} - -template< typename Real, - typename Device, - typename Index > -auto -logicalOr( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::ExpressionLogicalOr( a ); -} - -template< typename Real, - typename Device, - typename Index > -auto -binaryOr( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::ExpressionBinaryOr( a ); -} - -template< typename Real, - typename Device, - typename Index > -auto -logicalAnd( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::ExpressionLogicalAnd( a ); -} - -template< typename Real, - typename Device, - typename Index > -auto -binaryAnd( const Containers::VectorView< Real, Device, Index >& a ) -{ - return Containers::Expressions::ExpressionBinaryAnd( a ); -} - -} // namespace TNL -#endif // DOXYGEN_ONLY diff --git a/src/TNL/Containers/detail/StaticArrayAssignment.h b/src/TNL/Containers/detail/StaticArrayAssignment.h index 9a8d7d3eeb7bdbcfd9814ad3754d4ba9131004b5..6ba6c8e02a1ab81388203cef969eca594bef29c6 100644 --- a/src/TNL/Containers/detail/StaticArrayAssignment.h +++ b/src/TNL/Containers/detail/StaticArrayAssignment.h @@ -21,7 +21,7 @@ struct AssignArrayFunctor { template< typename LeftValue, typename RightValue > __cuda_callable__ - void operator()( int i, LeftValue& data, const RightValue& v ) const + void operator()( int i, LeftValue* data, const RightValue* v ) const { data[ i ] = v[ i ]; } @@ -31,7 +31,7 @@ struct AssignValueFunctor { template< typename LeftValue, typename RightValue > __cuda_callable__ - void operator()( int i, LeftValue& data, const RightValue& v ) const + void operator()( int i, LeftValue* data, const RightValue& v ) const { data[ i ] = v; } @@ -53,7 +53,7 @@ struct StaticArrayAssignment< StaticArray, T, true > static void assign( StaticArray& a, const T& v ) { static_assert( StaticArray::getSize() == T::getSize(), "Cannot assign static arrays with different size." ); - Algorithms::StaticFor< 0, StaticArray::getSize() >::exec( AssignArrayFunctor{}, a.getData(), v ); + Algorithms::StaticFor< 0, StaticArray::getSize() >::exec( AssignArrayFunctor{}, a.getData(), v.getData() ); } }; @@ -68,7 +68,7 @@ struct StaticArrayAssignment< StaticArray, T, false > __cuda_callable__ static void assign( StaticArray& a, const T& v ) { - Algorithms::StaticFor< 0, StaticArray::getSize() >::exec( AssignValueFunctor{}, a, v ); + Algorithms::StaticFor< 0, StaticArray::getSize() >::exec( AssignValueFunctor{}, a.getData(), v ); } }; diff --git a/src/TNL/Math.h b/src/TNL/Math.h index 321cc7ce39e0d0beb8c3c3c2a5ab3ac7bbfddbdd..01fd527cb452d810f624e3f9f94e21fac9302889 100644 --- a/src/TNL/Math.h +++ b/src/TNL/Math.h @@ -79,7 +79,7 @@ ResultType max( const T1& a, const T2& b ) * \brief This function returns absolute value of given number \e n. */ template< class T, - std::enable_if_t< ! std::is_unsigned<T>::value, bool > = true > + std::enable_if_t< ! std::is_unsigned<T>::value && ! std::is_class<T>::value, bool > = true > __cuda_callable__ inline T abs( const T& n ) { @@ -147,7 +147,9 @@ ResultType argAbsMax( const T1& a, const T2& b ) /** * \brief This function returns the result of \e base to the power of \e exp. */ -template< typename T1, typename T2, typename ResultType = typename std::common_type< T1, T2 >::type > +template< typename T1, typename T2, typename ResultType = typename std::common_type< T1, T2 >::type, + // enable_if is necessary to avoid ambiguity in vector expressions + std::enable_if_t< ! std::is_class<T1>::value && ! std::is_class<T2>::value, bool > = true > __cuda_callable__ inline ResultType pow( const T1& base, const T2& exp ) { @@ -458,7 +460,9 @@ void swap( Type& a, Type& b ) * It extracts the sign of the number \e a. In other words, the signum function projects * negative numbers to value -1, positive numbers to value 1 and zero to value 0. */ -template< class T > +template< class T, + // enable_if is necessary to avoid ambiguity in vector expressions + std::enable_if_t< ! HasSubscriptOperator<T>::value, bool > = true > __cuda_callable__ T sign( const T& a ) { diff --git a/src/TNL/Matrices/MatrixOperations.h b/src/TNL/Matrices/MatrixOperations.h index 354b0a9e19d89ddb3cb457ce578752c8f1f513b0..d37258d615719ae7039a86a885f8ad839d69f4e8 100644 --- a/src/TNL/Matrices/MatrixOperations.h +++ b/src/TNL/Matrices/MatrixOperations.h @@ -46,13 +46,13 @@ public: template< typename RealType, typename IndexType > static void - gemv( const IndexType& m, - const IndexType& n, - const RealType& alpha, + gemv( const IndexType m, + const IndexType n, + const RealType alpha, const RealType* A, - const IndexType& lda, + const IndexType lda, const RealType* x, - const RealType& beta, + const RealType beta, RealType* y ) { TNL_ASSERT_GT( m, 0, "m must be positive" ); @@ -164,16 +164,16 @@ public: template< typename RealType, typename IndexType > static void - geam( const IndexType& m, - const IndexType& n, - const RealType& alpha, + geam( const IndexType m, + const IndexType n, + const RealType alpha, const RealType* A, - const IndexType& lda, - const RealType& beta, + const IndexType lda, + const RealType beta, const RealType* B, - const IndexType& ldb, + const IndexType ldb, RealType* C, - const IndexType& ldc ) + const IndexType ldc ) { TNL_ASSERT_GT( m, 0, "m must be positive" ); TNL_ASSERT_GT( n, 0, "n must be positive" ); @@ -326,13 +326,13 @@ public: template< typename RealType, typename IndexType > static void - gemv( const IndexType& m, - const IndexType& n, - const RealType& alpha, + gemv( const IndexType m, + const IndexType n, + const RealType alpha, const RealType* A, - const IndexType& lda, + const IndexType lda, const RealType* x, - const RealType& beta, + const RealType beta, RealType* y ) { TNL_ASSERT( m <= lda, ); @@ -375,16 +375,16 @@ public: template< typename RealType, typename IndexType > static void - geam( const IndexType& m, - const IndexType& n, - const RealType& alpha, + geam( const IndexType m, + const IndexType n, + const RealType alpha, const RealType* A, - const IndexType& lda, - const RealType& beta, + const IndexType lda, + const RealType beta, const RealType* B, - const IndexType& ldb, + const IndexType ldb, RealType* C, - const IndexType& ldc ) + const IndexType ldc ) { TNL_ASSERT_GT( m, 0, "m must be positive" ); TNL_ASSERT_GT( n, 0, "n must be positive" ); diff --git a/src/TNL/Meshes/Geometry/getEntityMeasure.h b/src/TNL/Meshes/Geometry/getEntityMeasure.h index a3381ed96b1e72ddc2f0ccf25bbbdccd7e71739a..070c28c583a916a789e49166ea90d10eadc9bd63 100644 --- a/src/TNL/Meshes/Geometry/getEntityMeasure.h +++ b/src/TNL/Meshes/Geometry/getEntityMeasure.h @@ -116,8 +116,8 @@ getEntityMeasure( const Mesh< MeshConfig, Device > & mesh, const auto& v1 = mesh.template getEntity< 0 >( entity.template getSubentityIndex< 0 >( 1 ) ); const auto& v2 = mesh.template getEntity< 0 >( entity.template getSubentityIndex< 0 >( 2 ) ); using Point = decltype( v0.getPoint() ); - Point p1 = v2.getPoint() - v0.getPoint(); - Point p2 = v1.getPoint() - v0.getPoint(); + const Point p1 = v2.getPoint() - v0.getPoint(); + const Point p2 = v1.getPoint() - v0.getPoint(); return getTriangleArea( p1, p2 ); } @@ -134,7 +134,10 @@ getEntityMeasure( const Mesh< MeshConfig, Device > & mesh, const auto& v1 = mesh.template getEntity< 0 >( entity.template getSubentityIndex< 0 >( 1 ) ); const auto& v2 = mesh.template getEntity< 0 >( entity.template getSubentityIndex< 0 >( 2 ) ); const auto& v3 = mesh.template getEntity< 0 >( entity.template getSubentityIndex< 0 >( 3 ) ); - return getTriangleArea( v2.getPoint() - v0.getPoint(), v3.getPoint() - v1.getPoint() ); + using Point = decltype( v0.getPoint() ); + const Point p1 = v2.getPoint() - v0.getPoint(); + const Point p2 = v3.getPoint() - v1.getPoint(); + return getTriangleArea( p1, p2 ); } template< typename VectorExpression > diff --git a/src/TNL/Meshes/GridDetails/Grid1D.h b/src/TNL/Meshes/GridDetails/Grid1D.h index 81811fe9005c44bb1239f06fe423f4d566c7c77c..67b6e78e8c7f0c3a243abc80dab2fe4d319ac8b1 100644 --- a/src/TNL/Meshes/GridDetails/Grid1D.h +++ b/src/TNL/Meshes/GridDetails/Grid1D.h @@ -180,16 +180,6 @@ class Grid< 1, Real, Device, Index > : public Object */ __cuda_callable__ inline RealType getSmallestSpaceStep() const; - - - template< typename GridFunction > - typename GridFunction::RealType getDifferenceAbsMax( const GridFunction& f1, - const GridFunction& f2 ) const; - - template< typename GridFunction > - typename GridFunction::RealType getDifferenceLpNorm( const GridFunction& f1, - const GridFunction& f2, - const typename GridFunction::RealType& p ) const; void setDistMesh(DistributedMeshType * distMesh); diff --git a/src/TNL/Meshes/GridDetails/Grid1D_impl.h b/src/TNL/Meshes/GridDetails/Grid1D_impl.h index 279ec9810184ea097212e45984183ad1ddc97e70..679b473f1cebdc9e95a515676aec7bbceeb13229 100644 --- a/src/TNL/Meshes/GridDetails/Grid1D_impl.h +++ b/src/TNL/Meshes/GridDetails/Grid1D_impl.h @@ -290,51 +290,6 @@ getSmallestSpaceStep() const return this->spaceSteps.x(); } -template< typename Real, - typename Device, - typename Index > - template< typename GridFunction > -typename GridFunction::RealType -Grid< 1, Real, Device, Index >::getDifferenceAbsMax( const GridFunction& f1, - const GridFunction& f2 ) const -{ - typename GridFunction::RealType maxDiff( -1.0 ); - - Cell cell( *this ); - for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < getDimensions().x(); - cell.getCoordinates().x()++ ) - { - IndexType c = this->getEntityIndex( cell ); - maxDiff = max( maxDiff, abs( f1[ c ] - f2[ c ] ) ); - } - return maxDiff; -} - -template< typename Real, - typename Device, - typename Index > - template< typename GridFunction > -typename GridFunction::RealType -Grid< 1, Real, Device, Index >::getDifferenceLpNorm( const GridFunction& f1, - const GridFunction& f2, - const typename GridFunction::RealType& p ) const -{ - typedef typename GridFunction::RealType FunctionRealType; - FunctionRealType lpNorm( 0.0 ), cellVolume( this->getSpaceSteps().x() ); - - Cell cell( *this ); - for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < getDimensions().x(); - cell.getCoordinates().x()++ ) - { - IndexType c = this->getEntityIndex( cell ); - lpNorm += ::pow( abs( f1[ c ] - f2[ c ] ), p ); - } - lpNorm *= cellVolume; - return ::pow( lpNorm, 1.0 / p ); -} - template< typename Real, typename Device, typename Index > diff --git a/src/TNL/Meshes/GridDetails/Grid2D.h b/src/TNL/Meshes/GridDetails/Grid2D.h index b24be9ba29503f4f6b80f2c3ad0ada1097d89844..3d7335053b062baa7e92514acd1cb360b8bade00 100644 --- a/src/TNL/Meshes/GridDetails/Grid2D.h +++ b/src/TNL/Meshes/GridDetails/Grid2D.h @@ -174,22 +174,6 @@ class Grid< 2, Real, Device, Index > : public Object inline RealType getSmallestSpaceStep() const; - template< typename GridFunction > - typename GridFunction::RealType getAbsMax( const GridFunction& f ) const; - - template< typename GridFunction > - typename GridFunction::RealType getLpNorm( const GridFunction& f, - const typename GridFunction::RealType& p ) const; - - template< typename GridFunction > - typename GridFunction::RealType getDifferenceAbsMax( const GridFunction& f1, - const GridFunction& f2 ) const; - - template< typename GridFunction > - typename GridFunction::RealType getDifferenceLpNorm( const GridFunction& f1, - const GridFunction& f2, - const typename GridFunction::RealType& p ) const; - void setDistMesh(DistributedMeshType * distGrid); DistributedMeshType * getDistributedMesh() const; diff --git a/src/TNL/Meshes/GridDetails/Grid2D_impl.h b/src/TNL/Meshes/GridDetails/Grid2D_impl.h index 259181688c0566abdd3025bac1cbda1429a60d10..4f9f8fdd580f17a8e88c596127216e57e916bfee 100644 --- a/src/TNL/Meshes/GridDetails/Grid2D_impl.h +++ b/src/TNL/Meshes/GridDetails/Grid2D_impl.h @@ -348,76 +348,6 @@ Real Grid< 2, Real, Device, Index > :: getSmallestSpaceStep() const return min( this->spaceSteps.x(), this->spaceSteps.y() ); } -template< typename Real, - typename Device, - typename Index > - template< typename GridFunction > - typename GridFunction::RealType - Grid< 2, Real, Device, Index >::getAbsMax( const GridFunction& f ) const -{ - return f.absMax(); -} - -template< typename Real, - typename Device, - typename Index > - template< typename GridFunction > - typename GridFunction::RealType - Grid< 2, Real, Device, Index >::getLpNorm( const GridFunction& f1, - const typename GridFunction::RealType& p ) const -{ - typename GridFunction::RealType lpNorm( 0.0 ); - Cell cell( *this ); - for( cell.getCoordinates().y() = 0; - cell.getCoordinates().y() < getDimensions().y(); - cell.getCoordinates().y()++ ) - for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < getDimensions().x(); - cell.getCoordinates().x()++ ) - { - IndexType c = this->getEntityIndex( cell ); - lpNorm += ::pow( abs( f1[ c ] ), p ); - } - lpNorm *= this->getSpaceSteps().x() * this->getSpaceSteps().y(); - return ::pow( lpNorm, 1.0/p ); -} - -template< typename Real, - typename Device, - typename Index > - template< typename GridFunction > - typename GridFunction::RealType - Grid< 2, Real, Device, Index >::getDifferenceAbsMax( const GridFunction& f1, - const GridFunction& f2 ) const -{ - return TNL::max( TNL::abs( f1.getData() - f2.getData() ) ); -} - -template< typename Real, - typename Device, - typename Index > - template< typename GridFunction > - typename GridFunction::RealType - Grid< 2, Real, Device, Index >::getDifferenceLpNorm( const GridFunction& f1, - const GridFunction& f2, - const typename GridFunction::RealType& p ) const -{ - typename GridFunction::RealType lpNorm( 0.0 ); - Cell cell( *this ); - for( cell.getCoordinates().y() = 0; - cell.getCoordinates().y() < getDimensions().y(); - cell.getCoordinates().y()++ ) - for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < getDimensions().x(); - cell.getCoordinates().x()++ ) - { - IndexType c = this->getEntityIndex( cell ); - lpNorm += ::pow( abs( f1[ c ] - f2[ c ] ), p ); - } - lpNorm *= this->getSpaceSteps().x() * this->getSpaceSteps().y(); - return ::pow( lpNorm, 1.0 / p ); -} - template< typename Real, typename Device, typename Index > diff --git a/src/TNL/Meshes/GridDetails/Grid3D.h b/src/TNL/Meshes/GridDetails/Grid3D.h index 881fb0074bf642ca6fdcd1300df849c93d205792..7e3f0d5e86781d70a79bb7ef5ac83f19cd7404db 100644 --- a/src/TNL/Meshes/GridDetails/Grid3D.h +++ b/src/TNL/Meshes/GridDetails/Grid3D.h @@ -179,22 +179,6 @@ class Grid< 3, Real, Device, Index > : public Object __cuda_callable__ RealType getSmallestSpaceStep() const; - template< typename GridFunction > - typename GridFunction::RealType getAbsMax( const GridFunction& f ) const; - - template< typename GridFunction > - typename GridFunction::RealType getLpNorm( const GridFunction& f, - const typename GridFunction::RealType& p ) const; - - template< typename GridFunction > - typename GridFunction::RealType getDifferenceAbsMax( const GridFunction& f1, - const GridFunction& f2 ) const; - - template< typename GridFunction > - typename GridFunction::RealType getDifferenceLpNorm( const GridFunction& f1, - const GridFunction& f2, - const typename GridFunction::RealType& p ) const; - /** * \brief See Grid1D::save( File& file ) const. */ diff --git a/src/TNL/Meshes/GridDetails/Grid3D_impl.h b/src/TNL/Meshes/GridDetails/Grid3D_impl.h index f4707a8ce34654544f9d7455122ebc3a340d690b..dd91a7ed852c0d961be8c3cb0811d5c687735280 100644 --- a/src/TNL/Meshes/GridDetails/Grid3D_impl.h +++ b/src/TNL/Meshes/GridDetails/Grid3D_impl.h @@ -407,98 +407,6 @@ Real Grid< 3, Real, Device, Index > :: getSmallestSpaceStep() const return min( this->spaceSteps.x(), min( this->spaceSteps.y(), this->spaceSteps.z() ) ); } -template< typename Real, - typename Device, - typename Index > - template< typename GridFunction > -typename GridFunction::RealType - Grid< 3, Real, Device, Index >::getAbsMax( const GridFunction& f ) const -{ - return f.absMax(); -} - -template< typename Real, - typename Device, - typename Index > - template< typename GridFunction > -typename GridFunction::RealType - Grid< 3, Real, Device, Index >::getLpNorm( const GridFunction& f1, - const typename GridFunction::RealType& p ) const -{ - typename GridFunction::RealType lpNorm( 0.0 ); - Cell cell; - for( cell.getCoordinates().z() = 0; - cell.getCoordinates().z() < getDimensions().z(); - cell.getCoordinates().z()++ ) - for( cell.getCoordinates().y() = 0; - cell.getCoordinates().y() < getDimensions().y(); - cell.getCoordinates().y()++ ) - for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < getDimensions().x(); - cell.getCoordinates().x()++ ) - { - IndexType c = this->getEntityIndex( cell ); - lpNorm += ::pow( abs( f1[ c ] ), p );; - } - lpNorm *= this->getSpaceSteps()().x() * this->getSpaceSteps()().y() * this->getSpaceSteps()().z(); - return ::pow( lpNorm, 1.0/p ); -} - - -template< typename Real, - typename Device, - typename Index > - template< typename GridFunction > - typename GridFunction::RealType - Grid< 3, Real, Device, Index >::getDifferenceAbsMax( const GridFunction& f1, - const GridFunction& f2 ) const -{ - typename GridFunction::RealType maxDiff( -1.0 ); - Cell cell( *this ); - for( cell.getCoordinates().z() = 0; - cell.getCoordinates().z() < getDimensions().z(); - cell.getCoordinates().z()++ ) - for( cell.getCoordinates().y() = 0; - cell.getCoordinates().y() < getDimensions().y(); - cell.getCoordinates().y()++ ) - for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < getDimensions().x(); - cell.getCoordinates().x()++ ) - { - IndexType c = this->getEntityIndex( cell ); - maxDiff = max( maxDiff, abs( f1[ c ] - f2[ c ] ) ); - } - return maxDiff; -} - -template< typename Real, - typename Device, - typename Index > - template< typename GridFunction > - typename GridFunction::RealType - Grid< 3, Real, Device, Index >::getDifferenceLpNorm( const GridFunction& f1, - const GridFunction& f2, - const typename GridFunction::RealType& p ) const -{ - typename GridFunction::RealType lpNorm( 0.0 ); - Cell cell( *this ); - for( cell.getCoordinates().z() = 0; - cell.getCoordinates().z() < getDimensions().z(); - cell.getCoordinates().z()++ ) - for( cell.getCoordinates().y() = 0; - cell.getCoordinates().y() < getDimensions().y(); - cell.getCoordinates().y()++ ) - for( cell.getCoordinates().x() = 0; - cell.getCoordinates().x() < getDimensions().x(); - cell.getCoordinates().x()++ ) - { - IndexType c = this->getEntityIndex( cell ); - lpNorm += ::pow( abs( f1[ c ] - f2[ c ] ), p ); - } - lpNorm *= this->getSpaceSteps().x() * this->getSpaceSteps().y() * this->getSpaceSteps().z(); - return ::pow( lpNorm, 1.0 / p ); -} - template< typename Real, typename Device, typename Index > diff --git a/src/TNL/Meshes/MeshDetails/initializer/Initializer.h b/src/TNL/Meshes/MeshDetails/initializer/Initializer.h index 759490234a5a04f527eb124a4237f2e0d74a9a8b..acaeeaff4ab66abf552dc97b86ac71f77e67e67c 100644 --- a/src/TNL/Meshes/MeshDetails/initializer/Initializer.h +++ b/src/TNL/Meshes/MeshDetails/initializer/Initializer.h @@ -65,7 +65,9 @@ template< typename MeshConfig, bool EntityStorage = MeshTraits< MeshConfig >::template EntityTraits< DimensionTag::value >::storageEnabled, bool EntityReferenceOrientationStorage = - MeshTraits< MeshConfig >::template EntityTraits< DimensionTag::value >::orientationNeeded > + MeshTraits< MeshConfig >::template EntityTraits< DimensionTag::value >::orientationNeeded && + // orientationNeeded does not make sense without storageEnabled + MeshTraits< MeshConfig >::template EntityTraits< DimensionTag::value >::storageEnabled > class InitializerLayer; diff --git a/src/TNL/Meshes/TypeResolver/TypeResolver_impl.h b/src/TNL/Meshes/TypeResolver/TypeResolver_impl.h index d45016af193656cb6094f3782b304a92c224bf2a..f18188b9c5ebc40b3d40c70d22445529962fcd7c 100644 --- a/src/TNL/Meshes/TypeResolver/TypeResolver_impl.h +++ b/src/TNL/Meshes/TypeResolver/TypeResolver_impl.h @@ -19,6 +19,7 @@ #include <TNL/Meshes/Readers/VTKReader.h> #include <TNL/Meshes/TypeResolver/GridTypeResolver.h> #include <TNL/Meshes/TypeResolver/MeshTypeResolver.h> +#include <TNL/Communicators/NoDistrCommunicator.h> // TODO: implement this in TNL::String inline bool ends_with( const std::string& value, const std::string& ending ) @@ -117,7 +118,7 @@ template< typename CommunicatorType, bool loadMesh( const String& fileName, Mesh< MeshConfig, Device >& mesh, - DistributedMeshes::DistributedMesh< Mesh< MeshConfig, Device > > &distributedMesh ) + DistributedMeshes::DistributedMesh< Mesh< MeshConfig, Device > >& distributedMesh ) { if( CommunicatorType::isDistributed() ) { @@ -188,9 +189,12 @@ loadMesh( const String& fileName, } Mesh< MeshConfig, Devices::Host > hostMesh; - if( ! loadMesh( fileName, hostMesh ) ) + DistributedMeshes::DistributedMesh< Mesh< MeshConfig, Devices::Host > > hostDistributedMesh; + if( ! loadMesh< CommunicatorType >( fileName, hostMesh, hostDistributedMesh ) ) return false; mesh = hostMesh; + // TODO +// distributedMesh = hostDistributedMesh; return true; } @@ -278,5 +282,16 @@ decomposeMesh( const Config::ParameterContainer& parameters, return true; } +// convenient overload for non-distributed meshes +template< typename Mesh > +bool +loadMesh( const String& fileName, Mesh& mesh ) +{ + using Communicator = TNL::Communicators::NoDistrCommunicator; + using DistributedMesh = DistributedMeshes::DistributedMesh< Mesh>; + DistributedMesh distributedMesh; + return loadMesh< Communicator >( fileName, mesh, distributedMesh ); +} + } // namespace Meshes } // namespace TNL diff --git a/src/TNL/Solvers/Linear/BICGStabL_impl.h b/src/TNL/Solvers/Linear/BICGStabL_impl.h index 3f41e5115d0043b168bb9425a567bf02c97159b0..5597cfdf7c231da94dcdc62b702082991d7814b4 100644 --- a/src/TNL/Solvers/Linear/BICGStabL_impl.h +++ b/src/TNL/Solvers/Linear/BICGStabL_impl.h @@ -102,7 +102,7 @@ solve( ConstVectorViewType b, VectorViewType x ) */ Matrices::MatrixOperations< DeviceType >:: geam( size, j + 1, - 1.0, R.getData(), ldSize, + (RealType) 1.0, R.getData(), ldSize, -beta, U.getData(), ldSize, U.getData(), ldSize ); @@ -121,7 +121,7 @@ solve( ConstVectorViewType b, VectorViewType x ) */ Matrices::MatrixOperations< DeviceType >:: geam( size, j + 1, - 1.0, R.getData(), ldSize, + (RealType) 1.0, R.getData(), ldSize, -alpha, U.getData() + ldSize, ldSize, R.getData(), ldSize ); @@ -206,18 +206,18 @@ solve( ConstVectorViewType b, VectorViewType x ) g_2[ 0 ] = g_0[ 1 ]; Matrices::MatrixOperations< DeviceType >:: gemv( size, ell, - 1.0, R.getData(), ldSize, g_2.getData(), - 1.0, Traits::getLocalView( x ).getData() ); + (RealType) 1.0, R.getData(), ldSize, g_2.getData(), + (RealType) 1.0, Traits::getLocalView( x ).getData() ); // r_0 := r_0 - R_[1:ell] * g_1_[1:ell] Matrices::MatrixOperations< DeviceType >:: gemv( size, ell, - -1.0, R.getData() + ldSize, ldSize, &g_1[ 1 ], - 1.0, Traits::getLocalView( r_0 ).getData() ); + (RealType) -1.0, R.getData() + ldSize, ldSize, &g_1[ 1 ], + (RealType) 1.0, Traits::getLocalView( r_0 ).getData() ); // u_0 := u_0 - U_[1:ell] * g_0_[1:ell] Matrices::MatrixOperations< DeviceType >:: gemv( size, ell, - -1.0, U.getData() + ldSize, ldSize, &g_0[ 1 ], - 1.0, Traits::getLocalView( u_0 ).getData() ); + (RealType) -1.0, U.getData() + ldSize, ldSize, &g_0[ 1 ], + (RealType) 1.0, Traits::getLocalView( u_0 ).getData() ); if( exact_residue ) { /**** diff --git a/src/TNL/Solvers/Linear/GMRES_impl.h b/src/TNL/Solvers/Linear/GMRES_impl.h index 8e653e28b2d783e4a342f899eb794554d11c131a..2e1d9fbb25a8dfbb1d05b64c186dd855a479924b 100644 --- a/src/TNL/Solvers/Linear/GMRES_impl.h +++ b/src/TNL/Solvers/Linear/GMRES_impl.h @@ -243,8 +243,8 @@ orthogonalize_CGS( const int m, const RealType normb, const RealType beta ) // w := w - V_i * H_l Matrices::MatrixOperations< DeviceType >:: gemv( size, i + 1, - -1.0, V.getData(), ldSize, H_l, - 1.0, Traits::getLocalView( w ).getData() ); + (RealType) -1.0, V.getData(), ldSize, H_l, + (RealType) 1.0, Traits::getLocalView( w ).getData() ); } /*** * H_{i+1,i} = |w| @@ -607,8 +607,8 @@ hauseholder_cwy( VectorViewType v, // v = e_i - Y_i * aux Matrices::MatrixOperations< DeviceType >:: gemv( size, i + 1, - -1.0, Y.getData(), ldSize, aux, - 0.0, Traits::getLocalView( v ).getData() ); + (RealType) -1.0, Y.getData(), ldSize, aux, + (RealType) 0.0, Traits::getLocalView( v ).getData() ); if( localOffset == 0 ) v.setElement( i, 1.0 + v.getElement( i ) ); } @@ -649,8 +649,8 @@ hauseholder_cwy_transposed( VectorViewType z, z = w; Matrices::MatrixOperations< DeviceType >:: gemv( size, i + 1, - -1.0, Y.getData(), ldSize, aux, - 1.0, Traits::getLocalView( z ).getData() ); + (RealType) -1.0, Y.getData(), ldSize, aux, + (RealType) 1.0, Traits::getLocalView( z ).getData() ); } template< typename Matrix > @@ -691,8 +691,8 @@ update( const int k, // x = V * y + x Matrices::MatrixOperations< DeviceType >:: gemv( size, k + 1, - 1.0, V.getData(), ldSize, y, - 1.0, Traits::getLocalView( x ).getData() ); + (RealType) 1.0, V.getData(), ldSize, y, + (RealType) 1.0, Traits::getLocalView( x ).getData() ); } else { // The vectors v_i are not stored, they can be reconstructed as P_0...P_j * e_j. @@ -723,8 +723,8 @@ update( const int k, // x -= Y_{k+1} * aux Matrices::MatrixOperations< DeviceType >:: gemv( size, k + 1, - -1.0, Y.getData(), ldSize, aux, - 1.0, Traits::getLocalView( x ).getData() ); + (RealType) -1.0, Y.getData(), ldSize, aux, + (RealType) 1.0, Traits::getLocalView( x ).getData() ); // x += y if( localOffset == 0 ) diff --git a/src/TNL/Solvers/Linear/Preconditioners/ILU0.h b/src/TNL/Solvers/Linear/Preconditioners/ILU0.h index 8a177df055c682ead7b7037aae4772ae2d1ef1ab..d5127fab5dec1e67a97d254f57e81f8d49e3d847 100644 --- a/src/TNL/Solvers/Linear/Preconditioners/ILU0.h +++ b/src/TNL/Solvers/Linear/Preconditioners/ILU0.h @@ -31,7 +31,26 @@ namespace Preconditioners { // implementation template template< typename Matrix, typename Real, typename Device, typename Index > class ILU0_impl -{}; +: public Preconditioner< Matrix > +{ +public: + using RealType = Real; + using DeviceType = Device; + using IndexType = Index; + using typename Preconditioner< Matrix >::VectorViewType; + using typename Preconditioner< Matrix >::ConstVectorViewType; + using typename Preconditioner< Matrix >::MatrixPointer; + + virtual void update( const MatrixPointer& matrixPointer ) override + { + throw Exceptions::NotImplementedError("ILU0 is not implemented yet for the matrix type " + getType< Matrix >()); + } + + virtual void solve( ConstVectorViewType b, VectorViewType x ) const override + { + throw Exceptions::NotImplementedError("ILU0 is not implemented yet for the matrix type " + getType< Matrix >()); + } +}; // actual template to be used by users template< typename Matrix > diff --git a/src/TNL/TypeTraits.h b/src/TNL/TypeTraits.h index d617f2b42454bce2fad7a5d2ff69b685574723c9..3183460fef20a663705c02b641f8c866e2cde1c7 100644 --- a/src/TNL/TypeTraits.h +++ b/src/TNL/TypeTraits.h @@ -103,6 +103,33 @@ public: static constexpr bool value = type::value; }; +/** + * \brief Type trait for checking if T has operator+= taking one argument of type T. + */ +template< typename T > +class HasAddAssignmentOperator +{ +private: + template< typename U > + static constexpr auto check(U*) + -> typename + std::enable_if_t< + ! std::is_same< + decltype( std::declval<U>() += std::declval<U>() ), + void + >::value, + std::true_type + >; + + template< typename > + static constexpr std::false_type check(...); + + using type = decltype(check<T>(0)); + +public: + static constexpr bool value = type::value; +}; + /** * \brief Type trait for checking if T is an array type, e.g. * \ref Containers::Array or \ref Containers::Vector. @@ -118,6 +145,17 @@ struct IsArrayType HasSubscriptOperator< T >::value > {}; +/** + * \brief Type trait for checking if T is a vector type, e.g. + * \ref Containers::Vector or \ref Containers::VectorView. + */ +template< typename T > +struct IsVectorType +: public std::integral_constant< bool, + IsArrayType< T >::value && + HasAddAssignmentOperator< T >::value > +{}; + /** * \brief Type trait for checking if T has a \e constexpr \e getSize method. */ diff --git a/src/Tools/tnl-diff.cpp b/src/Tools/tnl-diff.cpp index 4614738154339739421fc29dda9e71d05b03d13a..7e442c982fe777abc2d02259a881f28d945e682f 100644 --- a/src/Tools/tnl-diff.cpp +++ b/src/Tools/tnl-diff.cpp @@ -23,10 +23,10 @@ void setupConfig( Config::ConfigDescription& config ) config.addEntryEnum< String >( "halves" ); config.addEntry< bool >( "exact-match", "Check if the data are exactly the same.", false ); config.addEntry< bool >( "write-difference", "Write difference grid function.", false ); - config.addEntry< bool >( "write-exact-curve", "Write exact curve with given radius.", false ); +// config.addEntry< bool >( "write-exact-curve", "Write exact curve with given radius.", false ); config.addEntry< int >( "edges-skip", "Width of the edges that will be skipped - not included into the error norms.", 0 ); - config.addEntry< bool >( "write-graph", "Draws a graph in the Gnuplot format of the dependence of the error norm on t.", true ); - config.addEntry< bool >( "write-log-graph", "Draws a logarithmic graph in the Gnuplot format of the dependence of the error norm on t.", true ); +// config.addEntry< bool >( "write-graph", "Draws a graph in the Gnuplot format of the dependence of the error norm on t.", true ); +// config.addEntry< bool >( "write-log-graph", "Draws a logarithmic graph in the Gnuplot format of the dependence of the error norm on t.", true ); config.addEntry< double >( "snapshot-period", "The period between consecutive snapshots.", 0.0 ); config.addEntry< bool >( "verbose", "Sets verbosity.", true ); } diff --git a/src/Tools/tnl-diff.h b/src/Tools/tnl-diff.h index e17ca7940b295d249822c59e92f34055613a136b..81a0620de91e188e9d1fff4ab62deb2059f43b87 100644 --- a/src/Tools/tnl-diff.h +++ b/src/Tools/tnl-diff.h @@ -394,8 +394,11 @@ bool computeDifferenceOfVectors( const MeshPointer& meshPointer, const Config::P //if( snapshotPeriod != 0.0 ) outputFile << std::setw( 6 ) << ( i - half ) * snapshotPeriod << " "; } - Real l1Diff = meshPointer->getDifferenceLpNorm( v1, v2, 1.0 ); - Real l2Diff = meshPointer->getDifferenceLpNorm( v1, v2, 2.0 ); + Real cellVolume = meshPointer->getCellMeasure(); +// Real l1Diff = meshPointer->getDifferenceLpNorm( v1, v2, 1.0 ); + Real l1Diff = cellVolume * sum( abs( v1 - v2 ) ); +// Real l2Diff = meshPointer->getDifferenceLpNorm( v1, v2, 2.0 ); + Real l2Diff = cellVolume * std::sqrt( dot(v1 - v2, v1 - v2) ); Real maxDiff = max( abs( v1 - v2 ) ); if( snapshotPeriod != 0.0 ) { diff --git a/src/Tools/tnl-grid-setup.cpp b/src/Tools/tnl-grid-setup.cpp index 1846dc09351a234b4068400edbb3c268f2a30bbe..261f1cf716d6f7b453b27a7acb3f2bfd7d6daa9a 100644 --- a/src/Tools/tnl-grid-setup.cpp +++ b/src/Tools/tnl-grid-setup.cpp @@ -15,11 +15,14 @@ void configSetup( Config::ConfigDescription& config ) { config.addDelimiter( "General parameters" ); config.addEntry < String >( "output-file", "Output file.", "mesh.tnl" ); - config.addEntry < int > ( "verbose", "Set the verbosity of the program.", 1 ); + config.addEntry < int > ( "verbose", "Set the verbosity of the program.", 1 ); - config.addDelimiter ( "Grid parameters" ); + config.addDelimiter ( "Grid parameters" ); config.addEntry < String >( "grid-name", "The grid name.", "tnl-grid" ); - config.addRequiredEntry< int > ( "dimensions", "The grid dimensions." ); + config.addRequiredEntry< int > ( "dimension", "The grid dimension." ); + config.addEntryEnum< int >( 1 ); + config.addEntryEnum< int >( 2 ); + config.addEntryEnum< int >( 3 ); config.addEntry < String >( "real-type", "Precision of the real type describing the grid.", "double" ); config.addEntryEnum < String >( "float" ); config.addEntryEnum < String >( "double" ); @@ -27,16 +30,16 @@ void configSetup( Config::ConfigDescription& config ) config.addEntry < String >( "index-type", "Type for the indexing of the grid elements." ,"int" ); config.addEntryEnum < String >( "int" ); config.addEntryEnum < String >( "long-int" ); - config.addEntry < double > ( "origin-x", "The x-coordinate of the origin.", 0.0 ); - config.addEntry < double > ( "origin-y", "The y-coordinate of the origin.", 0.0 ); - config.addEntry < double > ( "origin-z", "The z-coordinate of the origin.", 0.0 ); - config.addEntry < double > ( "proportions-x", "The proportions of the grid along the x axis.", 1.0 ); - config.addEntry < double > ( "proportions-y", "The proportions of the grid along the y axis.", 1.0 ); - config.addEntry < double > ( "proportions-z", "The proportions of the grid along the z axis.", 1.0 ); - config.addEntry < int > ( "size-x", "Number of elements along the x axis." ); - config.addEntry < int > ( "size-y", "Number of elements along the y axis." ); - config.addEntry < int > ( "size-z", "Number of elements along the z axis." ); - config.addEntry < bool > ( "equal-space-steps", "All space steps will be equivalent.", false ); + config.addEntry < double >( "origin-x", "The x-coordinate of the origin.", 0.0 ); + config.addEntry < double >( "origin-y", "The y-coordinate of the origin.", 0.0 ); + config.addEntry < double >( "origin-z", "The z-coordinate of the origin.", 0.0 ); + config.addEntry < double >( "proportions-x", "The proportions of the grid along the x axis.", 1.0 ); + config.addEntry < double >( "proportions-y", "The proportions of the grid along the y axis.", 1.0 ); + config.addEntry < double >( "proportions-z", "The proportions of the grid along the z axis.", 1.0 ); + config.addEntry < int > ( "size-x", "Number of elements along the x axis." ); + config.addEntry < int > ( "size-y", "Number of elements along the y axis." ); + config.addEntry < int > ( "size-z", "Number of elements along the z axis." ); + config.addEntry < bool > ( "equal-space-steps", "All space steps will be equivalent.", false ); } int main( int argc, char* argv[] ) @@ -50,5 +53,3 @@ int main( int argc, char* argv[] ) return EXIT_FAILURE; return EXIT_SUCCESS; } - - diff --git a/src/Tools/tnl-grid-setup.h b/src/Tools/tnl-grid-setup.h index 896d3abb971571abcededb8bed75dcd9cb0f1fff..867cfdb73bdb75f6ba073724b0ebd2db3769f6b4 100644 --- a/src/Tools/tnl-grid-setup.h +++ b/src/Tools/tnl-grid-setup.h @@ -19,14 +19,18 @@ using namespace TNL; template< typename RealType, typename IndexType > bool setupGrid( const Config::ParameterContainer& parameters ) { - String gridName = parameters. getParameter< String >( "grid-name" ); - String outputFile = parameters. getParameter< String >( "output-file" ); - int dimensions = parameters. getParameter< int >( "dimensions" ); - if( dimensions == 1 ) + const String gridName = parameters.getParameter< String >( "grid-name" ); + const String outputFile = parameters.getParameter< String >( "output-file" ); + const int dimension = parameters.getParameter< int >( "dimension" ); + if( dimension == 1 ) { - RealType originX = parameters. getParameter< double >( "origin-x" ); - RealType proportionsX = parameters. getParameter< double >( "proportions-x" ); - IndexType sizeX = parameters. getParameter< int >( "size-x" ); + RealType originX = parameters.getParameter< double >( "origin-x" ); + RealType proportionsX = parameters.getParameter< double >( "proportions-x" ); + if( ! parameters.checkParameter( "size-x" ) ) { + std::cerr << "The parameter size-x is required when the grid dimension is 1." << std::endl; + return false; + } + IndexType sizeX = parameters.getParameter< int >( "size-x" ); typedef Meshes::Grid< 1, RealType, Devices::Host, IndexType > GridType; typedef typename GridType::PointType PointType; @@ -46,12 +50,16 @@ bool setupGrid( const Config::ParameterContainer& parameters ) return false; } } - if( dimensions == 2 ) + if( dimension == 2 ) { RealType originX = parameters.getParameter< double >( "origin-x" ); RealType originY = parameters.getParameter< double >( "origin-y" ); RealType proportionsX = parameters.getParameter< double >( "proportions-x" ); RealType proportionsY = parameters.getParameter< double >( "proportions-y" ); + if( ! parameters.checkParameters( {"size-x", "size-y"} ) ) { + std::cerr << "The parameters size-x and size-y are required when the grid dimension is 2." << std::endl; + return false; + } IndexType sizeX = parameters.getParameter< int >( "size-x" ); IndexType sizeY = parameters.getParameter< int >( "size-y" ); typedef Meshes::Grid< 2, RealType, Devices::Host, IndexType > GridType; @@ -84,17 +92,21 @@ bool setupGrid( const Config::ParameterContainer& parameters ) return false; } } - if( dimensions == 3 ) + if( dimension == 3 ) { - RealType originX = parameters. getParameter< double >( "origin-x" ); - RealType originY = parameters. getParameter< double >( "origin-y" ); - RealType originZ = parameters. getParameter< double >( "origin-z" ); - RealType proportionsX = parameters. getParameter< double >( "proportions-x" ); - RealType proportionsY = parameters. getParameter< double >( "proportions-y" ); - RealType proportionsZ = parameters. getParameter< double >( "proportions-z" ); - IndexType sizeX = parameters. getParameter< int >( "size-x" ); - IndexType sizeY = parameters. getParameter< int >( "size-y" ); - IndexType sizeZ = parameters. getParameter< int >( "size-z" ); + RealType originX = parameters.getParameter< double >( "origin-x" ); + RealType originY = parameters.getParameter< double >( "origin-y" ); + RealType originZ = parameters.getParameter< double >( "origin-z" ); + RealType proportionsX = parameters.getParameter< double >( "proportions-x" ); + RealType proportionsY = parameters.getParameter< double >( "proportions-y" ); + RealType proportionsZ = parameters.getParameter< double >( "proportions-z" ); + if( ! parameters.checkParameters( {"size-x", "size-y", "size-z"} ) ) { + std::cerr << "The parameters size-x, size-y and size-z are required when the grid dimension is 3." << std::endl; + return false; + } + IndexType sizeX = parameters.getParameter< int >( "size-x" ); + IndexType sizeY = parameters.getParameter< int >( "size-y" ); + IndexType sizeZ = parameters.getParameter< int >( "size-z" ); typedef Meshes::Grid< 3, RealType, Devices::Host, IndexType > GridType; typedef typename GridType::PointType PointType; @@ -115,7 +127,7 @@ bool setupGrid( const Config::ParameterContainer& parameters ) } std::cout << "Setting dimensions to ... " << grid.getDimensions() << std::endl; std::cout << "Writing the grid to the file " << outputFile << " .... "; - + try { grid.save( outputFile ); @@ -126,34 +138,34 @@ bool setupGrid( const Config::ParameterContainer& parameters ) return false; } } - std::cout << "[ OK ] " << std::endl; + std::cout << "[ OK ] " << std::endl; return true; } template< typename RealType > bool resolveIndexType( const Config::ParameterContainer& parameters ) { - const String& indexType = parameters. getParameter< String >( "index-type" ); - std::cout << "Setting index type to ... " << indexType << std::endl; + const String& indexType = parameters.getParameter< String >( "index-type" ); + std::cout << "Setting index type to ... " << indexType << std::endl; if( indexType == "int" ) return setupGrid< RealType, int >( parameters ); if( indexType == "long-int" ) return setupGrid< RealType, long int >( parameters ); - std::cerr << "The index type '" << indexType << "' is not defined. " << std::endl; + std::cerr << "The index type '" << indexType << "' is not defined." << std::endl; return false; } bool resolveRealType( const Config::ParameterContainer& parameters ) { - String realType = parameters. getParameter< String >( "real-type" ); - std::cout << "Setting real type to ... " << realType << std::endl; + String realType = parameters.getParameter< String >( "real-type" ); + std::cout << "Setting real type to ... " << realType << std::endl; if( realType == "float" ) return resolveIndexType< float >( parameters ); if( realType == "double" ) return resolveIndexType< double >( parameters ); if( realType == "long-double" ) return resolveIndexType< long double >( parameters ); - std::cerr << "The real type '" << realType << "' is not supported. " << std::endl; + std::cerr << "The real type '" << realType << "' is not supported." << std::endl; return false; } diff --git a/src/Tools/tnl-view.cpp b/src/Tools/tnl-view.cpp index f426b6fe0c6bf36318e3e245ecce184b35ae0d0f..32fac87d9645c066fe111eef1fb2c66961ae1c5c 100644 --- a/src/Tools/tnl-view.cpp +++ b/src/Tools/tnl-view.cpp @@ -64,22 +64,22 @@ template< typename GlobalIndex > struct MeshIdTag< TNLViewBuildConfigTag, Global void setupConfig( Config::ConfigDescription& config ) { - config.addDelimiter ( "General settings:" ); - config.addEntry < String > ( "mesh", "Mesh file.", "mesh.tnl" ); - config.addRequiredList < String > ( "input-files", "Input files." ); - config.addList < String > ( "output-files", "Output files." ); - config.addEntry < bool > ( "check-output-file", "If the output file already exists, do not recreate it.", false ); + config.addDelimiter( "General settings:" ); + config.addEntry < String >( "mesh", "Mesh file.", "mesh.tnl" ); + config.addRequiredList < String >( "input-files", "Input files." ); +// config.addList < String >( "output-files", "Output files." ); + config.addEntry < bool > ( "check-output-file", "If the output file already exists, do not recreate it.", false ); config.addDelimiter( "Grid settings:"); - config.addList < double > ( "level-lines", "List of level sets which will be drawn." ); - config.addEntry < int > ( "output-x-size", "X size of the output." ); - config.addEntry < int > ( "output-y-size", "Y size of the output." ); - config.addEntry < int > ( "output-z-size", "Z size of the output." ); - config.addEntry < double > ( "scale", "Multiply the function by given number.", 1.0 ); - config.addEntry < String > ( "output-format", "Output file format.", "gnuplot" ); - config.addEntryEnum < String > ( "gnuplot" ); - config.addEntryEnum < String > ( "vtk" ); - config.addEntry < int > ( "verbose", "Set the verbosity of the program.", 1 ); +// config.addList < double >( "level-lines", "List of level sets which will be drawn." ); +// config.addEntry < int > ( "output-x-size", "X size of the output." ); +// config.addEntry < int > ( "output-y-size", "Y size of the output." ); +// config.addEntry < int > ( "output-z-size", "Z size of the output." ); + config.addEntry < double >( "scale", "Multiply the function by given number.", 1.0 ); + config.addEntry < String >( "output-format", "Output file format.", "gnuplot" ); + config.addEntryEnum< String > ( "gnuplot" ); + config.addEntryEnum< String > ( "vtk" ); + config.addEntry < int > ( "verbose", "Set the verbosity of the program.", 1 ); } int main( int argc, char* argv[] ) @@ -90,10 +90,9 @@ int main( int argc, char* argv[] ) if( ! parseCommandLine( argc, argv, conf_desc, parameters ) ) return EXIT_FAILURE; - String meshFile = parameters.getParameter< String >( "mesh" ); + const String meshFile = parameters.getParameter< String >( "mesh" ); return ! TNL::Meshes::resolveMeshType< TNLViewBuildConfigTag, Devices::Host, FilesProcessor > - ( meshFile, - parameters ); + ( meshFile, parameters ); } diff --git a/src/Tools/tnl-view.h b/src/Tools/tnl-view.h index 7e7b82bbfc8165245fad06e1e97dad072e621442..fd7bdd8c472095580169274b8d29452cc67a604d 100644 --- a/src/Tools/tnl-view.h +++ b/src/Tools/tnl-view.h @@ -415,7 +415,7 @@ struct FilesProcessor } bool checkOutputFile = parameters. getParameter< bool >( "check-output-file" ); - std::vector< String > inputFiles = parameters. getParameter< std::vector< String > >( "input-files" ); + std::vector< String > inputFiles = parameters.getParameter< std::vector< String > >( "input-files" ); bool error( false ); //#ifdef HAVE_OPENMP //#pragma omp parallel for diff --git a/src/UnitTests/Containers/CMakeLists.txt b/src/UnitTests/Containers/CMakeLists.txt index 6ff7570dd3b1a62051ce295180205ddac0675156..9f27aaa86078937540ccc1716069faec0f69b424 100644 --- a/src/UnitTests/Containers/CMakeLists.txt +++ b/src/UnitTests/Containers/CMakeLists.txt @@ -30,6 +30,11 @@ ADD_EXECUTABLE( VectorVerticalOperationsTest VectorVerticalOperationsTest.cpp ) TARGET_COMPILE_OPTIONS( VectorVerticalOperationsTest PRIVATE ${CXX_TESTS_FLAGS} ) TARGET_LINK_LIBRARIES( VectorVerticalOperationsTest ${GTEST_BOTH_LIBRARIES} ) +# FIXME +#ADD_EXECUTABLE( VectorOfStaticVectorsTest VectorOfStaticVectorsTest.cpp ) +#TARGET_COMPILE_OPTIONS( VectorOfStaticVectorsTest PRIVATE ${CXX_TESTS_FLAGS} ) +#TARGET_LINK_LIBRARIES( VectorOfStaticVectorsTest ${GTEST_BOTH_LIBRARIES} ) + IF( BUILD_CUDA ) CUDA_ADD_EXECUTABLE( ArrayTestCuda ArrayTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) @@ -54,6 +59,10 @@ IF( BUILD_CUDA ) CUDA_ADD_EXECUTABLE( VectorVerticalOperationsTestCuda VectorVerticalOperationsTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) TARGET_LINK_LIBRARIES( VectorVerticalOperationsTestCuda ${GTEST_BOTH_LIBRARIES} ) + + # FIXME +# CUDA_ADD_EXECUTABLE( VectorOfStaticVectorsTestCuda VectorOfStaticVectorsTest.cu OPTIONS ${CXX_TESTS_FLAGS} ) +# TARGET_LINK_LIBRARIES( VectorOfStaticVectorsTestCuda ${GTEST_BOTH_LIBRARIES} ) ENDIF( BUILD_CUDA ) ADD_EXECUTABLE( StaticArrayTest StaticArrayTest.cpp ) @@ -68,6 +77,11 @@ ADD_EXECUTABLE( StaticVectorOperationsTest StaticVectorOperationsTest.cpp ) TARGET_COMPILE_OPTIONS( StaticVectorOperationsTest PRIVATE ${CXX_TESTS_FLAGS} ) TARGET_LINK_LIBRARIES( StaticVectorOperationsTest ${GTEST_BOTH_LIBRARIES} ) +# FIXME +#ADD_EXECUTABLE( StaticVectorOfStaticVectorsTest StaticVectorOfStaticVectorsTest.cpp ) +#TARGET_COMPILE_OPTIONS( StaticVectorOfStaticVectorsTest PRIVATE ${CXX_TESTS_FLAGS} ) +#TARGET_LINK_LIBRARIES( StaticVectorOfStaticVectorsTest ${GTEST_BOTH_LIBRARIES} ) + ADD_TEST( ArrayTest ${EXECUTABLE_OUTPUT_PATH}/ArrayTest${CMAKE_EXECUTABLE_SUFFIX} ) ADD_TEST( ArrayViewTest ${EXECUTABLE_OUTPUT_PATH}/ArrayViewTest${CMAKE_EXECUTABLE_SUFFIX} ) @@ -77,6 +91,7 @@ ADD_TEST( VectorEvaluateAndReduceTest ${EXECUTABLE_OUTPUT_PATH}/VectorEvaluateAn ADD_TEST( VectorBinaryOperationsTest ${EXECUTABLE_OUTPUT_PATH}/VectorBinaryOperationsTest${CMAKE_EXECUTABLE_SUFFIX} ) ADD_TEST( VectorUnaryOperationsTest ${EXECUTABLE_OUTPUT_PATH}/VectorUnaryOperationsTest${CMAKE_EXECUTABLE_SUFFIX} ) ADD_TEST( VectorVerticalOperationsTest ${EXECUTABLE_OUTPUT_PATH}/VectorVerticalOperationsTest${CMAKE_EXECUTABLE_SUFFIX} ) +#ADD_TEST( VectorOfStaticVectorsTest ${EXECUTABLE_OUTPUT_PATH}/VectorOfStaticVectorsTest${CMAKE_EXECUTABLE_SUFFIX} ) IF( BUILD_CUDA ) ADD_TEST( ArrayTestCuda ${EXECUTABLE_OUTPUT_PATH}/ArrayTestCuda${CMAKE_EXECUTABLE_SUFFIX} ) ADD_TEST( ArrayViewTestCuda ${EXECUTABLE_OUTPUT_PATH}/ArrayViewTestCuda${CMAKE_EXECUTABLE_SUFFIX} ) @@ -86,10 +101,12 @@ IF( BUILD_CUDA ) ADD_TEST( VectorBinaryOperationsTestCuda ${EXECUTABLE_OUTPUT_PATH}/VectorBinaryOperationsTestCuda${CMAKE_EXECUTABLE_SUFFIX} ) ADD_TEST( VectorUnaryOperationsTestCuda ${EXECUTABLE_OUTPUT_PATH}/VectorUnaryOperationsTestCuda${CMAKE_EXECUTABLE_SUFFIX} ) ADD_TEST( VectorVerticalOperationsTestCuda ${EXECUTABLE_OUTPUT_PATH}/VectorVerticalOperationsTestCuda${CMAKE_EXECUTABLE_SUFFIX} ) +# ADD_TEST( VectorOfStaticVectorsTestCuda ${EXECUTABLE_OUTPUT_PATH}/VectorOfStaticVectorsTestCuda${CMAKE_EXECUTABLE_SUFFIX} ) ENDIF() ADD_TEST( StaticArrayTest ${EXECUTABLE_OUTPUT_PATH}/StaticArrayTest${CMAKE_EXECUTABLE_SUFFIX} ) ADD_TEST( StaticVectorTest ${EXECUTABLE_OUTPUT_PATH}/StaticVectorTest${CMAKE_EXECUTABLE_SUFFIX} ) ADD_TEST( StaticVectorOperationsTest ${EXECUTABLE_OUTPUT_PATH}/StaticVectorOperationsTest${CMAKE_EXECUTABLE_SUFFIX} ) +#ADD_TEST( StaticVectorOfStaticVectorsTest ${EXECUTABLE_OUTPUT_PATH}/StaticVectorOfStaticVectorsTest${CMAKE_EXECUTABLE_SUFFIX} ) ADD_SUBDIRECTORY( Multimaps ) diff --git a/src/UnitTests/Containers/StaticVectorOfStaticVectorsTest.cpp b/src/UnitTests/Containers/StaticVectorOfStaticVectorsTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..3b4ef0987d8dee435ec7f5bcdf98e4430218e4fd --- /dev/null +++ b/src/UnitTests/Containers/StaticVectorOfStaticVectorsTest.cpp @@ -0,0 +1,6 @@ +#define STATIC_VECTOR +#define VECTOR_OF_STATIC_VECTORS +#include "VectorBinaryOperationsTest.h" +#include "VectorUnaryOperationsTest.h" +#include "VectorVerticalOperationsTest.h" +#include "../main.h" diff --git a/src/UnitTests/Containers/VectorBinaryOperationsTest.h b/src/UnitTests/Containers/VectorBinaryOperationsTest.h index bae5ce5f389e703711df651084994c8f39775116..e8932d3e4ad2e0426746a8e647b742aa5c875cd5 100644 --- a/src/UnitTests/Containers/VectorBinaryOperationsTest.h +++ b/src/UnitTests/Containers/VectorBinaryOperationsTest.h @@ -21,6 +21,9 @@ #elif defined(STATIC_VECTOR) #include <TNL/Containers/StaticVector.h> #else + #ifdef VECTOR_OF_STATIC_VECTORS + #include <TNL/Containers/StaticVector.h> + #endif #include <TNL/Containers/Vector.h> #include <TNL/Containers/VectorView.h> #endif @@ -176,50 +179,76 @@ protected: #endif >; #elif defined(STATIC_VECTOR) - using VectorPairs = ::testing::Types< - Pair< StaticVector< 1, int >, StaticVector< 1, int > >, - Pair< StaticVector< 1, double >, StaticVector< 1, double > >, - Pair< StaticVector< 2, int >, StaticVector< 2, int > >, - Pair< StaticVector< 2, double >, StaticVector< 2, double > >, - Pair< StaticVector< 3, int >, StaticVector< 3, int > >, - Pair< StaticVector< 3, double >, StaticVector< 3, double > >, - Pair< StaticVector< 4, int >, StaticVector< 4, int > >, - Pair< StaticVector< 4, double >, StaticVector< 4, double > >, - Pair< StaticVector< 5, int >, StaticVector< 5, int > >, - Pair< StaticVector< 5, double >, StaticVector< 5, double > > - >; + #ifdef VECTOR_OF_STATIC_VECTORS + using VectorPairs = ::testing::Types< + Pair< StaticVector< 1, StaticVector< 3, double > >, StaticVector< 1, StaticVector< 3, double > > >, + Pair< StaticVector< 2, StaticVector< 3, double > >, StaticVector< 2, StaticVector< 3, double > > >, + Pair< StaticVector< 3, StaticVector< 3, double > >, StaticVector< 3, StaticVector< 3, double > > >, + Pair< StaticVector< 4, StaticVector< 3, double > >, StaticVector< 4, StaticVector< 3, double > > >, + Pair< StaticVector< 5, StaticVector< 3, double > >, StaticVector< 5, StaticVector< 3, double > > > + >; + #else + using VectorPairs = ::testing::Types< + Pair< StaticVector< 1, int >, StaticVector< 1, int > >, + Pair< StaticVector< 1, double >, StaticVector< 1, double > >, + Pair< StaticVector< 2, int >, StaticVector< 2, int > >, + Pair< StaticVector< 2, double >, StaticVector< 2, double > >, + Pair< StaticVector< 3, int >, StaticVector< 3, int > >, + Pair< StaticVector< 3, double >, StaticVector< 3, double > >, + Pair< StaticVector< 4, int >, StaticVector< 4, int > >, + Pair< StaticVector< 4, double >, StaticVector< 4, double > >, + Pair< StaticVector< 5, int >, StaticVector< 5, int > >, + Pair< StaticVector< 5, double >, StaticVector< 5, double > > + >; + #endif #else - using VectorPairs = ::testing::Types< - #ifndef HAVE_CUDA - Pair< Vector< int, Devices::Host >, Vector< int, Devices::Host > >, - Pair< VectorView< int, Devices::Host >, Vector< int, Devices::Host > >, - Pair< VectorView< const int, Devices::Host >, Vector< int, Devices::Host > >, - Pair< Vector< int, Devices::Host >, VectorView< int, Devices::Host > >, - Pair< Vector< int, Devices::Host >, VectorView< const int, Devices::Host > >, - Pair< VectorView< int, Devices::Host >, VectorView< int, Devices::Host > >, - Pair< VectorView< const int, Devices::Host >, VectorView< int, Devices::Host > >, - Pair< VectorView< const int, Devices::Host >, VectorView< const int, Devices::Host > >, - Pair< VectorView< int, Devices::Host >, VectorView< const int, Devices::Host > >, - Pair< Vector< double, Devices::Host >, Vector< double, Devices::Host > >, - Pair< VectorView< double, Devices::Host >, Vector< double, Devices::Host > >, - Pair< Vector< double, Devices::Host >, VectorView< double, Devices::Host > >, - Pair< VectorView< double, Devices::Host >, VectorView< double, Devices::Host > > + #ifdef VECTOR_OF_STATIC_VECTORS + using VectorPairs = ::testing::Types< + #ifndef HAVE_CUDA + Pair< Vector< StaticVector< 3, double >, Devices::Host >, Vector< StaticVector< 3, double >, Devices::Host > >, + Pair< VectorView< StaticVector< 3, double >, Devices::Host >, Vector< StaticVector< 3, double >, Devices::Host > >, + Pair< Vector< StaticVector< 3, double >, Devices::Host >, VectorView< StaticVector< 3, double >, Devices::Host > >, + Pair< VectorView< StaticVector< 3, double >, Devices::Host >, VectorView< StaticVector< 3, double >, Devices::Host > > + #else + Pair< Vector< StaticVector< 3, double >, Devices::Cuda >, Vector< StaticVector< 3, double >, Devices::Cuda > >, + Pair< VectorView< StaticVector< 3, double >, Devices::Cuda >, Vector< StaticVector< 3, double >, Devices::Cuda > >, + Pair< Vector< StaticVector< 3, double >, Devices::Cuda >, VectorView< StaticVector< 3, double >, Devices::Cuda > >, + Pair< VectorView< StaticVector< 3, double >, Devices::Cuda >, VectorView< StaticVector< 3, double >, Devices::Cuda > > + #endif + >; #else - Pair< Vector< int, Devices::Cuda >, Vector< int, Devices::Cuda > >, - Pair< VectorView< int, Devices::Cuda >, Vector< int, Devices::Cuda > >, - Pair< VectorView< const int, Devices::Cuda >, Vector< int, Devices::Cuda > >, - Pair< Vector< int, Devices::Cuda >, VectorView< int, Devices::Cuda > >, - Pair< Vector< int, Devices::Cuda >, VectorView< const int, Devices::Cuda > >, - Pair< VectorView< int, Devices::Cuda >, VectorView< int, Devices::Cuda > >, - Pair< VectorView< const int, Devices::Cuda >, VectorView< int, Devices::Cuda > >, - Pair< VectorView< const int, Devices::Cuda >, VectorView< const int, Devices::Cuda > >, - Pair< VectorView< int, Devices::Cuda >, VectorView< const int, Devices::Cuda > >, - Pair< Vector< double, Devices::Cuda >, Vector< double, Devices::Cuda > >, - Pair< VectorView< double, Devices::Cuda >, Vector< double, Devices::Cuda > >, - Pair< Vector< double, Devices::Cuda >, VectorView< double, Devices::Cuda > >, - Pair< VectorView< double, Devices::Cuda >, VectorView< double, Devices::Cuda > > + using VectorPairs = ::testing::Types< + #ifndef HAVE_CUDA + Pair< Vector< int, Devices::Host >, Vector< int, Devices::Host > >, + Pair< VectorView< int, Devices::Host >, Vector< int, Devices::Host > >, + Pair< VectorView< const int, Devices::Host >, Vector< int, Devices::Host > >, + Pair< Vector< int, Devices::Host >, VectorView< int, Devices::Host > >, + Pair< Vector< int, Devices::Host >, VectorView< const int, Devices::Host > >, + Pair< VectorView< int, Devices::Host >, VectorView< int, Devices::Host > >, + Pair< VectorView< const int, Devices::Host >, VectorView< int, Devices::Host > >, + Pair< VectorView< const int, Devices::Host >, VectorView< const int, Devices::Host > >, + Pair< VectorView< int, Devices::Host >, VectorView< const int, Devices::Host > >, + Pair< Vector< double, Devices::Host >, Vector< double, Devices::Host > >, + Pair< VectorView< double, Devices::Host >, Vector< double, Devices::Host > >, + Pair< Vector< double, Devices::Host >, VectorView< double, Devices::Host > >, + Pair< VectorView< double, Devices::Host >, VectorView< double, Devices::Host > > + #else + Pair< Vector< int, Devices::Cuda >, Vector< int, Devices::Cuda > >, + Pair< VectorView< int, Devices::Cuda >, Vector< int, Devices::Cuda > >, + Pair< VectorView< const int, Devices::Cuda >, Vector< int, Devices::Cuda > >, + Pair< Vector< int, Devices::Cuda >, VectorView< int, Devices::Cuda > >, + Pair< Vector< int, Devices::Cuda >, VectorView< const int, Devices::Cuda > >, + Pair< VectorView< int, Devices::Cuda >, VectorView< int, Devices::Cuda > >, + Pair< VectorView< const int, Devices::Cuda >, VectorView< int, Devices::Cuda > >, + Pair< VectorView< const int, Devices::Cuda >, VectorView< const int, Devices::Cuda > >, + Pair< VectorView< int, Devices::Cuda >, VectorView< const int, Devices::Cuda > >, + Pair< Vector< double, Devices::Cuda >, Vector< double, Devices::Cuda > >, + Pair< VectorView< double, Devices::Cuda >, Vector< double, Devices::Cuda > >, + Pair< Vector< double, Devices::Cuda >, VectorView< double, Devices::Cuda > >, + Pair< VectorView< double, Devices::Cuda >, VectorView< double, Devices::Cuda > > + #endif + >; #endif - >; #endif TYPED_TEST_SUITE( VectorBinaryOperationsTest, VectorPairs ); diff --git a/src/UnitTests/Containers/VectorOfStaticVectorsTest.cpp b/src/UnitTests/Containers/VectorOfStaticVectorsTest.cpp new file mode 100644 index 0000000000000000000000000000000000000000..859cf045c092aabd8ba11d80a88aad697efd7604 --- /dev/null +++ b/src/UnitTests/Containers/VectorOfStaticVectorsTest.cpp @@ -0,0 +1,5 @@ +#define VECTOR_OF_STATIC_VECTORS +#include "VectorBinaryOperationsTest.h" +#include "VectorUnaryOperationsTest.h" +#include "VectorVerticalOperationsTest.h" +#include "../main.h" diff --git a/src/UnitTests/Containers/VectorUnaryOperationsTest.h b/src/UnitTests/Containers/VectorUnaryOperationsTest.h index 827147cd53552209f9875370b93ca75d7514728a..aa595d8e97be4f34b9275adaf55cae182819fc02 100644 --- a/src/UnitTests/Containers/VectorUnaryOperationsTest.h +++ b/src/UnitTests/Containers/VectorUnaryOperationsTest.h @@ -21,6 +21,9 @@ #elif defined(STATIC_VECTOR) #include <TNL/Containers/StaticVector.h> #else + #ifdef VECTOR_OF_STATIC_VECTORS + #include <TNL/Containers/StaticVector.h> + #endif #include <TNL/Containers/Vector.h> #include <TNL/Containers/VectorView.h> #endif @@ -81,35 +84,57 @@ protected: #endif >; #elif defined(STATIC_VECTOR) - using VectorTypes = ::testing::Types< - StaticVector< 1, int >, - StaticVector< 1, double >, - StaticVector< 2, int >, - StaticVector< 2, double >, - StaticVector< 3, int >, - StaticVector< 3, double >, - StaticVector< 4, int >, - StaticVector< 4, double >, - StaticVector< 5, int >, - StaticVector< 5, double > - >; -#else - using VectorTypes = ::testing::Types< - #ifndef HAVE_CUDA - Vector< int, Devices::Host >, - VectorView< int, Devices::Host >, - VectorView< const int, Devices::Host >, - Vector< double, Devices::Host >, - VectorView< double, Devices::Host > + #ifdef VECTOR_OF_STATIC_VECTORS + using VectorTypes = ::testing::Types< + StaticVector< 1, StaticVector< 3, double > >, + StaticVector< 2, StaticVector< 3, double > >, + StaticVector< 3, StaticVector< 3, double > >, + StaticVector< 4, StaticVector< 3, double > >, + StaticVector< 5, StaticVector< 3, double > > + >; + #else + using VectorTypes = ::testing::Types< + StaticVector< 1, int >, + StaticVector< 1, double >, + StaticVector< 2, int >, + StaticVector< 2, double >, + StaticVector< 3, int >, + StaticVector< 3, double >, + StaticVector< 4, int >, + StaticVector< 4, double >, + StaticVector< 5, int >, + StaticVector< 5, double > + >; #endif - #ifdef HAVE_CUDA - Vector< int, Devices::Cuda >, - VectorView< int, Devices::Cuda >, - VectorView< const int, Devices::Cuda >, - Vector< double, Devices::Cuda >, - VectorView< double, Devices::Cuda > +#else + #ifdef VECTOR_OF_STATIC_VECTORS + using VectorTypes = ::testing::Types< + #ifndef HAVE_CUDA + Vector< StaticVector< 3, double >, Devices::Host >, + VectorView< StaticVector< 3, double >, Devices::Host > + #else + Vector< StaticVector< 3, double >, Devices::Cuda >, + VectorView< StaticVector< 3, double >, Devices::Cuda > + #endif + >; + #else + using VectorTypes = ::testing::Types< + #ifndef HAVE_CUDA + Vector< int, Devices::Host >, + VectorView< int, Devices::Host >, + VectorView< const int, Devices::Host >, + Vector< double, Devices::Host >, + VectorView< double, Devices::Host > + #endif + #ifdef HAVE_CUDA + Vector< int, Devices::Cuda >, + VectorView< int, Devices::Cuda >, + VectorView< const int, Devices::Cuda >, + Vector< double, Devices::Cuda >, + VectorView< double, Devices::Cuda > + #endif + >; #endif - >; #endif TYPED_TEST_SUITE( VectorUnaryOperationsTest, VectorTypes ); @@ -297,7 +322,7 @@ TYPED_TEST( VectorUnaryOperationsTest, abs ) EXPECT_EQ( abs(V1), V1 ); // unary expression EXPECT_EQ( abs(-V1), V1 ); - // unary expression + // binary expression EXPECT_EQ( abs(-V1-V1), V2 ); } diff --git a/src/UnitTests/Containers/VectorVerticalOperationsTest.h b/src/UnitTests/Containers/VectorVerticalOperationsTest.h index 93ff286ae65fb5b9dc170903d6aeb16032ebaa69..0650e3154a74830afd6ca24e2640df2f0ebe0b0e 100644 --- a/src/UnitTests/Containers/VectorVerticalOperationsTest.h +++ b/src/UnitTests/Containers/VectorVerticalOperationsTest.h @@ -21,6 +21,9 @@ #elif defined(STATIC_VECTOR) #include <TNL/Containers/StaticVector.h> #else + #ifdef VECTOR_OF_STATIC_VECTORS + #include <TNL/Containers/StaticVector.h> + #endif #include <TNL/Containers/Vector.h> #include <TNL/Containers/VectorView.h> #endif @@ -120,35 +123,57 @@ protected: #endif >; #elif defined(STATIC_VECTOR) - using VectorTypes = ::testing::Types< - StaticVector< 1, int >, - StaticVector< 1, double >, - StaticVector< 2, int >, - StaticVector< 2, double >, - StaticVector< 3, int >, - StaticVector< 3, double >, - StaticVector< 4, int >, - StaticVector< 4, double >, - StaticVector< 5, int >, - StaticVector< 5, double > - >; -#else - using VectorTypes = ::testing::Types< - #ifndef HAVE_CUDA - Vector< int, Devices::Host >, - VectorView< int, Devices::Host >, - VectorView< const int, Devices::Host >, - Vector< double, Devices::Host >, - VectorView< double, Devices::Host > + #ifdef VECTOR_OF_STATIC_VECTORS + using VectorTypes = ::testing::Types< + StaticVector< 1, StaticVector< 3, double > >, + StaticVector< 2, StaticVector< 3, double > >, + StaticVector< 3, StaticVector< 3, double > >, + StaticVector< 4, StaticVector< 3, double > >, + StaticVector< 5, StaticVector< 3, double > > + >; + #else + using VectorTypes = ::testing::Types< + StaticVector< 1, int >, + StaticVector< 1, double >, + StaticVector< 2, int >, + StaticVector< 2, double >, + StaticVector< 3, int >, + StaticVector< 3, double >, + StaticVector< 4, int >, + StaticVector< 4, double >, + StaticVector< 5, int >, + StaticVector< 5, double > + >; #endif - #ifdef HAVE_CUDA - Vector< int, Devices::Cuda >, - VectorView< int, Devices::Cuda >, - VectorView< const int, Devices::Cuda >, - Vector< double, Devices::Cuda >, - VectorView< double, Devices::Cuda > +#else + #ifdef VECTOR_OF_STATIC_VECTORS + using VectorTypes = ::testing::Types< + #ifndef HAVE_CUDA + Vector< StaticVector< 3, double >, Devices::Host >, + VectorView< StaticVector< 3, double >, Devices::Host > + #else + Vector< StaticVector< 3, double >, Devices::Cuda >, + VectorView< StaticVector< 3, double >, Devices::Cuda > + #endif + >; + #else + using VectorTypes = ::testing::Types< + #ifndef HAVE_CUDA + Vector< int, Devices::Host >, + VectorView< int, Devices::Host >, + VectorView< const int, Devices::Host >, + Vector< double, Devices::Host >, + VectorView< double, Devices::Host > + #endif + #ifdef HAVE_CUDA + Vector< int, Devices::Cuda >, + VectorView< int, Devices::Cuda >, + VectorView< const int, Devices::Cuda >, + Vector< double, Devices::Cuda >, + VectorView< double, Devices::Cuda > + #endif + >; #endif - >; #endif TYPED_TEST_SUITE( VectorVerticalOperationsTest, VectorTypes );