如何打印子矩阵?

时间:2017-11-24 16:13:26

标签: c++ matrix

我正在尝试绘制这个矩阵:

11 12 13 14  0  0 
0  22 23  0  0  0 
0  0  33 34 35 36 
0  0  0  44 45  0 
0  0  0   0  0 56 
0  0  0   0  0 66 

以这种方式:

11 12
0  22

13 14
23  0

0  0 
0  0 

0  0
0  0 

23  0
33 34

35 36
45  0

0  0
0  0

0  0
0  0

0 56 
0 66

但我不知道该怎么做! 我只能使用:

绘制第一个子块
 for(auto i=0; i < sz ; i++ )
      {
           for(auto j=0 ; j < sz ; j++)
           {
               {
                  std::cout << dense[i][j] << ' ' ;
               }   
           }
           std::cout << std::endl;
      }   
  • 其中sz = 2

但后来我不知道如何继续! <矩阵>存储在矢量中>

通过这种方式我仍然得到了错误的结果:

 for(auto k=0; k < bsz ; k++)
      {
        for(auto i=k; i < sz+k ; i++ )
        {
           for(auto j=k ; j < sz+k ; j++)
           {
               {
                  std::cout << dense[i][j] << ' ' ;
               }   
           }
           std::cout << std::endl;
       }
      } 
  • 其中bbz = sz*sz;

使用我得到的上述代码:

11 12 
0 22 

22 23 
0 33 

33 34 
0 44 

44 45 
0 0 

好对不起傻瓜帖...我已经解决了......

 for(auto w=0; w<= bsz ; w+=2)
     {
      for(auto k=0; k <= bsz ; k+=2)
      {
        for(auto i=w; i < sz+w ; i++ )
        {
           for(auto j=k ; j < sz+k ; j++)
           {
               {
                  std::cout << dense[i][j] << ' ' ;
               }   
           }
           std::cout<< std::endl;
       }
       std::cout << std::endl;
      } 
    }
}

现在我想要存储这个块,如果它们是全部零的不同!为此,我以这种方式编写@Jodocus建议的代码:

 for(std::size_t i = 0; i < dense.size() / sz ; i++)
    {    
        auto rowCount =0;
        for(std::size_t j = 0; j < dense[i].size() / sz ; j++)
        {
            if(validate_block(dense,i,j))
            {     

                  std::cout << "*" << j+1 << std::endl;
                  aj_.push_back(j*sz+1);
                  print_block(dense, i, j);
                  std::cout << '\n';
                  rowCount ++ ;
            }      

        }
        ai_[i+1] = ai_[i] + rowCount ;
     }

使用

template <typename T,std::size_t sz>
auto constexpr BCSRmatrix<T,sz>::print_block(const std::vector<std::vector<T>>& dense,
                                                       std::size_t i, std::size_t j) const noexcept
{   
   for(std::size_t m = i * sz ; m < sz * (i + 1); ++m) {
      for(std::size_t n = j * sz ; n < sz * (j + 1); ++n)
                  std::cout << dense[m][n] << ' ';
      std::cout << '\n';
   }
}


template <typename T,std::size_t sz>
auto constexpr BCSRmatrix<T,sz>::validate_block(const std::vector<std::vector<T>>& dense,
                                                       std::size_t i, std::size_t j) const noexcept
{   
   for(std::size_t m = i * sz ; m < sz * (i + 1); ++m)
   {
      for(std::size_t n = j * sz ; n < sz * (j + 1); ++n)
      {
            if(dense[m][n] != 0) return true;
      }
      return false ;
   }
}

不关心矢量ai_和aj_它只是我最后的例程! 你能告诉我为什么阻挡 0 0 67 0 这个

matrix = BCSRmatrix<int,2> bbcsr2 = {{11,12,0,0,0,0,0,0} ,{0,22,0,0,0,0,0,0} ,{31,32,33,0,0,0,0,0},
                              {41,42,43,44,0,0,0,0}, {0,0,0,0,55,56,0,0},{0,0,0,0,0,66,67,0},{0,0,0,0,0,0,77,78},{0,0,0,0,0,0,87,88}};

没有通过检查?

3 个答案:

答案 0 :(得分:0)

只需在内环的主体中每个四个块,然后按2

for(auto i=0; i < dense.size() ; i+=2 )
{
    for(auto j=0 ; j < dense[i].size() ; j+=2 )
    {
        {
            std::cout << dense[i  ][j  ] << ' ' ;
            std::cout << dense[i  ][j+1] << ' ' ;
            std::cout << std::endl;
            std::cout << dense[i+1][j  ] << ' ' ;
            std::cout << dense[i+1][j+1] << ' ' ;
            std::cout << std::endl;
        }   
    }
}

答案 1 :(得分:0)

您可以通过使用块大小的倍数作为索引以非常类似的方式执行此操作:

#include <iostream>
#include <vector>

// print the (i,j)-th block
template <typename T>
void print_block(const std::vector<std::vector<T>>& dense, std::size_t block_size, std::size_t i, std::size_t j) {   
   for(std::size_t m = i * block_size; m < block_size * (i + 1); ++m) {
      for(std::size_t n = j * block_size; n < block_size * (j + 1); ++n)
         std::cout << dense[m][n] << ' ';
      std::cout << '\n';
   }
}

int main() {
    std::vector<std::vector<double>> dense = { 
        { 1, 2, 3, 4 },
        { 0, 4, 3, 2 },
        { 4, 2, 1, 1 },
        { 9, 0, 8, 1 }
    };
    const std::size_t block_size = 2;

    for(std::size_t i = 0; i < dense.size() / block_size; ++i)
        for(std::size_t j = 0; j < dense[i].size() / block_size; ++j) {
            print_block(dense, block_size, i, j);
            std::cout << '\n';
        }
}

答案 2 :(得分:0)

首先为自己定义一个参考点。在这里,偶数行甚至列可能是您的参考点。然后,使用额外的数组打印您需要的任何模式。这样,只需更改模式值,就可以输出任何形状,而不仅仅是块。

int pattern[2][4] = {
{0, +1, 0, +1},
{0, 0, +1, +1}
};

for(int i = 0; i < sz; i+=2){
    for(int j = 0; j < sz; j+=2){
        for(int k = 0; k < 4; k++){//size of pattern
            int new_i = i + pattern[0][k];
            int new_j = j + pattern[1][k];

            if(new_i >= sz || new_j >= sz)
                break;
            std::cout << arr[new_i][new_j] << " ";
            if(k == 1) std::cout << std::endl;
        }
        std::cout << std::endl;
    }
}