El enfoque más simple es hacer algún tipo de interpolación de spline como sugiere Jim Clay (lineal o de otro tipo). Sin embargo, si tiene el lujo del procesamiento por lotes, y especialmente si tiene un conjunto sobredeterminado de muestras no uniformes, hay un algoritmo de "reconstrucción perfecta" que es extremadamente elegante. Por razones numéricas, puede no ser práctico en todos los casos, pero al menos vale la pena conocerlo conceptualmente. Lo leí por primera vez en este artículo .
El truco consiste en considerar que su conjunto de muestras no uniformes ya ha sido reconstruido a partir de muestras uniformes mediante interpolación sinc . Siguiendo la notación en el documento:
y( t ) = ∑k = 1nortey( k T) pecado( π( t - k T) / T)π( t- k T) / T= ∑k =1nortey(k T) s i n c ( t - k TT) .
Tenga en cuenta que esto proporciona un conjunto de ecuaciones lineales, una para cada muestra no uniforme , donde las incógnitas son las muestras igualmente espaciadas , así:y ( k T )y( t )y( k T)
⎡⎣⎢⎢⎢⎢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)⎤⎦⎥⎥⎥⎥.
En la ecuación anterior, es el número de muestras uniformes desconocidas, es el inverso de la frecuencia de muestreo uniforme, es el número de muestras no uniformes (que pueden ser mayores que ). Al calcular la solución de mínimos cuadrados de ese sistema, se pueden reconstruir las muestras uniformes. Técnicamente, solo se necesitan muestras no uniformes, pero dependiendo de cuán "dispersas" estén en el tiempo, la matriz de interpolación puede estar terriblemente mal acondicionada . Cuando ese es el caso, usar más muestras no uniformes generalmente ayuda.T mnTmnnn
Como ejemplo de juguete, aquí hay una comparación (usando numpy ) entre el método anterior y la interpolación de spline cúbico en una cuadrícula ligeramente nerviosa:
(El código para reproducir la trama anterior se incluye al final de esta respuesta)
Dicho todo esto, para métodos robustos de alta calidad, comenzar con algo en uno de los siguientes documentos probablemente sería más apropiado:
A. Aldroubi y Karlheinz Grochenig, Muestreo no uniforme y reconstrucción en espacios invariables por turnos , SIAM Rev., 2001, no. 4, 585-620. ( enlace pdf ).
K. Grochenig y H. Schwab, Métodos de reconstrucción local rápida para muestreo no uniforme en espacios invariables por desplazamiento , 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()