难以理解的Mathematica7 DumpSave []问题

时间:2010-08-25 16:35:00

标签: wolfram-mathematica

我有一个非常大的浮点图像数据:

In[25]:= Dimensions[daylightImgd]
Out[25]= {18, 2002, 2989}

In[26]:= daylightImgd[[1, 1]][[1 ;; 10]]

Out[26]= {0.0122293, 0.0104803, 0.0103955, 0.0115533, 0.0118063, \
0.0120648, 0.0122957, 0.011398, 0.0117426, 0.0119997}

我可以使用DumpSave a la:

成功将整个图像阵列保存到磁盘
DumpSave["thisWorks.mx", daylightImgd]

倾倒这个巨人(861兆字节文件)只需不到10秒。如果我对这些图像进行缩减采样,则la:

downsample[image_, f_] := Module[{w, h}, h = Dimensions[image][[1]];
  w = Dimensions[image][[2]];
  Table[image[[i, j]], {i, 1, h, f}, {j, 1, w, f}]]

In[26]:= daylightImgdDown = downsample[#, 4] & /@ daylightImgd;
In[27]:= Dimensions[daylightImgdDown]
Out[27]= {18, 500, 748}

In[28]:= daylightImgdDown[[1, 1]][[1 ;; 10]]

Out[28]= {0.0122293, 0.0118063, 0.0117426, 0.0119349, 0.0109443, \
0.0121632, 0.0121304, 0.00681408, 0.0101728, 0.00603242}

突然间我不能再倾倒了;这东西永远挂起并旋转 - 或者至少持续很长时间,直到我杀死它并且最大化CPU:

In[31]:= DumpSave["broken.mx", daylightImgdDown];    (* Hangs forever *)

据我所知,一切都是应有的:下采样图像具有正确的尺寸;你可以通过ArrayPlot绘制它们,一切看起来都很棒;手动列出第一行看起来很好。简而言之,所有内容都与非下采样图像相同,但在DumpSave悬挂的小得多的数据集上。

帮助?

更新:对迈克尔回答的评论

哇。感谢您提供了非常彻底的答案,这不仅回答了我的问题,而且还教会了我一些外围的东西。

供你参考,pack-ness的问题比用你的一个替换我的下行样本[]有点棘手。由于我试图转储的数组是一个包含18个图像的数组 - 换句话说是一个3d数组 - 而且由于我通过Map运算符应用了下采样,因此3d数组的打包错误(根据PackedArrayQ) )使用你的任何一个下采样重写。

但是,如果我获取这些应用程序的输出,然后打包生成的3d数组,然后整个3d数组被打包,只有才能我DumpSave它。奇怪的是,正如ByteCount所报告的那样,这个最终的打包过程虽然是成功的DumpSave所必需的,但似乎几乎没有改变尺寸。也许这在代码中更容易:

In[42]:= downsample3[image_, f_] := 
 Module[{w, h}, h = Dimensions[image][[1]];
  w = Dimensions[image][[2]];
  Developer`ToPackedArray@Table[image[[i, j]], {i, 1, h, f}, {j, 1, w, f}]]

In[43]:= daylightImgdDown = downsample3[#, downsampleSize] & /@ daylightImgd;
In[44]:= ByteCount[daylightImgdDown]
Out[44]= 53966192

In[45]:= Developer`PackedArrayQ[daylightImgdDown]
Out[45]= False

In[46]:= dd = Developer`ToPackedArray[daylightImgdDown];
In[47]:= Developer`PackedArrayQ[dd]
Out[47]= True

In[48]:= ByteCount[dd]
Out[48]= 53963844

In[49]:= DumpSave["daylightImgdDown.mx", dd]; (* works now! *)

再次,非常感谢。

1 个答案:

答案 0 :(得分:6)

没有实际数据,一个有根据的猜测是大型数组DumpSave快速的原因是因为它是一个所谓的“打包数组”,即一个机器大小的浮点数的数组在Mathematica中具有非常有效的表示。您的downsample函数(由于使用Table)不会返回打包数组,该数组在内存中要大得多,在下采样4X后可能会比原始数组更大。 ByteCount可能就是那里的例子。

您可以使用PackedArrayQ检查packed-array-ness,并尝试使用ToPackedArray打包一个解压缩的数组,这两个数组都位于Developer上下文中。

如果我的猜测是正确的,有两种解决方案。一种是使用ToPackedArray,如下所示:

downsample[image_, f_] := Module[{w, h}, h = Dimensions[image][[1]];
  w = Dimensions[image][[2]];
  Developer`ToPackedArray@Table[image[[i, j]], {i, 1, h, f}, {j, 1, w, f}]]

更好的是简单地将Table替换为Take,在这种情况下应该返回一个打包数组,并且比使用Table要快得多。

downsample[image_, f_] := Take[image, {1,-1,f}, {1,-1,f}]

您可能也对Mathematica 7中的所有新image processing functionality感兴趣。

希望有所帮助!