Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/loops/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/google-cloud-platform/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Performance 如何在Scilab中对所有矩阵元素执行操作?_Performance_Loops_Matrix_Scilab_Heat - Fatal编程技术网

Performance 如何在Scilab中对所有矩阵元素执行操作?

Performance 如何在Scilab中对所有矩阵元素执行操作?,performance,loops,matrix,scilab,heat,Performance,Loops,Matrix,Scilab,Heat,我试着模拟无限大平板上随时间的热量分布。为此,我编写了一个Scilab脚本。现在,它的关键点,是计算所有板块点的温度,我想观察的每一个例子都必须这样做: for j=2:S-1 for i=2:S-1 heat(i, j) = tcoeff*10000*(plate(i-1,j) + plate(i+1,j) - 4*plate(i,j) + plate(i, j-1) + plate(i, j+1)) + plate(i,j); end; e

我试着模拟无限大平板上随时间的热量分布。为此,我编写了一个Scilab脚本。现在,它的关键点,是计算所有板块点的温度,我想观察的每一个例子都必须这样做:

for j=2:S-1
    for i=2:S-1
        heat(i, j) = tcoeff*10000*(plate(i-1,j) + plate(i+1,j) - 4*plate(i,j) + plate(i, j-1) + plate(i, j+1)) + plate(i,j);          
    end;
end 
问题是,如果我想对一个100x100点的板做这个,这意味着,在这里(只对内部部分,没有边界条件),我必须循环98x98=9604次,每次循环计算给定
I,j
点的热量。如果我想观察,比如说100秒,用1s的步长,我必须重复100次,总共给出960400次迭代。这需要很长时间,我想避免。高达50x50板,这一切都发生在一个合理的,4-5秒的时间框架


现在我的问题是-是否有必要使用
for
循环来执行所有这些操作?Scilab中是否有内置的聚合函数,可以让我对矩阵的所有元素执行此操作?我还没有找到方法的原因是,每个点的结果取决于其他矩阵点的值,这使得我使用嵌套循环来实现。任何关于如何让它更快的想法都值得赞赏

在我看来,你想计算你的热场和某个扩散模式的2D相互关联。此模式可以被视为“过滤器”内核,这是使用线性过滤器矩阵修改图像的常用方法。您的“过滤器”是:

如果您安装了图像处理工具箱(IPD),您将有一个
MaskFilter
函数来执行此2D相互关联

S=500;
plate=rand(S,S);
tcoeff=1;

//your solution with nested for loops
t0=getdate();
for j=2:S-1
  for i=2:S-1
    heat(i, j) = tcoeff*10000*(plate(i-1,j)+plate(i+1,j)-..
    4*plate(i,j)+plate(i,j-1)+plate(i, j+1))+plate(i,j);          
  end
end
t1=getdate();
T0=etime(t1,t0);
mprintf("\nNested for loops: %f s (100 %%)",T0);

//optimised nested for loop
F=[0,1,0;1,-4,1;0,1,0];   //"filter" matrix
F=tcoeff*10000*F;
heat2=zeros(plate);
t0=getdate();
for j=2:S-1
  for i=2:S-1
    heat2(i,j)=sum(F.*plate(i-1:i+1,j-1:j+1));
  end
end
heat2=heat2+plate;
t1=getdate();
T2=etime(t1,t0);
mprintf("\nNested for loops optimised: %f s (%.2f %%)",T2,T2/T0*100);

//MaskFilter from IPD toolbox
t0=getdate();
heat3=MaskFilter(plate,F);
heat3=heat3+plate;
t1=getdate();
T3=etime(t1,t0);
mprintf("\nWith MaskFilter: %f s (%.2f %%)",T3,T3/T0*100);

disp(heat3(1:10,1:10)-heat(1:10,1:10),"Difference of the results (heat3-heat):");
请注意,
MaskFilter
在应用过滤器之前填充图像(原始矩阵),据我所知,它在边界上使用“镜像”数组。你应该检查这种行为是否适合你

速度增加约为*320(执行时间为原始代码的0.32%)。够快吗


理论上,它可以通过两个二维傅里叶变换来实现(使用Scilab内置的mfft
mfft
maybe),但它可能不会比这更快。请参阅:

< P>请考虑向量化操作与并行计算之间有很大区别,如我所解释的。虽然矢量化可能会稍微提高性能,但这无法与您通过GPU计算(例如OpenCL)所能实现的性能相比。我将尝试解释代码的矢量化形式,而不会过多地讨论细节。考虑这些问题:

S = ...;
tcoeff = ...;

function Plate = plate(i, j)
    ...;
endfunction

function Heat = heat(i, j)
    ...;
endfunction
现在您可以定义一个
meshgrid

x = 2 : S - 1;
y = 2 : S - 1;
[M, N] = meshgrid(x,y);
Result = feval(M, N, heat);

feval
是此处的键,它将在
M
N
矩阵上广播
feval
功能

您的方案是应用于矩形网格的拉普拉斯算子的有限差分方案。如果您选择自由度的行或列编号(此处为板(i,j))以将其视为向量,则可以通过将左侧的稀疏矩阵相乘来应用“离散”拉普拉斯算子(速度非常快),这在以下文档中得到了特别好的解释:


该实现在Matlab中描述,但在Scilab中很容易翻译。

是的,它肯定足够快。真棒的回答,谢谢!
x = 2 : S - 1;
y = 2 : S - 1;
[M, N] = meshgrid(x,y);
Result = feval(M, N, heat);