2009-03-06 34 views
7

Ngày 64-bit hệ thống Debian/Lenny của tôi (phân vùng swap 4GByte RAM + 4GByte) Tôi thành công có thể làm:Có cách nào để giảm độ chính xác scipy/numpy để giảm mức tiêu thụ bộ nhớ không?

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

nhưng với f là một np.complex128 tiêu thụ bộ nhớ là gây sốc, và tôi không thể làm được gì nhiều nhiều hơn với kết quả (ví dụ: điều chỉnh các hệ số và sau đó là f=ifftn(f)) mà không cần truy nguyên MemoryError.

Thay vì cài đặt thêm RAM và/hoặc mở rộng phân vùng trao đổi, có cách nào để kiểm soát độ chính xác mặc định của "scipy/numpy" và có tính toán mảng phức64 không?

Tôi biết tôi chỉ có thể giảm sau đó với f=array(f,dtype=np.complex64); Tôi đang tìm cách để nó thực sự làm công việc FFT trong chính xác 32-bit và một nửa bộ nhớ.

Trả lời

5

Dường như không có chức năng nào để thực hiện việc này trong các chức năng fip của scipy (xem http://www.astro.rug.nl/efidad/scipy.fftpack.basic.html).

Trừ khi bạn có thể tìm thư viện FFT điểm cố định cho python, không chắc rằng hàm bạn muốn tồn tại, vì định dạng điểm nổi phần cứng gốc của bạn là 128 bit. Nó trông giống như bạn có thể sử dụng phương pháp rfft để có được chỉ các thành phần có giá trị thực (không pha) của FFT, và điều đó sẽ tiết kiệm được một nửa RAM của bạn.

Tôi chạy sau trong python tương tác:

>>> 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'> 

Tại thời điểm này RSS (trú Set Size) của python là 265MB.

f = fft.fft(v) 

Và tại thời điểm này, RSS của python 2.3GB.

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

Và vào thời điểm này RSS đi xuống đến 2.0GB, vì tôi đã free'd lên v.

Sử dụng "fft.rfft (v)" để tính giá trị thực chỉ dẫn một RSS 1.3GB. (Gần một nửa, như mong đợi)

Làm:

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

là điều tồi tệ nhất của cả hai thế giới, kể từ khi nó lần đầu tiên tính phiên bản complex128 (2.3GB) và sau đó bản đó vào phiên bản complex64 (1,3GB) có nghĩa là RSS đỉnh trên máy tính của tôi là 3.6GB, và sau đó nó được giải quyết xuống 1.3GB một lần nữa.

Tôi nghĩ rằng nếu bạn có RAM 4GB, điều này tất cả chỉ hoạt động tốt (như tôi làm). Vấn đề là gì?

+1

Cảm ơn con trỏ tới các hàm rfftn; có những người làm công việc độc đáo. Sử dụng đỉnh cho f = rfftn (v), f = mảng (f, dtype = np.complex64), f = irfftn (f) là 6224MByte theo nghịch đảo. (Nếu không có dàn diễn viên trung gian đến phức tạp64 nó sử dụng 7754MByte ... hơi chặt). – timday

+0

Kích thước mảng sản xuất của bạn có thực sự lớn hơn 512^3 không? Tôi không chắc chắn lý do tại sao bạn nhìn thấy một cái gì đó như 4x sử dụng RAM mà tôi thấy trong mã ví dụ của tôi ở trên ... – slacy

+0

Vui lòng sửa lại bit mà bạn nói 'độ chính xác đơn không tồn tại vì phần cứng gốc của bạn là 128 bit' — phần cứng gốc không có 128 bit hơn 64 bit và FFTW rất linh hoạt trong việc hỗ trợ cả hai. Như câu trả lời của David cho thấy, 'scipy.fftpack.rfft' hỗ trợ điều này:' scipy.fftpack.rfft (v.astype (np.float32)). Dtype' trả về 'float32'. Thật không may, hỗ trợ Numpy là tụt lại phía sau Sciper, ngay cả trong năm 2015: https://github.com/numpy/numpy/issues/6012 –

4

Scipy 0.8 sẽ có hỗ trợ chính xác duy nhất cho hầu như tất cả mã fft (Mã đã có trong thân cây, vì vậy bạn có thể cài đặt scipy từ svn nếu bạn cần tính năng ngay bây giờ).

Các vấn đề liên quan