2009-03-06 5 views
7

На моей 64-битной системе Debian/Lenny (4GByte RAM + 4GByte раздел подкачки), я могу успешно сделать:Есть ли способ уменьшить точность scipy/numpy, чтобы уменьшить потребление памяти?

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-битной точностью и половиной памяти.

ответ

5

Не похоже, что в функциях fft scipy есть какая-либо функция (см. 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 (Resident Set Size) питона был 265MB.

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 GB, так как я free'd до ст.

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

Выполнение:

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

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

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

+1

Спасибо за указатель на функции rfftn; да, они прекрасно выполняют эту работу. Пиковое использование для f = rfftn (v), f = array (f, dtype = np.complex64), f = irfftn (f) - 6224MByte в обратном. (Без промежуточного нажатия на complex64 он использует 7754MByte ... немного туго). – timday

+0

Является ли ваш размер массива на самом деле больше 512^3? Я не уверен, почему вы видите что-то вроде 4x использования ОЗУ, которое я вижу в моем примере кода выше ... – slacy

+0

Пожалуйста, пересмотрите бит, в котором вы говорите: «Точная точность не существует, так как ваше собственное оборудование - это 128-битное» собственное устройство, не более 128 бит, чем 64 бит, и FFTW очень гибко поддерживает оба. Как показывает ответ Дэвида, 'scipy.fftpack.rfft' поддерживает это:' scipy.fftpack.rfft (v.astype (np.float32)). Dtype' возвращает 'float32'. К сожалению, поддержка Numpy отстает от Scipy, даже в 2015 году: https://github.com/numpy/numpy/issues/6012 –

4

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