You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Matlab依赖索引网格的循环向量化优化:加速三维数组最大化计算

问题描述

需要对三维数组V(e,b,d)沿第一维度执行最大化操作,得到b×d维度的矩阵e_opt,定义如下:
e_opt(b,d) = argmaxₑ {V(e,b,d)}

特殊点在于e的网格范围依赖于d,因此无法消除d维度的循环。现有代码单次运行约1秒,但因需多次执行,速度无法满足需求,寻求加速方案。以下为最小工作示例(MWE):

clear
close all
clc
rng("default")

% Size of grids
n_b = 1000;
n_d = 1000;
n_e = 5000;

% Parameters
delta   = 0.2696037674949296; 
%omega_0 = 0.0015534835229589;
%omega_1 = 0.0013023827114628;

% Generate fake data
cost_mat = rand(n_e,n_d);
prob_mat = rand(n_e,n_d);
option_nob = rand(n_b,1);
d_grid = linspace(0,2.3,n_d)';

%% Create a grid for "e". The non-standard feature is that the upper bound
% of the e_grid depends on "d"
e_grid_mat = zeros(n_e,n_d);
e_min = 0;
space = 1.5;
for d_c=1:n_d
    d_val = d_grid(d_c);
    e_max = 0.1+0.2*d_val; %silly example, don't take this literally
    % e_grid is NOT equally spaced
    e_grid_mat(:,d_c) = e_min+(e_max-e_min)*(linspace(0,1,n_e).^space)';
end

%% The code below is the part that I'd like to speed up
tic
e_opt = zeros(n_b,n_d);
for d_c = 1:n_d
    % Effort grid depends on d (upper bound changes, but same no. of elements)
    e_grid = e_grid_mat(:,d_c); %each column of e_grid_mat is different!
    % V(e,b) has dim: (n_e,n_b) and I maximize with respect to the first dimension, e
    V = -cost_mat(:,d_c)-delta*prob_mat(:,d_c).*option_nob';
    [~,max_ind] = max(V,[],1); %maxind is (1,n_b) vector
    e_opt(:,d_c)  = e_grid(max_ind);
end %end d
toc

%To check results
disp(mean(mean(e_opt)))

加速方案

1. 优化核心运算的向量化与预计算

原循环内重复计算V矩阵时,可利用矩阵乘法替代逐元素广播(MATLAB对BLAS优化的矩阵乘法效率更高),同时预计算固定部分减少重复运算:

% 预计算-cost_mat,避免循环内重复取负
pre_cost = -cost_mat;

tic
e_opt = zeros(n_b, n_d);
for d_c = 1:n_d
    e_grid = e_grid_mat(:,d_c);
    % 用矩阵乘法替代广播,提升运算速度
    V = pre_cost(:,d_c) - delta * prob_mat(:,d_c) * option_nob';
    [~,max_ind] = max(V,[],1);
    e_opt(:,d_c) = e_grid(max_ind);
end
toc

2. 并行化循环(Parfor)

由于各d_c对应的运算完全独立,可使用parfor开启多核心并行计算:

% 启动并行池(需提前配置MATLAB并行工具箱)
parpool;

tic
e_opt = zeros(n_b, n_d);
parfor d_c = 1:n_d
    e_grid = e_grid_mat(:,d_c);
    V = -cost_mat(:,d_c) - delta * prob_mat(:,d_c) * option_nob';
    [~,max_ind] = max(V,[],1);
    e_opt(:,d_c) = e_grid(max_ind);
end
toc

% 关闭并行池
delete(gcp);

3. GPU加速(若有可用GPU)

将数组转移至GPU执行运算,MATLAB会自动利用GPU的并行能力加速矩阵操作:

% 将所有数组转移到GPU
cost_mat_gpu = gpuArray(cost_mat);
prob_mat_gpu = gpuArray(prob_mat);
option_nob_gpu = gpuArray(option_nob);
e_grid_mat_gpu = gpuArray(e_grid_mat);
e_opt_gpu = gpuArray.zeros(n_b, n_d);
delta_gpu = gpuArray(delta);

tic
for d_c = 1:n_d
    e_grid = e_grid_mat_gpu(:,d_c);
    V = -cost_mat_gpu(:,d_c) - delta_gpu * prob_mat_gpu(:,d_c) * option_nob_gpu';
    [~,max_ind] = max(V,[],1);
    e_opt_gpu(:,d_c) = e_grid(max_ind);
end
toc

% 将结果转回CPU
e_opt = gather(e_opt_gpu);

4. 优化e_grid_mat的生成

原代码中每次循环都计算linspace(0,1,n_e).^space,可提前预计算该基础序列,减少重复运算:

e_base = linspace(0,1,n_e).^space;
e_grid_mat = zeros(n_e,n_d);
e_min = 0;
space = 1.5;
for d_c=1:n_d
    d_val = d_grid(d_c);
    e_max = 0.1+0.2*d_val;
    e_grid_mat(:,d_c) = e_min + (e_max - e_min) * e_base;
end

内容的提问来源于stack exchange,提问作者Alessandro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.02 20:28:19