这篇文章建立在我关于在Matlab中快速评估分析雅可比行列的文章的基础上:
fast evaluation of analytical jacobian in MATLAB
关键的区别在于,现在,我正在使用Hessian,每次评估粗体时,我必须评估接近700个matlab函数(而不是像我为Jacobian所做的那样的1个matlab函数)。因此,有机会以不同的方式做事。
到目前为止,我尝试过这两种方式,我正在考虑实施第三种方式,并且想知道是否有人有任何其他建议。我将通过一个玩具示例来介绍每个方法,但首先要进行一些预处理来生成这些matlab函数:
预处理:
% This part of the code is calculated once, it is not the issue
dvs = 5;
X=sym('X',[dvs,1]);
num = dvs - 1; % number of constraints
% multiple functions
for k = 1:num
f1(X(k+1),X(k)) = (X(k+1)^3 - X(k)^2*k^2);
c(k) = f1;
end
gradc = jacobian(c,X).'; % .' performs transpose
parfor k = 1:num
hessc{k} = jacobian(gradc(:,k),X);
end
parfor k = 1:num
hess_name = strcat('hessian_',num2str(k));
matlabFunction(hessc{k},'file',hess_name,'vars',X);
end
方法#1:系列评估功能
%% Now we use the functions to run an "optimization." Just for an example the "optimization" is just a for loop
fprintf('This is test A, where the functions are evaluated in series!\n');
tic
for q = 1:10
x_dv = rand(dvs,1); % these are the design variables
lambda = rand(num,1); % these are the lagrange multipliers
x_dv_cell = num2cell(x_dv); % for passing large design variables
for k = 1:num
hess_name = strcat('hessian_',num2str(k));
function_handle = str2func(hess_name);
H_temp(:,:,k) = lambda(k)*function_handle(x_dv_cell{:});
end
H = sum(H_temp,3);
end
fprintf('The time for test A was:\n')
toc
方法#2:并行评估功能
%% Try to run a parfor loop
fprintf('This is test B, where the functions are evaluated in parallel!\n');
tic
for q = 1:10
x_dv = rand(dvs,1); % these are the design variables
lambda = rand(num,1); % these are the lagrange multipliers
x_dv_cell = num2cell(x_dv); % for passing large design variables
parfor k = 1:num
hess_name = strcat('hessian_',num2str(k));
function_handle = str2func(hess_name);
H_temp(:,:,k) = lambda(k)*function_handle(x_dv_cell{:});
end
H = sum(H_temp,3);
end
fprintf('The time for test B was:\n')
toc
结果:
方法#1 = 0.008691秒
方法#2 = 0.464786秒
讨论结果
这个结果很有意义,因为这些函数非常快速地进行评估并且并行运行它们需要花费大量时间来设置并将作业发送到不同的Matlabs(然后从中获取数据)。我在实际问题上看到的结果相同。
方法#3:使用GPU评估功能
我还没有尝试过,但我很想知道性能差异是什么。我还不熟悉在Matlab中这样做,并且一旦完成就会添加它。
还有其他想法吗?评论?谢谢!