2016-05-09 22 views
5

Cho một tập hợp các điểm trong tọa độ (X, Y, Z). , Tôi muốn có thể nội suy các giá trị Z ở các tọa độ tùy ý (X, Y). Tôi đã tìm thấy một số thành công bằng cách sử dụng mlab.griddata cho các giá trị nội suy trên một lưới, nhưng tôi muốn có thể gọi một hàm sử dụng chung cho bất kỳ tọa độ (X, Y) nào.Cho một tập hợp các điểm được xác định trong tọa độ (X, Y, Z), nội suy Z-giá trị tùy ý (X, Y)

Tập hợp các điểm tạo thành bề mặt gần như bán cầu. Để đơn giản hóa vấn đề, tôi đang cố gắng viết một phương thức nội suy các giá trị giữa các điểm đã biết của bán cầu được xác định bởi các tọa độ x, y và z bên dưới. Mặc dù có một giải pháp phân tích để tìm z = f (x, y) cho một hình cầu hoàn hảo, vì vậy bạn không cần phải nội suy, tập hợp điểm thực tế sẽ không phải là một hình cầu hoàn hảo, vì vậy chúng ta nên giả định rằng chúng ta cần để nội suy các giá trị tại các tọa độ chưa biết (X, Y). Link to IPython notebook with point data

resolution = 10 
u = np.linspace(-np.pi/2, np.pi/2, resolution) 
v = np.linspace(0, np.pi, resolution) 

U, V = np.meshgrid(u, v) 

xs = np.sin(U) * np.cos(V) 
ys = np.sin(U) * np.sin(V) 
zs = np.cos(U) 

tôi đã được sử dụng scipy.interpolate.interp2d, mà "trả về một chức năng mà gọi phương thức sử dụng nội suy spline để tìm giá trị của các điểm mới."

def polar(xs, ys, zs, resolution=10): 
    rs = np.sqrt(np.multiply(xs, xs) + np.multiply(ys, ys)) 
    ts = np.arctan2(ys, xs) 
    func = interp2d(rs, ts, zs, kind='cubic') 
    vectorized = np.vectorize(func) 

    # Guesses 
    ri = np.linspace(0, rs.max(), resolution) 
    ti = np.linspace(0, np.pi * 2, resolution) 

    R, T = np.meshgrid(ri, ti) 
    Z = vectorized(R, T) 
    return R * np.cos(T), R * np.sin(T), Z 

Rất tiếc, tôi nhận được kết quả khá lạ, tương tự như một StackOverflow khác user who tried to use interp2d.

Polar result

Sự thành công nhất mà tôi đã tìm thấy cho đến nay đang sử dụng inverse squares để ước tính giá trị của Z (X, Y). Nhưng hàm này không hoàn hảo để ước tính giá trị của Z gần Z = 0.

Inverse Squares result

Tôi có thể làm gì để có được một hàm z = f(x, y) cung cấp một tập hợp các điểm trong (x, y, z)? Tôi có thiếu một cái gì đó ở đây ... tôi cần nhiều hơn một đám mây điểm để ước tính đáng tin cậy một giá trị trên một bề mặt?

EDIT:

Đây là chức năng mà tôi đã kết thúc bằng văn bản. Hàm này lấy các mảng đầu vào là xs, ys, zs và nội suy tại x, y sử dụng scipy.interpolate.griddata, không yêu cầu lưới thường xuyên. Tôi chắc chắn có một cách thông minh hơn để làm điều này và sẽ đánh giá cao mọi cập nhật, nhưng nó hoạt động và tôi không quan tâm đến hiệu suất. Bao gồm một đoạn trong trường hợp nó giúp bất cứ ai trong tương lai.

def interpolate(x, y, xs, ys, zs): 
    r = np.sqrt(x*x + y*y) 
    t = np.arctan2(y, x) 

    rs = np.sqrt(np.multiply(xs, xs) + np.multiply(ys, ys)) 
    ts = np.arctan2(ys, xs) 

    rs = rs.ravel() 
    ts = ts.ravel() 
    zs = zs.ravel() 

    ts = np.concatenate((ts - np.pi * 2, ts, ts + np.pi * 2)) 
    rs = np.concatenate((rs, rs, rs)) 
    zs = np.concatenate((zs, zs, zs)) 


    Z = scipy.interpolate.griddata((rs, ts), zs, (r, t)) 
    Z = Z.ravel() 
    R, T = np.meshgrid(r, t) 
    return Z 
+0

Sử dụng học máy. :) – erip

+0

bạn đã thử scipy.interpolate.LinearNDInterpolator chưa? Tôi có kinh nghiệm tốt với nó cho những loại vấn đề này –

Trả lời

2

Bạn đang nói rằng bạn đã thử sử dụng griddata. Vậy tại sao điều đó không hiệu quả? griddata cũng hoạt động nếu các điểm mới không được đặt cách nhau thường xuyên.Ví dụ:

# Definitions of xs, ys and zs 
nx, ny = 20, 30 
x = np.linspace(0, np.pi, nx) 
y = np.linspace(0, 2*np.pi, ny) 

X,Y = np.meshgrid(x, y) 

xs = X.reshape((nx*ny, 1)) 
ys = Y.reshape((nx*ny, 1)) 

## Arbitrary definition of zs 
zs = np.cos(3*xs/2.)+np.sin(5*ys/3.)**2 

## new points where I want the interpolations 
points = np.random.rand(1000, 2) 

import scipy.interpolate 
zs2 = scipy.interpolate.griddata(np.hstack((xs, ys)), zs, points) 

Đây không phải là những gì bạn đang theo dõi?

+0

Có, tính năng này hoạt động. Cảm ơn bạn! Tôi muốn thực hiện một nơi mà tôi có thể nhận được hàm gọi bên dưới (như giá trị trả về của interp2d) và chuyển vào một điểm tại một thời điểm, nhưng tôi luôn có thể cấu trúc lại mã khác để truyền vào mảng (X, Y). –

1

Nếu tôi hiểu câu hỏi của bạn, bạn có điểm xs, ys, zs được định nghĩa bởi

xs = np.sin(U) * np.cos(V) 
ys = np.sin(U) * np.sin(V) 
zs = np.cos(U) 

gì bạn muốn là để có thể suy và tìm thấy một giá trị z cho một định x và y? Tại sao bạn cần nội suy? Các phương trình trên đại diện cho một hình cầu, chúng có thể được viết lại như xs*xs + ys*ys + zs*zs = 1, do đó là một giải pháp phân tích đơn giản cho vấn đề này:

def Z(X, Y): 
    return np.sqrt(1-X**2-Y**2) 
    ## or return -np.sqrt(1-X**2-Y**2) since this equation has two solutions 

trừ khi tôi hiểu lầm câu hỏi.

+0

Ah, để làm rõ, tập hợp các điểm là gần như bán cầu, vì vậy giải pháp phân tích sẽ không nhất thiết phải đúng. Tôi sẽ chỉnh sửa câu hỏi của mình để bao gồm ... –

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