Есть ли способ уменьшить точность scipy / numpy, чтобы уменьшить потребление памяти?

StackOverflow https://stackoverflow.com/questions/620428

Вопрос

В моей 64-битной системе Debian / Lenny (раздел подкачки 4 Гбайт + раздел подкачки 4 Гбайт) я могу успешно выполнить следующие действия:

v=array(10000*random([512,512,512]),dtype=np.int16)
f=fftn(v)

но с f, являющимся np.complex128 , потребление памяти шокирует, и я не могу сделать намного больше с результатом (например, модулировать коэффициенты и затем f = ifftn (f ) ) без отслеживания MemoryError .

Вместо того, чтобы устанавливать больше оперативной памяти и / или расширять разделы подкачки, есть какой-то способ управления scipy / numpy " точность по умолчанию " и вместо этого он вычисляет массив complex64?

Я знаю, что потом могу просто уменьшить его с помощью f = array (f, dtype = np.complex64) ; Я хочу, чтобы он действительно выполнял работу FFT с 32-битной точностью и половиной памяти.

Это было полезно?

Решение

Не похоже, что есть какая-либо функция, делающая это в функциях fft Сципи (см. http://www.astro.rug.nl/efidad/scipy.fftpack.basic.html ).

Если вы не можете найти библиотеку FFT с фиксированной запятой для python, маловероятно, что нужная функция существует, поскольку ваш собственный аппаратный формат с плавающей запятой имеет 128 бит. Похоже, вы могли бы использовать метод rfft, чтобы получить только компоненты с реальной стоимостью (без фазы) БПФ, и это сэкономило бы половину вашей оперативной памяти.

Я запустил следующее в интерактивном питоне:

>>> from numpy import *
>>>  v = array(10000*random.random([512,512,512]),dtype=int16)
>>> shape(v)
(512, 512, 512)
>>> type(v[0,0,0])
<type 'numpy.int16'>

На данный момент RSS (размер резидентного набора) python был 265 МБ.

f = fft.fft(v)

И на данный момент RSS-версия Python 2.3GB.

>>> type(f)
<type 'numpy.ndarray'>
>>> type(f[0,0,0]) 
<type 'numpy.complex128'>
>>> v = []

И на этом этапе RSS уменьшается до 2,0 ГБ, так как у меня есть бесплатная версия v.

Использование " fft.rfft (v) " для вычисления реальных значений получаются только 1,3 ГБ RSS. (почти половина, как и ожидалось)

Делать:

>>> f = complex64(fft.fft(v))

Это худший из двух миров, поскольку сначала он вычисляет версию complex128 (2,3 ГБ), а затем копирует ее в версию complex64 (1,3 ГБ), что означает, что пиковое значение RSS на моей машине составляло 3,6 ГБ, а затем установилось до 1,3 ГБ снова.

Я думаю, что если у вас 4 ГБ ОЗУ, все должно работать нормально (как и у меня). В чем проблема?

Другие советы

Scipy 0.8 будет поддерживать одинарную точность почти для всего кода fft (код уже находится в стволе, поэтому вы можете установить scipy из svn, если вам нужна эта функция сейчас).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top