1 //=================================================================================================
2 /*!
3 //  \file blazetest/mathtest/operations/smatsvecmult/OperationTest.h
4 //  \brief Header file for the sparse matrix/sparse vector multiplication operation test
5 //
6 //  Copyright (C) 2012-2020 Klaus Iglberger - All Rights Reserved
7 //
8 //  This file is part of the Blaze library. You can redistribute it and/or modify it under
9 //  the terms of the New (Revised) BSD License. Redistribution and use in source and binary
10 //  forms, with or without modification, are permitted provided that the following conditions
11 //  are met:
12 //
13 //  1. Redistributions of source code must retain the above copyright notice, this list of
14 //     conditions and the following disclaimer.
15 //  2. Redistributions in binary form must reproduce the above copyright notice, this list
16 //     of conditions and the following disclaimer in the documentation and/or other materials
17 //     provided with the distribution.
18 //  3. Neither the names of the Blaze development group nor the names of its contributors
19 //     may be used to endorse or promote products derived from this software without specific
20 //     prior written permission.
21 //
22 //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
23 //  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 //  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25 //  SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 //  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 //  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 //  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 //  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 //  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 //  DAMAGE.
32 */
33 //=================================================================================================
34 
35 #ifndef _BLAZETEST_MATHTEST_OPERATIONS_SMATSVECMULT_OPERATIONTEST_H_
36 #define _BLAZETEST_MATHTEST_OPERATIONS_SMATSVECMULT_OPERATIONTEST_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <algorithm>
44 #include <cstring>
45 #include <sstream>
46 #include <stdexcept>
47 #include <string>
48 #include <typeinfo>
49 #include <utility>
50 #include <vector>
51 #include <blaze/math/Aliases.h>
52 #include <blaze/math/CompressedMatrix.h>
53 #include <blaze/math/constraints/ColumnMajorMatrix.h>
54 #include <blaze/math/constraints/ColumnVector.h>
55 #include <blaze/math/constraints/DenseMatrix.h>
56 #include <blaze/math/constraints/DenseVector.h>
57 #include <blaze/math/constraints/RowMajorMatrix.h>
58 #include <blaze/math/constraints/RowVector.h>
59 #include <blaze/math/constraints/Scalar.h>
60 #include <blaze/math/constraints/SparseMatrix.h>
61 #include <blaze/math/constraints/SparseVector.h>
62 #include <blaze/math/constraints/TransposeFlag.h>
63 #include <blaze/math/DynamicMatrix.h>
64 #include <blaze/math/Functors.h>
65 #include <blaze/math/StaticMatrix.h>
66 #include <blaze/math/traits/MultTrait.h>
67 #include <blaze/math/typetraits/IsRowMajorMatrix.h>
68 #include <blaze/math/typetraits/UnderlyingBuiltin.h>
69 #include <blaze/math/typetraits/UnderlyingScalar.h>
70 #include <blaze/math/Views.h>
71 #include <blaze/util/constraints/DerivedFrom.h>
72 #include <blaze/util/constraints/SameType.h>
73 #include <blaze/util/Random.h>
74 #include <blaze/util/typetraits/RemoveCVRef.h>
75 #include <blazetest/system/MathTest.h>
76 #include <blazetest/mathtest/Creator.h>
77 #include <blazetest/mathtest/IsEqual.h>
78 #include <blazetest/mathtest/RandomMaximum.h>
79 #include <blazetest/mathtest/RandomMinimum.h>
80 
81 
82 namespace blazetest {
83 
84 namespace mathtest {
85 
86 namespace operations {
87 
88 namespace smatsvecmult {
89 
90 //=================================================================================================
91 //
92 //  CLASS DEFINITION
93 //
94 //=================================================================================================
95 
96 //*************************************************************************************************
97 /*!\brief Auxiliary class template for the sparse matrix/sparse vector multiplication operation test.
98 //
99 // This class template represents one particular matrix/vector multiplication test between a
100 // matrix and a vector of particular types. The two template arguments \a MT and \a VT represent
101 // the types of the left-hand side matrix and right-hand side vector, respectively.
102 */
103 template< typename MT    // Type of the left-hand side sparse matrix
104         , typename VT >  // Type of the right-hand side sparse vector
105 class OperationTest
106 {
107  private:
108    //**Type definitions****************************************************************************
109    using MET = blaze::ElementType_t<MT>;  //!< Element type of the matrix type
110    using VET = blaze::ElementType_t<VT>;  //!< Element type of the vector type
111 
112    using OMT  = blaze::OppositeType_t<MT>;    //!< Matrix type with opposite storage order
113    using TMT  = blaze::TransposeType_t<MT>;   //!< Transpose matrix type
114    using TOMT = blaze::TransposeType_t<OMT>;  //!< Transpose matrix type with opposite storage order
115    using TVT  = blaze::TransposeType_t<VT>;   //!< Transpose vector type
116 
117    //! Sparse result type
118    using SRE = blaze::MultTrait_t<MT,VT>;
119 
120    using SET  = blaze::ElementType_t<SRE>;    //!< Element type of the sparse result
121    using TSRE = blaze::TransposeType_t<SRE>;  //!< Transpose sparse result type
122 
123    //! Dense result type
124    using DRE = blaze::DynamicVector<SET,false>;
125 
126    using DET  = blaze::ElementType_t<DRE>;    //!< Element type of the dense result
127    using TDRE = blaze::TransposeType_t<DRE>;  //!< Transpose dense result type
128 
129    using MRT  = blaze::DynamicMatrix<MET,false>;  //!< Matrix reference type
130    using VRT  = blaze::DynamicVector<VET,false>;  //!< Vector reference type
131    using RRE  = blaze::MultTrait_t<MRT,VRT>;      //!< Reference result type
132    using TRRE = blaze::TransposeType_t<RRE>;      //!< Transpose reference result type
133 
134    //! Type of the matrix/vector multiplication expression
135    using MatVecMultExprType =
136       blaze::RemoveCVRef_t< decltype( std::declval<MT>() * std::declval<VT>() ) >;
137 
138    //! Type of the transpose matrix/vector multiplication expression
139    using TMatVecMultExprType =
140       blaze::RemoveCVRef_t< decltype( std::declval<OMT>() * std::declval<VT>() ) >;
141    //**********************************************************************************************
142 
143  public:
144    //**Constructors********************************************************************************
145    /*!\name Constructors */
146    //@{
147    explicit OperationTest( const Creator<MT>& creator1, const Creator<VT>& creator2 );
148    // No explicitly declared copy constructor.
149    //@}
150    //**********************************************************************************************
151 
152    //**Destructor**********************************************************************************
153    // No explicitly declared destructor.
154    //**********************************************************************************************
155 
156  private:
157    //**Test functions******************************************************************************
158    /*!\name Test functions */
159    //@{
160                           void testInitialStatus     ();
161                           void testAssignment        ();
162                           void testEvaluation        ();
163                           void testElementAccess     ();
164                           void testBasicOperation    ();
165                           void testNegatedOperation  ();
166    template< typename T > void testScaledOperation   ( T scalar );
167                           void testTransOperation    ();
168                           void testCTransOperation   ();
169                           void testAbsOperation      ();
170                           void testConjOperation     ();
171                           void testRealOperation     ();
172                           void testImagOperation     ();
173                           void testEvalOperation     ();
174                           void testSerialOperation   ();
175                           void testNoAliasOperation  ();
176                           void testNoSIMDOperation   ();
177                           void testSubvectorOperation();
178                           void testElementsOperation ();
179 
180    template< typename OP > void testCustomOperation( OP op, const std::string& name );
181    //@}
182    //**********************************************************************************************
183 
184    //**Error detection functions*******************************************************************
185    /*!\name Error detection functions */
186    //@{
187    template< typename LT > void checkResults();
188    template< typename LT > void checkTransposeResults();
189    //@}
190    //**********************************************************************************************
191 
192    //**Utility functions***************************************************************************
193    /*!\name Utility functions */
194    //@{
195    void initResults();
196    void initTransposeResults();
197    template< typename LT > void convertException( const std::exception& ex );
198    //@}
199    //**********************************************************************************************
200 
201    //**Member variables****************************************************************************
202    /*!\name Member variables */
203    //@{
204    MT   lhs_;      //!< The left-hand side sparse matrix.
205    VT   rhs_;      //!< The right-hand side sparse vector.
206    DRE  dres_;     //!< The dense result vector.
207    SRE  sres_;     //!< The sparse result vector.
208    MRT  reflhs_;   //!< The reference left-hand side matrix.
209    VRT  refrhs_;   //!< The reference right-hand side vector.
210    RRE  refres_;   //!< The reference result.
211    OMT  olhs_;     //!< The left-hand side sparse matrix with opposite storage order.
212    TDRE tdres_;    //!< The transpose dense result vector.
213    TSRE tsres_;    //!< The transpose sparse result vector.
214    TRRE trefres_;  //!< The transpose reference result.
215 
216    std::string test_;   //!< Label of the currently performed test.
217    std::string error_;  //!< Description of the current error type.
218    //@}
219    //**********************************************************************************************
220 
221    //**Compile time checks*************************************************************************
222    /*! \cond BLAZE_INTERNAL */
223    BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE( MT   );
224    BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE( TMT  );
225    BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE( TOMT );
226    BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE( VT   );
227    BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE( TVT  );
228    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE ( MRT  );
229    BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE ( VRT  );
230    BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE ( RRE  );
231    BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE ( DRE  );
232    BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE( SRE  );
233    BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE ( TDRE );
234    BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE( TSRE );
235 
236    BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE   ( MT   );
237    BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE( TMT  );
238    BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE   ( TOMT );
239    BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE      ( VT   );
240    BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE         ( TVT  );
241    BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE   ( MRT  );
242    BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE      ( VRT  );
243    BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE      ( DRE  );
244    BLAZE_CONSTRAINT_MUST_BE_COLUMN_VECTOR_TYPE      ( SRE  );
245    BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE         ( TDRE );
246    BLAZE_CONSTRAINT_MUST_BE_ROW_VECTOR_TYPE         ( TSRE );
247 
248    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( MET, blaze::ElementType_t<OMT>    );
249    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( MET, blaze::ElementType_t<TMT>    );
250    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( MET, blaze::ElementType_t<TOMT>   );
251    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( VET, blaze::ElementType_t<TVT>    );
252    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( DET, blaze::ElementType_t<DRE>    );
253    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( DET, blaze::ElementType_t<TDRE>   );
254    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( DET, blaze::ElementType_t<SRE>    );
255    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( SET, blaze::ElementType_t<SRE>    );
256    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( SET, blaze::ElementType_t<TSRE>   );
257    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( SET, blaze::ElementType_t<DRE>    );
258    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( MT , blaze::OppositeType_t<OMT>   );
259    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( MT , blaze::TransposeType_t<TMT>  );
260    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( VT , blaze::TransposeType_t<TVT>  );
261    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( DRE, blaze::TransposeType_t<TDRE> );
262    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( SRE, blaze::TransposeType_t<TSRE> );
263 
264    BLAZE_CONSTRAINT_VECTORS_MUST_HAVE_SAME_TRANSPOSE_FLAG     ( MatVecMultExprType, blaze::ResultType_t<MatVecMultExprType>    );
265    BLAZE_CONSTRAINT_VECTORS_MUST_HAVE_DIFFERENT_TRANSPOSE_FLAG( MatVecMultExprType, blaze::TransposeType_t<MatVecMultExprType> );
266 
267    BLAZE_CONSTRAINT_VECTORS_MUST_HAVE_SAME_TRANSPOSE_FLAG     ( TMatVecMultExprType, blaze::ResultType_t<TMatVecMultExprType>    );
268    BLAZE_CONSTRAINT_VECTORS_MUST_HAVE_DIFFERENT_TRANSPOSE_FLAG( TMatVecMultExprType, blaze::TransposeType_t<TMatVecMultExprType> );
269 
270    BLAZE_CONSTRAINT_MUST_BE_DERIVED_FROM( MatVecMultExprType , blaze::BaseType_t<MatVecMultExprType > );
271    BLAZE_CONSTRAINT_MUST_BE_DERIVED_FROM( TMatVecMultExprType, blaze::BaseType_t<TMatVecMultExprType> );
272    /*! \endcond */
273    //**********************************************************************************************
274 };
275 //*************************************************************************************************
276 
277 
278 
279 
280 //=================================================================================================
281 //
282 //  CONSTRUCTORS
283 //
284 //=================================================================================================
285 
286 //*************************************************************************************************
287 /*!\brief Constructor for the sparse matrix/sparse vector multiplication operation test.
288 //
289 // \param creator1 The creator for the left-hand side sparse matrix of the multiplication.
290 // \param creator2 The creator for the right-hand side sparse vector of the multiplication.
291 // \exception std::runtime_error Operation error detected.
292 */
293 template< typename MT    // Type of the left-hand side sparse matrix
294         , typename VT >  // Type of the right-hand side sparse vector
OperationTest(const Creator<MT> & creator1,const Creator<VT> & creator2)295 OperationTest<MT,VT>::OperationTest( const Creator<MT>& creator1, const Creator<VT>& creator2 )
296    : lhs_ ( creator1() )  // The left-hand side sparse matrix
297    , rhs_ ( creator2() )  // The right-hand side sparse vector
298    , dres_()              // The dense result vector
299    , sres_()              // The sparse result vector
300    , reflhs_( lhs_ )      // The reference left-hand side matrix
301    , refrhs_( rhs_ )      // The reference right-hand side vector
302    , refres_()            // The reference result
303    , olhs_( lhs_ )        // The left-hand side sparse matrix with opposite storage order.
304    , tdres_()             // The transpose dense result vector.
305    , tsres_()             // The transpose sparse result vector.
306    , trefres_()           // The transpose reference result.
307    , test_()              // Label of the currently performed test
308    , error_()             // Description of the current error type
309 {
310    using Scalar = blaze::UnderlyingScalar_t<SET>;
311 
312    testInitialStatus();
313    testAssignment();
314    testEvaluation();
315    testElementAccess();
316    testBasicOperation();
317    testNegatedOperation();
318    testScaledOperation( 2 );
319    testScaledOperation( 2UL );
320    testScaledOperation( 2.0F );
321    testScaledOperation( 2.0 );
322    testScaledOperation( Scalar( 2 ) );
323    testTransOperation();
324    testCTransOperation();
325    testAbsOperation();
326    testConjOperation();
327    testRealOperation();
328    testImagOperation();
329    testEvalOperation();
330    testSerialOperation();
331    testNoAliasOperation();
332    testNoSIMDOperation();
333    testSubvectorOperation();
334    testElementsOperation();
335 }
336 //*************************************************************************************************
337 
338 
339 
340 
341 //=================================================================================================
342 //
343 //  TEST FUNCTIONS
344 //
345 //=================================================================================================
346 
347 //*************************************************************************************************
348 /*!\brief Tests on the initial status of the operands.
349 //
350 // \return void
351 // \exception std::runtime_error Initialization error detected.
352 //
353 // This function runs tests on the initial status of the operands. In case any initialization
354 // error is detected, a \a std::runtime_error exception is thrown.
355 */
356 template< typename MT    // Type of the left-hand side sparse matrix
357         , typename VT >  // Type of the right-hand side sparse vector
testInitialStatus()358 void OperationTest<MT,VT>::testInitialStatus()
359 {
360    //=====================================================================================
361    // Performing initial tests with the given types
362    //=====================================================================================
363 
364    // Checking the number of rows of the left-hand side operand
365    if( lhs_.rows() != reflhs_.rows() ) {
366       std::ostringstream oss;
367       oss << " Test: Initial size comparison of left-hand side sparse operand\n"
368           << " Error: Invalid number of rows\n"
369           << " Details:\n"
370           << "   Random seed = " << blaze::getSeed() << "\n"
371           << "   Sparse matrix type:\n"
372           << "     " << typeid( MT ).name() << "\n"
373           << "   Detected number of rows = " << lhs_.rows() << "\n"
374           << "   Expected number of rows = " << reflhs_.rows() << "\n";
375       throw std::runtime_error( oss.str() );
376    }
377 
378    // Checking the number of columns of the left-hand side operand
379    if( lhs_.columns() != reflhs_.columns() ) {
380       std::ostringstream oss;
381       oss << " Test: Initial size comparison of left-hand side sparse operand\n"
382           << " Error: Invalid number of columns\n"
383           << " Details:\n"
384           << "   Random seed = " << blaze::getSeed() << "\n"
385           << "   Sparse matrix type:\n"
386           << "     " << typeid( MT ).name() << "\n"
387           << "   Detected number of columns = " << lhs_.columns() << "\n"
388           << "   Expected number of columns = " << reflhs_.columns() << "\n";
389       throw std::runtime_error( oss.str() );
390    }
391 
392    // Checking the size of the right-hand side operand
393    if( rhs_.size() != refrhs_.size() ) {
394       std::ostringstream oss;
395       oss << " Test: Initial size comparison of right-hand side sparse operand\n"
396           << " Error: Invalid vector size\n"
397           << " Details:\n"
398           << "   Random seed = " << blaze::getSeed() << "\n"
399           << "   Sparse vector type:\n"
400           << "     " << typeid( VT ).name() << "\n"
401           << "   Detected size = " << rhs_.size() << "\n"
402           << "   Expected size = " << refrhs_.size() << "\n";
403       throw std::runtime_error( oss.str() );
404    }
405 
406    // Checking the initialization of the left-hand side operand
407    if( !isEqual( lhs_, reflhs_ ) ) {
408       std::ostringstream oss;
409       oss << " Test: Initial test of initialization of left-hand side sparse operand\n"
410           << " Error: Invalid matrix initialization\n"
411           << " Details:\n"
412           << "   Random seed = " << blaze::getSeed() << "\n"
413           << "   Sparse matrix type:\n"
414           << "     " << typeid( MT ).name() << "\n"
415           << "   Current initialization:\n" << lhs_ << "\n"
416           << "   Expected initialization:\n" << reflhs_ << "\n";
417       throw std::runtime_error( oss.str() );
418    }
419 
420    // Checking the initialization of the right-hand side operand
421    if( !isEqual( rhs_, refrhs_ ) ) {
422       std::ostringstream oss;
423       oss << " Test: Initial test of initialization of right-hand side sparse operand\n"
424           << " Error: Invalid vector initialization\n"
425           << " Details:\n"
426           << "   Random seed = " << blaze::getSeed() << "\n"
427           << "   Sparse vector type:\n"
428           << "     " << typeid( VT ).name() << "\n"
429           << "   Current initialization:\n" << rhs_ << "\n"
430           << "   Expected initialization:\n" << refrhs_ << "\n";
431       throw std::runtime_error( oss.str() );
432    }
433 
434 
435    //=====================================================================================
436    // Performing initial tests with the transpose types
437    //=====================================================================================
438 
439    // Checking the number of rows of the transpose left-hand side operand
440    if( olhs_.rows() != reflhs_.rows() ) {
441       std::ostringstream oss;
442       oss << " Test: Initial size comparison of transpose left-hand side sparse operand\n"
443           << " Error: Invalid number of rows\n"
444           << " Details:\n"
445           << "   Random seed = " << blaze::getSeed() << "\n"
446           << "   Transpose sparse matrix type:\n"
447           << "     " << typeid( TMT ).name() << "\n"
448           << "   Detected number of rows = " << olhs_.rows() << "\n"
449           << "   Expected number of rows = " << reflhs_.rows() << "\n";
450       throw std::runtime_error( oss.str() );
451    }
452 
453    // Checking the number of columns of the transpose left-hand side operand
454    if( olhs_.columns() != reflhs_.columns() ) {
455       std::ostringstream oss;
456       oss << " Test: Initial size comparison of transpose left-hand side sparse operand\n"
457           << " Error: Invalid number of columns\n"
458           << " Details:\n"
459           << "   Random seed = " << blaze::getSeed() << "\n"
460           << "   Transpose sparse matrix type:\n"
461           << "     " << typeid( TMT ).name() << "\n"
462           << "   Detected number of columns = " << olhs_.columns() << "\n"
463           << "   Expected number of columns = " << reflhs_.columns() << "\n";
464       throw std::runtime_error( oss.str() );
465    }
466 
467    // Checking the initialization of the transpose left-hand side operand
468    if( !isEqual( olhs_, reflhs_ ) ) {
469       std::ostringstream oss;
470       oss << " Test: Initial test of initialization of transpose left-hand side sparse operand\n"
471           << " Error: Invalid matrix initialization\n"
472           << " Details:\n"
473           << "   Random seed = " << blaze::getSeed() << "\n"
474           << "   Transpose sparse matrix type:\n"
475           << "     " << typeid( TMT ).name() << "\n"
476           << "   Current initialization:\n" << olhs_ << "\n"
477           << "   Expected initialization:\n" << reflhs_ << "\n";
478       throw std::runtime_error( oss.str() );
479    }
480 }
481 //*************************************************************************************************
482 
483 
484 //*************************************************************************************************
485 /*!\brief Testing the vector assignment.
486 //
487 // \return void
488 // \exception std::runtime_error Assignment error detected.
489 //
490 // This function tests the vector assignment. In case any error is detected, a
491 // \a std::runtime_error exception is thrown.
492 */
493 template< typename MT    // Type of the left-hand side sparse matrix
494         , typename VT >  // Type of the right-hand side sparse vector
testAssignment()495 void OperationTest<MT,VT>::testAssignment()
496 {
497    //=====================================================================================
498    // Performing an assignment with the given types
499    //=====================================================================================
500 
501    try {
502       lhs_ = reflhs_;
503       rhs_ = refrhs_;
504    }
505    catch( std::exception& ex ) {
506       std::ostringstream oss;
507       oss << " Test: Assignment with the given types\n"
508           << " Error: Failed assignment\n"
509           << " Details:\n"
510           << "   Random seed = " << blaze::getSeed() << "\n"
511           << "   Left-hand side sparse matrix type:\n"
512           << "     " << typeid( MT ).name() << "\n"
513           << "   Right-hand side sparse vector type:\n"
514           << "     " << typeid( VT ).name() << "\n"
515           << "   Error message: " << ex.what() << "\n";
516       throw std::runtime_error( oss.str() );
517    }
518 
519    if( !isEqual( lhs_, reflhs_ ) ) {
520       std::ostringstream oss;
521       oss << " Test: Checking the assignment result of left-hand side sparse operand\n"
522           << " Error: Invalid matrix initialization\n"
523           << " Details:\n"
524           << "   Random seed = " << blaze::getSeed() << "\n"
525           << "   Sparse matrix type:\n"
526           << "     " << typeid( MT ).name() << "\n"
527           << "   Current initialization:\n" << lhs_ << "\n"
528           << "   Expected initialization:\n" << reflhs_ << "\n";
529       throw std::runtime_error( oss.str() );
530    }
531 
532    if( !isEqual( rhs_, refrhs_ ) ) {
533       std::ostringstream oss;
534       oss << " Test: Checking the assignment result of right-hand side sparse operand\n"
535           << " Error: Invalid vector initialization\n"
536           << " Details:\n"
537           << "   Random seed = " << blaze::getSeed() << "\n"
538           << "   Sparse vector type:\n"
539           << "     " << typeid( VT ).name() << "\n"
540           << "   Current initialization:\n" << rhs_ << "\n"
541           << "   Expected initialization:\n" << refrhs_ << "\n";
542       throw std::runtime_error( oss.str() );
543    }
544 
545 
546    //=====================================================================================
547    // Performing an assignment with the transpose types
548    //=====================================================================================
549 
550    try {
551       olhs_ = reflhs_;
552    }
553    catch( std::exception& ex ) {
554       std::ostringstream oss;
555       oss << " Test: Assignment with the transpose types\n"
556           << " Error: Failed assignment\n"
557           << " Details:\n"
558           << "   Random seed = " << blaze::getSeed() << "\n"
559           << "   Transpose left-hand side sparse matrix type:\n"
560           << "     " << typeid( TMT ).name() << "\n"
561           << "   Error message: " << ex.what() << "\n";
562       throw std::runtime_error( oss.str() );
563    }
564 
565    if( !isEqual( olhs_, reflhs_ ) ) {
566       std::ostringstream oss;
567       oss << " Test: Checking the assignment result of transpose left-hand side sparse operand\n"
568           << " Error: Invalid matrix initialization\n"
569           << " Details:\n"
570           << "   Random seed = " << blaze::getSeed() << "\n"
571           << "   Transpose sparse matrix type:\n"
572           << "     " << typeid( TMT ).name() << "\n"
573           << "   Current initialization:\n" << olhs_ << "\n"
574           << "   Expected initialization:\n" << reflhs_ << "\n";
575       throw std::runtime_error( oss.str() );
576    }
577 }
578 //*************************************************************************************************
579 
580 
581 //*************************************************************************************************
582 /*!\brief Testing the explicit evaluation.
583 //
584 // \return void
585 // \exception std::runtime_error Evaluation error detected.
586 //
587 // This function tests the explicit evaluation. In case any error is detected, a
588 // \a std::runtime_error exception is thrown.
589 */
590 template< typename MT    // Type of the left-hand side sparse matrix
591         , typename VT >  // Type of the right-hand side sparse vector
testEvaluation()592 void OperationTest<MT,VT>::testEvaluation()
593 {
594    using blaze::IsRowMajorMatrix;
595 
596 
597    //=====================================================================================
598    // Testing the evaluation with the given types
599    //=====================================================================================
600 
601    {
602       const auto res   ( evaluate( lhs_    * rhs_    ) );
603       const auto refres( evaluate( reflhs_ * refrhs_ ) );
604 
605       if( !isEqual( res, refres ) ) {
606          std::ostringstream oss;
607          oss << " Test: Evaluation with the given matrix/vector\n"
608              << " Error: Failed evaluation\n"
609              << " Details:\n"
610              << "   Random seed = " << blaze::getSeed() << "\n"
611              << "   Left-hand side " << ( IsRowMajorMatrix<MT>::value ? ( "row-major" ) : ( "column-major" ) ) << " sparse matrix type:\n"
612              << "     " << typeid( lhs_ ).name() << "\n"
613              << "   Right-hand side sparse vector type:\n"
614              << "     " << typeid( rhs_ ).name() << "\n"
615              << "   Deduced result type:\n"
616              << "     " << typeid( res ).name() << "\n"
617              << "   Deduced reference result type:\n"
618              << "     " << typeid( refres ).name() << "\n"
619              << "   Result:\n" << res << "\n"
620              << "   Expected result:\n" << refres << "\n";
621          throw std::runtime_error( oss.str() );
622       }
623    }
624 
625    {
626       const auto res   ( evaluate( eval( lhs_ )    * eval( rhs_ )    ) );
627       const auto refres( evaluate( eval( reflhs_ ) * eval( refrhs_ ) ) );
628 
629       if( !isEqual( res, refres ) ) {
630          std::ostringstream oss;
631          oss << " Test: Evaluation with evaluated matrix/vector\n"
632              << " Error: Failed evaluation\n"
633              << " Details:\n"
634              << "   Random seed = " << blaze::getSeed() << "\n"
635              << "   Left-hand side " << ( IsRowMajorMatrix<MT>::value ? ( "row-major" ) : ( "column-major" ) ) << " sparse matrix type:\n"
636              << "     " << typeid( lhs_ ).name() << "\n"
637              << "   Right-hand side sparse vector type:\n"
638              << "     " << typeid( rhs_ ).name() << "\n"
639              << "   Deduced result type:\n"
640              << "     " << typeid( res ).name() << "\n"
641              << "   Deduced reference result type:\n"
642              << "     " << typeid( refres ).name() << "\n"
643              << "   Result:\n" << res << "\n"
644              << "   Expected result:\n" << refres << "\n";
645          throw std::runtime_error( oss.str() );
646       }
647    }
648 
649 
650    //=====================================================================================
651    // Testing the evaluation with the transpose types
652    //=====================================================================================
653 
654    {
655       const auto res   ( evaluate( olhs_   * rhs_    ) );
656       const auto refres( evaluate( reflhs_ * refrhs_ ) );
657 
658       if( !isEqual( res, refres ) ) {
659          std::ostringstream oss;
660          oss << " Test: Evaluation with the transpose matrix/vector\n"
661              << " Error: Failed evaluation\n"
662              << " Details:\n"
663              << "   Random seed = " << blaze::getSeed() << "\n"
664              << "   Left-hand side " << ( IsRowMajorMatrix<OMT>::value ? ( "row-major" ) : ( "column-major" ) ) << " sparse matrix type:\n"
665              << "     " << typeid( olhs_ ).name() << "\n"
666              << "   Right-hand side sparse vector type:\n"
667              << "     " << typeid( rhs_ ).name() << "\n"
668              << "   Deduced result type:\n"
669              << "     " << typeid( res ).name() << "\n"
670              << "   Deduced reference result type:\n"
671              << "     " << typeid( refres ).name() << "\n"
672              << "   Result:\n" << res << "\n"
673              << "   Expected result:\n" << refres << "\n";
674          throw std::runtime_error( oss.str() );
675       }
676    }
677 
678    {
679       const auto res   ( evaluate( eval( olhs_ )   * eval( rhs_ )    ) );
680       const auto refres( evaluate( eval( reflhs_ ) * eval( refrhs_ ) ) );
681 
682       if( !isEqual( res, refres ) ) {
683          std::ostringstream oss;
684          oss << " Test: Evaluation with evaluated transpose matrix/vector\n"
685              << " Error: Failed evaluation\n"
686              << " Details:\n"
687              << "   Random seed = " << blaze::getSeed() << "\n"
688              << "   Left-hand side " << ( IsRowMajorMatrix<OMT>::value ? ( "row-major" ) : ( "column-major" ) ) << " sparse matrix type:\n"
689              << "     " << typeid( olhs_ ).name() << "\n"
690              << "   Right-hand side sparse vector type:\n"
691              << "     " << typeid( rhs_ ).name() << "\n"
692              << "   Deduced result type:\n"
693              << "     " << typeid( res ).name() << "\n"
694              << "   Deduced reference result type:\n"
695              << "     " << typeid( refres ).name() << "\n"
696              << "   Result:\n" << res << "\n"
697              << "   Expected result:\n" << refres << "\n";
698          throw std::runtime_error( oss.str() );
699       }
700    }
701 }
702 //*************************************************************************************************
703 
704 
705 //*************************************************************************************************
706 /*!\brief Testing the vector element access.
707 //
708 // \return void
709 // \exception std::runtime_error Element access error detected.
710 //
711 // This function tests the element access via the subscript operator. In case any
712 // error is detected, a \a std::runtime_error exception is thrown.
713 */
714 template< typename MT    // Type of the left-hand side sparse matrix
715         , typename VT >  // Type of the right-hand side sparse vector
testElementAccess()716 void OperationTest<MT,VT>::testElementAccess()
717 {
718    using blaze::equal;
719 
720 
721    //=====================================================================================
722    // Testing the element access with the given types
723    //=====================================================================================
724 
725    if( lhs_.rows() > 0UL )
726    {
727       const size_t n( lhs_.rows() - 1UL );
728 
729       if( !equal( ( lhs_ * rhs_ )[n], ( reflhs_ * refrhs_ )[n] ) ||
730           !equal( ( lhs_ * rhs_ ).at(n), ( reflhs_ * refrhs_ ).at(n) ) ) {
731          std::ostringstream oss;
732          oss << " Test : Element access of multiplication expression\n"
733              << " Error: Unequal resulting elements at index " << n << " detected\n"
734              << " Details:\n"
735              << "   Random seed = " << blaze::getSeed() << "\n"
736              << "   Left-hand side row-major sparse matrix type:\n"
737              << "     " << typeid( MT ).name() << "\n"
738              << "   Right-hand side sparse vector type:\n"
739              << "     " << typeid( VT ).name() << "\n";
740          throw std::runtime_error( oss.str() );
741       }
742 
743       if( !equal( ( lhs_ * eval( rhs_ ) )[n], ( reflhs_ * eval( refrhs_ ) )[n] ) ||
744           !equal( ( lhs_ * eval( rhs_ ) ).at(n), ( reflhs_ * eval( refrhs_ ) ).at(n) ) ) {
745          std::ostringstream oss;
746          oss << " Test : Element access of right evaluated multiplication expression\n"
747              << " Error: Unequal resulting elements at index " << n << " detected\n"
748              << " Details:\n"
749              << "   Random seed = " << blaze::getSeed() << "\n"
750              << "   Left-hand side row-major sparse matrix type:\n"
751              << "     " << typeid( MT ).name() << "\n"
752              << "   Right-hand side sparse vector type:\n"
753              << "     " << typeid( VT ).name() << "\n";
754          throw std::runtime_error( oss.str() );
755       }
756 
757       if( !equal( ( eval( lhs_ ) * rhs_ )[n], ( eval( reflhs_ ) * refrhs_ )[n] ) ||
758           !equal( ( eval( lhs_ ) * rhs_ ).at(n), ( eval( reflhs_ ) * refrhs_ ).at(n) ) ) {
759          std::ostringstream oss;
760          oss << " Test : Element access of left evaluated multiplication expression\n"
761              << " Error: Unequal resulting elements at index " << n << " detected\n"
762              << " Details:\n"
763              << "   Random seed = " << blaze::getSeed() << "\n"
764              << "   Left-hand side row-major sparse matrix type:\n"
765              << "     " << typeid( MT ).name() << "\n"
766              << "   Right-hand side sparse vector type:\n"
767              << "     " << typeid( VT ).name() << "\n";
768          throw std::runtime_error( oss.str() );
769       }
770 
771       if( !equal( ( eval( lhs_ ) * eval( rhs_ ) )[n], ( eval( reflhs_ ) * eval( refrhs_ ) )[n] ) ||
772           !equal( ( eval( lhs_ ) * eval( rhs_ ) ).at(n), ( eval( reflhs_ ) * eval( refrhs_ ) ).at(n) ) ) {
773          std::ostringstream oss;
774          oss << " Test : Element access of fully evaluated multiplication expression\n"
775              << " Error: Unequal resulting elements at index " << n << " detected\n"
776              << " Details:\n"
777              << "   Random seed = " << blaze::getSeed() << "\n"
778              << "   Left-hand side row-major sparse matrix type:\n"
779              << "     " << typeid( MT ).name() << "\n"
780              << "   Right-hand side sparse vector type:\n"
781              << "     " << typeid( VT ).name() << "\n";
782          throw std::runtime_error( oss.str() );
783       }
784    }
785 
786    try {
787       ( lhs_ * rhs_ ).at( lhs_.rows() );
788 
789       std::ostringstream oss;
790       oss << " Test : Checked element access of multiplication expression\n"
791           << " Error: Out-of-bound access succeeded\n"
792           << " Details:\n"
793           << "   Random seed = " << blaze::getSeed() << "\n"
794           << "   Left-hand side row-major sparse matrix type:\n"
795           << "     " << typeid( MT ).name() << "\n"
796           << "   Right-hand side sparse vector type:\n"
797           << "     " << typeid( VT ).name() << "\n";
798       throw std::runtime_error( oss.str() );
799    }
800    catch( std::out_of_range& ) {}
801 
802 
803    //=====================================================================================
804    // Testing the element access with the transpose types
805    //=====================================================================================
806 
807    if( olhs_.rows() > 0UL )
808    {
809       const size_t n( olhs_.rows() - 1UL );
810 
811       if( !equal( ( olhs_ * rhs_ )[n], ( reflhs_ * refrhs_ )[n] ) ||
812           !equal( ( olhs_ * rhs_ ).at(n), ( reflhs_ * refrhs_ ).at(n) ) ) {
813          std::ostringstream oss;
814          oss << " Test : Element access of transpose multiplication expression\n"
815              << " Error: Unequal resulting elements at index " << n << " detected\n"
816              << " Details:\n"
817              << "   Random seed = " << blaze::getSeed() << "\n"
818              << "   Left-hand side column-major sparse matrix type:\n"
819              << "     " << typeid( TMT ).name() << "\n"
820              << "   Right-hand side sparse vector type:\n"
821              << "     " << typeid( VT ).name() << "\n";
822          throw std::runtime_error( oss.str() );
823       }
824 
825       if( !equal( ( olhs_ * eval( rhs_ ) )[n], ( reflhs_ * eval( refrhs_ ) )[n] ) ||
826           !equal( ( olhs_ * eval( rhs_ ) ).at(n), ( reflhs_ * eval( refrhs_ ) ).at(n) ) ) {
827          std::ostringstream oss;
828          oss << " Test : Element access of right evaluated transpose multiplication expression\n"
829              << " Error: Unequal resulting elements at index " << n << " detected\n"
830              << " Details:\n"
831              << "   Random seed = " << blaze::getSeed() << "\n"
832              << "   Left-hand side column-major sparse matrix type:\n"
833              << "     " << typeid( TMT ).name() << "\n"
834              << "   Right-hand side sparse vector type:\n"
835              << "     " << typeid( VT ).name() << "\n";
836          throw std::runtime_error( oss.str() );
837       }
838 
839       if( !equal( ( eval( olhs_ ) * rhs_ )[n], ( eval( reflhs_ ) * refrhs_ )[n] ) ||
840           !equal( ( eval( olhs_ ) * rhs_ ).at(n), ( eval( reflhs_ ) * refrhs_ ).at(n) ) ) {
841          std::ostringstream oss;
842          oss << " Test : Element access of left evaluated transpose multiplication expression\n"
843              << " Error: Unequal resulting elements at index " << n << " detected\n"
844              << " Details:\n"
845              << "   Random seed = " << blaze::getSeed() << "\n"
846              << "   Left-hand side column-major sparse matrix type:\n"
847              << "     " << typeid( TMT ).name() << "\n"
848              << "   Right-hand side sparse vector type:\n"
849              << "     " << typeid( VT ).name() << "\n";
850          throw std::runtime_error( oss.str() );
851       }
852 
853       if( !equal( ( eval( olhs_ ) * eval( rhs_ ) )[n], ( eval( reflhs_ ) * eval( refrhs_ ) )[n] ) ||
854           !equal( ( eval( olhs_ ) * eval( rhs_ ) ).at(n), ( eval( reflhs_ ) * eval( refrhs_ ) ).at(n) ) ) {
855          std::ostringstream oss;
856          oss << " Test : Element access of fully evaluated transpose multiplication expression\n"
857              << " Error: Unequal resulting elements at index " << n << " detected\n"
858              << " Details:\n"
859              << "   Random seed = " << blaze::getSeed() << "\n"
860              << "   Left-hand side column-major sparse matrix type:\n"
861              << "     " << typeid( TMT ).name() << "\n"
862              << "   Right-hand side sparse vector type:\n"
863              << "     " << typeid( VT ).name() << "\n";
864          throw std::runtime_error( oss.str() );
865       }
866    }
867 
868    try {
869       ( olhs_ * rhs_ ).at( olhs_.rows() );
870 
871       std::ostringstream oss;
872       oss << " Test : Checked element access of transpose multiplication expression\n"
873           << " Error: Out-of-bound access succeeded\n"
874           << " Details:\n"
875           << "   Random seed = " << blaze::getSeed() << "\n"
876           << "   Left-hand side column-major sparse matrix type:\n"
877           << "     " << typeid( TMT ).name() << "\n"
878           << "   Right-hand side sparse vector type:\n"
879           << "     " << typeid( VT ).name() << "\n";
880       throw std::runtime_error( oss.str() );
881    }
882    catch( std::out_of_range& ) {}
883 }
884 //*************************************************************************************************
885 
886 
887 //*************************************************************************************************
888 /*!\brief Testing the plain sparse matrix/sparse vector multiplication.
889 //
890 // \return void
891 // \exception std::runtime_error Multiplication error detected.
892 //
893 // This function tests the plain matrix/vector multiplication with plain assignment,
894 // addition assignment, subtraction assignment, and multiplication assignment. In case
895 // any error resulting from the multiplication or the subsequent assignment is detected,
896 // a \a std::runtime_error exception is thrown.
897 */
898 template< typename MT    // Type of the left-hand side sparse matrix
899         , typename VT >  // Type of the right-hand side sparse vector
testBasicOperation()900 void OperationTest<MT,VT>::testBasicOperation()
901 {
902 #if BLAZETEST_MATHTEST_TEST_BASIC_OPERATION
903    if( BLAZETEST_MATHTEST_TEST_BASIC_OPERATION > 1 )
904    {
905       //=====================================================================================
906       // Multiplication
907       //=====================================================================================
908 
909       // Multiplication with the given matrix/vector
910       {
911          test_  = "Multiplication with the given matrix/vector";
912          error_ = "Failed multiplication operation";
913 
914          try {
915             initResults();
916             dres_   = lhs_ * rhs_;
917             sres_   = lhs_ * rhs_;
918             refres_ = reflhs_ * refrhs_;
919          }
920          catch( std::exception& ex ) {
921             convertException<MT>( ex );
922          }
923 
924          checkResults<MT>();
925 
926          try {
927             initResults();
928             dres_   = olhs_ * rhs_;
929             sres_   = olhs_ * rhs_;
930             refres_ = reflhs_ * refrhs_;
931          }
932          catch( std::exception& ex ) {
933             convertException<TMT>( ex );
934          }
935 
936          checkResults<TMT>();
937       }
938 
939       // Multiplication with evaluated matrix/vector
940       {
941          test_  = "Multiplication with evaluated matrix/vector";
942          error_ = "Failed multiplication operation";
943 
944          try {
945             initResults();
946             dres_   = eval( lhs_ ) * eval( rhs_ );
947             sres_   = eval( lhs_ ) * eval( rhs_ );
948             refres_ = eval( reflhs_ ) * eval( refrhs_ );
949          }
950          catch( std::exception& ex ) {
951             convertException<MT>( ex );
952          }
953 
954          checkResults<MT>();
955 
956          try {
957             initResults();
958             dres_   = eval( olhs_ ) * eval( rhs_ );
959             sres_   = eval( olhs_ ) * eval( rhs_ );
960             refres_ = eval( reflhs_ ) * eval( refrhs_ );
961          }
962          catch( std::exception& ex ) {
963             convertException<TMT>( ex );
964          }
965 
966          checkResults<TMT>();
967       }
968 
969 
970       //=====================================================================================
971       // Multiplication with addition assignment
972       //=====================================================================================
973 
974       // Multiplication with addition assignment with the given matrix/vector
975       {
976          test_  = "Multiplication with addition assignment with the given matrix/vector";
977          error_ = "Failed addition assignment operation";
978 
979          try {
980             initResults();
981             dres_   += lhs_ * rhs_;
982             sres_   += lhs_ * rhs_;
983             refres_ += reflhs_ * refrhs_;
984          }
985          catch( std::exception& ex ) {
986             convertException<MT>( ex );
987          }
988 
989          checkResults<MT>();
990 
991          try {
992             initResults();
993             dres_   += olhs_ * rhs_;
994             sres_   += olhs_ * rhs_;
995             refres_ += reflhs_ * refrhs_;
996          }
997          catch( std::exception& ex ) {
998             convertException<TMT>( ex );
999          }
1000 
1001          checkResults<TMT>();
1002       }
1003 
1004       // Multiplication with addition assignment with evaluated matrix/vector
1005       {
1006          test_  = "Multiplication with addition assignment with evaluated matrix/vector";
1007          error_ = "Failed addition assignment operation";
1008 
1009          try {
1010             initResults();
1011             dres_   += eval( lhs_ ) * eval( rhs_ );
1012             sres_   += eval( lhs_ ) * eval( rhs_ );
1013             refres_ += eval( reflhs_ ) * eval( refrhs_ );
1014          }
1015          catch( std::exception& ex ) {
1016             convertException<MT>( ex );
1017          }
1018 
1019          checkResults<MT>();
1020 
1021          try {
1022             initResults();
1023             dres_   += eval( olhs_ ) * eval( rhs_ );
1024             sres_   += eval( olhs_ ) * eval( rhs_ );
1025             refres_ += eval( reflhs_ ) * eval( refrhs_ );
1026          }
1027          catch( std::exception& ex ) {
1028             convertException<TMT>( ex );
1029          }
1030 
1031          checkResults<TMT>();
1032       }
1033 
1034 
1035       //=====================================================================================
1036       // Multiplication with subtraction assignment
1037       //=====================================================================================
1038 
1039       // Multiplication with subtraction assignment with the given matrix/vector
1040       {
1041          test_  = "Multiplication with subtraction assignment with the given matrix/vector";
1042          error_ = "Failed subtraction assignment operation";
1043 
1044          try {
1045             initResults();
1046             dres_   -= lhs_ * rhs_;
1047             sres_   -= lhs_ * rhs_;
1048             refres_ -= reflhs_ * refrhs_;
1049          }
1050          catch( std::exception& ex ) {
1051             convertException<MT>( ex );
1052          }
1053 
1054          checkResults<MT>();
1055 
1056          try {
1057             initResults();
1058             dres_   -= olhs_ * rhs_;
1059             sres_   -= olhs_ * rhs_;
1060             refres_ -= reflhs_ * refrhs_;
1061          }
1062          catch( std::exception& ex ) {
1063             convertException<TMT>( ex );
1064          }
1065 
1066          checkResults<TMT>();
1067       }
1068 
1069       // Multiplication with subtraction assignment with evaluated matrix/vector
1070       {
1071          test_  = "Multiplication with subtraction assignment with evaluated matrix/vector";
1072          error_ = "Failed subtraction assignment operation";
1073 
1074          try {
1075             initResults();
1076             dres_   -= eval( lhs_ ) * eval( rhs_ );
1077             sres_   -= eval( lhs_ ) * eval( rhs_ );
1078             refres_ -= eval( reflhs_ ) * eval( refrhs_ );
1079          }
1080          catch( std::exception& ex ) {
1081             convertException<MT>( ex );
1082          }
1083 
1084          checkResults<MT>();
1085 
1086          try {
1087             initResults();
1088             dres_   -= eval( olhs_ ) * eval( rhs_ );
1089             sres_   -= eval( olhs_ ) * eval( rhs_ );
1090             refres_ -= eval( reflhs_ ) * eval( refrhs_ );
1091          }
1092          catch( std::exception& ex ) {
1093             convertException<TMT>( ex );
1094          }
1095 
1096          checkResults<TMT>();
1097       }
1098 
1099 
1100       //=====================================================================================
1101       // Multiplication with multiplication assignment
1102       //=====================================================================================
1103 
1104       // Multiplication with multiplication assignment with the given matrix/vector
1105       {
1106          test_  = "Multiplication with multiplication assignment with the given matrix/vector";
1107          error_ = "Failed multiplication assignment operation";
1108 
1109          try {
1110             initResults();
1111             dres_   *= lhs_ * rhs_;
1112             sres_   *= lhs_ * rhs_;
1113             refres_ *= reflhs_ * refrhs_;
1114          }
1115          catch( std::exception& ex ) {
1116             convertException<MT>( ex );
1117          }
1118 
1119          checkResults<MT>();
1120 
1121          try {
1122             initResults();
1123             dres_   *= olhs_ * rhs_;
1124             sres_   *= olhs_ * rhs_;
1125             refres_ *= reflhs_ * refrhs_;
1126          }
1127          catch( std::exception& ex ) {
1128             convertException<TMT>( ex );
1129          }
1130 
1131          checkResults<TMT>();
1132       }
1133 
1134       // Multiplication with multiplication assignment with evaluated matrix/vector
1135       {
1136          test_  = "Multiplication with multiplication assignment with evaluated matrix/vector";
1137          error_ = "Failed multiplication assignment operation";
1138 
1139          try {
1140             initResults();
1141             dres_   *= eval( lhs_ ) * eval( rhs_ );
1142             sres_   *= eval( lhs_ ) * eval( rhs_ );
1143             refres_ *= eval( reflhs_ ) * eval( refrhs_ );
1144          }
1145          catch( std::exception& ex ) {
1146             convertException<MT>( ex );
1147          }
1148 
1149          checkResults<MT>();
1150 
1151          try {
1152             initResults();
1153             dres_   *= eval( olhs_ ) * eval( rhs_ );
1154             sres_   *= eval( olhs_ ) * eval( rhs_ );
1155             refres_ *= eval( reflhs_ ) * eval( refrhs_ );
1156          }
1157          catch( std::exception& ex ) {
1158             convertException<TMT>( ex );
1159          }
1160 
1161          checkResults<TMT>();
1162       }
1163    }
1164 #endif
1165 }
1166 //*************************************************************************************************
1167 
1168 
1169 //*************************************************************************************************
1170 /*!\brief Testing the negated sparse matrix/sparse vector multiplication.
1171 //
1172 // \return void
1173 // \exception std::runtime_error Multiplication error detected.
1174 //
1175 // This function tests the negated matrix/vector multiplication with plain assignment, addition
1176 // assignment, subtraction assignment, and multiplication assignment. In case any error resulting
1177 // from the multiplication or the subsequent assignment is detected, a \a std::runtime_error
1178 // exception is thrown.
1179 */
1180 template< typename MT    // Type of the left-hand side sparse matrix
1181         , typename VT >  // Type of the right-hand side sparse vector
testNegatedOperation()1182 void OperationTest<MT,VT>::testNegatedOperation()
1183 {
1184 #if BLAZETEST_MATHTEST_TEST_NEGATED_OPERATION
1185    if( BLAZETEST_MATHTEST_TEST_NEGATED_OPERATION > 1 )
1186    {
1187       //=====================================================================================
1188       // Negated multiplication
1189       //=====================================================================================
1190 
1191       // Negated multiplication with the given matrix/vector
1192       {
1193          test_  = "Negated multiplication with the given matrix/vector";
1194          error_ = "Failed multiplication operation";
1195 
1196          try {
1197             initResults();
1198             dres_   = -( lhs_ * rhs_ );
1199             sres_   = -( lhs_ * rhs_ );
1200             refres_ = -( reflhs_ * refrhs_ );
1201          }
1202          catch( std::exception& ex ) {
1203             convertException<MT>( ex );
1204          }
1205 
1206          checkResults<MT>();
1207 
1208          try {
1209             initResults();
1210             dres_   = -( olhs_ * rhs_ );
1211             sres_   = -( olhs_ * rhs_ );
1212             refres_ = -( reflhs_ * refrhs_ );
1213          }
1214          catch( std::exception& ex ) {
1215             convertException<TMT>( ex );
1216          }
1217 
1218          checkResults<TMT>();
1219       }
1220 
1221       // Negated multiplication with evaluated matrix/vector
1222       {
1223          test_  = "Negated multiplication with evaluated matrix/vector";
1224          error_ = "Failed multiplication operation";
1225 
1226          try {
1227             initResults();
1228             dres_   = -( eval( lhs_ ) * eval( rhs_ ) );
1229             sres_   = -( eval( lhs_ ) * eval( rhs_ ) );
1230             refres_ = -( eval( reflhs_ ) * eval( refrhs_ ) );
1231          }
1232          catch( std::exception& ex ) {
1233             convertException<MT>( ex );
1234          }
1235 
1236          checkResults<MT>();
1237 
1238          try {
1239             initResults();
1240             dres_   = -( eval( olhs_ ) * eval( rhs_ ) );
1241             sres_   = -( eval( olhs_ ) * eval( rhs_ ) );
1242             refres_ = -( eval( reflhs_ ) * eval( refrhs_ ) );
1243          }
1244          catch( std::exception& ex ) {
1245             convertException<TMT>( ex );
1246          }
1247 
1248          checkResults<TMT>();
1249       }
1250 
1251 
1252       //=====================================================================================
1253       // Negated multiplication with addition assignment
1254       //=====================================================================================
1255 
1256       // Negated multiplication with addition assignment with the given matrix/vector
1257       {
1258          test_  = "Negated multiplication with addition assignment with the given matrix/vector";
1259          error_ = "Failed addition assignment operation";
1260 
1261          try {
1262             initResults();
1263             dres_   += -( lhs_ * rhs_ );
1264             sres_   += -( lhs_ * rhs_ );
1265             refres_ += -( reflhs_ * refrhs_ );
1266          }
1267          catch( std::exception& ex ) {
1268             convertException<MT>( ex );
1269          }
1270 
1271          checkResults<MT>();
1272 
1273          try {
1274             initResults();
1275             dres_   += -( olhs_ * rhs_ );
1276             sres_   += -( olhs_ * rhs_ );
1277             refres_ += -( reflhs_ * refrhs_ );
1278          }
1279          catch( std::exception& ex ) {
1280             convertException<TMT>( ex );
1281          }
1282 
1283          checkResults<TMT>();
1284       }
1285 
1286       // Negated multiplication with addition assignment with evaluated matrix/vector
1287       {
1288          test_  = "Negated multiplication with addition assignment with evaluated matrix/vector";
1289          error_ = "Failed addition assignment operation";
1290 
1291          try {
1292             initResults();
1293             dres_   += -( eval( lhs_ ) * eval( rhs_ ) );
1294             sres_   += -( eval( lhs_ ) * eval( rhs_ ) );
1295             refres_ += -( eval( reflhs_ ) * eval( refrhs_ ) );
1296          }
1297          catch( std::exception& ex ) {
1298             convertException<MT>( ex );
1299          }
1300 
1301          checkResults<MT>();
1302 
1303          try {
1304             initResults();
1305             dres_   += -( eval( olhs_ ) * eval( rhs_ ) );
1306             sres_   += -( eval( olhs_ ) * eval( rhs_ ) );
1307             refres_ += -( eval( reflhs_ ) * eval( refrhs_ ) );
1308          }
1309          catch( std::exception& ex ) {
1310             convertException<TMT>( ex );
1311          }
1312 
1313          checkResults<TMT>();
1314       }
1315 
1316 
1317       //=====================================================================================
1318       // Negated multiplication with subtraction assignment
1319       //=====================================================================================
1320 
1321       // Negated multiplication with subtraction assignment with the given matrix/vector
1322       {
1323          test_  = "Negated multiplication with subtraction assignment with the given matrix/vector";
1324          error_ = "Failed subtraction assignment operation";
1325 
1326          try {
1327             initResults();
1328             dres_   -= -( lhs_ * rhs_ );
1329             sres_   -= -( lhs_ * rhs_ );
1330             refres_ -= -( reflhs_ * refrhs_ );
1331          }
1332          catch( std::exception& ex ) {
1333             convertException<MT>( ex );
1334          }
1335 
1336          checkResults<MT>();
1337 
1338          try {
1339             initResults();
1340             dres_   -= -( olhs_ * rhs_ );
1341             sres_   -= -( olhs_ * rhs_ );
1342             refres_ -= -( reflhs_ * refrhs_ );
1343          }
1344          catch( std::exception& ex ) {
1345             convertException<TMT>( ex );
1346          }
1347 
1348          checkResults<TMT>();
1349       }
1350 
1351       // Negated multiplication with subtraction assignment with evaluated matrix/vector
1352       {
1353          test_  = "Negated multiplication with subtraction assignment with evaluated matrix/vector";
1354          error_ = "Failed subtraction assignment operation";
1355 
1356          try {
1357             initResults();
1358             dres_   -= -( eval( lhs_ ) * eval( rhs_ ) );
1359             sres_   -= -( eval( lhs_ ) * eval( rhs_ ) );
1360             refres_ -= -( eval( reflhs_ ) * eval( refrhs_ ) );
1361          }
1362          catch( std::exception& ex ) {
1363             convertException<MT>( ex );
1364          }
1365 
1366          checkResults<MT>();
1367 
1368          try {
1369             initResults();
1370             dres_   -= -( eval( olhs_ ) * eval( rhs_ ) );
1371             sres_   -= -( eval( olhs_ ) * eval( rhs_ ) );
1372             refres_ -= -( eval( reflhs_ ) * eval( refrhs_ ) );
1373          }
1374          catch( std::exception& ex ) {
1375             convertException<TMT>( ex );
1376          }
1377 
1378          checkResults<TMT>();
1379       }
1380 
1381 
1382       //=====================================================================================
1383       // Negated multiplication with multiplication assignment
1384       //=====================================================================================
1385 
1386       // Negated multiplication with multiplication assignment with the given matrix/vector
1387       {
1388          test_  = "Negated multiplication with multiplication assignment with the given matrix/vector";
1389          error_ = "Failed multiplication assignment operation";
1390 
1391          try {
1392             initResults();
1393             dres_   *= -( lhs_ * rhs_ );
1394             sres_   *= -( lhs_ * rhs_ );
1395             refres_ *= -( reflhs_ * refrhs_ );
1396          }
1397          catch( std::exception& ex ) {
1398             convertException<MT>( ex );
1399          }
1400 
1401          checkResults<MT>();
1402 
1403          try {
1404             initResults();
1405             dres_   *= -( olhs_ * rhs_ );
1406             sres_   *= -( olhs_ * rhs_ );
1407             refres_ *= -( reflhs_ * refrhs_ );
1408          }
1409          catch( std::exception& ex ) {
1410             convertException<TMT>( ex );
1411          }
1412 
1413          checkResults<TMT>();
1414       }
1415 
1416       // Negated multiplication with multiplication assignment with evaluated matrix/vector
1417       {
1418          test_  = "Negated multiplication with multiplication assignment with evaluated matrix/vector";
1419          error_ = "Failed multiplication assignment operation";
1420 
1421          try {
1422             initResults();
1423             dres_   *= -( eval( lhs_ ) * eval( rhs_ ) );
1424             sres_   *= -( eval( lhs_ ) * eval( rhs_ ) );
1425             refres_ *= -( eval( reflhs_ ) * eval( refrhs_ ) );
1426          }
1427          catch( std::exception& ex ) {
1428             convertException<MT>( ex );
1429          }
1430 
1431          checkResults<MT>();
1432 
1433          try {
1434             initResults();
1435             dres_   *= -( eval( olhs_ ) * eval( rhs_ ) );
1436             sres_   *= -( eval( olhs_ ) * eval( rhs_ ) );
1437             refres_ *= -( eval( reflhs_ ) * eval( refrhs_ ) );
1438          }
1439          catch( std::exception& ex ) {
1440             convertException<TMT>( ex );
1441          }
1442 
1443          checkResults<TMT>();
1444       }
1445    }
1446 #endif
1447 }
1448 //*************************************************************************************************
1449 
1450 
1451 //*************************************************************************************************
1452 /*!\brief Testing the scaled sparse matrix/sparse vector multiplication.
1453 //
1454 // \param scalar The scalar value.
1455 // \return void
1456 // \exception std::runtime_error Multiplication error detected.
1457 //
1458 // This function tests the scaled matrix/vector multiplication with plain assignment, addition
1459 // assignment, subtraction assignment, and multiplication assignment. In case any error resulting
1460 // from the multiplication or the subsequent assignment is detected, a \a std::runtime_error
1461 // exception is thrown.
1462 */
1463 template< typename MT    // Type of the left-hand side sparse matrix
1464         , typename VT >  // Type of the right-hand side sparse vector
1465 template< typename T >   // Type of the scalar
testScaledOperation(T scalar)1466 void OperationTest<MT,VT>::testScaledOperation( T scalar )
1467 {
1468    BLAZE_CONSTRAINT_MUST_BE_SCALAR_TYPE( T );
1469 
1470    if( scalar == T(0) )
1471       throw std::invalid_argument( "Invalid scalar parameter" );
1472 
1473 
1474 #if BLAZETEST_MATHTEST_TEST_SCALED_OPERATION
1475    if( BLAZETEST_MATHTEST_TEST_SCALED_OPERATION > 1 )
1476    {
1477       //=====================================================================================
1478       // Self-scaling (v*=s)
1479       //=====================================================================================
1480 
1481       // Self-scaling (v*=s)
1482       {
1483          test_ = "Self-scaling (v*=s)";
1484 
1485          try {
1486             dres_   = lhs_ * rhs_;
1487             sres_   = dres_;
1488             refres_ = dres_;
1489 
1490             dres_   *= scalar;
1491             sres_   *= scalar;
1492             refres_ *= scalar;
1493          }
1494          catch( std::exception& ex ) {
1495             std::ostringstream oss;
1496             oss << " Test : " << test_ << "\n"
1497                 << " Error: Failed self-scaling operation\n"
1498                 << " Details:\n"
1499                 << "   Random seed = " << blaze::getSeed() << "\n"
1500                 << "   Scalar = " << scalar << "\n"
1501                 << "   Error message: " << ex.what() << "\n";
1502             throw std::runtime_error( oss.str() );
1503          }
1504 
1505          checkResults<MT>();
1506       }
1507 
1508 
1509       //=====================================================================================
1510       // Self-scaling (v=v*s)
1511       //=====================================================================================
1512 
1513       // Self-scaling (v=v*s)
1514       {
1515          test_ = "Self-scaling (v=v*s)";
1516 
1517          try {
1518             dres_   = lhs_ * rhs_;
1519             sres_   = dres_;
1520             refres_ = dres_;
1521 
1522             dres_   = dres_   * scalar;
1523             sres_   = sres_   * scalar;
1524             refres_ = refres_ * scalar;
1525          }
1526          catch( std::exception& ex ) {
1527             std::ostringstream oss;
1528             oss << " Test : " << test_ << "\n"
1529                 << " Error: Failed self-scaling operation\n"
1530                 << " Details:\n"
1531                 << "   Random seed = " << blaze::getSeed() << "\n"
1532                 << "   Scalar = " << scalar << "\n"
1533                 << "   Error message: " << ex.what() << "\n";
1534             throw std::runtime_error( oss.str() );
1535          }
1536 
1537          checkResults<MT>();
1538       }
1539 
1540 
1541       //=====================================================================================
1542       // Self-scaling (v=s*v)
1543       //=====================================================================================
1544 
1545       // Self-scaling (v=s*v)
1546       {
1547          test_ = "Self-scaling (v=s*v)";
1548 
1549          try {
1550             dres_   = lhs_ * rhs_;
1551             sres_   = dres_;
1552             refres_ = dres_;
1553 
1554             dres_   = scalar * dres_;
1555             sres_   = scalar * sres_;
1556             refres_ = scalar * refres_;
1557          }
1558          catch( std::exception& ex ) {
1559             std::ostringstream oss;
1560             oss << " Test : " << test_ << "\n"
1561                 << " Error: Failed self-scaling operation\n"
1562                 << " Details:\n"
1563                 << "   Random seed = " << blaze::getSeed() << "\n"
1564                 << "   Scalar = " << scalar << "\n"
1565                 << "   Error message: " << ex.what() << "\n";
1566             throw std::runtime_error( oss.str() );
1567          }
1568 
1569          checkResults<MT>();
1570       }
1571 
1572 
1573       //=====================================================================================
1574       // Self-scaling (v/=s)
1575       //=====================================================================================
1576 
1577       // Self-scaling (v/=s)
1578       {
1579          test_ = "Self-scaling (v/=s)";
1580 
1581          try {
1582             dres_   = lhs_ * rhs_;
1583             sres_   = dres_;
1584             refres_ = dres_;
1585 
1586             dres_   /= scalar;
1587             sres_   /= scalar;
1588             refres_ /= scalar;
1589          }
1590          catch( std::exception& ex ) {
1591             std::ostringstream oss;
1592             oss << " Test : " << test_ << "\n"
1593                 << " Error: Failed self-scaling operation\n"
1594                 << " Details:\n"
1595                 << "   Random seed = " << blaze::getSeed() << "\n"
1596                 << "   Scalar = " << scalar << "\n"
1597                 << "   Error message: " << ex.what() << "\n";
1598             throw std::runtime_error( oss.str() );
1599          }
1600 
1601          checkResults<MT>();
1602       }
1603 
1604 
1605       //=====================================================================================
1606       // Self-scaling (v=v/s)
1607       //=====================================================================================
1608 
1609       // Self-scaling (v=v/s)
1610       {
1611          test_ = "Self-scaling (v=v/s)";
1612 
1613          try {
1614             dres_   = lhs_ * rhs_;
1615             sres_   = dres_;
1616             refres_ = dres_;
1617 
1618             dres_   = dres_   / scalar;
1619             sres_   = sres_   / scalar;
1620             refres_ = refres_ / scalar;
1621          }
1622          catch( std::exception& ex ) {
1623             std::ostringstream oss;
1624             oss << " Test : " << test_ << "\n"
1625                 << " Error: Failed self-scaling operation\n"
1626                 << " Details:\n"
1627                 << "   Random seed = " << blaze::getSeed() << "\n"
1628                 << "   Scalar = " << scalar << "\n"
1629                 << "   Error message: " << ex.what() << "\n";
1630             throw std::runtime_error( oss.str() );
1631          }
1632 
1633          checkResults<MT>();
1634       }
1635 
1636 
1637       //=====================================================================================
1638       // Scaled multiplication (s*OP)
1639       //=====================================================================================
1640 
1641       // Scaled multiplication with the given matrix/vector
1642       {
1643          test_  = "Scaled multiplication with the given matrix/vector (s*OP)";
1644          error_ = "Failed multiplication operation";
1645 
1646          try {
1647             initResults();
1648             dres_   = scalar * ( lhs_ * rhs_ );
1649             sres_   = scalar * ( lhs_ * rhs_ );
1650             refres_ = scalar * ( reflhs_ * refrhs_ );
1651          }
1652          catch( std::exception& ex ) {
1653             convertException<MT>( ex );
1654          }
1655 
1656          checkResults<MT>();
1657 
1658          try {
1659             initResults();
1660             dres_   = scalar * ( olhs_ * rhs_ );
1661             sres_   = scalar * ( olhs_ * rhs_ );
1662             refres_ = scalar * ( reflhs_ * refrhs_ );
1663          }
1664          catch( std::exception& ex ) {
1665             convertException<TMT>( ex );
1666          }
1667 
1668          checkResults<TMT>();
1669       }
1670 
1671       // Scaled multiplication with evaluated matrix/vector
1672       {
1673          test_  = "Scaled multiplication with evaluated matrix/vector (s*OP)";
1674          error_ = "Failed multiplication operation";
1675 
1676          try {
1677             initResults();
1678             dres_   = scalar * ( eval( lhs_ ) * eval( rhs_ ) );
1679             sres_   = scalar * ( eval( lhs_ ) * eval( rhs_ ) );
1680             refres_ = scalar * ( eval( reflhs_ ) * eval( refrhs_ ) );
1681          }
1682          catch( std::exception& ex ) {
1683             convertException<MT>( ex );
1684          }
1685 
1686          checkResults<MT>();
1687 
1688          try {
1689             initResults();
1690             dres_   = scalar * ( eval( olhs_ ) * eval( rhs_ ) );
1691             sres_   = scalar * ( eval( olhs_ ) * eval( rhs_ ) );
1692             refres_ = scalar * ( eval( reflhs_ ) * eval( refrhs_ ) );
1693          }
1694          catch( std::exception& ex ) {
1695             convertException<TMT>( ex );
1696          }
1697 
1698          checkResults<TMT>();
1699       }
1700 
1701 
1702       //=====================================================================================
1703       // Scaled multiplication (OP*s)
1704       //=====================================================================================
1705 
1706       // Scaled multiplication with the given matrix/vector
1707       {
1708          test_  = "Scaled multiplication with the given matrix/vector (OP*s)";
1709          error_ = "Failed multiplication operation";
1710 
1711          try {
1712             initResults();
1713             dres_   = ( lhs_ * rhs_ ) * scalar;
1714             sres_   = ( lhs_ * rhs_ ) * scalar;
1715             refres_ = ( reflhs_ * refrhs_ ) * scalar;
1716          }
1717          catch( std::exception& ex ) {
1718             convertException<MT>( ex );
1719          }
1720 
1721          checkResults<MT>();
1722 
1723          try {
1724             initResults();
1725             dres_   = ( olhs_ * rhs_ ) * scalar;
1726             sres_   = ( olhs_ * rhs_ ) * scalar;
1727             refres_ = ( reflhs_ * refrhs_ ) * scalar;
1728          }
1729          catch( std::exception& ex ) {
1730             convertException<TMT>( ex );
1731          }
1732 
1733          checkResults<TMT>();
1734       }
1735 
1736       // Scaled multiplication with evaluated matrix/vector
1737       {
1738          test_  = "Scaled multiplication with evaluated matrix/vector (OP*s)";
1739          error_ = "Failed multiplication operation";
1740 
1741          try {
1742             initResults();
1743             dres_   = ( eval( lhs_ ) * eval( rhs_ ) ) * scalar;
1744             sres_   = ( eval( lhs_ ) * eval( rhs_ ) ) * scalar;
1745             refres_ = ( eval( reflhs_ ) * eval( refrhs_ ) ) * scalar;
1746          }
1747          catch( std::exception& ex ) {
1748             convertException<MT>( ex );
1749          }
1750 
1751          checkResults<MT>();
1752 
1753          try {
1754             initResults();
1755             dres_ = ( eval( olhs_ ) * eval( rhs_ ) ) * scalar;
1756             sres_ = ( eval( olhs_ ) * eval( rhs_ ) ) * scalar;
1757             refres_ = ( eval( reflhs_ ) * eval( refrhs_ ) ) * scalar;
1758          }
1759          catch( std::exception& ex ) {
1760             convertException<TMT>( ex );
1761          }
1762 
1763          checkResults<TMT>();
1764       }
1765 
1766 
1767       //=====================================================================================
1768       // Scaled multiplication (OP/s)
1769       //=====================================================================================
1770 
1771       // Scaled multiplication with the given matrix/vector
1772       {
1773          test_  = "Scaled multiplication with the given matrix/vector (OP/s)";
1774          error_ = "Failed multiplication operation";
1775 
1776          try {
1777             initResults();
1778             dres_   = ( lhs_ * rhs_ ) / scalar;
1779             sres_   = ( lhs_ * rhs_ ) / scalar;
1780             refres_ = ( reflhs_ * refrhs_ ) / scalar;
1781          }
1782          catch( std::exception& ex ) {
1783             convertException<MT>( ex );
1784          }
1785 
1786          checkResults<MT>();
1787 
1788          try {
1789             initResults();
1790             dres_   = ( olhs_ * rhs_ ) / scalar;
1791             sres_   = ( olhs_ * rhs_ ) / scalar;
1792             refres_ = ( reflhs_ * refrhs_ ) / scalar;
1793          }
1794          catch( std::exception& ex ) {
1795             convertException<TMT>( ex );
1796          }
1797 
1798          checkResults<TMT>();
1799       }
1800 
1801       // Scaled multiplication with evaluated matrix/vector
1802       {
1803          test_  = "Scaled multiplication with evaluated matrix/vector (OP/s)";
1804          error_ = "Failed multiplication operation";
1805 
1806          try {
1807             initResults();
1808             dres_   = ( eval( lhs_ ) * eval( rhs_ ) ) / scalar;
1809             sres_   = ( eval( lhs_ ) * eval( rhs_ ) ) / scalar;
1810             refres_ = ( eval( reflhs_ ) * eval( refrhs_ ) ) / scalar;
1811          }
1812          catch( std::exception& ex ) {
1813             convertException<MT>( ex );
1814          }
1815 
1816          checkResults<MT>();
1817 
1818          try {
1819             initResults();
1820             dres_ = ( eval( olhs_ ) * eval( rhs_ ) ) / scalar;
1821             sres_ = ( eval( olhs_ ) * eval( rhs_ ) ) / scalar;
1822             refres_ = ( eval( reflhs_ ) * eval( refrhs_ ) ) / scalar;
1823          }
1824          catch( std::exception& ex ) {
1825             convertException<TMT>( ex );
1826          }
1827 
1828          checkResults<TMT>();
1829       }
1830 
1831 
1832       //=====================================================================================
1833       // Scaled multiplication with addition assignment (s*OP)
1834       //=====================================================================================
1835 
1836       // Scaled multiplication with addition assignment with the given matrix/vector
1837       {
1838          test_  = "Scaled multiplication with addition assignment with the given matrix/vector (s*OP)";
1839          error_ = "Failed addition assignment operation";
1840 
1841          try {
1842             initResults();
1843             dres_   += scalar * ( lhs_ * rhs_ );
1844             sres_   += scalar * ( lhs_ * rhs_ );
1845             refres_ += scalar * ( reflhs_ * refrhs_ );
1846          }
1847          catch( std::exception& ex ) {
1848             convertException<MT>( ex );
1849          }
1850 
1851          checkResults<MT>();
1852 
1853          try {
1854             initResults();
1855             dres_   += scalar * ( olhs_ * rhs_ );
1856             sres_   += scalar * ( olhs_ * rhs_ );
1857             refres_ += scalar * ( reflhs_ * refrhs_ );
1858          }
1859          catch( std::exception& ex ) {
1860             convertException<TMT>( ex );
1861          }
1862 
1863          checkResults<TMT>();
1864       }
1865 
1866       // Scaled multiplication with addition assignment with evaluated matrix/vector
1867       {
1868          test_  = "Scaled multiplication with addition assignment with evaluated matrix/vector (s*OP)";
1869          error_ = "Failed addition assignment operation";
1870 
1871          try {
1872             initResults();
1873             dres_   += scalar * ( eval( lhs_ ) * eval( rhs_ ) );
1874             sres_   += scalar * ( eval( lhs_ ) * eval( rhs_ ) );
1875             refres_ += scalar * ( eval( reflhs_ ) * eval( refrhs_ ) );
1876          }
1877          catch( std::exception& ex ) {
1878             convertException<MT>( ex );
1879          }
1880 
1881          checkResults<MT>();
1882 
1883          try {
1884             initResults();
1885             dres_   += scalar * ( eval( olhs_ ) * eval( rhs_ ) );
1886             sres_   += scalar * ( eval( olhs_ ) * eval( rhs_ ) );
1887             refres_ += scalar * ( eval( reflhs_ ) * eval( refrhs_ ) );
1888          }
1889          catch( std::exception& ex ) {
1890             convertException<TMT>( ex );
1891          }
1892 
1893          checkResults<TMT>();
1894       }
1895 
1896 
1897       //=====================================================================================
1898       // Scaled multiplication with addition assignment (OP*s)
1899       //=====================================================================================
1900 
1901       // Scaled multiplication with addition assignment with the given matrix/vector
1902       {
1903          test_  = "Scaled multiplication with addition assignment with the given matrix/vector (OP*s)";
1904          error_ = "Failed addition assignment operation";
1905 
1906          try {
1907             initResults();
1908             dres_   += ( lhs_ * rhs_ ) * scalar;
1909             sres_   += ( lhs_ * rhs_ ) * scalar;
1910             refres_ += ( reflhs_ * refrhs_ ) * scalar;
1911          }
1912          catch( std::exception& ex ) {
1913             convertException<MT>( ex );
1914          }
1915 
1916          checkResults<MT>();
1917 
1918          try {
1919             initResults();
1920             dres_   += ( olhs_ * rhs_ ) * scalar;
1921             sres_   += ( olhs_ * rhs_ ) * scalar;
1922             refres_ += ( reflhs_ * refrhs_ ) * scalar;
1923          }
1924          catch( std::exception& ex ) {
1925             convertException<TMT>( ex );
1926          }
1927 
1928          checkResults<TMT>();
1929       }
1930 
1931       // Scaled multiplication with addition assignment with evaluated matrix/vector
1932       {
1933          test_  = "Scaled multiplication with addition assignment with evaluated matrix/vector (OP*s)";
1934          error_ = "Failed addition assignment operation";
1935 
1936          try {
1937             initResults();
1938             dres_   += ( eval( lhs_ ) * eval( rhs_ ) ) * scalar;
1939             sres_   += ( eval( lhs_ ) * eval( rhs_ ) ) * scalar;
1940             refres_ += ( eval( reflhs_ ) * eval( refrhs_ ) ) * scalar;
1941          }
1942          catch( std::exception& ex ) {
1943             convertException<MT>( ex );
1944          }
1945 
1946          checkResults<MT>();
1947 
1948          try {
1949             initResults();
1950             dres_   += ( eval( olhs_ ) * eval( rhs_ ) ) * scalar;
1951             sres_   += ( eval( olhs_ ) * eval( rhs_ ) ) * scalar;
1952             refres_ += ( eval( reflhs_ ) * eval( refrhs_ ) ) * scalar;
1953          }
1954          catch( std::exception& ex ) {
1955             convertException<TMT>( ex );
1956          }
1957 
1958          checkResults<TMT>();
1959       }
1960 
1961 
1962       //=====================================================================================
1963       // Scaled multiplication with addition assignment (OP/s)
1964       //=====================================================================================
1965 
1966       // Scaled multiplication with addition assignment with the given matrix/vector
1967       {
1968          test_  = "Scaled multiplication with addition assignment with the given matrix/vector (OP/s)";
1969          error_ = "Failed addition assignment operation";
1970 
1971          try {
1972             initResults();
1973             dres_   += ( lhs_ * rhs_ ) / scalar;
1974             sres_   += ( lhs_ * rhs_ ) / scalar;
1975             refres_ += ( reflhs_ * refrhs_ ) / scalar;
1976          }
1977          catch( std::exception& ex ) {
1978             convertException<MT>( ex );
1979          }
1980 
1981          checkResults<MT>();
1982 
1983          try {
1984             initResults();
1985             dres_   += ( olhs_ * rhs_ ) / scalar;
1986             sres_   += ( olhs_ * rhs_ ) / scalar;
1987             refres_ += ( reflhs_ * refrhs_ ) / scalar;
1988          }
1989          catch( std::exception& ex ) {
1990             convertException<TMT>( ex );
1991          }
1992 
1993          checkResults<TMT>();
1994       }
1995 
1996       // Scaled multiplication with addition assignment with evaluated matrix/vector
1997       {
1998          test_  = "Scaled multiplication with addition assignment with evaluated matrix/vector (OP/s)";
1999          error_ = "Failed addition assignment operation";
2000 
2001          try {
2002             initResults();
2003             dres_   += ( eval( lhs_ ) * eval( rhs_ ) ) / scalar;
2004             sres_   += ( eval( lhs_ ) * eval( rhs_ ) ) / scalar;
2005             refres_ += ( eval( reflhs_ ) * eval( refrhs_ ) ) / scalar;
2006          }
2007          catch( std::exception& ex ) {
2008             convertException<MT>( ex );
2009          }
2010 
2011          checkResults<MT>();
2012 
2013          try {
2014             initResults();
2015             dres_   += ( eval( olhs_ ) * eval( rhs_ ) ) / scalar;
2016             sres_   += ( eval( olhs_ ) * eval( rhs_ ) ) / scalar;
2017             refres_ += ( eval( reflhs_ ) * eval( refrhs_ ) ) / scalar;
2018          }
2019          catch( std::exception& ex ) {
2020             convertException<TMT>( ex );
2021          }
2022 
2023          checkResults<TMT>();
2024       }
2025 
2026 
2027       //=====================================================================================
2028       // Scaled multiplication with subtraction assignment (s*OP)
2029       //=====================================================================================
2030 
2031       // Scaled multiplication with subtraction assignment with the given matrix/vector
2032       {
2033          test_  = "Scaled multiplication with subtraction assignment with the given matrix/vector (s*OP)";
2034          error_ = "Failed subtraction assignment operation";
2035 
2036          try {
2037             initResults();
2038             dres_   -= scalar * ( lhs_ * rhs_ );
2039             sres_   -= scalar * ( lhs_ * rhs_ );
2040             refres_ -= scalar * ( reflhs_ * refrhs_ );
2041          }
2042          catch( std::exception& ex ) {
2043             convertException<MT>( ex );
2044          }
2045 
2046          checkResults<MT>();
2047 
2048          try {
2049             initResults();
2050             dres_   -= scalar * ( olhs_ * rhs_ );
2051             sres_   -= scalar * ( olhs_ * rhs_ );
2052             refres_ -= scalar * ( reflhs_ * refrhs_ );
2053          }
2054          catch( std::exception& ex ) {
2055             convertException<TMT>( ex );
2056          }
2057 
2058          checkResults<TMT>();
2059       }
2060 
2061       // Scaled multiplication with subtraction assignment with evaluated matrix/vector
2062       {
2063          test_  = "Scaled multiplication with subtraction assignment with evaluated matrix/vector (s*OP)";
2064          error_ = "Failed subtraction assignment operation";
2065 
2066          try {
2067             initResults();
2068             dres_   -= scalar * ( eval( lhs_ ) * eval( rhs_ ) );
2069             sres_   -= scalar * ( eval( lhs_ ) * eval( rhs_ ) );
2070             refres_ -= scalar * ( eval( reflhs_ ) * eval( refrhs_ ) );
2071          }
2072          catch( std::exception& ex ) {
2073             convertException<MT>( ex );
2074          }
2075 
2076          checkResults<MT>();
2077 
2078          try {
2079             initResults();
2080             dres_   -= scalar * ( eval( olhs_ ) * eval( rhs_ ) );
2081             sres_   -= scalar * ( eval( olhs_ ) * eval( rhs_ ) );
2082             refres_ -= scalar * ( eval( reflhs_ ) * eval( refrhs_ ) );
2083          }
2084          catch( std::exception& ex ) {
2085             convertException<TMT>( ex );
2086          }
2087 
2088          checkResults<TMT>();
2089       }
2090 
2091 
2092       //=====================================================================================
2093       // Scaled multiplication with subtraction assignment (OP*s)
2094       //=====================================================================================
2095 
2096       // Scaled multiplication with subtraction assignment with the given matrix/vector
2097       {
2098          test_  = "Scaled multiplication with subtraction assignment with the given matrix/vector (OP*s)";
2099          error_ = "Failed subtraction assignment operation";
2100 
2101          try {
2102             initResults();
2103             dres_   -= ( lhs_ * rhs_ ) * scalar;
2104             sres_   -= ( lhs_ * rhs_ ) * scalar;
2105             refres_ -= ( reflhs_ * refrhs_ ) * scalar;
2106          }
2107          catch( std::exception& ex ) {
2108             convertException<MT>( ex );
2109          }
2110 
2111          checkResults<MT>();
2112 
2113          try {
2114             initResults();
2115             dres_   -= ( olhs_ * rhs_ ) * scalar;
2116             sres_   -= ( olhs_ * rhs_ ) * scalar;
2117             refres_ -= ( reflhs_ * refrhs_ ) * scalar;
2118          }
2119          catch( std::exception& ex ) {
2120             convertException<TMT>( ex );
2121          }
2122 
2123          checkResults<TMT>();
2124       }
2125 
2126       // Scaled multiplication with subtraction assignment with evaluated matrix/vector
2127       {
2128          test_  = "Scaled multiplication with subtraction assignment with evaluated matrix/vector (OP*s)";
2129          error_ = "Failed subtraction assignment operation";
2130 
2131          try {
2132             initResults();
2133             dres_   -= ( eval( lhs_ ) * eval( rhs_ ) ) * scalar;
2134             sres_   -= ( eval( lhs_ ) * eval( rhs_ ) ) * scalar;
2135             refres_ -= ( eval( reflhs_ ) * eval( refrhs_ ) ) * scalar;
2136          }
2137          catch( std::exception& ex ) {
2138             convertException<MT>( ex );
2139          }
2140 
2141          checkResults<MT>();
2142 
2143          try {
2144             initResults();
2145             dres_   -= ( eval( olhs_ ) * eval( rhs_ ) ) * scalar;
2146             sres_   -= ( eval( olhs_ ) * eval( rhs_ ) ) * scalar;
2147             refres_ -= ( eval( reflhs_ ) * eval( refrhs_ ) ) * scalar;
2148          }
2149          catch( std::exception& ex ) {
2150             convertException<TMT>( ex );
2151          }
2152 
2153          checkResults<TMT>();
2154       }
2155 
2156 
2157       //=====================================================================================
2158       // Scaled multiplication with subtraction assignment (OP/s)
2159       //=====================================================================================
2160 
2161       // Scaled multiplication with subtraction assignment with the given matrix/vector
2162       {
2163          test_  = "Scaled multiplication with subtraction assignment with the given matrix/vector (OP/s)";
2164          error_ = "Failed subtraction assignment operation";
2165 
2166          try {
2167             initResults();
2168             dres_   -= ( lhs_ * rhs_ ) / scalar;
2169             sres_   -= ( lhs_ * rhs_ ) / scalar;
2170             refres_ -= ( reflhs_ * refrhs_ ) / scalar;
2171          }
2172          catch( std::exception& ex ) {
2173             convertException<MT>( ex );
2174          }
2175 
2176          checkResults<MT>();
2177 
2178          try {
2179             initResults();
2180             dres_   -= ( olhs_ * rhs_ ) / scalar;
2181             sres_   -= ( olhs_ * rhs_ ) / scalar;
2182             refres_ -= ( reflhs_ * refrhs_ ) / scalar;
2183          }
2184          catch( std::exception& ex ) {
2185             convertException<TMT>( ex );
2186          }
2187 
2188          checkResults<TMT>();
2189       }
2190 
2191       // Scaled multiplication with subtraction assignment with evaluated matrix/vector
2192       {
2193          test_  = "Scaled multiplication with subtraction assignment with evaluated matrix/vector (OP/s)";
2194          error_ = "Failed subtraction assignment operation";
2195 
2196          try {
2197             initResults();
2198             dres_   -= ( eval( lhs_ ) * eval( rhs_ ) ) / scalar;
2199             sres_   -= ( eval( lhs_ ) * eval( rhs_ ) ) / scalar;
2200             refres_ -= ( eval( reflhs_ ) * eval( refrhs_ ) ) / scalar;
2201          }
2202          catch( std::exception& ex ) {
2203             convertException<MT>( ex );
2204          }
2205 
2206          checkResults<MT>();
2207 
2208          try {
2209             initResults();
2210             dres_   -= ( eval( olhs_ ) * eval( rhs_ ) ) / scalar;
2211             sres_   -= ( eval( olhs_ ) * eval( rhs_ ) ) / scalar;
2212             refres_ -= ( eval( reflhs_ ) * eval( refrhs_ ) ) / scalar;
2213          }
2214          catch( std::exception& ex ) {
2215             convertException<TMT>( ex );
2216          }
2217 
2218          checkResults<TMT>();
2219       }
2220 
2221 
2222       //=====================================================================================
2223       // Scaled multiplication with multiplication assignment (s*OP)
2224       //=====================================================================================
2225 
2226       // Scaled multiplication with multiplication assignment with the given matrix/vector
2227       {
2228          test_  = "Scaled multiplication with multiplication assignment with the given matrix/vector (s*OP)";
2229          error_ = "Failed multiplication assignment operation";
2230 
2231          try {
2232             initResults();
2233             dres_   *= scalar * ( lhs_ * rhs_ );
2234             sres_   *= scalar * ( lhs_ * rhs_ );
2235             refres_ *= scalar * ( reflhs_ * refrhs_ );
2236          }
2237          catch( std::exception& ex ) {
2238             convertException<MT>( ex );
2239          }
2240 
2241          checkResults<MT>();
2242 
2243          try {
2244             initResults();
2245             dres_   *= scalar * ( olhs_ * rhs_ );
2246             sres_   *= scalar * ( olhs_ * rhs_ );
2247             refres_ *= scalar * ( reflhs_ * refrhs_ );
2248          }
2249          catch( std::exception& ex ) {
2250             convertException<TMT>( ex );
2251          }
2252 
2253          checkResults<TMT>();
2254       }
2255 
2256       // Scaled multiplication with multiplication assignment with evaluated matrix/vector
2257       {
2258          test_  = "Scaled multiplication with multiplication assignment with evaluated matrix/vector (s*OP)";
2259          error_ = "Failed multiplication assignment operation";
2260 
2261          try {
2262             initResults();
2263             dres_   *= scalar * ( eval( lhs_ ) * eval( rhs_ ) );
2264             sres_   *= scalar * ( eval( lhs_ ) * eval( rhs_ ) );
2265             refres_ *= scalar * ( eval( reflhs_ ) * eval( refrhs_ ) );
2266          }
2267          catch( std::exception& ex ) {
2268             convertException<MT>( ex );
2269          }
2270 
2271          checkResults<MT>();
2272 
2273          try {
2274             initResults();
2275             dres_   *= scalar * ( eval( olhs_ ) * eval( rhs_ ) );
2276             sres_   *= scalar * ( eval( olhs_ ) * eval( rhs_ ) );
2277             refres_ *= scalar * ( eval( reflhs_ ) * eval( refrhs_ ) );
2278          }
2279          catch( std::exception& ex ) {
2280             convertException<TMT>( ex );
2281          }
2282 
2283          checkResults<TMT>();
2284       }
2285 
2286 
2287       //=====================================================================================
2288       // Scaled multiplication with multiplication assignment (OP*s)
2289       //=====================================================================================
2290 
2291       // Scaled multiplication with multiplication assignment with the given matrix/vector
2292       {
2293          test_  = "Scaled multiplication with multiplication assignment with the given matrix/vector (OP*s)";
2294          error_ = "Failed multiplication assignment operation";
2295 
2296          try {
2297             initResults();
2298             dres_   *= ( lhs_ * rhs_ ) * scalar;
2299             sres_   *= ( lhs_ * rhs_ ) * scalar;
2300             refres_ *= ( reflhs_ * refrhs_ ) * scalar;
2301          }
2302          catch( std::exception& ex ) {
2303             convertException<MT>( ex );
2304          }
2305 
2306          checkResults<MT>();
2307 
2308          try {
2309             initResults();
2310             dres_   *= ( olhs_ * rhs_ ) * scalar;
2311             sres_   *= ( olhs_ * rhs_ ) * scalar;
2312             refres_ *= ( reflhs_ * refrhs_ ) * scalar;
2313          }
2314          catch( std::exception& ex ) {
2315             convertException<TMT>( ex );
2316          }
2317 
2318          checkResults<TMT>();
2319       }
2320 
2321       // Scaled multiplication with multiplication assignment with evaluated matrix/vector
2322       {
2323          test_  = "Scaled multiplication with multiplication assignment with evaluated matrix/vector (OP*s)";
2324          error_ = "Failed multiplication assignment operation";
2325 
2326          try {
2327             initResults();
2328             dres_   *= ( eval( lhs_ ) * eval( rhs_ ) ) * scalar;
2329             sres_   *= ( eval( lhs_ ) * eval( rhs_ ) ) * scalar;
2330             refres_ *= ( eval( reflhs_ ) * eval( refrhs_ ) ) * scalar;
2331          }
2332          catch( std::exception& ex ) {
2333             convertException<MT>( ex );
2334          }
2335 
2336          checkResults<MT>();
2337 
2338          try {
2339             initResults();
2340             dres_   *= ( eval( olhs_ ) * eval( rhs_ ) ) * scalar;
2341             sres_   *= ( eval( olhs_ ) * eval( rhs_ ) ) * scalar;
2342             refres_ *= ( eval( reflhs_ ) * eval( refrhs_ ) ) * scalar;
2343          }
2344          catch( std::exception& ex ) {
2345             convertException<TMT>( ex );
2346          }
2347 
2348          checkResults<TMT>();
2349       }
2350 
2351 
2352       //=====================================================================================
2353       // Scaled multiplication with multiplication assignment (OP/s)
2354       //=====================================================================================
2355 
2356       // Scaled multiplication with multiplication assignment with the given matrix/vector
2357       {
2358          test_  = "Scaled multiplication with multiplication assignment with the given matrix/vector (OP/s)";
2359          error_ = "Failed multiplication assignment operation";
2360 
2361          try {
2362             initResults();
2363             dres_   *= ( lhs_ * rhs_ ) / scalar;
2364             sres_   *= ( lhs_ * rhs_ ) / scalar;
2365             refres_ *= ( reflhs_ * refrhs_ ) / scalar;
2366          }
2367          catch( std::exception& ex ) {
2368             convertException<MT>( ex );
2369          }
2370 
2371          checkResults<MT>();
2372 
2373          try {
2374             initResults();
2375             dres_   *= ( olhs_ * rhs_ ) / scalar;
2376             sres_   *= ( olhs_ * rhs_ ) / scalar;
2377             refres_ *= ( reflhs_ * refrhs_ ) / scalar;
2378          }
2379          catch( std::exception& ex ) {
2380             convertException<TMT>( ex );
2381          }
2382 
2383          checkResults<TMT>();
2384       }
2385 
2386       // Scaled multiplication with multiplication assignment with evaluated matrix/vector
2387       {
2388          test_  = "Scaled multiplication with multiplication assignment with evaluated matrix/vector (OP/s)";
2389          error_ = "Failed multiplication assignment operation";
2390 
2391          try {
2392             initResults();
2393             dres_   *= ( eval( lhs_ ) * eval( rhs_ ) ) / scalar;
2394             sres_   *= ( eval( lhs_ ) * eval( rhs_ ) ) / scalar;
2395             refres_ *= ( eval( reflhs_ ) * eval( refrhs_ ) ) / scalar;
2396          }
2397          catch( std::exception& ex ) {
2398             convertException<MT>( ex );
2399          }
2400 
2401          checkResults<MT>();
2402 
2403          try {
2404             initResults();
2405             dres_   *= ( eval( olhs_ ) * eval( rhs_ ) ) / scalar;
2406             sres_   *= ( eval( olhs_ ) * eval( rhs_ ) ) / scalar;
2407             refres_ *= ( eval( reflhs_ ) * eval( refrhs_ ) ) / scalar;
2408          }
2409          catch( std::exception& ex ) {
2410             convertException<TMT>( ex );
2411          }
2412 
2413          checkResults<TMT>();
2414       }
2415    }
2416 #endif
2417 }
2418 //*************************************************************************************************
2419 
2420 
2421 //*************************************************************************************************
2422 /*!\brief Testing the transpose sparse matrix/sparse vector multiplication.
2423 //
2424 // \return void
2425 // \exception std::runtime_error Multiplication error detected.
2426 //
2427 // This function tests the transpose matrix/vector multiplication with plain assignment,
2428 // addition assignment, subtraction assignment, and multiplication assignment. In case any
2429 // error resulting from the multiplication or the subsequent assignment is detected, a
2430 // \a std::runtime_error exception is thrown.
2431 */
2432 template< typename MT    // Type of the left-hand side sparse matrix
2433         , typename VT >  // Type of the right-hand side sparse vector
testTransOperation()2434 void OperationTest<MT,VT>::testTransOperation()
2435 {
2436 #if BLAZETEST_MATHTEST_TEST_TRANS_OPERATION
2437    if( BLAZETEST_MATHTEST_TEST_TRANS_OPERATION > 1 )
2438    {
2439       //=====================================================================================
2440       // Transpose multiplication
2441       //=====================================================================================
2442 
2443       // Transpose multiplication with the given matrix/vector
2444       {
2445          test_  = "Transpose multiplication with the given matrix/vector";
2446          error_ = "Failed multiplication operation";
2447 
2448          try {
2449             initTransposeResults();
2450             tdres_   = trans( lhs_ * rhs_ );
2451             tsres_   = trans( lhs_ * rhs_ );
2452             trefres_ = trans( reflhs_ * refrhs_ );
2453          }
2454          catch( std::exception& ex ) {
2455             convertException<MT>( ex );
2456          }
2457 
2458          checkTransposeResults<MT>();
2459 
2460          try {
2461             initTransposeResults();
2462             tdres_   = trans( olhs_ * rhs_ );
2463             tsres_   = trans( olhs_ * rhs_ );
2464             trefres_ = trans( reflhs_ * refrhs_ );
2465          }
2466          catch( std::exception& ex ) {
2467             convertException<TMT>( ex );
2468          }
2469 
2470          checkTransposeResults<TMT>();
2471       }
2472 
2473       // Transpose multiplication with evaluated matrix/vector
2474       {
2475          test_  = "Transpose multiplication with evaluated matrix/vector";
2476          error_ = "Failed multiplication operation";
2477 
2478          try {
2479             initTransposeResults();
2480             tdres_   = trans( eval( lhs_ ) * eval( rhs_ ) );
2481             tsres_   = trans( eval( lhs_ ) * eval( rhs_ ) );
2482             trefres_ = trans( eval( reflhs_ ) * eval( refrhs_ ) );
2483          }
2484          catch( std::exception& ex ) {
2485             convertException<MT>( ex );
2486          }
2487 
2488          checkTransposeResults<MT>();
2489 
2490          try {
2491             initTransposeResults();
2492             tdres_   = trans( eval( olhs_ ) * eval( rhs_ ) );
2493             tsres_   = trans( eval( olhs_ ) * eval( rhs_ ) );
2494             trefres_ = trans( eval( reflhs_ ) * eval( refrhs_ ) );
2495          }
2496          catch( std::exception& ex ) {
2497             convertException<TMT>( ex );
2498          }
2499 
2500          checkTransposeResults<TMT>();
2501       }
2502 
2503 
2504       //=====================================================================================
2505       // Transpose multiplication with addition assignment
2506       //=====================================================================================
2507 
2508       // Transpose multiplication with addition assignment with the given matrix/vector
2509       {
2510          test_  = "Transpose multiplication with addition assignment with the given matrix/vector";
2511          error_ = "Failed addition assignment operation";
2512 
2513          try {
2514             initTransposeResults();
2515             tdres_   += trans( lhs_ * rhs_ );
2516             tsres_   += trans( lhs_ * rhs_ );
2517             trefres_ += trans( reflhs_ * refrhs_ );
2518          }
2519          catch( std::exception& ex ) {
2520             convertException<MT>( ex );
2521          }
2522 
2523          checkTransposeResults<MT>();
2524 
2525          try {
2526             initTransposeResults();
2527             tdres_   += trans( olhs_ * rhs_ );
2528             tsres_   += trans( olhs_ * rhs_ );
2529             trefres_ += trans( reflhs_ * refrhs_ );
2530          }
2531          catch( std::exception& ex ) {
2532             convertException<TMT>( ex );
2533          }
2534 
2535          checkTransposeResults<TMT>();
2536       }
2537 
2538       // Transpose multiplication with addition assignment with evaluated matrix/vector
2539       {
2540          test_  = "Transpose multiplication with addition assignment with evaluated matrix/vector";
2541          error_ = "Failed addition assignment operation";
2542 
2543          try {
2544             initTransposeResults();
2545             tdres_   += trans( eval( lhs_ ) * eval( rhs_ ) );
2546             tsres_   += trans( eval( lhs_ ) * eval( rhs_ ) );
2547             trefres_ += trans( eval( reflhs_ ) * eval( refrhs_ ) );
2548          }
2549          catch( std::exception& ex ) {
2550             convertException<MT>( ex );
2551          }
2552 
2553          checkTransposeResults<MT>();
2554 
2555          try {
2556             initTransposeResults();
2557             tdres_   += trans( eval( olhs_ ) * eval( rhs_ ) );
2558             tsres_   += trans( eval( olhs_ ) * eval( rhs_ ) );
2559             trefres_ += trans( eval( reflhs_ ) * eval( refrhs_ ) );
2560          }
2561          catch( std::exception& ex ) {
2562             convertException<TMT>( ex );
2563          }
2564 
2565          checkTransposeResults<TMT>();
2566       }
2567 
2568 
2569       //=====================================================================================
2570       // Transpose multiplication with subtraction assignment
2571       //=====================================================================================
2572 
2573       // Transpose multiplication with subtraction assignment with the given matrix/vector
2574       {
2575          test_  = "Transpose multiplication with subtraction assignment with the given matrix/vector";
2576          error_ = "Failed subtraction assignment operation";
2577 
2578          try {
2579             initTransposeResults();
2580             tdres_   -= trans( lhs_ * rhs_ );
2581             tsres_   -= trans( lhs_ * rhs_ );
2582             trefres_ -= trans( reflhs_ * refrhs_ );
2583          }
2584          catch( std::exception& ex ) {
2585             convertException<MT>( ex );
2586          }
2587 
2588          checkTransposeResults<MT>();
2589 
2590          try {
2591             initTransposeResults();
2592             tdres_   -= trans( olhs_ * rhs_ );
2593             tsres_   -= trans( olhs_ * rhs_ );
2594             trefres_ -= trans( reflhs_ * refrhs_ );
2595          }
2596          catch( std::exception& ex ) {
2597             convertException<TMT>( ex );
2598          }
2599 
2600          checkTransposeResults<TMT>();
2601       }
2602 
2603       // Transpose multiplication with subtraction assignment with evaluated matrix/vector
2604       {
2605          test_  = "Transpose multiplication with subtraction assignment with evaluated matrix/vector";
2606          error_ = "Failed subtraction assignment operation";
2607 
2608          try {
2609             initTransposeResults();
2610             tdres_   -= trans( eval( lhs_ ) * eval( rhs_ ) );
2611             tsres_   -= trans( eval( lhs_ ) * eval( rhs_ ) );
2612             trefres_ -= trans( eval( reflhs_ ) * eval( refrhs_ ) );
2613          }
2614          catch( std::exception& ex ) {
2615             convertException<MT>( ex );
2616          }
2617 
2618          checkTransposeResults<MT>();
2619 
2620          try {
2621             initTransposeResults();
2622             tdres_   -= trans( eval( olhs_ ) * eval( rhs_ ) );
2623             tsres_   -= trans( eval( olhs_ ) * eval( rhs_ ) );
2624             trefres_ -= trans( eval( reflhs_ ) * eval( refrhs_ ) );
2625          }
2626          catch( std::exception& ex ) {
2627             convertException<TMT>( ex );
2628          }
2629 
2630          checkTransposeResults<TMT>();
2631       }
2632 
2633 
2634       //=====================================================================================
2635       // Transpose multiplication with multiplication assignment
2636       //=====================================================================================
2637 
2638       // Transpose multiplication with multiplication assignment with the given matrix/vector
2639       {
2640          test_  = "Transpose multiplication with multiplication assignment with the given matrix/vector";
2641          error_ = "Failed multiplication assignment operation";
2642 
2643          try {
2644             initTransposeResults();
2645             tdres_   *= trans( lhs_ * rhs_ );
2646             tsres_   *= trans( lhs_ * rhs_ );
2647             trefres_ *= trans( reflhs_ * refrhs_ );
2648          }
2649          catch( std::exception& ex ) {
2650             convertException<MT>( ex );
2651          }
2652 
2653          checkTransposeResults<MT>();
2654 
2655          try {
2656             initTransposeResults();
2657             tdres_   *= trans( olhs_ * rhs_ );
2658             tsres_   *= trans( olhs_ * rhs_ );
2659             trefres_ *= trans( reflhs_ * refrhs_ );
2660          }
2661          catch( std::exception& ex ) {
2662             convertException<TMT>( ex );
2663          }
2664 
2665          checkTransposeResults<TMT>();
2666       }
2667 
2668       // Transpose multiplication with multiplication assignment with evaluated matrix/vector
2669       {
2670          test_  = "Transpose multiplication with multiplication assignment with evaluated matrix/vector";
2671          error_ = "Failed multiplication assignment operation";
2672 
2673          try {
2674             initTransposeResults();
2675             tdres_   *= trans( eval( lhs_ ) * eval( rhs_ ) );
2676             tsres_   *= trans( eval( lhs_ ) * eval( rhs_ ) );
2677             trefres_ *= trans( eval( reflhs_ ) * eval( refrhs_ ) );
2678          }
2679          catch( std::exception& ex ) {
2680             convertException<MT>( ex );
2681          }
2682 
2683          checkTransposeResults<MT>();
2684 
2685          try {
2686             initTransposeResults();
2687             tdres_   *= trans( eval( olhs_ ) * eval( rhs_ ) );
2688             tsres_   *= trans( eval( olhs_ ) * eval( rhs_ ) );
2689             trefres_ *= trans( eval( reflhs_ ) * eval( refrhs_ ) );
2690          }
2691          catch( std::exception& ex ) {
2692             convertException<TMT>( ex );
2693          }
2694 
2695          checkTransposeResults<TMT>();
2696       }
2697    }
2698 #endif
2699 }
2700 //*************************************************************************************************
2701 
2702 
2703 //*************************************************************************************************
2704 /*!\brief Testing the conjugate transpose sparse matrix/sparse vector multiplication.
2705 //
2706 // \return void
2707 // \exception std::runtime_error Multiplication error detected.
2708 //
2709 // This function tests the conjugate transpose matrix/vector multiplication with plain
2710 // assignment, addition assignment, subtraction assignment, and multiplication assignment.
2711 // In case any error resulting from the multiplication or the subsequent assignment is
2712 // detected, a \a std::runtime_error exception is thrown.
2713 */
2714 template< typename MT    // Type of the left-hand side sparse matrix
2715         , typename VT >  // Type of the right-hand side sparse vector
testCTransOperation()2716 void OperationTest<MT,VT>::testCTransOperation()
2717 {
2718 #if BLAZETEST_MATHTEST_TEST_CTRANS_OPERATION
2719    if( BLAZETEST_MATHTEST_TEST_CTRANS_OPERATION > 1 )
2720    {
2721       //=====================================================================================
2722       // Conjugate transpose multiplication
2723       //=====================================================================================
2724 
2725       // Conjugate transpose multiplication with the given matrix/vector
2726       {
2727          test_  = "Conjugate transpose multiplication with the given matrix/vector";
2728          error_ = "Failed multiplication operation";
2729 
2730          try {
2731             initTransposeResults();
2732             tdres_   = ctrans( lhs_ * rhs_ );
2733             tsres_   = ctrans( lhs_ * rhs_ );
2734             trefres_ = ctrans( reflhs_ * refrhs_ );
2735          }
2736          catch( std::exception& ex ) {
2737             convertException<MT>( ex );
2738          }
2739 
2740          checkTransposeResults<MT>();
2741 
2742          try {
2743             initTransposeResults();
2744             tdres_   = ctrans( olhs_ * rhs_ );
2745             tsres_   = ctrans( olhs_ * rhs_ );
2746             trefres_ = ctrans( reflhs_ * refrhs_ );
2747          }
2748          catch( std::exception& ex ) {
2749             convertException<TMT>( ex );
2750          }
2751 
2752          checkTransposeResults<TMT>();
2753       }
2754 
2755       // Conjugate transpose multiplication with evaluated matrix/vector
2756       {
2757          test_  = "Conjugate transpose multiplication with evaluated matrix/vector";
2758          error_ = "Failed multiplication operation";
2759 
2760          try {
2761             initTransposeResults();
2762             tdres_   = ctrans( eval( lhs_ ) * eval( rhs_ ) );
2763             tsres_   = ctrans( eval( lhs_ ) * eval( rhs_ ) );
2764             trefres_ = ctrans( eval( reflhs_ ) * eval( refrhs_ ) );
2765          }
2766          catch( std::exception& ex ) {
2767             convertException<MT>( ex );
2768          }
2769 
2770          checkTransposeResults<MT>();
2771 
2772          try {
2773             initTransposeResults();
2774             tdres_   = ctrans( eval( olhs_ ) * eval( rhs_ ) );
2775             tsres_   = ctrans( eval( olhs_ ) * eval( rhs_ ) );
2776             trefres_ = ctrans( eval( reflhs_ ) * eval( refrhs_ ) );
2777          }
2778          catch( std::exception& ex ) {
2779             convertException<TMT>( ex );
2780          }
2781 
2782          checkTransposeResults<TMT>();
2783       }
2784 
2785 
2786       //=====================================================================================
2787       // Conjugate transpose multiplication with addition assignment
2788       //=====================================================================================
2789 
2790       // Conjugate transpose multiplication with addition assignment with the given matrix/vector
2791       {
2792          test_  = "Conjugate transpose multiplication with addition assignment with the given matrix/vector";
2793          error_ = "Failed addition assignment operation";
2794 
2795          try {
2796             initTransposeResults();
2797             tdres_   += ctrans( lhs_ * rhs_ );
2798             tsres_   += ctrans( lhs_ * rhs_ );
2799             trefres_ += ctrans( reflhs_ * refrhs_ );
2800          }
2801          catch( std::exception& ex ) {
2802             convertException<MT>( ex );
2803          }
2804 
2805          checkTransposeResults<MT>();
2806 
2807          try {
2808             initTransposeResults();
2809             tdres_   += ctrans( olhs_ * rhs_ );
2810             tsres_   += ctrans( olhs_ * rhs_ );
2811             trefres_ += ctrans( reflhs_ * refrhs_ );
2812          }
2813          catch( std::exception& ex ) {
2814             convertException<TMT>( ex );
2815          }
2816 
2817          checkTransposeResults<TMT>();
2818       }
2819 
2820       // Conjugate transpose multiplication with addition assignment with evaluated matrix/vector
2821       {
2822          test_  = "Conjugate transpose multiplication with addition assignment with evaluated matrix/vector";
2823          error_ = "Failed addition assignment operation";
2824 
2825          try {
2826             initTransposeResults();
2827             tdres_   += ctrans( eval( lhs_ ) * eval( rhs_ ) );
2828             tsres_   += ctrans( eval( lhs_ ) * eval( rhs_ ) );
2829             trefres_ += ctrans( eval( reflhs_ ) * eval( refrhs_ ) );
2830          }
2831          catch( std::exception& ex ) {
2832             convertException<MT>( ex );
2833          }
2834 
2835          checkTransposeResults<MT>();
2836 
2837          try {
2838             initTransposeResults();
2839             tdres_   += ctrans( eval( olhs_ ) * eval( rhs_ ) );
2840             tsres_   += ctrans( eval( olhs_ ) * eval( rhs_ ) );
2841             trefres_ += ctrans( eval( reflhs_ ) * eval( refrhs_ ) );
2842          }
2843          catch( std::exception& ex ) {
2844             convertException<TMT>( ex );
2845          }
2846 
2847          checkTransposeResults<TMT>();
2848       }
2849 
2850 
2851       //=====================================================================================
2852       // Conjugate transpose multiplication with subtraction assignment
2853       //=====================================================================================
2854 
2855       // Conjugate transpose multiplication with subtraction assignment with the given matrix/vector
2856       {
2857          test_  = "Conjugate transpose multiplication with subtraction assignment with the given matrix/vector";
2858          error_ = "Failed subtraction assignment operation";
2859 
2860          try {
2861             initTransposeResults();
2862             tdres_   -= ctrans( lhs_ * rhs_ );
2863             tsres_   -= ctrans( lhs_ * rhs_ );
2864             trefres_ -= ctrans( reflhs_ * refrhs_ );
2865          }
2866          catch( std::exception& ex ) {
2867             convertException<MT>( ex );
2868          }
2869 
2870          checkTransposeResults<MT>();
2871 
2872          try {
2873             initTransposeResults();
2874             tdres_   -= ctrans( olhs_ * rhs_ );
2875             tsres_   -= ctrans( olhs_ * rhs_ );
2876             trefres_ -= ctrans( reflhs_ * refrhs_ );
2877          }
2878          catch( std::exception& ex ) {
2879             convertException<TMT>( ex );
2880          }
2881 
2882          checkTransposeResults<TMT>();
2883       }
2884 
2885       // Conjugate transpose multiplication with subtraction assignment with evaluated matrix/vector
2886       {
2887          test_  = "Conjugate transpose multiplication with subtraction assignment with evaluated matrix/vector";
2888          error_ = "Failed subtraction assignment operation";
2889 
2890          try {
2891             initTransposeResults();
2892             tdres_   -= ctrans( eval( lhs_ ) * eval( rhs_ ) );
2893             tsres_   -= ctrans( eval( lhs_ ) * eval( rhs_ ) );
2894             trefres_ -= ctrans( eval( reflhs_ ) * eval( refrhs_ ) );
2895          }
2896          catch( std::exception& ex ) {
2897             convertException<MT>( ex );
2898          }
2899 
2900          checkTransposeResults<MT>();
2901 
2902          try {
2903             initTransposeResults();
2904             tdres_   -= ctrans( eval( olhs_ ) * eval( rhs_ ) );
2905             tsres_   -= ctrans( eval( olhs_ ) * eval( rhs_ ) );
2906             trefres_ -= ctrans( eval( reflhs_ ) * eval( refrhs_ ) );
2907          }
2908          catch( std::exception& ex ) {
2909             convertException<TMT>( ex );
2910          }
2911 
2912          checkTransposeResults<TMT>();
2913       }
2914 
2915 
2916       //=====================================================================================
2917       // Conjugate transpose multiplication with multiplication assignment
2918       //=====================================================================================
2919 
2920       // Conjugate transpose multiplication with multiplication assignment with the given matrix/vector
2921       {
2922          test_  = "Conjugate transpose multiplication with multiplication assignment with the given matrix/vector";
2923          error_ = "Failed multiplication assignment operation";
2924 
2925          try {
2926             initTransposeResults();
2927             tdres_   *= ctrans( lhs_ * rhs_ );
2928             tsres_   *= ctrans( lhs_ * rhs_ );
2929             trefres_ *= ctrans( reflhs_ * refrhs_ );
2930          }
2931          catch( std::exception& ex ) {
2932             convertException<MT>( ex );
2933          }
2934 
2935          checkTransposeResults<MT>();
2936 
2937          try {
2938             initTransposeResults();
2939             tdres_   *= ctrans( olhs_ * rhs_ );
2940             tsres_   *= ctrans( olhs_ * rhs_ );
2941             trefres_ *= ctrans( reflhs_ * refrhs_ );
2942          }
2943          catch( std::exception& ex ) {
2944             convertException<TMT>( ex );
2945          }
2946 
2947          checkTransposeResults<TMT>();
2948       }
2949 
2950       // Conjugate transpose multiplication with multiplication assignment with evaluated matrix/vector
2951       {
2952          test_  = "Conjugate transpose multiplication with multiplication assignment with evaluated matrix/vector";
2953          error_ = "Failed multiplication assignment operation";
2954 
2955          try {
2956             initTransposeResults();
2957             tdres_   *= ctrans( eval( lhs_ ) * eval( rhs_ ) );
2958             tsres_   *= ctrans( eval( lhs_ ) * eval( rhs_ ) );
2959             trefres_ *= ctrans( eval( reflhs_ ) * eval( refrhs_ ) );
2960          }
2961          catch( std::exception& ex ) {
2962             convertException<MT>( ex );
2963          }
2964 
2965          checkTransposeResults<MT>();
2966 
2967          try {
2968             initTransposeResults();
2969             tdres_   *= ctrans( eval( olhs_ ) * eval( rhs_ ) );
2970             tsres_   *= ctrans( eval( olhs_ ) * eval( rhs_ ) );
2971             trefres_ *= ctrans( eval( reflhs_ ) * eval( refrhs_ ) );
2972          }
2973          catch( std::exception& ex ) {
2974             convertException<TMT>( ex );
2975          }
2976 
2977          checkTransposeResults<TMT>();
2978       }
2979    }
2980 #endif
2981 }
2982 //*************************************************************************************************
2983 
2984 
2985 //*************************************************************************************************
2986 /*!\brief Testing the abs sparse matrix/sparse vector multiplication.
2987 //
2988 // \return void
2989 // \exception std::runtime_error Multiplication error detected.
2990 //
2991 // This function tests the abs matrix/vector multiplication with plain assignment, addition
2992 // assignment, subtraction assignment, and multiplication assignment. In case any error
2993 // resulting from the multiplication or the subsequent assignment is detected, a
2994 // \a std::runtime_error exception is thrown.
2995 */
2996 template< typename MT    // Type of the left-hand side sparse matrix
2997         , typename VT >  // Type of the right-hand side sparse vector
testAbsOperation()2998 void OperationTest<MT,VT>::testAbsOperation()
2999 {
3000 #if BLAZETEST_MATHTEST_TEST_ABS_OPERATION
3001    if( BLAZETEST_MATHTEST_TEST_ABS_OPERATION > 1 )
3002    {
3003       testCustomOperation( blaze::Abs(), "abs" );
3004    }
3005 #endif
3006 }
3007 //*************************************************************************************************
3008 
3009 
3010 //*************************************************************************************************
3011 /*!\brief Testing the conjugate sparse matrix/sparse vector multiplication.
3012 //
3013 // \return void
3014 // \exception std::runtime_error Multiplication error detected.
3015 //
3016 // This function tests the conjugate matrix/vector multiplication with plain assignment, addition
3017 // assignment, subtraction assignment, and multiplication assignment. In case any error resulting
3018 // from the multiplication or the subsequent assignment is detected, a \a std::runtime_error
3019 // exception is thrown.
3020 */
3021 template< typename MT    // Type of the left-hand side sparse matrix
3022         , typename VT >  // Type of the right-hand side sparse vector
testConjOperation()3023 void OperationTest<MT,VT>::testConjOperation()
3024 {
3025 #if BLAZETEST_MATHTEST_TEST_CONJ_OPERATION
3026    if( BLAZETEST_MATHTEST_TEST_CONJ_OPERATION > 1 )
3027    {
3028       testCustomOperation( blaze::Conj(), "conj" );
3029    }
3030 #endif
3031 }
3032 //*************************************************************************************************
3033 
3034 
3035 //*************************************************************************************************
3036 /*!\brief Testing the \a real sparse matrix/sparse vector multiplication.
3037 //
3038 // \return void
3039 // \exception std::runtime_error Multiplication error detected.
3040 //
3041 // This function tests the \a real matrix/vector multiplication with plain assignment, addition
3042 // assignment, subtraction assignment, and multiplication assignment. In case any error resulting
3043 // from the multiplication or the subsequent assignment is detected, a \a std::runtime_error
3044 // exception is thrown.
3045 */
3046 template< typename MT    // Type of the left-hand side sparse matrix
3047         , typename VT >  // Type of the right-hand side sparse vector
testRealOperation()3048 void OperationTest<MT,VT>::testRealOperation()
3049 {
3050 #if BLAZETEST_MATHTEST_TEST_REAL_OPERATION
3051    if( BLAZETEST_MATHTEST_TEST_REAL_OPERATION > 1 )
3052    {
3053       testCustomOperation( blaze::Real(), "real" );
3054    }
3055 #endif
3056 }
3057 //*************************************************************************************************
3058 
3059 
3060 //*************************************************************************************************
3061 /*!\brief Testing the \a imag sparse matrix/sparse vector multiplication.
3062 //
3063 // \return void
3064 // \exception std::runtime_error Multiplication error detected.
3065 //
3066 // This function tests the \a imag matrix/vector multiplication with plain assignment, addition
3067 // assignment, subtraction assignment, and multiplication assignment. In case any error resulting
3068 // from the multiplication or the subsequent assignment is detected, a \a std::runtime_error
3069 // exception is thrown.
3070 */
3071 template< typename MT    // Type of the left-hand side sparse matrix
3072         , typename VT >  // Type of the right-hand side sparse vector
testImagOperation()3073 void OperationTest<MT,VT>::testImagOperation()
3074 {
3075 #if BLAZETEST_MATHTEST_TEST_IMAG_OPERATION
3076    if( BLAZETEST_MATHTEST_TEST_IMAG_OPERATION > 1 )
3077    {
3078       testCustomOperation( blaze::Imag(), "imag" );
3079    }
3080 #endif
3081 }
3082 //*************************************************************************************************
3083 
3084 
3085 //*************************************************************************************************
3086 /*!\brief Testing the evaluated sparse matrix/sparse vector multiplication.
3087 //
3088 // \return void
3089 // \exception std::runtime_error Multiplication error detected.
3090 //
3091 // This function tests the evaluated matrix/vector multiplication with plain assignment, addition
3092 // assignment, subtraction assignment, and multiplication assignment. In case any error resulting
3093 // from the multiplication or the subsequent assignment is detected, a \a std::runtime_error
3094 // exception is thrown.
3095 */
3096 template< typename MT    // Type of the left-hand side sparse matrix
3097         , typename VT >  // Type of the right-hand side sparse vector
testEvalOperation()3098 void OperationTest<MT,VT>::testEvalOperation()
3099 {
3100 #if BLAZETEST_MATHTEST_TEST_EVAL_OPERATION
3101    if( BLAZETEST_MATHTEST_TEST_EVAL_OPERATION > 1 )
3102    {
3103       testCustomOperation( blaze::Eval(), "eval" );
3104    }
3105 #endif
3106 }
3107 //*************************************************************************************************
3108 
3109 
3110 //*************************************************************************************************
3111 /*!\brief Testing the serialized sparse matrix/sparse vector multiplication.
3112 //
3113 // \return void
3114 // \exception std::runtime_error Multiplication error detected.
3115 //
3116 // This function tests the serialized matrix/vector multiplication with plain assignment, addition
3117 // assignment, subtraction assignment, and multiplication assignment. In case any error resulting
3118 // from the multiplication or the subsequent assignment is detected, a \a std::runtime_error
3119 // exception is thrown.
3120 */
3121 template< typename MT    // Type of the left-hand side sparse matrix
3122         , typename VT >  // Type of the right-hand side sparse vector
testSerialOperation()3123 void OperationTest<MT,VT>::testSerialOperation()
3124 {
3125 #if BLAZETEST_MATHTEST_TEST_SERIAL_OPERATION
3126    if( BLAZETEST_MATHTEST_TEST_SERIAL_OPERATION > 1 )
3127    {
3128       testCustomOperation( blaze::Serial(), "serial" );
3129    }
3130 #endif
3131 }
3132 //*************************************************************************************************
3133 
3134 
3135 //*************************************************************************************************
3136 /*!\brief Testing the non-aliased sparse matrix/sparse vector multiplication.
3137 //
3138 // \return void
3139 // \exception std::runtime_error Multiplication error detected.
3140 //
3141 // This function tests the non-aliased matrix/vector multiplication with plain assignment, addition
3142 // assignment, subtraction assignment, and multiplication assignment. In case any error resulting
3143 // from the multiplication or the subsequent assignment is detected, a \a std::runtime_error
3144 // exception is thrown.
3145 */
3146 template< typename MT    // Type of the left-hand side sparse matrix
3147         , typename VT >  // Type of the right-hand side sparse vector
testNoAliasOperation()3148 void OperationTest<MT,VT>::testNoAliasOperation()
3149 {
3150 #if BLAZETEST_MATHTEST_TEST_NOALIAS_OPERATION
3151    if( BLAZETEST_MATHTEST_TEST_NOALIAS_OPERATION > 1 )
3152    {
3153       testCustomOperation( blaze::NoAlias(), "noalias" );
3154    }
3155 #endif
3156 }
3157 //*************************************************************************************************
3158 
3159 
3160 //*************************************************************************************************
3161 /*!\brief Testing the non-SIMD sparse matrix/sparse vector multiplication.
3162 //
3163 // \return void
3164 // \exception std::runtime_error Multiplication error detected.
3165 //
3166 // This function tests the non-SIMD matrix/vector multiplication with plain assignment, addition
3167 // assignment, subtraction assignment, and multiplication assignment. In case any error resulting
3168 // from the multiplication or the subsequent assignment is detected, a \a std::runtime_error
3169 // exception is thrown.
3170 */
3171 template< typename MT    // Type of the left-hand side sparse matrix
3172         , typename VT >  // Type of the right-hand side sparse vector
testNoSIMDOperation()3173 void OperationTest<MT,VT>::testNoSIMDOperation()
3174 {
3175 #if BLAZETEST_MATHTEST_TEST_NOSIMD_OPERATION
3176    if( BLAZETEST_MATHTEST_TEST_NOSIMD_OPERATION > 1 )
3177    {
3178       testCustomOperation( blaze::NoSIMD(), "nosimd" );
3179    }
3180 #endif
3181 }
3182 //*************************************************************************************************
3183 
3184 
3185 //*************************************************************************************************
3186 /*!\brief Testing the subvector-wise sparse matrix/sparse vector multiplication.
3187 //
3188 // \return void
3189 // \exception std::runtime_error Multiplication error detected.
3190 //
3191 // This function tests the subvector-wise matrix/vector multiplication with plain assignment,
3192 // addition assignment, subtraction assignment, and multiplication assignment. In case any
3193 // error resulting from the multiplication or the subsequent assignment is detected, a
3194 // \a std::runtime_error exception is thrown.
3195 */
3196 template< typename MT    // Type of the left-hand side sparse matrix
3197         , typename VT >  // Type of the right-hand side sparse vector
testSubvectorOperation()3198 void OperationTest<MT,VT>::testSubvectorOperation()
3199 {
3200 #if BLAZETEST_MATHTEST_TEST_SUBVECTOR_OPERATION
3201    if( BLAZETEST_MATHTEST_TEST_SUBVECTOR_OPERATION > 1 )
3202    {
3203       if( lhs_.rows() == 0UL )
3204          return;
3205 
3206 
3207       //=====================================================================================
3208       // Subvector-wise multiplication
3209       //=====================================================================================
3210 
3211       // Subvector-wise multiplication with the given matrix/vector
3212       {
3213          test_  = "Subvector-wise multiplication with the given matrix/vector";
3214          error_ = "Failed multiplication operation";
3215 
3216          try {
3217             initResults();
3218             for( size_t index=0UL, size=0UL; index<lhs_.rows(); index+=size ) {
3219                size = blaze::rand<size_t>( 1UL, lhs_.rows() - index );
3220                subvector( dres_  , index, size ) = subvector( lhs_ * rhs_      , index, size );
3221                subvector( sres_  , index, size ) = subvector( lhs_ * rhs_      , index, size );
3222                subvector( refres_, index, size ) = subvector( reflhs_ * refrhs_, index, size );
3223             }
3224          }
3225          catch( std::exception& ex ) {
3226             convertException<MT>( ex );
3227          }
3228 
3229          checkResults<MT>();
3230 
3231          try {
3232             initResults();
3233             for( size_t index=0UL, size=0UL; index<olhs_.rows(); index+=size ) {
3234                size = blaze::rand<size_t>( 1UL, olhs_.rows() - index );
3235                subvector( dres_  , index, size ) = subvector( olhs_ * rhs_     , index, size );
3236                subvector( sres_  , index, size ) = subvector( olhs_ * rhs_     , index, size );
3237                subvector( refres_, index, size ) = subvector( reflhs_ * refrhs_, index, size );
3238             }
3239          }
3240          catch( std::exception& ex ) {
3241             convertException<TMT>( ex );
3242          }
3243 
3244          checkResults<TMT>();
3245       }
3246 
3247       // Subvector-wise multiplication with evaluated matrix/vector
3248       {
3249          test_  = "Subvector-wise multiplication with evaluated matrix/vector";
3250          error_ = "Failed multiplication operation";
3251 
3252          try {
3253             initResults();
3254             for( size_t index=0UL, size=0UL; index<lhs_.rows(); index+=size ) {
3255                size = blaze::rand<size_t>( 1UL, lhs_.rows() - index );
3256                subvector( dres_  , index, size ) = subvector( eval( lhs_ ) * eval( rhs_ )      , index, size );
3257                subvector( sres_  , index, size ) = subvector( eval( lhs_ ) * eval( rhs_ )      , index, size );
3258                subvector( refres_, index, size ) = subvector( eval( reflhs_ ) * eval( refrhs_ ), index, size );
3259             }
3260          }
3261          catch( std::exception& ex ) {
3262             convertException<MT>( ex );
3263          }
3264 
3265          checkResults<MT>();
3266 
3267          try {
3268             initResults();
3269             for( size_t index=0UL, size=0UL; index<olhs_.rows(); index+=size ) {
3270                size = blaze::rand<size_t>( 1UL, olhs_.rows() - index );
3271                subvector( dres_  , index, size ) = subvector( eval( olhs_ ) * eval( rhs_ )     , index, size );
3272                subvector( sres_  , index, size ) = subvector( eval( olhs_ ) * eval( rhs_ )     , index, size );
3273                subvector( refres_, index, size ) = subvector( eval( reflhs_ ) * eval( refrhs_ ), index, size );
3274             }
3275          }
3276          catch( std::exception& ex ) {
3277             convertException<TMT>( ex );
3278          }
3279 
3280          checkResults<TMT>();
3281       }
3282 
3283 
3284       //=====================================================================================
3285       // Subvector-wise multiplication with addition assignment
3286       //=====================================================================================
3287 
3288       // Subvector-wise multiplication with addition assignment with the given matrix/vector
3289       {
3290          test_  = "Subvector-wise multiplication with addition assignment the given matrix/vector";
3291          error_ = "Failed addition assignment operation";
3292 
3293          try {
3294             initResults();
3295             for( size_t index=0UL, size=0UL; index<lhs_.rows(); index+=size ) {
3296                size = blaze::rand<size_t>( 1UL, lhs_.rows() - index );
3297                subvector( dres_  , index, size ) += subvector( lhs_ * rhs_      , index, size );
3298                subvector( sres_  , index, size ) += subvector( lhs_ * rhs_      , index, size );
3299                subvector( refres_, index, size ) += subvector( reflhs_ * refrhs_, index, size );
3300             }
3301          }
3302          catch( std::exception& ex ) {
3303             convertException<MT>( ex );
3304          }
3305 
3306          checkResults<MT>();
3307 
3308          try {
3309             initResults();
3310             for( size_t index=0UL, size=0UL; index<olhs_.rows(); index+=size ) {
3311                size = blaze::rand<size_t>( 1UL, olhs_.rows() - index );
3312                subvector( dres_  , index, size ) += subvector( olhs_ * rhs_     , index, size );
3313                subvector( sres_  , index, size ) += subvector( olhs_ * rhs_     , index, size );
3314                subvector( refres_, index, size ) += subvector( reflhs_ * refrhs_, index, size );
3315             }
3316          }
3317          catch( std::exception& ex ) {
3318             convertException<TMT>( ex );
3319          }
3320 
3321          checkResults<TMT>();
3322       }
3323 
3324       // Subvector-wise multiplication with addition assignment with evaluated matrix/vector
3325       {
3326          test_  = "Subvector-wise multiplication with addition assignment with evaluated matrix/vector";
3327          error_ = "Failed addition assignment operation";
3328 
3329          try {
3330             initResults();
3331             for( size_t index=0UL, size=0UL; index<lhs_.rows(); index+=size ) {
3332                size = blaze::rand<size_t>( 1UL, lhs_.rows() - index );
3333                subvector( dres_  , index, size ) += subvector( eval( lhs_ ) * eval( rhs_ )      , index, size );
3334                subvector( sres_  , index, size ) += subvector( eval( lhs_ ) * eval( rhs_ )      , index, size );
3335                subvector( refres_, index, size ) += subvector( eval( reflhs_ ) * eval( refrhs_ ), index, size );
3336             }
3337          }
3338          catch( std::exception& ex ) {
3339             convertException<MT>( ex );
3340          }
3341 
3342          checkResults<MT>();
3343 
3344          try {
3345             initResults();
3346             for( size_t index=0UL, size=0UL; index<olhs_.rows(); index+=size ) {
3347                size = blaze::rand<size_t>( 1UL, olhs_.rows() - index );
3348                subvector( dres_  , index, size ) += subvector( eval( olhs_ ) * eval( rhs_ )     , index, size );
3349                subvector( sres_  , index, size ) += subvector( eval( olhs_ ) * eval( rhs_ )     , index, size );
3350                subvector( refres_, index, size ) += subvector( eval( reflhs_ ) * eval( refrhs_ ), index, size );
3351             }
3352          }
3353          catch( std::exception& ex ) {
3354             convertException<TMT>( ex );
3355          }
3356 
3357          checkResults<TMT>();
3358       }
3359 
3360 
3361       //=====================================================================================
3362       // Subvector-wise multiplication with subtraction assignment
3363       //=====================================================================================
3364 
3365       // Subvector-wise multiplication with addition assignment with the given matrix/vector
3366       {
3367          test_  = "Subvector-wise multiplication with subtraction assignment the given matrix/vector";
3368          error_ = "Failed subtraction assignment operation";
3369 
3370          try {
3371             initResults();
3372             for( size_t index=0UL, size=0UL; index<lhs_.rows(); index+=size ) {
3373                size = blaze::rand<size_t>( 1UL, lhs_.rows() - index );
3374                subvector( dres_  , index, size ) -= subvector( lhs_ * rhs_      , index, size );
3375                subvector( sres_  , index, size ) -= subvector( lhs_ * rhs_      , index, size );
3376                subvector( refres_, index, size ) -= subvector( reflhs_ * refrhs_, index, size );
3377             }
3378          }
3379          catch( std::exception& ex ) {
3380             convertException<MT>( ex );
3381          }
3382 
3383          checkResults<MT>();
3384 
3385          try {
3386             initResults();
3387             for( size_t index=0UL, size=0UL; index<olhs_.rows(); index+=size ) {
3388                size = blaze::rand<size_t>( 1UL, olhs_.rows() - index );
3389                subvector( dres_  , index, size ) -= subvector( olhs_ * rhs_     , index, size );
3390                subvector( sres_  , index, size ) -= subvector( olhs_ * rhs_     , index, size );
3391                subvector( refres_, index, size ) -= subvector( reflhs_ * refrhs_, index, size );
3392             }
3393          }
3394          catch( std::exception& ex ) {
3395             convertException<TMT>( ex );
3396          }
3397 
3398          checkResults<TMT>();
3399       }
3400 
3401       // Subvector-wise multiplication with subtraction assignment with evaluated matrix/vector
3402       {
3403          test_  = "Subvector-wise multiplication with subtraction assignment with evaluated matrix/vector";
3404          error_ = "Failed subtraction assignment operation";
3405 
3406          try {
3407             initResults();
3408             for( size_t index=0UL, size=0UL; index<lhs_.rows(); index+=size ) {
3409                size = blaze::rand<size_t>( 1UL, lhs_.rows() - index );
3410                subvector( dres_  , index, size ) -= subvector( eval( lhs_ ) * eval( rhs_ )      , index, size );
3411                subvector( sres_  , index, size ) -= subvector( eval( lhs_ ) * eval( rhs_ )      , index, size );
3412                subvector( refres_, index, size ) -= subvector( eval( reflhs_ ) * eval( refrhs_ ), index, size );
3413             }
3414          }
3415          catch( std::exception& ex ) {
3416             convertException<MT>( ex );
3417          }
3418 
3419          checkResults<MT>();
3420 
3421          try {
3422             initResults();
3423             for( size_t index=0UL, size=0UL; index<olhs_.rows(); index+=size ) {
3424                size = blaze::rand<size_t>( 1UL, olhs_.rows() - index );
3425                subvector( dres_  , index, size ) -= subvector( eval( olhs_ ) * eval( rhs_ )     , index, size );
3426                subvector( sres_  , index, size ) -= subvector( eval( olhs_ ) * eval( rhs_ )     , index, size );
3427                subvector( refres_, index, size ) -= subvector( eval( reflhs_ ) * eval( refrhs_ ), index, size );
3428             }
3429          }
3430          catch( std::exception& ex ) {
3431             convertException<TMT>( ex );
3432          }
3433 
3434          checkResults<TMT>();
3435       }
3436 
3437 
3438       //=====================================================================================
3439       // Subvector-wise multiplication with multiplication assignment
3440       //=====================================================================================
3441 
3442       // Subvector-wise multiplication with addition assignment with the given matrix/vector
3443       {
3444          test_  = "Subvector-wise multiplication with multiplication assignment the given matrix/vector";
3445          error_ = "Failed multiplication assignment operation";
3446 
3447          try {
3448             initResults();
3449             for( size_t index=0UL, size=0UL; index<lhs_.rows(); index+=size ) {
3450                size = blaze::rand<size_t>( 1UL, lhs_.rows() - index );
3451                subvector( dres_  , index, size ) *= subvector( lhs_ * rhs_      , index, size );
3452                subvector( sres_  , index, size ) *= subvector( lhs_ * rhs_      , index, size );
3453                subvector( refres_, index, size ) *= subvector( reflhs_ * refrhs_, index, size );
3454             }
3455          }
3456          catch( std::exception& ex ) {
3457             convertException<MT>( ex );
3458          }
3459 
3460          checkResults<MT>();
3461 
3462          try {
3463             initResults();
3464             for( size_t index=0UL, size=0UL; index<olhs_.rows(); index+=size ) {
3465                size = blaze::rand<size_t>( 1UL, olhs_.rows() - index );
3466                subvector( dres_  , index, size ) *= subvector( olhs_ * rhs_     , index, size );
3467                subvector( sres_  , index, size ) *= subvector( olhs_ * rhs_     , index, size );
3468                subvector( refres_, index, size ) *= subvector( reflhs_ * refrhs_, index, size );
3469             }
3470          }
3471          catch( std::exception& ex ) {
3472             convertException<TMT>( ex );
3473          }
3474 
3475          checkResults<TMT>();
3476       }
3477 
3478       // Subvector-wise multiplication with multiplication assignment with evaluated matrix/vector
3479       {
3480          test_  = "Subvector-wise multiplication with multiplication assignment with evaluated matrix/vector";
3481          error_ = "Failed multiplication assignment operation";
3482 
3483          try {
3484             initResults();
3485             for( size_t index=0UL, size=0UL; index<lhs_.rows(); index+=size ) {
3486                size = blaze::rand<size_t>( 1UL, lhs_.rows() - index );
3487                subvector( dres_  , index, size ) *= subvector( eval( lhs_ ) * eval( rhs_ )      , index, size );
3488                subvector( sres_  , index, size ) *= subvector( eval( lhs_ ) * eval( rhs_ )      , index, size );
3489                subvector( refres_, index, size ) *= subvector( eval( reflhs_ ) * eval( refrhs_ ), index, size );
3490             }
3491          }
3492          catch( std::exception& ex ) {
3493             convertException<MT>( ex );
3494          }
3495 
3496          checkResults<MT>();
3497 
3498          try {
3499             initResults();
3500             for( size_t index=0UL, size=0UL; index<olhs_.rows(); index+=size ) {
3501                size = blaze::rand<size_t>( 1UL, olhs_.rows() - index );
3502                subvector( dres_  , index, size ) *= subvector( eval( olhs_ ) * eval( rhs_ )     , index, size );
3503                subvector( sres_  , index, size ) *= subvector( eval( olhs_ ) * eval( rhs_ )     , index, size );
3504                subvector( refres_, index, size ) *= subvector( eval( reflhs_ ) * eval( refrhs_ ), index, size );
3505             }
3506          }
3507          catch( std::exception& ex ) {
3508             convertException<TMT>( ex );
3509          }
3510 
3511          checkResults<TMT>();
3512       }
3513 
3514 
3515       //=====================================================================================
3516       // Failure cases
3517       //=====================================================================================
3518 
3519       try {
3520          auto sv = subvector( lhs_ * rhs_, 1UL, lhs_.rows() );
3521 
3522          std::ostringstream oss;
3523          oss << " Test: Subvector construction\n"
3524              << " Error: Setup of out-of-bounds subvector succeeded\n"
3525              << " Details:\n"
3526              << "   Random seed = " << blaze::getSeed() << "\n"
3527              << "   Left-hand side sparse matrix type:\n"
3528              << "     " << typeid( MT ).name() << "\n"
3529              << "   Right-hand side sparse vector type:\n"
3530              << "     " << typeid( VT ).name() << "\n"
3531              << "   Result:\n" << sv << "\n";
3532          throw std::runtime_error( oss.str() );
3533       }
3534       catch( std::invalid_argument& ex )
3535       {
3536          if( std::strcmp( ex.what(), "Invalid subvector specification" ) != 0 ) {
3537             std::ostringstream oss;
3538             oss << " Test: Subvector construction\n"
3539                 << " Error: Wrong error message\n"
3540                 << " Details:\n"
3541                 << "   Error message: \"" << ex.what() << "\"\n"
3542                 << "   Expected error message: \"Invalid subvector specification\"\n";
3543             throw std::runtime_error( oss.str() );
3544          }
3545       }
3546 
3547       try {
3548          auto sv = subvector( lhs_ * rhs_, lhs_.rows(), 1UL );
3549 
3550          std::ostringstream oss;
3551          oss << " Test: Subvector construction\n"
3552              << " Error: Setup of out-of-bounds subvector succeeded\n"
3553              << " Details:\n"
3554              << "   Random seed = " << blaze::getSeed() << "\n"
3555              << "   Left-hand side sparse matrix type:\n"
3556              << "     " << typeid( MT ).name() << "\n"
3557              << "   Right-hand side sparse vector type:\n"
3558              << "     " << typeid( VT ).name() << "\n"
3559              << "   Result:\n" << sv << "\n";
3560          throw std::runtime_error( oss.str() );
3561       }
3562       catch( std::invalid_argument& ex )
3563       {
3564          if( std::strcmp( ex.what(), "Invalid subvector specification" ) != 0 ) {
3565             std::ostringstream oss;
3566             oss << " Test: Subvector construction\n"
3567                 << " Error: Wrong error message\n"
3568                 << " Details:\n"
3569                 << "   Error message: \"" << ex.what() << "\"\n"
3570                 << "   Expected error message: \"Invalid subvector specification\"\n";
3571             throw std::runtime_error( oss.str() );
3572          }
3573       }
3574    }
3575 #endif
3576 }
3577 //*************************************************************************************************
3578 
3579 
3580 //*************************************************************************************************
3581 /*!\brief Testing the elements-wise sparse matrix/sparse vector multiplication.
3582 //
3583 // \return void
3584 // \exception std::runtime_error Multiplication error detected.
3585 //
3586 // This function tests the elements-wise matrix/vector multiplication with plain assignment,
3587 // addition assignment, subtraction assignment, multiplication assignment, and division
3588 // assignment. In case any error resulting from the multiplication or the subsequent
3589 // assignment is detected, a \a std::runtime_error exception is thrown.
3590 */
3591 template< typename MT    // Type of the left-hand side sparse matrix
3592         , typename VT >  // Type of the right-hand side sparse vector
testElementsOperation()3593 void OperationTest<MT,VT>::testElementsOperation()
3594 {
3595 #if BLAZETEST_MATHTEST_TEST_ELEMENTS_OPERATION
3596    if( BLAZETEST_MATHTEST_TEST_ELEMENTS_OPERATION > 1 )
3597    {
3598       if( lhs_.rows() == 0UL )
3599          return;
3600 
3601 
3602       std::vector<size_t> indices( lhs_.rows() );
3603       std::iota( indices.begin(), indices.end(), 0UL );
3604       std::random_shuffle( indices.begin(), indices.end() );
3605 
3606 
3607       //=====================================================================================
3608       // Elements-wise multiplication
3609       //=====================================================================================
3610 
3611       // Elements-wise multiplication with the given matrix/vector
3612       {
3613          test_  = "Elements-wise multiplication with the given matrix/vector";
3614          error_ = "Failed multiplication operation";
3615 
3616          try {
3617             initResults();
3618             for( size_t index=0UL, n=0UL; index<indices.size(); index+=n ) {
3619                n = blaze::rand<size_t>( 1UL, indices.size() - index );
3620                elements( dres_  , &indices[index], n ) = elements( lhs_ * rhs_      , &indices[index], n );
3621                elements( sres_  , &indices[index], n ) = elements( lhs_ * rhs_      , &indices[index], n );
3622                elements( refres_, &indices[index], n ) = elements( reflhs_ * refrhs_, &indices[index], n );
3623             }
3624          }
3625          catch( std::exception& ex ) {
3626             convertException<MT>( ex );
3627          }
3628 
3629          checkResults<MT>();
3630 
3631          try {
3632             initResults();
3633             for( size_t index=0UL, n=0UL; index<indices.size(); index+=n ) {
3634                n = blaze::rand<size_t>( 1UL, indices.size() - index );
3635                elements( dres_  , &indices[index], n ) = elements( olhs_ * rhs_     , &indices[index], n );
3636                elements( sres_  , &indices[index], n ) = elements( olhs_ * rhs_     , &indices[index], n );
3637                elements( refres_, &indices[index], n ) = elements( reflhs_ * refrhs_, &indices[index], n );
3638             }
3639          }
3640          catch( std::exception& ex ) {
3641             convertException<TMT>( ex );
3642          }
3643 
3644          checkResults<TMT>();
3645       }
3646 
3647       // Elements-wise multiplication with evaluated matrix/vector
3648       {
3649          test_  = "Elements-wise multiplication with evaluated matrix/vector";
3650          error_ = "Failed multiplication operation";
3651 
3652          try {
3653             initResults();
3654             for( size_t index=0UL, n=0UL; index<indices.size(); index+=n ) {
3655                n = blaze::rand<size_t>( 1UL, indices.size() - index );
3656                elements( dres_  , &indices[index], n ) = elements( eval( lhs_ ) * eval( rhs_ )      , &indices[index], n );
3657                elements( sres_  , &indices[index], n ) = elements( eval( lhs_ ) * eval( rhs_ )      , &indices[index], n );
3658                elements( refres_, &indices[index], n ) = elements( eval( reflhs_ ) * eval( refrhs_ ), &indices[index], n );
3659             }
3660          }
3661          catch( std::exception& ex ) {
3662             convertException<MT>( ex );
3663          }
3664 
3665          checkResults<MT>();
3666 
3667          try {
3668             initResults();
3669             for( size_t index=0UL, n=0UL; index<indices.size(); index+=n ) {
3670                n = blaze::rand<size_t>( 1UL, indices.size() - index );
3671                elements( dres_  , &indices[index], n ) = elements( eval( olhs_ ) * eval( rhs_ )     , &indices[index], n );
3672                elements( sres_  , &indices[index], n ) = elements( eval( olhs_ ) * eval( rhs_ )     , &indices[index], n );
3673                elements( refres_, &indices[index], n ) = elements( eval( reflhs_ ) * eval( refrhs_ ), &indices[index], n );
3674             }
3675          }
3676          catch( std::exception& ex ) {
3677             convertException<TMT>( ex );
3678          }
3679 
3680          checkResults<TMT>();
3681       }
3682 
3683 
3684       //=====================================================================================
3685       // Elements-wise multiplication with addition assignment
3686       //=====================================================================================
3687 
3688       // Elements-wise multiplication with addition assignment with the given matrix/vector
3689       {
3690          test_  = "Elements-wise multiplication with addition assignment the given matrix/vector";
3691          error_ = "Failed addition assignment operation";
3692 
3693          try {
3694             initResults();
3695             for( size_t index=0UL, n=0UL; index<indices.size(); index+=n ) {
3696                n = blaze::rand<size_t>( 1UL, indices.size() - index );
3697                elements( dres_  , &indices[index], n ) += elements( lhs_ * rhs_      , &indices[index], n );
3698                elements( sres_  , &indices[index], n ) += elements( lhs_ * rhs_      , &indices[index], n );
3699                elements( refres_, &indices[index], n ) += elements( reflhs_ * refrhs_, &indices[index], n );
3700             }
3701          }
3702          catch( std::exception& ex ) {
3703             convertException<MT>( ex );
3704          }
3705 
3706          checkResults<MT>();
3707 
3708          try {
3709             initResults();
3710             for( size_t index=0UL, n=0UL; index<indices.size(); index+=n ) {
3711                n = blaze::rand<size_t>( 1UL, indices.size() - index );
3712                elements( dres_  , &indices[index], n ) += elements( olhs_ * rhs_     , &indices[index], n );
3713                elements( sres_  , &indices[index], n ) += elements( olhs_ * rhs_     , &indices[index], n );
3714                elements( refres_, &indices[index], n ) += elements( reflhs_ * refrhs_, &indices[index], n );
3715             }
3716          }
3717          catch( std::exception& ex ) {
3718             convertException<TMT>( ex );
3719          }
3720 
3721          checkResults<TMT>();
3722       }
3723 
3724       // Elements-wise multiplication with addition assignment with evaluated matrix/vector
3725       {
3726          test_  = "Elements-wise multiplication with addition assignment with evaluated matrix/vector";
3727          error_ = "Failed addition assignment operation";
3728 
3729          try {
3730             initResults();
3731             for( size_t index=0UL, n=0UL; index<indices.size(); index+=n ) {
3732                n = blaze::rand<size_t>( 1UL, indices.size() - index );
3733                elements( dres_  , &indices[index], n ) += elements( eval( lhs_ ) * eval( rhs_ )      , &indices[index], n );
3734                elements( sres_  , &indices[index], n ) += elements( eval( lhs_ ) * eval( rhs_ )      , &indices[index], n );
3735                elements( refres_, &indices[index], n ) += elements( eval( reflhs_ ) * eval( refrhs_ ), &indices[index], n );
3736             }
3737          }
3738          catch( std::exception& ex ) {
3739             convertException<MT>( ex );
3740          }
3741 
3742          checkResults<MT>();
3743 
3744          try {
3745             initResults();
3746             for( size_t index=0UL, n=0UL; index<indices.size(); index+=n ) {
3747                n = blaze::rand<size_t>( 1UL, indices.size() - index );
3748                elements( dres_  , &indices[index], n ) += elements( eval( olhs_ ) * eval( rhs_ )     , &indices[index], n );
3749                elements( sres_  , &indices[index], n ) += elements( eval( olhs_ ) * eval( rhs_ )     , &indices[index], n );
3750                elements( refres_, &indices[index], n ) += elements( eval( reflhs_ ) * eval( refrhs_ ), &indices[index], n );
3751             }
3752          }
3753          catch( std::exception& ex ) {
3754             convertException<TMT>( ex );
3755          }
3756 
3757          checkResults<TMT>();
3758       }
3759 
3760 
3761       //=====================================================================================
3762       // Elements-wise multiplication with subtraction assignment
3763       //=====================================================================================
3764 
3765       // Elements-wise multiplication with subtraction assignment with the given matrix/vector
3766       {
3767          test_  = "Elements-wise multiplication with subtraction assignment the given matrix/vector";
3768          error_ = "Failed subtraction assignment operation";
3769 
3770          try {
3771             initResults();
3772             for( size_t index=0UL, n=0UL; index<indices.size(); index+=n ) {
3773                n = blaze::rand<size_t>( 1UL, indices.size() - index );
3774                elements( dres_  , &indices[index], n ) -= elements( lhs_ * rhs_      , &indices[index], n );
3775                elements( sres_  , &indices[index], n ) -= elements( lhs_ * rhs_      , &indices[index], n );
3776                elements( refres_, &indices[index], n ) -= elements( reflhs_ * refrhs_, &indices[index], n );
3777             }
3778          }
3779          catch( std::exception& ex ) {
3780             convertException<MT>( ex );
3781          }
3782 
3783          checkResults<MT>();
3784 
3785          try {
3786             initResults();
3787             for( size_t index=0UL, n=0UL; index<indices.size(); index+=n ) {
3788                n = blaze::rand<size_t>( 1UL, indices.size() - index );
3789                elements( dres_  , &indices[index], n ) -= elements( olhs_ * rhs_     , &indices[index], n );
3790                elements( sres_  , &indices[index], n ) -= elements( olhs_ * rhs_     , &indices[index], n );
3791                elements( refres_, &indices[index], n ) -= elements( reflhs_ * refrhs_, &indices[index], n );
3792             }
3793          }
3794          catch( std::exception& ex ) {
3795             convertException<TMT>( ex );
3796          }
3797 
3798          checkResults<TMT>();
3799       }
3800 
3801       // Elements-wise multiplication with subtraction assignment with evaluated matrix/vector
3802       {
3803          test_  = "Elements-wise multiplication with subtraction assignment with evaluated matrix/vector";
3804          error_ = "Failed subtraction assignment operation";
3805 
3806          try {
3807             initResults();
3808             for( size_t index=0UL, n=0UL; index<indices.size(); index+=n ) {
3809                n = blaze::rand<size_t>( 1UL, indices.size() - index );
3810                elements( dres_  , &indices[index], n ) -= elements( eval( lhs_ ) * eval( rhs_ )      , &indices[index], n );
3811                elements( sres_  , &indices[index], n ) -= elements( eval( lhs_ ) * eval( rhs_ )      , &indices[index], n );
3812                elements( refres_, &indices[index], n ) -= elements( eval( reflhs_ ) * eval( refrhs_ ), &indices[index], n );
3813             }
3814          }
3815          catch( std::exception& ex ) {
3816             convertException<MT>( ex );
3817          }
3818 
3819          checkResults<MT>();
3820 
3821          try {
3822             initResults();
3823             for( size_t index=0UL, n=0UL; index<indices.size(); index+=n ) {
3824                n = blaze::rand<size_t>( 1UL, indices.size() - index );
3825                elements( dres_  , &indices[index], n ) -= elements( eval( olhs_ ) * eval( rhs_ )     , &indices[index], n );
3826                elements( sres_  , &indices[index], n ) -= elements( eval( olhs_ ) * eval( rhs_ )     , &indices[index], n );
3827                elements( refres_, &indices[index], n ) -= elements( eval( reflhs_ ) * eval( refrhs_ ), &indices[index], n );
3828             }
3829          }
3830          catch( std::exception& ex ) {
3831             convertException<TMT>( ex );
3832          }
3833 
3834          checkResults<TMT>();
3835       }
3836 
3837 
3838       //=====================================================================================
3839       // Elements-wise multiplication with multiplication assignment
3840       //=====================================================================================
3841 
3842       // Elements-wise multiplication with multiplication assignment with the given matrix/vector
3843       {
3844          test_  = "Elements-wise multiplication with multiplication assignment the given matrix/vector";
3845          error_ = "Failed multiplication assignment operation";
3846 
3847          try {
3848             initResults();
3849             for( size_t index=0UL, n=0UL; index<indices.size(); index+=n ) {
3850                n = blaze::rand<size_t>( 1UL, indices.size() - index );
3851                elements( dres_  , &indices[index], n ) *= elements( lhs_ * rhs_      , &indices[index], n );
3852                elements( sres_  , &indices[index], n ) *= elements( lhs_ * rhs_      , &indices[index], n );
3853                elements( refres_, &indices[index], n ) *= elements( reflhs_ * refrhs_, &indices[index], n );
3854             }
3855          }
3856          catch( std::exception& ex ) {
3857             convertException<MT>( ex );
3858          }
3859 
3860          checkResults<MT>();
3861 
3862          try {
3863             initResults();
3864             for( size_t index=0UL, n=0UL; index<indices.size(); index+=n ) {
3865                n = blaze::rand<size_t>( 1UL, indices.size() - index );
3866                elements( dres_  , &indices[index], n ) *= elements( olhs_ * rhs_     , &indices[index], n );
3867                elements( sres_  , &indices[index], n ) *= elements( olhs_ * rhs_     , &indices[index], n );
3868                elements( refres_, &indices[index], n ) *= elements( reflhs_ * refrhs_, &indices[index], n );
3869             }
3870          }
3871          catch( std::exception& ex ) {
3872             convertException<TMT>( ex );
3873          }
3874 
3875          checkResults<TMT>();
3876       }
3877 
3878       // Elements-wise multiplication with multiplication assignment with evaluated matrix/vector
3879       {
3880          test_  = "Elements-wise multiplication with multiplication assignment with evaluated matrix/vector";
3881          error_ = "Failed multiplication assignment operation";
3882 
3883          try {
3884             initResults();
3885             for( size_t index=0UL, n=0UL; index<indices.size(); index+=n ) {
3886                n = blaze::rand<size_t>( 1UL, indices.size() - index );
3887                elements( dres_  , &indices[index], n ) *= elements( eval( lhs_ ) * eval( rhs_ )      , &indices[index], n );
3888                elements( sres_  , &indices[index], n ) *= elements( eval( lhs_ ) * eval( rhs_ )      , &indices[index], n );
3889                elements( refres_, &indices[index], n ) *= elements( eval( reflhs_ ) * eval( refrhs_ ), &indices[index], n );
3890             }
3891          }
3892          catch( std::exception& ex ) {
3893             convertException<MT>( ex );
3894          }
3895 
3896          checkResults<MT>();
3897 
3898          try {
3899             initResults();
3900             for( size_t index=0UL, n=0UL; index<indices.size(); index+=n ) {
3901                n = blaze::rand<size_t>( 1UL, indices.size() - index );
3902                elements( dres_  , &indices[index], n ) *= elements( eval( olhs_ ) * eval( rhs_ )     , &indices[index], n );
3903                elements( sres_  , &indices[index], n ) *= elements( eval( olhs_ ) * eval( rhs_ )     , &indices[index], n );
3904                elements( refres_, &indices[index], n ) *= elements( eval( reflhs_ ) * eval( refrhs_ ), &indices[index], n );
3905             }
3906          }
3907          catch( std::exception& ex ) {
3908             convertException<TMT>( ex );
3909          }
3910 
3911          checkResults<TMT>();
3912       }
3913 
3914 
3915       //=====================================================================================
3916       // Failure cases
3917       //=====================================================================================
3918 
3919       try {
3920          auto e = elements( lhs_ * rhs_, blaze::index_sequence<128>() );
3921 
3922          std::ostringstream oss;
3923          oss << " Test: Elements construction (index_sequence)\n"
3924              << " Error: Setup of out-of-bounds element selection succeeded\n"
3925              << " Details:\n"
3926              << "   Random seed = " << blaze::getSeed() << "\n"
3927              << "   Left-hand side sparse matrix type:\n"
3928              << "     " << typeid( MT ).name() << "\n"
3929              << "   Right-hand side sparse vector type:\n"
3930              << "     " << typeid( VT ).name() << "\n"
3931              << "   Result:\n" << e << "\n";
3932          throw std::runtime_error( oss.str() );
3933       }
3934       catch( std::invalid_argument& ex )
3935       {
3936          if( std::strcmp( ex.what(), "Invalid element access index" ) != 0 ) {
3937             std::ostringstream oss;
3938             oss << " Test: Elements construction (index_sequence)\n"
3939                 << " Error: Wrong error message\n"
3940                 << " Details:\n"
3941                 << "   Error message: \"" << ex.what() << "\"\n"
3942                 << "   Expected error message: \"Invalid element access index\"\n";
3943             throw std::runtime_error( oss.str() );
3944          }
3945       }
3946 
3947       try {
3948          auto e = elements( lhs_ * rhs_, { lhs_.rows() } );
3949 
3950          std::ostringstream oss;
3951          oss << " Test: Elements construction (initializer_list)\n"
3952              << " Error: Setup of out-of-bounds element selection succeeded\n"
3953              << " Details:\n"
3954              << "   Random seed = " << blaze::getSeed() << "\n"
3955              << "   Left-hand side sparse matrix type:\n"
3956              << "     " << typeid( MT ).name() << "\n"
3957              << "   Right-hand side sparse vector type:\n"
3958              << "     " << typeid( VT ).name() << "\n"
3959              << "   Result:\n" << e << "\n";
3960          throw std::runtime_error( oss.str() );
3961       }
3962       catch( std::invalid_argument& ex )
3963       {
3964          if( std::strcmp( ex.what(), "Invalid element access index" ) != 0 ) {
3965             std::ostringstream oss;
3966             oss << " Test: Elements construction (initializer_list)\n"
3967                 << " Error: Wrong error message\n"
3968                 << " Details:\n"
3969                 << "   Error message: \"" << ex.what() << "\"\n"
3970                 << "   Expected error message: \"Invalid element access index\"\n";
3971             throw std::runtime_error( oss.str() );
3972          }
3973       }
3974 
3975       try {
3976          auto e = elements( lhs_ * rhs_, [index=lhs_.rows()]( size_t ){ return index; }, 1UL );
3977 
3978          std::ostringstream oss;
3979          oss << " Test: Elements construction (lambda)\n"
3980              << " Error: Setup of out-of-bounds element selection succeeded\n"
3981              << " Details:\n"
3982              << "   Random seed = " << blaze::getSeed() << "\n"
3983              << "   Left-hand side sparse matrix type:\n"
3984              << "     " << typeid( MT ).name() << "\n"
3985              << "   Right-hand side sparse vector type:\n"
3986              << "     " << typeid( VT ).name() << "\n"
3987              << "   Result:\n" << e << "\n";
3988          throw std::runtime_error( oss.str() );
3989       }
3990       catch( std::invalid_argument& ex )
3991       {
3992          if( std::strcmp( ex.what(), "Invalid element access index" ) != 0 ) {
3993             std::ostringstream oss;
3994             oss << " Test: Elements construction (lambda)\n"
3995                 << " Error: Wrong error message\n"
3996                 << " Details:\n"
3997                 << "   Error message: \"" << ex.what() << "\"\n"
3998                 << "   Expected error message: \"Invalid element access index\"\n";
3999             throw std::runtime_error( oss.str() );
4000          }
4001       }
4002    }
4003 #endif
4004 }
4005 //*************************************************************************************************
4006 
4007 
4008 //*************************************************************************************************
4009 /*!\brief Testing the customized sparse matrix/sparse vector multiplication.
4010 //
4011 // \param op The custom operation to be tested.
4012 // \param name The human-readable name of the operation.
4013 // \return void
4014 // \exception std::runtime_error Multiplication error detected.
4015 //
4016 // This function tests the matrix/vector multiplication with plain assignment, addition assignment,
4017 // subtraction assignment, and multiplication assignment in combination with a custom operation.
4018 // In case any error resulting from the multiplication or the subsequent assignment is detected,
4019 // a \a std::runtime_error exception is thrown.
4020 */
4021 template< typename MT    // Type of the left-hand side sparse matrix
4022         , typename VT >  // Type of the right-hand side sparse vector
4023 template< typename OP >  // Type of the custom operation
testCustomOperation(OP op,const std::string & name)4024 void OperationTest<MT,VT>::testCustomOperation( OP op, const std::string& name )
4025 {
4026    //=====================================================================================
4027    // Customized multiplication
4028    //=====================================================================================
4029 
4030    // Customized multiplication with the given matrix/vector
4031    {
4032       test_  = "Customized multiplication with the given matrix/vector (" + name + ")";
4033       error_ = "Failed multiplication operation";
4034 
4035       try {
4036          initResults();
4037          dres_   = op( lhs_ * rhs_ );
4038          sres_   = op( lhs_ * rhs_ );
4039          refres_ = op( reflhs_ * refrhs_ );
4040       }
4041       catch( std::exception& ex ) {
4042          convertException<MT>( ex );
4043       }
4044 
4045       checkResults<MT>();
4046 
4047       try {
4048          initResults();
4049          dres_   = op( olhs_ * rhs_ );
4050          sres_   = op( olhs_ * rhs_ );
4051          refres_ = op( reflhs_ * refrhs_ );
4052       }
4053       catch( std::exception& ex ) {
4054          convertException<TMT>( ex );
4055       }
4056 
4057       checkResults<TMT>();
4058    }
4059 
4060    // Customized multiplication with evaluated matrix/vector
4061    {
4062       test_  = "Customized multiplication with evaluated matrix/vector (" + name + ")";
4063       error_ = "Failed multiplication operation";
4064 
4065       try {
4066          initResults();
4067          dres_   = op( eval( lhs_ ) * eval( rhs_ ) );
4068          sres_   = op( eval( lhs_ ) * eval( rhs_ ) );
4069          refres_ = op( eval( reflhs_ ) * eval( refrhs_ ) );
4070       }
4071       catch( std::exception& ex ) {
4072          convertException<MT>( ex );
4073       }
4074 
4075       checkResults<MT>();
4076 
4077       try {
4078          initResults();
4079          dres_   = op( eval( olhs_ ) * eval( rhs_ ) );
4080          sres_   = op( eval( olhs_ ) * eval( rhs_ ) );
4081          refres_ = op( eval( reflhs_ ) * eval( refrhs_ ) );
4082       }
4083       catch( std::exception& ex ) {
4084          convertException<TMT>( ex );
4085       }
4086 
4087       checkResults<TMT>();
4088    }
4089 
4090 
4091    //=====================================================================================
4092    // Customized multiplication with addition assignment
4093    //=====================================================================================
4094 
4095    // Customized multiplication with addition assignment with the given matrix/vector
4096    {
4097       test_  = "Customized multiplication with addition assignment with the given matrix/vector (" + name + ")";
4098       error_ = "Failed addition assignment operation";
4099 
4100       try {
4101          initResults();
4102          dres_   += op( lhs_ * rhs_ );
4103          sres_   += op( lhs_ * rhs_ );
4104          refres_ += op( reflhs_ * refrhs_ );
4105       }
4106       catch( std::exception& ex ) {
4107          convertException<MT>( ex );
4108       }
4109 
4110       checkResults<MT>();
4111 
4112       try {
4113          initResults();
4114          dres_   += op( olhs_ * rhs_ );
4115          sres_   += op( olhs_ * rhs_ );
4116          refres_ += op( reflhs_ * refrhs_ );
4117       }
4118       catch( std::exception& ex ) {
4119          convertException<TMT>( ex );
4120       }
4121 
4122       checkResults<TMT>();
4123    }
4124 
4125    // Customized multiplication with addition assignment with evaluated matrix/vector
4126    {
4127       test_  = "Customized multiplication with addition assignment with evaluated matrix/vector (" + name + ")";
4128       error_ = "Failed addition assignment operation";
4129 
4130       try {
4131          initResults();
4132          dres_   += op( eval( lhs_ ) * eval( rhs_ ) );
4133          sres_   += op( eval( lhs_ ) * eval( rhs_ ) );
4134          refres_ += op( eval( reflhs_ ) * eval( refrhs_ ) );
4135       }
4136       catch( std::exception& ex ) {
4137          convertException<MT>( ex );
4138       }
4139 
4140       checkResults<MT>();
4141 
4142       try {
4143          initResults();
4144          dres_   += op( eval( olhs_ ) * eval( rhs_ ) );
4145          sres_   += op( eval( olhs_ ) * eval( rhs_ ) );
4146          refres_ += op( eval( reflhs_ ) * eval( refrhs_ ) );
4147       }
4148       catch( std::exception& ex ) {
4149          convertException<TMT>( ex );
4150       }
4151 
4152       checkResults<TMT>();
4153    }
4154 
4155 
4156    //=====================================================================================
4157    // Customized multiplication with subtraction assignment
4158    //=====================================================================================
4159 
4160    // Customized multiplication with subtraction assignment with the given matrix/vector
4161    {
4162       test_  = "Customized multiplication with subtraction assignment with the given matrix/vector (" + name + ")";
4163       error_ = "Failed subtraction assignment operation";
4164 
4165       try {
4166          initResults();
4167          dres_   -= op( lhs_ * rhs_ );
4168          sres_   -= op( lhs_ * rhs_ );
4169          refres_ -= op( reflhs_ * refrhs_ );
4170       }
4171       catch( std::exception& ex ) {
4172          convertException<MT>( ex );
4173       }
4174 
4175       checkResults<MT>();
4176 
4177       try {
4178          initResults();
4179          dres_   -= op( olhs_ * rhs_ );
4180          sres_   -= op( olhs_ * rhs_ );
4181          refres_ -= op( reflhs_ * refrhs_ );
4182       }
4183       catch( std::exception& ex ) {
4184          convertException<TMT>( ex );
4185       }
4186 
4187       checkResults<TMT>();
4188    }
4189 
4190    // Customized multiplication with subtraction assignment with evaluated matrix/vector
4191    {
4192       test_  = "Customized multiplication with subtraction assignment with evaluated matrix/vector (" + name + ")";
4193       error_ = "Failed subtraction assignment operation";
4194 
4195       try {
4196          initResults();
4197          dres_   -= op( eval( lhs_ ) * eval( rhs_ ) );
4198          sres_   -= op( eval( lhs_ ) * eval( rhs_ ) );
4199          refres_ -= op( eval( reflhs_ ) * eval( refrhs_ ) );
4200       }
4201       catch( std::exception& ex ) {
4202          convertException<MT>( ex );
4203       }
4204 
4205       checkResults<MT>();
4206 
4207       try {
4208          initResults();
4209          dres_   -= op( eval( olhs_ ) * eval( rhs_ ) );
4210          sres_   -= op( eval( olhs_ ) * eval( rhs_ ) );
4211          refres_ -= op( eval( reflhs_ ) * eval( refrhs_ ) );
4212       }
4213       catch( std::exception& ex ) {
4214          convertException<TMT>( ex );
4215       }
4216 
4217       checkResults<TMT>();
4218    }
4219 
4220 
4221    //=====================================================================================
4222    // Customized multiplication with multiplication assignment
4223    //=====================================================================================
4224 
4225    // Customized multiplication with multiplication assignment with the given matrix/vector
4226    {
4227       test_  = "Customized multiplication with multiplication assignment with the given matrix/vector (" + name + ")";
4228       error_ = "Failed multiplication assignment operation";
4229 
4230       try {
4231          initResults();
4232          dres_   *= op( lhs_ * rhs_ );
4233          sres_   *= op( lhs_ * rhs_ );
4234          refres_ *= op( reflhs_ * refrhs_ );
4235       }
4236       catch( std::exception& ex ) {
4237          convertException<MT>( ex );
4238       }
4239 
4240       checkResults<MT>();
4241 
4242       try {
4243          initResults();
4244          dres_   *= op( olhs_ * rhs_ );
4245          sres_   *= op( olhs_ * rhs_ );
4246          refres_ *= op( reflhs_ * refrhs_ );
4247       }
4248       catch( std::exception& ex ) {
4249          convertException<TMT>( ex );
4250       }
4251 
4252       checkResults<TMT>();
4253    }
4254 
4255    // Customized multiplication with multiplication assignment with evaluated matrix/vector
4256    {
4257       test_  = "Customized multiplication with multiplication assignment with evaluated matrix/vector (" + name + ")";
4258       error_ = "Failed multiplication assignment operation";
4259 
4260       try {
4261          initResults();
4262          dres_   *= op( eval( lhs_ ) * eval( rhs_ ) );
4263          sres_   *= op( eval( lhs_ ) * eval( rhs_ ) );
4264          refres_ *= op( eval( reflhs_ ) * eval( refrhs_ ) );
4265       }
4266       catch( std::exception& ex ) {
4267          convertException<MT>( ex );
4268       }
4269 
4270       checkResults<MT>();
4271 
4272       try {
4273          initResults();
4274          dres_   *= op( eval( olhs_ ) * eval( rhs_ ) );
4275          sres_   *= op( eval( olhs_ ) * eval( rhs_ ) );
4276          refres_ *= op( eval( reflhs_ ) * eval( refrhs_ ) );
4277       }
4278       catch( std::exception& ex ) {
4279          convertException<TMT>( ex );
4280       }
4281 
4282       checkResults<TMT>();
4283    }
4284 }
4285 //*************************************************************************************************
4286 
4287 
4288 
4289 
4290 //=================================================================================================
4291 //
4292 //  ERROR DETECTION FUNCTIONS
4293 //
4294 //=================================================================================================
4295 
4296 //*************************************************************************************************
4297 /*!\brief Checking and comparing the computed results.
4298 //
4299 // \return void
4300 // \exception std::runtime_error Incorrect dense result detected.
4301 // \exception std::runtime_error Incorrect sparse result detected.
4302 //
4303 // This function is called after each test case to check and compare the computed results.
4304 // The template argument \a LT indicates the types of the left-hand side operand used for
4305 // the computations.
4306 */
4307 template< typename MT    // Type of the left-hand side sparse matrix
4308         , typename VT >  // Type of the right-hand side sparse vector
4309 template< typename LT >  // Type of the left-hand side operand
checkResults()4310 void OperationTest<MT,VT>::checkResults()
4311 {
4312    using blaze::IsRowMajorMatrix;
4313 
4314    if( !isEqual( dres_, refres_ ) ) {
4315       std::ostringstream oss;
4316       oss.precision( 20 );
4317       oss << " Test : " << test_ << "\n"
4318           << " Error: Incorrect dense result detected\n"
4319           << " Details:\n"
4320           << "   Random seed = " << blaze::getSeed() << "\n"
4321           << "   Left-hand side " << ( IsRowMajorMatrix<LT>::value ? ( "row-major" ) : ( "column-major" ) ) << " sparse matrix type:\n"
4322           << "     " << typeid( LT ).name() << "\n"
4323           << "   Right-hand side sparse vector type:\n"
4324           << "     " << typeid( VT ).name() << "\n"
4325           << "   Result:\n" << dres_ << "\n"
4326           << "   Expected result:\n" << refres_ << "\n";
4327       throw std::runtime_error( oss.str() );
4328    }
4329 
4330    if( !isEqual( sres_, refres_ ) ) {
4331       std::ostringstream oss;
4332       oss.precision( 20 );
4333       oss << " Test : " << test_ << "\n"
4334           << " Error: Incorrect sparse result detected\n"
4335           << " Details:\n"
4336           << "   Random seed = " << blaze::getSeed() << "\n"
4337           << "   Left-hand side " << ( IsRowMajorMatrix<LT>::value ? ( "row-major" ) : ( "column-major" ) ) << " sparse matrix type:\n"
4338           << "     " << typeid( LT ).name() << "\n"
4339           << "   Right-hand side sparse vector type:\n"
4340           << "     " << typeid( VT ).name() << "\n"
4341           << "   Result:\n" << sres_ << "\n"
4342           << "   Expected result:\n" << refres_ << "\n";
4343       throw std::runtime_error( oss.str() );
4344    }
4345 }
4346 //*************************************************************************************************
4347 
4348 
4349 //*************************************************************************************************
4350 /*!\brief Checking and comparing the computed transpose results.
4351 //
4352 // \return void
4353 // \exception std::runtime_error Incorrect dense result detected.
4354 // \exception std::runtime_error Incorrect sparse result detected.
4355 //
4356 // This function is called after each test case to check and compare the computed transpose
4357 // results. The template argument \a LT indicates the types of the left-hand side operand
4358 // used for the computations.
4359 */
4360 template< typename MT    // Type of the left-hand side sparse matrix
4361         , typename VT >  // Type of the right-hand side sparse vector
4362 template< typename LT >  // Type of the left-hand side operand
checkTransposeResults()4363 void OperationTest<MT,VT>::checkTransposeResults()
4364 {
4365    using blaze::IsRowMajorMatrix;
4366 
4367    if( !isEqual( tdres_, trefres_ ) ) {
4368       std::ostringstream oss;
4369       oss.precision( 20 );
4370       oss << " Test : " << test_ << "\n"
4371           << " Error: Incorrect dense result detected\n"
4372           << " Details:\n"
4373           << "   Random seed = " << blaze::getSeed() << "\n"
4374           << "   Left-hand side " << ( IsRowMajorMatrix<LT>::value ? ( "row-major" ) : ( "column-major" ) ) << " sparse matrix type:\n"
4375           << "     " << typeid( LT ).name() << "\n"
4376           << "   Right-hand side sparse vector type:\n"
4377           << "     " << typeid( VT ).name() << "\n"
4378           << "   Transpose result:\n" << tdres_ << "\n"
4379           << "   Expected transpose result:\n" << trefres_ << "\n";
4380       throw std::runtime_error( oss.str() );
4381    }
4382 
4383    if( !isEqual( tsres_, trefres_ ) ) {
4384       std::ostringstream oss;
4385       oss.precision( 20 );
4386       oss << " Test : " << test_ << "\n"
4387           << " Error: Incorrect sparse result detected\n"
4388           << " Details:\n"
4389           << "   Random seed = " << blaze::getSeed() << "\n"
4390           << "   Left-hand side " << ( IsRowMajorMatrix<LT>::value ? ( "row-major" ) : ( "column-major" ) ) << " sparse matrix type:\n"
4391           << "     " << typeid( LT ).name() << "\n"
4392           << "   Right-hand side sparse vector type:\n"
4393           << "     " << typeid( VT ).name() << "\n"
4394           << "   Transpose result:\n" << tsres_ << "\n"
4395           << "   Expected transpose result:\n" << trefres_ << "\n";
4396       throw std::runtime_error( oss.str() );
4397    }
4398 }
4399 //*************************************************************************************************
4400 
4401 
4402 
4403 
4404 //=================================================================================================
4405 //
4406 //  UTILITY FUNCTIONS
4407 //
4408 //=================================================================================================
4409 
4410 //*************************************************************************************************
4411 /*!\brief Initializing the non-transpose result vectors.
4412 //
4413 // \return void
4414 //
4415 // This function is called before each non-transpose test case to initialize the according result
4416 // vectors to random values.
4417 */
4418 template< typename MT    // Type of the left-hand side sparse matrix
4419         , typename VT >  // Type of the right-hand side sparse vector
initResults()4420 void OperationTest<MT,VT>::initResults()
4421 {
4422    const blaze::UnderlyingBuiltin_t<SRE> min( randmin );
4423    const blaze::UnderlyingBuiltin_t<SRE> max( randmax );
4424 
4425    resize( sres_, rows( lhs_ ) );
4426    randomize( sres_, min, max );
4427 
4428    dres_   = sres_;
4429    refres_ = sres_;
4430 }
4431 //*************************************************************************************************
4432 
4433 
4434 //*************************************************************************************************
4435 /*!\brief Initializing the transpose result vectors.
4436 //
4437 // \return void
4438 //
4439 // This function is called before each transpose test case to initialize the according result
4440 // vectors to random values.
4441 */
4442 template< typename MT    // Type of the left-hand side sparse matrix
4443         , typename VT >  // Type of the right-hand side sparse vector
initTransposeResults()4444 void OperationTest<MT,VT>::initTransposeResults()
4445 {
4446    const blaze::UnderlyingBuiltin_t<TSRE> min( randmin );
4447    const blaze::UnderlyingBuiltin_t<TSRE> max( randmax );
4448 
4449    resize( tsres_, rows( lhs_ ) );
4450    randomize( tsres_, min, max );
4451 
4452    tdres_   = tsres_;
4453    trefres_ = tsres_;
4454 }
4455 //*************************************************************************************************
4456 
4457 
4458 //*************************************************************************************************
4459 /*!\brief Convert the given exception into a \a std::runtime_error exception.
4460 //
4461 // \param ex The \a std::exception to be extended.
4462 // \return void
4463 // \exception std::runtime_error The converted exception.
4464 //
4465 // This function converts the given exception to a \a std::runtime_error exception. Additionally,
4466 // the function extends the given exception message by all available information for the failed
4467 // test. The template argument \a LT indicates the types of the left-hand side operand used for
4468 // used for the computations.
4469 */
4470 template< typename MT    // Type of the left-hand side sparse matrix
4471         , typename VT >  // Type of the right-hand side sparse vector
4472 template< typename LT >  // Type of the left-hand side operand
convertException(const std::exception & ex)4473 void OperationTest<MT,VT>::convertException( const std::exception& ex )
4474 {
4475    using blaze::IsRowMajorMatrix;
4476 
4477    std::ostringstream oss;
4478    oss << " Test : " << test_ << "\n"
4479        << " Error: " << error_ << "\n"
4480        << " Details:\n"
4481        << "   Random seed = " << blaze::getSeed() << "\n"
4482        << "   Left-hand side " << ( IsRowMajorMatrix<LT>::value ? ( "row-major" ) : ( "column-major" ) ) << " sparse matrix type:\n"
4483        << "     " << typeid( LT ).name() << "\n"
4484        << "   Right-hand side sparse vector type:\n"
4485        << "     " << typeid( VT ).name() << "\n"
4486        << "   Error message: " << ex.what() << "\n";
4487    throw std::runtime_error( oss.str() );
4488 }
4489 //*************************************************************************************************
4490 
4491 
4492 
4493 
4494 //=================================================================================================
4495 //
4496 //  GLOBAL TEST FUNCTIONS
4497 //
4498 //=================================================================================================
4499 
4500 //*************************************************************************************************
4501 /*!\brief Testing the matrix/vector multiplication between two specific types.
4502 //
4503 // \param creator1 The creator for the left-hand side matrix.
4504 // \param creator2 The creator for the right-hand side vector.
4505 // \return void
4506 */
4507 template< typename MT    // Type of the left-hand side sparse matrix
4508         , typename VT >  // Type of the right-hand side sparse vector
runTest(const Creator<MT> & creator1,const Creator<VT> & creator2)4509 void runTest( const Creator<MT>& creator1, const Creator<VT>& creator2 )
4510 {
4511 #if BLAZETEST_MATHTEST_TEST_MULTIPLICATION
4512    if( BLAZETEST_MATHTEST_TEST_MULTIPLICATION > 1 )
4513    {
4514       for( size_t rep=0UL; rep<BLAZETEST_REPETITIONS; ++rep ) {
4515          OperationTest<MT,VT>( creator1, creator2 );
4516       }
4517    }
4518 #endif
4519 }
4520 //*************************************************************************************************
4521 
4522 
4523 
4524 
4525 //=================================================================================================
4526 //
4527 //  MACROS
4528 //
4529 //=================================================================================================
4530 
4531 //*************************************************************************************************
4532 /*! \cond BLAZE_INTERNAL */
4533 /*!\brief Macro for the execution of a sparse matrix/sparse vector multiplication test case.
4534 */
4535 #define RUN_SMATSVECMULT_OPERATION_TEST( C1, C2 ) \
4536    blazetest::mathtest::operations::smatsvecmult::runTest( C1, C2 )
4537 /*! \endcond */
4538 //*************************************************************************************************
4539 
4540 } // namespace smatsvecmult
4541 
4542 } // namespace operations
4543 
4544 } // namespace mathtest
4545 
4546 } // namespace blazetest
4547 
4548 #endif
4549