Program Listing for File SparseMatrix.h

↰ Return to documentation for file (ADS/numeric/SparseMatrix.h)

/*--------------------------------------------------------------------------*/
/*-------------------------- File SparseMatrix.h ---------------------------*/
/*--------------------------------------------------------------------------*/
/*--------------------------------------------------------------------------*/
/*----------------------------- DEFINITIONS --------------------------------*/
/*--------------------------------------------------------------------------*/

#ifndef __ADS_SparseMatrix
 #define __ADS_SparseMatrix
                      /* self-identification: #endif constant */

/*--------------------------------------------------------------------------*/
/*------------------------------ INCLUDES ----------------------------------*/
/*--------------------------------------------------------------------------*/

#include "ADS/Contract.h"

#include <cmath>
#include <cstddef>
#include <iterator>
#include <map>
#include <ranges>
#include <utility>
#include <vector>

/*--------------------------------------------------------------------------*/
/*--------------------------- NAMESPACE ------------------------------------*/
/*--------------------------------------------------------------------------*/

namespace ADS {

namespace detail {

template< class Node >
class OrthogonalIterator {
 public:
 using reference = std::pair< std::size_t , double >;
 using value_type = reference;
 using difference_type = std::ptrdiff_t;
 using iterator_concept = std::forward_iterator_tag;
 using iterator_category = std::input_iterator_tag;

 OrthogonalIterator( void ) = default;
 OrthogonalIterator( const std::vector< Node > * N , long q , bool byRow )
  : f_N( N ) , f_q( q ) , f_row( byRow ) {}

 reference operator*( void ) const {
  const Node & x = ( *f_N )[ f_q ];
  return( reference( f_row ? x.col : x.row , x.val ) );
  }
 OrthogonalIterator & operator++( void ) {
  f_q = f_row ? ( *f_N )[ f_q ].right : ( *f_N )[ f_q ].down;
  return( *this );
  }
 OrthogonalIterator operator++( int ) {
  auto t = *this;
  ++*this;
  return( t );
  }
 bool operator==( const OrthogonalIterator & o ) const {
  return( f_q == o.f_q );
  }

 private:
 const std::vector< Node > * f_N = nullptr;
 long f_q = -1;
 bool f_row = true;

 };  // end( class OrthogonalIterator )

}  // end( namespace detail )

/*--------------------------------------------------------------------------*/
/*-------------------------- CLASS SparseMatrix ----------------------------*/
/*--------------------------------------------------------------------------*/

class SparseMatrix {

/*--------------------------------------------------------------------------*/
 public:

 SparseMatrix( std::size_t m , std::size_t n );

 [[nodiscard]] std::size_t rows( void ) const;
 [[nodiscard]] std::size_t cols( void ) const;

 [[nodiscard]] std::size_t nonzeros( void ) const;

 [[nodiscard]] double get( std::size_t i , std::size_t j ) const;

 void set( std::size_t i , std::size_t j , double v );

 [[nodiscard]] std::vector< std::pair< std::size_t , double > > row(
                                                       std::size_t i ) const;

 [[nodiscard]] std::vector< std::pair< std::size_t , double > > col(
                                                       std::size_t j ) const;

 void pivot( std::size_t r , std::size_t c , double eps = 0 );

/*--------------------------------------------------------------------------*/
 private:

 struct Node {
  std::size_t row , col;
  double val;
  long right , down;
  };

 public:

/*------------------------- THE STANDARD INTERFACE -------------------------*/

 // the nonzeros of a row or of a column as ranges, forward along the
 // orthogonal lists, instead of the vectors that row() and col() build

 using const_iterator = detail::OrthogonalIterator< Node >;

 [[nodiscard]] std::ranges::subrange< const_iterator > rowEntries(
                                                       std::size_t i ) const;

 [[nodiscard]] std::ranges::subrange< const_iterator > colEntries(
                                                       std::size_t j ) const;

 private:

 [[nodiscard]] std::pair< long , long > findInRow( std::size_t i ,
                                                   std::size_t j ) const;
 [[nodiscard]] long beforeInCol( std::size_t i , std::size_t j ) const;

 [[nodiscard]] bool linked( void ) const;

 std::size_t f_m , f_n;
 std::vector< Node > f_N;
 std::vector< long > f_freeNodes;
 std::size_t f_nnz = 0;

 };  // end( class SparseMatrix )

/*--------------------------------------------------------------------------*/

}  // end( namespace ADS )

/*--------------------------------------------------------------------------*/
/*-------------------------- IMPLEMENTATION --------------------------------*/
/*--------------------------------------------------------------------------*/

#include "ADS/numeric/impl/SparseMatrix.tpp"

/*--------------------------------------------------------------------------*/

#endif  /* SparseMatrix.h included */

/*--------------------------------------------------------------------------*/
/*------------------------ End File SparseMatrix.h -------------------------*/
/*--------------------------------------------------------------------------*/