gpt4 book ai didi

c - 尽可能高效地评估具有约 60,000 个短符号表达式的 vector (Matlab,C)

转载 作者:太空宇宙 更新时间:2023-11-03 23:28:39 25 4
gpt4 key购买 nike

我有一个符号 vector ,其中包含大约 60,000 个简短的符号表达式,每个单元格一个。这样的表达式通常看起来像:

(81*A_1_1*W1)/(646*L) - (81*A_6_6*L)/(646*W1)

这些表达式中总共出现了大约 20 个不同的变量,我知道其中的值。

问题的核心是尽可能高效地评估这个符号矩阵。将来我将需要执行此操作 1000 次(此计算是优化问题中目标函数的一部分)。

我编写了一个如下所示的 Matlab 函数:

function [K_1_uniques]=K_1_computation(C1,W1,L)

%Define variables from elasticity tensor C1
A_1_1=C1(1,1);
A_1_2=C1(1,2);
A_1_6=C1(1,3);
A_2_2=C1(2,2);
A_2_6=C1(2,3);
A_6_6=C1(3,3);
D_1_1=C1(4,4);
D_1_2=C1(4,5);
D_1_6=C1(4,6);
D_2_2=C1(5,5);
D_2_6=C1(5,6);
D_6_6=C1(6,6);
A_4_4=C1(7,7);
A_4_5=C1(7,8);
A_5_5=C1(8,8);

%Initialize vector
K_1_uniques=zeros(65251,1);

%Populate vector
K_1_uniques(1)=(81*A_1_1*W1)/(646*L) - (81*A_6_6*L)/(646*W1);
K_1_uniques(2)=(63*A_4_5*L)/1427660 - (27*A_5_5*W1)/1427660;
K_1_uniques(3)=(63*A_4_4*L)/1427660 - (27*A_4_5*W1)/1427660;
...
K_1_uniques(65251)=- (2187*A_4_4*L)/62817040 - (2187*A_4_5*W1)/102077690;

第一次运行 MATLAB 大约需要 12.3 秒(使用 tic-toc 计时),后续运行需要 0.030158 秒,因为我猜它保留了编译?我是否正确地假设 Mex 预编译将消除这个漫长的首次运行(IMO 由于 JIT)。

所以我想知道是否可以通过将其作为 Mex 文件运行来进一步加快计算速度?我没有编码器包,所以我不得不手写 C 代码(好吧,至少语法,我显然会使用 Matlab 的 fprintf 来编写 65,000 个表达式)。

这是我第一次编写 C Mex 代码(我有一些基本的 C 语言经验)。我已经设法运行了一个“hello world”和一些基本的整数和 double 算术,所以我知道发生了什么。

如果我没理解错的话,Mex 文件是预编译的 C 代码,因此与 Matlab 中的 JIT 编译相比应该节省一些时间。

我想向 Mex 文件输入一个 8*8 double 矩阵(弹性张量 C1)以及两个 double 值(标量)W1 和 L。

然后程序应该像在 Matlab 代码中那样分配 A_1_1=C1(1,1), A_1_2=C1(1,2)...。然后它应该填充一个新的矩阵数组,该数组具有 65,521 个输出条目。

我在下面有这样一段代码的简单大纲(仅 5 个条目),语法并不完全正确,但这是一个开始。它编译没有错误,但如果我尝试运行它,Matlab 就会崩溃。我已将 A_1_1 和 A_1_2 指定为标量输入,因为我不确定如何从输入矩阵 C1 中提取它们。我也不确定如何写入 matrixArray,所以我改用了 cellArray(应该更改)。

#include "mex.h" /* Always include this */
void mexFunction(double nlhs, mxArray *plhs[], /* Output variables */
double nrhs, mxArray *prhs[]) /* Input variables */
{
#define N 5
double A_1_1=*mxGetPr(prhs[0]);
double A_6_6=*mxGetPr(prhs[1]);

plhs[0]=mxCreateCellArray(1, N);
mxSetCell(plhs[0], 1, 2*A_1_1/84 + 3*A_6_6/92);
mxSetCell(plhs[0], 2, 5*A_1_1/120 + 7*A_6_6/11);
mxSetCell(plhs[0], 3, 2*A_1_1/56 + 4*A_6_6/82);
mxSetCell(plhs[0], 4, 12*A_1_1/7 + 3*A_6_6/48);
mxSetCell(plhs[0], 5, 2*A_1_1/74 + 8*A_6_6/92);

return;
}

如果能帮助运行此代码,我们将不胜感激。另外,我不知道有关内存分配等的任何 C 技巧可以进一步加速此过程。在这方面的任何建议或评论,以及我在更广泛意义上的尝试,将不胜感激。

最佳答案

我倾向于相信this answer to your previous question .甚至接受答案的回答者也同意它是正确的。你可能会再读一遍。

您的代码可以明显受益的一件事是 common subexpression elimination .这question/answer建议 Matlab 的 JIT 不执行此操作,但未指示 Matlab 的版本。对于您的代码,这将需要大量繁琐的工作。

当您使用符号数学工具箱时,subexpr功能可能对此有所帮助。我不确定这将如何工作,因为即使在具有大量内存的快速机器上,Symbolic 工具箱也会因大量输入而陷入困境,因此您可能需要解决问题。当然find和replace也可以用,只要你细心。使用后一种方法,您可以先查找并消除小的公共(public)子表达式,然后将它们组合起来。 Matlab 的编辑器在处理大文件时遇到问题,因为它会在每次更改时尝试对其着色并检查代码,因此您也可以切换到具有高级搜索和替换功能的全功能文本编辑器。只要您使用标准优化级别进行编译,迁移到 mex 也应该消除许多常见的子表达式。但在这一点上,将其作为更多标准循环植入会更有意义。

关于c - 尽可能高效地评估具有约 60,000 个短符号表达式的 vector (Matlab,C),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20596011/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com