2010-08-25 3 views
5

У меня есть очень большой массив данных с плавающей точкой изображения:Необъяснимые Mathematica7 DumpSave [] проблема

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 а-ля:

DumpSave["thisWorks.mx", daylightImgd] 

Сбрасывание этого гигантского (861 мегабайт файла) занимает менее 10 секунд. Если я уменьшу эти изображения, a 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 зависает.

Помощь?

UPDATE: Комментарии к ответу Майкла

Wow. Спасибо за очень подробный ответ, который не только ответил на мой вопрос, но и научил меня кучу периферийных вещей.

Для справки, вопрос о упакованности был немного сложнее, чем просто заменить мой downsample [] одним из ваших. Поскольку массив, который я пытался сбросить, представляет собой массив из 18 изображений - трехмерный массив, другими словами - и, поскольку я применяю понижающую дискретизацию с помощью оператора Map, упакованность 3d-массива ложна (согласно PackedArrayQ), используя любую из ваших перезаписных файлов.

Однако, если я беру выход из этих приложений, а затем упаковать результирующий массив 3d, затем весь 3d массив упакован, и только тогда я могу DumpSave его. Странно, однако, этот окончательный процесс упаковки, в то время как необходим для успешного DumpSave, едва ли изменит размер, как сообщает ByteCount. Возможно, это проще в коде:

In[42]:= downsample3[image_, f_] := 
Module[{w, h}, h = Dimensions[image][[1]]; 
    w = Dimensions[image][[2]]; 
    Developer`[email protected][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! *) 

Опять же, спасибо большое.

ответ

6

Без фактических данных обоснованная догадка заключается в том, что причиной большого массива DumpSave s является то, что это так называемый «упакованный массив», то есть массив чисел с плавающей запятой размером в машину, который имеет очень эффективное представление в Mathematica. Ваша функция downsample (из-за использования Table) не возвращает упакованный массив, который намного больше в памяти, потенциально больше, чем даже исходный массив, после того, как он будет уменьшен с дискретизацией 4X. ByteCount может быть наглядным.

Вы можете проверить наличие упакованных массивов с помощью PackedArrayQ и попытаться упаковать распакованный массив с помощью ToPackedArray, как в контексте Developer.

Есть два решения, если мои догадки верны.Одним из них является использование ToPackedArray, как показано ниже:

downsample[image_, f_] := Module[{w, h}, h = Dimensions[image][[1]]; 
    w = Dimensions[image][[2]]; 
    Developer`[email protected][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}] 

Вы также можете быть заинтересованы во всех новых image processing functionality в Mathematica 7.

Надежда, что помогает!

+0

Ничего себе, хороший ответ! Заинтересоваться, если это решает проблему афер. – dreeves

Смежные вопросы