2013-07-27 34 views
7

Tôi muốn biết cách hoạt động của numpy.gradient. Tôi đã sử dụng gradient để thử tính toán vận tốc nhóm (vận tốc nhóm của gói sóng là đạo hàm của các tần số liên quan đến wavenumbers, không phải là nhóm vận tốc). Tôi cho ăn một mảng 3 cột với nó, 2 colums đầu tiên là x và y coords, cột thứ ba là tần số của điểm đó (x, y). Tôi cần phải tính toán gradient và tôi đã mong đợi một vector 2d, là dốc nétTính toán độ dốc với python

df/dx*i+df/dy*j+df/dz*k 

và chức năng của tôi chỉ có một hàm của x và yi đã mong đợi một cái gì đó giống như

df/dx*i+df/dy*j 

Nhưng tôi đã nhận 2 mảng với 3 colums mỗi, tức là 2 vectơ 3d; lúc đầu tôi nghĩ rằng tổng của cả hai sẽ cho tôi véc tơ tôi đã tìm kiếm nhưng thành phần z không biến mất. Tôi hy vọng tôi đã đủ rõ ràng trong lời giải thích của tôi. Tôi muốn biết làm thế nào numpy.gradient hoạt động và nếu đó là sự lựa chọn đúng cho vấn đề của tôi. Nếu không tôi muốn biết nếu có bất kỳ chức năng python khác tôi có thể sử dụng.

gì tôi có nghĩa là: Tôi muốn tính toán gradient của một mảng các giá trị:

data=[[x1,x2,x3]...[x1,x2,x3]] 

nơi x1, x2 là điểm tọa độ trên lưới thống nhất (điểm của tôi về vùng Brillouin) và x3 là giá trị tần số cho điểm đó. Tôi cung cấp cho đầu vào cũng bước cho derivation cho 2 hướng:

