Pendekatan paling sederhana adalah dengan melakukan semacam interpolasi spline seperti yang disarankan Jim Clay (linier atau lainnya). Namun, jika Anda memiliki kemewahan pemrosesan batch, dan terutama jika Anda memiliki set sampel tidak seragam yang ditentukan secara berlebihan, ada algoritma "rekonstruksi sempurna" yang sangat elegan. Untuk alasan numerik, mungkin tidak praktis dalam semua kasus, tetapi setidaknya perlu diketahui secara konseptual. Saya pertama kali membacanya di makalah ini .
Caranya adalah dengan mempertimbangkan set sampel tidak seragam Anda yang telah direkonstruksi dari sampel yang seragam melalui interpolasi tulus . Mengikuti notasi di koran:
y(t)=∑k=1Ny(kT)sin(π(t−kT)/T)π(t−kT)/T=∑k=1Ny(kT)sinc(t−kTT).
Perhatikan bahwa ini menyediakan satu set persamaan linear, satu untuk setiap sampel tidak seragam , di mana yang tidak diketahui adalah sampel dengan spasi yang sama , seperti:y(t)y(kT)
⎡⎣⎢⎢⎢⎢y(t0)y(t1)⋯y(tm)⎤⎦⎥⎥⎥⎥=⎡⎣⎢⎢⎢⎢⎢⎢sinc(t0−TT)sinc(t1−TT)⋯sinc(tm−TT)sinc(t0−2TT)sinc(t1−2TT)⋯sinc(tm−2TT)⋯⋯⋯⋯sinc(t0−nTT)sinc(t1−nTT)⋯sinc(tm−nTT)⎤⎦⎥⎥⎥⎥⎥⎥⎡⎣⎢⎢⎢⎢y(T)y(2T)⋯y(nT)⎤⎦⎥⎥⎥⎥.
Dalam persamaan di atas, adalah jumlah sampel seragam yang tidak diketahui, adalah kebalikan dari laju sampel seragam, dan adalah jumlah sampel tidak seragam (yang mungkin lebih besar dari ). Dengan menghitung solusi kuadrat terkecil dari sistem itu, sampel yang seragam dapat direkonstruksi. Secara teknis, hanya sampel tidak seragam yang diperlukan, tetapi tergantung pada seberapa "tersebar" mereka dalam waktu, matriks interpolasi mungkin sangat buruk dikondisikan . Ketika itu masalahnya, menggunakan lebih banyak sampel yang tidak seragam biasanya membantu.nTmnn
Sebagai contoh mainan, inilah perbandingan (menggunakan numpy ) antara metode di atas dan interpolasi spline kubik pada kisi yang agak gugup:
(Kode untuk mereproduksi plot di atas termasuk di akhir jawaban ini)
Semua yang dikatakan, untuk metode berkualitas tinggi, kuat, dimulai dengan sesuatu di salah satu makalah berikut mungkin akan lebih tepat:
A. Aldroubi dan Karlheinz Grochenig, Pengambilan sampel dan rekonstruksi yang tidak seragam dalam ruang-ruang yang tidak berubah , SIAM Rev., 2001, no. 4, 585-620. ( tautan pdf ).
K. Grochenig dan H. Schwab, Metode rekonstruksi lokal cepat untuk pengambilan sampel tidak seragam di ruang shift-invariant , SIAM J. Matrix Anal. Appl., 24 (2003), 899-913.
-
import numpy as np
import pylab as py
import scipy.interpolate as spi
import numpy.random as npr
import numpy.linalg as npl
npr.seed(0)
class Signal(object):
def __init__(self, x, y):
self.x = x
self.y = y
def plot(self, title):
self._plot(title)
py.plot(self.x, self.y ,'bo-')
py.ylim([-1.8,1.8])
py.plot(hires.x,hires.y, 'k-', alpha=.5)
def _plot(self, title):
py.grid()
py.title(title)
py.xlim([0.0,1.0])
def sinc_resample(self, xnew):
m,n = (len(self.x), len(xnew))
T = 1./n
A = np.zeros((m,n))
for i in range(0,m):
A[i,:] = np.sinc((self.x[i] - xnew)/T)
return Signal(xnew, npl.lstsq(A,self.y)[0])
def spline_resample(self, xnew):
s = spi.splrep(self.x, self.y)
return Signal(xnew, spi.splev(xnew, s))
class Error(Signal):
def __init__(self, a, b):
self.x = a.x
self.y = np.abs(a.y - b.y)
def plot(self, title):
self._plot(title)
py.plot(self.x, self.y, 'bo-')
py.ylim([0.0,.5])
def grid(n): return np.linspace(0.0,1.0,n)
def sample(f, x): return Signal(x, f(x))
def random_offsets(n, amt=.5):
return (amt/n) * (npr.random(n) - .5)
def jittered_grid(n, amt=.5):
return np.sort(grid(n) + random_offsets(n,amt))
def f(x):
t = np.pi * 2.0 * x
return np.sin(t) + .5 * np.sin(14.0*t)
n = 30
m = n + 1
# Signals
even = sample(f, np.r_[1:n+1] / float(n))
uneven = sample(f, jittered_grid(m))
hires = sample(f, grid(10*n))
sinc = uneven.sinc_resample(even.x)
spline = uneven.spline_resample(even.x)
sinc_err = Error(sinc, even)
spline_err = Error(spline, even)
# Plot Labels
sn = lambda x,n: "%sly Sampled (%s points)" % (x,n)
r = lambda x: "%s Reconstruction" % x
re = lambda x: "%s Error" % r(x)
plots = [
[even, sn("Even", n)],
[uneven, sn("Uneven", m)],
[sinc, r("Sinc")],
[sinc_err, re("Sinc")],
[spline, r("Cubic Spline")],
[spline_err, re("Cubic Spline")]
]
for i in range(0,len(plots)):
py.subplot(3, 2, i+1)
p = plots[i]
p[0].plot(p[1])
py.show()