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