1 //=================================================================================================
2 /*!
3 // \file blaze/math/StaticMatrix.h
4 // \brief Header file for the complete StaticMatrix 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_STATICMATRIX_H_
36 #define _BLAZE_MATH_STATICMATRIX_H_
37
38
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42
43 #include <blaze/math/constraints/Scalar.h>
44 #include <blaze/math/dense/StaticMatrix.h>
45 #include <blaze/math/DenseMatrix.h>
46 #include <blaze/math/HybridMatrix.h>
47 #include <blaze/math/IdentityMatrix.h>
48 #include <blaze/math/shims/Conjugate.h>
49 #include <blaze/math/shims/Real.h>
50 #include <blaze/math/StaticVector.h>
51 #include <blaze/math/typetraits/UnderlyingBuiltin.h>
52 #include <blaze/math/ZeroMatrix.h>
53 #include <blaze/util/Assert.h>
54 #include <blaze/util/Random.h>
55 #include <blaze/util/StaticAssert.h>
56
57
58 namespace blaze {
59
60 //=================================================================================================
61 //
62 // RAND SPECIALIZATION
63 //
64 //=================================================================================================
65
66 //*************************************************************************************************
67 /*! \cond BLAZE_INTERNAL */
68 /*!\brief Specialization of the Rand class template for StaticMatrix.
69 // \ingroup random
70 //
71 // This specialization of the Rand class creates random instances of StaticMatrix.
72 */
73 template< typename Type // Data type of the matrix
74 , size_t M // Number of rows
75 , size_t N // Number of columns
76 , bool SO // Storage order
77 , AlignmentFlag AF // Alignment flag
78 , PaddingFlag PF // Padding flag
79 , typename Tag > // Type tag
80 class Rand< StaticMatrix<Type,M,N,SO,AF,PF,Tag> >
81 {
82 public:
83 //**********************************************************************************************
84 /*!\brief Generation of a random StaticMatrix.
85 //
86 // \return The generated random matrix.
87 */
generate()88 inline const StaticMatrix<Type,M,N,SO,AF,PF,Tag> generate() const
89 {
90 StaticMatrix<Type,M,N,SO,AF,PF,Tag> matrix;
91 randomize( matrix );
92 return matrix;
93 }
94 //**********************************************************************************************
95
96 //**********************************************************************************************
97 /*!\brief Generation of a random StaticMatrix.
98 //
99 // \param min The smallest possible value for a matrix element.
100 // \param max The largest possible value for a matrix element.
101 // \return The generated random matrix.
102 */
103 template< typename Arg > // Min/max argument type
104 inline const StaticMatrix<Type,M,N,SO,AF,PF,Tag>
generate(const Arg & min,const Arg & max)105 generate( const Arg& min, const Arg& max ) const
106 {
107 StaticMatrix<Type,M,N,SO,AF,PF,Tag> matrix;
108 randomize( matrix, min, max );
109 return matrix;
110 }
111 //**********************************************************************************************
112
113 //**********************************************************************************************
114 /*!\brief Randomization of a StaticMatrix.
115 //
116 // \param matrix The matrix to be randomized.
117 // \return void
118 */
randomize(StaticMatrix<Type,M,N,SO,AF,PF,Tag> & matrix)119 inline void randomize( StaticMatrix<Type,M,N,SO,AF,PF,Tag>& matrix ) const
120 {
121 using blaze::randomize;
122
123 for( size_t i=0UL; i<M; ++i ) {
124 for( size_t j=0UL; j<N; ++j ) {
125 randomize( matrix(i,j) );
126 }
127 }
128 }
129 //**********************************************************************************************
130
131 //**********************************************************************************************
132 /*!\brief Randomization of a StaticMatrix.
133 //
134 // \param matrix The matrix to be randomized.
135 // \param min The smallest possible value for a matrix element.
136 // \param max The largest possible value for a matrix element.
137 // \return void
138 */
139 template< typename Arg > // Min/max argument type
randomize(StaticMatrix<Type,M,N,SO,AF,PF,Tag> & matrix,const Arg & min,const Arg & max)140 inline void randomize( StaticMatrix<Type,M,N,SO,AF,PF,Tag>& matrix,
141 const Arg& min, const Arg& max ) const
142 {
143 using blaze::randomize;
144
145 for( size_t i=0UL; i<M; ++i ) {
146 for( size_t j=0UL; j<N; ++j ) {
147 randomize( matrix(i,j), min, max );
148 }
149 }
150 }
151 //**********************************************************************************************
152 };
153 /*! \endcond */
154 //*************************************************************************************************
155
156
157
158
159 //=================================================================================================
160 //
161 // MAKE FUNCTIONS
162 //
163 //=================================================================================================
164
165 //*************************************************************************************************
166 /*! \cond BLAZE_INTERNAL */
167 /*!\brief Setup of a random symmetric StaticMatrix.
168 //
169 // \param matrix The matrix to be randomized.
170 // \return void
171 // \exception std::invalid_argument Invalid non-square matrix provided.
172 */
173 template< typename Type // Data type of the matrix
174 , size_t M // Number of rows
175 , size_t N // Number of columns
176 , bool SO // Storage order
177 , AlignmentFlag AF // Alignment flag
178 , PaddingFlag PF // Padding flag
179 , typename Tag > // Type tag
makeSymmetric(StaticMatrix<Type,M,N,SO,AF,PF,Tag> & matrix)180 void makeSymmetric( StaticMatrix<Type,M,N,SO,AF,PF,Tag>& matrix )
181 {
182 using blaze::randomize;
183
184 BLAZE_STATIC_ASSERT( M == N );
185
186 for( size_t i=0UL; i<N; ++i ) {
187 for( size_t j=0UL; j<i; ++j ) {
188 randomize( matrix(i,j) );
189 matrix(j,i) = matrix(i,j);
190 }
191 randomize( matrix(i,i) );
192 }
193
194 BLAZE_INTERNAL_ASSERT( isSymmetric( matrix ), "Non-symmetric matrix detected" );
195 }
196 /*! \endcond */
197 //*************************************************************************************************
198
199
200 //*************************************************************************************************
201 /*! \cond BLAZE_INTERNAL */
202 /*!\brief Setup of a random symmetric StaticMatrix.
203 //
204 // \param matrix The matrix to be randomized.
205 // \param min The smallest possible value for a matrix element.
206 // \param max The largest possible value for a matrix element.
207 // \return void
208 // \exception std::invalid_argument Invalid non-square matrix provided.
209 */
210 template< typename Type // Data type of the matrix
211 , size_t M // Number of rows
212 , size_t N // Number of columns
213 , bool SO // Storage order
214 , AlignmentFlag AF // Alignment flag
215 , PaddingFlag PF // Padding flag
216 , typename Tag // Type tag
217 , typename Arg > // Min/max argument type
makeSymmetric(StaticMatrix<Type,M,N,SO,AF,PF,Tag> & matrix,const Arg & min,const Arg & max)218 void makeSymmetric( StaticMatrix<Type,M,N,SO,AF,PF,Tag>& matrix, const Arg& min, const Arg& max )
219 {
220 using blaze::randomize;
221
222 BLAZE_STATIC_ASSERT( M == N );
223
224 for( size_t i=0UL; i<N; ++i ) {
225 for( size_t j=0UL; j<i; ++j ) {
226 randomize( matrix(i,j), min, max );
227 matrix(j,i) = matrix(i,j);
228 }
229 randomize( matrix(i,i), min, max );
230 }
231
232 BLAZE_INTERNAL_ASSERT( isSymmetric( matrix ), "Non-symmetric matrix detected" );
233 }
234 /*! \endcond */
235 //*************************************************************************************************
236
237
238 //*************************************************************************************************
239 /*! \cond BLAZE_INTERNAL */
240 /*!\brief Setup of a random Hermitian StaticMatrix.
241 //
242 // \param matrix The matrix to be randomized.
243 // \return void
244 // \exception std::invalid_argument Invalid non-square matrix provided.
245 */
246 template< typename Type // Data type of the matrix
247 , size_t M // Number of rows
248 , size_t N // Number of columns
249 , bool SO // Storage order
250 , AlignmentFlag AF // Alignment flag
251 , PaddingFlag PF // Padding flag
252 , typename Tag > // Type tag
makeHermitian(StaticMatrix<Type,M,N,SO,AF,PF,Tag> & matrix)253 void makeHermitian( StaticMatrix<Type,M,N,SO,AF,PF,Tag>& matrix )
254 {
255 using blaze::randomize;
256
257 BLAZE_STATIC_ASSERT( M == N );
258 BLAZE_CONSTRAINT_MUST_BE_SCALAR_TYPE( Type );
259
260 using BT = UnderlyingBuiltin_t<Type>;
261
262 for( size_t i=0UL; i<N; ++i ) {
263 for( size_t j=0UL; j<i; ++j ) {
264 randomize( matrix(i,j) );
265 matrix(j,i) = conj( matrix(i,j) );
266 }
267 matrix(i,i) = rand<BT>();
268 }
269
270 BLAZE_INTERNAL_ASSERT( isHermitian( matrix ), "Non-Hermitian matrix detected" );
271 }
272 /*! \endcond */
273 //*************************************************************************************************
274
275
276 //*************************************************************************************************
277 /*! \cond BLAZE_INTERNAL */
278 /*!\brief Setup of a random Hermitian StaticMatrix.
279 //
280 // \param matrix The matrix to be randomized.
281 // \param min The smallest possible value for a matrix element.
282 // \param max The largest possible value for a matrix element.
283 // \return void
284 // \exception std::invalid_argument Invalid non-square matrix provided.
285 */
286 template< typename Type // Data type of the matrix
287 , size_t M // Number of rows
288 , size_t N // Number of columns
289 , bool SO // Storage order
290 , AlignmentFlag AF // Alignment flag
291 , PaddingFlag PF // Padding flag
292 , typename Tag // Type tag
293 , typename Arg > // Min/max argument type
makeHermitian(StaticMatrix<Type,M,N,SO,AF,PF,Tag> & matrix,const Arg & min,const Arg & max)294 void makeHermitian( StaticMatrix<Type,M,N,SO,AF,PF,Tag>& matrix, const Arg& min, const Arg& max )
295 {
296 using blaze::randomize;
297
298 BLAZE_STATIC_ASSERT( M == N );
299 BLAZE_CONSTRAINT_MUST_BE_SCALAR_TYPE( Type );
300
301 using BT = UnderlyingBuiltin_t<Type>;
302
303 for( size_t i=0UL; i<N; ++i ) {
304 for( size_t j=0UL; j<i; ++j ) {
305 randomize( matrix(i,j), min, max );
306 matrix(j,i) = conj( matrix(i,j) );
307 }
308 matrix(i,i) = rand<BT>( real( min ), real( max ) );
309 }
310
311 BLAZE_INTERNAL_ASSERT( isHermitian( matrix ), "Non-Hermitian matrix detected" );
312 }
313 /*! \endcond */
314 //*************************************************************************************************
315
316
317 //*************************************************************************************************
318 /*! \cond BLAZE_INTERNAL */
319 /*!\brief Setup of a random (Hermitian) positive definite StaticMatrix.
320 //
321 // \param matrix The matrix to be randomized.
322 // \return void
323 // \exception std::invalid_argument Invalid non-square matrix provided.
324 */
325 template< typename Type // Data type of the matrix
326 , size_t M // Number of rows
327 , size_t N // Number of columns
328 , bool SO // Storage order
329 , AlignmentFlag AF // Alignment flag
330 , PaddingFlag PF // Padding flag
331 , typename Tag > // Type tag
makePositiveDefinite(StaticMatrix<Type,M,N,SO,AF,PF,Tag> & matrix)332 void makePositiveDefinite( StaticMatrix<Type,M,N,SO,AF,PF,Tag>& matrix )
333 {
334 using blaze::randomize;
335
336 BLAZE_STATIC_ASSERT( M == N );
337 BLAZE_CONSTRAINT_MUST_BE_SCALAR_TYPE( Type );
338
339 randomize( matrix );
340 matrix *= ctrans( matrix );
341
342 for( size_t i=0UL; i<N; ++i ) {
343 matrix(i,i) += Type(N);
344 }
345
346 BLAZE_INTERNAL_ASSERT( isHermitian( matrix ), "Non-symmetric matrix detected" );
347 }
348 /*! \endcond */
349 //*************************************************************************************************
350
351 } // namespace blaze
352
353 #endif
354