function z = zernpol(n,m,r,nflag) oUlVI*~ND
%ZERNPOL Radial Zernike polynomials of order N and frequency M. 3^yK!-Wp(
% Z = ZERNPOL(N,M,R) returns the radial Zernike polynomials of Cp0=k
% order N and frequency M, evaluated at R. N is a vector of N;`n@9BF
% positive integers (including 0), and M is a vector with the TM%%O :3
% same number of elements as N. Each element k of M must be a w``U=sfmV
% positive integer, with possible values M(k) = 0,2,4,...,N(k) oEpFuWp%A
% for N(k) even, and M(k) = 1,3,5,...,N(k) for N(k) odd. R is A.w.rVDD
% a vector of numbers between 0 and 1. The output Z is a matrix SE*g;Cvg1
% with one column for every (N,M) pair, and one row for every yJIscwF
% element in R. 3u0RKLc\
% cw
<l{A
% Z = ZERNPOL(N,M,R,'norm') returns the normalized Zernike poly- nX8v+:&}
% nomials. The normalization factor Nnm = sqrt(2*(n+1)) is LrpM\}t
% chosen so that the integral of (r * [Znm(r)]^2) from r=0 to TB31-
()
% r=1 is unity. For the non-normalized polynomials, Znm(r=1)=1 #Gi$DMW
% for all [n,m]. K{+2G&i
% "3J}b?u_[
% The radial Zernike polynomials are the radial portion of the 0w7DsPdS
% Zernike functions, which are an orthogonal basis on the unit A,!-{/w c
% circle. The series representation of the radial Zernike G' 1'/
% polynomials is "" EQE>d
% -XG@'P_
% (n-m)/2 TWX.D`W
% __ n+ M <\
% m \ s n-2s 8 LCb+^
% Z(r) = /__ (-1) [(n-s)!/(s!((n-m)/2-s)!((n+m)/2-s)!)] * r f
_:A0
% n s=0 @2i9n
% <F'\lA9
% The following table shows the first 12 polynomials. uPvEwq*
C
% CTmT@A{
% n m Zernike polynomial Normalization Dw"\/p:-3
% --------------------------------------------- r9XZ(0/p
% 0 0 1 sqrt(2) |DwZ{(R"W
% 1 1 r 2 +b6v!7_
% 2 0 2*r^2 - 1 sqrt(6) Q,Eo mt
% 2 2 r^2 sqrt(6) [nh>vqum
% 3 1 3*r^3 - 2*r sqrt(8) /x *3}oI
% 3 3 r^3 sqrt(8) E{vbO/|kf
% 4 0 6*r^4 - 6*r^2 + 1 sqrt(10) 8{ I|$*nB
% 4 2 4*r^4 - 3*r^2 sqrt(10) lU]nd[x
% 4 4 r^4 sqrt(10) 4<v&S2Yq
% 5 1 10*r^5 - 12*r^3 + 3*r sqrt(12) x?<FJ"8"k
% 5 3 5*r^5 - 4*r^3 sqrt(12) 8 zb/xP>
% 5 5 r^5 sqrt(12) |uJ%5y#
% --------------------------------------------- ~V6D<
% "J1
4C9u
% Example: '5tCz9}Y
% yt2PU_),
% % Display three example Zernike radial polynomials U$UIN#
% r = 0:0.01:1; 1Z&(6cDY8M
% n = [3 2 5]; XK vi=0B
% m = [1 2 1]; wuo,kM
% z = zernpol(n,m,r); VxBo1\'
% figure 19] E 5'AI
% plot(r,z) 5lum $5
% grid on ugBCBr
% legend('Z_3^1(r)','Z_2^2(r)','Z_5^1(r)','Location','NorthWest') M3au{6y
% }QmqoCAE~m
% See also ZERNFUN, ZERNFUN2. 9tnD=A<PS
'c~4+o4co
% A note on the algorithm. %l%HHT
% ------------------------ 1.>m@Slr>
% The radial Zernike polynomials are computed using the series ji="DYtL
% representation shown in the Help section above. For many special 3(UVg!t
% functions, direct evaluation using the series representation can 1
TXioDs=_
% produce poor numerical results (floating point errors), because *NQ/UXE
% the summation often involves computing small differences between to&m4+5?6
% large successive terms in the series. (In such cases, the functions 8?C5L8)
% are often evaluated using alternative methods such as recurrence mp3s-YfRc
% relations: see the Legendre functions, for example). For the Zernike oL<St$1
% polynomials, however, this problem does not arise, because the qJw_
% polynomials are evaluated over the finite domain r = (0,1), and Yr|4Fl~U
% because the coefficients for a given polynomial are generally all Qg/rRiV
% of similar magnitude. E(|>Ddv B&
% yCo.cd-
% ZERNPOL has been written using a vectorized implementation: multiple ," ql5Q4
% Zernike polynomials can be computed (i.e., multiple sets of [N,M] eV~goj
% values can be passed as inputs) for a vector of points R. To achieve i@'dH3-kO
% this vectorization most efficiently, the algorithm in ZERNPOL t$ *0{w
E
% involves pre-determining all the powers p of R that are required to T^q
0'#/
% compute the outputs, and then compiling the {R^p} into a single FiU#T.`9'
% matrix. This avoids any redundant computation of the R^p, and Ir]\|t
% minimizes the sizes of certain intermediate variables. `$NP>%J-
% fc@A0Hf
% Paul Fricker 11/13/2006 B7%U_F|m
WEpoBP
CL
M^I(OuRMeI
% Check and prepare the inputs: [00m/fT6
% ----------------------------- -K$)DvV^(E
if ( ~any(size(n)==1) ) || ( ~any(size(m)==1) ) :hA#m[
error('zernpol:NMvectors','N and M must be vectors.') yLcEX
end DTs;{c
eDB ;cN
if length(n)~=length(m) tnIX:6
error('zernpol:NMlength','N and M must be the same length.') "7`<~>9t.
end QS j]ZA
2"~8Z(0
n = n(:); mA} "a<0
m = m(:); A)KZa"EX
length_n = length(n); |7Kbpj
B-ESFATc
if any(mod(n-m,2)) oXS}IL
og'
error('zernpol:NMmultiplesof2','All N and M must differ by multiples of 2 (including 0).') (iGTACoF
end |nF 8gh~}
/7LR;>B j
if any(m<0) |'2d_vR
error('zernpol:Mpositive','All M must be positive.') hzC>~Ub5
end <7$1kGlA
C.QO#b
if any(m>n) -.3w^D"l
error('zernpol:MlessthanN','Each M must be less than or equal to its corresponding N.') L8n|m!MOD
end "h ^Z
k_R"CKd
if any( r>1 | r<0 ) ze;KhUPRm
error('zernpol:Rlessthan1','All R must be between 0 and 1.') RT5T1K08I
end 1nOCQ\$l
(I}v[W
if ~any(size(r)==1) Np)lIGE
error('zernpol:Rvector','R must be a vector.') ]{L jRSV
end RGX=)
cS+>J@L
r = r(:); |D.ND%K&
length_r = length(r); Xm2'6f,
u2[w#
if nargin==4 U%<Inb}ad
isnorm = ischar(nflag) & strcmpi(nflag,'norm'); iyog`s c
if ~isnorm Xx(T">]vJ
error('zernpol:normalization','Unrecognized normalization flag.') .[ mRM
end wdZ/Xp9]
else PxE3K-S)G
isnorm = false; L_s:l9!r
end 8.~kK<)!
PYzvCf`?
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% ~v"L!=~G;a
% Compute the Zernike Polynomials C8 \^#5
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% bJ;'`sw1
-`t^7pr
% Determine the required powers of r: [fIg{Q
% ----------------------------------- 'P}0FktP`
rpowers = []; m#F`] {
for j = 1:length(n) 8JD,u
rpowers = [rpowers m(j):2:n(j)]; ]0\MmAJRn
end CWS4lx
rpowers = unique(rpowers); 4H<lm*!^
v9->nVc-
% Pre-compute the values of r raised to the required powers, FsryEHz
% and compile them in a matrix: ?R#)1{(8d~
% ----------------------------- j8`BdKg
if rpowers(1)==0 C6yuX\
rpowern = arrayfun(@(p)r.^p,rpowers(2:end),'UniformOutput',false); E+JqWR5
rpowern = cat(2,rpowern{:}); Oc; G(l(
rpowern = [ones(length_r,1) rpowern]; @ry_nKr9
else SZ$Kz n
rpowern = arrayfun(@(p)r.^p,rpowers,'UniformOutput',false); GM<-&s!Uj
rpowern = cat(2,rpowern{:}); fd2T=fz-
end tnG# IU
*
)>- =R5ZV
% Compute the values of the polynomials: K96<M);:g
% -------------------------------------- r>U@3%0&
z = zeros(length_r,length_n); m9Hit8f@Q
for j = 1:length_n VAu&@a`
s = 0:(n(j)-m(j))/2; 3%ZOKb"D*
pows = n(j):-2:m(j); ZQ0F$J)2~
for k = length(s):-1:1 DDH:)=;z
p = (1-2*mod(s(k),2))* ... '08=yqy4N
prod(2:(n(j)-s(k)))/ ... # Vha7
prod(2:s(k))/ ... '6Q=#:mc\
prod(2:((n(j)-m(j))/2-s(k)))/ ... :4%k9BGAj"
prod(2:((n(j)+m(j))/2-s(k))); |H+Wed|
idx = (pows(k)==rpowers); 8*T=Xei8
z(:,j) = z(:,j) + p*rpowern(:,idx); ^ovR7+V
end aAA U{EWW
(ICd}
if isnorm ,WB{i^TD
z(:,j) = z(:,j)*sqrt(2*(n(j)+1)); iW /}#
end 5o8EC"
0
end /~f'}]W
/gkX38
% EOF zernpol