All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TDVecDVecMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
20 //=================================================================================================
21 
22 #ifndef _BLAZE_MATH_EXPRESSIONS_TDVECDVECMULTEXPR_H_
23 #define _BLAZE_MATH_EXPRESSIONS_TDVECDVECMULTEXPR_H_
24 
25 
26 //*************************************************************************************************
27 // Includes
28 //*************************************************************************************************
29 
30 #include <stdexcept>
31 #include <boost/type_traits/remove_reference.hpp>
33 #include <blaze/math/Intrinsics.h>
35 #include <blaze/util/DisableIf.h>
36 #include <blaze/util/EnableIf.h>
37 #include <blaze/util/Types.h>
39 
40 
41 namespace blaze {
42 
43 //=================================================================================================
44 //
45 // CLASS DEFINITION
46 //
47 //=================================================================================================
48 
49 //*************************************************************************************************
54 template< typename T1 // Type of the left-hand side dense vector
55  , typename T2 > // Type of the right-hand side dense vector
56 struct TDVecDVecMultExprHelper
57 {
58  //**Type definitions****************************************************************************
60  typedef typename boost::remove_reference< typename T1::CompositeType >::type CT1;
61 
63  typedef typename boost::remove_reference< typename T2::CompositeType >::type CT2;
64  //**********************************************************************************************
65 
66  //**********************************************************************************************
67  enum { value = CT1::vectorizable &&
68  CT2::vectorizable &&
69  IsSame< typename CT1::ElementType, typename CT2::ElementType>::value &&
70  IntrinsicTrait< typename CT1::ElementType >::addition &&
71  IntrinsicTrait< typename CT2::ElementType >::multiplication };
72  //**********************************************************************************************
73 };
75 //*************************************************************************************************
76 
77 
78 
79 
80 //=================================================================================================
81 //
82 // GLOBAL BINARY ARITHMETIC OPERATORS
83 //
84 //=================================================================================================
85 
86 //*************************************************************************************************
112 template< typename T1 // Type of the left-hand side dense vector
113  , typename T2 > // Type of the right-hand side dense vector
114 inline typename DisableIf< TDVecDVecMultExprHelper<T1,T2>,
115  const typename MultTrait<typename T1::ElementType,typename T2::ElementType>::Type >::Type
117 {
118  if( (~lhs).size() != (~rhs).size() )
119  throw std::invalid_argument( "Vector sizes do not match" );
120 
121  typedef typename T1::CompositeType Lhs;
122  typedef typename T2::CompositeType Rhs;
123  typedef typename T1::ElementType ET1;
124  typedef typename T2::ElementType ET2;
125  typedef typename MultTrait<ET1,ET2>::Type MultType;
126 
127  if( (~lhs).size() == 0UL ) return MultType();
128 
129  Lhs left ( ~lhs );
130  Rhs right( ~rhs );
131 
132  MultType sp( left[0UL] * right[0UL] );
133 
134  for( size_t i=1UL; i<left.size(); ++i )
135  sp += left[i] * right[i];
136 
137  return sp;
138 }
139 //*************************************************************************************************
140 
141 
142 //*************************************************************************************************
170 template< typename T1 // Type of the left-hand side dense vector
171  , typename T2 > // Type of the right-hand side dense vector
172 inline typename EnableIf< TDVecDVecMultExprHelper<T1,T2>,
173  const typename MultTrait<typename T1::ElementType,typename T2::ElementType>::Type >::Type
174  operator*( const DenseVector<T1,true>& lhs, const DenseVector<T2,false>& rhs )
175 {
176  if( (~lhs).size() != (~rhs).size() )
177  throw std::invalid_argument( "Vector sizes do not match" );
178 
179  typedef typename T1::CompositeType Lhs;
180  typedef typename T2::CompositeType Rhs;
181  typedef typename T1::ElementType ET1;
182  typedef typename T2::ElementType ET2;
183  typedef typename MultTrait<ET1,ET2>::Type MultType;
184  typedef IntrinsicTrait<MultType> IT;
185 
186  if( (~lhs).size() == 0UL ) return MultType();
187 
188  Lhs left ( ~lhs );
189  Rhs right( ~rhs );
190 
191  typename IT::Type xmm1, xmm2, xmm3, xmm4;
192  MultType sp( 0 );
193 
194  const size_t N ( left.size() );
195  const size_t end( N - N % (IT::size*4UL) );
196 
197  for( size_t i=0UL; i<end; i+=IT::size*4UL ) {
198  xmm1 = xmm1 + ( left.get(i ) * right.get(i ) );
199  xmm2 = xmm2 + ( left.get(i+IT::size ) * right.get(i+IT::size ) );
200  xmm3 = xmm3 + ( left.get(i+IT::size*2UL) * right.get(i+IT::size*2UL) );
201  xmm4 = xmm4 + ( left.get(i+IT::size*3UL) * right.get(i+IT::size*3UL) );
202  }
203 
204  MultType array[IT::size];
205  store( array, xmm1 + xmm2 + xmm3 + xmm4 );
206 
207  for( size_t i=0UL; i<IT::size; ++i )
208  sp += array[i];
209  for( size_t i=end; i<N; ++i )
210  sp += left[i] * right[i];
211 
212  return sp;
213 }
214 //*************************************************************************************************
215 
216 } // namespace blaze
217 
218 #endif