1 //=================================================================================================
2 /*!
3 //  \file blaze/math/proxy/SparseMatrixProxy.h
4 //  \brief Header file for the SparseMatrixProxy class
5 //
6 //  Copyright (C) 2012-2020 Klaus Iglberger - All Rights Reserved
7 //
8 //  This file is part of the Blaze library. You can redistribute it and/or modify it under
9 //  the terms of the New (Revised) BSD License. Redistribution and use in source and binary
10 //  forms, with or without modification, are permitted provided that the following conditions
11 //  are met:
12 //
13 //  1. Redistributions of source code must retain the above copyright notice, this list of
14 //     conditions and the following disclaimer.
15 //  2. Redistributions in binary form must reproduce the above copyright notice, this list
16 //     of conditions and the following disclaimer in the documentation and/or other materials
17 //     provided with the distribution.
18 //  3. Neither the names of the Blaze development group nor the names of its contributors
19 //     may be used to endorse or promote products derived from this software without specific
20 //     prior written permission.
21 //
22 //  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
23 //  EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
24 //  OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
25 //  SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26 //  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
27 //  TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28 //  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 //  CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
30 //  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
31 //  DAMAGE.
32 */
33 //=================================================================================================
34 
35 #ifndef _BLAZE_MATH_PROXY_SPARSEMATRIXPROXY_H_
36 #define _BLAZE_MATH_PROXY_SPARSEMATRIXPROXY_H_
37 
38 
39 //*************************************************************************************************
40 // Includes
41 //*************************************************************************************************
42 
43 #include <blaze/math/Aliases.h>
44 #include <blaze/math/constraints/SparseMatrix.h>
45 #include <blaze/math/Exception.h>
46 #include <blaze/math/expressions/SparseMatrix.h>
47 #include <blaze/math/shims/Clear.h>
48 #include <blaze/math/shims/Reset.h>
49 #include <blaze/math/typetraits/IsSquare.h>
50 #include <blaze/math/typetraits/IsColumnMajorMatrix.h>
51 #include <blaze/system/Inline.h>
52 #include <blaze/util/EnableIf.h>
53 #include <blaze/util/Types.h>
54 
55 
56 namespace blaze {
57 
58 //=================================================================================================
59 //
60 //  CLASS DEFINITION
61 //
62 //=================================================================================================
63 
64 //*************************************************************************************************
65 /*!\brief Proxy backend for sparse matrix types.
66 // \ingroup math
67 //
68 // The SparseMatrixProxy class serves as a backend for the Proxy class. It is used in case the
69 // data type represented by the proxy is a sparse matrix and augments the Proxy interface by
70 // the complete interface required of sparse matrices.
71 */
72 template< typename PT    // Type of the proxy
73         , typename MT >  // Type of the sparse matrix
74 class SparseMatrixProxy
75    : public SparseMatrix< PT, IsColumnMajorMatrix_v<MT> >
76 {
77  public:
78    //**Type definitions****************************************************************************
79    using ResultType     = ResultType_t<MT>;      //!< Result type for expression template evaluations.
80    using OppositeType   = OppositeType_t<MT>;    //!< Result type with opposite storage order for expression template evaluations.
81    using TransposeType  = TransposeType_t<MT>;   //!< Transpose type for expression template evaluations.
82    using ElementType    = ElementType_t<MT>;     //!< Type of the sparse matrix elements.
83    using ReturnType     = ReturnType_t<MT>;      //!< Return type for expression template evaluations.
84    using CompositeType  = CompositeType_t<MT>;   //!< Data type for composite expression templates.
85    using Reference      = Reference_t<MT>;       //!< Reference to a non-constant matrix value.
86    using ConstReference = ConstReference_t<MT>;  //!< Reference to a constant matrix value.
87    using Iterator       = Iterator_t<MT>;        //!< Iterator over non-constant elements.
88    using ConstIterator  = ConstIterator_t<MT>;   //!< Iterator over constant elements.
89    //**********************************************************************************************
90 
91    //**Compilation flags***************************************************************************
92    //! Compilation flag for SMP assignments.
93    static constexpr bool smpAssignable = MT::smpAssignable;
94    //**********************************************************************************************
95 
96    //**Data access functions***********************************************************************
97    /*!\name Data access functions */
98    //@{
99    inline Reference operator()( size_t i, size_t j ) const;
100    inline Reference at( size_t i, size_t j ) const;
101 
102    inline Iterator      begin ( size_t i ) const;
103    inline ConstIterator cbegin( size_t i ) const;
104    inline Iterator      end   ( size_t i ) const;
105    inline ConstIterator cend  ( size_t i ) const;
106    //@}
107    //**********************************************************************************************
108 
109    //**Utility functions***************************************************************************
110    /*!\name Utility functions */
111    //@{
112    inline size_t rows() const;
113    inline size_t columns() const;
114    inline size_t capacity() const;
115    inline size_t capacity( size_t i ) const;
116    inline size_t nonZeros() const;
117    inline size_t nonZeros( size_t i ) const;
118    inline void   reset() const;
119    inline void   reset( size_t i ) const;
120    inline void   clear() const;
121    inline void   finalize( size_t i ) const;
122    inline void   resize( size_t m, size_t n, bool preserve=true ) const;
123    inline void   reserve( size_t n ) const;
124    inline void   reserve( size_t i, size_t n ) const;
125    inline void   trim() const;
126    inline void   trim( size_t i ) const;
127    //@}
128    //**********************************************************************************************
129 
130    //**Insertion functions*************************************************************************
131    /*!\name Insertion functions */
132    //@{
133    inline Iterator set   ( size_t i, size_t j, const ElementType& value ) const;
134    inline Iterator insert( size_t i, size_t j, const ElementType& value ) const;
135    inline void     append( size_t i, size_t j, const ElementType& value, bool check=false ) const;
136    //@}
137    //**********************************************************************************************
138 
139    //**Erase functions*****************************************************************************
140    /*!\name Erase functions */
141    //@{
142    inline void     erase( size_t i, size_t j ) const;
143    inline Iterator erase( size_t i, Iterator pos ) const;
144    inline Iterator erase( size_t i, Iterator first, Iterator last ) const;
145 
146    template< typename Pred >
147    inline void erase( Pred predicate );
148 
149    template< typename Pred >
150    inline void erase( size_t i, Iterator first, Iterator last, Pred predicate );
151    //@}
152    //**********************************************************************************************
153 
154    //**Lookup functions****************************************************************************
155    /*!\name Lookup functions */
156    //@{
157    inline Iterator find      ( size_t i, size_t j ) const;
158    inline Iterator lowerBound( size_t i, size_t j ) const;
159    inline Iterator upperBound( size_t i, size_t j ) const;
160    //@}
161    //**********************************************************************************************
162 
163    //**Numeric functions***************************************************************************
164    /*!\name Numeric functions */
165    //@{
166    inline void transpose() const;
167    inline void ctranspose() const;
168 
169    template< typename Other > inline void scale( const Other& scalar ) const;
170    //@}
171    //**********************************************************************************************
172 
173  protected:
174    //**Special member functions********************************************************************
175    /*!\name Special member functions */
176    //@{
177    SparseMatrixProxy() = default;
178    SparseMatrixProxy( const SparseMatrixProxy& ) = default;
179    SparseMatrixProxy( SparseMatrixProxy&& ) = default;
180    ~SparseMatrixProxy() = default;
181    SparseMatrixProxy& operator=( const SparseMatrixProxy& ) = default;
182    SparseMatrixProxy& operator=( SparseMatrixProxy&& ) = default;
183    //@}
184    //**********************************************************************************************
185 
186  private:
187    //**Compile time checks*************************************************************************
188    /*! \cond BLAZE_INTERNAL */
189    BLAZE_CONSTRAINT_MUST_BE_SPARSE_MATRIX_TYPE( MT );
190    /*! \endcond */
191    //**********************************************************************************************
192 };
193 //*************************************************************************************************
194 
195 
196 
197 
198 //=================================================================================================
199 //
200 //  DATA ACCESS FUNCTIONS
201 //
202 //=================================================================================================
203 
204 //*************************************************************************************************
205 /*!\brief Function call operator for the direct access to matrix elements.
206 //
207 // \param i Access index for the row. The index has to be in the range \f$[0..M-1]\f$.
208 // \param j Access index for the column. The index has to be in the range \f$[0..N-1]\f$.
209 // \return Reference to the accessed value.
210 // \exception std::invalid_argument Invalid access to restricted element.
211 //
212 // This function returns a reference to the accessed value at position (\a i,\a j). In case
213 // the sparse matrix does not yet store an element at position (\a i,\a j) , a new element is
214 // inserted into the sparse matrix. Note that this function only performs an index check in
215 // case BLAZE_USER_ASSERT() is active. In contrast, the at() function is guaranteed to perform
216 // a check of the given access indices.
217 */
218 template< typename PT    // Type of the proxy
219         , typename MT >  // Type of the sparse matrix
220 inline typename SparseMatrixProxy<PT,MT>::Reference
operator()221    SparseMatrixProxy<PT,MT>::operator()( size_t i, size_t j ) const
222 {
223    if( (**this).isRestricted() ) {
224       BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to restricted element" );
225    }
226 
227    return (**this).get()(i,j);
228 }
229 //*************************************************************************************************
230 
231 
232 //*************************************************************************************************
233 /*!\brief Checked access to the matrix elements.
234 //
235 // \param i Access index for the row. The index has to be in the range \f$[0..M-1]\f$.
236 // \param j Access index for the column. The index has to be in the range \f$[0..N-1]\f$.
237 // \return Reference to the accessed value.
238 // \exception std::invalid_argument Invalid access to restricted element.
239 // \exception std::out_of_range Invalid matrix access index.
240 //
241 // This function returns a reference to the accessed value at position (\a i,\a j). In case
242 // the sparse matrix does not yet store an element at position (\a i,\a j) , a new element is
243 // inserted into the sparse matrix. In contrast to the subscript operator this function always
244 // performs a check of the given access indices.
245 */
246 template< typename PT    // Type of the proxy
247         , typename MT >  // Type of the sparse matrix
248 inline typename SparseMatrixProxy<PT,MT>::Reference
at(size_t i,size_t j)249    SparseMatrixProxy<PT,MT>::at( size_t i, size_t j ) const
250 {
251    if( (**this).isRestricted() ) {
252       BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to restricted element" );
253    }
254 
255    return (**this).get().at(i,j);
256 }
257 //*************************************************************************************************
258 
259 
260 //*************************************************************************************************
261 /*!\brief Returns an iterator to the first element of row/column \a i of the represented matrix.
262 //
263 // \param i The row/column index.
264 // \return Iterator to the first element of row/column \a i.
265 //
266 // This function returns a row/column iterator to the first non-zero element of row/column \a i.
267 // In case the storage order is set to \a rowMajor the function returns an iterator to the first
268 // non-zero element of row \a i, in case the storage flag is set to \a columnMajor the function
269 // returns an iterator to the first non-zero element of column \a i.
270 */
271 template< typename PT    // Type of the proxy
272         , typename MT >  // Type of the sparse matrix
273 inline typename SparseMatrixProxy<PT,MT>::Iterator
begin(size_t i)274    SparseMatrixProxy<PT,MT>::begin( size_t i ) const
275 {
276    return (**this).get().begin(i);
277 }
278 //*************************************************************************************************
279 
280 
281 //*************************************************************************************************
282 /*!\brief Returns an iterator to the first element of row/column \a i of the represented matrix.
283 //
284 // \param i The row/column index.
285 // \return Iterator to the first element of row/column \a i.
286 //
287 // This function returns a row/column iterator to the first non-zero element of row/column \a i.
288 // In case the storage order is set to \a rowMajor the function returns an iterator to the first
289 // non-zero element of row \a i, in case the storage flag is set to \a columnMajor the function
290 // returns an iterator to the first non-zero element of column \a i.
291 */
292 template< typename PT    // Type of the proxy
293         , typename MT >  // Type of the sparse matrix
294 inline typename SparseMatrixProxy<PT,MT>::ConstIterator
cbegin(size_t i)295    SparseMatrixProxy<PT,MT>::cbegin( size_t i ) const
296 {
297    return (**this).get().cbegin(i);
298 }
299 //*************************************************************************************************
300 
301 
302 //*************************************************************************************************
303 /*!\brief Returns an iterator just past the last element of row/column \a i of the represented matrix.
304 //
305 // \param i The row/column index.
306 // \return Iterator just past the last element of row/column \a i.
307 //
308 // This function returns an row/column iterator just past the last non-zero element of row/column
309 // \a i. In case the storage order is set to \a rowMajor the function returns an iterator just
310 // past the last non-zero element of row \a i, in case the storage flag is set to \a columnMajor
311 // the function returns an iterator just past the last non-zero element of column \a i.
312 */
313 template< typename PT    // Type of the proxy
314         , typename MT >  // Type of the sparse matrix
315 inline typename SparseMatrixProxy<PT,MT>::Iterator
end(size_t i)316    SparseMatrixProxy<PT,MT>::end( size_t i ) const
317 {
318    return (**this).get().end(i);
319 }
320 //*************************************************************************************************
321 
322 
323 //*************************************************************************************************
324 /*!\brief Returns an iterator just past the last element of row/column \a i of the represented matrix.
325 //
326 // \param i The row/column index.
327 // \return Iterator just past the last element of row/column \a i.
328 //
329 // This function returns an row/column iterator just past the last non-zero element of row/column
330 // \a i. In case the storage order is set to \a rowMajor the function returns an iterator just
331 // past the last non-zero element of row \a i, in case the storage flag is set to \a columnMajor
332 // the function returns an iterator just past the last non-zero element of column \a i.
333 */
334 template< typename PT    // Type of the proxy
335         , typename MT >  // Type of the sparse matrix
336 inline typename SparseMatrixProxy<PT,MT>::ConstIterator
cend(size_t i)337    SparseMatrixProxy<PT,MT>::cend( size_t i ) const
338 {
339    return (**this).get().cend(i);
340 }
341 //*************************************************************************************************
342 
343 
344 
345 
346 //=================================================================================================
347 //
348 //  UTILITY FUNCTIONS
349 //
350 //=================================================================================================
351 
352 //*************************************************************************************************
353 /*!\brief Returns the current number of rows of the represented matrix.
354 //
355 // \return The number of rows of the matrix.
356 */
357 template< typename PT    // Type of the proxy
358         , typename MT >  // Type of the sparse matrix
rows()359 inline size_t SparseMatrixProxy<PT,MT>::rows() const
360 {
361    return (**this).get().rows();
362 }
363 //*************************************************************************************************
364 
365 
366 //*************************************************************************************************
367 /*!\brief Returns the current number of columns of the represented matrix.
368 //
369 // \return The number of columns of the matrix.
370 */
371 template< typename PT    // Type of the proxy
372         , typename MT >  // Type of the sparse matrix
columns()373 inline size_t SparseMatrixProxy<PT,MT>::columns() const
374 {
375    return (**this).get().columns();
376 }
377 //*************************************************************************************************
378 
379 
380 //*************************************************************************************************
381 /*!\brief Returns the maximum capacity of the represented matrix.
382 //
383 // \return The capacity of the matrix.
384 */
385 template< typename PT    // Type of the proxy
386         , typename MT >  // Type of the sparse matrix
capacity()387 inline size_t SparseMatrixProxy<PT,MT>::capacity() const
388 {
389    return (**this).get().capacity();
390 }
391 //*************************************************************************************************
392 
393 
394 //*************************************************************************************************
395 /*!\brief Returns the current capacity of the specified row/column of the represented matrix.
396 //
397 // \param i The index of the row/column.
398 // \return The current capacity of row/column \a i.
399 //
400 // This function returns the current capacity of the specified row/column. In case the
401 // storage order is set to \a rowMajor the function returns the capacity of row \a i,
402 // in case the storage flag is set to \a columnMajor the function returns the capacity
403 // of column \a i.
404 */
405 template< typename PT    // Type of the proxy
406         , typename MT >  // Type of the sparse matrix
capacity(size_t i)407 inline size_t SparseMatrixProxy<PT,MT>::capacity( size_t i ) const
408 {
409    return (**this).get().capacity(i);
410 }
411 //*************************************************************************************************
412 
413 
414 //*************************************************************************************************
415 /*!\brief Returns the number of non-zero elements in the represented matrix.
416 //
417 // \return The number of non-zero elements in the matrix.
418 */
419 template< typename PT    // Type of the proxy
420         , typename MT >  // Type of the sparse matrix
nonZeros()421 inline size_t SparseMatrixProxy<PT,MT>::nonZeros() const
422 {
423    return (**this).get().nonZeros();
424 }
425 //*************************************************************************************************
426 
427 
428 //*************************************************************************************************
429 /*!\brief Returns the number of non-zero elements in the specified row/column of the represented matrix.
430 //
431 // \param i The index of the row/column.
432 // \return The number of non-zero elements of row/column \a i.
433 //
434 // This function returns the current number of non-zero elements in the specified row/column.
435 // In case the storage order is set to \a rowMajor the function returns the number of non-zero
436 // elements in row \a i, in case the storage flag is set to \a columnMajor the function returns
437 // the number of non-zero elements in column \a i.
438 */
439 template< typename PT    // Type of the proxy
440         , typename MT >  // Type of the sparse matrix
nonZeros(size_t i)441 inline size_t SparseMatrixProxy<PT,MT>::nonZeros( size_t i ) const
442 {
443    return (**this).get().nonZeros(i);
444 }
445 //*************************************************************************************************
446 
447 
448 //*************************************************************************************************
449 /*!\brief Reset to the default initial value.
450 //
451 // \return void
452 //
453 // This function resets all elements of the matrix to the default initial values.
454 */
455 template< typename PT    // Type of the proxy
456         , typename MT >  // Type of the sparse matrix
reset()457 inline void SparseMatrixProxy<PT,MT>::reset() const
458 {
459    using blaze::reset;
460 
461    reset( (**this).get() );
462 }
463 //*************************************************************************************************
464 
465 
466 //*************************************************************************************************
467 /*!\brief Reset the specified row/column to the default initial values.
468 //
469 // \param i The index of the row/column.
470 // \return void
471 //
472 // This function resets the values in the specified row/column to their default value. In case
473 // the storage order is set to \a rowMajor the function resets the values in row \a i, in case
474 // the storage order is set to \a columnMajor the function resets the values in column \a i.
475 // Note that the capacity of the row/column remains unchanged.
476 */
477 template< typename PT    // Type of the proxy
478         , typename MT >  // Type of the sparse matrix
reset(size_t i)479 inline void SparseMatrixProxy<PT,MT>::reset( size_t i ) const
480 {
481    using blaze::reset;
482 
483    reset( (**this).get(), i );
484 }
485 //*************************************************************************************************
486 
487 
488 //*************************************************************************************************
489 /*!\brief Clearing the represented vector.
490 //
491 // \return void
492 //
493 // This function clears the matrix to its default initial state.
494 */
495 template< typename PT    // Type of the proxy
496         , typename MT >  // Type of the sparse matrix
clear()497 inline void SparseMatrixProxy<PT,MT>::clear() const
498 {
499    using blaze::clear;
500 
501    clear( (**this).get() );
502 }
503 //*************************************************************************************************
504 
505 
506 //*************************************************************************************************
507 /*!\brief Setting an element of the represented sparse matrix.
508 //
509 // \param i The row index of the new element. The index has to be in the range \f$[0..M-1]\f$.
510 // \param j The column index of the new element. The index has to be in the range \f$[0..N-1]\f$.
511 // \param value The value of the element to be set.
512 // \return Iterator to the set element.
513 // \exception std::invalid_argument Invalid access to restricted element.
514 // \exception std::invalid_argument Invalid sparse matrix access index.
515 //
516 // This function sets the value of an element of the sparse matrix. In case the sparse matrix
517 // already contains an element with row index \a i and column index \a j its value is modified,
518 // else a new element with the given \a value is inserted.
519 */
520 template< typename PT    // Type of the proxy
521         , typename MT >  // Type of the sparse matrix
522 inline typename SparseMatrixProxy<PT,MT>::Iterator
set(size_t i,size_t j,const ElementType & value)523    SparseMatrixProxy<PT,MT>::set( size_t i, size_t j, const ElementType& value ) const
524 {
525    if( (**this).isRestricted() ) {
526       BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to restricted element" );
527    }
528 
529    return (**this).get().set( i, j, value );
530 }
531 //*************************************************************************************************
532 
533 
534 //*************************************************************************************************
535 /*!\brief Inserting an element into the represented sparse matrix.
536 //
537 // \param i The row index of the new element. The index has to be in the range \f$[0..M-1]\f$.
538 // \param j The column index of the new element. The index has to be in the range \f$[0..N-1]\f$.
539 // \param value The value of the element to be inserted.
540 // \return Iterator to the newly inserted element.
541 // \exception std::invalid_argument Invalid access to restricted element.
542 // \exception std::invalid_argument Invalid sparse matrix access index.
543 //
544 // This function inserts a new element into the sparse matrix. However, duplicate elements are
545 // not allowed. In case the sparse matrix already contains an element with row index \a i and
546 // column index \a j, a \a std::invalid_argument exception is thrown.
547 */
548 template< typename PT    // Type of the proxy
549         , typename MT >  // Type of the sparse matrix
550 inline typename SparseMatrixProxy<PT,MT>::Iterator
insert(size_t i,size_t j,const ElementType & value)551    SparseMatrixProxy<PT,MT>::insert( size_t i, size_t j, const ElementType& value ) const
552 {
553    if( (**this).isRestricted() ) {
554       BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to restricted element" );
555    }
556 
557    return (**this).get().insert( i, j, value );
558 }
559 //*************************************************************************************************
560 
561 
562 //*************************************************************************************************
563 /*!\brief Appending an element to the specified row/column of the sparse matrix.
564 //
565 // \param i The row index of the new element. The index has to be in the range \f$[0..M-1]\f$.
566 // \param j The column index of the new element. The index has to be in the range \f$[0..N-1]\f$.
567 // \param value The value of the element to be appended.
568 // \param check \a true if the new value should be checked for default values, \a false if not.
569 // \return void
570 // \exception std::invalid_argument Invalid access to restricted element.
571 //
572 // This function provides a very efficient way to fill a sparse matrix with elements. It appends
573 // a new element to the end of the specified row/column without any additional memory allocation.
574 // Therefore it is strictly necessary to keep the following preconditions in mind:
575 //
576 //  - the index of the new element must be strictly larger than the largest index of non-zero
577 //    elements in the specified row/column of the sparse matrix
578 //  - the current number of non-zero elements in the matrix must be smaller than the capacity
579 //    of the matrix
580 //
581 // Ignoring these preconditions might result in undefined behavior! The optional \a check
582 // parameter specifies whether the new value should be tested for a default value. If the new
583 // value is a default value (for instance 0 in case of an integral element type) the value is
584 // not appended. Per default the values are not tested.
585 //
586 // \note Although append() does not allocate new memory, it still invalidates all iterators
587 // returned by the end() functions!
588 */
589 template< typename PT    // Type of the proxy
590         , typename MT >  // Type of the sparse matrix
append(size_t i,size_t j,const ElementType & value,bool check)591 inline void SparseMatrixProxy<PT,MT>::append( size_t i, size_t j, const ElementType& value, bool check ) const
592 {
593    if( (**this).isRestricted() ) {
594       BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to restricted element" );
595    }
596 
597    (**this).get().append( i, j, value, check );
598 }
599 //*************************************************************************************************
600 
601 
602 //*************************************************************************************************
603 /*!\brief Finalizing the element insertion of a row/column.
604 //
605 // \param i The index of the row/column to be finalized \f$[0..M-1]\f$.
606 // \return void
607 // \exception std::invalid_argument Invalid access to restricted element.
608 //
609 // This function is part of the low-level interface to efficiently fill a matrix with elements.
610 // After completion of row/column \a i via the append() function, this function can be called to
611 // finalize row/column \a i and prepare the next row/column for insertion process via append().
612 //
613 // \note Although finalize() does not allocate new memory, it still invalidates all iterators
614 // returned by the end() functions!
615 */
616 template< typename PT    // Type of the proxy
617         , typename MT >  // Type of the sparse matrix
finalize(size_t i)618 inline void SparseMatrixProxy<PT,MT>::finalize( size_t i ) const
619 {
620    if( (**this).isRestricted() ) {
621       BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to restricted element" );
622    }
623 
624    (**this).get().finalize( i );
625 }
626 //*************************************************************************************************
627 
628 
629 //*************************************************************************************************
630 /*!\brief Changing the size of the represented matrix.
631 //
632 // \param m The new number of rows of the matrix.
633 // \param n The new number of columns of the matrix.
634 // \param preserve \a true if the old values of the matrix should be preserved, \a false if not.
635 // \return void
636 // \exception std::invalid_argument Invalid access to restricted element.
637 //
638 // This function resizes the matrix using the given size to \f$ m \times n \f$. Depending on
639 // the type of the matrix, during this operation new dynamic memory may be allocated in case
640 // the capacity of the matrix is too small. Note that this function may invalidate all existing
641 // views (submatrices, rows, columns, ...) on the matrix if it is used to shrink the matrix.
642 // Additionally, the resize operation potentially changes all matrix elements. In order to
643 // preserve the old matrix values, the \a preserve flag can be set to \a true.
644 */
645 template< typename PT    // Type of the proxy
646         , typename MT >  // Type of the sparse matrix
resize(size_t m,size_t n,bool preserve)647 inline void SparseMatrixProxy<PT,MT>::resize( size_t m, size_t n, bool preserve ) const
648 {
649    if( (**this).isRestricted() ) {
650       BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to restricted element" );
651    }
652 
653    (**this).get().resize( m, n, preserve );
654 }
655 //*************************************************************************************************
656 
657 
658 //*************************************************************************************************
659 /*!\brief Setting the minimum capacity of the represented matrix.
660 //
661 // \param n The new minimum capacity of the matrix.
662 // \return void
663 // \exception std::invalid_argument Invalid access to restricted element.
664 //
665 // This function increases the capacity of the sparse matrix to at least \a nonzeros elements.
666 // The current values of the matrix elements and the individual capacities of the matrix rows
667 // are preserved.
668 */
669 template< typename PT    // Type of the proxy
670         , typename MT >  // Type of the sparse matrix
reserve(size_t n)671 inline void SparseMatrixProxy<PT,MT>::reserve( size_t n ) const
672 {
673    if( (**this).isRestricted() ) {
674       BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to restricted element" );
675    }
676 
677    (**this).get().reserve( n );
678 }
679 //*************************************************************************************************
680 
681 
682 //*************************************************************************************************
683 /*!\brief Setting the minimum capacity of a specific row/column of the sparse matrix.
684 //
685 // \param i The row/column index of the new element \f$[0..M-1]\f$ or \f$[0..N-1]\f$.
686 // \param n The new minimum capacity of the specified row/column.
687 // \return void
688 // \exception std::invalid_argument Invalid access to restricted element.
689 //
690 // This function increases the capacity of row/column \a i of the sparse matrix to at least
691 // \a nonzeros elements. The current values of the sparse matrix and all other individual
692 // row/column capacities are preserved. In case the storage order is set to \a rowMajor, the
693 // function reserves capacity for row \a i and the index has to be in the range \f$[0..M-1]\f$.
694 // In case the storage order is set to \a columnMajor, the function reserves capacity for column
695 // \a i and the index has to be in the range \f$[0..N-1]\f$.
696 */
697 template< typename PT    // Type of the proxy
698         , typename MT >  // Type of the sparse matrix
reserve(size_t i,size_t n)699 inline void SparseMatrixProxy<PT,MT>::reserve( size_t i, size_t n ) const
700 {
701    if( (**this).isRestricted() ) {
702       BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to restricted element" );
703    }
704 
705    (**this).get().reserve( i, n );
706 }
707 //*************************************************************************************************
708 
709 
710 //*************************************************************************************************
711 /*!\brief Removing all excessive capacity from all rows/columns.
712 //
713 // \return void
714 // \exception std::invalid_argument Invalid access to restricted element.
715 //
716 // The trim() function can be used to reverse the effect of all row/column-specific reserve()
717 // calls. The function removes all excessive capacity from all rows (in case of a rowMajor
718 // matrix) or columns (in case of a columnMajor matrix). Note that this function does not
719 // remove the overall capacity but only reduces the capacity per row/column.
720 */
721 template< typename PT    // Type of the proxy
722         , typename MT >  // Type of the sparse matrix
trim()723 inline void SparseMatrixProxy<PT,MT>::trim() const
724 {
725    if( (**this).isRestricted() ) {
726       BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to restricted element" );
727    }
728 
729    (**this).get().trim();
730 }
731 //*************************************************************************************************
732 
733 
734 //*************************************************************************************************
735 /*!\brief Removing all excessive capacity of a specific row/column of the sparse matrix.
736 //
737 // \param i The index of the row/column to be trimmed (\f$[0..M-1]\f$ or \f$[0..N-1]\f$).
738 // \return void
739 // \exception std::invalid_argument Invalid access to restricted element.
740 //
741 // This function can be used to reverse the effect of a row/column-specific reserve() call.
742 // It removes all excessive capacity from the specified row (in case of a rowMajor matrix)
743 // or column (in case of a columnMajor matrix). The excessive capacity is assigned to the
744 // subsequent row/column.
745 */
746 template< typename PT    // Type of the proxy
747         , typename MT >  // Type of the sparse matrix
trim(size_t i)748 inline void SparseMatrixProxy<PT,MT>::trim( size_t i ) const
749 {
750    if( (**this).isRestricted() ) {
751       BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to restricted element" );
752    }
753 
754    (**this).get().trim( i );
755 }
756 //*************************************************************************************************
757 
758 
759 //*************************************************************************************************
760 /*!\brief In-place transpose of the represented matrix.
761 //
762 // \return Reference to the transposed matrix.
763 // \exception std::invalid_argument Invalid access to restricted element.
764 */
765 template< typename PT    // Type of the proxy
766         , typename MT >  // Type of the sparse matrix
transpose()767 inline void SparseMatrixProxy<PT,MT>::transpose() const
768 {
769    if( (**this).isRestricted() ) {
770       BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to restricted element" );
771    }
772 
773    (**this).get().transpose();
774 }
775 //*************************************************************************************************
776 
777 
778 //*************************************************************************************************
779 /*!\brief In-place conjugate transpose of the represented matrix.
780 //
781 // \return Reference to the transposed matrix.
782 // \exception std::invalid_argument Invalid access to restricted element.
783 */
784 template< typename PT    // Type of the proxy
785         , typename MT >  // Type of the sparse matrix
ctranspose()786 inline void SparseMatrixProxy<PT,MT>::ctranspose() const
787 {
788    if( (**this).isRestricted() ) {
789       BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to restricted element" );
790    }
791 
792    (**this).get().ctranspose();
793 }
794 //*************************************************************************************************
795 
796 
797 //*************************************************************************************************
798 /*!\brief Scaling of the sparse matrix by the scalar value \a scalar (\f$ A=B*s \f$).
799 //
800 // \param scalar The scalar value for the matrix scaling.
801 // \return void
802 // \exception std::invalid_argument Invalid access to restricted element.
803 //
804 // This function scales the matrix by applying the given scalar value \a scalar to each element
805 // of the matrix. For built-in and \c complex data types it has the same effect as using the
806 // multiplication assignment operator.
807 */
808 template< typename PT       // Type of the proxy
809         , typename MT >     // Type of the sparse matrix
810 template< typename Other >  // Data type of the scalar value
scale(const Other & scalar)811 inline void SparseMatrixProxy<PT,MT>::scale( const Other& scalar ) const
812 {
813    if( (**this).isRestricted() ) {
814       BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to restricted element" );
815    }
816 
817    (**this).get().scale( scalar );
818 }
819 //*************************************************************************************************
820 
821 
822 
823 
824 //=================================================================================================
825 //
826 //  ERASE FUNCTIONS
827 //
828 //=================================================================================================
829 
830 //*************************************************************************************************
831 /*!\brief Erasing an element from the sparse matrix.
832 //
833 // \param i The row index of the element to be erased. The index has to be in the range \f$[0..M-1]\f$.
834 // \param j The column index of the element to be erased. The index has to be in the range \f$[0..N-1]\f$.
835 // \return void
836 // \exception std::invalid_argument Invalid access to restricted element.
837 //
838 // This function erases an element from the sparse matrix.
839 */
840 template< typename PT    // Type of the proxy
841         , typename MT >  // Type of the sparse matrix
erase(size_t i,size_t j)842 inline void SparseMatrixProxy<PT,MT>::erase( size_t i, size_t j ) const
843 {
844    if( (**this).isRestricted() ) {
845       BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to restricted element" );
846    }
847 
848    (**this).get().erase( i, j );
849 }
850 //*************************************************************************************************
851 
852 
853 //*************************************************************************************************
854 /*!\brief Erasing an element from the sparse matrix.
855 //
856 // \param i The row/column index of the element to be erased. The index has to be in the range \f$[0..M-1]\f$.
857 // \param pos Iterator to the element to be erased.
858 // \return Iterator to the element after the erased element.
859 // \exception std::invalid_argument Invalid access to restricted element.
860 //
861 // This function erases an element from the sparse matrix. In case the storage order is set to
862 // \a rowMajor the function erases an element from row \a i, in case the storage flag is set to
863 // \a columnMajor the function erases an element from column \a i.
864 */
865 template< typename PT    // Type of the proxy
866         , typename MT >  // Type of the sparse matrix
867 inline typename SparseMatrixProxy<PT,MT>::Iterator
erase(size_t i,Iterator pos)868    SparseMatrixProxy<PT,MT>::erase( size_t i, Iterator pos ) const
869 {
870    if( (**this).isRestricted() ) {
871       BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to restricted element" );
872    }
873 
874    return (**this).get().erase( i, pos );
875 }
876 //*************************************************************************************************
877 
878 
879 //*************************************************************************************************
880 /*!\brief Erasing a range of elements from the sparse matrix.
881 //
882 // \param i The row/column index of the element to be erased. The index has to be in the range \f$[0..M-1]\f$.
883 // \param first Iterator to first element to be erased.
884 // \param last Iterator just past the last element to be erased.
885 // \return Iterator to the element after the erased element.
886 // \exception std::invalid_argument Invalid access to restricted element.
887 //
888 // This function erases a range of elements from the sparse matrix. In case the storage order is
889 // set to \a rowMajor the function erases a range of elements from row \a i, in case the storage
890 // flag is set to \a columnMajor the function erases a range of elements from column \a i.
891 */
892 template< typename PT    // Type of the proxy
893         , typename MT >  // Type of the sparse matrix
894 inline typename SparseMatrixProxy<PT,MT>::Iterator
erase(size_t i,Iterator first,Iterator last)895    SparseMatrixProxy<PT,MT>::erase( size_t i, Iterator first, Iterator last ) const
896 {
897    if( (**this).isRestricted() ) {
898       BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to restricted element" );
899    }
900 
901    return (**this).get().erase( i, first, last );
902 }
903 //*************************************************************************************************
904 
905 
906 //*************************************************************************************************
907 /*!\brief Erasing specific elements from the sparse matrix.
908 //
909 // \param predicate The unary predicate for the element selection.
910 // \return void.
911 //
912 // This function erases specific elements from the sparse matrix. The elements are selected
913 // by the given unary predicate \a predicate, which is expected to accept a single argument of
914 // the type of the elements and to be pure.
915 //
916 // \note The predicate is required to be pure, i.e. to produce deterministic results for elements
917 // with the same value. The attempt to use an impure predicate leads to undefined behavior!
918 */
919 template< typename PT      // Type of the proxy
920         , typename MT >    // Type of the sparse matrix
921 template< typename Pred >  // Type of the unary predicate
erase(Pred predicate)922 inline void SparseMatrixProxy<PT,MT>::erase( Pred predicate )
923 {
924    if( (**this).isRestricted() ) {
925       BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to restricted element" );
926    }
927 
928    (**this).get().erase( predicate );
929 }
930 //*************************************************************************************************
931 
932 
933 //*************************************************************************************************
934 /*!\brief Erasing specific elements from a range of the sparse matrix.
935 //
936 // \param i The row/column index of the elements to be erased. The index has to be in the range \f$[0..M-1]\f$.
937 // \param first Iterator to first element of the range.
938 // \param last Iterator just past the last element of the range.
939 // \param predicate The unary predicate for the element selection.
940 // \return void
941 //
942 // This function erases specific elements from a range of elements of the sparse matrix. The
943 // elements are selected by the given unary predicate \a predicate, which is expected to accept
944 // a single argument of the type of the elements and to be pure. In case the storage order is
945 // set to \a rowMajor the function erases a range of elements from row \a i, in case the storage
946 // flag is set to \a columnMajor the function erases a range of elements from column \a i.
947 //
948 // \note The predicate is required to be pure, i.e. to produce deterministic results for elements
949 // with the same value. The attempt to use an impure predicate leads to undefined behavior!
950 */
951 template< typename PT      // Type of the proxy
952         , typename MT >    // Type of the sparse matrix
953 template< typename Pred >  // Type of the unary predicate
erase(size_t i,Iterator first,Iterator last,Pred predicate)954 inline void SparseMatrixProxy<PT,MT>::erase( size_t i, Iterator first, Iterator last, Pred predicate )
955 {
956    if( (**this).isRestricted() ) {
957       BLAZE_THROW_INVALID_ARGUMENT( "Invalid access to restricted element" );
958    }
959 
960    (**this).get().erase( i, first, last, predicate );
961 }
962 //*************************************************************************************************
963 
964 
965 
966 
967 //=================================================================================================
968 //
969 //  LOOKUP FUNCTIONS
970 //
971 //=================================================================================================
972 
973 //*************************************************************************************************
974 /*!\brief Searches for a specific matrix element.
975 //
976 // \param i The row index of the search element. The index has to be in the range \f$[0..M-1]\f$.
977 // \param j The column index of the search element. The index has to be in the range \f$[0..N-1]\f$.
978 // \return Iterator to the element in case the index is found, end() iterator otherwise.
979 //
980 // This function can be used to check whether a specific element is contained in the sparse
981 // matrix. It specifically searches for the element with row index \a i and column index \a j.
982 // In case the element is found, the function returns an row/column iterator to the element.
983 // Otherwise an iterator just past the last non-zero element of row \a i or column \a j (the
984 // end() iterator) is returned. Note that the returned sparse matrix iterator is subject to
985 // invalidation due to inserting operations via the function call operator, the set() function
986 // or the insert() function!
987 */
988 template< typename PT    // Type of the proxy
989         , typename MT >  // Type of the sparse matrix
990 inline typename SparseMatrixProxy<PT,MT>::Iterator
find(size_t i,size_t j)991    SparseMatrixProxy<PT,MT>::find( size_t i, size_t j ) const
992 {
993    return (**this).get().find( i, j );
994 }
995 //*************************************************************************************************
996 
997 
998 //*************************************************************************************************
999 /*!\brief Returns an iterator to the first index not less then the given index.
1000 //
1001 // \param i The row index of the search element. The index has to be in the range \f$[0..M-1]\f$.
1002 // \param j The column index of the search element. The index has to be in the range \f$[0..N-1]\f$.
1003 // \return Iterator to the first index not less then the given index, end() iterator otherwise.
1004 //
1005 // In case of a row-major matrix, this function returns a row iterator to the first element with
1006 // an index not less then the given column index. In case of a column-major matrix, the function
1007 // returns a column iterator to the first element with an index not less then the given row
1008 // index. In combination with the upperBound() function this function can be used to create a
1009 // pair of iterators specifying a range of indices. Note that the returned sparse matrix iterator
1010 // is subject to invalidation due to inserting operations via the function call operator, the
1011 // set() function or the insert() function!
1012 */
1013 template< typename PT    // Type of the proxy
1014         , typename MT >  // Type of the sparse matrix
1015 inline typename SparseMatrixProxy<PT,MT>::Iterator
lowerBound(size_t i,size_t j)1016    SparseMatrixProxy<PT,MT>::lowerBound( size_t i, size_t j ) const
1017 {
1018    return (**this).get().lowerBound( i, j );
1019 }
1020 //*************************************************************************************************
1021 
1022 
1023 //*************************************************************************************************
1024 /*!\brief Returns an iterator to the first index greater then the given index.
1025 //
1026 // \param i The row index of the search element. The index has to be in the range \f$[0..M-1]\f$.
1027 // \param j The column index of the search element. The index has to be in the range \f$[0..N-1]\f$.
1028 // \return Iterator to the first index greater then the given index, end() iterator otherwise.
1029 //
1030 // In case of a row-major matrix, this function returns a row iterator to the first element with
1031 // an index greater then the given column index. In case of a column-major matrix, the function
1032 // returns a column iterator to the first element with an index greater then the given row
1033 // index. In combination with the lowerBound() function this function can be used to create a
1034 // pair of iterators specifying a range of indices. Note that the returned sparse matrix iterator
1035 // is subject to invalidation due to inserting operations via the function call operator, the
1036 // set() function or the insert() function!
1037 */
1038 template< typename PT    // Type of the proxy
1039         , typename MT >  // Type of the sparse matrix
1040 inline typename SparseMatrixProxy<PT,MT>::Iterator
upperBound(size_t i,size_t j)1041    SparseMatrixProxy<PT,MT>::upperBound( size_t i, size_t j ) const
1042 {
1043    return (**this).get().upperBound( i, j );
1044 }
1045 //*************************************************************************************************
1046 
1047 
1048 
1049 
1050 //=================================================================================================
1051 //
1052 //  GLOBAL FUNCTIONS
1053 //
1054 //=================================================================================================
1055 
1056 //*************************************************************************************************
1057 /*!\name SparseMatrixProxy global functions */
1058 //@{
1059 template< typename PT, typename MT >
1060 typename SparseMatrixProxy<PT,MT>::Iterator
1061    begin( const SparseMatrixProxy<PT,MT>& proxy, size_t i );
1062 
1063 template< typename PT, typename MT >
1064 typename SparseMatrixProxy<PT,MT>::ConstIterator
1065    cbegin( const SparseMatrixProxy<PT,MT>& proxy, size_t i );
1066 
1067 template< typename PT, typename MT >
1068 typename SparseMatrixProxy<PT,MT>::Iterator
1069    end( const SparseMatrixProxy<PT,MT>& proxy, size_t i );
1070 
1071 template< typename PT, typename MT >
1072 typename SparseMatrixProxy<PT,MT>::ConstIterator
1073    cend( const SparseMatrixProxy<PT,MT>& proxy, size_t i );
1074 
1075 template< typename PT, typename MT >
1076 size_t rows( const SparseMatrixProxy<PT,MT>& proxy );
1077 
1078 template< typename PT, typename MT >
1079 size_t columns( const SparseMatrixProxy<PT,MT>& proxy );
1080 
1081 template< typename PT, typename MT >
1082 size_t capacity( const SparseMatrixProxy<PT,MT>& proxy );
1083 
1084 template< typename PT, typename MT >
1085 size_t capacity( const SparseMatrixProxy<PT,MT>& proxy, size_t i );
1086 
1087 template< typename PT, typename MT >
1088 size_t nonZeros( const SparseMatrixProxy<PT,MT>& proxy );
1089 
1090 template< typename PT, typename MT >
1091 size_t nonZeros( const SparseMatrixProxy<PT,MT>& proxy, size_t i );
1092 
1093 template< typename PT, typename MT >
1094 void resize( const SparseMatrixProxy<PT,MT>& proxy, size_t m, size_t n, bool preserve=true );
1095 
1096 template< typename PT, typename MT >
1097 void reset( const SparseMatrixProxy<PT,MT>& proxy );
1098 
1099 template< typename PT, typename MT >
1100 void reset( const SparseMatrixProxy<PT,MT>& proxy, size_t i );
1101 
1102 template< typename PT, typename MT >
1103 void clear( const SparseMatrixProxy<PT,MT>& proxy );
1104 
1105 template< typename PT, typename MT >
1106 typename SparseMatrixProxy<PT,MT>::Iterator
1107    find( const SparseMatrixProxy<PT,MT>& proxy, size_t i, size_t j );
1108 
1109 template< typename PT, typename MT >
1110 typename SparseMatrixProxy<PT,MT>::Iterator
1111    lowerBound( const SparseMatrixProxy<PT,MT>& proxy, size_t i, size_t j );
1112 
1113 template< typename PT, typename MT >
1114 typename SparseMatrixProxy<PT,MT>::Iterator
1115    upperBound( const SparseMatrixProxy<PT,MT>& proxy, size_t i, size_t j );
1116 //@}
1117 //*************************************************************************************************
1118 
1119 
1120 //*************************************************************************************************
1121 /*!\brief Returns an iterator to the first element of row/column \a i of the represented matrix.
1122 // \ingroup math
1123 //
1124 // \param proxy The given access proxy.
1125 // \param i The row/column index.
1126 // \return Iterator to the first element of row/column \a i.
1127 //
1128 // This function returns a row/column iterator to the first element of row/column \a i. In case
1129 // the given matrix is a row-major matrix the function returns an iterator to the first element
1130 // of row \a i, in case it is a column-major matrix the function returns an iterator to the first
1131 // element of column \a i.
1132 */
1133 template< typename PT    // Type of the proxy
1134         , typename MT >  // Type of the sparse matrix
1135 BLAZE_ALWAYS_INLINE typename SparseMatrixProxy<PT,MT>::Iterator
begin(const SparseMatrixProxy<PT,MT> & proxy,size_t i)1136    begin( const SparseMatrixProxy<PT,MT>& proxy, size_t i )
1137 {
1138    return proxy.begin(i);
1139 }
1140 //*************************************************************************************************
1141 
1142 
1143 //*************************************************************************************************
1144 /*!\brief Returns an iterator to the first element of row/column \a i of the represented matrix.
1145 // \ingroup math
1146 //
1147 // \param proxy The given access proxy.
1148 // \param i The row/column index.
1149 // \return Iterator to the first element of row/column \a i.
1150 //
1151 // This function returns a row/column iterator to the first element of row/column \a i. In case
1152 // the given matrix is a row-major matrix the function returns an iterator to the first element
1153 // of row \a i, in case it is a column-major matrix the function returns an iterator to the first
1154 // element of column \a i.
1155 */
1156 template< typename PT    // Type of the proxy
1157         , typename MT >  // Type of the sparse matrix
1158 BLAZE_ALWAYS_INLINE typename SparseMatrixProxy<PT,MT>::ConstIterator
cbegin(const SparseMatrixProxy<PT,MT> & proxy,size_t i)1159    cbegin( const SparseMatrixProxy<PT,MT>& proxy, size_t i )
1160 {
1161    return proxy.cbegin(i);
1162 }
1163 //*************************************************************************************************
1164 
1165 
1166 //*************************************************************************************************
1167 /*!\brief Returns an iterator just past the last element of row/column \a i of the represented matrix.
1168 // \ingroup math
1169 //
1170 // \param proxy The given access proxy.
1171 // \param i The row/column index.
1172 // \return Iterator just past the last element of row/column \a i.
1173 //
1174 // In case the access proxy represents a matrix-like data structure that provides an end()
1175 // function, this function returns an iterator just past the last element of row/column \a i of
1176 // the matrix. In case the given matrix is a row-major matrix the function returns an iterator
1177 // just past the last element of row \a i, in case it is a column-major matrix the function
1178 // returns an iterator just past the last element of column \a i.
1179 */
1180 template< typename PT    // Type of the proxy
1181         , typename MT >  // Type of the sparse matrix
1182 BLAZE_ALWAYS_INLINE typename SparseMatrixProxy<PT,MT>::Iterator
end(const SparseMatrixProxy<PT,MT> & proxy,size_t i)1183    end( const SparseMatrixProxy<PT,MT>& proxy, size_t i )
1184 {
1185    return proxy.end(i);
1186 }
1187 //*************************************************************************************************
1188 
1189 
1190 //*************************************************************************************************
1191 /*!\brief Returns an iterator just past the last element of row/column \a i of the represented matrix.
1192 // \ingroup math
1193 //
1194 // \param proxy The given access proxy.
1195 // \param i The row/column index.
1196 // \return Iterator just past the last element of row/column \a i.
1197 //
1198 // In case the access proxy represents a matrix-like data structure that provides a cend()
1199 // function, this function returns an iterator just past the last element of row/column \a i of
1200 // the matrix. In case the given matrix is a row-major matrix the function returns an iterator
1201 // just past the last element of row \a i, in case it is a column-major matrix the function
1202 // returns an iterator just past the last element of column \a i.
1203 */
1204 template< typename PT    // Type of the proxy
1205         , typename MT >  // Type of the sparse matrix
1206 BLAZE_ALWAYS_INLINE typename SparseMatrixProxy<PT,MT>::ConstIterator
cend(const SparseMatrixProxy<PT,MT> & proxy,size_t i)1207    cend( const SparseMatrixProxy<PT,MT>& proxy, size_t i )
1208 {
1209    return proxy.cend(i);
1210 }
1211 //*************************************************************************************************
1212 
1213 
1214 //*************************************************************************************************
1215 /*!\brief Returns the current number of rows of the represented matrix.
1216 // \ingroup math
1217 //
1218 // \param proxy The given access proxy.
1219 // \return The number of rows of the matrix.
1220 */
1221 template< typename PT    // Type of the proxy
1222         , typename MT >  // Type of the sparse matrix
rows(const SparseMatrixProxy<PT,MT> & proxy)1223 BLAZE_ALWAYS_INLINE size_t rows( const SparseMatrixProxy<PT,MT>& proxy )
1224 {
1225    return proxy.rows();
1226 }
1227 //*************************************************************************************************
1228 
1229 
1230 //*************************************************************************************************
1231 /*!\brief Returns the current number of columns of the represented matrix.
1232 // \ingroup math
1233 //
1234 // \param proxy The given access proxy.
1235 // \return The number of columns of the matrix.
1236 */
1237 template< typename PT    // Type of the proxy
1238         , typename MT >  // Type of the sparse matrix
columns(const SparseMatrixProxy<PT,MT> & proxy)1239 BLAZE_ALWAYS_INLINE size_t columns( const SparseMatrixProxy<PT,MT>& proxy )
1240 {
1241    return proxy.columns();
1242 }
1243 //*************************************************************************************************
1244 
1245 
1246 //*************************************************************************************************
1247 /*!\brief Returns the maximum capacity of the represented matrix.
1248 // \ingroup math
1249 //
1250 // \param proxy The given access proxy.
1251 // \return The capacity of the matrix.
1252 */
1253 template< typename PT    // Type of the proxy
1254         , typename MT >  // Type of the sparse matrix
capacity(const SparseMatrixProxy<PT,MT> & proxy)1255 BLAZE_ALWAYS_INLINE size_t capacity( const SparseMatrixProxy<PT,MT>& proxy )
1256 {
1257    return proxy.capacity();
1258 }
1259 //*************************************************************************************************
1260 
1261 
1262 //*************************************************************************************************
1263 /*!\brief Returns the current capacity of the specified row/column of the represented matrix.
1264 // \ingroup math
1265 //
1266 // \param proxy The given access proxy.
1267 // \param i The index of the row/column.
1268 // \return The current capacity of row/column \a i.
1269 //
1270 // This function returns the current capacity of the specified row/column. In case the
1271 // storage order is set to \a rowMajor the function returns the capacity of row \a i,
1272 // in case the storage flag is set to \a columnMajor the function returns the capacity
1273 // of column \a i.
1274 */
1275 template< typename PT    // Type of the proxy
1276         , typename MT >  // Type of the sparse matrix
capacity(const SparseMatrixProxy<PT,MT> & proxy,size_t i)1277 BLAZE_ALWAYS_INLINE size_t capacity( const SparseMatrixProxy<PT,MT>& proxy, size_t i )
1278 {
1279    return proxy.capacity(i);
1280 }
1281 //*************************************************************************************************
1282 
1283 
1284 //*************************************************************************************************
1285 /*!\brief Returns the number of non-zero elements in the represented matrix.
1286 // \ingroup math
1287 //
1288 // \param proxy The given access proxy.
1289 // \return The number of non-zero elements in the matrix.
1290 */
1291 template< typename PT    // Type of the proxy
1292         , typename MT >  // Type of the sparse matrix
nonZeros(const SparseMatrixProxy<PT,MT> & proxy)1293 BLAZE_ALWAYS_INLINE size_t nonZeros( const SparseMatrixProxy<PT,MT>& proxy )
1294 {
1295    return proxy.nonZeros();
1296 }
1297 //*************************************************************************************************
1298 
1299 
1300 //*************************************************************************************************
1301 /*!\brief Returns the number of non-zero elements in the specified row/column of the represented matrix.
1302 // \ingroup math
1303 //
1304 // \param proxy The given access proxy.
1305 // \param i The index of the row/column.
1306 // \return The number of non-zero elements of row/column \a i.
1307 //
1308 // This function returns the current number of non-zero elements in the specified row/column.
1309 // In case the storage order is set to \a rowMajor the function returns the number of non-zero
1310 // elements in row \a i, in case the storage flag is set to \a columnMajor the function returns
1311 // the number of non-zero elements in column \a i.
1312 */
1313 template< typename PT    // Type of the proxy
1314         , typename MT >  // Type of the sparse matrix
nonZeros(const SparseMatrixProxy<PT,MT> & proxy,size_t i)1315 BLAZE_ALWAYS_INLINE size_t nonZeros( const SparseMatrixProxy<PT,MT>& proxy, size_t i )
1316 {
1317    return proxy.nonZeros(i);
1318 }
1319 //*************************************************************************************************
1320 
1321 
1322 //*************************************************************************************************
1323 /*! \cond BLAZE_INTERNAL */
1324 /*!\brief Backend implementation of the \c resize() function for non-square matrices.
1325 // \ingroup math
1326 //
1327 // \param proxy The given access proxy.
1328 // \param m The new number of rows of the matrix.
1329 // \param n The new number of columns of the matrix.
1330 // \param preserve \a true if the old values of the matrix should be preserved, \a false if not.
1331 // \return void
1332 //
1333 // This function changes the number of rows and columns of the given non-square matrix.
1334 */
1335 template< typename PT    // Type of the proxy
1336         , typename MT >  // Type of the sparse matrix
1337 BLAZE_ALWAYS_INLINE DisableIf_t< IsSquare_v<MT> >
resize_backend(const SparseMatrixProxy<PT,MT> & proxy,size_t m,size_t n,bool preserve)1338    resize_backend( const SparseMatrixProxy<PT,MT>& proxy, size_t m, size_t n, bool preserve )
1339 {
1340    proxy.resize( m, n, preserve );
1341 }
1342 /*! \endcond */
1343 //*************************************************************************************************
1344 
1345 
1346 //*************************************************************************************************
1347 /*! \cond BLAZE_INTERNAL */
1348 /*!\brief Backend implementation of the \c resize() function for square matrices.
1349 // \ingroup math
1350 //
1351 // \param proxy The given access proxy.
1352 // \param m The new number of rows of the matrix.
1353 // \param n The new number of columns of the matrix.
1354 // \param preserve \a true if the old values of the matrix should be preserved, \a false if not.
1355 // \return void
1356 // \exception std::invalid_argument Invalid resize arguments for square matrix.
1357 //
1358 // This function changes the number of rows and columns of the given square matrix.
1359 */
1360 template< typename PT    // Type of the proxy
1361         , typename MT >  // Type of the sparse matrix
1362 BLAZE_ALWAYS_INLINE EnableIf_t< IsSquare_v<MT> >
resize_backend(const SparseMatrixProxy<PT,MT> & proxy,size_t m,size_t n,bool preserve)1363    resize_backend( const SparseMatrixProxy<PT,MT>& proxy, size_t m, size_t n, bool preserve )
1364 {
1365    if( m != n ) {
1366       BLAZE_THROW_INVALID_ARGUMENT( "Invalid resize arguments for square matrix" );
1367    }
1368 
1369    proxy.resize( m, preserve );
1370 }
1371 /*! \endcond */
1372 //*************************************************************************************************
1373 
1374 
1375 //*************************************************************************************************
1376 /*!\brief Changing the size of the represented matrix.
1377 // \ingroup math
1378 //
1379 // \param proxy The given access proxy.
1380 // \param m The new number of rows of the matrix.
1381 // \param n The new number of columns of the matrix.
1382 // \param preserve \a true if the old values of the matrix should be preserved, \a false if not.
1383 // \return void
1384 // \exception std::invalid_argument Invalid resize arguments for square matrix.
1385 //
1386 // This function resizes the represented matrix to the specified dimensions. Note that in case
1387 // the matrix is a compile time square matrix (as for instance the blaze::SymmetricMatrix adaptor,
1388 // ...) the specified number of rows must be identical to the number of columns. Otherwise a
1389 // \a std::invalid_argument exception is thrown.
1390 */
1391 template< typename PT    // Type of the proxy
1392         , typename MT >  // Type of the sparse matrix
resize(const SparseMatrixProxy<PT,MT> & proxy,size_t m,size_t n,bool preserve)1393 BLAZE_ALWAYS_INLINE void resize( const SparseMatrixProxy<PT,MT>& proxy, size_t m, size_t n, bool preserve )
1394 {
1395    resize_backend( proxy, m, n, preserve );
1396 }
1397 //*************************************************************************************************
1398 
1399 
1400 //*************************************************************************************************
1401 /*!\brief Resetting the represented element to the default initial values.
1402 // \ingroup math
1403 //
1404 // \param proxy The given access proxy.
1405 // \return void
1406 //
1407 // This function resets all elements of the matrix to the default initial values.
1408 */
1409 template< typename PT    // Type of the proxy
1410         , typename MT >  // Type of the sparse matrix
reset(const SparseMatrixProxy<PT,MT> & proxy)1411 BLAZE_ALWAYS_INLINE void reset( const SparseMatrixProxy<PT,MT>& proxy )
1412 {
1413    proxy.reset();
1414 }
1415 //*************************************************************************************************
1416 
1417 
1418 //*************************************************************************************************
1419 /*!\brief Reset the specified row/column of the represented matrix.
1420 // \ingroup math
1421 //
1422 // \param proxy The given access proxy.
1423 // \param i The index of the row/column to be resetted.
1424 // \return void
1425 //
1426 // This function resets all elements in the specified row/column of the given matrix to their
1427 // default value. In case the given matrix is a \a rowMajor matrix the function resets the values
1428 // in row \a i, if it is a \a columnMajor matrix the function resets the values in column \a i.
1429 // Note that the capacity of the row/column remains unchanged.
1430 */
1431 template< typename PT    // Type of the proxy
1432         , typename MT >  // Type of the sparse matrix
reset(const SparseMatrixProxy<PT,MT> & proxy,size_t i)1433 BLAZE_ALWAYS_INLINE void reset( const SparseMatrixProxy<PT,MT>& proxy, size_t i )
1434 {
1435    proxy.reset(i);
1436 }
1437 //*************************************************************************************************
1438 
1439 
1440 //*************************************************************************************************
1441 /*!\brief Clearing the represented matrix.
1442 // \ingroup math
1443 //
1444 // \param proxy The given access proxy.
1445 // \return void
1446 //
1447 // This function clears the matrix to its default initial state.
1448 */
1449 template< typename PT    // Type of the proxy
1450         , typename MT >  // Type of the sparse matrix
clear(const SparseMatrixProxy<PT,MT> & proxy)1451 BLAZE_ALWAYS_INLINE void clear( const SparseMatrixProxy<PT,MT>& proxy )
1452 {
1453    proxy.clear();
1454 }
1455 //*************************************************************************************************
1456 
1457 
1458 //*************************************************************************************************
1459 /*!\brief Searches for a specific matrix element.
1460 // \ingroup math
1461 //
1462 // \param proxy The given access proxy.
1463 // \param i The row index of the search element. The index has to be in the range \f$[0..M-1]\f$.
1464 // \param j The column index of the search element. The index has to be in the range \f$[0..N-1]\f$.
1465 // \return Iterator to the element in case the index is found, end() iterator otherwise.
1466 */
1467 template< typename PT    // Type of the proxy
1468         , typename MT >  // Type of the sparse matrix
1469 BLAZE_ALWAYS_INLINE typename SparseMatrixProxy<PT,MT>::Iterator
find(const SparseMatrixProxy<PT,MT> & proxy,size_t i,size_t j)1470    find( const SparseMatrixProxy<PT,MT>& proxy, size_t i, size_t j )
1471 {
1472    return proxy.find( i, j );
1473 }
1474 //*************************************************************************************************
1475 
1476 
1477 //*************************************************************************************************
1478 /*!\brief Returns an iterator to the first index not less than the given index.
1479 // \ingroup math
1480 //
1481 // \param proxy The given access proxy.
1482 // \param i The row index of the search element. The index has to be in the range \f$[0..M-1]\f$.
1483 // \param j The column index of the search element. The index has to be in the range \f$[0..N-1]\f$.
1484 // \return Iterator to the first index not less than the given index, end() iterator otherwise.
1485 */
1486 template< typename PT    // Type of the proxy
1487         , typename MT >  // Type of the sparse matrix
1488 BLAZE_ALWAYS_INLINE typename SparseMatrixProxy<PT,MT>::Iterator
lowerBound(const SparseMatrixProxy<PT,MT> & proxy,size_t i,size_t j)1489    lowerBound( const SparseMatrixProxy<PT,MT>& proxy, size_t i, size_t j )
1490 {
1491    return proxy.lowerBound( i, j );
1492 }
1493 //*************************************************************************************************
1494 
1495 
1496 //*************************************************************************************************
1497 /*!\brief Returns an iterator to the first index greater than the given index.
1498 // \ingroup math
1499 //
1500 // \param proxy The given access proxy.
1501 // \param i The row index of the search element. The index has to be in the range \f$[0..M-1]\f$.
1502 // \param j The column index of the search element. The index has to be in the range \f$[0..N-1]\f$.
1503 // \return Iterator to the first index greater than the given index, end() iterator otherwise.
1504 */
1505 template< typename PT    // Type of the proxy
1506         , typename MT >  // Type of the sparse matrix
1507 BLAZE_ALWAYS_INLINE typename SparseMatrixProxy<PT,MT>::Iterator
upperBound(const SparseMatrixProxy<PT,MT> & proxy,size_t i,size_t j)1508    upperBound( const SparseMatrixProxy<PT,MT>& proxy, size_t i, size_t j )
1509 {
1510    return proxy.upperBound( i, j );
1511 }
1512 //*************************************************************************************************
1513 
1514 } // namespace blaze
1515 
1516 #endif
1517