1 //=================================================================================================
2 /*!
3 // \file blaze/math/expressions/DVecMapExpr.h
4 // \brief Header file for the dense vector map expression
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_DVECMAPEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_DVECMAPEXPR_H_
37
38
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42
43 #include <iterator>
44 #include <utility>
45 #include <blaze/math/Aliases.h>
46 #include <blaze/math/constraints/DenseVector.h>
47 #include <blaze/math/constraints/RequiresEvaluation.h>
48 #include <blaze/math/constraints/TransposeFlag.h>
49 #include <blaze/math/Exception.h>
50 #include <blaze/math/expressions/Computation.h>
51 #include <blaze/math/expressions/DenseVector.h>
52 #include <blaze/math/expressions/Forward.h>
53 #include <blaze/math/expressions/VecMapExpr.h>
54 #include <blaze/math/Functors.h>
55 #include <blaze/math/shims/Serial.h>
56 #include <blaze/math/SIMD.h>
57 #include <blaze/math/traits/AddTrait.h>
58 #include <blaze/math/traits/DivTrait.h>
59 #include <blaze/math/traits/MapTrait.h>
60 #include <blaze/math/traits/MultTrait.h>
61 #include <blaze/math/traits/SubTrait.h>
62 #include <blaze/math/typetraits/HasLoad.h>
63 #include <blaze/math/typetraits/IsAligned.h>
64 #include <blaze/math/typetraits/IsComputation.h>
65 #include <blaze/math/typetraits/IsExpression.h>
66 #include <blaze/math/typetraits/IsPadded.h>
67 #include <blaze/math/typetraits/IsPaddingEnabled.h>
68 #include <blaze/math/typetraits/IsScalar.h>
69 #include <blaze/math/typetraits/IsSIMDEnabled.h>
70 #include <blaze/math/typetraits/RequiresEvaluation.h>
71 #include <blaze/math/typetraits/UnderlyingScalar.h>
72 #include <blaze/system/HostDevice.h>
73 #include <blaze/system/Inline.h>
74 #include <blaze/system/MacroDisable.h>
75 #include <blaze/util/Assert.h>
76 #include <blaze/util/EnableIf.h>
77 #include <blaze/util/FunctionTrace.h>
78 #include <blaze/util/IntegralConstant.h>
79 #include <blaze/util/mpl/If.h>
80 #include <blaze/util/Types.h>
81 #include <blaze/util/typetraits/IsNumeric.h>
82 #include <blaze/util/typetraits/IsSame.h>
83
84
85 namespace blaze {
86
87 //=================================================================================================
88 //
89 // CLASS DVECMAPEXPR
90 //
91 //=================================================================================================
92
93 //*************************************************************************************************
94 /*!\brief Expression object for the dense vector map() function.
95 // \ingroup dense_vector_expression
96 //
97 // The DVecMapExpr class represents the compile time expression for the evaluation of a custom
98 // operation on each element of a dense vector via the map() function.
99 */
100 template< typename VT // Type of the dense vector
101 , typename OP // Type of the custom operation
102 , bool TF > // Transpose flag
103 class DVecMapExpr
104 : public VecMapExpr< DenseVector< DVecMapExpr<VT,OP,TF>, TF > >
105 , private Computation
106 {
107 private:
108 //**Type definitions****************************************************************************
109 using RT = ResultType_t<VT>; //!< Result type of the dense vector expression.
110 using ET = ElementType_t<VT>; //!< Element type of the dense vector expression.
111 using RN = ReturnType_t<VT>; //!< Return type of the dense vector expression.
112 //**********************************************************************************************
113
114 //**Serial evaluation strategy******************************************************************
115 //! Compilation switch for the serial evaluation strategy of the map expression.
116 /*! The \a useAssign compile time constant expression represents a compilation switch for
117 the serial evaluation strategy of the map expression. In case the given dense vector
118 expression of type \a VT is a computation expression and requires an intermediate
119 evaluation, \a useAssign will be set to 1 and the map expression will be evaluated
120 via the \a assign function family. Otherwise \a useAssign will be set to 0 and the
121 expression will be evaluated via the subscript operator. */
122 static constexpr bool useAssign = ( IsComputation_v<VT> && RequiresEvaluation_v<VT> );
123
124 /*! \cond BLAZE_INTERNAL */
125 //! Helper variable template for the explicit application of the SFINAE principle.
126 template< typename VT2 >
127 static constexpr bool UseAssign_v = useAssign;
128 /*! \endcond */
129 //**********************************************************************************************
130
131 //**Parallel evaluation strategy****************************************************************
132 /*! \cond BLAZE_INTERNAL */
133 //! Helper variable template for the explicit application of the SFINAE principle.
134 /*! This variable template is a helper for the selection of the parallel evaluation strategy.
135 In case either the target vector or the dense vector operand is not SMP assignable and
136 the vector operand requires an intermediate evaluation, the variable is set to 1 and the
137 expression specific evaluation strategy is selected. Otherwise the variable is set to 0
138 and the default strategy is chosen. */
139 template< typename VT2 >
140 static constexpr bool UseSMPAssign_v =
141 ( ( !VT2::smpAssignable || !VT::smpAssignable ) && useAssign );
142 /*! \endcond */
143 //**********************************************************************************************
144
145 public:
146 //**Type definitions****************************************************************************
147 //! Type of this DVecMapExpr instance.
148 using This = DVecMapExpr<VT,OP,TF>;
149
150 //! Base type of this DVecMapExpr instance.
151 using BaseType = VecMapExpr< DenseVector<This,TF> >;
152
153 using ResultType = MapTrait_t<RT,OP>; //!< Result type for expression template evaluations.
154 using TransposeType = TransposeType_t<ResultType>; //!< Transpose type for expression template evaluations.
155 using ElementType = ElementType_t<ResultType>; //!< Resulting element type.
156
157 //! Return type for expression template evaluations.
158 using ReturnType = decltype( std::declval<OP>()( std::declval<RN>() ) );
159
160 //! Data type for composite expression templates.
161 using CompositeType = If_t< useAssign, const ResultType, const DVecMapExpr& >;
162
163 //! Composite data type of the dense vector expression.
164 using Operand = If_t< IsExpression_v<VT>, const VT, const VT& >;
165
166 //! Data type of the custom unary operation.
167 using Operation = OP;
168 //**********************************************************************************************
169
170 //**ConstIterator class definition**************************************************************
171 /*!\brief Iterator over the elements of the dense vector map expression.
172 */
173 class ConstIterator
174 {
175 public:
176 //**Type definitions*************************************************************************
177 using IteratorCategory = std::random_access_iterator_tag; //!< The iterator category.
178 using ValueType = ElementType; //!< Type of the underlying elements.
179 using PointerType = ElementType*; //!< Pointer return type.
180 using ReferenceType = ElementType&; //!< Reference return type.
181 using DifferenceType = ptrdiff_t; //!< Difference between two iterators.
182
183 // STL iterator requirements
184 using iterator_category = IteratorCategory; //!< The iterator category.
185 using value_type = ValueType; //!< Type of the underlying elements.
186 using pointer = PointerType; //!< Pointer return type.
187 using reference = ReferenceType; //!< Reference return type.
188 using difference_type = DifferenceType; //!< Difference between two iterators.
189
190 //! ConstIterator type of the left-hand side dense vector expression.
191 using IteratorType = ConstIterator_t<VT>;
192 //*******************************************************************************************
193
194 //**Constructor******************************************************************************
195 /*!\brief Constructor for the ConstIterator class.
196 //
197 // \param it Iterator to the initial vector element.
198 // \param op The custom unary operation.
199 */
ConstIterator(IteratorType it,OP op)200 inline BLAZE_DEVICE_CALLABLE ConstIterator( IteratorType it, OP op )
201 : it_( it ) // Iterator to the current vector element
202 , op_( std::move(op) ) // The custom unary operation
203 {}
204 //*******************************************************************************************
205
206 //**Addition assignment operator*************************************************************
207 /*!\brief Addition assignment operator.
208 //
209 // \param inc The increment of the iterator.
210 // \return The incremented iterator.
211 */
212 inline BLAZE_DEVICE_CALLABLE ConstIterator& operator+=( size_t inc ) {
213 it_ += inc;
214 return *this;
215 }
216 //*******************************************************************************************
217
218 //**Subtraction assignment operator**********************************************************
219 /*!\brief Subtraction assignment operator.
220 //
221 // \param dec The decrement of the iterator.
222 // \return The decremented iterator.
223 */
224 inline BLAZE_DEVICE_CALLABLE ConstIterator& operator-=( size_t dec ) {
225 it_ -= dec;
226 return *this;
227 }
228 //*******************************************************************************************
229
230 //**Prefix increment operator****************************************************************
231 /*!\brief Pre-increment operator.
232 //
233 // \return Reference to the incremented iterator.
234 */
235 inline BLAZE_DEVICE_CALLABLE ConstIterator& operator++() {
236 ++it_;
237 return *this;
238 }
239 //*******************************************************************************************
240
241 //**Postfix increment operator***************************************************************
242 /*!\brief Post-increment operator.
243 //
244 // \return The previous position of the iterator.
245 */
246 inline BLAZE_DEVICE_CALLABLE const ConstIterator operator++( int ) {
247 return ConstIterator( it_++, op_ );
248 }
249 //*******************************************************************************************
250
251 //**Prefix decrement operator****************************************************************
252 /*!\brief Pre-decrement operator.
253 //
254 // \return Reference to the decremented iterator.
255 */
256 inline BLAZE_DEVICE_CALLABLE ConstIterator& operator--() {
257 --it_;
258 return *this;
259 }
260 //*******************************************************************************************
261
262 //**Postfix decrement operator***************************************************************
263 /*!\brief Post-decrement operator.
264 //
265 // \return The previous position of the iterator.
266 */
267 inline BLAZE_DEVICE_CALLABLE const ConstIterator operator--( int ) {
268 return ConstIterator( it_--, op_ );
269 }
270 //*******************************************************************************************
271
272 //**Element access operator******************************************************************
273 /*!\brief Direct access to the element at the current iterator position.
274 //
275 // \return The resulting value.
276 */
277 inline BLAZE_DEVICE_CALLABLE ReturnType operator*() const {
278 return op_( *it_ );
279 }
280 //*******************************************************************************************
281
282 //**Load function****************************************************************************
283 /*!\brief Access to the SIMD elements of the vector.
284 //
285 // \return The resulting SIMD element.
286 */
load()287 inline auto load() const noexcept {
288 return op_.load( it_.load() );
289 }
290 //*******************************************************************************************
291
292 //**Equality operator************************************************************************
293 /*!\brief Equality comparison between two ConstIterator objects.
294 //
295 // \param rhs The right-hand side iterator.
296 // \return \a true if the iterators refer to the same element, \a false if not.
297 */
298 inline BLAZE_DEVICE_CALLABLE bool operator==( const ConstIterator& rhs ) const {
299 return it_ == rhs.it_;
300 }
301 //*******************************************************************************************
302
303 //**Inequality operator**********************************************************************
304 /*!\brief Inequality comparison between two ConstIterator objects.
305 //
306 // \param rhs The right-hand side iterator.
307 // \return \a true if the iterators don't refer to the same element, \a false if they do.
308 */
309 inline BLAZE_DEVICE_CALLABLE bool operator!=( const ConstIterator& rhs ) const {
310 return it_ != rhs.it_;
311 }
312 //*******************************************************************************************
313
314 //**Less-than operator***********************************************************************
315 /*!\brief Less-than comparison between two ConstIterator objects.
316 //
317 // \param rhs The right-hand side iterator.
318 // \return \a true if the left-hand side iterator is smaller, \a false if not.
319 */
320 inline BLAZE_DEVICE_CALLABLE bool operator<( const ConstIterator& rhs ) const {
321 return it_ < rhs.it_;
322 }
323 //*******************************************************************************************
324
325 //**Greater-than operator********************************************************************
326 /*!\brief Greater-than comparison between two ConstIterator objects.
327 //
328 // \param rhs The right-hand side iterator.
329 // \return \a true if the left-hand side iterator is greater, \a false if not.
330 */
331 inline BLAZE_DEVICE_CALLABLE bool operator>( const ConstIterator& rhs ) const {
332 return it_ > rhs.it_;
333 }
334 //*******************************************************************************************
335
336 //**Less-or-equal-than operator**************************************************************
337 /*!\brief Less-than comparison between two ConstIterator objects.
338 //
339 // \param rhs The right-hand side iterator.
340 // \return \a true if the left-hand side iterator is smaller or equal, \a false if not.
341 */
342 inline BLAZE_DEVICE_CALLABLE bool operator<=( const ConstIterator& rhs ) const {
343 return it_ <= rhs.it_;
344 }
345 //*******************************************************************************************
346
347 //**Greater-or-equal-than operator***********************************************************
348 /*!\brief Greater-than comparison between two ConstIterator objects.
349 //
350 // \param rhs The right-hand side iterator.
351 // \return \a true if the left-hand side iterator is greater or equal, \a false if not.
352 */
353 inline BLAZE_DEVICE_CALLABLE bool operator>=( const ConstIterator& rhs ) const {
354 return it_ >= rhs.it_;
355 }
356 //*******************************************************************************************
357
358 //**Subtraction operator*********************************************************************
359 /*!\brief Calculating the number of elements between two iterators.
360 //
361 // \param rhs The right-hand side iterator.
362 // \return The number of elements between the two iterators.
363 */
364 inline BLAZE_DEVICE_CALLABLE DifferenceType operator-( const ConstIterator& rhs ) const {
365 return it_ - rhs.it_;
366 }
367 //*******************************************************************************************
368
369 //**Addition operator************************************************************************
370 /*!\brief Addition between a ConstIterator and an integral value.
371 //
372 // \param it The iterator to be incremented.
373 // \param inc The number of elements the iterator is incremented.
374 // \return The incremented iterator.
375 */
376 friend inline BLAZE_DEVICE_CALLABLE const ConstIterator operator+( const ConstIterator& it, size_t inc ) {
377 return ConstIterator( it.it_ + inc, it.op_ );
378 }
379 //*******************************************************************************************
380
381 //**Addition operator************************************************************************
382 /*!\brief Addition between an integral value and a ConstIterator.
383 //
384 // \param inc The number of elements the iterator is incremented.
385 // \param it The iterator to be incremented.
386 // \return The incremented iterator.
387 */
388 friend inline BLAZE_DEVICE_CALLABLE const ConstIterator operator+( size_t inc, const ConstIterator& it ) {
389 return ConstIterator( it.it_ + inc, it.op_ );
390 }
391 //*******************************************************************************************
392
393 //**Subtraction operator*********************************************************************
394 /*!\brief Subtraction between a ConstIterator and an integral value.
395 //
396 // \param it The iterator to be decremented.
397 // \param dec The number of elements the iterator is decremented.
398 // \return The decremented iterator.
399 */
400 friend inline BLAZE_DEVICE_CALLABLE const ConstIterator operator-( const ConstIterator& it, size_t dec ) {
401 return ConstIterator( it.it_ - dec, it.op_ );
402 }
403 //*******************************************************************************************
404
405 private:
406 //**Member variables*************************************************************************
407 IteratorType it_; //!< Iterator to the current vector element.
408 OP op_; //!< The custom unary operation.
409 //*******************************************************************************************
410 };
411 //**********************************************************************************************
412
413 public:
414 //**Compilation flags***************************************************************************
415 //! Compilation switch for the expression template evaluation strategy.
416 static constexpr bool simdEnabled =
417 ( VT::simdEnabled &&
418 If_t< HasSIMDEnabled_v<OP>, GetSIMDEnabled<OP,ET>, HasLoad<OP> >::value );
419
420 //! Compilation switch for the expression template assignment strategy.
421 static constexpr bool smpAssignable = VT::smpAssignable;
422 //**********************************************************************************************
423
424 //**SIMD properties*****************************************************************************
425 //! The number of elements packed within a single SIMD element.
426 static constexpr size_t SIMDSIZE = SIMDTrait<ElementType>::size;
427 //**********************************************************************************************
428
429 //**Constructor*********************************************************************************
430 /*!\brief Constructor for the DVecMapExpr class.
431 //
432 // \param dv The dense vector operand of the map expression.
433 // \param op The custom unary operation.
434 */
DVecMapExpr(const VT & dv,OP op)435 inline DVecMapExpr( const VT& dv, OP op ) noexcept
436 : dv_( dv ) // Dense vector of the map expression
437 , op_( std::move(op) ) // The custom unary operation
438 {}
439 //**********************************************************************************************
440
441 //**Subscript operator**************************************************************************
442 /*!\brief Subscript operator for the direct access to the vector elements.
443 //
444 // \param index Access index. The index has to be in the range \f$[0..N-1]\f$.
445 // \return The resulting value.
446 */
447 inline ReturnType operator[]( size_t index ) const {
448 BLAZE_INTERNAL_ASSERT( index < dv_.size(), "Invalid vector access index" );
449 return op_( dv_[index] );
450 }
451 //**********************************************************************************************
452
453 //**At function*********************************************************************************
454 /*!\brief Checked access to the vector elements.
455 //
456 // \param index Access index. The index has to be in the range \f$[0..N-1]\f$.
457 // \return The resulting value.
458 // \exception std::out_of_range Invalid vector access index.
459 */
at(size_t index)460 inline ReturnType at( size_t index ) const {
461 if( index >= dv_.size() ) {
462 BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
463 }
464 return (*this)[index];
465 }
466 //**********************************************************************************************
467
468 //**Load function*******************************************************************************
469 /*!\brief Access to the SIMD elements of the vector.
470 //
471 // \param index Access index. The index has to be in the range \f$[0..N-1]\f$.
472 // \return Reference to the accessed values.
473 */
load(size_t index)474 BLAZE_ALWAYS_INLINE auto load( size_t index ) const noexcept {
475 BLAZE_INTERNAL_ASSERT( index < dv_.size() , "Invalid vector access index" );
476 BLAZE_INTERNAL_ASSERT( index % SIMDSIZE == 0UL, "Invalid vector access index" );
477 return op_.load( dv_.load( index ) );
478 }
479 //**********************************************************************************************
480
481 //**Begin function******************************************************************************
482 /*!\brief Returns an iterator to the first non-zero element of the dense vector.
483 //
484 // \return Iterator to the first non-zero element of the dense vector.
485 */
begin()486 inline ConstIterator begin() const {
487 return ConstIterator( dv_.begin(), op_ );
488 }
489 //**********************************************************************************************
490
491 //**End function********************************************************************************
492 /*!\brief Returns an iterator just past the last non-zero element of the dense vector.
493 //
494 // \return Iterator just past the last non-zero element of the dense vector.
495 */
end()496 inline ConstIterator end() const {
497 return ConstIterator( dv_.end(), op_ );
498 }
499 //**********************************************************************************************
500
501 //**Size function*******************************************************************************
502 /*!\brief Returns the current size/dimension of the vector.
503 //
504 // \return The size of the vector.
505 */
size()506 inline size_t size() const noexcept {
507 return dv_.size();
508 }
509 //**********************************************************************************************
510
511 //**Operand access******************************************************************************
512 /*!\brief Returns the dense vector operand.
513 //
514 // \return The dense vector operand.
515 */
operand()516 inline Operand operand() const noexcept {
517 return dv_;
518 }
519 //**********************************************************************************************
520
521 //**Operation access****************************************************************************
522 /*!\brief Returns a copy of the custom operation.
523 //
524 // \return A copy of the custom operation.
525 */
operation()526 inline Operation operation() const {
527 return op_;
528 }
529 //**********************************************************************************************
530
531 //**********************************************************************************************
532 /*!\brief Returns whether the expression can alias with the given address \a alias.
533 //
534 // \param alias The alias to be checked.
535 // \return \a true in case the expression can alias, \a false otherwise.
536 */
537 template< typename T >
canAlias(const T * alias)538 inline bool canAlias( const T* alias ) const noexcept {
539 return IsExpression_v<VT> && dv_.canAlias( alias );
540 }
541 //**********************************************************************************************
542
543 //**********************************************************************************************
544 /*!\brief Returns whether the expression is aliased with the given address \a alias.
545 //
546 // \param alias The alias to be checked.
547 // \return \a true in case an alias effect is detected, \a false otherwise.
548 */
549 template< typename T >
isAliased(const T * alias)550 inline bool isAliased( const T* alias ) const noexcept {
551 return dv_.isAliased( alias );
552 }
553 //**********************************************************************************************
554
555 //**********************************************************************************************
556 /*!\brief Returns whether the operands of the expression are properly aligned in memory.
557 //
558 // \return \a true in case the operands are aligned, \a false if not.
559 */
isAligned()560 inline bool isAligned() const noexcept {
561 return dv_.isAligned();
562 }
563 //**********************************************************************************************
564
565 //**********************************************************************************************
566 /*!\brief Returns whether the expression can be used in SMP assignments.
567 //
568 // \return \a true in case the expression can be used in SMP assignments, \a false if not.
569 */
canSMPAssign()570 inline bool canSMPAssign() const noexcept {
571 return dv_.canSMPAssign();
572 }
573 //**********************************************************************************************
574
575 private:
576 //**Member variables****************************************************************************
577 Operand dv_; //!< Dense vector of the map expression.
578 Operation op_; //!< The custom unary operation.
579 //**********************************************************************************************
580
581 //**Assignment to dense vectors*****************************************************************
582 /*! \cond BLAZE_INTERNAL */
583 /*!\brief Assignment of a dense vector map expression to a dense vector.
584 // \ingroup dense_vector
585 //
586 // \param lhs The target left-hand side dense vector.
587 // \param rhs The right-hand side map expression to be assigned.
588 // \return void
589 //
590 // This function implements the performance optimized assignment of a dense vector map
591 // expression to a dense vector. Due to the explicit application of the SFINAE principle,
592 // this function can only be selected by the compiler in case the operand requires an
593 // intermediate evaluation and the underlying numeric data type of the operand and the
594 // target vector are identical.
595 */
596 template< typename VT2 > // Type of the target dense vector
597 friend inline auto assign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
598 -> EnableIf_t< UseAssign_v<VT2> &&
599 IsSame_v< UnderlyingScalar_t<VT>, UnderlyingScalar_t<VT2> > >
600 {
601 BLAZE_FUNCTION_TRACE;
602
603 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
604
605 assign( *lhs, rhs.dv_ );
606 assign( *lhs, map( *lhs, rhs.op_ ) );
607 }
608 /*! \endcond */
609 //**********************************************************************************************
610
611 //**Assignment to dense vectors*****************************************************************
612 /*! \cond BLAZE_INTERNAL */
613 /*!\brief Assignment of a dense vector map expression to a dense vector.
614 // \ingroup dense_vector
615 //
616 // \param lhs The target left-hand side dense vector.
617 // \param rhs The right-hand side map expression to be assigned.
618 // \return void
619 //
620 // This function implements the performance optimized assignment of a dense vector map
621 // expression to a dense vector. Due to the explicit application of the SFINAE principle,
622 // this function can only be selected by the compiler in case the operand requires an
623 // intermediate evaluation and the underlying numeric data type of the operand and the
624 // target vector differ.
625 */
626 template< typename VT2 > // Type of the target dense vector
627 friend inline auto assign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
628 -> EnableIf_t< UseAssign_v<VT2> &&
629 !IsSame_v< UnderlyingScalar_t<VT>, UnderlyingScalar_t<VT2> > >
630 {
631 BLAZE_FUNCTION_TRACE;
632
633 BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
634 BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
635 BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
636
637 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
638
639 const RT tmp( serial( rhs.dv_ ) );
640 assign( *lhs, map( tmp, rhs.op_ ) );
641 }
642 /*! \endcond */
643 //**********************************************************************************************
644
645 //**Assignment to sparse vectors****************************************************************
646 /*! \cond BLAZE_INTERNAL */
647 /*!\brief Assignment of a dense vector map expression to a sparse vector.
648 // \ingroup dense_vector
649 //
650 // \param lhs The target left-hand side sparse vector.
651 // \param rhs The right-hand side map expression to be assigned.
652 // \return void
653 //
654 // This function implements the performance optimized assignment of a dense vector map
655 // expression to a sparse vector. Due to the explicit application of the SFINAE principle,
656 // this function can only be selected by the compiler in case the operand requires an
657 // intermediate evaluation.
658 */
659 template< typename VT2 > // Type of the target sparse vector
660 friend inline auto assign( SparseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
661 -> EnableIf_t< UseAssign_v<VT2> >
662 {
663 BLAZE_FUNCTION_TRACE;
664
665 BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
666 BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
667 BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
668
669 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
670
671 const RT tmp( serial( rhs.dv_ ) );
672 assign( *lhs, map( tmp, rhs.op_ ) );
673 }
674 /*! \endcond */
675 //**********************************************************************************************
676
677 //**Addition assignment to dense vectors********************************************************
678 /*! \cond BLAZE_INTERNAL */
679 /*!\brief Addition assignment of a dense vector map expression to a dense vector.
680 // \ingroup dense_vector
681 //
682 // \param lhs The target left-hand side dense vector.
683 // \param rhs The right-hand side map expression to be added.
684 // \return void
685 //
686 // This function implements the performance optimized addition assignment of a dense vector
687 // map expression to a dense vector. Due to the explicit application of the SFINAE principle,
688 // this function can only be selected by the compiler in case the operand requires an
689 // intermediate evaluation.
690 */
691 template< typename VT2 > // Type of the target dense vector
692 friend inline auto addAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
693 -> EnableIf_t< UseAssign_v<VT2> >
694 {
695 BLAZE_FUNCTION_TRACE;
696
697 BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
698 BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
699 BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
700
701 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
702
703 const RT tmp( serial( rhs.dv_ ) );
704 addAssign( *lhs, map( tmp, rhs.op_ ) );
705 }
706 /*! \endcond */
707 //**********************************************************************************************
708
709 //**Addition assignment to sparse vectors*******************************************************
710 // No special implementation for the addition assignment to sparse vectors.
711 //**********************************************************************************************
712
713 //**Subtraction assignment to dense vectors*****************************************************
714 /*! \cond BLAZE_INTERNAL */
715 /*!\brief Subtraction assignment of a dense vector map expression to a dense vector.
716 // \ingroup dense_vector
717 //
718 // \param lhs The target left-hand side dense vector.
719 // \param rhs The right-hand side map expression to be subtracted.
720 // \return void
721 //
722 // This function implements the performance optimized subtraction assignment of a dense
723 // vector map expression to a dense vector. Due to the explicit application of the SFINAE
724 // principle, this function can only be selected by the compiler in case the operand
725 // requires an intermediate evaluation.
726 */
727 template< typename VT2 > // Type of the target dense vector
728 friend inline auto subAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
729 -> EnableIf_t< UseAssign_v<VT2> >
730 {
731 BLAZE_FUNCTION_TRACE;
732
733 BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
734 BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
735 BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
736
737 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
738
739 const RT tmp( serial( rhs.dv_ ) );
740 subAssign( *lhs, map( tmp, rhs.op_ ) );
741 }
742 /*! \endcond */
743 //**********************************************************************************************
744
745 //**Subtraction assignment to sparse vectors****************************************************
746 // No special implementation for the subtraction assignment to sparse vectors.
747 //**********************************************************************************************
748
749 //**Multiplication assignment to dense vectors**************************************************
750 /*! \cond BLAZE_INTERNAL */
751 /*!\brief Multiplication assignment of a dense vector map expression to a dense vector.
752 // \ingroup dense_vector
753 //
754 // \param lhs The target left-hand side dense vector.
755 // \param rhs The right-hand side map expression to be multiplied.
756 // \return void
757 //
758 // This function implements the performance optimized multiplication assignment of a dense
759 // vector map expression to a dense vector. Due to the explicit application of the SFINAE
760 // principle, this function can only be selected by the compiler in case the operand requires
761 // an intermediate evaluation.
762 */
763 template< typename VT2 > // Type of the target dense vector
764 friend inline auto multAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
765 -> EnableIf_t< UseAssign_v<VT2> >
766 {
767 BLAZE_FUNCTION_TRACE;
768
769 BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
770 BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
771 BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
772
773 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
774
775 const RT tmp( serial( rhs.dv_ ) );
776 multAssign( *lhs, map( tmp, rhs.op_ ) );
777 }
778 /*! \endcond */
779 //**********************************************************************************************
780
781 //**Multiplication assignment to sparse vectors*************************************************
782 // No special implementation for the multiplication assignment to sparse vectors.
783 //**********************************************************************************************
784
785 //**Division assignment to dense vectors********************************************************
786 /*! \cond BLAZE_INTERNAL */
787 /*!\brief Division assignment of a dense vector map expression to a dense vector.
788 // \ingroup dense_vector
789 //
790 // \param lhs The target left-hand side dense vector.
791 // \param rhs The right-hand side map expression divisor.
792 // \return void
793 //
794 // This function implements the performance optimized division assignment of a dense vector
795 // map expression to a dense vector. Due to the explicit application of the SFINAE principle,
796 // this function can only be selected by the compiler in case the operand requires an
797 // intermediate evaluation.
798 */
799 template< typename VT2 > // Type of the target dense vector
800 friend inline auto divAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
801 -> EnableIf_t< UseAssign_v<VT2> >
802 {
803 BLAZE_FUNCTION_TRACE;
804
805 BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
806 BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
807 BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
808
809 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
810
811 const RT tmp( serial( rhs.dv_ ) );
812 divAssign( *lhs, map( tmp, rhs.op_ ) );
813 }
814 /*! \endcond */
815 //**********************************************************************************************
816
817 //**Division assignment to sparse vectors*******************************************************
818 // No special implementation for the division assignment to sparse vectors.
819 //**********************************************************************************************
820
821 //**SMP assignment to dense vectors*************************************************************
822 /*! \cond BLAZE_INTERNAL */
823 /*!\brief SMP assignment of a dense vector map expression to a dense vector.
824 // \ingroup dense_vector
825 //
826 // \param lhs The target left-hand side dense vector.
827 // \param rhs The right-hand side map expression to be assigned.
828 // \return void
829 //
830 // This function implements the performance optimized SMP assignment of a dense vector map
831 // expression to a dense vector. Due to the explicit application of the SFINAE principle,
832 // this function can only be selected by the compiler in case the expression specific parallel
833 // evaluation strategy is selected and the underlying numeric data type of the operand and the
834 // target vector are identical
835 */
836 template< typename VT2 > // Type of the target dense vector
837 friend inline auto smpAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
838 -> EnableIf_t< UseSMPAssign_v<VT2> &&
839 IsSame_v< UnderlyingScalar_t<VT>, UnderlyingScalar_t<VT2> > >
840 {
841 BLAZE_FUNCTION_TRACE;
842
843 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
844
845 smpAssign( *lhs, rhs.dv_ );
846 smpAssign( *lhs, map( *lhs, rhs.op_ ) );
847 }
848 /*! \endcond */
849 //**********************************************************************************************
850
851 //**SMP assignment to dense vectors*************************************************************
852 /*! \cond BLAZE_INTERNAL */
853 /*!\brief SMP assignment of a dense vector map expression to a dense vector.
854 // \ingroup dense_vector
855 //
856 // \param lhs The target left-hand side dense vector.
857 // \param rhs The right-hand side map expression to be assigned.
858 // \return void
859 //
860 // This function implements the performance optimized SMP assignment of a dense vector map
861 // expression to a dense vector. Due to the explicit application of the SFINAE principle,
862 // this function can only be selected by the compiler in case the expression specific parallel
863 // evaluation strategy is selected and the underlying numeric data type of the operand and the
864 // target vector differ.
865 */
866 template< typename VT2 > // Type of the target dense vector
867 friend inline auto smpAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
868 -> EnableIf_t< UseSMPAssign_v<VT2> &&
869 !IsSame_v< UnderlyingScalar_t<VT>, UnderlyingScalar_t<VT2> > >
870 {
871 BLAZE_FUNCTION_TRACE;
872
873 BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
874 BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
875 BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
876
877 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
878
879 const RT tmp( rhs.dv_ );
880 smpAssign( *lhs, map( tmp, rhs.op_ ) );
881 }
882 /*! \endcond */
883 //**********************************************************************************************
884
885 //**SMP assignment to sparse vectors************************************************************
886 /*! \cond BLAZE_INTERNAL */
887 /*!\brief SMP assignment of a dense vector map expression to a sparse vector.
888 // \ingroup dense_vector
889 //
890 // \param lhs The target left-hand side sparse vector.
891 // \param rhs The right-hand side map expression to be assigned.
892 // \return void
893 //
894 // This function implements the performance optimized SMP assignment of a dense vector map
895 // expression to a sparse vector. Due to the explicit application of the SFINAE principle,
896 // this function can only be selected by the compiler in case the expression specific parallel
897 // evaluation strategy is selected.
898 */
899 template< typename VT2 > // Type of the target sparse vector
900 friend inline auto smpAssign( SparseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
901 -> EnableIf_t< UseSMPAssign_v<VT2> >
902 {
903 BLAZE_FUNCTION_TRACE;
904
905 BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
906 BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
907 BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
908
909 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
910
911 const RT tmp( rhs.dv_ );
912 smpAssign( *lhs, map( tmp, rhs.op_ ) );
913 }
914 /*! \endcond */
915 //**********************************************************************************************
916
917 //**SMP addition assignment to dense vectors****************************************************
918 /*! \cond BLAZE_INTERNAL */
919 /*!\brief SMP addition assignment of a dense vector map expression to a dense vector.
920 // \ingroup dense_vector
921 //
922 // \param lhs The target left-hand side dense vector.
923 // \param rhs The right-hand side map expression to be added.
924 // \return void
925 //
926 // This function implements the performance optimized SMP addition assignment of a dense
927 // vector map expression to a dense vector. Due to the explicit application of the SFINAE
928 // principle, this function can only be selected by the compiler in case the expression
929 // specific parallel evaluation strategy is selected.
930 */
931 template< typename VT2 > // Type of the target dense vector
932 friend inline auto smpAddAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
933 -> EnableIf_t< UseSMPAssign_v<VT2> >
934 {
935 BLAZE_FUNCTION_TRACE;
936
937 BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
938 BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
939 BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
940
941 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
942
943 const RT tmp( rhs.dv_ );
944 smpAddAssign( *lhs, map( tmp, rhs.op_ ) );
945 }
946 /*! \endcond */
947 //**********************************************************************************************
948
949 //**SMP addition assignment to sparse vectors***************************************************
950 // No special implementation for the SMP addition assignment to sparse vectors.
951 //**********************************************************************************************
952
953 //**SMP subtraction assignment to dense vectors*************************************************
954 /*! \cond BLAZE_INTERNAL */
955 /*!\brief SMP subtraction assignment of a dense vector map expression to a dense vector.
956 // \ingroup dense_vector
957 //
958 // \param lhs The target left-hand side dense vector.
959 // \param rhs The right-hand side map expression to be subtracted.
960 // \return void
961 //
962 // This function implements the performance optimized SMP subtraction assignment of a dense
963 // vector map expression to a dense vector. Due to the explicit application of the SFINAE
964 // principle, this function can only be selected by the compiler in case the expression
965 // specific parallel evaluation strategy is selected.
966 */
967 template< typename VT2 > // Type of the target dense vector
968 friend inline auto smpSubAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
969 -> EnableIf_t< UseSMPAssign_v<VT2> >
970 {
971 BLAZE_FUNCTION_TRACE;
972
973 BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
974 BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
975 BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
976
977 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
978
979 const RT tmp( rhs.dv_ );
980 smpSubAssign( *lhs, map( tmp, rhs.op_ ) );
981 }
982 /*! \endcond */
983 //**********************************************************************************************
984
985 //**SMP subtraction assignment to sparse vectors************************************************
986 // No special implementation for the SMP subtraction assignment to sparse vectors.
987 //**********************************************************************************************
988
989 //**SMP multiplication assignment to dense vectors**********************************************
990 /*! \cond BLAZE_INTERNAL */
991 /*!\brief SMP multiplication assignment of a dense vector map expression to a dense vector.
992 // \ingroup dense_vector
993 //
994 // \param lhs The target left-hand side dense vector.
995 // \param rhs The right-hand side map expression to be multiplied.
996 // \return void
997 //
998 // This function implements the performance optimized SMP multiplication assignment of a
999 // dense vector map expression to a dense vector. Due to the explicit application of the
1000 // SFINAE principle, this function can only be selected by the compiler in case the
1001 // expression specific parallel evaluation strategy is selected.
1002 */
1003 template< typename VT2 > // Type of the target dense vector
1004 friend inline auto smpMultAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
1005 -> EnableIf_t< UseSMPAssign_v<VT2> >
1006 {
1007 BLAZE_FUNCTION_TRACE;
1008
1009 BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
1010 BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
1011 BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
1012
1013 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
1014
1015 const RT tmp( rhs.dv_ );
1016 smpMultAssign( *lhs, map( tmp, rhs.op_ ) );
1017 }
1018 /*! \endcond */
1019 //**********************************************************************************************
1020
1021 //**SMP multiplication assignment to sparse vectors*********************************************
1022 // No special implementation for the SMP multiplication assignment to sparse vectors.
1023 //**********************************************************************************************
1024
1025 //**SMP division assignment to dense vectors****************************************************
1026 /*! \cond BLAZE_INTERNAL */
1027 /*!\brief SMP division assignment of a dense vector map expression to a dense vector.
1028 // \ingroup dense_vector
1029 //
1030 // \param lhs The target left-hand side dense vector.
1031 // \param rhs The right-hand side map expression divisor.
1032 // \return void
1033 //
1034 // This function implements the performance optimized SMP division assignment of a dense
1035 // vector map expression to a dense vector. Due to the explicit application of the SFINAE
1036 // principle, this function can only be selected by the compiler in case the expression
1037 // specific parallel evaluation strategy is selected.
1038 */
1039 template< typename VT2 > // Type of the target dense vector
1040 friend inline auto smpDivAssign( DenseVector<VT2,TF>& lhs, const DVecMapExpr& rhs )
1041 -> EnableIf_t< UseSMPAssign_v<VT2> >
1042 {
1043 BLAZE_FUNCTION_TRACE;
1044
1045 BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( RT );
1046 BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
1047 BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
1048
1049 BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
1050
1051 const RT tmp( rhs.dv_ );
1052 smpDivAssign( *lhs, map( tmp, rhs.op_ ) );
1053 }
1054 /*! \endcond */
1055 //**********************************************************************************************
1056
1057 //**SMP division assignment to sparse vectors***************************************************
1058 // No special implementation for the SMP division assignment to sparse vectors.
1059 //**********************************************************************************************
1060
1061 //**Compile time checks*************************************************************************
1062 /*! \cond BLAZE_INTERNAL */
1063 BLAZE_CONSTRAINT_MUST_BE_DENSE_VECTOR_TYPE( VT );
1064 BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( VT, TF );
1065 /*! \endcond */
1066 //**********************************************************************************************
1067 };
1068 //*************************************************************************************************
1069
1070
1071
1072
1073 //=================================================================================================
1074 //
1075 // GLOBAL FUNCTIONS
1076 //
1077 //=================================================================================================
1078
1079 //*************************************************************************************************
1080 /*!\brief Evaluates the given custom operation on each single element of the dense vector \a dv.
1081 // \ingroup dense_vector
1082 //
1083 // \param dv The input vector.
1084 // \param op The custom operation.
1085 // \return The custom operation applied to each single element of \a dv.
1086 //
1087 // The \a map() function evaluates the given custom operation on each element of the input
1088 // vector \a dv. The function returns an expression representing this operation.\n
1089 // The following example demonstrates the use of the \a map() function:
1090
1091 \code
1092 blaze::DynamicVector<double> a, b;
1093 // ... Resizing and initialization
1094 b = map( a, []( double a ){ return std::sqrt( a ); } );
1095 \endcode
1096 */
1097 template< typename VT // Type of the dense vector
1098 , bool TF // Transpose flag
1099 , typename OP > // Type of the custom operation
decltype(auto)1100 inline decltype(auto) map( const DenseVector<VT,TF>& dv, OP op )
1101 {
1102 BLAZE_FUNCTION_TRACE;
1103
1104 using ReturnType = const DVecMapExpr<VT,OP,TF>;
1105 return ReturnType( *dv, std::move(op) );
1106 }
1107 //*************************************************************************************************
1108
1109
1110 //*************************************************************************************************
1111 /*!\brief Evaluates the given custom operation on each single element of the dense vector \a dv.
1112 // \ingroup dense_vector
1113 //
1114 // \param dv The input vector.
1115 // \param op The custom operation.
1116 // \return The custom operation applied to each single element of \a dv.
1117 //
1118 // The \a forEach() function evaluates the given custom operation on each element of the input
1119 // vector \a dv. The function returns an expression representing this operation.\n
1120 // The following example demonstrates the use of the \a forEach() function:
1121
1122 \code
1123 blaze::DynamicVector<double> a, b;
1124 // ... Resizing and initialization
1125 b = forEach( a, []( double a ){ return std::sqrt( a ); } );
1126 \endcode
1127 */
1128 template< typename VT // Type of the dense vector
1129 , bool TF // Transpose flag
1130 , typename OP > // Type of the custom operation
decltype(auto)1131 inline decltype(auto) forEach( const DenseVector<VT,TF>& dv, OP op )
1132 {
1133 BLAZE_FUNCTION_TRACE;
1134
1135 return map( *dv, std::move(op) );
1136 }
1137 //*************************************************************************************************
1138
1139
1140 //*************************************************************************************************
1141 /*!\brief Computes the componentwise minimum of a dense vector \a dv and a scalar.
1142 // \ingroup dense_vector
1143 //
1144 // \param dv The left-hand side dense vector operand.
1145 // \param scalar The right-hand side scalar value.
1146 // \return The resulting dense vector.
1147 //
1148 // This operator computes the componentwise minimum of a dense vector \a dv and a uniform vector
1149 // represented by the scalar value \a scalar. The function returns an expression representing this
1150 // operation.\n
1151 // The following example demonstrates the use of the \a min() function:
1152
1153 \code
1154 blaze::DynamicVector<double> a, b;
1155 // ... Resizing and initialization
1156 b = min( a, 0.0 );
1157 \endcode
1158 */
1159 template< typename VT // Type of the dense vector
1160 , bool TF // Transpose flag
1161 , typename ST // Type of the scalar exponent
1162 , EnableIf_t< IsScalar_v<ST> >* = nullptr >
decltype(auto)1163 decltype(auto) min( const DenseVector<VT,TF>& dv, ST scalar )
1164 {
1165 BLAZE_FUNCTION_TRACE;
1166
1167 using ET = ElementType_t<VT>;
1168 using ScalarType = If_t< IsNumeric_v<ET> && IsNumeric_v<ST>, MapTrait_t<ET,ST,Min>, ST >;
1169 return map( *dv, bind2nd( Min(), ScalarType( scalar ) ) );
1170 }
1171 //*************************************************************************************************
1172
1173
1174 //*************************************************************************************************
1175 /*!\brief Computes the componentwise minimum of a scalar and a dense vector \a dv.
1176 // \ingroup dense_vector
1177 //
1178 // \param scalar The left-hand side scalar value.
1179 // \param dv The right-hand side dense vector operand.
1180 // \return The resulting dense vector.
1181 //
1182 // This operator computes the componentwise minimum of a uniform vector represented by the scalar
1183 // value \a scalar and a dense vector \a dv. The function returns an expression representing this
1184 // operation.\n
1185 // The following example demonstrates the use of the \a min() function:
1186
1187 \code
1188 blaze::DynamicVector<double> a, b;
1189 // ... Resizing and initialization
1190 b = min( 0.0, a );
1191 \endcode
1192 */
1193 template< typename ST // Type of the scalar exponent
1194 , typename VT // Type of the dense vector
1195 , bool TF // Transpose flag
1196 , EnableIf_t< IsScalar_v<ST> >* = nullptr >
decltype(auto)1197 decltype(auto) min( ST scalar, const DenseVector<VT,TF>& dv )
1198 {
1199 BLAZE_FUNCTION_TRACE;
1200
1201 using ET = ElementType_t<VT>;
1202 using ScalarType = If_t< IsNumeric_v<ST> && IsNumeric_v<ET>, MapTrait_t<ST,ET,Min>, ST >;
1203 return map( *dv, bind1st( Min(), ScalarType( scalar ) ) );
1204 }
1205 //*************************************************************************************************
1206
1207
1208 //*************************************************************************************************
1209 /*!\brief Computes the componentwise maximum of a dense vector \a dv and a scalar.
1210 // \ingroup dense_vector
1211 //
1212 // \param dv The left-hand side dense vector operand.
1213 // \param scalar The right-hand side scalar value.
1214 // \return The resulting dense vector.
1215 //
1216 // This operator computes the componentwise maximum of a dense vector \a dv and a uniform vector
1217 // represented by the scalar value \a scalar. The function returns an expression representing this
1218 // operation.\n
1219 // The following example demonstrates the use of the \a max() function:
1220
1221 \code
1222 blaze::DynamicVector<double> a, b;
1223 // ... Resizing and initialization
1224 b = max( a, 0.0 );
1225 \endcode
1226
1227 // In case the current sizes of the two given vectors don't match, a \a std::invalid_argument
1228 // is thrown.
1229 */
1230 template< typename VT // Type of the dense vector
1231 , bool TF // Transpose flag
1232 , typename ST // Type of the scalar exponent
1233 , EnableIf_t< IsScalar_v<ST> >* = nullptr >
decltype(auto)1234 decltype(auto) max( const DenseVector<VT,TF>& dv, ST scalar )
1235 {
1236 BLAZE_FUNCTION_TRACE;
1237
1238 using ET = ElementType_t<VT>;
1239 using ScalarType = If_t< IsNumeric_v<ET> && IsNumeric_v<ST>, MapTrait_t<ET,ST,Max>, ST >;
1240 return map( *dv, bind2nd( Max(), ScalarType( scalar ) ) );
1241 }
1242 //*************************************************************************************************
1243
1244
1245 //*************************************************************************************************
1246 /*!\brief Computes the componentwise maximum of a scalar and a dense vector \a dv.
1247 // \ingroup dense_vector
1248 //
1249 // \param scalar The left-hand side scalar value.
1250 // \param dv The right-hand side dense vector operand.
1251 // \return The resulting dense vector.
1252 //
1253 // This operator computes the componentwise maximum of a uniform vector represented by the scalar
1254 // value \a scalar and a dense vector \a dv. The function returns an expression representing this
1255 // operation.\n
1256 // The following example demonstrates the use of the \a max() function:
1257
1258 \code
1259 blaze::DynamicVector<double> a, b;
1260 // ... Resizing and initialization
1261 b = max( 0.0, a );
1262 \endcode
1263 */
1264 template< typename ST // Type of the scalar exponent
1265 , typename VT // Type of the dense vector
1266 , bool TF // Transpose flag
1267 , EnableIf_t< IsScalar_v<ST> >* = nullptr >
decltype(auto)1268 decltype(auto) max( ST scalar, const DenseVector<VT,TF>& dv )
1269 {
1270 BLAZE_FUNCTION_TRACE;
1271
1272 using ET = ElementType_t<VT>;
1273 using ScalarType = If_t< IsNumeric_v<ST> && IsNumeric_v<ET>, MapTrait_t<ST,ET,Max>, ST >;
1274 return map( *dv, bind1st( Max(), ScalarType( scalar ) ) );
1275 }
1276 //*************************************************************************************************
1277
1278
1279 //*************************************************************************************************
1280 /*!\brief Applies the \a abs() function to each single element of the dense vector \a dv.
1281 // \ingroup dense_vector
1282 //
1283 // \param dv The input vector.
1284 // \return The resulting dense vector.
1285 //
1286 // This function applies the \a abs() function to each element of the input vector \a dv. The
1287 // function returns an expression representing this operation.\n
1288 // The following example demonstrates the use of the \a abs() function:
1289
1290 \code
1291 blaze::DynamicVector<double> a, b;
1292 // ... Resizing and initialization
1293 b = abs( a );
1294 \endcode
1295 */
1296 template< typename VT // Type of the dense vector
1297 , bool TF > // Transpose flag
decltype(auto)1298 inline decltype(auto) abs( const DenseVector<VT,TF>& dv )
1299 {
1300 BLAZE_FUNCTION_TRACE;
1301
1302 return map( *dv, Abs() );
1303 }
1304 //*************************************************************************************************
1305
1306
1307 //*************************************************************************************************
1308 /*!\brief Applies the \a sign() function to each single element of the dense vector \a dv.
1309 // \ingroup dense_vector
1310 //
1311 // \param dv The input vector.
1312 // \return The resulting dense vector.
1313 //
1314 // This function applies the \a sign() function to each element of the input vector \a dv. The
1315 // function returns an expression representing this operation.\n
1316 // The following example demonstrates the use of the \a sign() function:
1317
1318 \code
1319 blaze::DynamicVector<double> a, b;
1320 // ... Resizing and initialization
1321 b = sign( a );
1322 \endcode
1323 */
1324 template< typename VT // Type of the dense vector
1325 , bool TF > // Transpose flag
decltype(auto)1326 inline decltype(auto) sign( const DenseVector<VT,TF>& dv )
1327 {
1328 BLAZE_FUNCTION_TRACE;
1329
1330 return map( *dv, Sign() );
1331 }
1332 //*************************************************************************************************
1333
1334
1335 //*************************************************************************************************
1336 /*!\brief Applies the \a floor() function to each single element of the dense vector \a dv.
1337 // \ingroup dense_vector
1338 //
1339 // \param dv The input vector.
1340 // \return The resulting dense vector.
1341 //
1342 // This function applies the \a floor() function to each element of the input vector \a dv. The
1343 // function returns an expression representing this operation.\n
1344 // The following example demonstrates the use of the \a floor() function:
1345
1346 \code
1347 blaze::DynamicVector<double> a, b;
1348 // ... Resizing and initialization
1349 b = floor( a );
1350 \endcode
1351 */
1352 template< typename VT // Type of the dense vector
1353 , bool TF > // Transpose flag
decltype(auto)1354 inline decltype(auto) floor( const DenseVector<VT,TF>& dv )
1355 {
1356 BLAZE_FUNCTION_TRACE;
1357
1358 return map( *dv, Floor() );
1359 }
1360 //*************************************************************************************************
1361
1362
1363 //*************************************************************************************************
1364 /*!\brief Applies the \a ceil() function to each single element of the dense vector \a dv.
1365 // \ingroup dense_vector
1366 //
1367 // \param dv The input vector.
1368 // \return The resulting dense vector.
1369 //
1370 // This function applies the \a ceil() function to each element of the input vector \a dv. The
1371 // function returns an expression representing this operation.\n
1372 // The following example demonstrates the use of the \a ceil() function:
1373
1374 \code
1375 blaze::DynamicVector<double> a, b;
1376 // ... Resizing and initialization
1377 b = ceil( a );
1378 \endcode
1379 */
1380 template< typename VT // Type of the dense vector
1381 , bool TF > // Transpose flag
decltype(auto)1382 inline decltype(auto) ceil( const DenseVector<VT,TF>& dv )
1383 {
1384 BLAZE_FUNCTION_TRACE;
1385
1386 return map( *dv, Ceil() );
1387 }
1388 //*************************************************************************************************
1389
1390
1391 //*************************************************************************************************
1392 /*!\brief Applies the \a trunc() function to each single element of the dense vector \a dv.
1393 // \ingroup dense_vector
1394 //
1395 // \param dv The input vector.
1396 // \return The resulting dense vector.
1397 //
1398 // This function applies the \a trunc() function to each element of the input vector \a dv. The
1399 // function returns an expression representing this operation.\n
1400 // The following example demonstrates the use of the \a trunc() function:
1401
1402 \code
1403 blaze::DynamicVector<double> a, b;
1404 // ... Resizing and initialization
1405 b = trunc( a );
1406 \endcode
1407 */
1408 template< typename VT // Type of the dense vector
1409 , bool TF > // Transpose flag
decltype(auto)1410 inline decltype(auto) trunc( const DenseVector<VT,TF>& dv )
1411 {
1412 BLAZE_FUNCTION_TRACE;
1413
1414 return map( *dv, Trunc() );
1415 }
1416 //*************************************************************************************************
1417
1418
1419 //*************************************************************************************************
1420 /*!\brief Applies the \a round() function to each single element of the dense vector \a dv.
1421 // \ingroup dense_vector
1422 //
1423 // \param dv The input vector.
1424 // \return The resulting dense vector.
1425 //
1426 // This function applies the \a round() function to each element of the input vector \a dv. The
1427 // function returns an expression representing this operation.\n
1428 // The following example demonstrates the use of the \a round() function:
1429
1430 \code
1431 blaze::DynamicVector<double> a, b;
1432 // ... Resizing and initialization
1433 b = round( a );
1434 \endcode
1435 */
1436 template< typename VT // Type of the dense vector
1437 , bool TF > // Transpose flag
decltype(auto)1438 inline decltype(auto) round( const DenseVector<VT,TF>& dv )
1439 {
1440 BLAZE_FUNCTION_TRACE;
1441
1442 return map( *dv, Round() );
1443 }
1444 //*************************************************************************************************
1445
1446
1447 //*************************************************************************************************
1448 /*!\brief Returns a vector containing the complex conjugate of each single element of \a dv.
1449 // \ingroup dense_vector
1450 //
1451 // \param dv The input vector.
1452 // \return The complex conjugate of each single element of \a dv.
1453 //
1454 // The \a conj() function calculates the complex conjugate of each element of the input vector
1455 // \a dv. The function returns an expression representing this operation.\n
1456 // The following example demonstrates the use of the \a conj() function:
1457
1458 \code
1459 blaze::DynamicVector< complex<double> > a, b;
1460 // ... Resizing and initialization
1461 b = conj( a );
1462 \endcode
1463 */
1464 template< typename VT // Type of the dense vector
1465 , bool TF > // Transpose flag
decltype(auto)1466 inline decltype(auto) conj( const DenseVector<VT,TF>& dv )
1467 {
1468 BLAZE_FUNCTION_TRACE;
1469
1470 return map( *dv, Conj() );
1471 }
1472 //*************************************************************************************************
1473
1474
1475 //*************************************************************************************************
1476 /*!\brief Returns the conjugate transpose vector of \a dv.
1477 // \ingroup dense_vector
1478 //
1479 // \param dv The input vector.
1480 // \return The conjugate transpose of \a dv.
1481 //
1482 // The \a ctrans() function returns an expression representing the conjugate transpose (also
1483 // called adjoint matrix, Hermitian conjugate matrix or transjugate matrix) of the given input
1484 // vector \a dv.\n
1485 // The following example demonstrates the use of the \a ctrans() function:
1486
1487 \code
1488 blaze::DynamicVector< complex<double> > a, b;
1489 // ... Resizing and initialization
1490 b = ctrans( a );
1491 \endcode
1492
1493 // Note that the \a ctrans() function has the same effect as manually applying the \a conj() and
1494 // \a trans function in any order:
1495
1496 \code
1497 b = trans( conj( a ) ); // Computing the conjugate transpose vector
1498 b = conj( trans( a ) ); // Computing the conjugate transpose vector
1499 \endcode
1500 */
1501 template< typename VT // Type of the dense vector
1502 , bool TF > // Transpose flag
decltype(auto)1503 inline decltype(auto) ctrans( const DenseVector<VT,TF>& dv )
1504 {
1505 BLAZE_FUNCTION_TRACE;
1506
1507 return trans( conj( *dv ) );
1508 }
1509 //*************************************************************************************************
1510
1511
1512 //*************************************************************************************************
1513 /*!\brief Returns a vector containing the real part of each single element of \a dv.
1514 // \ingroup dense_vector
1515 //
1516 // \param dv The input vector.
1517 // \return The real part of each single element of \a dv.
1518 //
1519 // The \a real() function calculates the real part of each element of the input vector \a dv.
1520 // The function returns an expression representing this operation.\n
1521 // The following example demonstrates the use of the \a real() function:
1522
1523 \code
1524 blaze::DynamicVector<double> a, b;
1525 // ... Resizing and initialization
1526 b = real( a );
1527 \endcode
1528 */
1529 template< typename VT // Type of the dense vector
1530 , bool TF > // Transpose flag
decltype(auto)1531 inline decltype(auto) real( const DenseVector<VT,TF>& dv )
1532 {
1533 BLAZE_FUNCTION_TRACE;
1534
1535 return map( *dv, Real() );
1536 }
1537 //*************************************************************************************************
1538
1539
1540 //*************************************************************************************************
1541 /*!\brief Returns a vector containing the imaginary part of each single element of \a dv.
1542 // \ingroup dense_vector
1543 //
1544 // \param dv The input vector.
1545 // \return The imaginary part of each single element of \a dv.
1546 //
1547 // The \a imag() function calculates the imaginary part of each element of the input vector \a dv.
1548 // The function returns an expression representing this operation.\n
1549 // The following example demonstrates the use of the \a imag() function:
1550
1551 \code
1552 blaze::DynamicVector<double> a, b;
1553 // ... Resizing and initialization
1554 b = imag( a );
1555 \endcode
1556 */
1557 template< typename VT // Type of the dense vector
1558 , bool TF > // Transpose flag
decltype(auto)1559 inline decltype(auto) imag( const DenseVector<VT,TF>& dv )
1560 {
1561 BLAZE_FUNCTION_TRACE;
1562
1563 return map( *dv, Imag() );
1564 }
1565 //*************************************************************************************************
1566
1567
1568 //*************************************************************************************************
1569 /*!\brief Returns a vector containing the phase angle of each single element of \a dv.
1570 // \ingroup dense_vector
1571 //
1572 // \param dv The input vector.
1573 // \return The phase angle of each single element of \a dv.
1574 //
1575 // The \a arg() function calculates the phase angle of each element of the input vector \a dv.
1576 // The function returns an expression representing this operation.\n
1577 // The following example demonstrates the use of the \a arg() function:
1578
1579 \code
1580 blaze::DynamicVector<double> a, b;
1581 // ... Resizing and initialization
1582 b = arg( a );
1583 \endcode
1584 */
1585 template< typename VT // Type of the dense vector
1586 , bool TF > // Transpose flag
decltype(auto)1587 inline decltype(auto) arg( const DenseVector<VT,TF>& dv )
1588 {
1589 BLAZE_FUNCTION_TRACE;
1590
1591 return map( *dv, Arg() );
1592 }
1593 //*************************************************************************************************
1594
1595
1596 //*************************************************************************************************
1597 /*!\brief Computes the square root of each single element of the dense vector \a dv.
1598 // \ingroup dense_vector
1599 //
1600 // \param dv The input vector; all elements must be in the range \f$[0..\infty)\f$.
1601 // \return The square root of each single element of \a dv.
1602 //
1603 // The \a sqrt() function computes the square root of each element of the input vector \a dv.
1604 // The function returns an expression representing this operation.\n
1605 // The following example demonstrates the use of the \a sqrt() function:
1606
1607 \code
1608 blaze::DynamicVector<double> a, b;
1609 // ... Resizing and initialization
1610 b = sqrt( a );
1611 \endcode
1612
1613 // \note All elements are expected to be in the range \f$[0..\infty)\f$. No runtime checks are
1614 // performed to assert this precondition!
1615 */
1616 template< typename VT // Type of the dense vector
1617 , bool TF > // Transpose flag
decltype(auto)1618 inline decltype(auto) sqrt( const DenseVector<VT,TF>& dv )
1619 {
1620 BLAZE_FUNCTION_TRACE;
1621
1622 return map( *dv, Sqrt() );
1623 }
1624 //*************************************************************************************************
1625
1626
1627 //*************************************************************************************************
1628 /*!\brief Computes the inverse square root of each single element of the dense vector \a dv.
1629 // \ingroup dense_vector
1630 //
1631 // \param dv The input vector; all elements must be in the range \f$(0..\infty)\f$.
1632 // \return The inverse square root of each single element of \a dv.
1633 //
1634 // The \a invsqrt() function computes the inverse square root of each element of the input vector
1635 // \a dv. The function returns an expression representing this operation.\n
1636 // The following example demonstrates the use of the \a invsqrt() function:
1637
1638 \code
1639 blaze::DynamicVector<double> a, b;
1640 // ... Resizing and initialization
1641 b = invsqrt( a );
1642 \endcode
1643
1644 // \note All elements are expected to be in the range \f$(0..\infty)\f$. No runtime checks are
1645 // performed to assert this precondition!
1646 */
1647 template< typename VT // Type of the dense vector
1648 , bool TF > // Transpose flag
decltype(auto)1649 inline decltype(auto) invsqrt( const DenseVector<VT,TF>& dv )
1650 {
1651 BLAZE_FUNCTION_TRACE;
1652
1653 return map( *dv, InvSqrt() );
1654 }
1655 //*************************************************************************************************
1656
1657
1658 //*************************************************************************************************
1659 /*!\brief Computes the cubic root of each single element of the dense vector \a dv.
1660 // \ingroup dense_vector
1661 //
1662 // \param dv The input vector; all elements must be in the range \f$[0..\infty)\f$.
1663 // \return The cubic root of each single element of \a dv.
1664 //
1665 // The \a cbrt() function computes the cubic root of each element of the input vector \a dv. The
1666 // function returns an expression representing this operation.\n
1667 // The following example demonstrates the use of the \a cbrt() function:
1668
1669 \code
1670 blaze::DynamicVector<double> a, b;
1671 // ... Resizing and initialization
1672 b = cbrt( a );
1673 \endcode
1674
1675 // \note All elements are expected to be in the range \f$[0..\infty)\f$. No runtime checks are
1676 // performed to assert this precondition!
1677 */
1678 template< typename VT // Type of the dense vector
1679 , bool TF > // Transpose flag
decltype(auto)1680 inline decltype(auto) cbrt( const DenseVector<VT,TF>& dv )
1681 {
1682 BLAZE_FUNCTION_TRACE;
1683
1684 return map( *dv, Cbrt() );
1685 }
1686 //*************************************************************************************************
1687
1688
1689 //*************************************************************************************************
1690 /*!\brief Computes the inverse cubic root of each single element of the dense vector \a dv.
1691 // \ingroup dense_vector
1692 //
1693 // \param dv The input vector; all elements must be in the range \f$(0..\infty)\f$.
1694 // \return The inverse cubic root of each single element of \a dv.
1695 //
1696 // The \a invcbrt() function computes the inverse cubic root of each element of the input vector
1697 // \a dv. The function returns an expression representing this operation.\n
1698 // The following example demonstrates the use of the \a invcbrt() function:
1699
1700 \code
1701 blaze::DynamicVector<double> a, b;
1702 // ... Resizing and initialization
1703 b = invcbrt( a );
1704 \endcode
1705
1706 // \note All elements are expected to be in the range \f$(0..\infty)\f$. No runtime checks are
1707 // performed to assert this precondition!
1708 */
1709 template< typename VT // Type of the dense vector
1710 , bool TF > // Transpose flag
decltype(auto)1711 inline decltype(auto) invcbrt( const DenseVector<VT,TF>& dv )
1712 {
1713 BLAZE_FUNCTION_TRACE;
1714
1715 return map( *dv, InvCbrt() );
1716 }
1717 //*************************************************************************************************
1718
1719
1720 //*************************************************************************************************
1721 /*!\brief Restricts each single element of the dense vector \a dv to the range \f$[min..max]\f$.
1722 // \ingroup dense_vector
1723 //
1724 // \param dv The input vector.
1725 // \param min The lower delimiter.
1726 // \param max The upper delimiter.
1727 // \return The vector with restricted elements.
1728 //
1729 // The \a clamp() function restricts each element of the input vector \a dv to the range
1730 // \f$[min..max]\f$. The function returns an expression representing this operation.\n
1731 // The following example demonstrates the use of the \a clamp() function:
1732
1733 \code
1734 blaze::DynamicVector<double> a, b;
1735 // ... Resizing and initialization
1736 b = clamp( a, -1.0, 1.0 );
1737 \endcode
1738 */
1739 template< typename VT // Type of the dense vector
1740 , bool TF // Transpose flag
1741 , typename DT > // Type of the delimiters
decltype(auto)1742 inline decltype(auto) clamp( const DenseVector<VT,TF>& dv, const DT& min, const DT& max )
1743 {
1744 BLAZE_FUNCTION_TRACE;
1745
1746 return map( *dv, bind2nd( bind3rd( Clamp(), max ), min ) );
1747 }
1748 //*************************************************************************************************
1749
1750
1751 //*************************************************************************************************
1752 /*!\brief Computes the exponential value for each single element of the dense vector \a dv.
1753 // \ingroup dense_vector
1754 //
1755 // \param dv The input vector.
1756 // \param exp The scalar exponent.
1757 // \return The exponential value of each single element of \a dv.
1758 //
1759 // The \a pow() function computes the exponential value for each element of the input vector
1760 // \a dv. The function returns an expression representing this operation.\n
1761 // The following example demonstrates the use of the \a pow() function:
1762
1763 \code
1764 blaze::DynamicVector<double> a, b;
1765 // ... Resizing and initialization
1766 b = pow( a, 4.2 );
1767 \endcode
1768 */
1769 template< typename VT // Type of the dense vector
1770 , bool TF // Transpose flag
1771 , typename ST // Type of the scalar exponent
1772 , EnableIf_t< IsScalar_v<ST> >* = nullptr >
decltype(auto)1773 inline decltype(auto) pow( const DenseVector<VT,TF>& dv, ST exp )
1774 {
1775 BLAZE_FUNCTION_TRACE;
1776
1777 using ET = ElementType_t<VT>;
1778 using ScalarType = If_t< IsNumeric_v<ET> && IsNumeric_v<ST>, MultTrait_t<ET,ST>, ST >;
1779 return map( *dv, blaze::bind2nd( Pow(), ScalarType( exp ) ) );
1780 }
1781 //*************************************************************************************************
1782
1783
1784 //*************************************************************************************************
1785 /*!\brief Computes \f$ e^x \f$ for each single element of the dense vector \a dv.
1786 // \ingroup dense_vector
1787 //
1788 // \param dv The input vector.
1789 // \return The resulting dense vector.
1790 //
1791 // The \a exp() function computes \f$ e^x \f$ for each element of the input vector \a dv. The
1792 // function returns an expression representing this operation.\n
1793 // The following example demonstrates the use of the \a exp() function:
1794
1795 \code
1796 blaze::DynamicVector<double> a, b;
1797 // ... Resizing and initialization
1798 b = exp( a );
1799 \endcode
1800 */
1801 template< typename VT // Type of the dense vector
1802 , bool TF > // Transpose flag
decltype(auto)1803 inline decltype(auto) exp( const DenseVector<VT,TF>& dv )
1804 {
1805 BLAZE_FUNCTION_TRACE;
1806
1807 return map( *dv, Exp() );
1808 }
1809 //*************************************************************************************************
1810
1811
1812 //*************************************************************************************************
1813 /*!\brief Computes \f$ 2^x \f$ for each single element of the dense vector \a dv.
1814 // \ingroup dense_vector
1815 //
1816 // \param dv The input vector.
1817 // \return The resulting dense vector.
1818 //
1819 // The \a exp2() function computes \f$ 2^x \f$ for each element of the input vector \a dv. The
1820 // function returns an expression representing this operation.\n
1821 // The following example demonstrates the use of the \a exp2() function:
1822
1823 \code
1824 blaze::DynamicVector<double> a, b;
1825 // ... Resizing and initialization
1826 b = exp2( a );
1827 \endcode
1828 */
1829 template< typename VT // Type of the dense vector
1830 , bool TF > // Transpose flag
decltype(auto)1831 inline decltype(auto) exp2( const DenseVector<VT,TF>& dv )
1832 {
1833 BLAZE_FUNCTION_TRACE;
1834
1835 return map( *dv, Exp2() );
1836 }
1837 //*************************************************************************************************
1838
1839
1840 //*************************************************************************************************
1841 /*!\brief Computes \f$ 10^x \f$ for each single element of the dense vector \a dv.
1842 // \ingroup dense_vector
1843 //
1844 // \param dv The input vector.
1845 // \return The resulting dense vector.
1846 //
1847 // The \a exp10() function computes \f$ 10^x \f$ for each element of the input vector \a dv. The
1848 // function returns an expression representing this operation.\n
1849 // The following example demonstrates the use of the \a exp10() function:
1850
1851 \code
1852 blaze::DynamicVector<double> a, b;
1853 // ... Resizing and initialization
1854 b = exp10( a );
1855 \endcode
1856 */
1857 template< typename VT // Type of the dense vector
1858 , bool TF > // Transpose flag
decltype(auto)1859 inline decltype(auto) exp10( const DenseVector<VT,TF>& dv )
1860 {
1861 BLAZE_FUNCTION_TRACE;
1862
1863 return map( *dv, Exp10() );
1864 }
1865 //*************************************************************************************************
1866
1867
1868 //*************************************************************************************************
1869 /*!\brief Computes the natural logarithm for each single element of the dense vector \a dv.
1870 // \ingroup dense_vector
1871 //
1872 // \param dv The input vector; all elements must be in the range \f$[0..\infty)\f$.
1873 // \return The natural logarithm of each single element of \a dv.
1874 //
1875 // The \a log() function computes natural logarithm for each element of the input vector \a dv.
1876 // The function returns an expression representing this operation.\n
1877 // The following example demonstrates the use of the \a log() function:
1878
1879 \code
1880 blaze::DynamicVector<double> a, b;
1881 // ... Resizing and initialization
1882 b = log( a );
1883 \endcode
1884
1885 // \note All elements are expected to be in the range \f$[0..\infty)\f$. No runtime checks are
1886 // performed to assert this precondition!
1887 */
1888 template< typename VT // Type of the dense vector
1889 , bool TF > // Transpose flag
decltype(auto)1890 inline decltype(auto) log( const DenseVector<VT,TF>& dv )
1891 {
1892 BLAZE_FUNCTION_TRACE;
1893
1894 return map( *dv, Log() );
1895 }
1896 //*************************************************************************************************
1897
1898
1899 //*************************************************************************************************
1900 /*!\brief Computes the binary logarithm for each single element of the dense vector \a dv.
1901 // \ingroup dense_vector
1902 //
1903 // \param dv The input vector; all elements must be in the range \f$[0..\infty)\f$.
1904 // \return The binary logarithm of each single element of \a dv.
1905 //
1906 // The \a log2() function computes binary logarithm for each element of the input vector \a dv.
1907 // The function returns an expression representing this operation.\n
1908 // The following example demonstrates the use of the \a log2() function:
1909
1910 \code
1911 blaze::DynamicVector<double> a, b;
1912 // ... Resizing and initialization
1913 b = log2( a );
1914 \endcode
1915
1916 // \note All elements are expected to be in the range \f$[0..\infty)\f$. No runtime checks are
1917 // performed to assert this precondition!
1918 */
1919 template< typename VT // Type of the dense vector
1920 , bool TF > // Transpose flag
decltype(auto)1921 inline decltype(auto) log2( const DenseVector<VT,TF>& dv )
1922 {
1923 BLAZE_FUNCTION_TRACE;
1924
1925 return map( *dv, Log2() );
1926 }
1927 //*************************************************************************************************
1928
1929
1930 //*************************************************************************************************
1931 /*!\brief Computes the common logarithm for each single element of the dense vector \a dv.
1932 // \ingroup dense_vector
1933 //
1934 // \param dv The input vector; all elements must be in the range \f$[0..\infty)\f$.
1935 // \return The common logarithm of each single element of \a dv.
1936 //
1937 // The \a log10() function computes common logarithm for each element of the input vector \a dv.
1938 // The function returns an expression representing this operation.\n
1939 // The following example demonstrates the use of the \a log10() function:
1940
1941 \code
1942 blaze::DynamicVector<double> a, b;
1943 // ... Resizing and initialization
1944 b = log10( a );
1945 \endcode
1946
1947 // \note All elements are expected to be in the range \f$[0..\infty)\f$. No runtime checks are
1948 // performed to assert this precondition!
1949 */
1950 template< typename VT // Type of the dense vector
1951 , bool TF > // Transpose flag
decltype(auto)1952 inline decltype(auto) log10( const DenseVector<VT,TF>& dv )
1953 {
1954 BLAZE_FUNCTION_TRACE;
1955
1956 return map( *dv, Log10() );
1957 }
1958 //*************************************************************************************************
1959
1960
1961 //*************************************************************************************************
1962 /*!\brief Computes the natural logarithm of x+1 for each single element of the dense vector \a dv.
1963 // \ingroup dense_vector
1964 //
1965 // \param dv The input vector; all elements must be in the range \f$[-1..\infty)\f$.
1966 // \return The natural logarithm of x+1 of each single element of \a dv.
1967 //
1968 // The \a log1p() function computes the natural logarithm of x+1 for each element of the input
1969 // vector \a dv. This may be preferred over the natural logarithm for higher precision computing
1970 // the natural logarithm of a quantity very close to 1. The function returns an expression
1971 // representing this operation.\n
1972 // The following example demonstrates the use of the \a log1p() function:
1973
1974 \code
1975 blaze::DynamicVector<double> a, b;
1976 // ... Resizing and initialization
1977 b = log1p( a );
1978 \endcode
1979
1980 // \note All elements are expected to be in the range \f$[-1..\infty)\f$. No runtime checks are
1981 // performed to assert this precondition!
1982 */
1983 template< typename VT // Type of the dense vector
1984 , bool TF > // Transpose flag
decltype(auto)1985 inline decltype(auto) log1p( const DenseVector<VT,TF>& dv )
1986 {
1987 BLAZE_FUNCTION_TRACE;
1988
1989 return map( *dv, Log1p() );
1990 }
1991 //*************************************************************************************************
1992
1993
1994 //*************************************************************************************************
1995 /*!\brief Computes the natural logarithm of the absolute value of the gamma function for each
1996 // single element of the dense vector \a dv.
1997 // \ingroup dense_vector
1998 //
1999 // \param dv The input vector; all elements must be in the range \f$[0..\infty)\f$.
2000 // \return The natural logarithm of the absolute value of the gamma function of each single element of \a dv.
2001 //
2002 // The \a lgamma() function computes the natural logarithm of the absolute value of the gamma
2003 // function for each element of the input vector \a dv. The function returns an expression
2004 // representing this operation.\n
2005 // The following example demonstrates the use of the \a lgamma() function:
2006
2007 \code
2008 blaze::DynamicVector<double> a, b;
2009 // ... Resizing and initialization
2010 b = lgamma( a );
2011 \endcode
2012
2013 // \note All elements are expected to be in the range \f$[0..\infty)\f$. No runtime checks are
2014 // performed to assert this precondition!
2015 */
2016 template< typename VT // Type of the dense vector
2017 , bool SO > // Storage order
decltype(auto)2018 inline decltype(auto) lgamma( const DenseVector<VT,SO>& dv )
2019 {
2020 BLAZE_FUNCTION_TRACE;
2021
2022 return map( *dv, LGamma() );
2023 }
2024 //*************************************************************************************************
2025
2026
2027 //*************************************************************************************************
2028 /*!\brief Computes the sine for each single element of the dense vector \a dv.
2029 // \ingroup dense_vector
2030 //
2031 // \param dv The input vector.
2032 // \return The sine of each single element of \a dv.
2033 //
2034 // The \a sin() function computes the sine for each element of the input vector \a dv. The
2035 // function returns an expression representing this operation.\n
2036 // The following example demonstrates the use of the \a sin() function:
2037
2038 \code
2039 blaze::DynamicVector<double> a, b;
2040 // ... Resizing and initialization
2041 b = sin( a );
2042 \endcode
2043 */
2044 template< typename VT // Type of the dense vector
2045 , bool TF > // Transpose flag
decltype(auto)2046 inline decltype(auto) sin( const DenseVector<VT,TF>& dv )
2047 {
2048 BLAZE_FUNCTION_TRACE;
2049
2050 return map( *dv, Sin() );
2051 }
2052 //*************************************************************************************************
2053
2054
2055 //*************************************************************************************************
2056 /*!\brief Computes the inverse sine for each single element of the dense vector \a dv.
2057 // \ingroup dense_vector
2058 //
2059 // \param dv The input vector; all elements must be in the range \f$[-1..1]\f$.
2060 // \return The inverse sine of each single element of \a dv.
2061 //
2062 // The \a asin() function computes the inverse sine for each element of the input vector \a dv.
2063 // The function returns an expression representing this operation.\n
2064 // The following example demonstrates the use of the \a asin() function:
2065
2066 \code
2067 blaze::DynamicVector<double> a, b;
2068 // ... Resizing and initialization
2069 b = asin( a );
2070 \endcode
2071
2072 // \note All elements are expected to be in the range \f$[-1..1]\f$. No runtime checks are
2073 // performed to assert this precondition!
2074 */
2075 template< typename VT // Type of the dense vector
2076 , bool TF > // Transpose flag
decltype(auto)2077 inline decltype(auto) asin( const DenseVector<VT,TF>& dv )
2078 {
2079 BLAZE_FUNCTION_TRACE;
2080
2081 return map( *dv, Asin() );
2082 }
2083 //*************************************************************************************************
2084
2085
2086 //*************************************************************************************************
2087 /*!\brief Computes the hyperbolic sine for each single element of the dense vector \a dv.
2088 // \ingroup dense_vector
2089 //
2090 // \param dv The input vector.
2091 // \return The hyperbolic sine of each single element of \a dv.
2092 //
2093 // The \a sinh() function computes the hyperbolic sine for each element of the input vector \a dv.
2094 // The function returns an expression representing this operation.\n
2095 // The following example demonstrates the use of the \a sinh() function:
2096
2097 \code
2098 blaze::DynamicVector<double> a, b;
2099 // ... Resizing and initialization
2100 b = sinh( a );
2101 \endcode
2102 */
2103 template< typename VT // Type of the dense vector
2104 , bool TF > // Transpose flag
decltype(auto)2105 inline decltype(auto) sinh( const DenseVector<VT,TF>& dv )
2106 {
2107 BLAZE_FUNCTION_TRACE;
2108
2109 return map( *dv, Sinh() );
2110 }
2111 //*************************************************************************************************
2112
2113
2114 //*************************************************************************************************
2115 /*!\brief Computes the inverse hyperbolic sine for each single element of the dense vector \a dv.
2116 // \ingroup dense_vector
2117 //
2118 // \param dv The input vector.
2119 // \return The inverse hyperbolic sine of each single element of \a dv.
2120 //
2121 // The \a asinh() function computes the inverse hyperbolic sine for each element of the input
2122 // vector \a dv. The function returns an expression representing this operation.\n
2123 // The following example demonstrates the use of the \a asinh() function:
2124
2125 \code
2126 blaze::DynamicVector<double> a, b;
2127 // ... Resizing and initialization
2128 b = asinh( a );
2129 \endcode
2130 */
2131 template< typename VT // Type of the dense vector
2132 , bool TF > // Transpose flag
decltype(auto)2133 inline decltype(auto) asinh( const DenseVector<VT,TF>& dv )
2134 {
2135 BLAZE_FUNCTION_TRACE;
2136
2137 return map( *dv, Asinh() );
2138 }
2139 //*************************************************************************************************
2140
2141
2142 //*************************************************************************************************
2143 /*!\brief Computes the cosine for each single element of the dense vector \a dv.
2144 // \ingroup dense_vector
2145 //
2146 // \param dv The input vector.
2147 // \return The cosine of each single element of \a dv.
2148 //
2149 // The \a cos() function computes the cosine for each element of the input vector \a dv. The
2150 // function returns an expression representing this operation.\n
2151 // The following example demonstrates the use of the \a cos() function:
2152
2153 \code
2154 blaze::DynamicVector<double> a, b;
2155 // ... Resizing and initialization
2156 b = cos( a );
2157 \endcode
2158 */
2159 template< typename VT // Type of the dense vector
2160 , bool TF > // Transpose flag
decltype(auto)2161 inline decltype(auto) cos( const DenseVector<VT,TF>& dv )
2162 {
2163 BLAZE_FUNCTION_TRACE;
2164
2165 return map( *dv, Cos() );
2166 }
2167 //*************************************************************************************************
2168
2169
2170 //*************************************************************************************************
2171 /*!\brief Computes the inverse cosine for each single element of the dense vector \a dv.
2172 // \ingroup dense_vector
2173 //
2174 // \param dv The input vector; all elements must be in the range \f$[-1..1]\f$.
2175 // \return The inverse cosine of each single element of \a dv.
2176 //
2177 // The \a acos() function computes the inverse cosine for each element of the input vector \a dv.
2178 // The function returns an expression representing this operation.\n
2179 // The following example demonstrates the use of the \a acos() function:
2180
2181 \code
2182 blaze::DynamicVector<double> a, b;
2183 // ... Resizing and initialization
2184 b = acos( a );
2185 \endcode
2186
2187 // \note All elements are expected to be in the range \f$[-1..1]\f$. No runtime checks are
2188 // performed to assert this precondition!
2189 */
2190 template< typename VT // Type of the dense vector
2191 , bool TF > // Transpose flag
decltype(auto)2192 inline decltype(auto) acos( const DenseVector<VT,TF>& dv )
2193 {
2194 BLAZE_FUNCTION_TRACE;
2195
2196 return map( *dv, Acos() );
2197 }
2198 //*************************************************************************************************
2199
2200
2201 //*************************************************************************************************
2202 /*!\brief Computes the hyperbolic cosine for each single element of the dense vector \a dv.
2203 // \ingroup dense_vector
2204 //
2205 // \param dv The input vector.
2206 // \return The hyperbolic cosine of each single element of \a dv.
2207 //
2208 // The \a cosh() function computes the hyperbolic cosine for each element of the input vector
2209 // \a dv. The function returns an expression representing this operation.\n
2210 // The following example demonstrates the use of the \a cosh() function:
2211
2212 \code
2213 blaze::DynamicVector<double> a, b;
2214 // ... Resizing and initialization
2215 b = cosh( a );
2216 \endcode
2217 */
2218 template< typename VT // Type of the dense vector
2219 , bool TF > // Transpose flag
decltype(auto)2220 inline decltype(auto) cosh( const DenseVector<VT,TF>& dv )
2221 {
2222 BLAZE_FUNCTION_TRACE;
2223
2224 return map( *dv, Cosh() );
2225 }
2226 //*************************************************************************************************
2227
2228
2229 //*************************************************************************************************
2230 /*!\brief Computes the inverse hyperbolic cosine for each single element of the dense vector \a dv.
2231 // \ingroup dense_vector
2232 //
2233 // \param dv The input vector; all elements must be in the range \f$[1..\infty)\f$.
2234 // \return The inverse hyperbolic cosine of each single element of \a dv.
2235 //
2236 // The \a acosh() function computes the inverse hyperbolic cosine for each element of the input
2237 // vector \a dv. The function returns an expression representing this operation.\n
2238 // The following example demonstrates the use of the \a acosh() function:
2239
2240 \code
2241 blaze::DynamicVector<double> a, b;
2242 // ... Resizing and initialization
2243 b = acosh( a );
2244 \endcode
2245
2246 // \note All elements are expected to be in the range \f$[1..\infty)\f$. No runtime checks are
2247 // performed to assert this precondition!
2248 */
2249 template< typename VT // Type of the dense vector
2250 , bool TF > // Transpose flag
decltype(auto)2251 inline decltype(auto) acosh( const DenseVector<VT,TF>& dv )
2252 {
2253 BLAZE_FUNCTION_TRACE;
2254
2255 return map( *dv, Acosh() );
2256 }
2257 //*************************************************************************************************
2258
2259
2260 //*************************************************************************************************
2261 /*!\brief Computes the tangent for each single element of the dense vector \a dv.
2262 // \ingroup dense_vector
2263 //
2264 // \param dv The input vector.
2265 // \return The tangent of each single element of \a dv.
2266 //
2267 // The \a tan() function computes the tangent for each element of the input vector \a dv. The
2268 // function returns an expression representing this operation.\n
2269 // The following example demonstrates the use of the \a tan() function:
2270
2271 \code
2272 blaze::DynamicVector<double> a, b;
2273 // ... Resizing and initialization
2274 b = tan( a );
2275 \endcode
2276 */
2277 template< typename VT // Type of the dense vector
2278 , bool TF > // Transpose flag
decltype(auto)2279 inline decltype(auto) tan( const DenseVector<VT,TF>& dv )
2280 {
2281 BLAZE_FUNCTION_TRACE;
2282
2283 return map( *dv, Tan() );
2284 }
2285 //*************************************************************************************************
2286
2287
2288 //*************************************************************************************************
2289 /*!\brief Computes the inverse tangent for each single element of the dense vector \a dv.
2290 // \ingroup dense_vector
2291 //
2292 // \param dv The input vector.
2293 // \return The inverse tangent of each single element of \a dv.
2294 //
2295 // The \a atan() function computes the inverse tangent for each element of the input vector \a dv.
2296 // The function returns an expression representing this operation.\n
2297 // The following example demonstrates the use of the \a atan() function:
2298
2299 \code
2300 blaze::DynamicVector<double> a, b;
2301 // ... Resizing and initialization
2302 b = atan( a );
2303 \endcode
2304 */
2305 template< typename VT // Type of the dense vector
2306 , bool TF > // Transpose flag
decltype(auto)2307 inline decltype(auto) atan( const DenseVector<VT,TF>& dv )
2308 {
2309 BLAZE_FUNCTION_TRACE;
2310
2311 return map( *dv, Atan() );
2312 }
2313 //*************************************************************************************************
2314
2315
2316 //*************************************************************************************************
2317 /*!\brief Computes the hyperbolic tangent for each single element of the dense vector \a dv.
2318 // \ingroup dense_vector
2319 //
2320 // \param dv The input vector; all elements must be in the range \f$[-1..1]\f$.
2321 // \return The hyperbolic tangent of each single element of \a dv.
2322 //
2323 // The \a tanh() function computes the hyperbolic tangent for each element of the input vector
2324 // \a dv. The function returns an expression representing this operation.\n
2325 // The following example demonstrates the use of the \a tanh() function:
2326
2327 \code
2328 blaze::DynamicVector<double> a, b;
2329 // ... Resizing and initialization
2330 b = tanh( a );
2331 \endcode
2332
2333 // \note All elements are expected to be in the range \f$[-1..1]\f$. No runtime checks are
2334 // performed to assert this precondition!
2335 */
2336 template< typename VT // Type of the dense vector
2337 , bool TF > // Transpose flag
decltype(auto)2338 inline decltype(auto) tanh( const DenseVector<VT,TF>& dv )
2339 {
2340 BLAZE_FUNCTION_TRACE;
2341
2342 return map( *dv, Tanh() );
2343 }
2344 //*************************************************************************************************
2345
2346
2347 //*************************************************************************************************
2348 /*!\brief Computes the inverse hyperbolic tangent for each single element of the dense vector \a dv.
2349 // \ingroup dense_vector
2350 //
2351 // \param dv The input vector; all elements must be in the range \f$[-1..1]\f$.
2352 // \return The inverse hyperbolic tangent of each single element of \a dv.
2353 //
2354 // The \a atanh() function computes the inverse hyperbolic tangent for each element of the input
2355 // vector \a dv. The function returns an expression representing this operation.\n
2356 // The following example demonstrates the use of the \a atanh() function:
2357
2358 \code
2359 blaze::DynamicVector<double> a, b;
2360 // ... Resizing and initialization
2361 b = atanh( a );
2362 \endcode
2363
2364 // \note All elements are expected to be in the range \f$[-1..1]\f$. No runtime checks are
2365 // performed to assert this precondition!
2366 */
2367 template< typename VT // Type of the dense vector
2368 , bool TF > // Transpose flag
decltype(auto)2369 inline decltype(auto) atanh( const DenseVector<VT,TF>& dv )
2370 {
2371 BLAZE_FUNCTION_TRACE;
2372
2373 return map( *dv, Atanh() );
2374 }
2375 //*************************************************************************************************
2376
2377
2378 //*************************************************************************************************
2379 /*!\brief Computes the error function for each single element of the dense vector \a dv.
2380 // \ingroup dense_vector
2381 //
2382 // \param dv The input vector.
2383 // \return The error function of each single element of \a dv.
2384 //
2385 // The \a erf() function computes the error function for each element of the input vector \a dv.
2386 // The function returns an expression representing this operation.\n
2387 // The following example demonstrates the use of the \a erf() function:
2388
2389 \code
2390 blaze::DynamicVector<double> a, b;
2391 // ... Resizing and initialization
2392 b = erf( a );
2393 \endcode
2394 */
2395 template< typename VT // Type of the dense vector
2396 , bool TF > // Transpose flag
decltype(auto)2397 inline decltype(auto) erf( const DenseVector<VT,TF>& dv )
2398 {
2399 BLAZE_FUNCTION_TRACE;
2400
2401 return map( *dv, Erf() );
2402 }
2403 //*************************************************************************************************
2404
2405
2406 //*************************************************************************************************
2407 /*!\brief Computes the complementary error function for each single element of the dense vector \a dv.
2408 // \ingroup dense_vector
2409 //
2410 // \param dv The input vector.
2411 // \return The complementary error function of each single element of \a dv.
2412 //
2413 // The \a erfc() function computes the complementary error function for each element of the input
2414 // vector \a dv. The function returns an expression representing this operation.\n
2415 // The following example demonstrates the use of the \a erfc() function:
2416
2417 \code
2418 blaze::DynamicVector<double> a, b;
2419 // ... Resizing and initialization
2420 b = erfc( a );
2421 \endcode
2422 */
2423 template< typename VT // Type of the dense vector
2424 , bool TF > // Transpose flag
decltype(auto)2425 inline decltype(auto) erfc( const DenseVector<VT,TF>& dv )
2426 {
2427 BLAZE_FUNCTION_TRACE;
2428
2429 return map( *dv, Erfc() );
2430 }
2431 //*************************************************************************************************
2432
2433
2434
2435
2436 //=================================================================================================
2437 //
2438 // GLOBAL RESTRUCTURING FUNCTIONS
2439 //
2440 //=================================================================================================
2441
2442 //*************************************************************************************************
2443 /*! \cond BLAZE_INTERNAL */
2444 /*!\brief Absolute value function for absolute value dense vector expressions.
2445 // \ingroup dense_vector
2446 //
2447 // \param dv The absolute value dense vector expression.
2448 // \return The absolute value of each single element of \a dv.
2449 //
2450 // This function implements a performance optimized treatment of the absolute value operation
2451 // on a dense vector absolute value expression.
2452 */
2453 template< typename VT // Type of the dense vector
2454 , bool TF > // Transpose flag
decltype(auto)2455 inline decltype(auto) abs( const DVecMapExpr<VT,Abs,TF>& dv )
2456 {
2457 BLAZE_FUNCTION_TRACE;
2458
2459 return dv;
2460 }
2461 /*! \endcond */
2462 //*************************************************************************************************
2463
2464
2465 //*************************************************************************************************
2466 /*! \cond BLAZE_INTERNAL */
2467 /*!\brief Applies the \a sign() function for dense vector \a sign() expressions.
2468 // \ingroup dense_vector
2469 //
2470 // \param dv The dense vector \a sign() expression.
2471 // \return The resulting dense vector.
2472 //
2473 // This function implements a performance optimized treatment of the \a sign() operation on a
2474 // dense vector \a sign() expression.
2475 */
2476 template< typename VT // Type of the dense vector
2477 , bool TF > // Transpose flag
decltype(auto)2478 inline decltype(auto) sign( const DVecMapExpr<VT,Sign,TF>& dv )
2479 {
2480 BLAZE_FUNCTION_TRACE;
2481
2482 return dv;
2483 }
2484 /*! \endcond */
2485 //*************************************************************************************************
2486
2487
2488 //*************************************************************************************************
2489 /*! \cond BLAZE_INTERNAL */
2490 /*!\brief Applies the \a floor() function to a dense vector \a floor() expressions.
2491 // \ingroup dense_vector
2492 //
2493 // \param dv The dense vector \a floor() expression.
2494 // \return The resulting dense vector.
2495 //
2496 // This function implements a performance optimized treatment of the \a floor() operation on
2497 // a dense vector \a floor() expression.
2498 */
2499 template< typename VT // Type of the dense vector
2500 , bool TF > // Transpose flag
decltype(auto)2501 inline decltype(auto) floor( const DVecMapExpr<VT,Floor,TF>& dv )
2502 {
2503 BLAZE_FUNCTION_TRACE;
2504
2505 return dv;
2506 }
2507 /*! \endcond */
2508 //*************************************************************************************************
2509
2510
2511 //*************************************************************************************************
2512 /*! \cond BLAZE_INTERNAL */
2513 /*!\brief Applies the \a ceil() function to a dense vector \a ceil() expressions.
2514 // \ingroup dense_vector
2515 //
2516 // \param dv The dense vector \a ceil() expression.
2517 // \return The resulting dense vector.
2518 //
2519 // This function implements a performance optimized treatment of the \a ceil() operation on
2520 // a dense vector \a ceil() expression.
2521 */
2522 template< typename VT // Type of the dense vector
2523 , bool TF > // Transpose flag
decltype(auto)2524 inline decltype(auto) ceil( const DVecMapExpr<VT,Ceil,TF>& dv )
2525 {
2526 BLAZE_FUNCTION_TRACE;
2527
2528 return dv;
2529 }
2530 /*! \endcond */
2531 //*************************************************************************************************
2532
2533
2534 //*************************************************************************************************
2535 /*! \cond BLAZE_INTERNAL */
2536 /*!\brief Applies the \a trunc() function to a dense vector \a trunc() expressions.
2537 // \ingroup dense_vector
2538 //
2539 // \param dv The dense vector \a trunc() expression.
2540 // \return The resulting dense vector.
2541 //
2542 // This function implements a performance optimized treatment of the \a trunc() operation on
2543 // a dense vector \a trunc() expression.
2544 */
2545 template< typename VT // Type of the dense vector
2546 , bool TF > // Transpose flag
decltype(auto)2547 inline decltype(auto) trunc( const DVecMapExpr<VT,Trunc,TF>& dv )
2548 {
2549 BLAZE_FUNCTION_TRACE;
2550
2551 return dv;
2552 }
2553 /*! \endcond */
2554 //*************************************************************************************************
2555
2556
2557 //*************************************************************************************************
2558 /*! \cond BLAZE_INTERNAL */
2559 /*!\brief Applies the \a round() function to a dense vector \a round() expressions.
2560 // \ingroup dense_vector
2561 //
2562 // \param dv The dense vector \a round() expression.
2563 // \return The resulting dense vector.
2564 //
2565 // This function implements a performance optimized treatment of the \a round() operation on
2566 // a dense vector \a round() expression.
2567 */
2568 template< typename VT // Type of the dense vector
2569 , bool TF > // Transpose flag
decltype(auto)2570 inline decltype(auto) round( const DVecMapExpr<VT,Round,TF>& dv )
2571 {
2572 BLAZE_FUNCTION_TRACE;
2573
2574 return dv;
2575 }
2576 /*! \endcond */
2577 //*************************************************************************************************
2578
2579
2580 //*************************************************************************************************
2581 /*! \cond BLAZE_INTERNAL */
2582 /*!\brief Complex conjugate function for complex conjugate dense vector expressions.
2583 // \ingroup dense_vector
2584 //
2585 // \param dv The complex conjugate dense vector expression.
2586 // \return The original dense vector.
2587 //
2588 // This function implements a performance optimized treatment of the complex conjugate operation
2589 // on a dense vector complex conjugate expression. It returns an expression representing the
2590 // original dense vector:
2591
2592 \code
2593 blaze::DynamicVector< complex<double> > a, b;
2594 // ... Resizing and initialization
2595 b = conj( conj( a ) );
2596 \endcode
2597 */
2598 template< typename VT // Type of the dense vector
2599 , bool TF > // Transpose flag
decltype(auto)2600 inline decltype(auto) conj( const DVecMapExpr<VT,Conj,TF>& dv )
2601 {
2602 BLAZE_FUNCTION_TRACE;
2603
2604 return dv.operand();
2605 }
2606 /*! \endcond */
2607 //*************************************************************************************************
2608
2609
2610 //*************************************************************************************************
2611 /*! \cond BLAZE_INTERNAL */
2612 /*!\brief Complex conjugate function for conjugate transpose dense vector expressions.
2613 // \ingroup dense_vector
2614 //
2615 // \param dv The conjugate transpose dense vector expression.
2616 // \return The transpose dense vector.
2617 //
2618 // This function implements a performance optimized treatment of the complex conjugate operation
2619 // on a dense vector conjugate transpose expression. It returns an expression representing the
2620 // transpose of the dense vector:
2621
2622 \code
2623 blaze::DynamicVector< complex<double> > a, b;
2624 // ... Resizing and initialization
2625 b = conj( ctrans( a ) );
2626 \endcode
2627 */
2628 template< typename VT // Type of the dense vector
2629 , bool TF > // Transpose flag
decltype(auto)2630 inline decltype(auto) conj( const DVecTransExpr<DVecMapExpr<VT,Conj,TF>,!TF>& dv )
2631 {
2632 BLAZE_FUNCTION_TRACE;
2633
2634 return trans( dv.operand().operand() );
2635 }
2636 /*! \endcond */
2637 //*************************************************************************************************
2638
2639
2640 //*************************************************************************************************
2641 /*! \cond BLAZE_INTERNAL */
2642 /*!\brief Real part function for real part dense vector expressions.
2643 // \ingroup dense_vector
2644 //
2645 // \param dv The real part dense vector expression.
2646 // \return The real part of each single element of \a dv.
2647 //
2648 // This function implements a performance optimized treatment of the real part operation on
2649 // a dense vector real part expression.
2650 */
2651 template< typename VT // Type of the dense vector
2652 , bool TF > // Transpose flag
decltype(auto)2653 inline decltype(auto) real( const DVecMapExpr<VT,Real,TF>& dv )
2654 {
2655 BLAZE_FUNCTION_TRACE;
2656
2657 return dv;
2658 }
2659 /*! \endcond */
2660 //*************************************************************************************************
2661
2662
2663
2664
2665 //=================================================================================================
2666 //
2667 // GLOBAL ARITHMETIC OPERATORS
2668 //
2669 //=================================================================================================
2670
2671 //*************************************************************************************************
2672 /*!\brief Addition operator for the addition of a dense vector and a scalar value
2673 // (\f$ \vec{a}=\vec{b}+s \f$).
2674 // \ingroup dense_vector
2675 //
2676 // \param vec The left-hand side dense vector for the addition.
2677 // \param scalar The right-hand side scalar value for the addition.
2678 // \return The vector sum.
2679 //
2680 // This operator represents the elementwise addition of a dense vector and a uniform vector
2681 // represented by a scalar value:
2682
2683 \code
2684 blaze::DynamicVector<double> a, b;
2685 // ... Resizing and initialization
2686 b = a + 1.25;
2687 \endcode
2688
2689 // The operator returns an expression representing a dense vector of the higher-order element type
2690 // of the involved data types \a VT::ElementType and \a ST. Both data types \a VT::ElementType and
2691 // \a ST have to be supported by the AddTrait class template. Note that this operator only works
2692 // for scalar values of built-in data type.
2693 */
2694 template< typename VT // Type of the left-hand side dense vector
2695 , bool TF // Transpose flag of the left-hand side dense vector
2696 , typename ST // Type of the right-hand side scalar
2697 , EnableIf_t< IsScalar_v<ST> >* = nullptr >
2698 inline decltype(auto) operator+( const DenseVector<VT,TF>& vec, ST scalar )
2699 {
2700 BLAZE_FUNCTION_TRACE;
2701
2702 using ET = ElementType_t<VT>;
2703 using ScalarType = If_t< IsNumeric_v<ET> && IsNumeric_v<ST>, AddTrait_t<ET,ST>, ST >;
2704 return map( *vec, blaze::bind2nd( Add{}, ScalarType( scalar ) ) );
2705 }
2706 //*************************************************************************************************
2707
2708
2709 //*************************************************************************************************
2710 /*!\brief Addition operator for the addition of a scalar value and a dense vector
2711 // (\f$ \vec{a}=s+\vec{b} \f$).
2712 // \ingroup dense_vector
2713 //
2714 // \param scalar The left-hand side scalar value for the addition.
2715 // \param vec The right-hand side dense vector for the addition.
2716 // \return The vector sum.
2717 //
2718 // This operator represents the elementwise addition of a uniform vector represented by a scalar
2719 // value and a dense vector:
2720
2721 \code
2722 blaze::DynamicVector<double> a, b;
2723 // ... Resizing and initialization
2724 b = 1.25 + a;
2725 \endcode
2726
2727 // The operator returns an expression representing a dense vector of the higher-order element type
2728 // of the involved data types \a VT::ElementType and \a ST. Both data types \a VT::ElementType and
2729 // \a ST have to be supported by the AddTrait class template. Note that this operator only works
2730 // for scalar values of built-in data type.
2731 */
2732 template< typename ST // Type of the left-hand side scalar
2733 , typename VT // Type of the right-hand side dense vector
2734 , bool TF // Transpose flag of the right-hand side dense vector
2735 , EnableIf_t< IsScalar_v<ST> >* = nullptr >
2736 inline decltype(auto) operator+( ST scalar, const DenseVector<VT,TF>& vec )
2737 {
2738 BLAZE_FUNCTION_TRACE;
2739
2740 using ET = ElementType_t<VT>;
2741 using ScalarType = If_t< IsNumeric_v<ST> && IsNumeric_v<ET>, AddTrait_t<ST,ET>, ST >;
2742 return map( *vec, blaze::bind1st( Add{}, ScalarType( scalar ) ) );
2743 }
2744 //*************************************************************************************************
2745
2746
2747 //*************************************************************************************************
2748 /*!\brief Subtraction operator for the subtraction of a dense vector and a scalar value
2749 // (\f$ \vec{a}=\vec{b}-s \f$).
2750 // \ingroup dense_vector
2751 //
2752 // \param vec The left-hand side dense vector for the subtraction.
2753 // \param scalar The right-hand side scalar value for the subtraction.
2754 // \return The vector difference.
2755 //
2756 // This operator represents the elementwise subtraction of a uniform vector represented by a
2757 // scalar value from a dense vector:
2758
2759 \code
2760 blaze::DynamicVector<double> a, b;
2761 // ... Resizing and initialization
2762 b = a - 1.25;
2763 \endcode
2764
2765 // The operator returns an expression representing a dense vector of the higher-order element type
2766 // of the involved data types \a VT::ElementType and \a ST. Both data types \a VT::ElementType and
2767 // \a ST have to be supported by the SubTrait class template. Note that this operator only works
2768 // for scalar values of built-in data type.
2769 */
2770 template< typename VT // Type of the left-hand side dense vector
2771 , bool TF // Transpose flag of the left-hand side dense vector
2772 , typename ST // Type of the right-hand side scalar
2773 , EnableIf_t< IsScalar_v<ST> >* = nullptr >
2774 inline decltype(auto) operator-( const DenseVector<VT,TF>& vec, ST scalar )
2775 {
2776 BLAZE_FUNCTION_TRACE;
2777
2778 using ET = ElementType_t<VT>;
2779 using ScalarType = If_t< IsNumeric_v<ET> && IsNumeric_v<ST>, SubTrait_t<ET,ST>, ST >;
2780 return map( *vec, blaze::bind2nd( Sub{}, ScalarType( scalar ) ) );
2781 }
2782 //*************************************************************************************************
2783
2784
2785 //*************************************************************************************************
2786 /*!\brief Subtraction operator for the subtraction of a scalar value and a dense vector
2787 // (\f$ \vec{a}=s-\vec{b} \f$).
2788 // \ingroup dense_vector
2789 //
2790 // \param scalar The left-hand side scalar value for the subtraction.
2791 // \param vec The right-hand side dense vector for the subtraction.
2792 // \return The vector difference.
2793 //
2794 // This operator represents the elementwise subtraction of a dense vector from a uniform vector
2795 // represented by a scalar value:
2796
2797 \code
2798 blaze::DynamicVector<double> a, b;
2799 // ... Resizing and initialization
2800 b = 1.25 - a;
2801 \endcode
2802
2803 // The operator returns an expression representing a dense vector of the higher-order element type
2804 // of the involved data types \a VT::ElementType and \a ST. Both data types \a VT::ElementType and
2805 // \a ST have to be supported by the SubTrait class template. Note that this operator only works
2806 // for scalar values of built-in data type.
2807 */
2808 template< typename ST // Type of the left-hand side scalar
2809 , typename VT // Type of the right-hand side dense vector
2810 , bool TF // Transpose flag of the right-hand side dense vector
2811 , EnableIf_t< IsScalar_v<ST> >* = nullptr >
2812 inline decltype(auto) operator-( ST scalar, const DenseVector<VT,TF>& vec )
2813 {
2814 BLAZE_FUNCTION_TRACE;
2815
2816 using ET = ElementType_t<VT>;
2817 using ScalarType = If_t< IsNumeric_v<ST> && IsNumeric_v<ET>, SubTrait_t<ST,ET>, ST >;
2818 return map( *vec, blaze::bind1st( Sub{}, ScalarType( scalar ) ) );
2819 }
2820 //*************************************************************************************************
2821
2822
2823 //*************************************************************************************************
2824 /*!\brief Division operator for the division of a scalar value and a dense vector
2825 // (\f$ \vec{a}=s/\vec{b} \f$).
2826 // \ingroup dense_vector
2827 //
2828 // \param scalar The left-hand side scalar value for the division.
2829 // \param vec The right-hand side dense vector for the division.
2830 // \return The vector quotient.
2831 //
2832 // This operator represents the elementwise division of a uniform vector represented by a scalar
2833 // value and a dense vector:
2834
2835 \code
2836 blaze::DynamicVector<double> a, b;
2837 // ... Resizing and initialization
2838 b = 1.25 / a;
2839 \endcode
2840
2841 // The operator returns an expression representing a dense vector of the higher-order element type
2842 // of the involved data types \a VT::ElementType and \a ST. Both data types \a VT::ElementType and
2843 // \a ST have to be supported by the DivTrait class template. Note that this operator only works
2844 // for scalar values of built-in data type.
2845 */
2846 template< typename ST // Type of the left-hand side scalar
2847 , typename VT // Type of the right-hand side dense vector
2848 , bool TF // Transpose flag of the right-hand side dense vector
2849 , EnableIf_t< IsScalar_v<ST> >* = nullptr >
2850 inline decltype(auto) operator/( ST scalar, const DenseVector<VT,TF>& vec )
2851 {
2852 BLAZE_FUNCTION_TRACE;
2853
2854 using ET = ElementType_t<VT>;
2855 using ScalarType = If_t< IsNumeric_v<ST> && IsNumeric_v<ET>, DivTrait_t<ST,ET>, ST >;
2856 return map( *vec, blaze::bind1st( Div{}, ScalarType( scalar ) ) );
2857 }
2858 //*************************************************************************************************
2859
2860
2861 //*************************************************************************************************
2862 /*!\brief Left-shift operator for the uniform left-shift of a dense vector.
2863 // \ingroup dense_vector
2864 //
2865 // \param vec The dense vector for the uniform left-shift operation.
2866 // \param count The number of bits to shift all vector elements.
2867 // \return The resulting vector.
2868 //
2869 // This operator represents the uniform left-shift of all elements of a dense vector:
2870
2871 \code
2872 blaze::DynamicVector<unsigned int> a, b;
2873 // ... Resizing and initialization
2874 b = a << 3;
2875 \endcode
2876 */
2877 template< typename VT // Type of the dense vector
2878 , bool TF > // Transpose flag
2879 inline decltype(auto) operator<<( const DenseVector<VT,TF>& vec, int count )
2880 {
2881 BLAZE_FUNCTION_TRACE;
2882
2883 return map( *vec, ShiftLI( count ) );
2884 }
2885 //*************************************************************************************************
2886
2887
2888 //*************************************************************************************************
2889 /*!\brief Right-shift operator for the uniform right-shift of a dense vector.
2890 // \ingroup dense_vector
2891 //
2892 // \param vec The dense vector for the uniform right-shift operation.
2893 // \param count The number of bits to shift all vector elements.
2894 // \return The resulting vector.
2895 //
2896 // This operator represents the uniform right-shift of all elements of a dense vector:
2897
2898 \code
2899 blaze::DynamicVector<unsigned int> a, b;
2900 // ... Resizing and initialization
2901 b = a >> 3;
2902 \endcode
2903 */
2904 template< typename VT // Type of the dense vector
2905 , bool TF > // Transpose flag
decltype(auto)2906 inline decltype(auto) operator>>( const DenseVector<VT,TF>& vec, int count )
2907 {
2908 BLAZE_FUNCTION_TRACE;
2909
2910 return map( *vec, ShiftRI( count ) );
2911 }
2912 //*************************************************************************************************
2913
2914
2915 //*************************************************************************************************
2916 /*!\brief Bitwise AND operator for the bitwise AND of a dense vector and a scalar value.
2917 // \ingroup dense_vector
2918 //
2919 // \param vec The left-hand side dense vector for the bitwise AND.
2920 // \param scalar The right-hand side scalar value for the bitwise AND.
2921 // \return The resulting vector.
2922 //
2923 // This operator represents the bitwise AND of a scalar value with all elements of a dense vector:
2924
2925 \code
2926 blaze::DynamicVector<unsigned int> a, b;
2927 // ... Resizing and initialization
2928 b = a & 7U;
2929 \endcode
2930 */
2931 template< typename VT // Type of the left-hand side dense vector
2932 , bool TF // Transpose flag
2933 , typename ST // Type of the right-hand side scalar
2934 , EnableIf_t< IsScalar_v<ST> >* = nullptr >
decltype(auto)2935 inline decltype(auto) operator&( const DenseVector<VT,TF>& vec, ST scalar )
2936 {
2937 BLAZE_FUNCTION_TRACE;
2938
2939 return map( *vec, blaze::bind2nd( Bitand{}, scalar ) );
2940 }
2941 //*************************************************************************************************
2942
2943
2944 //*************************************************************************************************
2945 /*!\brief Bitwise OR operator for the bitwise OR of a dense vector and a scalar value.
2946 // \ingroup dense_vector
2947 //
2948 // \param vec The left-hand side dense vector for the bitwise OR.
2949 // \param scalar The right-hand side scalar value for the bitwise OR.
2950 // \return The resulting vector.
2951 //
2952 // This operator represents the bitwise OR of a scalar value with all elements of a dense vector:
2953
2954 \code
2955 blaze::DynamicVector<unsigned int> a, b;
2956 // ... Resizing and initialization
2957 b = a | 7U;
2958 \endcode
2959 */
2960 template< typename VT // Type of the left-hand side dense vector
2961 , bool TF // Transpose flag
2962 , typename ST // Type of the right-hand side scalar
2963 , EnableIf_t< IsScalar_v<ST> >* = nullptr >
2964 inline decltype(auto) operator|( const DenseVector<VT,TF>& vec, ST scalar )
2965 {
2966 BLAZE_FUNCTION_TRACE;
2967
2968 return map( *vec, blaze::bind2nd( Bitor{}, scalar ) );
2969 }
2970 //*************************************************************************************************
2971
2972
2973 //*************************************************************************************************
2974 /*!\brief Bitwise XOR operator for the bitwise XOR of a dense vector and a scalar value.
2975 // \ingroup dense_vector
2976 //
2977 // \param vec The left-hand side dense vector for the bitwise XOR.
2978 // \param scalar The right-hand side scalar value for the bitwise XOR.
2979 // \return The resulting vector.
2980 //
2981 // This operator represents the bitwise XOR of a scalar value with all elements of a dense vector:
2982
2983 \code
2984 blaze::DynamicVector<unsigned int> a, b;
2985 // ... Resizing and initialization
2986 b = a ^ 7U;
2987 \endcode
2988 */
2989 template< typename VT // Type of the left-hand side dense vector
2990 , bool TF // Transpose flag
2991 , typename ST // Type of the right-hand side scalar
2992 , EnableIf_t< IsScalar_v<ST> >* = nullptr >
2993 inline decltype(auto) operator^( const DenseVector<VT,TF>& vec, ST scalar )
2994 {
2995 BLAZE_FUNCTION_TRACE;
2996
2997 return map( *vec, blaze::bind2nd( Bitxor{}, scalar ) );
2998 }
2999 //*************************************************************************************************
3000
3001
3002
3003
3004 //=================================================================================================
3005 //
3006 // GLOBAL LOGICAL OPERATORS
3007 //
3008 //=================================================================================================
3009
3010 //*************************************************************************************************
3011 /*!\brief Logical NOT operator for the logical NOT of a dense vector.
3012 // \ingroup dense_vector
3013 //
3014 // \param vec The dense vector for the logical NOT.
3015 // \return The negated vector.
3016 //
3017 // This operator represents the logical NOT of all elements of a dense vector:
3018
3019 \code
3020 blaze::DynamicVector<bool> a, b;
3021 // ... Resizing and initialization
3022 b = !a;
3023 \endcode
3024 */
3025 template< typename VT // Type of the dense vector
3026 , bool TF > // Transpose flag
3027 inline decltype(auto) operator!( const DenseVector<VT,TF>& vec )
3028 {
3029 BLAZE_FUNCTION_TRACE;
3030
3031 return map( *vec, Not{} );
3032 }
3033 //*************************************************************************************************
3034
3035
3036
3037
3038 //=================================================================================================
3039 //
3040 // ISALIGNED SPECIALIZATIONS
3041 //
3042 //=================================================================================================
3043
3044 //*************************************************************************************************
3045 /*! \cond BLAZE_INTERNAL */
3046 template< typename VT, typename OP, bool TF >
3047 struct IsAligned< DVecMapExpr<VT,OP,TF> >
3048 : public IsAligned<VT>
3049 {};
3050 /*! \endcond */
3051 //*************************************************************************************************
3052
3053
3054
3055
3056 //=================================================================================================
3057 //
3058 // ISPADDED SPECIALIZATIONS
3059 //
3060 //=================================================================================================
3061
3062 //*************************************************************************************************
3063 /*! \cond BLAZE_INTERNAL */
3064 template< typename VT, typename OP, bool TF >
3065 struct IsPadded< DVecMapExpr<VT,OP,TF> >
3066 : public BoolConstant< IsPadded_v<VT> && IsPaddingEnabled_v<OP> >
3067 {};
3068 /*! \endcond */
3069 //*************************************************************************************************
3070
3071 } // namespace blaze
3072
3073 #endif
3074