1 //=================================================================================================
2 /*!
3 //  \file blazetest/mathtest/adaptors/uniuppermatrix/DenseTest.h
4 //  \brief Header file for the UniUpperMatrix dense 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_ADAPTORS_UNIUPPERMATRIX_DENSETEST_H_
36 #define _BLAZETEST_MATHTEST_ADAPTORS_UNIUPPERMATRIX_DENSETEST_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <sstream>
44 #include <stdexcept>
45 #include <string>
46 #include <blaze/math/constraints/ColumnMajorMatrix.h>
47 #include <blaze/math/constraints/DenseMatrix.h>
48 #include <blaze/math/constraints/RequiresEvaluation.h>
49 #include <blaze/math/constraints/RowMajorMatrix.h>
50 #include <blaze/math/constraints/UniLower.h>
51 #include <blaze/math/constraints/UniUpper.h>
52 #include <blaze/math/DynamicMatrix.h>
53 #include <blaze/math/UniUpperMatrix.h>
54 #include <blaze/math/typetraits/IsRowMajorMatrix.h>
55 #include <blaze/util/constraints/SameType.h>
56 #include <blazetest/system/Types.h>
57 
58 
59 namespace blazetest {
60 
61 namespace mathtest {
62 
63 namespace adaptors {
64 
65 namespace uniuppermatrix {
66 
67 //=================================================================================================
68 //
69 //  CLASS DEFINITION
70 //
71 //=================================================================================================
72 
73 //*************************************************************************************************
74 /*!\brief Auxiliary class for all tests of the dense UniUpperMatrix specialization.
75 //
76 // This class represents a test suite for the blaze::UniUpperMatrix class template specialization
77 // for dense matrices. It performs a series of both compile time as well as runtime tests.
78 */
79 class DenseTest
80 {
81  public:
82    //**Constructors********************************************************************************
83    /*!\name Constructors */
84    //@{
85    explicit DenseTest();
86    // No explicitly declared copy constructor.
87    //@}
88    //**********************************************************************************************
89 
90    //**Destructor**********************************************************************************
91    // No explicitly declared destructor.
92    //**********************************************************************************************
93 
94  private:
95    //**Test functions******************************************************************************
96    /*!\name Test functions */
97    //@{
98    void testConstructors();
99    void testAssignment  ();
100    void testAddAssign   ();
101    void testSubAssign   ();
102    void testSchurAssign ();
103    void testMultAssign  ();
104    void testFunctionCall();
105    void testIterator    ();
106    void testNonZeros    ();
107    void testReset       ();
108    void testClear       ();
109    void testResize      ();
110    void testExtend      ();
111    void testReserve     ();
112    void testShrinkToFit ();
113    void testSwap        ();
114    void testIsDefault   ();
115    void testSubmatrix   ();
116    void testRow         ();
117    void testColumn      ();
118 
119    template< typename Type >
120    void checkRows( const Type& matrix, size_t expectedRows ) const;
121 
122    template< typename Type >
123    void checkColumns( const Type& matrix, size_t expectedColumns ) const;
124 
125    template< typename Type >
126    void checkCapacity( const Type& matrix, size_t minCapacity ) const;
127 
128    template< typename Type >
129    void checkNonZeros( const Type& matrix, size_t expectedNonZeros ) const;
130 
131    template< typename Type >
132    void checkNonZeros( const Type& matrix, size_t index, size_t expectedNonZeros ) const;
133    //@}
134    //**********************************************************************************************
135 
136    //**Member variables****************************************************************************
137    /*!\name Member variables */
138    //@{
139    std::string test_;  //!< Label of the currently performed test.
140    //@}
141    //**********************************************************************************************
142 
143    //**Type definitions****************************************************************************
144    //! Type of the row-major uniupper matrix.
145    using UT = blaze::UniUpperMatrix< blaze::DynamicMatrix<int,blaze::rowMajor> >;
146 
147    //! Type of the column-major uniupper matrix.
148    using OUT = blaze::UniUpperMatrix< blaze::DynamicMatrix<int,blaze::columnMajor> >;
149 
150    using RUT  = UT::Rebind<double>::Other;   //!< Rebound row-major uniupper matrix type.
151    using ORUT = OUT::Rebind<double>::Other;  //!< Rebound column-major uniupper matrix type.
152    //**********************************************************************************************
153 
154    //**Compile time checks*************************************************************************
155    /*! \cond BLAZE_INTERNAL */
156    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( UT                  );
157    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( UT::ResultType      );
158    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( UT::OppositeType    );
159    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( UT::TransposeType   );
160    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( OUT                 );
161    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( OUT::ResultType     );
162    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( OUT::OppositeType   );
163    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( OUT::TransposeType  );
164    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( RUT                 );
165    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( RUT::ResultType     );
166    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( RUT::OppositeType   );
167    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( RUT::TransposeType  );
168    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( ORUT                );
169    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( ORUT::ResultType    );
170    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( ORUT::OppositeType  );
171    BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( ORUT::TransposeType );
172 
173    BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE   ( UT                  );
174    BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE   ( UT::ResultType      );
175    BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE( UT::OppositeType    );
176    BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE( UT::TransposeType   );
177    BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE( OUT                 );
178    BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE( OUT::ResultType     );
179    BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE   ( OUT::OppositeType   );
180    BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE   ( OUT::TransposeType  );
181    BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE   ( RUT                 );
182    BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE   ( RUT::ResultType     );
183    BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE( RUT::OppositeType   );
184    BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE( RUT::TransposeType  );
185    BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE( ORUT                );
186    BLAZE_CONSTRAINT_MUST_BE_COLUMN_MAJOR_MATRIX_TYPE( ORUT::ResultType    );
187    BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE   ( ORUT::OppositeType  );
188    BLAZE_CONSTRAINT_MUST_BE_ROW_MAJOR_MATRIX_TYPE   ( ORUT::TransposeType );
189 
190    BLAZE_CONSTRAINT_MUST_BE_UNIUPPER_MATRIX_TYPE( UT                  );
191    BLAZE_CONSTRAINT_MUST_BE_UNIUPPER_MATRIX_TYPE( UT::ResultType      );
192    BLAZE_CONSTRAINT_MUST_BE_UNIUPPER_MATRIX_TYPE( UT::OppositeType    );
193    BLAZE_CONSTRAINT_MUST_BE_UNILOWER_MATRIX_TYPE( UT::TransposeType   );
194    BLAZE_CONSTRAINT_MUST_BE_UNIUPPER_MATRIX_TYPE( OUT                 );
195    BLAZE_CONSTRAINT_MUST_BE_UNIUPPER_MATRIX_TYPE( OUT::ResultType     );
196    BLAZE_CONSTRAINT_MUST_BE_UNIUPPER_MATRIX_TYPE( OUT::OppositeType   );
197    BLAZE_CONSTRAINT_MUST_BE_UNILOWER_MATRIX_TYPE( OUT::TransposeType  );
198    BLAZE_CONSTRAINT_MUST_BE_UNIUPPER_MATRIX_TYPE( RUT                 );
199    BLAZE_CONSTRAINT_MUST_BE_UNIUPPER_MATRIX_TYPE( RUT::ResultType     );
200    BLAZE_CONSTRAINT_MUST_BE_UNIUPPER_MATRIX_TYPE( RUT::OppositeType   );
201    BLAZE_CONSTRAINT_MUST_BE_UNILOWER_MATRIX_TYPE( RUT::TransposeType  );
202    BLAZE_CONSTRAINT_MUST_BE_UNIUPPER_MATRIX_TYPE( ORUT                );
203    BLAZE_CONSTRAINT_MUST_BE_UNIUPPER_MATRIX_TYPE( ORUT::ResultType    );
204    BLAZE_CONSTRAINT_MUST_BE_UNIUPPER_MATRIX_TYPE( ORUT::OppositeType  );
205    BLAZE_CONSTRAINT_MUST_BE_UNILOWER_MATRIX_TYPE( ORUT::TransposeType );
206 
207    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( UT::ResultType      );
208    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( UT::OppositeType    );
209    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( UT::TransposeType   );
210    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( OUT::ResultType     );
211    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( OUT::OppositeType   );
212    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( OUT::TransposeType  );
213    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RUT::ResultType     );
214    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RUT::OppositeType   );
215    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RUT::TransposeType  );
216    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ORUT::ResultType    );
217    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ORUT::OppositeType  );
218    BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( ORUT::TransposeType );
219 
220    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( UT::ElementType,   UT::ResultType::ElementType      );
221    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( UT::ElementType,   UT::OppositeType::ElementType    );
222    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( UT::ElementType,   UT::TransposeType::ElementType   );
223    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( OUT::ElementType,  OUT::ResultType::ElementType     );
224    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( OUT::ElementType,  OUT::OppositeType::ElementType   );
225    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( OUT::ElementType,  OUT::TransposeType::ElementType  );
226    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( RUT::ElementType,  RUT::ResultType::ElementType     );
227    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( RUT::ElementType,  RUT::OppositeType::ElementType   );
228    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( RUT::ElementType,  RUT::TransposeType::ElementType  );
229    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ORUT::ElementType, ORUT::ResultType::ElementType    );
230    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ORUT::ElementType, ORUT::OppositeType::ElementType  );
231    BLAZE_CONSTRAINT_MUST_BE_SAME_TYPE( ORUT::ElementType, ORUT::TransposeType::ElementType );
232    /*! \endcond */
233    //**********************************************************************************************
234 };
235 //*************************************************************************************************
236 
237 
238 
239 
240 //=================================================================================================
241 //
242 //  TEST FUNCTIONS
243 //
244 //=================================================================================================
245 
246 //*************************************************************************************************
247 /*!\brief Checking the number of rows of the given matrix.
248 //
249 // \param matrix The matrix to be checked.
250 // \param expectedRows The expected number of rows of the matrix.
251 // \return void
252 // \exception std::runtime_error Error detected.
253 //
254 // This function checks the number of rows of the given matrix. In case the actual number of
255 // rows does not correspond to the given expected number of rows, a \a std::runtime_error
256 // exception is thrown.
257 */
258 template< typename Type >  // Type of the matrix
checkRows(const Type & matrix,size_t expectedRows)259 void DenseTest::checkRows( const Type& matrix, size_t expectedRows ) const
260 {
261    if( matrix.rows() != expectedRows ) {
262       std::ostringstream oss;
263       oss << " Test: " << test_ << "\n"
264           << " Error: Invalid number of rows detected\n"
265           << " Details:\n"
266           << "   Number of rows         : " << matrix.rows() << "\n"
267           << "   Expected number of rows: " << expectedRows << "\n";
268       throw std::runtime_error( oss.str() );
269    }
270 }
271 //*************************************************************************************************
272 
273 
274 //*************************************************************************************************
275 /*!\brief Checking the number of columns of the given matrix.
276 //
277 // \param matrix The matrix to be checked.
278 // \param expectedRows The expected number of columns of the matrix.
279 // \return void
280 // \exception std::runtime_error Error detected.
281 //
282 // This function checks the number of columns of the given matrix. In case the actual number of
283 // columns does not correspond to the given expected number of columns, a \a std::runtime_error
284 // exception is thrown.
285 */
286 template< typename Type >  // Type of the matrix
checkColumns(const Type & matrix,size_t expectedColumns)287 void DenseTest::checkColumns( const Type& matrix, size_t expectedColumns ) const
288 {
289    if( matrix.columns() != expectedColumns ) {
290       std::ostringstream oss;
291       oss << " Test: " << test_ << "\n"
292           << " Error: Invalid number of columns detected\n"
293           << " Details:\n"
294           << "   Number of columns         : " << matrix.columns() << "\n"
295           << "   Expected number of columns: " << expectedColumns << "\n";
296       throw std::runtime_error( oss.str() );
297    }
298 }
299 //*************************************************************************************************
300 
301 
302 //*************************************************************************************************
303 /*!\brief Checking the capacity of the given matrix.
304 //
305 // \param matrix The matrix to be checked.
306 // \param minCapacity The expected minimum capacity of the matrix.
307 // \return void
308 // \exception std::runtime_error Error detected.
309 //
310 // This function checks the capacity of the given matrix. In case the actual capacity is smaller
311 // than the given expected minimum capacity, a \a std::runtime_error exception is thrown.
312 */
313 template< typename Type >  // Type of the matrix
checkCapacity(const Type & matrix,size_t minCapacity)314 void DenseTest::checkCapacity( const Type& matrix, size_t minCapacity ) const
315 {
316    if( capacity( matrix ) < minCapacity ) {
317       std::ostringstream oss;
318       oss << " Test: " << test_ << "\n"
319           << " Error: Invalid capacity detected\n"
320           << " Details:\n"
321           << "   Capacity                 : " << capacity( matrix ) << "\n"
322           << "   Expected minimum capacity: " << minCapacity << "\n";
323       throw std::runtime_error( oss.str() );
324    }
325 }
326 //*************************************************************************************************
327 
328 
329 //*************************************************************************************************
330 /*!\brief Checking the number of non-zero elements of the given matrix.
331 //
332 // \param matrix The matrix to be checked.
333 // \param expectedNonZeros The expected number of non-zero elements of the matrix.
334 // \return void
335 // \exception std::runtime_error Error detected.
336 //
337 // This function checks the number of non-zero elements of the given matrix. In case the
338 // actual number of non-zero elements does not correspond to the given expected number,
339 // a \a std::runtime_error exception is thrown.
340 */
341 template< typename Type >  // Type of the matrix
checkNonZeros(const Type & matrix,size_t expectedNonZeros)342 void DenseTest::checkNonZeros( const Type& matrix, size_t expectedNonZeros ) const
343 {
344    if( nonZeros( matrix ) != expectedNonZeros ) {
345       std::ostringstream oss;
346       oss << " Test: " << test_ << "\n"
347           << " Error: Invalid number of non-zero elements\n"
348           << " Details:\n"
349           << "   Number of non-zeros         : " << nonZeros( matrix ) << "\n"
350           << "   Expected number of non-zeros: " << expectedNonZeros << "\n";
351       throw std::runtime_error( oss.str() );
352    }
353 
354    if( capacity( matrix ) < nonZeros( matrix ) ) {
355       std::ostringstream oss;
356       oss << " Test: " << test_ << "\n"
357           << " Error: Invalid capacity detected\n"
358           << " Details:\n"
359           << "   Number of non-zeros: " << nonZeros( matrix ) << "\n"
360           << "   Capacity           : " << capacity( matrix ) << "\n";
361       throw std::runtime_error( oss.str() );
362    }
363 }
364 //*************************************************************************************************
365 
366 
367 //*************************************************************************************************
368 /*!\brief Checking the number of non-zero elements in a specific row/column of the given matrix.
369 //
370 // \param matrix The matrix to be checked.
371 // \param index The row/column to be checked.
372 // \param expectedNonZeros The expected number of non-zero elements in the specified row/column.
373 // \return void
374 // \exception std::runtime_error Error detected.
375 //
376 // This function checks the number of non-zero elements in the specified row/column of the
377 // given matrix. In case the actual number of non-zero elements does not correspond to the
378 // given expected number, a \a std::runtime_error exception is thrown.
379 */
380 template< typename Type >  // Type of the matrix
checkNonZeros(const Type & matrix,size_t index,size_t expectedNonZeros)381 void DenseTest::checkNonZeros( const Type& matrix, size_t index, size_t expectedNonZeros ) const
382 {
383    if( nonZeros( matrix, index ) != expectedNonZeros ) {
384       std::ostringstream oss;
385       oss << " Test: " << test_ << "\n"
386           << " Error: Invalid number of non-zero elements in "
387           << ( blaze::IsRowMajorMatrix<Type>::value ? "row " : "column " ) << index << "\n"
388           << " Details:\n"
389           << "   Number of non-zeros         : " << nonZeros( matrix, index ) << "\n"
390           << "   Expected number of non-zeros: " << expectedNonZeros << "\n";
391       throw std::runtime_error( oss.str() );
392    }
393 
394    if( capacity( matrix, index ) < nonZeros( matrix, index ) ) {
395       std::ostringstream oss;
396       oss << " Test: " << test_ << "\n"
397           << " Error: Invalid capacity detected in "
398           << ( blaze::IsRowMajorMatrix<Type>::value ? "row " : "column " ) << index << "\n"
399           << " Details:\n"
400           << "   Number of non-zeros: " << nonZeros( matrix, index ) << "\n"
401           << "   Capacity           : " << capacity( matrix, index ) << "\n";
402       throw std::runtime_error( oss.str() );
403    }
404 }
405 //*************************************************************************************************
406 
407 
408 
409 
410 //=================================================================================================
411 //
412 //  GLOBAL TEST FUNCTIONS
413 //
414 //=================================================================================================
415 
416 //*************************************************************************************************
417 /*!\brief Testing the functionality of the dense UniUpperMatrix specialization.
418 //
419 // \return void
420 */
runTest()421 void runTest()
422 {
423    DenseTest();
424 }
425 //*************************************************************************************************
426 
427 
428 
429 
430 //=================================================================================================
431 //
432 //  MACRO DEFINITIONS
433 //
434 //=================================================================================================
435 
436 //*************************************************************************************************
437 /*! \cond BLAZE_INTERNAL */
438 /*!\brief Macro for the execution of the UniUpperMatrix dense test.
439 */
440 #define RUN_UNIUPPERMATRIX_DENSE_TEST \
441    blazetest::mathtest::adaptors::uniuppermatrix::runTest()
442 /*! \endcond */
443 //*************************************************************************************************
444 
445 } // namespace uniuppermatrix
446 
447 } // namespace adaptors
448 
449 } // namespace mathtest
450 
451 } // namespace blazetest
452 
453 #endif
454