1 //=================================================================================================
2 /*!
3 // \file blaze/math/expressions/MatScalarMultExpr.h
4 // \brief Header file for the MatScalarMultExpr base class
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_EXPRESSIONS_MATSCALARMULTEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_MATSCALARMULTEXPR_H_
37
38
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42
43 #include <blaze/math/Aliases.h>
44 #include <blaze/math/Exception.h>
45 #include <blaze/math/expressions/Forward.h>
46 #include <blaze/math/expressions/MultExpr.h>
47 #include <blaze/math/typetraits/IsInvertible.h>
48 #include <blaze/math/typetraits/IsScalar.h>
49 #include <blaze/util/Assert.h>
50 #include <blaze/util/EnableIf.h>
51 #include <blaze/util/FunctionTrace.h>
52
53
54 namespace blaze {
55
56 //=================================================================================================
57 //
58 // CLASS DEFINITION
59 //
60 //=================================================================================================
61
62 //*************************************************************************************************
63 /*!\brief Base class for all matrix/scalar multiplication expression templates.
64 // \ingroup math
65 //
66 // The MatScalarMultExpr class serves as a tag for all expression templates that implement a
67 // matrix/scalar multiplication. All classes, that represent a matrix/scalar multiplication
68 // and that are used within the expression template environment of the Blaze library have
69 // to derive publicly from this class in order to qualify as matrix/scalar multiplication
70 // expression template. Only in case a class is derived publicly from the MatScalarMultExpr
71 // base class, the IsMatScalarMultExpr type trait recognizes the class as valid matrix/scalar
72 // multiplication expression template.
73 */
74 template< typename MT > // Matrix base type of the expression
75 struct MatScalarMultExpr
76 : public MultExpr<MT>
77 {};
78 //*************************************************************************************************
79
80
81
82
83 //=================================================================================================
84 //
85 // GLOBAL RESTRUCTURING UNARY ARITHMETIC OPERATORS
86 //
87 //=================================================================================================
88
89 //*************************************************************************************************
90 /*! \cond BLAZE_INTERNAL */
91 /*!\brief Unary minus operator for the negation of a matrix-scalar multiplication
92 // (\f$ A = -(B*s) \f$).
93 // \ingroup math
94 //
95 // \param mat The matrix-scalar multiplication to be negated.
96 // \return The negation of the matrix-scalar multiplication.
97 //
98 // This operator implements a performance optimized treatment of the negation of a matrix-scalar
99 // multiplication expression.
100 */
101 template< typename MT > // Matrix base type of the expression
102 inline decltype(auto) operator-( const MatScalarMultExpr<MT>& mat )
103 {
104 BLAZE_FUNCTION_TRACE;
105
106 return (*mat).leftOperand() * ( -(*mat).rightOperand() );
107 }
108 /*! \endcond */
109 //*************************************************************************************************
110
111
112
113
114 //=================================================================================================
115 //
116 // GLOBAL RESTRUCTURING BINARY ARITHMETIC OPERATORS
117 //
118 //=================================================================================================
119
120 //*************************************************************************************************
121 /*! \cond BLAZE_INTERNAL */
122 /*!\brief Multiplication operator for the multiplication of a matrix-scalar multiplication
123 // expression and a scalar value (\f$ A=(B*s1)*s2 \f$).
124 // \ingroup math
125 //
126 // \param mat The left-hand side matrix-scalar multiplication.
127 // \param scalar The right-hand side scalar value for the multiplication.
128 // \return The scaled result matrix.
129 //
130 // This operator implements a performance optimized treatment of the multiplication of a
131 // matrix-scalar multiplication expression and a scalar value.
132 */
133 template< typename MT // Matrix base type of the expression
134 , typename ST // Type of the right-hand side scalar
135 , EnableIf_t< IsScalar_v<ST> >* = nullptr >
decltype(auto)136 inline decltype(auto) operator*( const MatScalarMultExpr<MT>& mat, ST scalar )
137 {
138 BLAZE_FUNCTION_TRACE;
139
140 return (*mat).leftOperand() * ( (*mat).rightOperand() * scalar );
141 }
142 /*! \endcond */
143 //*************************************************************************************************
144
145
146 //*************************************************************************************************
147 /*! \cond BLAZE_INTERNAL */
148 /*!\brief Multiplication operator for the multiplication of a scalar value and a matrix-scalar
149 // multiplication expression (\f$ A=s2*(B*s1) \f$).
150 // \ingroup math
151 //
152 // \param scalar The left-hand side scalar value for the multiplication.
153 // \param mat The right-hand side matrix-scalar multiplication.
154 // \return The scaled result matrix.
155 //
156 // This operator implements a performance optimized treatment of the multiplication of a
157 // scalar value and a matrix-scalar multiplication expression.
158 */
159 template< typename ST // Type of the left-hand side scalar
160 , typename MT // Matrix base type of the expression
161 , EnableIf_t< IsScalar_v<ST> >* = nullptr >
decltype(auto)162 inline decltype(auto) operator*( ST scalar, const MatScalarMultExpr<MT>& mat )
163 {
164 BLAZE_FUNCTION_TRACE;
165
166 return (*mat).leftOperand() * ( scalar * (*mat).rightOperand() );
167 }
168 /*! \endcond */
169 //*************************************************************************************************
170
171
172 //*************************************************************************************************
173 /*! \cond BLAZE_INTERNAL */
174 /*!\brief Division operator for the division of a matrix-scalar multiplication expression by
175 // a scalar value (\f$ A=(B*s1)/s2 \f$).
176 // \ingroup math
177 //
178 // \param mat The left-hand side matrix-scalar multiplication.
179 // \param scalar The right-hand side scalar value for the division.
180 // \return The scaled result matrix.
181 //
182 // This operator implements a performance optimized treatment of the division of a
183 // matrix-scalar multiplication expression by a scalar value.
184 */
185 template< typename MT // Matrix base type of the expression
186 , typename ST // Type of the right-hand side scalar
187 , EnableIf_t< IsScalar_v<ST> &&
188 ( IsInvertible_v<ST> ||
189 IsInvertible_v< RightOperand_t< MatrixType_t<MT> > > ) >* = nullptr >
190 inline decltype(auto) operator/( const MatScalarMultExpr<MT>& mat, ST scalar )
191 {
192 BLAZE_FUNCTION_TRACE;
193
194 BLAZE_USER_ASSERT( scalar != ST(0), "Division by zero detected" );
195
196 return (*mat).leftOperand() * ( (*mat).rightOperand() / scalar );
197 }
198 /*! \endcond */
199 //*************************************************************************************************
200
201
202 //*************************************************************************************************
203 /*! \cond BLAZE_INTERNAL */
204 /*!\brief Multiplication operator for the multiplication of a matrix-scalar multiplication
205 // expression and a dense vector (\f$ \vec{a}=(B*s1)*\vec{c} \f$).
206 // \ingroup math
207 //
208 // \param mat The left-hand side matrix-scalar multiplication.
209 // \param vec The right-hand side dense vector.
210 // \return The scaled result vector.
211 //
212 // This operator implements the performance optimized treatment of the multiplication
213 // of a matrix-scalar multiplication and a dense vector. It restructures the expression
214 // \f$ \vec{a}=(B*s1)*\vec{c} \f$ to the expression \f$ \vec{a}=(B*\vec{c})*s1 \f$.
215 */
216 template< typename MT // Matrix base type of the left-hand side expression
217 , typename VT > // Type of the right-hand side dense vector
decltype(auto)218 inline decltype(auto)
219 operator*( const MatScalarMultExpr<MT>& mat, const DenseVector<VT,false>& vec )
220 {
221 BLAZE_FUNCTION_TRACE;
222
223 return ( (*mat).leftOperand() * (*vec) ) * (*mat).rightOperand();
224 }
225 /*! \endcond */
226 //*************************************************************************************************
227
228
229 //*************************************************************************************************
230 /*! \cond BLAZE_INTERNAL */
231 /*!\brief Multiplication operator for the multiplication of a dense vector and a
232 // matrix-scalar multiplication expression (\f$ \vec{a}^T=\vec{c}^T*(B*s1) \f$).
233 // \ingroup math
234 //
235 // \param vec The left-hand side dense vector.
236 // \param mat The right-hand side matrix-scalar multiplication.
237 // \return The scaled result vector.
238 //
239 // This operator implements the performance optimized treatment of the multiplication
240 // of a dense vector and a matrix-scalar multiplication. It restructures the expression
241 // \f$ \vec{a}=\vec{c}^T*(B*s1) \f$ to the expression \f$ \vec{a}^T=(\vec{c}^T*B)*s1 \f$.
242 */
243 template< typename VT // Type of the left-hand side dense vector
244 , typename MT > // Matrix base type of the right-hand side expression
decltype(auto)245 inline decltype(auto)
246 operator*( const DenseVector<VT,true>& vec, const MatScalarMultExpr<MT>& mat )
247 {
248 BLAZE_FUNCTION_TRACE;
249
250 return ( (*vec) * (*mat).leftOperand() ) * (*mat).rightOperand();
251 }
252 /*! \endcond */
253 //*************************************************************************************************
254
255
256 //*************************************************************************************************
257 /*! \cond BLAZE_INTERNAL */
258 /*!\brief Multiplication operator for the multiplication of a matrix-scalar multiplication
259 // expression and a sparse vector (\f$ \vec{a}=(B*s1)*\vec{c} \f$).
260 // \ingroup math
261 //
262 // \param mat The left-hand side matrix-scalar multiplication.
263 // \param vec The right-hand side sparse vector.
264 // \return The scaled result vector.
265 //
266 // This operator implements the performance optimized treatment of the multiplication
267 // of a matrix-scalar multiplication and a sparse vector. It restructures the expression
268 // \f$ \vec{a}=(B*s1)*\vec{c} \f$ to the expression \f$ \vec{a}=(B*\vec{c})*s1 \f$.
269 */
270 template< typename MT // Matrix base type of the left-hand side expression
271 , typename VT > // Type of the right-hand side sparse vector
decltype(auto)272 inline decltype(auto)
273 operator*( const MatScalarMultExpr<MT>& mat, const SparseVector<VT,false>& vec )
274 {
275 BLAZE_FUNCTION_TRACE;
276
277 return ( (*mat).leftOperand() * (*vec) ) * (*mat).rightOperand();
278 }
279 /*! \endcond */
280 //*************************************************************************************************
281
282
283 //*************************************************************************************************
284 /*! \cond BLAZE_INTERNAL */
285 /*!\brief Multiplication operator for the multiplication of a sparse vector and a
286 // matrix-scalar multiplication expression (\f$ \vec{a}^T=\vec{c}^T*(B*s1) \f$).
287 // \ingroup math
288 //
289 // \param vec The left-hand side sparse vector.
290 // \param mat The right-hand side matrix-scalar multiplication.
291 // \return The scaled result vector.
292 //
293 // This operator implements the performance optimized treatment of the multiplication
294 // of a sparse vector and a matrix-scalar multiplication. It restructures the expression
295 // \f$ \vec{a}=\vec{c}^T*(B*s1) \f$ to the expression \f$ \vec{a}^T=(\vec{c}^T*B)*s1 \f$.
296 */
297 template< typename VT // Type of the left-hand side sparse vector
298 , typename MT > // Matrix base type of the right-hand side expression
decltype(auto)299 inline decltype(auto)
300 operator*( const SparseVector<VT,true>& vec, const MatScalarMultExpr<MT>& mat )
301 {
302 BLAZE_FUNCTION_TRACE;
303
304 return ( (*vec) * (*mat).leftOperand() ) * (*mat).rightOperand();
305 }
306 /*! \endcond */
307 //*************************************************************************************************
308
309
310 //*************************************************************************************************
311 /*! \cond BLAZE_INTERNAL */
312 /*!\brief Multiplication operator for the multiplication of a matrix-scalar multiplication
313 // expression and a vector-scalar multiplication expression
314 // (\f$ \vec{a}=(B*s1)*(\vec{c}*s2) \f$).
315 // \ingroup math
316 //
317 // \param mat The left-hand side matrix-scalar multiplication.
318 // \param vec The right-hand side vector-scalar multiplication.
319 // \return The scaled result vector.
320 //
321 // This operator implements the performance optimized treatment of the multiplication of a matrix-
322 // scalar multiplication and a vector-scalar multiplication. It restructures the expression
323 // \f$ \vec{a}=(B*s1)*(\vec{c}*s2) \f$ to the expression \f$ \vec{a}=(B*\vec{c})*(s1*s2) \f$.
324 */
325 template< typename MT // Matrix base type of the left-hand side expression
326 , typename VT > // Vector base type of the right-hand side expression
decltype(auto)327 inline decltype(auto)
328 operator*( const MatScalarMultExpr<MT>& mat, const VecScalarMultExpr<VT>& vec )
329 {
330 BLAZE_FUNCTION_TRACE;
331
332 return ( (*mat).leftOperand() * (*vec).leftOperand() ) * ( (*mat).rightOperand() * (*vec).rightOperand() );
333 }
334 /*! \endcond */
335 //*************************************************************************************************
336
337
338 //*************************************************************************************************
339 /*! \cond BLAZE_INTERNAL */
340 /*!\brief Multiplication operator for the multiplication of a vector-scalar multiplication
341 // expression and a matrix-scalar multiplication expression
342 // (\f$ \vec{a}^T=\vec{b}^T*(C*s1) \f$).
343 // \ingroup math
344 //
345 // \param vec The left-hand side vector-scalar multiplication.
346 // \param mat The right-hand side matrix-scalar multiplication.
347 // \return The scaled result vector.
348 //
349 // This operator implements the performance optimized treatment of the multiplication of a vector-
350 // scalar multiplication and a matrix-scalar multiplication. It restructures the expression
351 // \f$ \vec{a}=(\vec{b}^T*s1)*(C*s2) \f$ to the expression \f$ \vec{a}^T=(\vec{b}^T*C)*(s1*s2) \f$.
352 */
353 template< typename VT // Vector base type of the left-hand side expression
354 , typename MT > // Matrix base type of the right-hand side expression
decltype(auto)355 inline decltype(auto)
356 operator*( const VecScalarMultExpr<VT>& vec, const MatScalarMultExpr<MT>& mat )
357 {
358 BLAZE_FUNCTION_TRACE;
359
360 return ( (*vec).leftOperand() * (*mat).leftOperand() ) * ( (*vec).rightOperand() * (*mat).rightOperand() );
361 }
362 /*! \endcond */
363 //*************************************************************************************************
364
365
366 //*************************************************************************************************
367 /*! \cond BLAZE_INTERNAL */
368 /*!\brief Multiplication operator for the multiplication of a matrix-scalar multiplication
369 // expression and a dense matrix (\f$ A=(B*s1)*C \f$).
370 // \ingroup math
371 //
372 // \param lhs The left-hand side matrix-scalar multiplication.
373 // \param rhs The right-hand side dense matrix.
374 // \return The scaled result matrix.
375 //
376 // This operator implements the performance optimized treatment of the multiplication
377 // of a matrix-scalar multiplication and a dense matrix. It restructures the expression
378 // \f$ A=(B*s1)*C \f$ to the expression \f$ A=(B*C)*s1 \f$.
379 */
380 template< typename MT1 // Matrix base type of the left-hand side expression
381 , typename MT2 // Type of the right-hand side dense matrix
382 , bool SO > // Storage order of the right-hand side dense matrix
decltype(auto)383 inline decltype(auto)
384 operator*( const MatScalarMultExpr<MT1>& lhs, const DenseMatrix<MT2,SO>& rhs )
385 {
386 BLAZE_FUNCTION_TRACE;
387
388 return ( (*lhs).leftOperand() * (*rhs) ) * (*lhs).rightOperand();
389 }
390 /*! \endcond */
391 //*************************************************************************************************
392
393
394 //*************************************************************************************************
395 /*! \cond BLAZE_INTERNAL */
396 /*!\brief Multiplication operator for the multiplication of a dense matrix and a matrix-scalar
397 // multiplication expression (\f$ A=(B*s1)*C \f$).
398 // \ingroup math
399 //
400 // \param lhs The left-hand side dense matrix.
401 // \param rhs The right-hand side matrix-scalar multiplication.
402 // \return The scaled result matrix.
403 //
404 // This operator implements the performance optimized treatment of the multiplication
405 // of a dense matrix and a matrix-scalar multiplication. It restructures the expression
406 // \f$ A=B*(C*s1) \f$ to the expression \f$ A=(B*C)*s1 \f$.
407 */
408 template< typename MT1 // Type of the left-hand side dense matrix
409 , bool SO // Storage order of the left-hand side dense matrix
410 , typename MT2 > // Matrix base type of the right-hand side expression
decltype(auto)411 inline decltype(auto)
412 operator*( const DenseMatrix<MT1,SO>& lhs, const MatScalarMultExpr<MT2>& rhs )
413 {
414 BLAZE_FUNCTION_TRACE;
415
416 return ( (*lhs) * (*rhs).leftOperand() ) * (*rhs).rightOperand();
417 }
418 /*! \endcond */
419 //*************************************************************************************************
420
421
422 //*************************************************************************************************
423 /*! \cond BLAZE_INTERNAL */
424 /*!\brief Multiplication operator for the multiplication of a matrix-scalar multiplication
425 // expression and a sparse matrix (\f$ A=(B*s1)*C \f$).
426 // \ingroup math
427 //
428 // \param lhs The left-hand side matrix-scalar multiplication.
429 // \param rhs The right-hand side sparse matrix.
430 // \return The scaled result matrix.
431 //
432 // This operator implements the performance optimized treatment of the multiplication
433 // of a matrix-scalar multiplication and a sparse matrix. It restructures the expression
434 // \f$ A=(B*s1)*C \f$ to the expression \f$ A=(B*C)*s1 \f$.
435 */
436 template< typename MT1 // Matrix base type of the left-hand side expression
437 , typename MT2 // Type of the right-hand side sparse matrix
438 , bool SO > // Storage order of the right-hand side sparse matrix
decltype(auto)439 inline decltype(auto)
440 operator*( const MatScalarMultExpr<MT1>& lhs, const SparseMatrix<MT2,SO>& rhs )
441 {
442 BLAZE_FUNCTION_TRACE;
443
444 return ( (*lhs).leftOperand() * (*rhs) ) * (*lhs).rightOperand();
445 }
446 /*! \endcond */
447 //*************************************************************************************************
448
449
450 //*************************************************************************************************
451 /*! \cond BLAZE_INTERNAL */
452 /*!\brief Multiplication operator for the multiplication of a sparse matrix and a matrix-scalar
453 // multiplication expression (\f$ A=(B*s1)*C \f$).
454 // \ingroup math
455 //
456 // \param lhs The left-hand side sparse matrix.
457 // \param rhs The right-hand side matrix-scalar multiplication.
458 // \return The scaled result matrix.
459 //
460 // This operator implements the performance optimized treatment of the multiplication
461 // of a sparse matrix and a matrix-scalar multiplication. It restructures the expression
462 // \f$ A=B*(C*s1) \f$ to the expression \f$ A=(B*C)*s1 \f$.
463 */
464 template< typename MT1 // Type of the left-hand side sparse matrix
465 , bool SO // Storage order of the left-hand side sparse matrix
466 , typename MT2 > // Matrix base type of the right-hand side expression
decltype(auto)467 inline decltype(auto)
468 operator*( const SparseMatrix<MT1,SO>& lhs, const MatScalarMultExpr<MT2>& rhs )
469 {
470 BLAZE_FUNCTION_TRACE;
471
472 return ( (*lhs) * (*rhs).leftOperand() ) * (*rhs).rightOperand();
473 }
474 /*! \endcond */
475 //*************************************************************************************************
476
477
478 //*************************************************************************************************
479 /*! \cond BLAZE_INTERNAL */
480 /*!\brief Multiplication operator for the multiplication of two matrix-scalar multiplication
481 // expressions (\f$ A=(B*s1)*(C*s2) \f$).
482 // \ingroup math
483 //
484 // \param lhs The left-hand side matrix-scalar multiplication.
485 // \param rhs The right-hand side matrix-scalar multiplication.
486 // \return The scaled result matrix.
487 //
488 // This operator implements the performance optimized treatment of the multiplication of
489 // two matrix-scalar multiplication expressions. It restructures the expression
490 // \f$ A=(B*s1)*(C*s2) \f$ to the expression \f$ A=(B*C)*(s1*s2) \f$.
491 */
492 template< typename MT1 // Matrix base type of the left-hand side expression
493 , typename MT2 > // Matrix base type of the right-hand side expression
decltype(auto)494 inline decltype(auto)
495 operator*( const MatScalarMultExpr<MT1>& lhs, const MatScalarMultExpr<MT2>& rhs )
496 {
497 BLAZE_FUNCTION_TRACE;
498
499 return ( (*lhs).leftOperand() * (*rhs).leftOperand() ) * ( (*lhs).rightOperand() * (*rhs).rightOperand() );
500 }
501 /*! \endcond */
502 //*************************************************************************************************
503
504
505
506
507 //=================================================================================================
508 //
509 // GLOBAL RESTRUCTURING FUNCTIONS
510 //
511 //=================================================================================================
512
513 //*************************************************************************************************
514 /*! \cond BLAZE_INTERNAL */
515 /*!\brief Calculation of the transpose of the given matrix-scalar multiplication.
516 // \ingroup math
517 //
518 // \param matrix The matrix-scalar multiplication expression to be transposed.
519 // \return The transpose of the expression.
520 //
521 // This operator implements the performance optimized treatment of the transpose of a
522 // matrix-scalar multiplication. It restructures the expression \f$ A=trans(B*s1) \f$ to
523 // the expression \f$ A=trans(B)*s1 \f$.
524 */
525 template< typename MT > // Matrix base type of the expression
decltype(auto)526 inline decltype(auto) trans( const MatScalarMultExpr<MT>& matrix )
527 {
528 BLAZE_FUNCTION_TRACE;
529
530 return trans( (*matrix).leftOperand() ) * (*matrix).rightOperand();
531 }
532 /*! \endcond */
533 //*************************************************************************************************
534
535
536 //*************************************************************************************************
537 /*! \cond BLAZE_INTERNAL */
538 /*!\brief Calculation of the complex conjugate of the given matrix-scalar multiplication.
539 // \ingroup math
540 //
541 // \param matrix The matrix-scalar multiplication expression to be conjugated.
542 // \return The complex conjugate of the expression.
543 //
544 // This operator implements the performance optimized treatment of the complex conjugate of a
545 // matrix-scalar multiplication. It restructures the expression \f$ a=conj(b*s1) \f$ to the
546 // expression \f$ a=conj(b)*s1 \f$.
547 */
548 template< typename MT > // Matrix base type of the expression
decltype(auto)549 inline decltype(auto) conj( const MatScalarMultExpr<MT>& matrix )
550 {
551 BLAZE_FUNCTION_TRACE;
552
553 return conj( (*matrix).leftOperand() ) * (*matrix).rightOperand();
554 }
555 /*! \endcond */
556 //*************************************************************************************************
557
558
559 //*************************************************************************************************
560 /*! \cond BLAZE_INTERNAL */
561 /*!\brief Declares the given non-symmetric matrix-scalar multiplication expression as symmetric.
562 // \ingroup math
563 //
564 // \param matrix The input matrix-scalar multiplication expression.
565 // \return The redeclared expression.
566 // \exception std::invalid_argument Invalid symmetric matrix specification.
567 //
568 // This function implements the application of the \a declsym operation on a matrix-scalar
569 // multiplication. It restructures the expression \f$ A=declsym(B*s1) \f$ to the expression
570 // \f$ A=declsym(B)*s1 \f$. In case the given matrix is not a square matrix, a
571 // \a std::invalid_argument exception is thrown.
572 */
573 template< typename MT > // Matrix base type of the expression
decltype(auto)574 inline decltype(auto) declsym( const MatScalarMultExpr<MT>& matrix )
575 {
576 BLAZE_FUNCTION_TRACE;
577
578 if( !isSquare( *matrix ) ) {
579 BLAZE_THROW_INVALID_ARGUMENT( "Invalid symmetric matrix specification" );
580 }
581
582 return declsym( (*matrix).leftOperand() ) * (*matrix).rightOperand();
583 }
584 /*! \endcond */
585 //*************************************************************************************************
586
587
588 //*************************************************************************************************
589 /*! \cond BLAZE_INTERNAL */
590 /*!\brief Declares the given non-Hermitian matrix-scalar multiplication expression as Hermitian.
591 // \ingroup math
592 //
593 // \param matrix The input matrix-scalar multiplication expression.
594 // \return The redeclared expression.
595 // \exception std::invalid_argument Invalid Hermitian matrix specification.
596 //
597 // This function implements the application of the declherm() operation on a matrix-scalar
598 // multiplication. It restructures the expression \f$ A=declherm(B*s1) \f$ to the expression
599 // \f$ A=declherm(B)*s1 \f$. In case the given matrix is not a square matrix,
600 // a \a std::invalid_argument exception is thrown.
601 */
602 template< typename MT > // Matrix base type of the expression
decltype(auto)603 inline decltype(auto) declherm( const MatScalarMultExpr<MT>& matrix )
604 {
605 BLAZE_FUNCTION_TRACE;
606
607 if( !isSquare( *matrix ) ) {
608 BLAZE_THROW_INVALID_ARGUMENT( "Invalid Hermitian matrix specification" );
609 }
610
611 return declherm( (*matrix).leftOperand() ) * (*matrix).rightOperand();
612 }
613 /*! \endcond */
614 //*************************************************************************************************
615
616
617 //*************************************************************************************************
618 /*! \cond BLAZE_INTERNAL */
619 /*!\brief Declares the given non-lower matrix-scalar multiplication expression as lower.
620 // \ingroup math
621 //
622 // \param matrix The input matrix-scalar multiplication expression.
623 // \return The redeclared expression.
624 // \exception std::invalid_argument Invalid lower matrix specification.
625 //
626 // This function implements the application of the decllow() operation on a matrix-scalar
627 // multiplication. It restructures the expression \f$ A=decllow(B*s1) \f$ to the expression
628 // \f$ A=decllow(B)*s1 \f$. In case the given matrix is not a square matrix,
629 // a \a std::invalid_argument exception is thrown.
630 */
631 template< typename MT > // Matrix base type of the expression
decltype(auto)632 inline decltype(auto) decllow( const MatScalarMultExpr<MT>& matrix )
633 {
634 BLAZE_FUNCTION_TRACE;
635
636 if( !isSquare( *matrix ) ) {
637 BLAZE_THROW_INVALID_ARGUMENT( "Invalid lower matrix specification" );
638 }
639
640 return decllow( (*matrix).leftOperand() ) * (*matrix).rightOperand();
641 }
642 /*! \endcond */
643 //*************************************************************************************************
644
645
646 //*************************************************************************************************
647 /*! \cond BLAZE_INTERNAL */
648 /*!\brief Declares the given non-unilower matrix-scalar multiplication expression as unilower.
649 // \ingroup math
650 //
651 // \param matrix The input matrix-scalar multiplication expression.
652 // \return The redeclared expression.
653 // \exception std::invalid_argument Invalid unilower matrix specification.
654 //
655 // This function implements the application of the declunilow() operation on a matrix-scalar
656 // multiplication. It restructures the expression \f$ A=declunilow(B*s1) \f$ to the expression
657 // \f$ A=declunilow(B)*s1 \f$. In case the given matrix is not a square matrix,
658 // a \a std::invalid_argument exception is thrown.
659 */
660 template< typename MT > // Matrix base type of the expression
decltype(auto)661 inline decltype(auto) declunilow( const MatScalarMultExpr<MT>& matrix )
662 {
663 BLAZE_FUNCTION_TRACE;
664
665 if( !isSquare( *matrix ) ) {
666 BLAZE_THROW_INVALID_ARGUMENT( "Invalid unilower matrix specification" );
667 }
668
669 return declunilow( (*matrix).leftOperand() ) * (*matrix).rightOperand();
670 }
671 /*! \endcond */
672 //*************************************************************************************************
673
674
675 //*************************************************************************************************
676 /*! \cond BLAZE_INTERNAL */
677 /*!\brief Declares the given non-strictly-lower matrix-scalar multiplication expression as
678 // strictly lower.
679 // \ingroup math
680 //
681 // \param matrix The input matrix-scalar multiplication expression.
682 // \return The redeclared expression.
683 // \exception std::invalid_argument Invalid strictly lower matrix specification.
684 //
685 // This function implements the application of the declstrlow() operation on a matrix-scalar
686 // multiplication. It restructures the expression \f$ A=declstrlow(B*s1) \f$ to the expression
687 // \f$ A=declstrlow(B)*s1 \f$. In case the given matrix is not a square matrix,
688 // a \a std::invalid_argument exception is thrown.
689 */
690 template< typename MT > // Matrix base type of the expression
decltype(auto)691 inline decltype(auto) declstrlow( const MatScalarMultExpr<MT>& matrix )
692 {
693 BLAZE_FUNCTION_TRACE;
694
695 if( !isSquare( *matrix ) ) {
696 BLAZE_THROW_INVALID_ARGUMENT( "Invalid strictly lower matrix specification" );
697 }
698
699 return declstrlow( (*matrix).leftOperand() ) * (*matrix).rightOperand();
700 }
701 /*! \endcond */
702 //*************************************************************************************************
703
704
705 //*************************************************************************************************
706 /*! \cond BLAZE_INTERNAL */
707 /*!\brief Declares the given non-upper matrix-scalar multiplication expression as upper.
708 // \ingroup math
709 //
710 // \param matrix The input matrix-scalar multiplication expression.
711 // \return The redeclared expression.
712 // \exception std::invalid_argument Invalid upper matrix specification.
713 //
714 // This function implements the application of the declupp() operation on a matrix-scalar
715 // multiplication. It restructures the expression \f$ A=declupp(B*s1) \f$ to the expression
716 // \f$ A=declupp(B)*s1 \f$. In case the given matrix is not a square matrix,
717 // a \a std::invalid_argument exception is thrown.
718 */
719 template< typename MT > // Matrix base type of the expression
decltype(auto)720 inline decltype(auto) declupp( const MatScalarMultExpr<MT>& matrix )
721 {
722 BLAZE_FUNCTION_TRACE;
723
724 if( !isSquare( *matrix ) ) {
725 BLAZE_THROW_INVALID_ARGUMENT( "Invalid upper matrix specification" );
726 }
727
728 return declupp( (*matrix).leftOperand() ) * (*matrix).rightOperand();
729 }
730 /*! \endcond */
731 //*************************************************************************************************
732
733
734 //*************************************************************************************************
735 /*! \cond BLAZE_INTERNAL */
736 /*!\brief Declares the given non-uniupper matrix-scalar multiplication expression as uniupper.
737 // \ingroup math
738 //
739 // \param matrix The input matrix-scalar multiplication expression.
740 // \return The redeclared expression.
741 // \exception std::invalid_argument Invalid uniupper matrix specification.
742 //
743 // This function implements the application of the decluniupp() operation on a matrix-scalar
744 // multiplication. It restructures the expression \f$ A=decluniupp(B*s1) \f$ to the expression
745 // \f$ A=decluniupp(B)*s1 \f$. In case the given matrix is not a square matrix,
746 // a \a std::invalid_argument exception is thrown.
747 */
748 template< typename MT > // Matrix base type of the expression
decltype(auto)749 inline decltype(auto) decluniupp( const MatScalarMultExpr<MT>& matrix )
750 {
751 BLAZE_FUNCTION_TRACE;
752
753 if( !isSquare( *matrix ) ) {
754 BLAZE_THROW_INVALID_ARGUMENT( "Invalid uniupper matrix specification" );
755 }
756
757 return decluniupp( (*matrix).leftOperand() ) * (*matrix).rightOperand();
758 }
759 /*! \endcond */
760 //*************************************************************************************************
761
762
763 //*************************************************************************************************
764 /*! \cond BLAZE_INTERNAL */
765 /*!\brief Declares the given non-strictly-upper matrix-scalar multiplication expression as
766 // strictly upper.
767 // \ingroup math
768 //
769 // \param matrix The input matrix-scalar multiplication expression.
770 // \return The redeclared expression.
771 // \exception std::invalid_argument Invalid strictly upper matrix specification.
772 //
773 // This function implements the application of the declstrupp() operation on a matrix-scalar
774 // multiplication. It restructures the expression \f$ A=declstrupp(B*s1) \f$ to the expression
775 // \f$ A=declstrupp(B)*s1 \f$. In case the given matrix is not a square matrix,
776 // a \a std::invalid_argument exception is thrown.
777 */
778 template< typename MT > // Matrix base type of the expression
decltype(auto)779 inline decltype(auto) declstrupp( const MatScalarMultExpr<MT>& matrix )
780 {
781 BLAZE_FUNCTION_TRACE;
782
783 if( !isSquare( *matrix ) ) {
784 BLAZE_THROW_INVALID_ARGUMENT( "Invalid strictly upper matrix specification" );
785 }
786
787 return declstrupp( (*matrix).leftOperand() ) * (*matrix).rightOperand();
788 }
789 /*! \endcond */
790 //*************************************************************************************************
791
792
793 //*************************************************************************************************
794 /*! \cond BLAZE_INTERNAL */
795 /*!\brief Declares the given non-diagonal matrix-scalar multiplication expression as diagonal.
796 // \ingroup math
797 //
798 // \param matrix The input matrix-scalar multiplication expression.
799 // \return The redeclared expression.
800 // \exception std::invalid_argument Invalid diagonal matrix specification.
801 //
802 // This function implements the application of the decldiag() operation on a matrix-scalar
803 // multiplication. It restructures the expression \f$ A=decldiag(B*s1) \f$ to the expression
804 // \f$ A=decldiag(B)*s1 \f$. In case the given matrix is not a square matrix,
805 // a \a std::invalid_argument exception is thrown.
806 */
807 template< typename MT > // Matrix base type of the expression
decltype(auto)808 inline decltype(auto) decldiag( const MatScalarMultExpr<MT>& matrix )
809 {
810 BLAZE_FUNCTION_TRACE;
811
812 if( !isSquare( *matrix ) ) {
813 BLAZE_THROW_INVALID_ARGUMENT( "Invalid diagonal matrix specification" );
814 }
815
816 return decldiag( (*matrix).leftOperand() ) * (*matrix).rightOperand();
817 }
818 /*! \endcond */
819 //*************************************************************************************************
820
821 } // namespace blaze
822
823 #endif
824