Необъяснимая проблема Mathematica7 DumpSave [] - PullRequest
5 голосов
/ 25 августа 2010

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

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 секунд.Если я уменьшу выборку этих изображений, а-ля:

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}

Тогда вдруг я не смогу больше сохранять дамп;эта вещь зависает и вращается навсегда - или, по крайней мере, в течение многих минут, пока я ее не убью, и максимально увеличивает процессор:

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

Насколько я могу определить, все так и должно быть: изображения с пониженной выборкойиметь правильные размеры;Вы можете построить их через ArrayPlot, и все выглядит отлично;вручную перечисление первого ряда выглядит нормально.Короче говоря, все выглядит так же, как и с изображениями без дискретизации, но в гораздо меньшем наборе данных DumpSave зависает.

Справка?

ОБНОВЛЕНИЕ: Комментарии к ответу Майкла

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

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

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

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 Ответ

6 голосов
/ 25 августа 2010

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

Вы можете проверить наличие упакованного массива с помощью PackedArrayQ и попытаться упаковать распакованный массив с помощью 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.

Надеюсь, это поможет!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...