如何在MATLAB中提取原矩阵内M×N型非零子矩阵(M>1且N>1)
在MATLAB中查找满足条件的M×N非零子矩阵
需求说明
从给定矩阵中提取所有行数M>1、列数N>1的子矩阵,且子矩阵内所有元素均为非零值。
实现方案
以下提供两种实现思路,分别适配直观理解和高效计算场景:
方法1:滑动窗口遍历(直观易懂)
通过遍历所有可能的子矩阵尺寸与起始位置,逐一检查窗口内元素是否全为非零。
% 定义原始矩阵 A = [ 0 10 1 4 0 6 0 17 16 0 18 2 5 1 18 0 20 20 9 12 16 10 0 11 5 6 7 0 13 0 8 6 2 14 20 8 19 6 18 1 8 20 10 15 13 11 6 5 11 0 0 18 0 5 0 8 12 6 2 0 15 6 13 0 0 11 12 0 8 0 4 20 ]; % 转换为二值矩阵(非零=1,零=0) B = A ~= 0; % 初始化结果存储结构体 valid_submatrices = struct('start_row', [], 'start_col', [], 'rows', [], 'cols', [], 'data', []); count = 0; [rows_A, cols_A] = size(A); % 遍历所有符合要求的子矩阵尺寸 for M = 2:rows_A for N = 2:cols_A % 计算起始位置的有效范围 start_row_range = 1:(rows_A - M + 1); start_col_range = 1:(cols_A - N + 1); % 遍历所有起始位置 for r = start_row_range for c = start_col_range % 提取当前窗口并检查是否全非零 window = B(r:r+M-1, c:c+N-1); if all(window(:)) count = count + 1; valid_submatrices(count).start_row = r; valid_submatrices(count).start_col = c; valid_submatrices(count).rows = M; valid_submatrices(count).cols = N; valid_submatrices(count).data = A(r:r+M-1, c:c+N-1); end end end end end % 打印所有符合条件的子矩阵 for k = 1:count fprintf('子矩阵 %d:起始行=%d,起始列=%d,尺寸=%dx%d\n', ... k, valid_submatrices(k).start_row, valid_submatrices(k).start_col, ... valid_submatrices(k).rows, valid_submatrices(k).cols); disp(valid_submatrices(k).data); fprintf('\n'); end
方法2:卷积加速(高效处理大矩阵)
利用conv2函数快速计算每个窗口内的非零元素数量,直接筛选出全非零的窗口,避免嵌套循环的冗余计算。
% 定义原始矩阵 A = [ 0 10 1 4 0 6 0 17 16 0 18 2 5 1 18 0 20 20 9 12 16 10 0 11 5 6 7 0 13 0 8 6 2 14 20 8 19 6 18 1 8 20 10 15 13 11 6 5 11 0 0 18 0 5 0 8 12 6 2 0 15 6 13 0 0 11 12 0 8 0 4 20 ]; % 转换为二值矩阵 B = A ~= 0; % 初始化结果存储结构体 valid_submatrices = struct('start_row', [], 'start_col', [], 'rows', [], 'cols', [], 'data', []); count = 0; [rows_A, cols_A] = size(A); % 遍历所有符合要求的子矩阵尺寸 for M = 2:rows_A for N = 2:cols_A % 创建卷积核,计算窗口内非零元素总数 kernel = ones(M, N); non_zero_count = conv2(B, kernel, 'valid'); % 找到全非零的窗口位置 [r_idx, c_idx] = find(non_zero_count == M*N); % 存储符合条件的子矩阵 for k = 1:length(r_idx) start_r = r_idx(k); start_c = c_idx(k); count = count + 1; valid_submatrices(count).start_row = start_r; valid_submatrices(count).start_col = start_c; valid_submatrices(count).rows = M; valid_submatrices(count).cols = N; valid_submatrices(count).data = A(start_r:start_r+M-1, start_c:start_c+N-1); end end end % 打印结果 for k = 1:count fprintf('子矩阵 %d:起始行=%d,起始列=%d,尺寸=%dx%d\n', ... k, valid_submatrices(k).start_row, valid_submatrices(k).start_col, ... valid_submatrices(k).rows, valid_submatrices(k).cols); disp(valid_submatrices(k).data); fprintf('\n'); end
结果说明
运行代码后,会输出所有符合条件的子矩阵,包括其起始位置、尺寸和具体数据,与预期的非零子矩阵完全匹配。
内容的提问来源于stack exchange,提问作者Josh E.
相关产品推荐
相关产品推荐

