1 //=================================================================================================
2 /*!
3 //  \file blaze/math/expressions/SVecMapExpr.h
4 //  \brief Header file for the sparse 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_SVECMAPEXPR_H_
36 #define _BLAZE_MATH_EXPRESSIONS_SVECMAPEXPR_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/RequiresEvaluation.h>
47 #include <blaze/math/constraints/SparseVector.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/Forward.h>
52 #include <blaze/math/expressions/SparseVector.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/sparse/ValueIndexPair.h>
57 #include <blaze/math/traits/MapTrait.h>
58 #include <blaze/math/traits/MultTrait.h>
59 #include <blaze/math/typetraits/IsExpression.h>
60 #include <blaze/math/typetraits/IsScalar.h>
61 #include <blaze/math/typetraits/RequiresEvaluation.h>
62 #include <blaze/math/typetraits/UnderlyingBuiltin.h>
63 #include <blaze/math/typetraits/UnderlyingScalar.h>
64 #include <blaze/system/MacroDisable.h>
65 #include <blaze/util/Assert.h>
66 #include <blaze/util/EnableIf.h>
67 #include <blaze/util/FunctionTrace.h>
68 #include <blaze/util/mpl/If.h>
69 #include <blaze/util/Types.h>
70 #include <blaze/util/typetraits/IsSame.h>
71 #include <blaze/util/typetraits/RemoveReference.h>
72 
73 
74 namespace blaze {
75 
76 //=================================================================================================
77 //
78 //  CLASS SVECMAPEXPR
79 //
80 //=================================================================================================
81 
82 //*************************************************************************************************
83 /*!\brief Expression object for the sparse vector map() function.
84 // \ingroup sparse_vector_expression
85 //
86 // The SVecMapExpr class represents the compile time expression for the evaluation of a custom
87 // operation on each element of a sparse vector via the map() function.
88 */
89 template< typename VT  // Type of the sparse vector
90         , typename OP  // Type of the custom operation
91         , bool TF >    // Transpose flag
92 class SVecMapExpr
93    : public VecMapExpr< SparseVector< SVecMapExpr<VT,OP,TF>, TF > >
94    , private Computation
95 {
96  private:
97    //**Type definitions****************************************************************************
98    using RT = ResultType_t<VT>;  //!< Result type of the sparse vector expression.
99    using RN = ReturnType_t<VT>;  //!< Return type of the sparse vector expression.
100    //**********************************************************************************************
101 
102    //**Serial evaluation strategy******************************************************************
103    //! Compilation switch for the serial evaluation strategy of the map expression.
104    /*! The \a useAssign compile time constant expression represents a compilation switch for
105        the serial evaluation strategy of the map expression. In case the given sparse vector
106        expression of type \a VT requires an intermediate evaluation, \a useAssign will be
107        set to 1 and the map expression will be evaluated via the \a assign function family.
108        Otherwise \a useAssign will be set to 0 and the expression will be evaluated via the
109        subscript operator. */
110    static constexpr bool useAssign = RequiresEvaluation_v<VT>;
111 
112    /*! \cond BLAZE_INTERNAL */
113    //! Helper variable template for the explicit application of the SFINAE principle.
114    template< typename VT2 >
115    static constexpr bool UseAssign_v = useAssign;
116    /*! \endcond */
117    //**********************************************************************************************
118 
119    //**Parallel evaluation strategy****************************************************************
120    /*! \cond BLAZE_INTERNAL */
121    //! Helper variable template for the explicit application of the SFINAE principle.
122    /*! This variable template is a helper for the selection of the parallel evaluation strategy.
123        In case either the target vector or the sparse vector operand is not SMP assignable and
124        the vector operand requires an intermediate evaluation, the variable is set to 1 and the
125        expression specific evaluation strategy is selected. Otherwise the variable is set to 0
126        and the default strategy is chosen. */
127    template< typename VT2 >
128    static constexpr bool UseSMPAssign_v =
129       ( ( !VT2::smpAssignable || !VT::smpAssignable ) && useAssign );
130    /*! \endcond */
131    //**********************************************************************************************
132 
133  public:
134    //**Type definitions****************************************************************************
135    //! Type of this SVecMapExpr instance.
136    using This = SVecMapExpr<VT,OP,TF>;
137 
138    //! Base type of this SVecMapExpr instance.
139    using BaseType = VecMapExpr< SparseVector<This,TF> >;
140 
141    using ResultType    = MapTrait_t<RT,OP>;            //!< Result type for expression template evaluations.
142    using TransposeType = TransposeType_t<ResultType>;  //!< Transpose type for expression template evaluations.
143    using ElementType   = ElementType_t<ResultType>;    //!< Resulting element type.
144 
145    //! Return type for expression template evaluations.
146    using ReturnType = decltype( std::declval<OP>()( std::declval<RN>() ) );
147 
148    //! Data type for composite expression templates.
149    using CompositeType = If_t< useAssign, const ResultType, const SVecMapExpr& >;
150 
151    //! Composite data type of the sparse vector expression.
152    using Operand = If_t< IsExpression_v<VT>, const VT, const VT& >;
153 
154    //! Data type of the custom unary operation.
155    using Operation = OP;
156    //**********************************************************************************************
157 
158    //**ConstIterator class definition**************************************************************
159    /*!\brief Iterator over the elements of the sparse vector map expression.
160    */
161    class ConstIterator
162    {
163     public:
164       //**Type definitions*************************************************************************
165       //! Element type of the sparse vector expression.
166       using Element = ValueIndexPair<ElementType>;
167 
168       //! Iterator type of the sparse vector expression.
169       using IteratorType = ConstIterator_t< RemoveReference_t<Operand> >;
170 
171       using IteratorCategory = std::forward_iterator_tag;  //!< The iterator category.
172       using ValueType        = Element;                    //!< Type of the underlying pointers.
173       using PointerType      = ValueType*;                 //!< Pointer return type.
174       using ReferenceType    = ValueType&;                 //!< Reference return type.
175       using DifferenceType   = ptrdiff_t;                  //!< Difference between two iterators.
176 
177       // STL iterator requirements
178       using iterator_category = IteratorCategory;  //!< The iterator category.
179       using value_type        = ValueType;         //!< Type of the underlying pointers.
180       using pointer           = PointerType;       //!< Pointer return type.
181       using reference         = ReferenceType;     //!< Reference return type.
182       using difference_type   = DifferenceType;    //!< Difference between two iterators.
183       //*******************************************************************************************
184 
185       //**Constructor******************************************************************************
186       /*!\brief Constructor for the ConstIterator class.
187       //
188       // \param it Iterator to the initial vector element.
189       // \param op The custom unary operation.
190       */
ConstIterator(IteratorType it,OP op)191       inline ConstIterator( IteratorType it, OP op )
192          : it_( it )             // Iterator over the elements of the sparse vector expression
193          , op_( std::move(op) )  // The custom unary operation
194       {}
195       //*******************************************************************************************
196 
197       //**Prefix increment operator****************************************************************
198       /*!\brief Pre-increment operator.
199       //
200       // \return Reference to the incremented expression iterator.
201       */
202       inline ConstIterator& operator++() {
203          ++it_;
204          return *this;
205       }
206       //*******************************************************************************************
207 
208       //**Element access operator******************************************************************
209       /*!\brief Direct access to the sparse vector element at the current iterator position.
210       //
211       // \return The current value of the sparse element.
212       */
213       inline const Element operator*() const {
214          return Element( op_( it_->value() ), it_->index() );
215       }
216       //*******************************************************************************************
217 
218       //**Element access operator******************************************************************
219       /*!\brief Direct access to the sparse vector element at the current iterator position.
220       //
221       // \return Reference to the sparse vector element at the current iterator position.
222       */
223       inline const ConstIterator* operator->() const {
224          return this;
225       }
226       //*******************************************************************************************
227 
228       //**Value function***************************************************************************
229       /*!\brief Access to the current value of the sparse element.
230       //
231       // \return The current value of the sparse element.
232       */
value()233       inline ReturnType value() const {
234          return op_( it_->value() );
235       }
236       //*******************************************************************************************
237 
238       //**Index function***************************************************************************
239       /*!\brief Access to the current index of the sparse element.
240       //
241       // \return The current index of the sparse element.
242       */
index()243       inline size_t index() const {
244          return it_->index();
245       }
246       //*******************************************************************************************
247 
248       //**Equality operator************************************************************************
249       /*!\brief Equality comparison between two ConstIterator objects.
250       //
251       // \param rhs The right-hand side expression iterator.
252       // \return \a true if the iterators refer to the same element, \a false if not.
253       */
254       inline bool operator==( const ConstIterator& rhs ) const {
255          return it_ == rhs.it_;
256       }
257       //*******************************************************************************************
258 
259       //**Inequality operator**********************************************************************
260       /*!\brief Inequality comparison between two ConstIterator objects.
261       //
262       // \param rhs The right-hand side expression iterator.
263       // \return \a true if the iterators don't refer to the same element, \a false if they do.
264       */
265       inline bool operator!=( const ConstIterator& rhs ) const {
266          return it_ != rhs.it_;
267       }
268       //*******************************************************************************************
269 
270       //**Subtraction operator*********************************************************************
271       /*!\brief Calculating the number of elements between two expression iterators.
272       //
273       // \param rhs The right-hand side expression iterator.
274       // \return The number of elements between the two expression iterators.
275       */
276       inline DifferenceType operator-( const ConstIterator& rhs ) const {
277          return it_ - rhs.it_;
278       }
279       //*******************************************************************************************
280 
281     private:
282       //**Member variables*************************************************************************
283       IteratorType it_;  //!< Iterator over the elements of the sparse vector expression.
284       OP           op_;  //!< The custom unary operation.
285       //*******************************************************************************************
286    };
287    //**********************************************************************************************
288 
289    //**Compilation flags***************************************************************************
290    //! Compilation switch for the expression template assignment strategy.
291    static constexpr bool smpAssignable = VT::smpAssignable;
292    //**********************************************************************************************
293 
294    //**Constructor*********************************************************************************
295    /*!\brief Constructor for the SVecMapExpr class.
296    //
297    // \param sv The sparse vector operand of the map expression.
298    // \param op The custom unary operation.
299    */
SVecMapExpr(const VT & sv,OP op)300    inline SVecMapExpr( const VT& sv, OP op ) noexcept
301       : sv_( sv )             // Sparse vector of the map expression
302       , op_( std::move(op) )  // The custom unary operation
303    {}
304    //**********************************************************************************************
305 
306    //**Subscript operator**************************************************************************
307    /*!\brief Subscript operator for the direct access to the vector elements.
308    //
309    // \param index Access index. The index has to be in the range \f$[0..N-1]\f$.
310    // \return The resulting value.
311    */
312    inline ReturnType operator[]( size_t index ) const {
313       BLAZE_INTERNAL_ASSERT( index < sv_.size(), "Invalid vector access index" );
314       return op_( sv_[index] );
315    }
316    //**********************************************************************************************
317 
318    //**At function*********************************************************************************
319    /*!\brief Checked access to the vector elements.
320    //
321    // \param index Access index. The index has to be in the range \f$[0..N-1]\f$.
322    // \return The resulting value.
323    // \exception std::out_of_range Invalid vector access index.
324    */
at(size_t index)325    inline ReturnType at( size_t index ) const {
326       if( index >= sv_.size() ) {
327          BLAZE_THROW_OUT_OF_RANGE( "Invalid vector access index" );
328       }
329       return (*this)[index];
330    }
331    //**********************************************************************************************
332 
333    //**Begin function******************************************************************************
334    /*!\brief Returns an iterator to the first non-zero element of the sparse vector.
335    //
336    // \return Iterator to the first non-zero element of the sparse vector.
337    */
begin()338    inline ConstIterator begin() const {
339       return ConstIterator( sv_.begin(), op_ );
340    }
341    //**********************************************************************************************
342 
343    //**End function********************************************************************************
344    /*!\brief Returns an iterator just past the last non-zero element of the sparse vector.
345    //
346    // \return Iterator just past the last non-zero element of the sparse vector.
347    */
end()348    inline ConstIterator end() const {
349       return ConstIterator( sv_.end(), op_ );
350    }
351    //**********************************************************************************************
352 
353    //**Size function*******************************************************************************
354    /*!\brief Returns the current size/dimension of the vector.
355    //
356    // \return The size of the vector.
357    */
size()358    inline size_t size() const noexcept {
359       return sv_.size();
360    }
361    //**********************************************************************************************
362 
363    //**NonZeros function***************************************************************************
364    /*!\brief Returns the number of non-zero elements in the sparse vector.
365    //
366    // \return The number of non-zero elements in the sparse vector.
367    */
nonZeros()368    inline size_t nonZeros() const {
369       return sv_.nonZeros();
370    }
371    //**********************************************************************************************
372 
373    //**Find function*******************************************************************************
374    /*!\brief Searches for a specific vector element.
375    //
376    // \param index The index of the search element.
377    // \return Iterator to the element in case the index is found, end() iterator otherwise.
378    */
find(size_t index)379    inline ConstIterator find( size_t index ) const {
380       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( VT );
381       return ConstIterator( sv_.find( index ), op_ );
382    }
383    //**********************************************************************************************
384 
385    //**LowerBound function*************************************************************************
386    /*!\brief Returns an iterator to the first index not less then the given index.
387    //
388    // \param index The index of the search element.
389    // \return Iterator to the first index not less then the given index, end() iterator otherwise.
390    */
lowerBound(size_t index)391    inline ConstIterator lowerBound( size_t index ) const {
392       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( VT );
393       return ConstIterator( sv_.lowerBound( index ), op_ );
394    }
395    //**********************************************************************************************
396 
397    //**UpperBound function*************************************************************************
398    /*!\brief Returns an iterator to the first index greater then the given index.
399    //
400    // \param index The index of the search element.
401    // \return Iterator to the first index greater then the given index, end() iterator otherwise.
402    */
upperBound(size_t index)403    inline ConstIterator upperBound( size_t index ) const {
404       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( VT );
405       return ConstIterator( sv_.upperBound( index ), op_ );
406    }
407    //**********************************************************************************************
408 
409    //**Operand access******************************************************************************
410    /*!\brief Returns the sparse vector operand.
411    //
412    // \return The sparse vector operand.
413    */
operand()414    inline Operand operand() const noexcept {
415       return sv_;
416    }
417    //**********************************************************************************************
418 
419    //**Operation access****************************************************************************
420    /*!\brief Returns a copy of the custom operation.
421    //
422    // \return A copy of the custom operation.
423    */
operation()424    inline Operation operation() const {
425       return op_;
426    }
427    //**********************************************************************************************
428 
429    //**********************************************************************************************
430    /*!\brief Returns whether the expression can alias with the given address \a alias.
431    //
432    // \param alias The alias to be checked.
433    // \return \a true in case the expression can alias, \a false otherwise.
434    */
435    template< typename T >
canAlias(const T * alias)436    inline bool canAlias( const T* alias ) const noexcept {
437       return sv_.canAlias( alias );
438    }
439    //**********************************************************************************************
440 
441    //**********************************************************************************************
442    /*!\brief Returns whether the expression is aliased with the given address \a alias.
443    //
444    // \param alias The alias to be checked.
445    // \return \a true in case an alias effect is detected, \a false otherwise.
446    */
447    template< typename T >
isAliased(const T * alias)448    inline bool isAliased( const T* alias ) const noexcept {
449       return sv_.isAliased( alias );
450    }
451    //**********************************************************************************************
452 
453    //**********************************************************************************************
454    /*!\brief Returns whether the expression can be used in SMP assignments.
455    //
456    // \return \a true in case the expression can be used in SMP assignments, \a false if not.
457    */
canSMPAssign()458    inline bool canSMPAssign() const noexcept {
459       return sv_.canSMPAssign();
460    }
461    //**********************************************************************************************
462 
463  private:
464    //**Member variables****************************************************************************
465    Operand   sv_;  //!< Sparse vector of the map expression.
466    Operation op_;  //!< The custom unary operation.
467    //**********************************************************************************************
468 
469    //**Assignment to dense vectors*****************************************************************
470    /*! \cond BLAZE_INTERNAL */
471    /*!\brief Assignment of a sparse vector map expression to a dense vector.
472    // \ingroup sparse_vector
473    //
474    // \param lhs The target left-hand side dense vector.
475    // \param rhs The right-hand side map expression to be assigned.
476    // \return void
477    //
478    // This function implements the performance optimized assignment of a sparse vector map
479    // expression to a dense vector. Due to the explicit application of the SFINAE principle,
480    // this function can only be selected by the compiler in case the operand requires an
481    // intermediate evaluation.
482    */
483    template< typename VT2 >  // Type of the target dense vector
484    friend inline auto assign( DenseVector<VT2,TF>& lhs, const SVecMapExpr& rhs )
485       -> EnableIf_t< UseAssign_v<VT2> >
486    {
487       BLAZE_FUNCTION_TRACE;
488 
489       BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE( RT );
490       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
491       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
492 
493       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
494 
495       const RT tmp( serial( rhs.sv_ ) );
496       assign( *lhs, map( tmp, rhs.op_ ) );
497    }
498    /*! \endcond */
499    //**********************************************************************************************
500 
501    //**Assignment to sparse vectors****************************************************************
502    /*! \cond BLAZE_INTERNAL */
503    /*!\brief Assignment of a sparse vector map expression to a sparse vector.
504    // \ingroup sparse_vector
505    //
506    // \param lhs The target left-hand side sparse vector.
507    // \param rhs The right-hand side map expression to be assigned.
508    // \return void
509    //
510    // This function implements the performance optimized assignment of a sparse vector map
511    // expression to a sparse vector. Due to the explicit application of the SFINAE principle,
512    // this function can only be selected by the compiler in case the operand requires an
513    // intermediate evaluation and the underlying numeric data type of the operand and the
514    // target vector are identical.
515    */
516    template< typename VT2 >  // Type of the target sparse vector
517    friend inline auto assign( SparseVector<VT2,TF>& lhs, const SVecMapExpr& rhs )
518       -> EnableIf_t< UseAssign_v<VT2> &&
519                      IsSame_v< UnderlyingScalar_t<VT>, UnderlyingScalar_t<VT2> > >
520    {
521       BLAZE_FUNCTION_TRACE;
522 
523       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
524 
525       assign( *lhs, rhs.sv_ );
526 
527       const auto end( (*lhs).end() );
528       for( auto element=(*lhs).begin(); element!=end; ++element ) {
529          element->value() = rhs.op_( element->value() );
530       }
531    }
532    /*! \endcond */
533    //**********************************************************************************************
534 
535    //**Assignment to sparse vectors****************************************************************
536    /*! \cond BLAZE_INTERNAL */
537    /*!\brief Assignment of a sparse vector map expression to a sparse vector.
538    // \ingroup sparse_vector
539    //
540    // \param lhs The target left-hand side sparse vector.
541    // \param rhs The right-hand side map expression to be assigned.
542    // \return void
543    //
544    // This function implements the performance optimized assignment of a sparse vector map
545    // expression to a sparse vector. Due to the explicit application of the SFINAE principle,
546    // this function can only be selected by the compiler in case the operand requires an
547    // intermediate evaluation and the underlying numeric data type of the operand and the
548    // target vector differ.
549    */
550    template< typename VT2 >  // Type of the target sparse vector
551    friend inline auto assign( SparseVector<VT2,TF>& lhs, const SVecMapExpr& rhs )
552       -> EnableIf_t< UseAssign_v<VT2> &&
553                      !IsSame_v< UnderlyingScalar_t<VT>, UnderlyingScalar_t<VT2> > >
554    {
555       BLAZE_FUNCTION_TRACE;
556 
557       BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE( RT );
558       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
559       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
560 
561       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
562 
563       const RT tmp( serial( rhs.sv_ ) );
564       (*lhs).reserve( tmp.nonZeros() );
565       assign( *lhs, map( tmp, rhs.op_ ) );
566    }
567    /*! \endcond */
568    //**********************************************************************************************
569 
570    //**Addition assignment to dense vectors********************************************************
571    /*! \cond BLAZE_INTERNAL */
572    /*!\brief Addition assignment of a sparse vector map expression to a dense vector.
573    // \ingroup sparse_vector
574    //
575    // \param lhs The target left-hand side dense vector.
576    // \param rhs The right-hand side map expression to be added.
577    // \return void
578    //
579    // This function implements the performance optimized addition assignment of a sparse vector
580    // map expression to a dense vector. Due to the explicit application of the SFINAE principle,
581    // this function can only be selected by the compiler in case the operand requires an
582    // intermediate evaluation.
583    */
584    template< typename VT2 >  // Type of the target dense vector
585    friend inline auto addAssign( DenseVector<VT2,TF>& lhs, const SVecMapExpr& rhs )
586       -> EnableIf_t< UseAssign_v<VT2> >
587    {
588       BLAZE_FUNCTION_TRACE;
589 
590       BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE( RT );
591       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
592       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
593 
594       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
595 
596       const RT tmp( serial( rhs.sv_ ) );
597       addAssign( *lhs, map( tmp, rhs.op_ ) );
598    }
599    /*! \endcond */
600    //**********************************************************************************************
601 
602    //**Addition assignment to sparse vectors*******************************************************
603    // No special implementation for the addition assignment to sparse vectors.
604    //**********************************************************************************************
605 
606    //**Subtraction assignment to dense vectors*****************************************************
607    /*! \cond BLAZE_INTERNAL */
608    /*!\brief Subtraction assignment of a sparse vector map expression to a dense vector.
609    // \ingroup sparse_vector
610    //
611    // \param lhs The target left-hand side dense vector.
612    // \param rhs The right-hand side map expression to be subtracted.
613    // \return void
614    //
615    // This function implements the performance optimized subtraction assignment of a sparse
616    // vector map expression to a dense vector. Due to the explicit application of the SFINAE
617    // principle, this function can only be selected by the compiler in case the operand
618    // requires an intermediate evaluation.
619    */
620    template< typename VT2 >  // Type of the target dense vector
621    friend inline auto subAssign( DenseVector<VT2,TF>& lhs, const SVecMapExpr& rhs )
622       -> EnableIf_t< UseAssign_v<VT2> >
623    {
624       BLAZE_FUNCTION_TRACE;
625 
626       BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE( RT );
627       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
628       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
629 
630       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
631 
632       const RT tmp( serial( rhs.sv_ ) );
633       subAssign( *lhs, map( tmp, rhs.op_ ) );
634    }
635    /*! \endcond */
636    //**********************************************************************************************
637 
638    //**Subtraction assignment to sparse vectors****************************************************
639    // No special implementation for the subtraction assignment to sparse vectors.
640    //**********************************************************************************************
641 
642    //**Multiplication assignment to dense vectors**************************************************
643    /*! \cond BLAZE_INTERNAL */
644    /*!\brief Multiplication assignment of a sparse vector map expression to a dense vector.
645    // \ingroup sparse_vector
646    //
647    // \param lhs The target left-hand side dense vector.
648    // \param rhs The right-hand side map expression to be multiplied.
649    // \return void
650    //
651    // This function implements the performance optimized multiplication assignment of a sparse
652    // vector map expression to a dense vector. Due to the explicit application of the SFINAE
653    // principle, this function can only be selected by the compiler in case the operand requires
654    // an intermediate evaluation.
655    */
656    template< typename VT2 >  // Type of the target dense vector
657    friend inline auto multAssign( DenseVector<VT2,TF>& lhs, const SVecMapExpr& rhs )
658       -> EnableIf_t< UseAssign_v<VT2> >
659    {
660       BLAZE_FUNCTION_TRACE;
661 
662       BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE( RT );
663       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
664       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
665 
666       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
667 
668       const RT tmp( serial( rhs.sv_ ) );
669       multAssign( *lhs, map( tmp, rhs.op_ ) );
670    }
671    /*! \endcond */
672    //**********************************************************************************************
673 
674    //**Multiplication assignment to sparse vectors*************************************************
675    // No special implementation for the multiplication assignment to sparse vectors.
676    //**********************************************************************************************
677 
678    //**SMP assignment to dense vectors*************************************************************
679    /*! \cond BLAZE_INTERNAL */
680    /*!\brief SMP assignment of a sparse vector map expression to a dense vector.
681    // \ingroup sparse_vector
682    //
683    // \param lhs The target left-hand side dense vector.
684    // \param rhs The right-hand side map expression to be assigned.
685    // \return void
686    //
687    // This function implements the performance optimized SMP assignment of a sparse vector map
688    // expression to a dense vector. Due to the explicit application of the SFINAE principle,
689    // this function can only be selected by the compiler in case the expression specific parallel
690    // evaluation strategy is selected.
691    */
692    template< typename VT2 >  // Type of the target dense vector
693    friend inline auto smpAssign( DenseVector<VT2,TF>& lhs, const SVecMapExpr& rhs )
694       -> EnableIf_t< UseSMPAssign_v<VT2> >
695    {
696       BLAZE_FUNCTION_TRACE;
697 
698       BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE( RT );
699       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
700       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
701 
702       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
703 
704       const RT tmp( rhs.sv_ );
705       smpAssign( *lhs, map( tmp, rhs.op_ ) );
706    }
707    /*! \endcond */
708    //**********************************************************************************************
709 
710    //**SMP assignment to sparse vectors************************************************************
711    // No special implementation for the SMP assignment to sparse vectors.
712    //**********************************************************************************************
713 
714    //**SMP addition assignment to dense vectors****************************************************
715    /*! \cond BLAZE_INTERNAL */
716    /*!\brief SMP addition assignment of a sparse vector map expression to a dense vector.
717    // \ingroup sparse_vector
718    //
719    // \param lhs The target left-hand side dense vector.
720    // \param rhs The right-hand side map expression to be added.
721    // \return void
722    //
723    // This function implements the performance optimized SMP addition assignment of a sparse
724    // vector map expression to a dense vector. Due to the explicit application of the SFINAE
725    // principle, this function can only be selected by the compiler in case the expression
726    // specific parallel evaluation strategy is selected.
727    */
728    template< typename VT2 >  // Type of the target dense vector
729    friend inline auto smpAddAssign( DenseVector<VT2,TF>& lhs, const SVecMapExpr& rhs )
730       -> EnableIf_t< UseSMPAssign_v<VT2> >
731    {
732       BLAZE_FUNCTION_TRACE;
733 
734       BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE( RT );
735       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
736       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
737 
738       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
739 
740       const RT tmp( rhs.sv_ );
741       smpAddAssign( *lhs, map( tmp, rhs.op_ ) );
742    }
743    /*! \endcond */
744    //**********************************************************************************************
745 
746    //**SMP addition assignment to sparse vectors***************************************************
747    // No special implementation for the SMP addition assignment to sparse vectors.
748    //**********************************************************************************************
749 
750    //**SMP subtraction assignment to dense vectors*************************************************
751    /*! \cond BLAZE_INTERNAL */
752    /*!\brief SMP subtraction assignment of a sparse vector map expression to a dense vector.
753    // \ingroup sparse_vector
754    //
755    // \param lhs The target left-hand side dense vector.
756    // \param rhs The right-hand side map expression to be subtracted.
757    // \return void
758    //
759    // This function implements the performance optimized SMP subtraction assignment of a sparse
760    // vector map expression to a dense vector. Due to the explicit application of the SFINAE
761    // principle, this function can only be selected by the compiler in case the expression
762    // specific parallel evaluation strategy is selected.
763    */
764    template< typename VT2 >  // Type of the target dense vector
765    friend inline auto smpSubAssign( DenseVector<VT2,TF>& lhs, const SVecMapExpr& rhs )
766       -> EnableIf_t< UseSMPAssign_v<VT2> >
767    {
768       BLAZE_FUNCTION_TRACE;
769 
770       BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE( RT );
771       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
772       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
773 
774       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
775 
776       const RT tmp( rhs.sv_ );
777       smpSubAssign( *lhs, map( tmp, rhs.op_ ) );
778    }
779    /*! \endcond */
780    //**********************************************************************************************
781 
782    //**SMP subtraction assignment to sparse vectors************************************************
783    // No special implementation for the SMP subtraction assignment to sparse vectors.
784    //**********************************************************************************************
785 
786    //**SMP multiplication assignment to dense vectors**********************************************
787    /*! \cond BLAZE_INTERNAL */
788    /*!\brief SMP multiplication assignment of a sparse vector map expression to a dense vector.
789    // \ingroup sparse_vector
790    //
791    // \param lhs The target left-hand side dense vector.
792    // \param rhs The right-hand side map expression to be multiplied.
793    // \return void
794    //
795    // This function implements the performance optimized SMP multiplication assignment of a
796    // sparse vector map expression to a dense vector. Due to the explicit application of the
797    // SFINAE principle, this function can only be selected by the compiler in case the
798    // expression specific parallel evaluation strategy is selected.
799    */
800    template< typename VT2 >  // Type of the target dense vector
801    friend inline auto smpMultAssign( DenseVector<VT2,TF>& lhs, const SVecMapExpr& rhs )
802       -> EnableIf_t< UseSMPAssign_v<VT2> >
803    {
804       BLAZE_FUNCTION_TRACE;
805 
806       BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE( RT );
807       BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( RT, TF );
808       BLAZE_CONSTRAINT_MUST_NOT_REQUIRE_EVALUATION( RT );
809 
810       BLAZE_INTERNAL_ASSERT( (*lhs).size() == rhs.size(), "Invalid vector sizes" );
811 
812       const RT tmp( rhs.sv_ );
813       smpMultAssign( *lhs, map( tmp, rhs.op_ ) );
814    }
815    /*! \endcond */
816    //**********************************************************************************************
817 
818    //**SMP multiplication assignment to sparse vectors*********************************************
819    // No special implementation for the SMP multiplication assignment to sparse vectors.
820    //**********************************************************************************************
821 
822    //**Compile time checks*************************************************************************
823    /*! \cond BLAZE_INTERNAL */
824    BLAZE_CONSTRAINT_MUST_BE_SPARSE_VECTOR_TYPE( VT );
825    BLAZE_CONSTRAINT_MUST_BE_VECTOR_WITH_TRANSPOSE_FLAG( VT, TF );
826    /*! \endcond */
827    //**********************************************************************************************
828 };
829 //*************************************************************************************************
830 
831 
832 
833 
834 //=================================================================================================
835 //
836 //  GLOBAL FUNCTIONS
837 //
838 //=================================================================================================
839 
840 //*************************************************************************************************
841 /*!\brief Evaluates the given custom operation on each non-zero element of the sparse vector \a sv.
842 // \ingroup sparse_vector
843 //
844 // \param sv The input vector.
845 // \param op The custom operation.
846 // \return The custom operation applied to each single element of \a sv.
847 //
848 // The \a map() function evaluates the given custom operation on each non-zero element of the
849 // input vector \a sv. The function returns an expression representing this operation.\n
850 // The following example demonstrates the use of the \a map() function:
851 
852    \code
853    blaze::CompressedVector<double> a, b;
854    // ... Resizing and initialization
855    b = map( a, []( double a ){ return std::sqrt( a ); } );
856    \endcode
857 */
858 template< typename VT    // Type of the sparse vector
859         , bool TF        // Transpose flag
860         , typename OP >  // Type of the custom operation
decltype(auto)861 inline decltype(auto) map( const SparseVector<VT,TF>& sv, OP op )
862 {
863    BLAZE_FUNCTION_TRACE;
864 
865    using ReturnType = const SVecMapExpr<VT,OP,TF>;
866    return ReturnType( *sv, std::move(op) );
867 }
868 //*************************************************************************************************
869 
870 
871 //*************************************************************************************************
872 /*!\brief Evaluates the given custom operation on each non-zero element of the sparse vector \a sv.
873 // \ingroup sparse_vector
874 //
875 // \param sv The input vector.
876 // \param op The custom operation.
877 // \return The custom operation applied to each single element of \a sv.
878 //
879 // The \a forEach() function evaluates the given custom operation on each non-zero element of the
880 // input vector \a sv. The function returns an expression representing this operation.\n
881 // The following example demonstrates the use of the \a forEach() function:
882 
883    \code
884    blaze::CompressedVector<double> a, b;
885    // ... Resizing and initialization
886    b = forEach( a, []( double a ){ return std::sqrt( a ); } );
887    \endcode
888 */
889 template< typename VT    // Type of the sparse vector
890         , bool TF        // Transpose flag
891         , typename OP >  // Type of the custom operation
decltype(auto)892 inline decltype(auto) forEach( const SparseVector<VT,TF>& sv, OP op )
893 {
894    BLAZE_FUNCTION_TRACE;
895 
896    return map( *sv, std::move(op) );
897 }
898 //*************************************************************************************************
899 
900 
901 //*************************************************************************************************
902 /*!\brief Applies the \a abs() function to each non-zero element of the sparse vector \a sv.
903 // \ingroup sparse_vector
904 //
905 // \param sv The input vector.
906 // \return The resulting sparse vector.
907 //
908 // This function applies the \a abs() function to each non-zero element of the input vector
909 // \a sv. The function returns an expression representing this operation.\n
910 // The following example demonstrates the use of the \a abs() function:
911 
912    \code
913    blaze::DynamicVector<double> a, b;
914    // ... Resizing and initialization
915    b = abs( a );
916    \endcode
917 */
918 template< typename VT  // Type of the sparse vector
919         , bool TF >    // Transpose flag
decltype(auto)920 inline decltype(auto) abs( const SparseVector<VT,TF>& sv )
921 {
922    BLAZE_FUNCTION_TRACE;
923 
924    return map( *sv, Abs() );
925 }
926 //*************************************************************************************************
927 
928 
929 //*************************************************************************************************
930 /*!\brief Applies the \a sign() function to each non-zero element of the sparse vector \a sv.
931 // \ingroup sparse_vector
932 //
933 // \param sv The input vector.
934 // \return The resulting sparse vector.
935 //
936 // This function applies the \a sign() function to each non-zero element of the input vector
937 // \a sv. The function returns an expression representing this operation.\n
938 // The following example demonstrates the use of the \a sign() function:
939 
940    \code
941    blaze::DynamicVector<double> a, b;
942    // ... Resizing and initialization
943    b = sign( a );
944    \endcode
945 */
946 template< typename VT  // Type of the sparse vector
947         , bool TF >    // Transpose flag
decltype(auto)948 inline decltype(auto) sign( const SparseVector<VT,TF>& sv )
949 {
950    BLAZE_FUNCTION_TRACE;
951 
952    return map( *sv, Sign() );
953 }
954 //*************************************************************************************************
955 
956 
957 //*************************************************************************************************
958 /*!\brief Applies the \a floor() function to each non-zero element of the sparse vector \a sv.
959 // \ingroup sparse_vector
960 //
961 // \param sv The input vector.
962 // \return The resulting sparse vector.
963 //
964 // This function applies the \a floor() function to each non-zero element of the input vector
965 // \a sv. The function returns an expression representing this operation.\n
966 // The following example demonstrates the use of the \a floor() function:
967 
968    \code
969    blaze::DynamicVector<double> a, b;
970    // ... Resizing and initialization
971    b = floor( a );
972    \endcode
973 */
974 template< typename VT  // Type of the sparse vector
975         , bool TF >    // Transpose flag
decltype(auto)976 inline decltype(auto) floor( const SparseVector<VT,TF>& sv )
977 {
978    BLAZE_FUNCTION_TRACE;
979 
980    return map( *sv, Floor() );
981 }
982 //*************************************************************************************************
983 
984 
985 //*************************************************************************************************
986 /*!\brief Applies the \a ceil() function to each non-zero element of the sparse vector \a sv.
987 // \ingroup sparse_vector
988 //
989 // \param sv The input vector.
990 // \return The resulting sparse vector.
991 //
992 // This function applies the \a ceil() function to each non-zero element of the input vector
993 // \a sv. The function returns an expression representing this operation.\n
994 // The following example demonstrates the use of the \a ceil() function:
995 
996    \code
997    blaze::DynamicVector<double> a, b;
998    // ... Resizing and initialization
999    b = ceil( a );
1000    \endcode
1001 */
1002 template< typename VT  // Type of the sparse vector
1003         , bool TF >    // Transpose flag
decltype(auto)1004 inline decltype(auto) ceil( const SparseVector<VT,TF>& sv )
1005 {
1006    BLAZE_FUNCTION_TRACE;
1007 
1008    return map( *sv, Ceil() );
1009 }
1010 //*************************************************************************************************
1011 
1012 
1013 //*************************************************************************************************
1014 /*!\brief Applies the \a trunc() function to each non-zero element of the sparse vector \a sv.
1015 // \ingroup sparse_vector
1016 //
1017 // \param sv The input vector.
1018 // \return The resulting sparse vector.
1019 //
1020 // This function applies the \a trunc() function to each non-zero element of the input vector
1021 // \a sv. The function returns an expression representing this operation.\n
1022 // The following example demonstrates the use of the \a trunc() function:
1023 
1024    \code
1025    blaze::DynamicVector<double> a, b;
1026    // ... Resizing and initialization
1027    b = trunc( a );
1028    \endcode
1029 */
1030 template< typename VT  // Type of the sparse vector
1031         , bool TF >    // Transpose flag
decltype(auto)1032 inline decltype(auto) trunc( const SparseVector<VT,TF>& sv )
1033 {
1034    BLAZE_FUNCTION_TRACE;
1035 
1036    return map( *sv, Trunc() );
1037 }
1038 //*************************************************************************************************
1039 
1040 
1041 //*************************************************************************************************
1042 /*!\brief Applies the \a round() function to each non-zero element of the sparse vector \a sv.
1043 // \ingroup sparse_vector
1044 //
1045 // \param sv The input vector.
1046 // \return The resulting sparse vector.
1047 //
1048 // This function applies the \a round() function to each non-zero element of the input vector
1049 // \a sv. The function returns an expression representing this operation.\n
1050 // The following example demonstrates the use of the \a round() function:
1051 
1052    \code
1053    blaze::DynamicVector<double> a, b;
1054    // ... Resizing and initialization
1055    b = round( a );
1056    \endcode
1057 */
1058 template< typename VT  // Type of the sparse vector
1059         , bool TF >    // Transpose flag
decltype(auto)1060 inline decltype(auto) round( const SparseVector<VT,TF>& sv )
1061 {
1062    BLAZE_FUNCTION_TRACE;
1063 
1064    return map( *sv, Round() );
1065 }
1066 //*************************************************************************************************
1067 
1068 
1069 //*************************************************************************************************
1070 /*!\brief Returns a vector containing the complex conjugate of each single element of \a sv.
1071 // \ingroup sparse_vector
1072 //
1073 // \param sv The integral sparse input vector.
1074 // \return The complex conjugate of each single element of \a sv.
1075 //
1076 // The \a conj() function calculates the complex conjugate of each element of the sparse input
1077 // vector \a sv. The function returns an expression representing this operation.\n
1078 // The following example demonstrates the use of the \a conj() function:
1079 
1080    \code
1081    blaze::CompressedVector<double> a, b;
1082    // ... Resizing and initialization
1083    b = conj( a );
1084    \endcode
1085 */
1086 template< typename VT  // Type of the sparse vector
1087         , bool TF >    // Transpose flag
decltype(auto)1088 inline decltype(auto) conj( const SparseVector<VT,TF>& sv )
1089 {
1090    BLAZE_FUNCTION_TRACE;
1091 
1092    return map( *sv, Conj() );
1093 }
1094 //*************************************************************************************************
1095 
1096 
1097 //*************************************************************************************************
1098 /*!\brief Returns the conjugate transpose vector of \a sv.
1099 // \ingroup sparse_vector
1100 //
1101 // \param sv The input vector.
1102 // \return The conjugate transpose of \a sv.
1103 //
1104 // The \a ctrans() function returns an expression representing the conjugate transpose (also
1105 // called adjoint matrix, Hermitian conjugate matrix or transjugate matrix) of the given input
1106 // vector \a sv.\n
1107 // The following example demonstrates the use of the \a ctrans() function:
1108 
1109    \code
1110    blaze::CompressedVector< complex<double> > a, b;
1111    // ... Resizing and initialization
1112    b = ctrans( a );
1113    \endcode
1114 
1115 // Note that the \a ctrans() function has the same effect as manually applying the \a conj() and
1116 // \a trans function in any order:
1117 
1118    \code
1119    b = trans( conj( a ) );  // Computing the conjugate transpose vector
1120    b = conj( trans( a ) );  // Computing the conjugate transpose vector
1121    \endcode
1122 */
1123 template< typename VT  // Type of the sparse vector
1124         , bool TF >    // Transpose flag
decltype(auto)1125 inline decltype(auto) ctrans( const SparseVector<VT,TF>& sv )
1126 {
1127    BLAZE_FUNCTION_TRACE;
1128 
1129    return trans( conj( *sv ) );
1130 }
1131 //*************************************************************************************************
1132 
1133 
1134 //*************************************************************************************************
1135 /*!\brief Returns a vector containing the real parts of each single element of \a sv.
1136 // \ingroup sparse_vector
1137 //
1138 // \param sv The integral sparse input vector.
1139 // \return The real part of each single element of \a sv.
1140 //
1141 // The \a real() function calculates the real part of each element of the sparse input vector
1142 // \a sv. The function returns an expression representing this operation.\n
1143 // The following example demonstrates the use of the \a real() function:
1144 
1145    \code
1146    blaze::CompressedVector<double> a, b;
1147    // ... Resizing and initialization
1148    b = real( a );
1149    \endcode
1150 */
1151 template< typename VT  // Type of the sparse vector
1152         , bool TF >    // Transpose flag
decltype(auto)1153 inline decltype(auto) real( const SparseVector<VT,TF>& sv )
1154 {
1155    BLAZE_FUNCTION_TRACE;
1156 
1157    return map( *sv, Real() );
1158 }
1159 //*************************************************************************************************
1160 
1161 
1162 //*************************************************************************************************
1163 /*!\brief Returns a vector containing the imaginary parts of each single element of \a sv.
1164 // \ingroup sparse_vector
1165 //
1166 // \param sv The integral sparse input vector.
1167 // \return The imaginary part of each single element of \a sv.
1168 //
1169 // The \a imag() function calculates the imaginary part of each element of the sparse input vector
1170 // \a sv. The function returns an expression representing this operation.\n
1171 // The following example demonstrates the use of the \a imag() function:
1172 
1173    \code
1174    blaze::CompressedVector<double> a, b;
1175    // ... Resizing and initialization
1176    b = imag( a );
1177    \endcode
1178 */
1179 template< typename VT  // Type of the sparse vector
1180         , bool TF >    // Transpose flag
decltype(auto)1181 inline decltype(auto) imag( const SparseVector<VT,TF>& sv )
1182 {
1183    BLAZE_FUNCTION_TRACE;
1184 
1185    return map( *sv, Imag() );
1186 }
1187 //*************************************************************************************************
1188 
1189 
1190 //*************************************************************************************************
1191 /*!\brief Returns a vector containing the phase angle of each single element of \a sv.
1192 // \ingroup sparse_vector
1193 //
1194 // \param sv The integral sparse input vector.
1195 // \return The phase angle of each single element of \a sv.
1196 //
1197 // The \a arg() function calculates the phase angle of each element of the sparse input vector
1198 // \a sv. The function returns an expression representing this operation.\n
1199 // The following example demonstrates the use of the \a arg() function:
1200 
1201    \code
1202    blaze::CompressedVector<double> a, b;
1203    // ... Resizing and initialization
1204    b = arg( a );
1205    \endcode
1206 */
1207 template< typename VT  // Type of the sparse vector
1208         , bool TF >    // Transpose flag
decltype(auto)1209 inline decltype(auto) arg( const SparseVector<VT,TF>& sv )
1210 {
1211    BLAZE_FUNCTION_TRACE;
1212 
1213    return map( *sv, Arg() );
1214 }
1215 //*************************************************************************************************
1216 
1217 
1218 //*************************************************************************************************
1219 /*!\brief Computes the square root of each non-zero element of the sparse vector \a sv.
1220 // \ingroup sparse_vector
1221 //
1222 // \param sv The input vector; all non-zero elements must be in the range \f$[0..\infty)\f$.
1223 // \return The square root of each single element of \a sv.
1224 //
1225 // The \a sqrt() function computes the square root of each non-zero element of the input vector
1226 // \a sv. The function returns an expression representing this operation.\n
1227 // The following example demonstrates the use of the \a sqrt() function:
1228 
1229    \code
1230    blaze::CompressedVector<double> a, b;
1231    // ... Resizing and initialization
1232    b = sqrt( a );
1233    \endcode
1234 
1235 // \note All non-zero elements are expected to be in the range \f$[0..\infty)\f$. No runtime
1236 // checks are performed to assert this precondition!
1237 */
1238 template< typename VT  // Type of the sparse vector
1239         , bool TF >    // Transpose flag
decltype(auto)1240 inline decltype(auto) sqrt( const SparseVector<VT,TF>& sv )
1241 {
1242    BLAZE_FUNCTION_TRACE;
1243 
1244    return map( *sv, Sqrt() );
1245 }
1246 //*************************************************************************************************
1247 
1248 
1249 //*************************************************************************************************
1250 /*!\brief Computes the inverse square root of each non-zero element of the sparse vector \a sv.
1251 // \ingroup sparse_vector
1252 //
1253 // \param sv The input vector; all non-zero elements must be in the range \f$(0..\infty)\f$.
1254 // \return The inverse square root of each single element of \a sv.
1255 //
1256 // The \a invsqrt() function computes the inverse square root of each non-zero element of the
1257 // input vector \a sv. The function returns an expression representing this operation.\n
1258 // The following example demonstrates the use of the \a invsqrt() function:
1259 
1260    \code
1261    blaze::CompressedVector<double> a, b;
1262    // ... Resizing and initialization
1263    b = invsqrt( a );
1264    \endcode
1265 
1266 // \note All non-zero elements are expected to be in the range \f$(0..\infty)\f$. No runtime
1267 // checks are performed to assert this precondition!
1268 */
1269 template< typename VT  // Type of the sparse vector
1270         , bool TF >    // Transpose flag
decltype(auto)1271 inline decltype(auto) invsqrt( const SparseVector<VT,TF>& sv )
1272 {
1273    BLAZE_FUNCTION_TRACE;
1274 
1275    return map( *sv, InvSqrt() );
1276 }
1277 //*************************************************************************************************
1278 
1279 
1280 //*************************************************************************************************
1281 /*!\brief Computes the cubic root of each non-zero element of the sparse vector \a sv.
1282 // \ingroup sparse_vector
1283 //
1284 // \param sv The input vector; all non-zero elements must be in the range \f$[0..\infty)\f$.
1285 // \return The cubic root of each single element of \a sv.
1286 //
1287 // The \a cbrt() function computes the cubic root of each non-zero element of the input vector
1288 // \a sv. The function returns an expression representing this operation.\n
1289 // The following example demonstrates the use of the \a cbrt() function:
1290 
1291    \code
1292    blaze::CompressedVector<double> a, b;
1293    // ... Resizing and initialization
1294    b = cbrt( a );
1295    \endcode
1296 
1297 // \note All non-zero elements are expected to be in the range \f$[0..\infty)\f$. No runtime
1298 // checks are performed to assert this precondition!
1299 */
1300 template< typename VT  // Type of the sparse vector
1301         , bool TF >    // Transpose flag
decltype(auto)1302 inline decltype(auto) cbrt( const SparseVector<VT,TF>& sv )
1303 {
1304    BLAZE_FUNCTION_TRACE;
1305 
1306    return map( *sv, Cbrt() );
1307 }
1308 //*************************************************************************************************
1309 
1310 
1311 //*************************************************************************************************
1312 /*!\brief Computes the inverse cubic root of each non-zero element of the sparse vector \a sv.
1313 // \ingroup sparse_vector
1314 //
1315 // \param sv The input vector; all non-zero elements must be in the range \f$(0..\infty)\f$.
1316 // \return The inverse cubic root of each single element of \a sv.
1317 //
1318 // The \a invcbrt() function computes the inverse cubic root of each non-zero element of the
1319 // input vector \a sv. The function returns an expression representing this operation.\n
1320 // The following example demonstrates the use of the \a invcbrt() function:
1321 
1322    \code
1323    blaze::CompressedVector<double> a, b;
1324    // ... Resizing and initialization
1325    b = invcbrt( a );
1326    \endcode
1327 
1328 // \note All non-zero elements are expected to be in the range \f$(0..\infty)\f$. No runtime
1329 // checks are performed to assert this precondition!
1330 */
1331 template< typename VT  // Type of the sparse vector
1332         , bool TF >    // Transpose flag
decltype(auto)1333 inline decltype(auto) invcbrt( const SparseVector<VT,TF>& sv )
1334 {
1335    BLAZE_FUNCTION_TRACE;
1336 
1337    return map( *sv, InvCbrt() );
1338 }
1339 //*************************************************************************************************
1340 
1341 
1342 //*************************************************************************************************
1343 /*!\brief Restricts each single element of the sparse vector \a sv to the range \f$[min..max]\f$.
1344 // \ingroup sparse_vector
1345 //
1346 // \param sv The input vector.
1347 // \param min The lower delimiter.
1348 // \param max The upper delimiter.
1349 // \return The vector with restricted elements.
1350 //
1351 // The \a clamp() function resetricts each element of the input vector \a sv to the range
1352 // \f$[min..max]\f$. The function returns an expression representing this operation.\n
1353 // The following example demonstrates the use of the \a clamp() function:
1354 
1355    \code
1356    blaze::CompressedVector<double> a, b;
1357    // ... Resizing and initialization
1358    b = clamp( a, -1.0, 1.0 );
1359    \endcode
1360 */
1361 template< typename VT    // Type of the sparse vector
1362         , bool TF        // Transpose flag
1363         , typename DT >  // Type of the delimiters
decltype(auto)1364 inline decltype(auto) clamp( const SparseVector<VT,TF>& sv, const DT& min, const DT& max )
1365 {
1366    BLAZE_FUNCTION_TRACE;
1367 
1368    return map( *sv, bind2nd( bind3rd( Clamp(), max ), min ) );
1369 }
1370 //*************************************************************************************************
1371 
1372 
1373 //*************************************************************************************************
1374 /*!\brief Computes the exponential value for each non-zero element of the sparse vector \a sv.
1375 // \ingroup sparse_vector
1376 //
1377 // \param sv The input vector.
1378 // \param exp The scalar exponent.
1379 // \return The exponential value of each non-zero element of \a sv.
1380 //
1381 // The \a pow() function computes the exponential value for each non-zero element of the input
1382 // vector \a sv. The function returns an expression representing this operation.\n
1383 // The following example demonstrates the use of the \a pow() function:
1384 
1385    \code
1386    blaze::DynamicVector<double> A, B;
1387    // ... Resizing and initialization
1388    B = pow( A, 4.2 );
1389    \endcode
1390 */
1391 template< typename VT  // Type of the sparse vector
1392         , bool TF      // Transpose flag
1393         , typename ST  // Type of the scalar exponent
1394         , EnableIf_t< IsScalar_v<ST> >* = nullptr >
decltype(auto)1395 inline decltype(auto) pow( const SparseVector<VT,TF>& sv, ST exp )
1396 {
1397    BLAZE_FUNCTION_TRACE;
1398 
1399    using ScalarType = MultTrait_t< UnderlyingBuiltin_t<VT>, ST >;
1400    return map( *sv, blaze::bind2nd( Pow(), ScalarType( exp ) ) );
1401 }
1402 //*************************************************************************************************
1403 
1404 
1405 //*************************************************************************************************
1406 /*!\brief Computes \f$ e^x \f$ of each non-zero element of the sparse vector \a sv.
1407 // \ingroup sparse_vector
1408 //
1409 // \param sv The input vector.
1410 // \return The resulting sparse vector.
1411 //
1412 // The \a exp() function computes \f$ e^x \f$ for each non-zero element of the input vector
1413 // \a sv. The function returns an expression representing this operation.\n
1414 // The following example demonstrates the use of the \a exp() function:
1415 
1416    \code
1417    blaze::CompressedVector<double> a, b;
1418    // ... Resizing and initialization
1419    b = exp( a );
1420    \endcode
1421 */
1422 template< typename VT  // Type of the sparse vector
1423         , bool TF >    // Transpose flag
decltype(auto)1424 inline decltype(auto) exp( const SparseVector<VT,TF>& sv )
1425 {
1426    BLAZE_FUNCTION_TRACE;
1427 
1428    return map( *sv, Exp() );
1429 }
1430 //*************************************************************************************************
1431 
1432 
1433 //*************************************************************************************************
1434 /*!\brief Computes \f$ 2^x \f$ of each non-zero element of the sparse vector \a sv.
1435 // \ingroup sparse_vector
1436 //
1437 // \param sv The input vector.
1438 // \return The resulting sparse vector.
1439 //
1440 // The \a exp2() function computes \f$ 2^x \f$ for each non-zero element of the input vector
1441 // \a sv. The function returns an expression representing this operation.\n
1442 // The following example demonstrates the use of the \a exp2() function:
1443 
1444    \code
1445    blaze::CompressedVector<double> a, b;
1446    // ... Resizing and initialization
1447    b = exp2( a );
1448    \endcode
1449 */
1450 template< typename VT  // Type of the sparse vector
1451         , bool TF >    // Transpose flag
decltype(auto)1452 inline decltype(auto) exp2( const SparseVector<VT,TF>& sv )
1453 {
1454    BLAZE_FUNCTION_TRACE;
1455 
1456    return map( *sv, Exp2() );
1457 }
1458 //*************************************************************************************************
1459 
1460 
1461 //*************************************************************************************************
1462 /*!\brief Computes \f$ 10^x \f$ of each non-zero element of the sparse vector \a sv.
1463 // \ingroup sparse_vector
1464 //
1465 // \param sv The input vector.
1466 // \return The resulting sparse vector.
1467 //
1468 // The \a exp10() function computes \f$ 10^x \f$ for each non-zero element of the input vector
1469 // \a sv. The function returns an expression representing this operation.\n
1470 // The following example demonstrates the use of the \a exp10() function:
1471 
1472    \code
1473    blaze::CompressedVector<double> a, b;
1474    // ... Resizing and initialization
1475    b = exp10( a );
1476    \endcode
1477 */
1478 template< typename VT  // Type of the sparse vector
1479         , bool TF >    // Transpose flag
decltype(auto)1480 inline decltype(auto) exp10( const SparseVector<VT,TF>& sv )
1481 {
1482    BLAZE_FUNCTION_TRACE;
1483 
1484    return map( *sv, Exp10() );
1485 }
1486 //*************************************************************************************************
1487 
1488 
1489 //*************************************************************************************************
1490 /*!\brief Computes the natural logarithm of each non-zero element of the sparse vector \a sv.
1491 // \ingroup sparse_vector
1492 //
1493 // \param sv The input vector; all non-zero elements must be in the range \f$[0..\infty)\f$.
1494 // \return The natural logaritm of each non-zero element of \a sv.
1495 //
1496 // The \a log() function computes the natural logarithm for each non-zero element of the input
1497 // vector \a sv. The function returns an expression representing this operation.\n
1498 // The following example demonstrates the use of the \a log() function:
1499 
1500    \code
1501    blaze::CompressedVector<double> a, b;
1502    // ... Resizing and initialization
1503    b = log( a );
1504    \endcode
1505 
1506 // \note All non-zero elements are expected to be in the range \f$[0..\infty)\f$. No runtime
1507 // checks are performed to assert this precondition!
1508 */
1509 template< typename VT  // Type of the sparse vector
1510         , bool TF >    // Transpose flag
decltype(auto)1511 inline decltype(auto) log( const SparseVector<VT,TF>& sv )
1512 {
1513    BLAZE_FUNCTION_TRACE;
1514 
1515    return map( *sv, Log() );
1516 }
1517 //*************************************************************************************************
1518 
1519 
1520 //*************************************************************************************************
1521 /*!\brief Computes the binary logarithm of each non-zero element of the sparse vector \a sv.
1522 // \ingroup sparse_vector
1523 //
1524 // \param sv The input vector; all non-zero elements must be in the range \f$[0..\infty)\f$.
1525 // \return The binary logaritm of each non-zero element of \a sv.
1526 //
1527 // The \a log2() function computes the binary logarithm for each non-zero element of the input
1528 // vector \a sv. The function returns an expression representing this operation.\n
1529 // The following example demonstrates the use of the \a log2() function:
1530 
1531    \code
1532    blaze::CompressedVector<double> a, b;
1533    // ... Resizing and initialization
1534    b = log2( a );
1535    \endcode
1536 
1537 // \note All non-zero elements are expected to be in the range \f$[0..\infty)\f$. No runtime
1538 // checks are performed to assert this precondition!
1539 */
1540 template< typename VT  // Type of the sparse vector
1541         , bool TF >    // Transpose flag
decltype(auto)1542 inline decltype(auto) log2( const SparseVector<VT,TF>& sv )
1543 {
1544    BLAZE_FUNCTION_TRACE;
1545 
1546    return map( *sv, Log2() );
1547 }
1548 //*************************************************************************************************
1549 
1550 
1551 //*************************************************************************************************
1552 /*!\brief Computes the common logarithm of each non-zero element of the sparse vector \a sv.
1553 // \ingroup sparse_vector
1554 //
1555 // \param sv The input vector; all non-zero elements must be in the range \f$[0..\infty)\f$.
1556 // \return The common logaritm of each non-zero element of \a sv.
1557 //
1558 // The \a log10() function computes the common logarithm for each non-zero element of the input
1559 // vector \a sv. The function returns an expression representing this operation.\n
1560 // The following example demonstrates the use of the \a log10() function:
1561 
1562    \code
1563    blaze::CompressedVector<double> a, b;
1564    // ... Resizing and initialization
1565    b = log10( a );
1566    \endcode
1567 
1568 // \note All non-zero elements are expected to be in the range \f$[0..\infty)\f$. No runtime
1569 // checks are performed to assert this precondition!
1570 */
1571 template< typename VT  // Type of the sparse vector
1572         , bool TF >    // Transpose flag
decltype(auto)1573 inline decltype(auto) log10( const SparseVector<VT,TF>& sv )
1574 {
1575    BLAZE_FUNCTION_TRACE;
1576 
1577    return map( *sv, Log10() );
1578 }
1579 //*************************************************************************************************
1580 
1581 
1582 //*************************************************************************************************
1583 /*!\brief Computes the natural logarithm of x+1 of each non-zero element of the sparse vector \a sv.
1584 // \ingroup sparse_vector
1585 //
1586 // \param sv The input vector; all non-zero elements must be in the range \f$[-1..\infty)\f$.
1587 // \return The natural logarithm of x+1 of each non-zero element of \a sv.
1588 //
1589 // The \a log1p() function computes the natural logarithm of x+1 for each non-zero element of
1590 // the input vector \a sv. This may be preferred over the natural logarithm for higher precision
1591 // computing the natural logarithm of a quantity very close to 1. The function returns an
1592 // expression representing this operation.\n
1593 // The following example demonstrates the use of the \a log1p() function:
1594 
1595    \code
1596    blaze::CompressedVector<double> a, b;
1597    // ... Resizing and initialization
1598    b = log1p( a );
1599    \endcode
1600 
1601 // \note All non-zero elements are expected to be in the range \f$[-1..\infty)\f$. No runtime
1602 // checks are performed to assert this precondition!
1603 */
1604 template< typename VT  // Type of the sparse vector
1605         , bool TF >    // Transpose flag
decltype(auto)1606 inline decltype(auto) log1p( const SparseVector<VT,TF>& sv )
1607 {
1608    BLAZE_FUNCTION_TRACE;
1609 
1610    return map( *sv, Log1p() );
1611 }
1612 //*************************************************************************************************
1613 
1614 
1615 //*************************************************************************************************
1616 /*!\brief Computes the natural logarithm of the absolute value of the gamma function of each
1617 //        non-zero element of the sparse vector \a sv.
1618 // \ingroup sparse_vector
1619 //
1620 // \param sv The input vector; all non-zero elements must be in the range \f$[0..\infty)\f$.
1621 // \return The natural logarithm of the absolute value of the gamma function of each non-zero element of \a sv.
1622 //
1623 // The \a lgamma() function computes the natural logarithm of the absolute value of the gamma
1624 // function for each non-zero element. The function returns an expression representing this
1625 // operation.\n
1626 // The following example demonstrates the use of the \a lgamma() function:
1627 
1628    \code
1629    blaze::CompressedVector<double> a, b;
1630    // ... Resizing and initialization
1631    b = lgamma( a );
1632    \endcode
1633 
1634 // \note All non-zero elements are expected to be in the range \f$[0..\infty)\f$. No runtime
1635 // checks are performed to assert this precondition!
1636 */
1637 template< typename VT  // Type of the sparse vector
1638         , bool TF >    // Transpose flag
decltype(auto)1639 inline decltype(auto) lgamma( const SparseVector<VT,TF>& sv )
1640 {
1641    BLAZE_FUNCTION_TRACE;
1642 
1643    return map( *sv, LGamma() );
1644 }
1645 //*************************************************************************************************
1646 
1647 
1648 //*************************************************************************************************
1649 /*!\brief Computes the sine of each non-zero element of the sparse vector \a sv.
1650 // \ingroup sparse_vector
1651 //
1652 // \param sv The input vector.
1653 // \return The sine of each non-zero element of \a sv.
1654 //
1655 // The \a sin() function computes the sine for each non-zero element of the input vector \a sv.
1656 // The function returns an expression representing this operation.\n
1657 // The following example demonstrates the use of the \a sin() function:
1658 
1659    \code
1660    blaze::CompressedVector<double> a, b;
1661    // ... Resizing and initialization
1662    b = sin( a );
1663    \endcode
1664 */
1665 template< typename VT  // Type of the sparse vector
1666         , bool TF >    // Transpose flag
decltype(auto)1667 inline decltype(auto) sin( const SparseVector<VT,TF>& sv )
1668 {
1669    BLAZE_FUNCTION_TRACE;
1670 
1671    return map( *sv, Sin() );
1672 }
1673 //*************************************************************************************************
1674 
1675 
1676 //*************************************************************************************************
1677 /*!\brief Computes the inverse sine of each non-zero element of the sparse vector \a sv.
1678 // \ingroup sparse_vector
1679 //
1680 // \param sv The input vector; all non-zero elements must be in the range \f$[-1..1]\f$.
1681 // \return The inverse sine of each non-zero element of \a sv.
1682 //
1683 // The \a asin() function computes the inverse sine for each non-zero element of the input vector
1684 // \a sv. The function returns an expression representing this operation.\n
1685 // The following example demonstrates the use of the \a asin() function:
1686 
1687    \code
1688    blaze::CompressedVector<double> a, b;
1689    // ... Resizing and initialization
1690    b = asin( a );
1691    \endcode
1692 
1693 // \note All non-zero elements are expected to be in the range \f$[-1..1]\f$. No runtime checks
1694 // are performed to assert this precondition!
1695 */
1696 template< typename VT  // Type of the sparse vector
1697         , bool TF >    // Transpose flag
decltype(auto)1698 inline decltype(auto) asin( const SparseVector<VT,TF>& sv )
1699 {
1700    BLAZE_FUNCTION_TRACE;
1701 
1702    return map( *sv, Asin() );
1703 }
1704 //*************************************************************************************************
1705 
1706 
1707 //*************************************************************************************************
1708 /*!\brief Computes the hyperbolic sine of each non-zero element of the sparse vector \a sv.
1709 // \ingroup sparse_vector
1710 //
1711 // \param sv The input vector.
1712 // \return The hyperbolic sine of each non-zero element of \a sv.
1713 //
1714 // The \a sinh() function computes the hyperbolic sine for each non-zero element of the input
1715 // vector \a sv. The function returns an expression representing this operation.\n
1716 // The following example demonstrates the use of the \a sinh() function:
1717 
1718    \code
1719    blaze::CompressedVector<double> a, b;
1720    // ... Resizing and initialization
1721    b = sinh( a );
1722    \endcode
1723 */
1724 template< typename VT  // Type of the sparse vector
1725         , bool TF >    // Transpose flag
decltype(auto)1726 inline decltype(auto) sinh( const SparseVector<VT,TF>& sv )
1727 {
1728    BLAZE_FUNCTION_TRACE;
1729 
1730    return map( *sv, Sinh() );
1731 }
1732 //*************************************************************************************************
1733 
1734 
1735 //*************************************************************************************************
1736 /*!\brief Computes the inverse hyperbolic sine of each non-zero element of the sparse vector \a sv.
1737 // \ingroup sparse_vector
1738 //
1739 // \param sv The input vector.
1740 // \return The inverse hyperbolic sine of each non-zero element of \a sv.
1741 //
1742 // The \a asinh() function computes the inverse hyperbolic sine for each non-zero element of the
1743 // input vector \a sv. The function returns an expression representing this operation.\n
1744 // The following example demonstrates the use of the \a asinh() function:
1745 
1746    \code
1747    blaze::CompressedVector<double> a, b;
1748    // ... Resizing and initialization
1749    b = asinh( a );
1750    \endcode
1751 */
1752 template< typename VT  // Type of the sparse vector
1753         , bool TF >    // Transpose flag
decltype(auto)1754 inline decltype(auto) asinh( const SparseVector<VT,TF>& sv )
1755 {
1756    BLAZE_FUNCTION_TRACE;
1757 
1758    return map( *sv, Asinh() );
1759 }
1760 //*************************************************************************************************
1761 
1762 
1763 //*************************************************************************************************
1764 /*!\brief Computes the cosine of each non-zero element of the sparse vector \a sv.
1765 // \ingroup sparse_vector
1766 //
1767 // \param sv The input vector.
1768 // \return The cosine of each non-zero element of \a sv.
1769 //
1770 // The \a cos() function computes the cosine for each non-zero element of the input vector \a sv.
1771 // The function returns an expression representing this operation.\n
1772 // The following example demonstrates the use of the \a cos() function:
1773 
1774    \code
1775    blaze::CompressedVector<double> a, b;
1776    // ... Resizing and initialization
1777    b = cos( a );
1778    \endcode
1779 */
1780 template< typename VT  // Type of the sparse vector
1781         , bool TF >    // Transpose flag
decltype(auto)1782 inline decltype(auto) cos( const SparseVector<VT,TF>& sv )
1783 {
1784    BLAZE_FUNCTION_TRACE;
1785 
1786    return map( *sv, Cos() );
1787 }
1788 //*************************************************************************************************
1789 
1790 
1791 //*************************************************************************************************
1792 /*!\brief Computes the inverse cosine of each non-zero element of the sparse vector \a sv.
1793 // \ingroup sparse_vector
1794 //
1795 // \param sv The input vector; all non-zero elements must be in the range \f$[-1..1]\f$.
1796 // \return The inverse cosine of each non-zero element of \a sv.
1797 //
1798 // The \a acos() function computes the inverse cosine for each non-zero element of the input vector
1799 // \a sv. The function returns an expression representing this operation.\n
1800 // The following example demonstrates the use of the \a acos() function:
1801 
1802    \code
1803    blaze::CompressedVector<double> a, b;
1804    // ... Resizing and initialization
1805    b = acos( a );
1806    \endcode
1807 
1808 // \note All non-zero elements are expected to be in the range \f$[-1..1]\f$. No runtime checks
1809 // are performed to assert this precondition!
1810 */
1811 template< typename VT  // Type of the sparse vector
1812         , bool TF >    // Transpose flag
decltype(auto)1813 inline decltype(auto) acos( const SparseVector<VT,TF>& sv )
1814 {
1815    BLAZE_FUNCTION_TRACE;
1816 
1817    return map( *sv, Acos() );
1818 }
1819 //*************************************************************************************************
1820 
1821 
1822 //*************************************************************************************************
1823 /*!\brief Computes the hyperbolic cosine of each non-zero element of the sparse vector \a sv.
1824 // \ingroup sparse_vector
1825 //
1826 // \param sv The input vector.
1827 // \return The hyperbolic cosine of each non-zero element of \a sv.
1828 //
1829 // The \a cosh() function computes the hyperbolic cosine for each non-zero element of the input
1830 // vector \a sv. The function returns an expression representing this operation.\n
1831 // The following example demonstrates the use of the \a cosh() function:
1832 
1833    \code
1834    blaze::CompressedVector<double> a, b;
1835    // ... Resizing and initialization
1836    b = cosh( a );
1837    \endcode
1838 */
1839 template< typename VT  // Type of the sparse vector
1840         , bool TF >    // Transpose flag
decltype(auto)1841 inline decltype(auto) cosh( const SparseVector<VT,TF>& sv )
1842 {
1843    BLAZE_FUNCTION_TRACE;
1844 
1845    return map( *sv, Cosh() );
1846 }
1847 //*************************************************************************************************
1848 
1849 
1850 //*************************************************************************************************
1851 /*!\brief Computes the inverse hyperbolic cosine of each non-zero element of the sparse vector \a sv.
1852 // \ingroup sparse_vector
1853 //
1854 // \param sv The input vector; all non-zero elements must be in the range \f$[1..\infty)\f$.
1855 // \return The inverse hyperbolic cosine of each non-zero element of \a sv.
1856 //
1857 // The \a acosh() function computes the inverse hyperbolic cosine for each non-zero element of
1858 // the input vector \a sv. The function returns an expression representing this operation.\n
1859 // The following example demonstrates the use of the \a acosh() function:
1860 
1861    \code
1862    blaze::CompressedVector<double> a, b;
1863    // ... Resizing and initialization
1864    b = acosh( a );
1865    \endcode
1866 
1867 // \note All non-zero elements are expected to be in the range \f$[1..\infty)\f$. No runtime
1868 // checks are performed to assert this precondition!
1869 */
1870 template< typename VT  // Type of the sparse vector
1871         , bool TF >    // Transpose flag
decltype(auto)1872 inline decltype(auto) acosh( const SparseVector<VT,TF>& sv )
1873 {
1874    BLAZE_FUNCTION_TRACE;
1875 
1876    return map( *sv, Acosh() );
1877 }
1878 //*************************************************************************************************
1879 
1880 
1881 //*************************************************************************************************
1882 /*!\brief Computes the tangent of each non-zero element of the sparse vector \a sv.
1883 // \ingroup sparse_vector
1884 //
1885 // \param sv The input vector.
1886 // \return The tangent of each non-zero element of \a sv.
1887 //
1888 // The \a tan() function computes the tangent for each non-zero element of the input vector \a sv.
1889 // The function returns an expression representing this operation.\n
1890 // The following example demonstrates the use of the \a tan() function:
1891 
1892    \code
1893    blaze::CompressedVector<double> a, b;
1894    // ... Resizing and initialization
1895    b = tan( a );
1896    \endcode
1897 */
1898 template< typename VT  // Type of the sparse vector
1899         , bool TF >    // Transpose flag
decltype(auto)1900 inline decltype(auto) tan( const SparseVector<VT,TF>& sv )
1901 {
1902    BLAZE_FUNCTION_TRACE;
1903 
1904    return map( *sv, Tan() );
1905 }
1906 //*************************************************************************************************
1907 
1908 
1909 //*************************************************************************************************
1910 /*!\brief Computes the inverse tangent of each non-zero element of the sparse vector \a sv.
1911 // \ingroup sparse_vector
1912 //
1913 // \param sv The input vector.
1914 // \return The inverse tangent of each non-zero element of \a sv.
1915 //
1916 // The \a atan() function computes the inverse tangent for each non-zero element of the input
1917 // vector \a sv. The function returns an expression representing this operation.\n
1918 // The following example demonstrates the use of the \a atan() function:
1919 
1920    \code
1921    blaze::CompressedVector<double> a, b;
1922    // ... Resizing and initialization
1923    b = atan( a );
1924    \endcode
1925 */
1926 template< typename VT  // Type of the sparse vector
1927         , bool TF >    // Transpose flag
decltype(auto)1928 inline decltype(auto) atan( const SparseVector<VT,TF>& sv )
1929 {
1930    BLAZE_FUNCTION_TRACE;
1931 
1932    return map( *sv, Atan() );
1933 }
1934 //*************************************************************************************************
1935 
1936 
1937 //*************************************************************************************************
1938 /*!\brief Computes the hyperbolic tangent of each non-zero element of the sparse vector \a sv.
1939 // \ingroup sparse_vector
1940 //
1941 // \param sv The input vector; all non-zero elements must be in the range \f$[-1..1]\f$.
1942 // \return The hyperbolic tangent of each non-zero element of \a sv.
1943 //
1944 // The \a tanh() function computes the hyperbolic tangent for each non-zero element of the input
1945 // vector \a sv. The function returns an expression representing this operation.\n
1946 // The following example demonstrates the use of the \a tanh() function:
1947 
1948    \code
1949    blaze::CompressedVector<double> a, b;
1950    // ... Resizing and initialization
1951    b = tanh( a );
1952    \endcode
1953 
1954 // \note All non-zero elements are expected to be in the range \f$[-1..1]\f$. No runtime checks
1955 // are performed to assert this precondition!
1956 */
1957 template< typename VT  // Type of the sparse vector
1958         , bool TF >    // Transpose flag
decltype(auto)1959 inline decltype(auto) tanh( const SparseVector<VT,TF>& sv )
1960 {
1961    BLAZE_FUNCTION_TRACE;
1962 
1963    return map( *sv, Tanh() );
1964 }
1965 //*************************************************************************************************
1966 
1967 
1968 //*************************************************************************************************
1969 /*!\brief Computes the inverse hyperbolic tangent of each non-zero element of the sparse vector \a sv.
1970 // \ingroup sparse_vector
1971 //
1972 // \param sv The input vector; all non-zero elements must be in the range \f$[-1..1]\f$.
1973 // \return The inverse hyperbolic tangent of each non-zero element of \a sv.
1974 //
1975 // The \a atanh() function computes the inverse hyperbolic tangent for each non-zero element of
1976 // the input vector \a sv. The function returns an expression representing this operation.\n
1977 // The following example demonstrates the use of the \a atanh() function:
1978 
1979    \code
1980    blaze::CompressedVector<double> a, b;
1981    // ... Resizing and initialization
1982    b = atanh( a );
1983    \endcode
1984 
1985 // \note All non-zero elements are expected to be in the range \f$[-1..1]\f$. No runtime checks
1986 // are performed to assert this precondition!
1987 */
1988 template< typename VT  // Type of the sparse vector
1989         , bool TF >    // Transpose flag
decltype(auto)1990 inline decltype(auto) atanh( const SparseVector<VT,TF>& sv )
1991 {
1992    BLAZE_FUNCTION_TRACE;
1993 
1994    return map( *sv, Atanh() );
1995 }
1996 //*************************************************************************************************
1997 
1998 
1999 //*************************************************************************************************
2000 /*!\brief Computes the error function of each non-zero element of the sparse vector \a sv.
2001 // \ingroup sparse_vector
2002 //
2003 // \param sv The input vector.
2004 // \return The error function of each non-zero element of \a sv.
2005 //
2006 // The \a erf() function computes the error function for each non-zero element of the input
2007 // vector \a sv. The function returns an expression representing this operation.\n
2008 // The following example demonstrates the use of the \a erf() function:
2009 
2010    \code
2011    blaze::CompressedVector<double> a, b;
2012    // ... Resizing and initialization
2013    b = erf( a );
2014    \endcode
2015 */
2016 template< typename VT  // Type of the sparse vector
2017         , bool TF >    // Transpose flag
decltype(auto)2018 inline decltype(auto) erf( const SparseVector<VT,TF>& sv )
2019 {
2020    BLAZE_FUNCTION_TRACE;
2021 
2022    return map( *sv, Erf() );
2023 }
2024 //*************************************************************************************************
2025 
2026 
2027 //*************************************************************************************************
2028 /*!\brief Computes the complementary error function of each non-zero element of the sparse vector \a sv.
2029 // \ingroup sparse_vector
2030 //
2031 // \param sv The input vector.
2032 // \return The complementary error function of each non-zero element of \a sv.
2033 //
2034 // The \a erfc() function computes the complementary error function for each non-zero element of
2035 // the input vector \a sv. The function returns an expression representing this operation.\n
2036 // The following example demonstrates the use of the \a erfc() function:
2037 
2038    \code
2039    blaze::CompressedVector<double> a, b;
2040    // ... Resizing and initialization
2041    b = erfc( a );
2042    \endcode
2043 */
2044 template< typename VT  // Type of the sparse vector
2045         , bool TF >    // Transpose flag
decltype(auto)2046 inline decltype(auto) erfc( const SparseVector<VT,TF>& sv )
2047 {
2048    BLAZE_FUNCTION_TRACE;
2049 
2050    return map( *sv, Erfc() );
2051 }
2052 //*************************************************************************************************
2053 
2054 
2055 
2056 
2057 //=================================================================================================
2058 //
2059 //  GLOBAL RESTRUCTURING FUNCTIONS
2060 //
2061 //=================================================================================================
2062 
2063 //*************************************************************************************************
2064 /*! \cond BLAZE_INTERNAL */
2065 /*!\brief Absolute value function for absolute value sparse vector expressions.
2066 // \ingroup sparse_vector
2067 //
2068 // \param sv The absolute value sparse vector expression.
2069 // \return The absolute value of each single element of \a sv.
2070 //
2071 // This function implements a performance optimized treatment of the absolute value operation
2072 // on a sparse vector absolute value expression.
2073 */
2074 template< typename VT  // Type of the sparse vector
2075         , bool TF >    // Transpose flag
decltype(auto)2076 inline decltype(auto) abs( const SVecMapExpr<VT,Abs,TF>& sv )
2077 {
2078    BLAZE_FUNCTION_TRACE;
2079 
2080    return sv;
2081 }
2082 /*! \endcond */
2083 //*************************************************************************************************
2084 
2085 
2086 //*************************************************************************************************
2087 /*! \cond BLAZE_INTERNAL */
2088 /*!\brief Applies the \a sign() function to a sparse vector \a sign() expressions.
2089 // \ingroup sparse_vector
2090 //
2091 // \param sv The sparse vector \a sign() expression.
2092 // \return The resulting sparse vector.
2093 //
2094 // This function implements a performance optimized treatment of the \a sign() operation on
2095 // a sparse vector \a sign() expression.
2096 */
2097 template< typename VT  // Type of the sparse vector
2098         , bool TF >    // Transpose flag
decltype(auto)2099 inline decltype(auto) sign( const SVecMapExpr<VT,Sign,TF>& sv )
2100 {
2101    BLAZE_FUNCTION_TRACE;
2102 
2103    return sv;
2104 }
2105 /*! \endcond */
2106 //*************************************************************************************************
2107 
2108 
2109 //*************************************************************************************************
2110 /*! \cond BLAZE_INTERNAL */
2111 /*!\brief Applies the \a floor() function to a sparse vector \a floor() expressions.
2112 // \ingroup sparse_vector
2113 //
2114 // \param sv The sparse vector \a floor() expression.
2115 // \return The resulting sparse vector.
2116 //
2117 // This function implements a performance optimized treatment of the \a floor() operation on
2118 // a sparse vector \a floor() expression.
2119 */
2120 template< typename VT  // Type of the sparse vector
2121         , bool TF >    // Transpose flag
decltype(auto)2122 inline decltype(auto) floor( const SVecMapExpr<VT,Floor,TF>& sv )
2123 {
2124    BLAZE_FUNCTION_TRACE;
2125 
2126    return sv;
2127 }
2128 /*! \endcond */
2129 //*************************************************************************************************
2130 
2131 
2132 //*************************************************************************************************
2133 /*! \cond BLAZE_INTERNAL */
2134 /*!\brief Applies the \a ceil() function to a sparse vector \a ceil() expressions.
2135 // \ingroup sparse_vector
2136 //
2137 // \param sv The sparse vector \a ceil() expression.
2138 // \return The resulting sparse vector.
2139 //
2140 // This function implements a performance optimized treatment of the \a ceil() operation on
2141 // a sparse vector \a ceil() expression.
2142 */
2143 template< typename VT  // Type of the sparse vector
2144         , bool TF >    // Transpose flag
decltype(auto)2145 inline decltype(auto) ceil( const SVecMapExpr<VT,Ceil,TF>& sv )
2146 {
2147    BLAZE_FUNCTION_TRACE;
2148 
2149    return sv;
2150 }
2151 /*! \endcond */
2152 //*************************************************************************************************
2153 
2154 
2155 //*************************************************************************************************
2156 /*! \cond BLAZE_INTERNAL */
2157 /*!\brief Applies the \a trunc() function to a sparse vector \a trunc() expressions.
2158 // \ingroup sparse_vector
2159 //
2160 // \param sv The sparse vector \a trunc() expression.
2161 // \return The resulting sparse vector.
2162 //
2163 // This function implements a performance optimized treatment of the \a trunc() operation on
2164 // a sparse vector \a trunc() expression.
2165 */
2166 template< typename VT  // Type of the sparse vector
2167         , bool TF >    // Transpose flag
decltype(auto)2168 inline decltype(auto) trunc( const SVecMapExpr<VT,Trunc,TF>& sv )
2169 {
2170    BLAZE_FUNCTION_TRACE;
2171 
2172    return sv;
2173 }
2174 /*! \endcond */
2175 //*************************************************************************************************
2176 
2177 
2178 //*************************************************************************************************
2179 /*! \cond BLAZE_INTERNAL */
2180 /*!\brief Applies the \a round() function to a sparse vector \a round() expressions.
2181 // \ingroup sparse_vector
2182 //
2183 // \param sv The sparse vector \a round() expression.
2184 // \return The resulting sparse vector.
2185 //
2186 // This function implements a performance optimized treatment of the \a round() operation on
2187 // a sparse vector \a round() expression.
2188 */
2189 template< typename VT  // Type of the sparse vector
2190         , bool TF >    // Transpose flag
decltype(auto)2191 inline decltype(auto) round( const SVecMapExpr<VT,Round,TF>& sv )
2192 {
2193    BLAZE_FUNCTION_TRACE;
2194 
2195    return sv;
2196 }
2197 /*! \endcond */
2198 //*************************************************************************************************
2199 
2200 
2201 //*************************************************************************************************
2202 /*! \cond BLAZE_INTERNAL */
2203 /*!\brief Complex conjugate function for complex conjugate sparse vector expressions.
2204 // \ingroup sparse_vector
2205 //
2206 // \param sv The complex conjugate sparse vector expression.
2207 // \return The original sparse vector.
2208 //
2209 // This function implements a performance optimized treatment of the complex conjugate operation
2210 // on a sparse vector complex conjugate expression. It returns an expression representing the
2211 // original sparse vector:
2212 
2213    \code
2214    blaze::CompressedVector< complex<double> > a, b;
2215    // ... Resizing and initialization
2216    b = conj( conj( a ) );
2217    \endcode
2218 */
2219 template< typename VT  // Type of the sparse vector
2220         , bool TF >    // Transpose flag
decltype(auto)2221 inline decltype(auto) conj( const SVecMapExpr<VT,Conj,TF>& sv )
2222 {
2223    BLAZE_FUNCTION_TRACE;
2224 
2225    return sv.operand();
2226 }
2227 /*! \endcond */
2228 //*************************************************************************************************
2229 
2230 
2231 //*************************************************************************************************
2232 /*! \cond BLAZE_INTERNAL */
2233 /*!\brief Complex conjugate function for conjugate transpose sparse vector expressions.
2234 // \ingroup sparse_vector
2235 //
2236 // \param sv The conjugate transpose sparse vector expression.
2237 // \return The transpose sparse vector.
2238 //
2239 // This function implements a performance optimized treatment of the complex conjugate operation
2240 // on a sparse vector conjugate transpose expression. It returns an expression representing the
2241 // transpose of the sparse vector:
2242 
2243    \code
2244    blaze::CompressedVector< complex<double> > a, b;
2245    // ... Resizing and initialization
2246    b = conj( ctrans( a ) );
2247    \endcode
2248 */
2249 template< typename VT  // Type of the sparse vector
2250         , bool TF >    // Transpose flag
decltype(auto)2251 inline decltype(auto) conj( const SVecTransExpr<SVecMapExpr<VT,Conj,TF>,!TF>& sv )
2252 {
2253    BLAZE_FUNCTION_TRACE;
2254 
2255    return trans( sv.operand().operand() );
2256 }
2257 /*! \endcond */
2258 //*************************************************************************************************
2259 
2260 
2261 //*************************************************************************************************
2262 /*! \cond BLAZE_INTERNAL */
2263 /*!\brief Real part function for real part sparse vector expressions.
2264 // \ingroup sparse_vector
2265 //
2266 // \param sv The real part sparse vector expression.
2267 // \return The real part of each single element of \a sv.
2268 //
2269 // This function implements a performance optimized treatment of the real part operation on
2270 // a sparse vector real part expression.
2271 */
2272 template< typename VT  // Type of the sparse vector
2273         , bool TF >    // Transpose flag
decltype(auto)2274 inline decltype(auto) real( const SVecMapExpr<VT,Real,TF>& sv )
2275 {
2276    BLAZE_FUNCTION_TRACE;
2277 
2278    return sv;
2279 }
2280 /*! \endcond */
2281 //*************************************************************************************************
2282 
2283 } // namespace blaze
2284 
2285 #endif
2286