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  //**Constructor*********************************************************************************
135  explicit inline SVecSVecMultExpr( const VT1& lhs, const VT2& rhs )
136  : lhs_( lhs ) // Left-hand side sparse vector of the multiplication expression
137  , rhs_( rhs ) // Right-hand side sparse vector of the multiplication expression
138  {
139  BLAZE_INTERNAL_ASSERT( lhs.size() == rhs.size(), "Invalid vector sizes" );
140  }
141  //**********************************************************************************************
142 
143  //**Subscript operator**************************************************************************
149  inline ReturnType operator[]( size_t index ) const {
150  BLAZE_INTERNAL_ASSERT( index < lhs_.size(), "Invalid vector access index" );
151  return lhs_[index] * rhs_[index];
152  }
153  //**********************************************************************************************
154 
155  //**Size function*******************************************************************************
160  inline size_t size() const {
161  return lhs_.size();
162  }
163  //**********************************************************************************************
164 
165  //**NonZeros function***************************************************************************
170  inline size_t nonZeros() const {
171  return min( lhs_.nonZeros(), rhs_.nonZeros() );
172  }
173  //**********************************************************************************************
174 
175  //**Left operand access*************************************************************************
180  inline LeftOperand leftOperand() const {
181  return lhs_;
182  }
183  //**********************************************************************************************
184 
185  //**Right operand access************************************************************************
190  inline RightOperand rightOperand() const {
191  return rhs_;
192  }
193  //**********************************************************************************************
194 
195  //**********************************************************************************************
201  template< typename T >
202  inline bool canAlias( const T* alias ) const {
203  return ( lhs_.canAlias( alias ) || rhs_.canAlias( alias ) );
204  }
205  //**********************************************************************************************
206 
207  //**********************************************************************************************
213  template< typename T >
214  inline bool isAliased( const T* alias ) const {
215  return ( lhs_.isAliased( alias ) || rhs_.isAliased( alias ) );
216  }
217  //**********************************************************************************************
218 
219  private:
220  //**Member variables****************************************************************************
223  //**********************************************************************************************
224 
225  //**Assignment to dense vectors*****************************************************************
237  template< typename VT > // Type of the target dense vector
238  friend inline void assign( DenseVector<VT,TF>& lhs, const SVecSVecMultExpr& rhs )
239  {
241 
242  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
243 
244  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
245  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
246 
247  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
248  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
249 
250  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
251  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
252  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
253 
254  const LeftIterator lend( x.end() );
255  const RightIterator rend( y.end() );
256 
257  LeftIterator l( x.begin() );
258  RightIterator r( y.begin() );
259 
260  for( ; l!=lend; ++l ) {
261  while( r!=rend && r->index() < l->index() ) ++r;
262  if( r==rend ) break;
263  if( l->index() == r->index() ) {
264  (~lhs)[l->index()] = l->value() * r->value();
265  ++r;
266  }
267  }
268  }
270  //**********************************************************************************************
271 
272  //**Assignment to sparse vectors****************************************************************
284  template< typename VT > // Type of the target sparse vector
285  friend inline void assign( SparseVector<VT,TF>& lhs, const SVecSVecMultExpr& rhs )
286  {
288 
289  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
290 
291  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
292  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
293 
294  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
295  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
296 
297  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
298  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
299  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
300 
301  const LeftIterator lend( x.end() );
302  const RightIterator rend( y.end() );
303 
304  LeftIterator l( x.begin() );
305  RightIterator r( y.begin() );
306 
307  for( ; l!=lend; ++l ) {
308  while( r!=rend && r->index() < l->index() ) ++r;
309  if( r==rend ) break;
310  if( l->index() == r->index() ) {
311  (~lhs).append( l->index(), l->value() * r->value() );
312  ++r;
313  }
314  }
315  }
317  //**********************************************************************************************
318 
319  //**Addition assignment to dense vectors********************************************************
331  template< typename VT > // Type of the target dense vector
332  friend inline void addAssign( DenseVector<VT,TF>& lhs, const SVecSVecMultExpr& rhs )
333  {
335 
336  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
337 
338  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
339  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
340 
341  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
342  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
343 
344  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
345  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
346  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
347 
348  const LeftIterator lend( x.end() );
349  const RightIterator rend( y.end() );
350 
351  LeftIterator l( x.begin() );
352  RightIterator r( y.begin() );
353 
354  for( ; l!=lend; ++l ) {
355  while( r!=rend && r->index() < l->index() ) ++r;
356  if( r==rend ) break;
357  if( l->index() == r->index() ) {
358  (~lhs)[l->index()] += l->value() * r->value();
359  ++r;
360  }
361  }
362  }
364  //**********************************************************************************************
365 
366  //**Addition assignment to sparse vectors*******************************************************
367  // No special implementation for the addition assignment to sparse vectors.
368  //**********************************************************************************************
369 
370  //**Subtraction assignment to dense vectors*****************************************************
382  template< typename VT > // Type of the target dense vector
383  friend inline void subAssign( DenseVector<VT,TF>& lhs, const SVecSVecMultExpr& rhs )
384  {
386 
387  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
388 
389  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
390  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
391 
392  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
393  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
394 
395  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
396  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
397  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
398 
399  const LeftIterator lend( x.end() );
400  const RightIterator rend( y.end() );
401 
402  LeftIterator l( x.begin() );
403  RightIterator r( y.begin() );
404 
405  for( ; l!=lend; ++l ) {
406  while( r!=rend && r->index() < l->index() ) ++r;
407  if( r==rend ) break;
408  if( l->index() == r->index() ) {
409  (~lhs)[l->index()] -= l->value() * r->value();
410  ++r;
411  }
412  }
413  }
415  //**********************************************************************************************
416 
417  //**Subtraction assignment to sparse vectors****************************************************
418  // No special implementation for the subtraction assignment to sparse vectors.
419  //**********************************************************************************************
420 
421  //**Multiplication assignment to dense vectors**************************************************
433  template< typename VT > // Type of the target dense vector
434  friend inline void multAssign( DenseVector<VT,TF>& lhs, const SVecSVecMultExpr& rhs )
435  {
437 
438  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
439 
440  typedef typename RemoveReference<CT1>::Type::ConstIterator LeftIterator;
441  typedef typename RemoveReference<CT2>::Type::ConstIterator RightIterator;
442 
443  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
444  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
445 
446  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
447  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
448  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
449 
450  const LeftIterator lend( x.end() );
451  const RightIterator rend( y.end() );
452 
453  LeftIterator l( x.begin() );
454  RightIterator r( y.begin() );
455 
456  size_t i( 0 );
457 
458  for( ; l!=lend; ++l ) {
459  while( r!=rend && r->index() < l->index() ) ++r;
460  if( r==rend ) break;
461  if( l->index() == r->index() ) {
462  for( ; i<r->index(); ++i )
463  reset( (~lhs)[i] );
464  (~lhs)[l->index()] *= l->value() * r->value();
465  ++r;
466  ++i;
467  }
468  }
469 
470  for( ; i<rhs.size(); ++i )
471  reset( (~lhs)[i] );
472  }
474  //**********************************************************************************************
475 
476  //**Multiplication assignment to sparse vectors*************************************************
488  template< typename VT > // Type of the target sparse vector
489  friend inline void multAssign( SparseVector<VT,TF>& lhs, const SVecSVecMultExpr& rhs )
490  {
492 
493  BLAZE_INTERNAL_ASSERT( (~lhs).size() == rhs.size(), "Invalid vector sizes" );
494 
495  typedef typename VT::ConstIterator Iterator1;
496  typedef typename RemoveReference<CT1>::Type::ConstIterator Iterator2;
497  typedef typename RemoveReference<CT2>::Type::ConstIterator Iterator3;
498 
499  CT1 x( rhs.lhs_ ); // Evaluation of the left-hand side sparse vector operand
500  CT2 y( rhs.rhs_ ); // Evaluation of the right-hand side sparse vector operand
501 
502  BLAZE_INTERNAL_ASSERT( x.size() == rhs.lhs_.size(), "Invalid vector size" );
503  BLAZE_INTERNAL_ASSERT( y.size() == rhs.rhs_.size(), "Invalid vector size" );
504  BLAZE_INTERNAL_ASSERT( x.size() == (~lhs).size() , "Invalid vector size" );
505 
506  VT tmp( rhs.size(), rhs.nonZeros() );
507 
508  const Iterator1 end1( (~lhs).end() );
509  const Iterator2 end2( x.end() );
510  const Iterator3 end3( y.end() );
511 
512  Iterator1 i1( (~lhs).begin() );
513  Iterator2 i2( x.begin() );
514  Iterator3 i3( y.begin() );
515 
516  for( ; i1!=end1; ++i1 ) {
517  while( i2!=end2 && i2->index() < i1->index() ) ++i2;
518  if( i2==end2 ) break;
519  while( i3!=end3 && i3->index() < i1->index() ) ++i3;
520  if( i3==end3 ) break;
521  if( i1->index() == i2->index() && i1->index() == i3->index() ) {
522  tmp.append( i1->index(), i1->value() * i2->value() * i3->value() );
523  ++i2;
524  ++i3;
525  }
526  }
527 
528  swap( ~lhs, tmp );
529  }
531  //**********************************************************************************************
532 
533  //**Compile time checks*************************************************************************
540  //**********************************************************************************************
541 };
542 //*************************************************************************************************
543 
544 
545 
546 
547 //=================================================================================================
548 //
549 // GLOBAL BINARY ARITHMETIC OPERATORS
550 //
551 //=================================================================================================
552 
553 //*************************************************************************************************
578 template< typename T1 // Type of the left-hand side sparse vector
579  , typename T2 // Type of the right-hand side sparse vector
580  , bool TF > // Transpose flag
581 inline const SVecSVecMultExpr<T1,T2,TF>
583 {
585 
586  if( (~lhs).size() != (~rhs).size() )
587  throw std::invalid_argument( "Vector sizes do not match" );
588 
589  return SVecSVecMultExpr<T1,T2,TF>( ~lhs, ~rhs );
590 }
591 //*************************************************************************************************
592 
593 
594 
595 
596 //=================================================================================================
597 //
598 // EXPRESSION TRAIT SPECIALIZATIONS
599 //
600 //=================================================================================================
601 
602 //*************************************************************************************************
604 template< typename VT1, typename VT2, bool TF >
605 struct SubvectorExprTrait< SVecSVecMultExpr<VT1,VT2,TF> >
606 {
607  public:
608  //**********************************************************************************************
609  typedef typename MultExprTrait< typename SubvectorExprTrait<const VT1>::Type
610  , typename SubvectorExprTrait<const VT2>::Type >::Type Type;
611  //**********************************************************************************************
612 };
614 //*************************************************************************************************
615 
616 } // namespace blaze
617 
618 #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:4512
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:3703
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:196
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:202
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:2375
Type ElementType
Type of the sparse matrix elements.
Definition: CompressedMatrix.h:248
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:160
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:2379
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:2372
RightOperand rhs_
Right-hand side sparse vector of the multiplication expression.
Definition: SVecSVecMultExpr.h:222
LeftOperand leftOperand() const
Returns the left-hand side sparse vector operand.
Definition: SVecSVecMultExpr.h:180
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:2374
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:149
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:4584
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:170
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:221
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:190
bool isAliased(const T *alias) const
Returns whether the expression is aliased with the given address alias.
Definition: SVecSVecMultExpr.h:214
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:2370
SVecSVecMultExpr(const VT1 &lhs, const VT2 &rhs)
Constructor for the SVecSVecMultExpr class.
Definition: SVecSVecMultExpr.h:135
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.