function z = zernpol(n,m,r,nflag) -X%twy=
%ZERNPOL Radial Zernike polynomials of order N and frequency M. 8,vP']4r%
% Z = ZERNPOL(N,M,R) returns the radial Zernike polynomials of e@Ev']
% order N and frequency M, evaluated at R. N is a vector of eX"Ecl{
% positive integers (including 0), and M is a vector with the V?x&\<;,
% same number of elements as N. Each element k of M must be a C\BKdx5;
% positive integer, with possible values M(k) = 0,2,4,...,N(k) 4h--x~ @
% for N(k) even, and M(k) = 1,3,5,...,N(k) for N(k) odd. R is md18q:AG)
% a vector of numbers between 0 and 1. The output Z is a matrix &Fuk+Cu{
% with one column for every (N,M) pair, and one row for every AT3HHQD
% element in R. ^z,B}Nz
% LCA+y1LP-_
% Z = ZERNPOL(N,M,R,'norm') returns the normalized Zernike poly- /`aPV"$M
% nomials. The normalization factor Nnm = sqrt(2*(n+1)) is r^rk@W;[
% chosen so that the integral of (r * [Znm(r)]^2) from r=0 to pG)dF@
% r=1 is unity. For the non-normalized polynomials, Znm(r=1)=1 k$J!,!q
% for all [n,m]. tq'hiS(b
% []
"bn9
+
% The radial Zernike polynomials are the radial portion of the Wrp+B[{r\
% Zernike functions, which are an orthogonal basis on the unit bZfq?
% circle. The series representation of the radial Zernike rZ-< Ryg
% polynomials is }.9a!/@Aj
% iS.gN&\z^
% (n-m)/2 4K`b?{){+a
% __ w^nA/=;r
% m \ s n-2s 7iM@BeIf
% Z(r) = /__ (-1) [(n-s)!/(s!((n-m)/2-s)!((n+m)/2-s)!)] * r Q7v1xBM
% n s=0 @RuMo"js
% &c&TQkx
% The following table shows the first 12 polynomials. oVbs^sbRH
% 2Y[n
% n m Zernike polynomial Normalization &;JeLL1J
% --------------------------------------------- T5T[$%]6
% 0 0 1 sqrt(2) :ntAU2)H
% 1 1 r 2 Zn)o@'{}{
% 2 0 2*r^2 - 1 sqrt(6) 0
.T5%
_/
% 2 2 r^2 sqrt(6) LqJV
% 3 1 3*r^3 - 2*r sqrt(8) 0Db=/sJ>
% 3 3 r^3 sqrt(8) wEI?
9
% 4 0 6*r^4 - 6*r^2 + 1 sqrt(10) FdEUZ[IT`{
% 4 2 4*r^4 - 3*r^2 sqrt(10) O6b+eS
% 4 4 r^4 sqrt(10)
;Q/1l=Bn
% 5 1 10*r^5 - 12*r^3 + 3*r sqrt(12) \fI05GZ
% 5 3 5*r^5 - 4*r^3 sqrt(12) C; U4`0=8
% 5 5 r^5 sqrt(12) i7 YUyU
% --------------------------------------------- u`(yT<>H
% "66#F
% Example: a7u*d`3X=
% ;tA$
x!5]
% % Display three example Zernike radial polynomials +N2ILE8[<
% r = 0:0.01:1; eBmHb\
% n = [3 2 5]; mO]dP;,
% m = [1 2 1]; *(]ZdB_2
% z = zernpol(n,m,r); Uy)pEEu
% figure <KCyXU*
% plot(r,z) j*f\Z!EeZ
% grid on r[7*1'.p
% legend('Z_3^1(r)','Z_2^2(r)','Z_5^1(r)','Location','NorthWest') P;'ZdZ(SLu
% D97 vfC
% See also ZERNFUN, ZERNFUN2. &l_}yf"v
0blbf@XA
% A note on the algorithm. ?pd/cj^
% ------------------------ {:n1|_r4Z
% The radial Zernike polynomials are computed using the series 4N7|LxNNl_
% representation shown in the Help section above. For many special %i?v)EW
% functions, direct evaluation using the series representation can =9p3^:S
% produce poor numerical results (floating point errors), because o:4#AkS
% the summation often involves computing small differences between }rs>B,=*k
% large successive terms in the series. (In such cases, the functions n8T'}d+mm
% are often evaluated using alternative methods such as recurrence ^4<&"aoo
% relations: see the Legendre functions, for example). For the Zernike DeT$4c*:[
% polynomials, however, this problem does not arise, because the T;PLUjp}
% polynomials are evaluated over the finite domain r = (0,1), and Pl`Nniy
% because the coefficients for a given polynomial are generally all 1B~Z1w
% of similar magnitude. m$pRA0s2`
% *1_Ef).
% ZERNPOL has been written using a vectorized implementation: multiple "d}ey=$h4
% Zernike polynomials can be computed (i.e., multiple sets of [N,M] jPx}-_jM
% values can be passed as inputs) for a vector of points R. To achieve ,i;#e
% this vectorization most efficiently, the algorithm in ZERNPOL $2}%3{<j
% involves pre-determining all the powers p of R that are required to 08%Bx~88_%
% compute the outputs, and then compiling the {R^p} into a single 7+X~i@#rU
% matrix. This avoids any redundant computation of the R^p, and 0&2`)W?9
% minimizes the sizes of certain intermediate variables. Xi\c>eALO
% JZ:yPvJ
% Paul Fricker 11/13/2006 `}bvbvmA
in K;n
*_}0vd
% Check and prepare the inputs: #<u;.'R
% ----------------------------- O;}K7rSc
if ( ~any(size(n)==1) ) || ( ~any(size(m)==1) ) HGd.meQ
error('zernpol:NMvectors','N and M must be vectors.')
cJTwgm?
end aS\$@41"
i*!2n1c[
if length(n)~=length(m) \W=
qqE]
error('zernpol:NMlength','N and M must be the same length.') fd>&RbUp
end +#< Z/
Ve)BF1YG
n = n(:); [/n@BK
m = m(:); ja&m-CFK
length_n = length(n); |z:4T%ES
'lu3BQvfh
if any(mod(n-m,2)) O(D2F$VlL
error('zernpol:NMmultiplesof2','All N and M must differ by multiples of 2 (including 0).') e:C4f
end HXZ,"S
U)aftH
*Pk
if any(m<0) B_b5&M@
error('zernpol:Mpositive','All M must be positive.') &CN(PZv
end +"k?G
Y|
ch ;
if any(m>n) 8gt&*;'}*D
error('zernpol:MlessthanN','Each M must be less than or equal to its corresponding N.') %yk_(3a
end R-1MD
Z{yH:{Vk
if any( r>1 | r<0 ) lNWP9?X
error('zernpol:Rlessthan1','All R must be between 0 and 1.') HSAr6h
end 8VO];+N
G|8>Q3D
if ~any(size(r)==1) "h7Dye
error('zernpol:Rvector','R must be a vector.') /4+(e I7
end !=a]Awr\
wEJzLFCn
r = r(:); BNI)y@E^X
length_r = length(r); jiLJiYMg
CXyb8z4/+
if nargin==4 [+xsX*+
isnorm = ischar(nflag) & strcmpi(nflag,'norm'); lCl5#L9
if ~isnorm u|.7w2
error('zernpol:normalization','Unrecognized normalization flag.') D>HbJCG4^
end 8Gnf_lkI
else *kYGXT,f]
isnorm = false; J.M&Vj:
end woBx609Aak
t4/ye>P &
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% mw;4/
/R
% Compute the Zernike Polynomials T&b_*)=S
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% K:~tZ
=adHP|S
% Determine the required powers of r: ftl?x'P%
% ----------------------------------- yO!M$aOn/
rpowers = []; W g6H~x
for j = 1:length(n) X?n=UebO^
rpowers = [rpowers m(j):2:n(j)];
/7:+.#Ag`
end YhS_ ,3E
rpowers = unique(rpowers); JPng !tvR
p:W]
% Pre-compute the values of r raised to the required powers, h&}iH
% and compile them in a matrix: TO"Md["GI
% ----------------------------- kV4Oq.E
if rpowers(1)==0 ~T-uk
rpowern = arrayfun(@(p)r.^p,rpowers(2:end),'UniformOutput',false); A>2 _I)
rpowern = cat(2,rpowern{:}); `8RKpZv&
rpowern = [ones(length_r,1) rpowern]; ()O&O+R|)
else ,u PcQ
rpowern = arrayfun(@(p)r.^p,rpowers,'UniformOutput',false); nw%`CnzT
rpowern = cat(2,rpowern{:}); 2{vAs
end `&