All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SVecSVecMultExpr.h
Go to the documentation of this file.
1 //=================================================================================================
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_EXPRESSIONS_SVECSVECMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SVECSVECMULTEXPR_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <stdexcept>
50 #include <blaze/math/Functions.h>
57 #include <blaze/util/Assert.h>
60 #include <blaze/util/SelectType.h>
61 #include <blaze/util/Types.h>
63 
64 
65 namespace blaze {
66 
67 //=================================================================================================
68 //
69 // CLASS SVECSVECMULTEXPR
70 //
71 //=================================================================================================
72 
73 //*************************************************************************************************
80 template< typename VT1 // Type of the left-hand side sparse vector
81  , typename VT2 // Type of the right-hand side sparse vector
82  , bool TF > // Transpose flag
83 class SVecSVecMultExpr : public SparseVector< SVecSVecMultExpr<VT1,VT2,TF>, TF >
84  , private VecVecMultExpr
85  , private Computation
86 {
87  private:
88  //**Type definitions****************************************************************************
89  typedef typename VT1::ResultType RT1;
90  typedef typename VT2::ResultType RT2;
91  typedef typename VT1::ReturnType RN1;
92  typedef typename VT2::ReturnType RN2;
93  typedef typename VT1::CompositeType CT1;
94  typedef typename VT2::CompositeType CT2;
95  typedef typename VT1::TransposeType TT1;
96  typedef typename VT2::TransposeType TT2;
97  //**********************************************************************************************
98 
99  //**Return type evaluation**********************************************************************
101 
106  enum { returnExpr = !IsTemporary<RN1>::value && !IsTemporary<RN2>::value };
107 
110  //**********************************************************************************************
111 
112  public:
113  //**Type definitions****************************************************************************
118 
121 
123  typedef const ResultType CompositeType;
124 
126  typedef typename SelectType< IsExpression<VT1>::value, const VT1, const VT1& >::Type LeftOperand;
127 
129  typedef typename SelectType< IsExpression<VT2>::value, const VT2, const VT2& >::Type RightOperand;
130  //**********************************************************************************************
131 
132  //**Compilation flags***************************************************************************
134  enum { smpAssignable = 0 };
135  //**********************************************************************************************
136 
137  //**Constructor*********************************************************************************
140  explicit inline SVecSVecMultExpr( const VT1& lhs, const VT2& rhs )
141  : lhs_( lhs ) // Left-hand side sparse vector of the multiplication expression
142  , rhs_( rhs ) // Right-hand side sparse vector of the multiplication expression
143  {
144  BLAZE_INTERNAL_ASSERT( lhs.size() == rhs.size(), "Invalid vector sizes" );
145  }
146  //**********************************************************************************************
147 
148  //**Subscript operator**************************************************************************
154  inline ReturnType operator[]( size_t index ) const {
155  BLAZE_INTERNAL_ASSERT( index < lhs_.size(), "Invalid vector access index" );
156  return lhs_[index] * rhs_[index];
157  }
158  //**********************************************************************************************
159 
160  //**Size function*******************************************************************************
165  inline size_t size() const {
166  return lhs_.size();
167  }
168  //**********************************************************************************************
169 
170  //**NonZeros function***************************************************************************
175  inline size_t nonZeros() const {
176  return min( lhs_.nonZeros(), rhs_.nonZeros() );
177  }
178  //**********************************************************************************************
179 
180  //**Left operand access*************************************************************************
185  inline LeftOperand leftOperand() const {
186  return lhs_;
187  }
188  //**********************************************************************************************
189 
190  //**Right operand access************************************************************************
195  inline RightOperand rightOperand() const {
196  return rhs_;
197  }
198  //**********************************************************************************************
199 
200  //**********************************************************************************************
206  template< typename T >
207  inline bool canAlias( const T* alias ) const {
208  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
209  }
210  //**********************************************************************************************
211 
212  //**********************************************************************************************
218  template< typename T >
219  inline bool isAliased( const T* alias ) const {
220  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
221  }
222  //**********************************************************************************************
223 
224  private:
225  //**Member variables****************************************************************************
228  //**********************************************************************************************
229 
230  //**Assignment to dense vectors*****************************************************************
242  template< typename VT > // Type of the target dense vector
243  friend inline void assign( DenseVector<VT,TF>& lhs, const SVecSVecMultExpr& rhs )
244  {
246 
247  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
248 
249  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
250  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
251 
252  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
253  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
254 
255  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
256  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
257  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
258 
259  const LeftIterator lend( x.end() );
260  const RightIterator rend( y.end() );
261 
262  LeftIterator l( x.begin() );
263  RightIterator r( y.begin() );
264 
265  for( ; l!=lend; ++l ) {
266  while( r!=rend && r->index() < l->index() ) ++r;
267  if( r==rend ) break;
268  if( l->index() == r->index() ) {
269  (~lhs)[l->index()] = l->value() * r->value();
270  ++r;
271  }
272  }
273  }
275  //**********************************************************************************************
276 
277  //**Assignment to sparse vectors****************************************************************
289  template< typename VT > // Type of the target sparse vector
290  friend inline void assign( SparseVector<VT,TF>& lhs, const SVecSVecMultExpr& rhs )
291  {
293 
294  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
295 
296  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
297  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
298 
299  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
300  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
301 
302  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
303  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
304  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
305 
306  const LeftIterator lend( x.end() );
307  const RightIterator rend( y.end() );
308 
309  LeftIterator l( x.begin() );
310  RightIterator r( y.begin() );
311 
312  for( ; l!=lend; ++l ) {
313  while( r!=rend && r->index() < l->index() ) ++r;
314  if( r==rend ) break;
315  if( l->index() == r->index() ) {
316  (~lhs).append( l->index(), l->value() * r->value() );
317  ++r;
318  }
319  }
320  }
322  //**********************************************************************************************
323 
324  //**Addition assignment to dense vectors********************************************************
336  template< typename VT > // Type of the target dense vector
337  friend inline void addAssign( DenseVector<VT,TF>& lhs, const SVecSVecMultExpr& rhs )
338  {
340 
341  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
342 
343  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
344  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
345 
346  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
347  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
348 
349  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
350  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
351  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
352 
353  const LeftIterator lend( x.end() );
354  const RightIterator rend( y.end() );
355 
356  LeftIterator l( x.begin() );
357  RightIterator r( y.begin() );
358 
359  for( ; l!=lend; ++l ) {
360  while( r!=rend && r->index() < l->index() ) ++r;
361  if( r==rend ) break;
362  if( l->index() == r->index() ) {
363  (~lhs)[l->index()] += l->value() * r->value();
364  ++r;
365  }
366  }
367  }
369  //**********************************************************************************************
370 
371  //**Addition assignment to sparse vectors*******************************************************
372  // No special implementation for the addition assignment to sparse vectors.
373  //**********************************************************************************************
374 
375  //**Subtraction assignment to dense vectors*****************************************************
387  template< typename VT > // Type of the target dense vector
388  friend inline void subAssign( DenseVector<VT,TF>& lhs, const SVecSVecMultExpr& rhs )
389  {
391 
392  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
393 
394  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
395  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
396 
397  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
398  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
399 
400  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
401  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
402  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
403 
404  const LeftIterator lend( x.end() );
405  const RightIterator rend( y.end() );
406 
407  LeftIterator l( x.begin() );
408  RightIterator r( y.begin() );
409 
410  for( ; l!=lend; ++l ) {
411  while( r!=rend && r->index() < l->index() ) ++r;
412  if( r==rend ) break;
413  if( l->index() == r->index() ) {
414  (~lhs)[l->index()] -= l->value() * r->value();
415  ++r;
416  }
417  }
418  }
420  //**********************************************************************************************
421 
422  //**Subtraction assignment to sparse vectors****************************************************
423  // No special implementation for the subtraction assignment to sparse vectors.
424  //**********************************************************************************************
425 
426  //**Multiplication assignment to dense vectors**************************************************
438  template< typename VT > // Type of the target dense vector
439  friend inline void multAssign( DenseVector<VT,TF>& lhs, const SVecSVecMultExpr& rhs )
440  {
442 
443  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
444 
445  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
446  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
447 
448  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
449  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
450 
451  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
452  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
453  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
454 
455  const LeftIterator lend( x.end() );
456  const RightIterator rend( y.end() );
457 
458  LeftIterator l( x.begin() );
459  RightIterator r( y.begin() );
460 
461  size_t i( 0 );
462 
463  for( ; l!=lend; ++l ) {
464  while( r!=rend && r->index() < l->index() ) ++r;
465  if( r==rend ) break;
466  if( l->index() == r->index() ) {
467  for( ; i<r->index(); ++i )
468  reset( (~lhs)[i] );
469  (~lhs)[l->index()] *= l->value() * r->value();
470  ++r;
471  ++i;
472  }
473  }
474 
475  for( ; i<rhs.size(); ++i )
476  reset( (~lhs)[i] );
477  }
479  //**********************************************************************************************
480 
481  //**Multiplication assignment to sparse vectors*************************************************
493  template< typename VT > // Type of the target sparse vector
494  friend inline void multAssign( SparseVector<VT,TF>& lhs, const SVecSVecMultExpr& rhs )
495  {
497 
498  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
499 
500  typedef typename VT::ConstIterator Iterator1;
501  typedef typename RemoveReference<CT1>::Type::ConstIterator Iterator2;
502  typedef typename RemoveReference<CT2>::Type::ConstIterator Iterator3;
503 
504  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
505  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
506 
507  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
508  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
509  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
510 
511  VT tmp( rhs.size(), rhs.nonZeros() );
512 
513  const Iterator1 end1( (~lhs).end() );
514  const Iterator2 end2( x.end() );
515  const Iterator3 end3( y.end() );
516 
517  Iterator1 i1( (~lhs).begin() );
518  Iterator2 i2( x.begin() );
519  Iterator3 i3( y.begin() );
520 
521  for( ; i1!=end1; ++i1 ) {
522  while( i2!=end2 && i2->index() < i1->index() ) ++i2;
523  if( i2==end2 ) break;
524  while( i3!=end3 && i3->index() < i1->index() ) ++i3;
525  if( i3==end3 ) break;
526  if( i1->index() == i2->index() && i1->index() == i3->index() ) {
527  tmp.append( i1->index(), i1->value() * i2->value() * i3->value() );
528  ++i2;
529  ++i3;
530  }
531  }
532 
533  swap( ~lhs, tmp );
534  }
536  //**********************************************************************************************
537 
538  //**Compile time checks*************************************************************************
545  //**********************************************************************************************
546 };
547 //*************************************************************************************************
548 
549 
550 
551 
552 //=================================================================================================
553 //
554 // GLOBAL BINARY ARITHMETIC OPERATORS
555 //
556 //=================================================================================================
557 
558 //*************************************************************************************************
583 template< typename T1 // Type of the left-hand side sparse vector
584  , typename T2 // Type of the right-hand side sparse vector
585  , bool TF > // Transpose flag
586 inline const SVecSVecMultExpr<T1,T2,TF>
588 {
590 
591  if( (~lhs).size() != (~rhs).size() )
592  throw std::invalid_argument( "Vector sizes do not match" );
593 
594  return SVecSVecMultExpr<T1,T2,TF>( ~lhs, ~rhs );
595 }
596 //*************************************************************************************************
597 
598 
599 
600 
601 //=================================================================================================
602 //
603 // EXPRESSION TRAIT SPECIALIZATIONS
604 //
605 //=================================================================================================
606 
607 //*************************************************************************************************
609 template< typename VT1, typename VT2, bool TF, bool AF >
610 struct SubvectorExprTrait< SVecSVecMultExpr<VT1,VT2,TF>, AF >
611 {
612  public:
613  //**********************************************************************************************
614  typedef typename MultExprTrait< typename SubvectorExprTrait<const VT1,AF>::Type
615  , typename SubvectorExprTrait<const VT2,AF>::Type >::Type Type;
616  //**********************************************************************************************
617 };
619 //*************************************************************************************************
620 
621 } // namespace blaze
622 
623 #endif
Header file for mathematical functions.
SelectType< IsExpression< VT2 >::value, const VT2, const VT2 & >::Type RightOperand
Composite type of the right-hand side sparse vector expression.
Definition: SVecSVecMultExpr.h:129
void reset(DynamicMatrix< Type, SO > &m)
Resetting the given dense matrix.
Definition: DynamicMatrix.h:4579
Compile time check whether the given type is a temporary vector or matrix type.This type trait class ...
Definition: IsTemporary.h:87
const DMatDMatMultExpr< T1, T2 > operator*(const DenseMatrix< T1, false > &lhs, const DenseMatrix< T2, false > &rhs)
Multiplication operator for the multiplication of two row-major dense matrices ( ).
Definition: DMatDMatMultExpr.h:4075
MultTrait< RT1, RT2 >::Type ResultType
Result type for expression template evaluations.
Definition: SVecSVecMultExpr.h:115
Header file for the SparseVector base class.
VT1::TransposeType TT1
Transpose type of the left-hand side sparse vector expression.
Definition: SVecSVecMultExpr.h:95
Efficient implementation of a compressed matrix.The CompressedMatrix class template is the represent...
Definition: CompressedMatrix.h:197
SelectType< IsExpression< VT1 >::value, const VT1, const VT1 & >::Type LeftOperand
Composite type of the left-hand side sparse vector expression.
Definition: SVecSVecMultExpr.h:126
bool canAlias(const T *alias) const
Returns whether the expression can alias with the given address alias.
Definition: SVecSVecMultExpr.h:207
VT2::ResultType RT2
Result type of the right-hand side sparse vector expression.
Definition: SVecSVecMultExpr.h:90
const ResultType CompositeType
Data type for composite expression templates.
Definition: SVecSVecMultExpr.h:123
const This & CompositeType
Data type for composite expression templates.
Definition: CompressedMatrix.h:2384
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:249
VT1::ReturnType RN1
Return type of the left-hand side sparse vector expression.
Definition: SVecSVecMultExpr.h:91
Header file for the Computation base class.
size_t size() const
Returns the current size/dimension of the vector.
Definition: SVecSVecMultExpr.h:165
Constraint on the data type.
VT1::CompositeType CT1
Composite type of the left-hand side sparse vector expression.
Definition: SVecSVecMultExpr.h:93
Header file for the MultExprTrait class template.
Compile time type selection.The SelectType class template selects one of the two given types T1 and T...
Definition: SelectType.h:59
Header file for the IsTemporary type trait class.
Header file for the multiplication trait.
const Element * ConstIterator
Iterator over constant elements.
Definition: CompressedMatrix.h:2388
MultExprTrait< RN1, RN2 >::Type ExprReturnType
Expression return type for the subscript operator.
Definition: SVecSVecMultExpr.h:109
void assign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the assignment of a matrix to a matrix.
Definition: Matrix.h:179
Base class for N-dimensional dense vectors.The DenseVector class is a base class for all arbitrarily ...
Definition: DenseVector.h:70
VT2::ReturnType RN2
Return type of the right-hand side sparse vector expression.
Definition: SVecSVecMultExpr.h:92
#define BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE(T)
Constraint on the data type.In case the given data type T is not a sparse, N-dimensional vector type...
Definition: SparseVector.h:79
Constraint on the data type.
CompressedMatrix< Type, false > TransposeType
Transpose type for expression template evaluations.
Definition: CompressedMatrix.h:2381
RightOperand rhs_
Right-hand side sparse vector of the multiplication expression.
Definition: SVecSVecMultExpr.h:227
LeftOperand leftOperand() const
Returns the left-hand side sparse vector operand.
Definition: SVecSVecMultExpr.h:185
Header file for the VecVecMultExpr base class.
void multAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the multiplication assignment of a matrix to a matrix.
Definition: Matrix.h:269
Header file for the SelectType class template.
Header file for all forward declarations for expression class templates.
Constraint on the data type.
const Type & ReturnType
Return type for expression template evaluations.
Definition: CompressedMatrix.h:2383
Removal of reference modifiers.The RemoveCV type trait removes any reference modifiers from the given...
Definition: RemoveReference.h:69
VT1::ResultType RT1
Result type of the left-hand side sparse vector expression.
Definition: SVecSVecMultExpr.h:89
Expression object for sparse vector-sparse vector multiplications.The SVecSVecMultExpr class represen...
Definition: Forward.h:115
ReturnType operator[](size_t index) const
Subscript operator for the direct access to the vector elements.
Definition: SVecSVecMultExpr.h:154
Header file for run time assertion macros.
Base template for the MultTrait class.
Definition: MultTrait.h:141
void swap(DynamicMatrix< Type, SO > &a, DynamicMatrix< Type, SO > &b)
Swapping the contents of two matrices.
Definition: DynamicMatrix.h:4651
void addAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the addition assignment of a matrix to a matrix.
Definition: Matrix.h:209
ResultType::TransposeType TransposeType
Transpose type for expression template evaluations.
Definition: SVecSVecMultExpr.h:116
void subAssign(Matrix< MT1, SO1 > &lhs, const Matrix< MT2, SO2 > &rhs)
Default implementation of the subtraction assignment of a matrix to matrix.
Definition: Matrix.h:239
size_t nonZeros() const
Returns the number of non-zero elements in the sparse vector.
Definition: SVecSVecMultExpr.h:175
VT2::CompositeType CT2
Composite type of the right-hand side sparse vector expression.
Definition: SVecSVecMultExpr.h:94
const SelectType< returnExpr, ExprReturnType, ElementType >::Type ReturnType
Return type for expression template evaluations.
Definition: SVecSVecMultExpr.h:120
Header file for the RemoveReference type trait.
LeftOperand lhs_
Left-hand side sparse vector of the multiplication expression.
Definition: SVecSVecMultExpr.h:226
SVecSVecMultExpr< VT1, VT2, TF > This
Type of this SVecSVecMultExpr instance.
Definition: SVecSVecMultExpr.h:114
Header file for the IsComputation type trait class.
RightOperand rightOperand() const
Returns the right-hand side sparse vector operand.
Definition: SVecSVecMultExpr.h:195
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: SVecSVecMultExpr.h:219
Base class for sparse vectors.The SparseVector class is a base class for all arbitrarily sized (N-dim...
Definition: Forward.h:105
#define BLAZE_FUNCTION_TRACE
Function trace macro.This macro can be used to reliably trace function calls. In case function tracin...
Definition: FunctionTrace.h:157
This ResultType
Result type for expression template evaluations.
Definition: CompressedMatrix.h:2379
SVecSVecMultExpr(const VT1 &lhs, const VT2 &rhs)
Constructor for the SVecSVecMultExpr class.
Definition: SVecSVecMultExpr.h:140
Header file for basic type definitions.
Header file for the SubvectorExprTrait class template.
ResultType::ElementType ElementType
Resulting element type.
Definition: SVecSVecMultExpr.h:117
Evaluation of the resulting expression type of a multiplication.Via this type trait it is possible to...
Definition: MultExprTrait.h:137
#define BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG(T, TF)
Constraint on the data type.In case the given data type T is not a dense or sparse vector type and in...
Definition: TransposeFlag.h:238
#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
VT2::TransposeType TT2
Transpose type of the right-hand side sparse vector expression.
Definition: SVecSVecMultExpr.h:96
Header file for the IsExpression type trait class.
Header file for the FunctionTrace class.