稀疏矩阵的行列式

时间:2017-11-06 11:16:44

标签: c++ matrix determinants

我正在实现一个稀疏矩阵类,使用map向量来存储数据(该映射表示一行矩阵,其中键是列的索引,值是此位置的maitrix值) 我已经写了计算行列式的函数,但我不知道是否有办法计算这个节省时间(因为矩阵是稀疏的,大部分值都是零) 在这里我的实施:

template <typename T>
T det(const SparseMatrix<T>& a )
{
      T d =0 ; // value of determinant ! 
      std::size_t row  = a.getRows() ;
      std::size_t cols = a.getCols() ;

      if(row == cols) // square Matrix;
      {     

         if(row == 1)   
         {
            d = a(1,1);  // matrix 1x1
         }
         else if(row == 2) 
         {
            d = a(1,1) * a(2,2) - a(2,1) * a (1,2);
         }
         else // 3x3 of greather ..
         {  
              for(std::size_t c = 1 ; c <= cols ; c++ )
              {
                  SparseMatrix<T> m = a.minors(1,c);
                  d += pow(-1,1+c) * a(1,c) * det(m) ;
              }
         }
      }
      else
      {
          throw std::runtime_error("Matrix must be square! Error occured in SparseMatrix::det()");   
      }
      return d ;
}

这是类接口

template <typename element_type>
class SparseMatrix {

  public:
   template<class T>
   friend SparseMatrix<T> operator+(const SparseMatrix<T>& m1 , const SparseMatrix<T>& m2 );  

   template<class T>
   friend SparseMatrix<T> operator-(const SparseMatrix<T>& m1 , const SparseMatrix<T>& m2 );  

   template <class T>
   friend SparseMatrix<T> operator*(const SparseMatrix<T>& m1 , const SparseMatrix<T>& m2  );

   template <class T>
   friend std::ostream& operator<<(std::ostream& out , const SparseMatrix<T>& m);

   template <class T>
   friend SparseMatrix<T> dot(const SparseMatrix<T>& m1 , const SparseMatrix<T>& m2  );

   template <class T>
   T det(const SparseMatrix<T>& a );




  public:
    // container type ;  
    using data_type = std::vector<std::map<std::size_t , element_type >> ;
    using it_rows   = typename std::map<std::size_t , element_type>::iterator ; 

    constexpr SparseMatrix(std::size_t rows , std::size_t cols) : rows{rows} , columns{cols}
    {
       data.resize(rows);     
    }

    SparseMatrix(std::initializer_list<std::initializer_list<element_type>> l );

    SparseMatrix(const std::string );  


    auto insert(std::size_t i , std::pair<std::size_t, element_type> p )
    { 
       assert( i < rows && p.first < columns); // , "Index out of bound" );
       data.at(i).insert(p);
    }

    auto insert(std::size_t i, std::size_t j, element_type val)
    {
      assert(i<rows && j <columns);
      data.at(i)[j] = val ;
    }

    auto identity() noexcept ;

    auto diag(const element_type& v) noexcept ;

    auto print() const noexcept ; 

    auto dataType() const noexcept ;

    auto traspose() noexcept ;

    auto printf()const noexcept ;

    constexpr auto getRows() const noexcept { return rows; }  

    constexpr auto getCols() const noexcept { return columns; } 

    SparseMatrix<element_type> operator*=(const SparseMatrix<element_type>) ;

    const element_type operator()(std::size_t , std::size_t) const noexcept ;  

    element_type operator()(std::size_t , std::size_t) noexcept ;  

    constexpr SparseMatrix<element_type> minors(const std::size_t , const std::size_t ) const;  

  private:

    std::size_t rows    ;
    std::size_t columns ;
      data_type data    ;     // vector containing row element 


};

我计算行列式的方式是什么? 认为operator()以这种方式重载

template <typename T>
T SparseMatrix<T>::operator()(std::size_t i, std::size_t j) noexcept 
{
      i -= 1 ;
      j -= 1 ;
      if(data.at(i).find(j) != data.at(i).end()) 
      {
         return data.at(i).at(j) ;
      }
      else
      {
         return 0.0 ;    
      }
}

提前感谢您的帮助

1 个答案:

答案 0 :(得分:0)

你需要能够构建未成年人,而无需分配所有内容的新副本;你需要一些小观点。

次要视图有一个指向其源矩阵的指针,以及一些描述跳过哪些列和行的有效方法。

您希望能够轻松跳过空列/行,并快速迭代而无需检查每个条目。因此,您可能希望存储要开始的地图,然后改进以获取压缩矢量和/或跳过列表。如果ypur矩阵真的很稀疏,那么在每个索引处检查零可以控制你的计算。