Blaze  3.6
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>
64 #include <blaze/math/SIMD.h>
72 #include <blaze/util/Assert.h>
75 #include <blaze/util/mpl/And.h>
76 #include <blaze/util/mpl/If.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 ET = ElementType_t<MT>;
105 
107  using CT = RemoveReference_t< CompositeType_t<MT> >;
108  //**********************************************************************************************
109 
110  //**********************************************************************************************
111  static constexpr bool value =
112  ( useOptimizedKernels &&
113  CT::simdEnabled &&
114  If_t< HasSIMDEnabled_v<Abs> && HasSIMDEnabled_v<Power>
115  , And_t< GetSIMDEnabled<Abs,ET>, GetSIMDEnabled<Power,ET> >
116  , And_t< HasLoad<Abs>, HasLoad<Power> > >::value &&
117  HasSIMDAdd_v< ElementType_t<CT>, ElementType_t<CT> > );
118  //**********************************************************************************************
119 };
121 //*************************************************************************************************
122 
123 
124 
125 
126 //=================================================================================================
127 //
128 // GLOBAL FUNCTIONS
129 //
130 //=================================================================================================
131 
132 //*************************************************************************************************
147 template< typename MT // Type of the dense matrix
148  , typename Abs // Type of the abs opertaion
149  , typename Power // Type of the power operation
150  , typename Root > // Type of the root operation
151 inline decltype(auto) norm_backend( const DenseMatrix<MT,false>& dm, Abs abs, Power power, Root root, FalseType )
152 {
153  using CT = CompositeType_t<MT>;
154  using ET = ElementType_t<MT>;
155  using RT = decltype( evaluate( root( std::declval<ET>() ) ) );
156 
157  if( (~dm).rows() == 0UL || (~dm).columns() == 0UL ) return RT();
158 
159  CT tmp( ~dm );
160 
161  const size_t M( tmp.rows() );
162  const size_t N( tmp.columns() );
163 
164  ET norm( power( abs( tmp(0UL,0UL) ) ) );
165 
166  {
167  size_t j( 1UL );
168 
169  for( ; (j+4UL) <= N; j+=4UL ) {
170  norm += power( abs( tmp(0UL,j ) ) ) + power( abs( tmp(0UL,j+1UL) ) ) +
171  power( abs( tmp(0UL,j+2UL) ) ) + power( abs( tmp(0UL,j+3UL) ) );
172  }
173  for( ; (j+2UL) <= N; j+=2UL ) {
174  norm += power( abs( tmp(0UL,j) ) ) + power( abs( tmp(0UL,j+1UL) ) );
175  }
176  for( ; j<N; ++j ) {
177  norm += power( abs( tmp(0UL,j) ) );
178  }
179  }
180 
181  for( size_t i=1UL; i<M; ++i )
182  {
183  size_t j( 0UL );
184 
185  for( ; (j+4UL) <= N; j+=4UL ) {
186  norm += power( abs( tmp(i,j ) ) ) + power( abs( tmp(i,j+1UL) ) ) +
187  power( abs( tmp(i,j+2UL) ) ) + power( abs( tmp(i,j+3UL) ) );
188  }
189  for( ; (j+2UL) <= N; j+=2UL ) {
190  norm += power( abs( tmp(i,j) ) ) + power( abs( tmp(i,j+1UL) ) );
191  }
192  for( ; j<N; ++j ) {
193  norm += power( abs( tmp(i,j) ) );
194  }
195  }
196 
197  return evaluate( root( norm ) );
198 }
200 //*************************************************************************************************
201 
202 
203 //*************************************************************************************************
218 template< typename MT // Type of the dense matrix
219  , typename Abs // Type of the abs operation
220  , typename Power // Type of the power operation
221  , typename Root > // Type of the root operation
222 inline decltype(auto) norm_backend( const DenseMatrix<MT,true>& dm, Abs abs, Power power, Root root, FalseType )
223 {
224  using CT = CompositeType_t<MT>;
225  using ET = ElementType_t<MT>;
226  using RT = decltype( evaluate( root( std::declval<ET>() ) ) );
227 
228  if( (~dm).rows() == 0UL || (~dm).columns() == 0UL ) return RT();
229 
230  CT tmp( ~dm );
231 
232  const size_t M( tmp.rows() );
233  const size_t N( tmp.columns() );
234 
235  ET norm( power( abs( tmp(0UL,0UL) ) ) );
236 
237  {
238  size_t i( 1UL );
239 
240  for( ; (i+4UL) <= M; i+=4UL ) {
241  norm += power( abs( tmp(i ,0UL) ) ) + power( abs( tmp(i+1UL,0UL) ) ) +
242  power( abs( tmp(i+2UL,0UL) ) ) + power( abs( tmp(i+3UL,0UL) ) );
243  }
244  for( ; (i+2UL) <= M; i+=2UL ) {
245  norm += power( abs( tmp(i,0UL) ) ) + power( abs( tmp(i+1UL,0UL) ) );
246  }
247  for( ; i<M; ++i ) {
248  norm += power( abs( tmp(i,0UL) ) );
249  }
250  }
251 
252  for( size_t j=1UL; j<N; ++j )
253  {
254  size_t i( 0UL );
255 
256  for( ; (i+4UL) <= M; i+=4UL ) {
257  norm += power( abs( tmp(i ,j) ) ) + power( abs( tmp(i+1UL,j) ) ) +
258  power( abs( tmp(i+2UL,j) ) ) + power( abs( tmp(i+3UL,j) ) );
259  }
260  for( ; (i+2UL) <= M; i+=2UL ) {
261  norm += power( abs( tmp(i,j) ) ) + power( abs( tmp(i+1UL,j) ) );
262  }
263  for( ; i<M; ++i ) {
264  norm += power( abs( tmp(i,j) ) );
265  }
266  }
267 
268  return evaluate( root( norm ) );
269 }
271 //*************************************************************************************************
272 
273 
274 //*************************************************************************************************
289 template< typename MT // Type of the dense matrix
290  , typename Abs // Type of the abs operation
291  , typename Power // Type of the power operation
292  , typename Root > // Type of the root operation
293 inline decltype(auto) norm_backend( const DenseMatrix<MT,false>& dm, Abs abs, Power power, Root root, TrueType )
294 {
295  using CT = CompositeType_t<MT>;
296  using ET = ElementType_t<MT>;
297  using RT = decltype( evaluate( root( std::declval<ET>() ) ) );
298 
299  static constexpr size_t SIMDSIZE = SIMDTrait<ET>::size;
300 
301  if( (~dm).rows() == 0UL || (~dm).columns() == 0UL ) return RT();
302 
303  CT tmp( ~dm );
304 
305  const size_t M( tmp.rows() );
306  const size_t N( tmp.columns() );
307 
308  constexpr bool remainder( !usePadding || !IsPadded_v< RemoveReference_t<CT> > );
309 
310  const size_t jpos( ( remainder )?( N & size_t(-SIMDSIZE) ):( N ) );
311  BLAZE_INTERNAL_ASSERT( !remainder || ( N - ( N % SIMDSIZE ) ) == jpos, "Invalid end calculation" );
312 
313  SIMDTrait_t<ET> xmm1, xmm2, xmm3, xmm4;
314  ET norm{};
315 
316  for( size_t i=0UL; i<M; ++i )
317  {
318  size_t j( 0UL );
319 
320  for( ; (j+SIMDSIZE*3UL) < jpos; j+=SIMDSIZE*4UL ) {
321  xmm1 += power( abs( tmp.load(i,j ) ) );
322  xmm2 += power( abs( tmp.load(i,j+SIMDSIZE ) ) );
323  xmm3 += power( abs( tmp.load(i,j+SIMDSIZE*2UL) ) );
324  xmm4 += power( abs( tmp.load(i,j+SIMDSIZE*3UL) ) );
325  }
326  for( ; (j+SIMDSIZE) < jpos; j+=SIMDSIZE*2UL ) {
327  xmm1 += power( abs( tmp.load(i,j ) ) );
328  xmm2 += power( abs( tmp.load(i,j+SIMDSIZE) ) );
329  }
330  for( ; j<jpos; j+=SIMDSIZE ) {
331  xmm1 += power( abs( tmp.load(i,j) ) );
332  }
333  for( ; remainder && j<N; ++j ) {
334  norm += power( abs( tmp(i,j) ) );
335  }
336  }
337 
338  norm += sum( xmm1 + xmm2 + xmm3 + xmm4 );
339 
340  return evaluate( root( norm ) );
341 }
343 //*************************************************************************************************
344 
345 
346 //*************************************************************************************************
361 template< typename MT // Type of the dense matrix
362  , typename Abs // Type of the abs operation
363  , typename Power // Type of the power operation
364  , typename Root > // Type of the root operation
365 inline decltype(auto) norm_backend( const DenseMatrix<MT,true>& dm, Abs abs, Power power, Root root, TrueType )
366 {
367  using CT = CompositeType_t<MT>;
368  using ET = ElementType_t<MT>;
369  using RT = decltype( evaluate( root( std::declval<ET>() ) ) );
370 
371  static constexpr size_t SIMDSIZE = SIMDTrait<ET>::size;
372 
373  if( (~dm).rows() == 0UL || (~dm).columns() == 0UL ) return RT();
374 
375  CT tmp( ~dm );
376 
377  const size_t M( tmp.rows() );
378  const size_t N( tmp.columns() );
379 
380  constexpr bool remainder( !usePadding || !IsPadded_v< RemoveReference_t<CT> > );
381 
382  const size_t ipos( ( remainder )?( M & size_t(-SIMDSIZE) ):( M ) );
383  BLAZE_INTERNAL_ASSERT( !remainder || ( M - ( M % SIMDSIZE ) ) == ipos, "Invalid end calculation" );
384 
385  SIMDTrait_t<ET> xmm1, xmm2, xmm3, xmm4;
386  ET norm{};
387 
388  for( size_t j=0UL; j<N; ++j )
389  {
390  size_t i( 0UL );
391 
392  for( ; (i+SIMDSIZE*3UL) < ipos; i+=SIMDSIZE*4UL ) {
393  xmm1 += power( abs( tmp.load(i ,j) ) );
394  xmm2 += power( abs( tmp.load(i+SIMDSIZE ,j) ) );
395  xmm3 += power( abs( tmp.load(i+SIMDSIZE*2UL,j) ) );
396  xmm4 += power( abs( tmp.load(i+SIMDSIZE*3UL,j) ) );
397  }
398  for( ; (i+SIMDSIZE) < ipos; i+=SIMDSIZE*2UL ) {
399  xmm1 += power( abs( tmp.load(i ,j) ) );
400  xmm2 += power( abs( tmp.load(i+SIMDSIZE,j) ) );
401  }
402  for( ; i<ipos; i+=SIMDSIZE ) {
403  xmm1 += power( abs( tmp.load(i,j) ) );
404  }
405  for( ; remainder && i<M; ++i ) {
406  norm += power( abs( tmp(i,j) ) );
407  }
408  }
409 
410  norm += sum( xmm1 + xmm2 + xmm3 + xmm4 );
411 
412  return evaluate( root( norm ) );
413 }
415 //*************************************************************************************************
416 
417 
418 //*************************************************************************************************
439 template< typename MT // Type of the dense matrix
440  , bool SO // Storage order
441  , typename Abs // Type of the abs operation
442  , typename Power // Type of the power operation
443  , typename Root > // Type of the root operation
444 decltype(auto) norm_backend( const DenseMatrix<MT,SO>& dm, Abs abs, Power power, Root root )
445 {
446  return norm_backend( ~dm, abs, power, root, Bool_t< DMatNormHelper<MT,Abs,Power>::value >() );
447 }
449 //*************************************************************************************************
450 
451 
452 //*************************************************************************************************
467 template< typename MT // Type of the dense matrix
468  , bool SO > // Storage order
469 decltype(auto) norm( const DenseMatrix<MT,SO>& dm )
470 {
472 
473  return norm_backend( ~dm, SqrAbs(), Noop(), Sqrt() );
474 }
475 //*************************************************************************************************
476 
477 
478 //*************************************************************************************************
493 template< typename MT // Type of the dense matrix
494  , bool SO > // Storage order
495 decltype(auto) sqrNorm( const DenseMatrix<MT,SO>& dm )
496 {
498 
499  return norm_backend( ~dm, SqrAbs(), Noop(), Noop() );
500 }
501 //*************************************************************************************************
502 
503 
504 //*************************************************************************************************
519 template< typename MT // Type of the dense matrix
520  , bool SO > // Storage order
521 decltype(auto) l1Norm( const DenseMatrix<MT,SO>& dm )
522 {
524 
525  return norm_backend( ~dm, Abs(), Noop(), Noop() );
526 }
527 //*************************************************************************************************
528 
529 
530 //*************************************************************************************************
545 template< typename MT // Type of the dense matrix
546  , bool SO > // Storage order
547 decltype(auto) l2Norm( const DenseMatrix<MT,SO>& dm )
548 {
550 
551  return norm_backend( ~dm, SqrAbs(), Noop(), Sqrt() );
552 }
553 //*************************************************************************************************
554 
555 
556 //*************************************************************************************************
571 template< typename MT // Type of the dense matrix
572  , bool SO > // Storage order
573 decltype(auto) l3Norm( const DenseMatrix<MT,SO>& dm )
574 {
576 
577  return norm_backend( ~dm, Abs(), Pow3(), Cbrt() );
578 }
579 //*************************************************************************************************
580 
581 
582 //*************************************************************************************************
597 template< typename MT // Type of the dense matrix
598  , bool SO > // Storage order
599 decltype(auto) l4Norm( const DenseMatrix<MT,SO>& dm )
600 {
602 
603  return norm_backend( ~dm, SqrAbs(), Pow2(), Qdrt() );
604 }
605 //*************************************************************************************************
606 
607 
608 //*************************************************************************************************
628 template< typename MT // Type of the dense matrix
629  , bool SO // Storage order
630  , typename ST > // Type of the norm parameter
631 decltype(auto) lpNorm( const DenseMatrix<MT,SO>& dm, ST p )
632 {
634 
635  BLAZE_USER_ASSERT( !isZero( p ), "Invalid p for Lp norm detected" );
636 
637  using ScalarType = MultTrait_t< UnderlyingBuiltin_t<MT>, decltype( inv( p ) ) >;
638  using UnaryPow = Bind2nd<Pow,ScalarType>;
639  return norm_backend( ~dm, Abs(), UnaryPow( Pow(), p ), UnaryPow( Pow(), inv( p ) ) );
640 }
641 //*************************************************************************************************
642 
643 
644 //*************************************************************************************************
663 template< size_t P // Compile time norm parameter
664  , typename MT // Type of the dense matrix
665  , bool SO > // Storage order
666 inline decltype(auto) lpNorm( const DenseMatrix<MT,SO>& dm )
667 {
668  BLAZE_STATIC_ASSERT_MSG( P > 0UL, "Invalid norm parameter detected" );
669 
671  using Norm = typename TypeAt< Norms, min( P-1UL, 4UL ) >::Type;
672 
673  return Norm()( ~dm );
674 }
675 //*************************************************************************************************
676 
677 
678 //*************************************************************************************************
693 template< typename MT // Type of the dense matrix
694  , bool SO > // Storage order
695 decltype(auto) linfNorm( const DenseMatrix<MT,SO>& dm )
696 {
698 
699  return max( abs( ~dm ) );
700 }
701 //*************************************************************************************************
702 
703 
704 //*************************************************************************************************
719 template< typename MT // Type of the dense matrix
720  , bool SO > // Storage order
721 decltype(auto) maxNorm( const DenseMatrix<MT,SO>& dm )
722 {
724 
725  return linfNorm( ~dm );
726 }
727 //*************************************************************************************************
728 
729 } // namespace blaze
730 
731 #endif
Header file for the Pow functor.
decltype(auto) sqrNorm(const DenseMatrix< MT, SO > &dm)
Computes the squared L2 norm for the given dense matrix.
Definition: DMatNormExpr.h:495
BoolConstant< false > FalseType
Type/value traits base class.The FalseType class is used as base class for type traits and value trai...
Definition: IntegralConstant.h:121
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,...
Definition: Assert.h:117
Generic wrapper for the cbrt() function.
Definition: Cbrt.h:81
Generic wrapper for the squared abs() function.
Definition: SqrAbs.h:85
Header file for the HasLoad type trait.
Header file for basic type definitions.
decltype(auto) l3Norm(const DenseMatrix< MT, SO > &dm)
Computes the L3 norm for the given dense matrix.
Definition: DMatNormExpr.h:573
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:547
decltype(auto) l4Norm(const DenseMatrix< MT, SO > &dm)
Computes the L4 norm for the given dense matrix.
Definition: DMatNormExpr.h:599
Header file for the isZero shim.
Header file for the Bind2nd functor.
Header file for the And_t alias template.
decltype(auto) lpNorm(const DenseMatrix< MT, SO > &dm, ST p)
Computes the Lp norm for the given dense matrix.
Definition: DMatNormExpr.h:631
Header file for the invert shim.
Generic wrapper for the qdrt() function.
Definition: Qdrt.h:82
BoolConstant< true > TrueType
Type traits base class.The TrueType class is used as base class for type traits and value traits that...
Definition: IntegralConstant.h:132
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:912
constexpr size_t columns(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of columns of the matrix.
Definition: Matrix.h:514
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:81
bool isZero(const DiagonalProxy< MT > &proxy)
Returns whether the represented element is 0.
Definition: DiagonalProxy.h:677
Generic wrapper for the abs() function.
Definition: Abs.h:83
Generic wrapper for the sqrt() function.
Definition: Sqrt.h:83
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 the If class template.
Compile time assertion.
Header file for the SqrAbs functor.
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:521
decltype(auto) min(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise minimum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1162
decltype(auto) sum(const DenseMatrix< MT, SO > &dm)
Reduces the given dense matrix by means of addition.
Definition: DMatReduceExpr.h:2147
Header file for the HasSIMDAdd type trait.
Header file for the DenseMatrix base class.
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.
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:60
decltype(auto) max(const DenseMatrix< MT1, SO1 > &lhs, const DenseMatrix< MT2, SO2 > &rhs)
Computes the componentwise maximum of the dense matrices lhs and rhs.
Definition: DMatDMatMapExpr.h:1198
IntegralConstant< bool, B > Bool_t
Compile time integral constant wrapper for bool.The Bool_t alias template represents an integral wrap...
Definition: IntegralConstant.h:153
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:1156
decltype(auto) maxNorm(const DenseMatrix< MT, SO > &dm)
Computes the maximum norm for the given dense matrix.
Definition: DMatNormExpr.h:721
typename MultTrait< T1, T2 >::Type MultTrait_t
Auxiliary alias declaration for the MultTrait class template.The MultTrait_t alias declaration provid...
Definition: MultTrait.h:240
Header file for the evaluate shim.
Header file for the IsSIMDEnabled type trait.
Generic wrapper for the pow2() function.
Definition: Pow2.h:78
constexpr bool IsPadded_v
Auxiliary variable template for the IsPadded type trait.The IsPadded_v variable template provides a c...
Definition: IsPadded.h:134
Header file for run time assertion macros.
Generic wrapper for the pow() function.
Definition: Pow.h:63
Indexing a type list.The TypeAt class can be used to access a type list at a specified position to qu...
Definition: TypeAt.h:75
Header file for the Unique class template.
#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
Generic wrapper for a binary operation with fixed 2nd argument.
Definition: Bind2nd.h:65
constexpr size_t size(const Matrix< MT, SO > &matrix) noexcept
Returns the total number of elements of the matrix.
Definition: Matrix.h:530
Header file for the HasMember type traits.
Header file for the Noop functor.
constexpr size_t rows(const Matrix< MT, SO > &matrix) noexcept
Returns the current number of rows of the matrix.
Definition: Matrix.h:498
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:469
decltype(auto) linfNorm(const DenseMatrix< MT, SO > &dm)
Computes the infinity norm for the given dense matrix.
Definition: DMatNormExpr.h:695
Generic wrapper for the pow3() function.
Definition: Pow3.h:78
Header file for the L3Norm functor.
Header file for the IntegralConstant class template.
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,...
Definition: Assert.h:101
Header file for the Pow3 functor.
Header file for the function trace functionality.