在修改的压缩稀疏行矩阵

时间:2017-11-16 19:11:17

标签: c++ matrix sparse-matrix

我实施线性代数课程,我没有找到任何库,所以我从头开始实现它。我在这里谈到修改后的压缩稀疏行矩阵类reference,我编写了正常工作的构造函数:

template <typename T>
constexpr MCSRmatrix<T>::MCSRmatrix( std::initializer_list<std::initializer_list<T>> rows)
{
      this->dim  = rows.size();
      auto _rows = *(rows.begin());

      aa_.resize(dim+1);
      ja_.resize(dim+1);

      if(dim != _rows.size())
      {
          throw InvalidSizeException("Error in costructor! MCSR format require square matrix!");  
      }

      itype w = 0 ;
      ja_.at(w) = dim+2 ;
      for(auto ii = rows.begin(), i=1; ii != rows.end() ; ++ii, i++)
      {
          for(auto ij = ii->begin(), j=1, elemCount = 0 ; ij != ii->end() ; ++ij, j++ )   
          {
              if(i==j)
                 aa_[i-1] = *ij ;
              else if( i != j && *ij != 0 )
              {   
                 ja_.push_back(j); 
                 aa_.push_back(*ij); 
                 elemCount++ ;
              }
              ja_[i] = ja_[i-1] + elemCount;           
          }
      }     
}

然后我需要从2容器(值aa_和指针ja_)开始打印整个矩阵,所以我创建了一个效用函数,给出2索引返回值的索引&#39; s向量如果存在于该位置,否则为-1;

template <typename T>
std::size_t constexpr MCSRmatrix<T>::findIndex(const itype row ,  const itype col) const noexcept 
{    
     assert( row > 0 && row <= dim && col > 0 && col <= dim ); 
     if(row == col)
     {
       return row-1;
     }
     int i = -1;

      for(int i = ja_.at(row-1)-1 ; i < ja_.at(row)-1 ; i++ )
      {
            if( ja_.at(i) == col ) 
            { 
              return i ;
            }
      }
      return -1;
}

这个函数工作正常,为了验证我以这种方式使用重载的operator():

template <typename T>
const T MCSRmatrix<T>::operator()(const itype r , const itype c) const noexcept 
{     
     auto i = findIndex(r,c); 
     if( i != -1 && i < aa_.size() )
     {      
            return aa_.at(i) ;
     }
     else
     {
            return 0.0 ;
     }       
}

只需编写运算符&lt;&lt;&lt;&lt;&lt;&lt;&lt;像往常一样:

template <typename T>
std::ostream& operator<<(std::ostream& os ,const MCSRmatrix<T>& m) noexcept 
{
      //m.print();
     for(std::size_t i=1 ; i <= m.dim ; i++ )
     {       
         for(std::size_t j=1 ; j <= m.dim ; j++)   
            os << std::setw(8) << m(i,j) << ' ' ;
         os << std::endl;   
     } 
     return os;
}

现在终于到了问题/问题: 如何将元素插入矩阵?我写了这个(有问题的)方法,但正如你所看到的那样,充满了纠正......仅仅是为了恢复一些经过验证的情况,它没有正常工作:

template<typename T>
auto constexpr MCSRmatrix<T>::insertAt(itype row ,itype col , T elem) noexcept 
{
      if(elem == 0)
      {
          std::cerr << "zero element to insert ! Exit 1" << std::endl; 
      }

      int index = findIndex(row,col);
      if( index != -1  || row == col)
      {     
          aa_.at(index) = elem ;
      }
      else if(index == -1) 
      {

          for(auto i=row; i< dim+1 ; i++) 
          {     
                ja_.at(i) += 1 ;
          }

          if(ja_.at(row) > aa_.size() ) //std::cout << aa_.size() << ' ' <<ja_.at(row) << std::endl;
          {   

              aa_.push_back(elem);
              ja_.push_back(col);
          }
          else if ( ja_.at(row) <= aa_.size() )
          {    
                if( dim==4 && (ja_.at(2) - ja_.at(1) == 2) && (row==2 ) )
                {
                     //std::cout << "c1" << std::endl;   
                     ja_.insert( ja_.begin() + dim  + row +1 , col );
                     aa_.insert( aa_.begin() + dim  + row +1 , elem);
                }
                else if( dim==4 && (ja_.at(3) - ja_.at(2) == 2) && (row==3 ) )
                {
                     //std::cout << "c2"  << std::endl;   
                     ja_.insert( ja_.begin() + dim  + row +1 , col );
                     aa_.insert( aa_.begin() + dim  + row +1 , elem);
                }
                else  
                {  
                  //std::cout << "i  " << row << "dim+row  " << dim + row << std::endl; 
                  ja_.insert( ja_.begin() + dim  + row , col );
                  aa_.insert( aa_.begin() + dim  + row , elem);
                }

          }
      }
}

itype = std::size_t,你能帮我找一个解决方案吗?我需要添加一个值,不仅仅是为了添加一个值,而是为了执行此类的2矩阵或产品之间的总和。

如果你想尝试主要的课程:

int main(){

  MCSRmatrix<int> m1 = {{4,0,1,2,0},{0,1,0,0,0},{0,0,5,7,0},{6,3,0,8,0},{0,0,0,0,9}};    

  m1.insertAt(3,4,16);

  cout << m1 ;

  MCSRmatrix<int> m2 = {{4,0,1,2},{0,1,0,2},{0,0,5,7},{6,3,0,8}}; 

  m2.insertAt(2,3,44);
  cout << m2 ;

  return 0;
}

0 个答案:

没有答案