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