DMatNormExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_DMATNORMEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_DMATNORMEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <utility>
44 #include <blaze/math/Aliases.h>
63 #include <blaze/math/SIMD.h>
69 #include <blaze/util/Assert.h>
70 #include <blaze/util/FalseType.h>
72 #include <blaze/util/mpl/And.h>
73 #include <blaze/util/mpl/Bool.h>
74 #include <blaze/util/mpl/If.h>
76 #include <blaze/util/Template.h>
77 #include <blaze/util/TrueType.h>
78 #include <blaze/util/TypeList.h>
79 #include <blaze/util/Types.h>
82 
83 
84 namespace blaze {
85 
86 //=================================================================================================
87 //
88 // CLASS DEFINITION
89 //
90 //=================================================================================================
91 
92 //*************************************************************************************************
97 template< typename MT // Type of the dense matrix
98  , typename Abs // Type of the abs operation
99  , typename Power > // Type of the power operation
100 struct DMatNormHelper
101 {
102  //**Type definitions****************************************************************************
104  using CT = RemoveReference_< CompositeType_<MT> >;
105  //**********************************************************************************************
106 
107  //**SIMD support detection**********************************************************************
109  BLAZE_CREATE_HAS_DATA_OR_FUNCTION_MEMBER_TYPE_TRAIT( HasSIMDEnabled, simdEnabled );
110 
113 
115  struct UseSIMDEnabledFlag {
116  enum : bool { value = Power::BLAZE_TEMPLATE simdEnabled< ElementType_<MT> >() };
117  };
118  //**********************************************************************************************
119 
120  //**********************************************************************************************
121  enum : bool { value = useOptimizedKernels &&
122  CT::simdEnabled &&
123  If_< And< HasSIMDEnabled<Abs>, HasSIMDEnabled<Power> >
124  , UseSIMDEnabledFlag
125  , And< HasLoad<Abs>, HasLoad<Power> > >::value &&
126  HasSIMDAdd< ElementType_<CT>, ElementType_<CT> >::value };
127  //**********************************************************************************************
128 };
130 //*************************************************************************************************
131 
132 
133 
134 
135 //=================================================================================================
136 //
137 // GLOBAL FUNCTIONS
138 //
139 //=================================================================================================
140 
141 //*************************************************************************************************
156 template< typename MT // Type of the dense matrix
157  , typename Abs // Type of the abs opertaion
158  , typename Power // Type of the power operation
159  , typename Root > // Type of the root operation
160 inline decltype(auto) norm_backend( const DenseMatrix<MT,false>& dm, Abs abs, Power power, Root root, FalseType )
161 {
162  using CT = CompositeType_<MT>;
163  using ET = ElementType_<MT>;
164  using RT = decltype( evaluate( root( std::declval<ET>() ) ) );
165 
166  if( (~dm).rows() == 0UL || (~dm).columns() == 0UL ) return RT();
167 
168  CT tmp( ~dm );
169 
170  const size_t M( tmp.rows() );
171  const size_t N( tmp.columns() );
172 
173  ET norm( power( abs( tmp(0UL,0UL) ) ) );
174 
175  {
176  size_t j( 1UL );
177 
178  for( ; (j+4UL) <= N; j+=4UL ) {
179  norm += power( abs( tmp(0UL,j ) ) ) + power( abs( tmp(0UL,j+1UL) ) ) +
180  power( abs( tmp(0UL,j+2UL) ) ) + power( abs( tmp(0UL,j+3UL) ) );
181  }
182  for( ; (j+2UL) <= N; j+=2UL ) {
183  norm += power( abs( tmp(0UL,j) ) ) + power( abs( tmp(0UL,j+1UL) ) );
184  }
185  for( ; j<N; ++j ) {
186  norm += power( abs( tmp(0UL,j) ) );
187  }
188  }
189 
190  for( size_t i=1UL; i<M; ++i )
191  {
192  size_t j( 0UL );
193 
194  for( ; (j+4UL) <= N; j+=4UL ) {
195  norm += power( abs( tmp(i,j ) ) ) + power( abs( tmp(i,j+1UL) ) ) +
196  power( abs( tmp(i,j+2UL) ) ) + power( abs( tmp(i,j+3UL) ) );
197  }
198  for( ; (j+2UL) <= N; j+=2UL ) {
199  norm += power( abs( tmp(i,j) ) ) + power( abs( tmp(i,j+1UL) ) );
200  }
201  for( ; j<N; ++j ) {
202  norm += power( abs( tmp(i,j) ) );
203  }
204  }
205 
206  return evaluate( root( norm ) );
207 }
209 //*************************************************************************************************
210 
211 
212 //*************************************************************************************************
227 template< typename MT // Type of the dense matrix
228  , typename Abs // Type of the abs operation
229  , typename Power // Type of the power operation
230  , typename Root > // Type of the root operation
231 inline decltype(auto) norm_backend( const DenseMatrix<MT,true>& dm, Abs abs, Power power, Root root, FalseType )
232 {
233  using CT = CompositeType_<MT>;
234  using ET = ElementType_<MT>;
235  using RT = decltype( evaluate( root( std::declval<ET>() ) ) );
236 
237  if( (~dm).rows() == 0UL || (~dm).columns() == 0UL ) return RT();
238 
239  CT tmp( ~dm );
240 
241  const size_t M( tmp.rows() );
242  const size_t N( tmp.columns() );
243 
244  ET norm( power( abs( tmp(0UL,0UL) ) ) );
245 
246  {
247  size_t i( 1UL );
248 
249  for( ; (i+4UL) <= M; i+=4UL ) {
250  norm += power( abs( tmp(i ,0UL) ) ) + power( abs( tmp(i+1UL,0UL) ) ) +
251  power( abs( tmp(i+2UL,0UL) ) ) + power( abs( tmp(i+3UL,0UL) ) );
252  }
253  for( ; (i+2UL) <= M; i+=2UL ) {
254  norm += power( abs( tmp(i,0UL) ) ) + power( abs( tmp(i+1UL,0UL) ) );
255  }
256  for( ; i<M; ++i ) {
257  norm += power( abs( tmp(i,0UL) ) );
258  }
259  }
260 
261  for( size_t j=1UL; j<N; ++j )
262  {
263  size_t i( 0UL );
264 
265  for( ; (i+4UL) <= M; i+=4UL ) {
266  norm += power( abs( tmp(i ,j) ) ) + power( abs( tmp(i+1UL,j) ) ) +
267  power( abs( tmp(i+2UL,j) ) ) + power( abs( tmp(i+3UL,j) ) );
268  }
269  for( ; (i+2UL) <= M; i+=2UL ) {
270  norm += power( abs( tmp(i,j) ) ) + power( abs( tmp(i+1UL,j) ) );
271  }
272  for( ; i<M; ++i ) {
273  norm += power( abs( tmp(i,j) ) );
274  }
275  }
276 
277  return evaluate( root( norm ) );
278 }
280 //*************************************************************************************************
281 
282 
283 //*************************************************************************************************
298 template< typename MT // Type of the dense matrix
299  , typename Abs // Type of the abs operation
300  , typename Power // Type of the power operation
301  , typename Root > // Type of the root operation
302 inline decltype(auto) norm_backend( const DenseMatrix<MT,false>& dm, Abs abs, Power power, Root root, TrueType )
303 {
304  using CT = CompositeType_<MT>;
305  using ET = ElementType_<MT>;
306  using RT = decltype( evaluate( root( std::declval<ET>() ) ) );
307 
308  enum : size_t { SIMDSIZE = SIMDTrait<ET>::size };
309 
310  if( (~dm).rows() == 0UL || (~dm).columns() == 0UL ) return RT();
311 
312  CT tmp( ~dm );
313 
314  const size_t M( tmp.rows() );
315  const size_t N( tmp.columns() );
316 
317  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
318 
319  const size_t jpos( ( remainder )?( N & size_t(-SIMDSIZE) ):( N ) );
320  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
321 
322  SIMDTrait_<ET> xmm1, xmm2, xmm3, xmm4;
323  ET norm{};
324 
325  for( size_t i=0UL; i<M; ++i )
326  {
327  size_t j( 0UL );
328 
329  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
330  xmm1 += power( abs( tmp.load(i,j ) ) );
331  xmm2 += power( abs( tmp.load(i,j+SIMDSIZE ) ) );
332  xmm3 += power( abs( tmp.load(i,j+SIMDSIZE*2UL) ) );
333  xmm4 += power( abs( tmp.load(i,j+SIMDSIZE*3UL) ) );
334  }
335  for( ; (j+SIMDSIZE) < jpos; j+=SIMDSIZE*2UL ) {
336  xmm1 += power( abs( tmp.load(i,j ) ) );
337  xmm2 += power( abs( tmp.load(i,j+SIMDSIZE) ) );
338  }
339  for( ; j<jpos; j+=SIMDSIZE ) {
340  xmm1 += power( abs( tmp.load(i,j) ) );
341  }
342  for( ; remainder && j<N; ++j ) {
343  norm += power( abs( tmp(i,j) ) );
344  }
345  }
346 
347  norm += sum( xmm1 + xmm2 + xmm3 + xmm4 );
348 
349  return evaluate( root( norm ) );
350 }
352 //*************************************************************************************************
353 
354 
355 //*************************************************************************************************
370 template< typename MT // Type of the dense matrix
371  , typename Abs // Type of the abs operation
372  , typename Power // Type of the power operation
373  , typename Root > // Type of the root operation
374 inline decltype(auto) norm_backend( const DenseMatrix<MT,true>& dm, Abs abs, Power power, Root root, TrueType )
375 {
376  using CT = CompositeType_<MT>;
377  using ET = ElementType_<MT>;
378  using RT = decltype( evaluate( root( std::declval<ET>() ) ) );
379 
380  enum : size_t { SIMDSIZE = SIMDTrait<ET>::size };
381 
382  if( (~dm).rows() == 0UL || (~dm).columns() == 0UL ) return RT();
383 
384  CT tmp( ~dm );
385 
386  const size_t M( tmp.rows() );
387  const size_t N( tmp.columns() );
388 
389  constexpr bool remainder( !usePadding || !IsPadded<MT>::value );
390 
391  const size_t ipos( ( remainder )?( M & size_t(-SIMDSIZE) ):( M ) );
392  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
393 
394  SIMDTrait_<ET> xmm1, xmm2, xmm3, xmm4;
395  ET norm{};
396 
397  for( size_t j=0UL; j<N; ++j )
398  {
399  size_t i( 0UL );
400 
401  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
402  xmm1 += power( abs( tmp.load(i ,j) ) );
403  xmm2 += power( abs( tmp.load(i+SIMDSIZE ,j) ) );
404  xmm3 += power( abs( tmp.load(i+SIMDSIZE*2UL,j) ) );
405  xmm4 += power( abs( tmp.load(i+SIMDSIZE*3UL,j) ) );
406  }
407  for( ; (i+SIMDSIZE) < ipos; i+=SIMDSIZE*2UL ) {
408  xmm1 += power( abs( tmp.load(i ,j) ) );
409  xmm2 += power( abs( tmp.load(i+SIMDSIZE,j) ) );
410  }
411  for( ; i<ipos; i+=SIMDSIZE ) {
412  xmm1 += power( abs( tmp.load(i,j) ) );
413  }
414  for( ; remainder && i<M; ++i ) {
415  norm += power( abs( tmp(i,j) ) );
416  }
417  }
418 
419  norm += sum( xmm1 + xmm2 + xmm3 + xmm4 );
420 
421  return evaluate( root( norm ) );
422 }
424 //*************************************************************************************************
425 
426 
427 //*************************************************************************************************
448 template< typename MT // Type of the dense matrix
449  , bool SO // Storage order
450  , typename Abs // Type of the abs operation
451  , typename Power // Type of the power operation
452  , typename Root > // Type of the root operation
453 decltype(auto) norm_backend( const DenseMatrix<MT,SO>& dm, Abs abs, Power power, Root root )
454 {
455  return norm_backend( ~dm, abs, power, root, Bool< DMatNormHelper<MT,Abs,Power>::value >() );
456 }
458 //*************************************************************************************************
459 
460 
461 //*************************************************************************************************
476 template< typename MT // Type of the dense matrix
477  , bool SO > // Storage order
478 decltype(auto) norm( const DenseMatrix<MT,SO>& dm )
479 {
481 
482  return norm_backend( ~dm, Noop(), Pow2(), Sqrt() );
483 }
484 //*************************************************************************************************
485 
486 
487 //*************************************************************************************************
502 template< typename MT // Type of the dense matrix
503  , bool SO > // Storage order
504 decltype(auto) sqrNorm( const DenseMatrix<MT,SO>& dm )
505 {
507 
508  return norm_backend( ~dm, Noop(), Pow2(), Noop() );
509 }
510 //*************************************************************************************************
511 
512 
513 //*************************************************************************************************
528 template< typename MT // Type of the dense matrix
529  , bool SO > // Storage order
530 decltype(auto) l1Norm( const DenseMatrix<MT,SO>& dm )
531 {
533 
534  return norm_backend( ~dm, Abs(), Noop(), Noop() );
535 }
536 //*************************************************************************************************
537 
538 
539 //*************************************************************************************************
554 template< typename MT // Type of the dense matrix
555  , bool SO > // Storage order
556 decltype(auto) l2Norm( const DenseMatrix<MT,SO>& dm )
557 {
559 
560  return norm_backend( ~dm, Noop(), Pow2(), Sqrt() );
561 }
562 //*************************************************************************************************
563 
564 
565 //*************************************************************************************************
580 template< typename MT // Type of the dense matrix
581  , bool SO > // Storage order
582 decltype(auto) l3Norm( const DenseMatrix<MT,SO>& dm )
583 {
585 
586  return norm_backend( ~dm, Abs(), Pow3(), Cbrt() );
587 }
588 //*************************************************************************************************
589 
590 
591 //*************************************************************************************************
606 template< typename MT // Type of the dense matrix
607  , bool SO > // Storage order
608 decltype(auto) l4Norm( const DenseMatrix<MT,SO>& dm )
609 {
611 
612  return norm_backend( ~dm, Noop(), Pow4(), Qdrt() );
613 }
614 //*************************************************************************************************
615 
616 
617 //*************************************************************************************************
637 template< typename MT // Type of the dense matrix
638  , bool SO // Storage order
639  , typename ST > // Type of the norm parameter
640 decltype(auto) lpNorm( const DenseMatrix<MT,SO>& dm, ST p )
641 {
643 
644  BLAZE_USER_ASSERT( !isZero( p ), "Invalid p for Lp norm detected" );
645 
646  using ScalarType = MultTrait_< UnderlyingBuiltin_<MT>, decltype( inv( p ) ) >;
647  return norm_backend( ~dm, Abs(), UnaryPow<ScalarType>( p ), UnaryPow<ScalarType>( inv( p ) ) );
648 }
649 //*************************************************************************************************
650 
651 
652 //*************************************************************************************************
671 template< size_t P // Compile time norm parameter
672  , typename MT // Type of the dense matrix
673  , bool SO > // Storage order
674 inline decltype(auto) lpNorm( const DenseMatrix<MT,SO>& dm )
675 {
676  BLAZE_STATIC_ASSERT_MSG( P > 0UL, "Invalid norm parameter detected" );
677 
679  using Norm = typename TypeAt< Norms, min( P-1UL, 4UL ) >::Type;
680 
681  return Norm()( ~dm );
682 }
683 //*************************************************************************************************
684 
685 
686 //*************************************************************************************************
701 template< typename MT // Type of the dense matrix
702  , bool SO > // Storage order
703 decltype(auto) maxNorm( const DenseMatrix<MT,SO>& dm )
704 {
706 
707  return max( abs( ~dm ) );
708 }
709 //*************************************************************************************************
710 
711 } // namespace blaze
712 
713 #endif
decltype(auto) sqrNorm(const DenseMatrix< MT, SO > &dm)
Computes the squared L2 norm for the given dense matrix.
Definition: DMatNormExpr.h:504
BoolConstant< false > FalseType
Type/value traits base class.The FalseType class is used as base class for type traits and value trai...
Definition: FalseType.h:61
Header file for the Sqrt functor.
Header file for auxiliary alias declarations.
#define BLAZE_USER_ASSERT(expr, msg)
Run time assertion macro for user checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_USER_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERT flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:117
Generic wrapper for the cbrt() function.
Definition: Cbrt.h:62
Header file for the Pow4 functor.
Header file for basic type definitions.
#define BLAZE_CREATE_HAS_DATA_OR_FUNCTION_MEMBER_TYPE_TRAIT(TYPE_TRAIT_NAME, MEMBER_NAME)
Macro for the creation of a type trait for compile time checks for member data and functions...
Definition: HasMember.h:98
decltype(auto) l3Norm(const DenseMatrix< MT, SO > &dm)
Computes the L3 norm for the given dense matrix.
Definition: DMatNormExpr.h:582
Header file for the Pow2 functor.
decltype(auto) l2Norm(const DenseMatrix< MT, SO > &dm)
Computes the L2 norm for the given dense matrix.
Definition: DMatNormExpr.h:556
Header file for the FalseType type/value trait base class.
decltype(auto) l4Norm(const DenseMatrix< MT, SO > &dm)
Computes the L4 norm for the given dense matrix.
Definition: DMatNormExpr.h:608
BLAZE_ALWAYS_INLINE size_t size(const Vector< VT, TF > &vector) noexcept
Returns the current size/dimension of the vector.
Definition: Vector.h:265
Header file for the And class template.
const ElementType_< MT > min(const DenseMatrix< MT, SO > &dm)
Returns the smallest element of the dense matrix.
Definition: DenseMatrix.h:1903
Generic wrapper for the pow() function with fixed exponent.
Definition: Forward.h:119
decltype(auto) lpNorm(const DenseMatrix< MT, SO > &dm, ST p)
Computes the Lp norm for the given dense matrix.
Definition: DMatNormExpr.h:640
Header file for the invert shim.
typename MultTrait< T1, T2 >::Type MultTrait_
Auxiliary alias declaration for the MultTrait class template.The MultTrait_ alias declaration provide...
Definition: MultTrait.h:291
Generic wrapper for the qdrt() function.
Definition: Qdrt.h:61
BoolConstant< true > TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: TrueType.h:61
System settings for performance optimizations.
#define BLAZE_STATIC_ASSERT_MSG(expr, msg)
Compile time assertion macro.In case of an invalid compile time expression, a compilation error is cr...
Definition: StaticAssert.h:123
const MT::ResultType evaluate(const Matrix< MT, SO > &matrix)
Evaluates the given matrix expression.
Definition: Matrix.h:888
const ElementType_< MT > max(const DenseMatrix< MT, SO > &dm)
Returns the largest element of the dense matrix.
Definition: DenseMatrix.h:1950
Header file for the Cbrt functor.
Header file for the LpNorm functor.
Base class for dense matrices.The DenseMatrix class is a base class for all dense matrix classes...
Definition: DenseMatrix.h:80
bool isZero(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is 0.
Definition: DiagonalProxy.h:670
Generic wrapper for the sqrt() function.
Definition: Sqrt.h:62
Header file for the multiplication trait.
Namespace of the Blaze C++ math library.
Definition: Blaze.h:58
Header file for the L4Norm functor.
Header file for nested template disabiguation.
Header file for the If class template.
Compile time assertion.
Header file for the UnderlyingBuiltin type trait.
decltype(auto) l1Norm(const DenseMatrix< MT, SO > &dm)
Computes the L1 norm for the given dense matrix.
Definition: DMatNormExpr.h:530
Header file for the HasSIMDAdd type trait.
Header file for the DenseMatrix base class.
Header file for the isZero shim.
decltype(auto) inv(const DenseMatrix< MT, SO > &dm)
Calculation of the inverse of the given dense matrix.
Definition: DMatInvExpr.h:423
Header file for all SIMD functionality.
Header file for the L2Norm functor.
BLAZE_ALWAYS_INLINE size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:506
Implementation of a type list.The TypeList class template represents a list of data types of arbitrar...
Definition: TypeList.h:119
Generic wrapper for the null function.
Definition: Noop.h:59
Header file for the Abs functor.
Header file for the IsPadded type trait.
decltype(auto) abs(const DenseMatrix< MT, SO > &dm)
Applies the abs() function to each single element of the dense matrix dm.
Definition: DMatMapExpr.h:1176
decltype(auto) maxNorm(const DenseMatrix< MT, SO > &dm)
Computes the maximum norm for the given dense matrix.
Definition: DMatNormExpr.h:703
Generic wrapper for the pow4() function.
Definition: Pow4.h:61
Header file for the evaluate shim.
Generic wrapper for the pow2() function.
Definition: Pow2.h:61
BLAZE_ALWAYS_INLINE ValueType_< T > sum(const SIMDi8< T > &a) noexcept
Returns the sum of all elements in the 8-bit integral SIMD vector.
Definition: Reduction.h:65
Header file for run time assertion macros.
Indexing a type list.The TypeAt class can be used to access a type list at a specified position to qu...
Definition: TypeAt.h:76
Header file for the Unique class template.
Header file for the UnaryPow functor.
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:94
Header file for the HasMember type traits.
Header file for the Noop functor.
Header file for the RemoveReference type trait.
decltype(auto) norm(const DenseMatrix< MT, SO > &dm)
Computes the L2 norm for the given dense matrix.
Definition: DMatNormExpr.h:478
BLAZE_ALWAYS_INLINE size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:490
Generic wrapper for the pow3() function.
Definition: Pow3.h:61
Header file for the L3Norm functor.
Header file for the L1Norm functor.
Header file for the Qdrt functor.
#define BLAZE_INTERNAL_ASSERT(expr, msg)
Run time assertion macro for internal checks.In case of an invalid run time expression, the program execution is terminated. The BLAZE_INTERNAL_ASSERT macro can be disabled by setting the BLAZE_USER_ASSERTION flag to zero or by defining NDEBUG during the compilation.
Definition: Assert.h:101
Header file for the Bool class template.
Header file for the Pow3 functor.
Header file for the TrueType type/value trait base class.
Header file for the function trace functionality.