Wolfram mathematica 二维数据集的高效数值计算

Wolfram mathematica 二维数据集的高效数值计算,wolfram-mathematica,Wolfram Mathematica,我想计算高斯光束的傅里叶变换。稍后我想对下面的示例代码做一些修改。在所需的1e-6步长下,使用8内核的计算在我的工作站上需要1244秒。很明显,最消耗的部分是性能的产生。有人有什么想法来提高绩效吗?为什么mathematica不从我的表达式中创建一个压缩列表,而我的表达式中既有实值又有复值 uin[gx_, gy_, z_] := Module[{w0 = L1[[1]], z0 = L1[[3]], w, R, \[Zeta], k}, w = w0 Sqrt[1 + (z/z0)^2];

我想计算高斯光束的傅里叶变换。稍后我想对下面的示例代码做一些修改。在所需的1e-6步长下,使用8内核的计算在我的工作站上需要1244秒。很明显,最消耗的部分是性能的产生。有人有什么想法来提高绩效吗?为什么mathematica不从我的表达式中创建一个压缩列表,而我的表达式中既有实值又有复值

uin[gx_, gy_, z_] :=  Module[{w0 = L1[[1]], z0 = L1[[3]], w, R, \[Zeta], k},
w = w0 Sqrt[1 + (z/z0)^2];
R = z (1 + (z0/z)^2);
\[Zeta] = ArcTan[z/z0];
k = 2*Pi/193*^-9;
Developer`ToPackedArray[
  ParallelTable[
  w0/w Exp[-(x^2 + y^2)/w^2] Exp[-I k/2/R (x^2 + y^2)/2] Exp[-I k z*0 + 
  I \[Zeta]*0], {x, gx}, {y, gy}]
  ]  
]

AbsoluteTiming[ 
dx = 1*^-6;  
gx = Range[-8*^-3, 8*^-3, dx];
gy = gx;
d = 15*^-3;
uaperture = uin[gx, gy, d];
ufft = dx*dx* Fourier[uaperture];
uout = RotateRight[
Abs[ufft]*dx^2, {Floor[Length[gx]/2], Floor[Length[gx]/2]}];
]
提前感谢,


Johannes

您可以先对其进行矢量化(
uin2
),然后对其进行编译(
uin3
):

我们得到了约160倍的加速,即使这不是并行运行

结果相同:

In[12]:= r1 == r2
Out[12]= True
由于数值误差,这里有一个微小的差异:

In[13]:= r2 == r3
Out[13]= False

In[14]:= Max@Abs[r2 - r3]
Out[14]= 5.63627*10^-14

在打包之前,使用
ToPackedArray[0.I+数组]
将所有内容强制为
Complex
。然后它将成功地创建一个压缩数组。感谢提示,但是
ToPackedArray[ParallelTable[Exp[-(x^2+y^2)/w^2]Exp[-ik/2/R(x^2+y^2)/2],{x,gx},{y,gy}]
是一个压缩数组。不幸的是,
ParallelTable
首先计算为未打包的数组,这会消耗大量内存和时间。如果我尝试
ParallelTable[Exp[-(x^2+y^2)/w^2],{x,gx},{y,gy}]]
而不使用复杂部分,结果是一个压缩数组。我没有仔细查看代码,但我怀疑
ParallelTable
中的
方法->“粗粒度”
可能会减少由于解包而导致的内存使用。但那可能不是。。。我只是想试试。谢谢,至少在我的家用电脑上,用2个内核似乎可以提高速度和内存开销,但我相信它也会提高工作站的速度。但令人惊讶的是,与在Matlab中实现的相同代码相比,Mathematica计算相同结果所需的时间要长20多个。对于未来的问题,您也可以尝试Mathematica社区更为活跃,几乎没有问题无法回答。哇,惊人的加速!我知道矢量化代码是使用Matlab编写的,但在Mathematica中从未这样使用过。我也对编译代码感到惊讶。非常感谢示例代码和mathematica.stackexchange.com链接。
In[13]:= r2 == r3
Out[13]= False

In[14]:= Max@Abs[r2 - r3]
Out[14]= 5.63627*10^-14