在本文中,Honarvar 和 Paramesran 推导出了一种有趣的方法,以非常好的递归方式计算径向 Zernike 多项式。递归公式非常简单,无需除以或乘以大整数:
Rmn(ρ)=ρ(R|m−1|n−1(ρ)+Rm+1n−1(ρ))−Rmn−2(ρ)
我建议看一下 Honarvar 和 Paramesran 论文中的图 1,它清楚地说明了不同 Zernike 多项式之间的依赖关系。
这是在以下 Octave 脚本中实现的:
clear % Tested with Octave instead of Matlab
N = 120;
n_r = 1000;
R = cell(N+1,N+1);
rho = [0:n_r]/n_r;
rho_x_2 = 2*[0:n_r]/n_r;
R{0+1,0+1} = ones(1,n_r+1); % R^0_0 Unfortunately zero based cell indexing is not possible
R{1+1,1+1} = R{0+1,0+1}.*rho; % R^1_1 ==> R{...+1,...+1} etc.
for n = 2:N,
if bitget(n,1) == 0, % n is even
R{0+1,n+1} = -R{0+1,n-2+1}+rho_x_2.*R{1+1,n-1+1}; % R^0_n
m_lo = 2;
m_hi = n-2;
else
m_lo = 1;
m_hi = n-1;
end
for m = m_lo:2:m_hi,
R{m+1,n+1} = rho.*(R{m-1+1,n-1+1}+R{m+1+1,n-1+1})-R{m+1,n-2+1}; % R^m_n
end
R{n+1,n+1} = rho.*R{n-1+1,n-1+1}; % R^n_n
end;
Z = @(m,n,rho) (-1)^((n-m)/2) * rho.^m .* jacobiPD((n-m)/2,m,0,1-2*rho.^2);
m = 22;
n = 112;
figure
plot(rho,Z(m,n,rho))
hold on
plot(rho,R{m+1,n+1},'r');
xlabel("rho")
ylabel("R^{22}_{112}(rho)")
legend("via Jacobi","recursive");
%print -djpg plt.jpg
m = 0;
n = 46;
max_diff_m_0_n_46 = norm(Z(m,n,rho)-R{m+1,n+1},inf)
例如,此代码生成的图显示,m=22, 和n=112,灾难性的取消发生在附近ρ=0.7,如果 Zernike 径向多项式是通过 Jacobi 多项式计算的。因此,人们还必须担心低次泽尼克多项式的准确性。
递归方法似乎更适合以稳定的方式计算这些高阶 Zernike 多项式。尽管如此,对于m=0和n=46,雅可比和递归方法之间的最大差异是(仅?)1.4e-10
,这对于您的应用程序可能足够准确。