Estoy tratando de calcular los momentos de Zernike de orden superior (p. Ej. m=0
, n=46
) Para alguna imagen. Sin embargo, me encuentro con un problema con respecto al polinomio radial (ver wikipedia ). Este es un polinomio definido en el intervalo [0 1]. Ver el código MATLAB a continuación
function R = radial_polynomial(m,n,RHO)
R = 0;
for k = 0:((n-m)/2)
R = R + (-1).^k.*factorial(n-k) ...
./ ( factorial(k).*factorial((n+m)./2-k) .* factorial((n-m)./2-k) ) ...
.*RHO.^(n-2.*k);
end
end
Sin embargo, esto obviamente tiene problemas numéricos cercanos RHO > 0.9
.
Traté de refactorizarlo para polyval
pensar que podría tener algunos mejores algoritmos detrás de escena, pero eso no resolvió nada. La conversión a un cálculo simbólico creó el gráfico deseado, pero fue increíblemente lento incluso para un gráfico simple como se muestra.
¿Existe una forma numéricamente estable de evaluar tales polinomios de alto orden?
matlab
polynomials
numerical-limitations
Sanchises
fuente
fuente
Respuestas:
Esto se implementa en el siguiente script de Octave:
1.4e-10
fuente
jacobiPD
, no como una cancelación catastrófica genérica.JacobiPD
6.9e-13
JacobiPD
factorial(n+a) * factorial(n+b)
1/(factorial(s)*factorial(n+a-s)*factorial(b+s)*factorial(n-s)) * ((x-1)/2).^(n-s).*((x+1)/2).^s * factorial(n+a) * factorial(n+b)
1.4e18
-2.1
Una posible solución (sugerida por @gammatester) es usar polinomios de Jacobi. Esto evita el problema de la cancelación catastrófica al agregar los grandes coeficientes polinómicos mediante una evaluación polinómica "ingenua".
El polinomio radial de Zernike se puede expresar mediante los polinomios de Jacobi de la siguiente manera (ver ecuación (6) )
Sin embargo, en MATLAB, el uso de
jacobiP(n,a,b,x)
es inaceptablemente lento para grandes vectores / matrices dex=rho
. LajacobiP
función es en realidad parte de la Caja de herramientas simbólica, y la evaluación del polinomio se difiere al motor simbólico, que intercambia velocidad por precisión arbitraria. Por lo tanto, es necesaria una implementación manual de los polinomios de Jacobi.En MATLAB, esto se traduce en (Jacobi
p olice d epartmentP olynomial, implementación ' D ' doble ')El polinomio radial real de Zernike es así (para
m=abs(m)
)Nota: esta auto respuesta es solo una solución práctica; siéntase libre de etiquetar otra respuesta que explique por qué esto funciona.
fuente