Nas*_*ser 6 wolfram-mathematica
我之前没有使用过PackedArray,但是今天就开始考虑使用它们来阅读它们.
我所拥有的是所有实数的大尺寸1D和2D矩阵,没有符号(它是有限差分PDE求解器),所以我认为我应该利用PackedArray.
我有一个初始化函数,我分配所需的所有数据/网格.所以我去ToPackedArray了他们.它似乎更快一点,但我需要做更多的性能测试,以更好地比较前后的速度,并比较RAM的使用情况.
但是当我看到这个时,我注意到M中的一些操作已经自动返回PackedArray中的列表,而有些则没有.
例如,这不会返回打包数组
a = Table[RandomReal[], {5}, {5}];
Developer`PackedArrayQ[a]
Run Code Online (Sandbox Code Playgroud)
但这样做
a = RandomReal[1, {5, 5}];
Developer`PackedArrayQ[a]
Run Code Online (Sandbox Code Playgroud)
这样做
a = Table[0, {5}, {5}];
b = ListConvolve[ {{0, 1, 0}, {1, 4, 1}, {0, 1, 1}}, a, 1];
Developer`PackedArrayQ[b]
Run Code Online (Sandbox Code Playgroud)
并且矩阵乘法确实在打包数组中返回结果
a = Table[0, {5}, {5}];
b = a.a;
Developer`PackedArrayQ[b]
Run Code Online (Sandbox Code Playgroud)
但元素乘法不是
b = a*a;
Developer`PackedArrayQ[b]
Run Code Online (Sandbox Code Playgroud)
我的问题:是否有一个列表哪个文件哪个M命令返回PackedArray而不是?(假设数据符合要求,例如Real,不混合,没有符号等.)
另外,一个小问题,你认为在调用ToPackedArray它之前首先检查创建的列表/矩阵是否已经打包会更好吗?我认为呼叫ToPackedArray已经打包的列表不会花费任何费用,因为呼叫将立即返回.
谢谢,
更新(1)
只是想提一下,刚发现在演示CDF中不允许使用PackedArray符号,因为我在上传一个时遇到错误.所以,不得不删除我的所有包装代码.由于我主要编写演示,现在这个主题对我来说只是学术兴趣.但是要感谢大家的时间和好的答案.
没有全面的清单.指出一些事情:
In[66]:= a = RandomReal[1, {5, 5}];
In[67]:= Developer`PackedArrayQ /@ {a, a.a, a*a}
Out[67]= {True, True, True}
请注意,我的版本(8.0.4)没有解包为逐元素乘法.
是否Table会导致打包数组取决于元素的数量:
In[71]:= Developer`PackedArrayQ[Table[RandomReal[], {24}, {10}]]
Out[71]= False
In[72]:= Developer`PackedArrayQ[Table[RandomReal[], {24}, {11}]]
Out[72]= True
In[73]:= Developer`PackedArrayQ[Table[RandomReal[], {25}, {10}]]
Out[73]= True
On["Packing"] 当打开包装时,会打开消息让你知道:
In[77]:= On["Packing"]
In[78]:= a = RandomReal[1, 10];
In[79]:= Developer`PackedArrayQ[a]
Out[79]= True
In[80]:= a[[1]] = 0 (* force unpacking due to type mismatch *)
Developer`FromPackedArray::punpack1: Unpacking array with dimensions {10}. >>
Out[80]= 0
In[81]:= a = RandomReal[1, 10];
In[82]:= Position[a, Max[a]]
Developer`FromPackedArray::unpack: Unpacking array in call to Position. >>
Out[82]= {{4}}
ToPackedArray已打包列表的罚款足够小,我不会太担心它:
In[90]:= a = RandomReal[1, 10^7];
In[91]:= Timing[Do[Identity[a], {10^5}];]
Out[91]= {0.028089, Null}
In[92]:= Timing[Do[Developer`ToPackedArray[a], {10^5}];]
Out[92]= {0.043788, Null}
Dynamic和Manipulate:
In[97]:= Developer`PackedArrayQ[{1}]
Out[97]= False
In[98]:= Dynamic[Developer`PackedArrayQ[{1}]]
Out[98]= True
这只是Brett答案的附录:
SystemOptions["CompileOptions"]
Run Code Online (Sandbox Code Playgroud)
将为您提供函数将返回打包数组的长度.因此,如果您确实需要打包一个小列表,作为使用的替代方法,Developer`ToPackedArray您可以暂时为其中一个编译选项设置较小的数字.例如
SetSystemOptions["CompileOptions" -> {"TableCompileLength" -> 20}]
Run Code Online (Sandbox Code Playgroud)
还要注意一些功能之间的差异对我来说至少看起来并不直观,所以每当我使用它们时我通常都要测试这些东西,而不是本能地知道什么是最好的:
f = # + 1 &;
g[x_] := x + 1;
data = RandomReal[1, 10^6];
On["Packing"]
Timing[Developer`PackedArrayQ[f /@ data]]
{0.131565, True}
Timing[Developer`PackedArrayQ[g /@ data]]
Developer`FromPackedArray::punpack1: Unpacking array with dimensions {1000000}.
{1.95083, False}
Run Code Online (Sandbox Code Playgroud)