将矩阵拆分为小矩阵块的方法

Method to split a matrix into blocks of the small matrix

本文关键字:方法 拆分      更新时间:2023-10-16

>我有一个问题,想知道是否有人可以提供理想的解决方案。

基本上(小数据),但是,如果我有这样的矩阵:

     0 1 0 0
     1 1 1 0
     0 0 0 0
     1 1 0 0

然后,我需要将此矩阵拆分为与第二个矩阵大小相同的块,在本例中为 2x2:

0 1
1 1

我知道这与 offsetX/Y 值有关,这些值会根据(小)矩阵的大小而变化,我只是不知道计算此类结果的计算方法。我将把 offsetX/Y 传递给一个函数(带有向量),这样我就可以计算特定块的总和。

有人有什么建议吗?

谢谢

import std.stdio : writeln;
void main(string[] args)
{
    int m=4, n=4;
    int[][] matrix = [[0, 1, 0, 0], [1, 1, 1, 0], [0, 0, 0, 0], [1, 1, 0, 0]];
    int mm=2, nn=2;
    int sum;
    for(int x=0; x<m; x+=mm)
      for(int y=0; y<n; y+=nn)
        sum += summation(matrix, x, y, mm, nn);
    writeln(sum);
}    
int summation(int[][] matrix, int offsetx, int offsety, int m, int n)
{
  int sum;
  for(int x=offsetx; x<offsetx+m; x++)
    for(int y=offsety; y<offsety+n; y++)
      sum += matrix[x][y];
  return sum;
}

除非你正在寻找别的东西? 在解释您的要求时,您的问题很模糊。

(这是用 D 编译的,因为它是我唯一可以访问 atm 的东西,请将其用作转换为 C++ 的指南)

为了原位拆分矩阵(即不复制它),您需要一个可以处理原始和拆分片段的表示 - 这将使定义递归算法变得更加容易,等等:

template <class elt> class MatRef {
    elt* m_data;
    unsigned m_rows, m_cols;
    unsigned m_step;
    unsigned index(unsigned row, unsigned col)
    {
        assert(row < m_rows && col < m_cols);
        return m_step * row + col;
    }
public: // access
    elt& operator() (unsigned row, unsigned col)
    {
        return m_data[index(row,col)];
    }
public: // constructors
    MatRef(unsigned rows, unsigned cols, elt* backing)  // original matrix
        : m_rows(rows)
        , m_cols(cols)
        , m_step(cols)
        , m_data(backing)
    {}
    MatRef(unsigned start_row, unsigned start_col,
           unsigned rows, unsigned cols, MatRef &orig) // sub-matrix
        : m_rows(rows)
        , m_cols(cols)
        , m_step(orig.m_step)
        , m_data(orig.m_data + orig.index(start_row, start_col))
    {
        assert(start_row+rows <= orig.m_rows && start_col+cols <= orig.m_cols);
    }
};

原始矩阵构造函数假定其backing参数指向至少 rows*cols 长的数据元素数组,用于存储矩阵数据。 矩阵的维度由数据成员m_rowsm_cols定义。

数据成员m_step指示从一行的开始到下一行的开始有多少个数据元素。 对于原始矩阵,这与 m_cols 相同。 请注意,子矩阵的m_cols可能小于它所引用的原始矩阵的 - 这就是子矩阵"跳过"原始矩阵中不属于子矩阵的元素的方式。 为了使它正常工作,m_step必须与原始矩阵中的相同。

无论矩阵是否跳过元素,数据成员m_data始终指向矩阵的第一个元素。 子矩阵构造函数中的assert()可确保每个新的子矩阵都适合其派生自的矩阵。


我不确定这是否算作"有趣的算法",但它是定义和访问子矩阵的一种高效便捷的方法。

在数学上,你可以用曲线分割矩阵,例如Z曲线或皮亚诺曲线。这样,您还可以降低尺寸复杂性。z 曲线使用 4 个四边形来分割平面,类似于四叉树。

编辑:我刚刚了解到这是z顺序曲线而不是z曲线:http://en.wikipedia.org/wiki/Z-order_curve。z曲线是生物信息学中的3d http://en.wikipedia.org/wiki/Z_curve???哈哈!我不是生物信息学家,也不是维基百科,但这对我来说听起来像是胡说八道。z 有序曲线也可以覆盖 3d 区域。也许维基百科想这么说?这是 3d z 阶曲线 http://en.wikipedia.org/wiki/File:Lebesgue-3d-step3.png 的大图。它甚至在维基百科的文章中?????