stepx=abs(max(unique(data[:,0])-min(unique(data[:,0]))/(len(unique(data[:,0]))-1) 

tương tự cho hướng y. Tôi không xây dựng dữ liệu của mình trên lưới, tôi đã có lưới và đây là lý do tại sao các ví dụ được đưa ra ở đây trong câu trả lời không giúp tôi. Một ví dụ phù hợp hơn nên có một mạng lưới các điểm và các giá trị như một tôi có:

data=[] 
for i in range(10): 
    for j in range(10): 
    data.append([i,j,i**2+j**2]) 

data=array(data,dtype=float) 

gx,gy=gradient(data) 

một điều tôi có thể thêm là lưới của tôi không phải là một hình vuông nhưng có hình dạng của một đa giác là Brillouin vùng của tinh thể 2d.

Tôi đã hiểu rằng numpy.gradient chỉ hoạt động đúng trên một mạng lưới giá trị vuông, chứ không phải những gì tôi đang tìm kiếm. Ngay cả khi tôi tạo dữ liệu của tôi dưới dạng lưới sẽ có nhiều số không bên ngoài đa giác của dữ liệu gốc, điều đó sẽ thêm các vectơ thực sự cao vào gradient của tôi ảnh hưởng đến độ chính xác của tính toán. Mô-đun này dường như với tôi nhiều đồ chơi hơn là một công cụ, nó có những hạn chế nghiêm trọng.

Sự cố được giải quyết bằng từ điển.

+0

Soooo câu hỏi là gì? Bạn nên sử dụng mô-đun nào? Có vấn đề gì không? – Stephan

+0

Câu hỏi là gradient làm gì? Tại sao lại cho tôi 2 vectơ 3d thay vì 1 vector 2d? Do gradient thực sự tính toán thực sự là một gradient? Bởi sản lượng của nó tôi không thể nói. Không nhìn chính xác với tôi. –

+0

Tôi nghĩ rằng nó là rõ ràng, thành phần thứ 3 của đầu vào của tôi là trường vô hướng, mỗi giá trị trên thành phần thứ 3 là giá trị của hàm của tôi cho mỗi điểm (x, y). –

Trả lời

22

Bạn cần cung cấp gradient ma trận mô tả các giá trị tần số góc cho các điểm (x,y) của mình. ví dụ.

def f(x,y): 
    return np.sin((x + y)) 
x = y = np.arange(-5, 5, 0.05) 
X, Y = np.meshgrid(x, y) 
zs = np.array([f(x,y) for x,y in zip(np.ravel(X), np.ravel(Y))]) 
Z = zs.reshape(X.shape) 

gx,gy = np.gradient(Z,0.05,0.05) 

Bạn có thể thấy rằng âm mưu Z như một bề mặt cho:

sinxpy

Sau đây là cách để giải thích gradient của bạn:

gx là một ma trận cung cấp cho sự thay đổi dz/dx ở tất cả điểm. ví dụ. gx [0] [0] là dz/dx tại (x0,y0).Hình dung gx giúp trong việc tìm hiểu:

gx

Kể từ dữ liệu của tôi được tạo ra từ f(x,y) = sin(x+y) gy trông giống nhau.

Dưới đây là một ví dụ rõ ràng hơn bằng f(x,y) = sin(x) ...

f (x, y) enter image description here

và gradient

g2

g1

cập nhật Hãy xem các cặp xy.

Đây là mã tôi đã sử dụng:

def f(x,y): 
    return np.sin(x) 
x = y = np.arange(-3,3,.05) 
X, Y = np.meshgrid(x, y) 
zs = np.array([f(x,y) for x,y in zip(np.ravel(X), np.ravel(Y))]) 
xy_pairs = np.array([str(x)+','+str(y) for x,y in zip(np.ravel(X), np.ravel(Y))]) 
Z = zs.reshape(X.shape) 
xy_pairs = xy_pairs.reshape(X.shape) 

gy,gx = np.gradient(Z,.05,.05) 

Bây giờ chúng ta có thể tìm và xem chính xác những gì đang xảy ra. Giả sử chúng tôi muốn biết điểm nào được liên kết với giá trị tại Z[20][30]? Sau đó ...

>>> Z[20][30] 
-0.99749498660405478 

Và điểm mấu chốt là

>>> xy_pairs[20][30] 
'-1.5,-2.0' 

Có phải như vậy phải không? Hãy kiểm tra.

>>> np.sin(-1.5) 
-0.99749498660405445 

Có.

Và các thành phần gradient của chúng tôi tại điểm đó là gì?

>>> gy[20][30] 
0.0 
>>> gx[20][30] 
0.070707731517679617 

Làm những việc đó?

dz/dy always 0 kiểm tra. dz/dx = cos(x) và ...

>>> np.cos(-1.5) 
0.070737201667702906 

Có vẻ tốt.

Bạn sẽ nhận thấy chúng không chính xác, đó là vì dữ liệu Z của tôi không liên tục, có kích thước bước là 0.05gradient chỉ có thể ước tính tỷ lệ thay đổi.

+0

Lưới đã có trong tệp mà tôi cung cấp cho numpy.gradient. Tôi không thể tính toán hàm như bạn đã làm vì tôi không biết phương trình. Tôi nhận được những giá trị đó từ một phép tính initio ab. Và một lần nữa: tôi không biết tại sao tôi nên có 2 véc tơ 3d khi cho một gradient 2 biến chức năng là một vector 2d ... –

+1

Chức năng của tôi là một phần của ví dụ giả tạo, một phương tiện để tạo ra dữ liệu Z. Bạn nói trong câu hỏi của bạn, bạn có dữ liệu 'x, y, z', vì vậy bạn không cần một hàm ... chỉ cần tạo Z một cách thích hợp với dữ liệu tần số của bạn. 'gx' và' gy' đưa ra các dẫn xuất 'x' và' y' cho mọi điểm trong Z, phải là một ma trận 'X' bởi' Y'. – seth

+0

Tôi đã cố gắng làm những gì bạn đã làm trong ví dụ của bạn nhưng gradient vẫn cho tôi 2 vectơ 3-d ... Tính toán initio cho tôi 8 tần số cho mỗi điểm (đó là một mối quan hệ phân tán phonon) lưới là một mẫu của vùng brillouin . Không biết làm thế nào để làm cho Z một cách thích hợp, nó phải đã được thích hợp ... Có lẽ gradient chỉ đơn giản là không tính toán gradient? Tôi thử với x ** 2 + y ** 2, gradiend nên là 2d vector: (2x, 2y), nhưng tôi vẫn nhận được 2 3-d vectơ. Làm thế nào tôi có thể có được gradient thực từ đầu ra như vậy? –