function z = zernpol(n,m,r,nflag) V;$lgTs|'
%ZERNPOL Radial Zernike polynomials of order N and frequency M. rie1F,
% Z = ZERNPOL(N,M,R) returns the radial Zernike polynomials of SLW1]ZaG
% order N and frequency M, evaluated at R. N is a vector of yDPek*#^"q
% positive integers (including 0), and M is a vector with the ZEW`?6
% same number of elements as N. Each element k of M must be a <R2bz1!h.
% positive integer, with possible values M(k) = 0,2,4,...,N(k) t^q/'9Ai&J
% for N(k) even, and M(k) = 1,3,5,...,N(k) for N(k) odd. R is IySlu^a
% a vector of numbers between 0 and 1. The output Z is a matrix
M`bK
% with one column for every (N,M) pair, and one row for every t<4+CC2H
% element in R. bp }~{]:b
% f.!cR3XgV
% Z = ZERNPOL(N,M,R,'norm') returns the normalized Zernike poly- s;>jy/o0 s
% nomials. The normalization factor Nnm = sqrt(2*(n+1)) is ;lGjj9we>
% chosen so that the integral of (r * [Znm(r)]^2) from r=0 to
*h`zV<j
% r=1 is unity. For the non-normalized polynomials, Znm(r=1)=1
8$1<N
% for all [n,m]. kc}e},k
% AtSEKpKc
% The radial Zernike polynomials are the radial portion of the 8kk$:8
% Zernike functions, which are an orthogonal basis on the unit <MoWS9s!yb
% circle. The series representation of the radial Zernike 1Eh(U
% polynomials is gP`8hNwR
% hW(Mf
% (n-m)/2 K?) &8S
% __ NI3_wV
% m \ s n-2s <}G7#xg
% Z(r) = /__ (-1) [(n-s)!/(s!((n-m)/2-s)!((n+m)/2-s)!)] * r Wfp[)MM;
% n s=0 {@k5e)
Q
% d&F8nBIM5
% The following table shows the first 12 polynomials. IG
6yt
% ]"^U
% n m Zernike polynomial Normalization ;:f.a(~c
% --------------------------------------------- +Ibcc8Qud
% 0 0 1 sqrt(2) IF<pT)
% 1 1 r 2 S-*4HV_l
% 2 0 2*r^2 - 1 sqrt(6) Pr9$(6MX
% 2 2 r^2 sqrt(6) PE0A `
% 3 1 3*r^3 - 2*r sqrt(8) 4Z,MqG>
% 3 3 r^3 sqrt(8) l@%MS\{
% 4 0 6*r^4 - 6*r^2 + 1 sqrt(10) ckS.j)@.c
% 4 2 4*r^4 - 3*r^2 sqrt(10) voEg[Gg4%I
% 4 4 r^4 sqrt(10) O)n"a\LD
% 5 1 10*r^5 - 12*r^3 + 3*r sqrt(12) [td)v,
% 5 3 5*r^5 - 4*r^3 sqrt(12)
pO[ @2tF
% 5 5 r^5 sqrt(12) P;C3{>G9
% --------------------------------------------- CNwIM6t
% kZfa8wL]P
% Example: Z_Qs^e$
% {1Z8cV
% % Display three example Zernike radial polynomials ],V_"\ATD
% r = 0:0.01:1; 2r4owB?
% n = [3 2 5]; B&3oo
% m = [1 2 1]; yY+)IU.
% z = zernpol(n,m,r); yPs4S?<s
% figure MEf`&<t
% plot(r,z) %5Q5xw]w3
% grid on >]s\%GO
% legend('Z_3^1(r)','Z_2^2(r)','Z_5^1(r)','Location','NorthWest') QQ;<L"VW
% {xJq F4
% See also ZERNFUN, ZERNFUN2. /P { Zo
>zx]%
W
% A note on the algorithm. YW9r'{(D(I
% ------------------------ 7/C,<$Ep
% The radial Zernike polynomials are computed using the series P&I%!'<
% representation shown in the Help section above. For many special J'{69<`Dl
% functions, direct evaluation using the series representation can q=Xd a0c
% produce poor numerical results (floating point errors), because ;J[ed>v;3
% the summation often involves computing small differences between KT'Ebb]
% large successive terms in the series. (In such cases, the functions WRIOj Q:
% are often evaluated using alternative methods such as recurrence RgTm^?Ex
% relations: see the Legendre functions, for example). For the Zernike }#'I,?_k
% polynomials, however, this problem does not arise, because the q+<<Ku(20
% polynomials are evaluated over the finite domain r = (0,1), and wwmHr!b:6
% because the coefficients for a given polynomial are generally all n@1;5)&k~
% of similar magnitude. n`v;S>aT
% F/8="dM
% ZERNPOL has been written using a vectorized implementation: multiple }enS'Fpf`
% Zernike polynomials can be computed (i.e., multiple sets of [N,M] cl\Gh
% values can be passed as inputs) for a vector of points R. To achieve -O&u;kh4g
% this vectorization most efficiently, the algorithm in ZERNPOL \Dn47V{7-
% involves pre-determining all the powers p of R that are required to ^lw0}
i
% compute the outputs, and then compiling the {R^p} into a single &>%R)?SZh
% matrix. This avoids any redundant computation of the R^p, and /i!3Fr"
% minimizes the sizes of certain intermediate variables. yLFZo"r
% ioJ~k[T
% Paul Fricker 11/13/2006 \}:RG^*m
3P}^Wu
/Ko{S_3<I
% Check and prepare the inputs: H0dHW;U<1
% ----------------------------- xbTvv>'U
if ( ~any(size(n)==1) ) || ( ~any(size(m)==1) ) =P}BAJ
error('zernpol:NMvectors','N and M must be vectors.') 6cQ)*,Q
end 4hQ.RO
n7A %y2
if length(n)~=length(m) n "J+?~9
error('zernpol:NMlength','N and M must be the same length.') GS*Mv{JJ
end #&$a7L}
XT"-
n = n(:); 9y$"[d27;+
m = m(:); W]TO%x{
length_n = length(n); Sd9%tO9mf
Lh_Q@>k
if any(mod(n-m,2)) s7
K](T4
error('zernpol:NMmultiplesof2','All N and M must differ by multiples of 2 (including 0).') I\y=uC
end n){F
FM
rzk-_AFR
if any(m<0) WVMkLMg8d
error('zernpol:Mpositive','All M must be positive.') :~PzTUz
end )a;ou>u
xRiWg/Z~
if any(m>n) "TQ3{=j{
error('zernpol:MlessthanN','Each M must be less than or equal to its corresponding N.') bMjE@S&
end _?m%i]~o
Fx]}<IudA^
if any( r>1 | r<0 ) B098/`r
error('zernpol:Rlessthan1','All R must be between 0 and 1.') ]ysEj3
end Ojwhcb^
M[}aQWT$v
if ~any(size(r)==1) "I
n[= 2w
error('zernpol:Rvector','R must be a vector.') <<iwJ
U%:
end &}."sGK
pf%B
r = r(:); c
0/vB
length_r = length(r); W6y-~
,T<q"d7-#
if nargin==4 P-2 5]-
isnorm = ischar(nflag) & strcmpi(nflag,'norm'); iQ7S*s+l5O
if ~isnorm x./l27}6
error('zernpol:normalization','Unrecognized normalization flag.') 5p]Cwj<u
end NJqjW
else Zk .V
isnorm = false; 3;t {V$
end ynQ+yW74Z
s(u,mtG
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% }s>.Fh
% Compute the Zernike Polynomials 4
>2g&);B
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% |tVWmm^m
*41
2)zEy
% Determine the required powers of r: ~;ZT<eCIA
% ----------------------------------- ~bsL
W:.'
rpowers = []; K'tckJ#%
for j = 1:length(n) !L|PDGD
rpowers = [rpowers m(j):2:n(j)]; }]K^b1Fs5
end VQe@H8>3
rpowers = unique(rpowers); >M-ZjT>
8-clL\bm
% Pre-compute the values of r raised to the required powers, ;mtv
% and compile them in a matrix: hY5tBL
% ----------------------------- 2z+-vT%
if rpowers(1)==0 [/'=M h
rpowern = arrayfun(@(p)r.^p,rpowers(2:end),'UniformOutput',false); *v6 j7<H
rpowern = cat(2,rpowern{:}); 4Y!_tZ>
rpowern = [ones(length_r,1) rpowern]; k}tTl 2
else 9u%S<F"
rpowern = arrayfun(@(p)r.^p,rpowers,'UniformOutput',false); 3`3`iN!8\@
rpowern = cat(2,rpowern{:}); DwBKqhu
end -!JnyD
`j1(GQt
% Compute the values of the polynomials: 8*[Q{:'.
% -------------------------------------- blHJhB&8
z = zeros(length_r,length_n); Uc>$w?oA
for j = 1:length_n T
7EkRcb
s = 0:(n(j)-m(j))/2; JrhDqyk*
pows = n(j):-2:m(j); LkA_M'G
for k = length(s):-1:1 ?Gr2@,jlD
p = (1-2*mod(s(k),2))* ... kntM
prod(2:(n(j)-s(k)))/ ... uU;]/
prod(2:s(k))/ ... e/*T,ZJ
prod(2:((n(j)-m(j))/2-s(k)))/ ... `zmjiC
prod(2:((n(j)+m(j))/2-s(k))); SZ )AO8&
idx = (pows(k)==rpowers); p#DJow
z(:,j) = z(:,j) + p*rpowern(:,idx); >56I`[)
end 0'Y'K6hG`
8n`O{8:fi
if isnorm p.50BcDg
z(:,j) = z(:,j)*sqrt(2*(n(j)+1)); ?r"QJa>
end /Q*o6Gys0
end [Kc"L+H\
/rQ[Ik$|
% EOF zernpol