使用matlab对矩阵进行分块

1. 前言

由于matlab内存限制,导致无法处理较大尺寸的矩阵;

2. 解决思路

读取原始大尺寸矩阵,分块后处理,及时删除中间过程文件,只保留分块处理后的最终结果,最后合并结果文件,减少内存占用。

3. 矩阵分割函数

Matlab 复制代码
function output_mat_blocks = mat_gap(input_mat, gap_num)
    % 进行矩阵分割,否则矩阵太大,超出内存无法处理
    % 参数说明:
    %       输入:input_mat 为输入的原始矩阵,gap_num 为进行行列分割的阈值
    %       输出:output_mat_blocks 为输出的分割后的矩阵分块,cell格式
    [rows, cols] = size(input_mat);
    % gap_num = 2000; % 设置分块大小阈值
    if rows > gap_num || cols > gap_num
        row_gap_num = ceil(rows / gap_num);
        col_gap_num = ceil(cols / gap_num);
        row_block_size = floor(rows / row_gap_num);
        col_block_size = floor(cols / col_gap_num);
        % 输出分割行列
        row_gap = zeros(row_gap_num-1,1);
        col_gap = zeros(col_gap_num-1,1);
        for p=1:row_gap_num-1
            row_gap(p)=row_block_size*p;
        end
        for q=1:col_gap_num-1
            col_gap(q)=col_block_size*q;
        end

        %...切割矩阵
        output_mat_blocks=cell(row_gap_num,col_gap_num);
        for i=1:row_gap_num
            for j=1:col_gap_num
                if i~=row_gap_num && j~=col_gap_num
                    output_mat_blocks{i,j}=input_mat(row_block_size*(i-1)+1:row_block_size*i,col_block_size*(j-1)+1:col_block_size*j);
                elseif i==row_gap_num && j~=col_gap_num
                    output_mat_blocks{i,j}=input_mat(row_block_size*(i-1)+1:end,col_block_size*(j-1)+1:col_block_size*j);
                elseif i~=row_gap_num && j==col_gap_num   
                    output_mat_blocks{i,j}=input_mat(row_block_size*(i-1)+1:row_block_size*i,col_block_size*(j-1)+1:end);
                elseif i==row_gap_num && j==col_gap_num    
                    output_mat_blocks{i,j}=input_mat(row_block_size*(i-1)+1:end,col_block_size*(j-1)+1:end);
                end
            end
        end
    else
        output_mat_blocks=input_mat;
    end
end

4. 矩阵合并函数

Matlab 复制代码
function recover_mat = merge_mat_blocks(output_mat_blocks, rows, cols)
    % 合并分割后的矩阵块,重建原始大矩阵
    % 参数说明:
    %       输入:output_mat_blocks 为分割后的矩阵分块,cell格式
    %              rows 为原始矩阵的行数
    %              cols 为原始矩阵的列数
    %       输出:reconstructed_mat 为合并后的原始矩阵
    if iscell(output_mat_blocks)
        % 获取分块的数量
        [row_gap_num, col_gap_num] = size(output_mat_blocks);
        % 计算每个分块的大小
        row_block_size = floor(rows / row_gap_num);
        col_block_size = floor(cols / col_gap_num);
        % 初始化一个空矩阵,大小与原始矩阵相同,填充0
        recover_mat = zeros(rows, cols);
        % 合并分块
        for i = 1:row_gap_num
            for j = 1:col_gap_num
                % 计算当前分块在原始矩阵中的起始位置
                row_start = (i - 1) * row_block_size + 1;
                col_start = (j - 1) * col_block_size + 1;
                % 确定当前分块的大小
                if i == row_gap_num
                    row_end = rows;
                else
                    row_end = row_start + row_block_size - 1;
                end
                if j == col_gap_num
                    col_end = cols;
                else
                    col_end = col_start + col_block_size - 1;
                end
                % 将分块数据复制到正确的位置
                recover_mat(row_start:row_end, col_start:col_end) = output_mat_blocks{i, j};
            end
        end
    else
        % 如果没有分割,则 output_mat_blocks 就是原始矩阵
        recover_mat = output_mat_blocks;
    end
end

5. 调用

Matlab 复制代码
% 1. 栅格读取
[dem,dem_r]=readgeoraster('dem.tif'); % DEM数据文件
info=geotiffinfo('dem.tif');
dem_res=dem_r.CellExtentInWorldX;
[rows, cols]=size(dem);

% 2. 进行矩阵分割
gap_num=3000;
dem_mat_blocks = mat_gap(dem, gap_num);
clear dem

% 3. 进行矩阵分块处理
blocks_num = size(dem_mat_blocks,1)*size(dem_mat_blocks,2);
result=cell(size(dem_mat_blocks));  % 假如输出的结果为 result
for blocks_i=1:blocks_num
    dem=dem_mat_blocks{blocks_i};
    ...;  % 你对DEM的数据过程
    result{(blocks_i}=...;  
end

% 4. 合并结果矩阵(即result)
recover_mat = merge_mat_blocks(result, rows, cols);
相关推荐
死磕音视频10 小时前
让小模型做选择题:限定候选项并读取 logits 概率的入门实践(附 Python 代码)
开发语言·python·大模型·文本分类·transformers
顽疲12 小时前
Java vue 养老系统源码详解:月账单 care_month_bill 与 Quartz 扣费 Job 实践
java·开发语言·vue.js·vue养老·springboot养老·java养老
Wang's Blog12 小时前
Java 项目实战: 交友项目 - 安装开发工具与环境准备
java·开发语言·交友
程序喵大人14 小时前
【C++入门】编译链接模型 - 07 链接器怎样把符号对上号
开发语言·c++·编译器·编译链接·链接器
微三云 - 廖会灵 (私域系统开发)14 小时前
供应链系统实战:多渠道订单聚合与分布式库存一致性方案总结
开发语言·分布式·php
学逆向的15 小时前
C 数据溢出与精度丢失
c语言·开发语言·网络安全
霸道流氓气质15 小时前
AgentFlow 入门与实战:Task-Based 并发、EWMA 动态调度与四道门禁的 Java 生产级编排
java·开发语言
释厄62316 小时前
错误无误公理——错误正确本同源都迭代定律——逆转有价值
android·开发语言·kotlin
2601_9628857216 小时前
如何用 Python计算 CR能量指标(中间意愿指标)?
开发语言·python
临床数据科学和人工智能兴趣组17 小时前
在R语言的生态系统中,字符串处理一直是一个重要且复杂的任务
开发语言·正则表达式·r语言·r语言-4.2.1