1 //================================================================================================= 2 /*! 3 // \file blaze/math/Submatrix.h 4 // \brief Header file for the complete Submatrix implementation 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 _BLAZE_MATH_SUBMATRIX_H_ 36 #define _BLAZE_MATH_SUBMATRIX_H_ 37 38 39 //************************************************************************************************* 40 // Includes 41 //************************************************************************************************* 42 43 #include <blaze/math/Aliases.h> 44 #include <blaze/math/constraints/DenseMatrix.h> 45 #include <blaze/math/constraints/SparseMatrix.h> 46 #include <blaze/math/constraints/Submatrix.h> 47 #include <blaze/math/Exception.h> 48 #include <blaze/math/smp/DenseMatrix.h> 49 #include <blaze/math/smp/SparseMatrix.h> 50 #include <blaze/math/views/Submatrix.h> 51 #include <blaze/math/views/Subvector.h> 52 #include <blaze/util/Random.h> 53 #include <blaze/util/typetraits/RemoveReference.h> 54 55 56 namespace blaze { 57 58 //================================================================================================= 59 // 60 // RAND SPECIALIZATION FOR DENSE SUBMATRICES 61 // 62 //================================================================================================= 63 64 //************************************************************************************************* 65 /*! \cond BLAZE_INTERNAL */ 66 /*!\brief Specialization of the Rand class template for dense submatrices. 67 // \ingroup random 68 // 69 // This specialization of the Rand class randomizes dense submatrices. 70 */ 71 template< typename MT // Type of the matrix 72 , AlignmentFlag AF // Alignment flag 73 , bool SO // Storage order 74 , size_t... CSAs > // Compile time submatrix arguments 75 class Rand< Submatrix<MT,AF,SO,true,CSAs...> > 76 { 77 public: 78 //********************************************************************************************** 79 /*!\brief Randomization of a dense submatrix. 80 // 81 // \param submatrix The submatrix to be randomized. 82 // \return void 83 */ 84 template< typename SMT > // Type of the submatrix randomize(SMT && submatrix)85 inline void randomize( SMT&& submatrix ) const 86 { 87 using blaze::randomize; 88 89 using SubmatrixType = RemoveReference_t<SMT>; 90 91 BLAZE_CONSTRAINT_MUST_BE_SUBMATRIX_TYPE( SubmatrixType ); 92 BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( SubmatrixType ); 93 94 if( SO == rowMajor ) { 95 for( size_t i=0UL; i<submatrix.rows(); ++i ) { 96 for( size_t j=0UL; j<submatrix.columns(); ++j ) { 97 randomize( submatrix(i,j) ); 98 } 99 } 100 } 101 else { 102 for( size_t j=0UL; j<submatrix.columns(); ++j ) { 103 for( size_t i=0UL; i<submatrix.rows(); ++i ) { 104 randomize( submatrix(i,j) ); 105 } 106 } 107 } 108 } 109 //********************************************************************************************** 110 111 //********************************************************************************************** 112 /*!\brief Randomization of a dense submatrix. 113 // 114 // \param submatrix The submatrix to be randomized. 115 // \param min The smallest possible value for a matrix element. 116 // \param max The largest possible value for a matrix element. 117 // \return void 118 */ 119 template< typename SMT // Type of the submatrix 120 , typename Arg > // Min/max argument type randomize(SMT && submatrix,const Arg & min,const Arg & max)121 inline void randomize( SMT&& submatrix, const Arg& min, const Arg& max ) const 122 { 123 using blaze::randomize; 124 125 using SubmatrixType = RemoveReference_t<SMT>; 126 127 BLAZE_CONSTRAINT_MUST_BE_SUBMATRIX_TYPE( SubmatrixType ); 128 BLAZE_CONSTRAINT_MUST_BE_DENSE_MATRIX_TYPE( SubmatrixType ); 129 130 if( SO == rowMajor ) { 131 for( size_t i=0UL; i<submatrix.rows(); ++i ) { 132 for( size_t j=0UL; j<submatrix.columns(); ++j ) { 133 randomize( submatrix(i,j), min, max ); 134 } 135 } 136 } 137 else { 138 for( size_t j=0UL; j<submatrix.columns(); ++j ) { 139 for( size_t i=0UL; i<submatrix.rows(); ++i ) { 140 randomize( submatrix(i,j), min, max ); 141 } 142 } 143 } 144 } 145 //********************************************************************************************** 146 }; 147 /*! \endcond */ 148 //************************************************************************************************* 149 150 151 152 153 //================================================================================================= 154 // 155 // RAND SPECIALIZATION FOR SPARSE SUBMATRICES 156 // 157 //================================================================================================= 158 159 //************************************************************************************************* 160 /*! \cond BLAZE_INTERNAL */ 161 /*!\brief Specialization of the Rand class template for sparse submatrices. 162 // \ingroup random 163 // 164 // This specialization of the Rand class randomizes sparse submatrices. 165 */ 166 template< typename MT // Type of the dense matrix 167 , AlignmentFlag AF // Alignment flag 168 , bool SO // Storage order 169 , size_t... CSAs > // Compile time submatrix arguments 170 class Rand< Submatrix<MT,AF,SO,false,CSAs...> > 171 { 172 public: 173 //********************************************************************************************** 174 /*!\brief Randomization of a sparse submatrix. 175 // 176 // \param submatrix The submatrix to be randomized. 177 // \return void 178 */ 179 template< typename SMT > // Type of the submatrix randomize(SMT && submatrix)180 inline void randomize( SMT&& submatrix ) const 181 { 182 using SubmatrixType = RemoveReference_t<SMT>; 183 using ElementType = ElementType_t<SubmatrixType>; 184 185 BLAZE_CONSTRAINT_MUST_BE_SUBMATRIX_TYPE( SubmatrixType ); 186 BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE( SubmatrixType ); 187 188 const size_t m( submatrix.rows() ); 189 const size_t n( submatrix.columns() ); 190 191 if( m == 0UL || n == 0UL ) return; 192 193 const size_t nonzeros( rand<size_t>( 1UL, std::ceil( 0.5*m*n ) ) ); 194 195 submatrix.reset(); 196 submatrix.reserve( nonzeros ); 197 198 while( submatrix.nonZeros() < nonzeros ) { 199 submatrix( rand<size_t>( 0UL, m-1UL ), rand<size_t>( 0UL, n-1UL ) ) = rand<ElementType>(); 200 } 201 } 202 //********************************************************************************************** 203 204 //********************************************************************************************** 205 /*!\brief Randomization of a sparse submatrix. 206 // 207 // \param submatrix The submatrix to be randomized. 208 // \param nonzeros The number of non-zero elements of the random submatrix. 209 // \return void 210 // \exception std::invalid_argument Invalid number of non-zero elements. 211 */ 212 template< typename SMT > // Type of the submatrix randomize(SMT && submatrix,size_t nonzeros)213 inline void randomize( SMT&& submatrix, size_t nonzeros ) const 214 { 215 using SubmatrixType = RemoveReference_t<SMT>; 216 using ElementType = ElementType_t<SubmatrixType>; 217 218 BLAZE_CONSTRAINT_MUST_BE_SUBMATRIX_TYPE( SubmatrixType ); 219 BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE( SubmatrixType ); 220 221 const size_t m( submatrix.rows() ); 222 const size_t n( submatrix.columns() ); 223 224 if( nonzeros > m*n ) { 225 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of non-zero elements" ); 226 } 227 228 if( m == 0UL || n == 0UL ) return; 229 230 submatrix.reset(); 231 submatrix.reserve( nonzeros ); 232 233 while( submatrix.nonZeros() < nonzeros ) { 234 submatrix( rand<size_t>( 0UL, m-1UL ), rand<size_t>( 0UL, n-1UL ) ) = rand<ElementType>(); 235 } 236 } 237 //********************************************************************************************** 238 239 //********************************************************************************************** 240 /*!\brief Randomization of a sparse submatrix. 241 // 242 // \param submatrix The submatrix to be randomized. 243 // \param min The smallest possible value for a submatrix element. 244 // \param max The largest possible value for a submatrix element. 245 // \return void 246 */ 247 template< typename SMT // Type of the submatrix 248 , typename Arg > // Min/max argument type randomize(SMT && submatrix,const Arg & min,const Arg & max)249 inline void randomize( SMT&& submatrix, const Arg& min, const Arg& max ) const 250 { 251 using SubmatrixType = RemoveReference_t<SMT>; 252 using ElementType = ElementType_t<SubmatrixType>; 253 254 BLAZE_CONSTRAINT_MUST_BE_SUBMATRIX_TYPE( SubmatrixType ); 255 BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE( SubmatrixType ); 256 257 const size_t m( submatrix.rows() ); 258 const size_t n( submatrix.columns() ); 259 260 if( m == 0UL || n == 0UL ) return; 261 262 const size_t nonzeros( rand<size_t>( 1UL, std::ceil( 0.5*m*n ) ) ); 263 264 submatrix.reset(); 265 submatrix.reserve( nonzeros ); 266 267 while( submatrix.nonZeros() < nonzeros ) { 268 submatrix( rand<size_t>( 0UL, m-1UL ), rand<size_t>( 0UL, n-1UL ) ) = rand<ElementType>( min, max ); 269 } 270 } 271 //********************************************************************************************** 272 273 //********************************************************************************************** 274 /*!\brief Randomization of a sparse submatrix. 275 // 276 // \param submatrix The submatrix to be randomized. 277 // \param nonzeros The number of non-zero elements of the random submatrix. 278 // \param min The smallest possible value for a submatrix element. 279 // \param max The largest possible value for a submatrix element. 280 // \return void 281 // \exception std::invalid_argument Invalid number of non-zero elements. 282 */ 283 template< typename SMT // Type of the submatrix 284 , typename Arg > // Min/max argument type randomize(SMT && submatrix,size_t nonzeros,const Arg & min,const Arg & max)285 inline void randomize( SMT&& submatrix, size_t nonzeros, const Arg& min, const Arg& max ) const 286 { 287 using SubmatrixType = RemoveReference_t<SMT>; 288 using ElementType = ElementType_t<SubmatrixType>; 289 290 BLAZE_CONSTRAINT_MUST_BE_SUBMATRIX_TYPE( SubmatrixType ); 291 BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE( SubmatrixType ); 292 293 const size_t m( submatrix.rows() ); 294 const size_t n( submatrix.columns() ); 295 296 if( nonzeros > m*n ) { 297 BLAZE_THROW_INVALID_ARGUMENT( "Invalid number of non-zero elements" ); 298 } 299 300 if( m == 0UL || n == 0UL ) return; 301 302 submatrix.reset(); 303 submatrix.reserve( nonzeros ); 304 305 while( submatrix.nonZeros() < nonzeros ) { 306 submatrix( rand<size_t>( 0UL, m-1UL ), rand<size_t>( 0UL, n-1UL ) ) = rand<ElementType>( min, max ); 307 } 308 } 309 //********************************************************************************************** 310 }; 311 /*! \endcond */ 312 //************************************************************************************************* 313 314 } // namespace blaze 315 316 #endif 317