function z = zernpol(n,m,r,nflag) cv(PP-'\
%ZERNPOL Radial Zernike polynomials of order N and frequency M. k/03ZxC-
% Z = ZERNPOL(N,M,R) returns the radial Zernike polynomials of xP=/N!,#
% order N and frequency M, evaluated at R. N is a vector of vfNAs>X g"
% positive integers (including 0), and M is a vector with the fGv#s
X
% same number of elements as N. Each element k of M must be a |8bq>01~
% positive integer, with possible values M(k) = 0,2,4,...,N(k) Lw'9
% for N(k) even, and M(k) = 1,3,5,...,N(k) for N(k) odd. R is 2Sq_Tw3^
% a vector of numbers between 0 and 1. The output Z is a matrix h b/]8mR
% with one column for every (N,M) pair, and one row for every xcJ`1*1N
% element in R. y}v+c%d
% Bk}><H
% Z = ZERNPOL(N,M,R,'norm') returns the normalized Zernike poly- 2S8P}$mM
% nomials. The normalization factor Nnm = sqrt(2*(n+1)) is KI]wm
% chosen so that the integral of (r * [Znm(r)]^2) from r=0 to "v}pdUW
% r=1 is unity. For the non-normalized polynomials, Znm(r=1)=1 +f0~D(d!_
% for all [n,m]. D{v8q)5r
% 5/QRL\
% The radial Zernike polynomials are the radial portion of the f1PN|
% Zernike functions, which are an orthogonal basis on the unit "C?5f]T
% circle. The series representation of the radial Zernike \7z^!m
% polynomials is .d?%;2*{q
% _al|'obomy
% (n-m)/2 ICB~_O5
% __ 0GDvwy D1
% m \ s n-2s 0Y]0!}
% Z(r) = /__ (-1) [(n-s)!/(s!((n-m)/2-s)!((n+m)/2-s)!)] * r L&-hXGx=7
% n s=0 y[@\j9Hq
% ^+SkCO
% The following table shows the first 12 polynomials. #,(sAj
% *[eL~oN.c
% n m Zernike polynomial Normalization O9(r{Vu7u
% --------------------------------------------- as+GbstN
% 0 0 1 sqrt(2) zNSu
% 1 1 r 2 K1?Gmue#I
% 2 0 2*r^2 - 1 sqrt(6) %g]vxm5?
% 2 2 r^2 sqrt(6) l$*=<tV
% 3 1 3*r^3 - 2*r sqrt(8) qEUT90
% 3 3 r^3 sqrt(8) ]v G{kAnH
% 4 0 6*r^4 - 6*r^2 + 1 sqrt(10) "Dy'Kd%,%/
% 4 2 4*r^4 - 3*r^2 sqrt(10) CJaKnz
% 4 4 r^4 sqrt(10) A\Txb_x
% 5 1 10*r^5 - 12*r^3 + 3*r sqrt(12) d {2
% 5 3 5*r^5 - 4*r^3 sqrt(12) *FR$vLGn
% 5 5 r^5 sqrt(12) MYe
HS
% --------------------------------------------- jy2IZ o
% ":Edu,6O
% Example: 'rb'7=z5
% Wk4.%tpeO7
% % Display three example Zernike radial polynomials iP3Z
% r = 0:0.01:1; 9^F2$+T[:
% n = [3 2 5]; $!A:5jech
% m = [1 2 1]; uk`8X`'
% z = zernpol(n,m,r); s|bM%!$1
% figure Gi^Ha=?J%
% plot(r,z) >i,iOx|E-
% grid on nL]^$J$
% legend('Z_3^1(r)','Z_2^2(r)','Z_5^1(r)','Location','NorthWest') 1U\$iy8}
%
Aw!gSf)
% See also ZERNFUN, ZERNFUN2. V_U'P>_I
r!N]$lB
% A note on the algorithm. *B)yy[8j+
% ------------------------ (y4#.vZh:
% The radial Zernike polynomials are computed using the series RBGlzk
% representation shown in the Help section above. For many special {Z{o"56f
% functions, direct evaluation using the series representation can %1McD{
% produce poor numerical results (floating point errors), because TB
aVW
% the summation often involves computing small differences between |-2}j2'
% large successive terms in the series. (In such cases, the functions Ek.&Sf$cd'
% are often evaluated using alternative methods such as recurrence !{_yaVF
% relations: see the Legendre functions, for example). For the Zernike |I[7,`C~
% polynomials, however, this problem does not arise, because the \[wCp*;1}
% polynomials are evaluated over the finite domain r = (0,1), and HO|-@yOF^
% because the coefficients for a given polynomial are generally all Md;/nJO~{
% of similar magnitude. K=u0nrG*
% %NHYW\sKX
% ZERNPOL has been written using a vectorized implementation: multiple u>T76,8|\
% Zernike polynomials can be computed (i.e., multiple sets of [N,M] #$'"cfRxc
% values can be passed as inputs) for a vector of points R. To achieve &$fbP5uAZ
% this vectorization most efficiently, the algorithm in ZERNPOL &;q<M_<
% involves pre-determining all the powers p of R that are required to S9Y[4*//
% compute the outputs, and then compiling the {R^p} into a single ,i`h
x,
Rg
% matrix. This avoids any redundant computation of the R^p, and `QP
~
% minimizes the sizes of certain intermediate variables. &bC}3D
% Vj^dD9:
% Paul Fricker 11/13/2006 U_z2J(e~
EH9Hpo
+`| *s3M
% Check and prepare the inputs: p_terD:
% ----------------------------- 1-;?0en&0
if ( ~any(size(n)==1) ) || ( ~any(size(m)==1) ) zDBD .5R;
error('zernpol:NMvectors','N and M must be vectors.') ]= x
1`j
end Aa(<L$e!`
|DG@ht
if length(n)~=length(m) 0~E 6QhV:
error('zernpol:NMlength','N and M must be the same length.') '?/&n8J\
end Q2'eQ0W{o
:
1)}Epo,
n = n(:); M?6;|-HH
m = m(:); sB*o)8
length_n = length(n); 9k2,3It
whkJ pK(
if any(mod(n-m,2)) w{7ji}
error('zernpol:NMmultiplesof2','All N and M must differ by multiples of 2 (including 0).') ]
VG?+
end {K.rl%_|N
u35q,u=I
if any(m<0) *=nO
error('zernpol:Mpositive','All M must be positive.') NtZ6$o<Y
end Kr3];(w{
c;V D}UD'
if any(m>n) -Ds|qzrN%
error('zernpol:MlessthanN','Each M must be less than or equal to its corresponding N.') ;~tsF.=
end IKm&xzV-
Yw"P)Zp
if any( r>1 | r<0 ) ckwF|:e7*
error('zernpol:Rlessthan1','All R must be between 0 and 1.') ?n*fy
end hLA;Bl
!UNNjBBP7
if ~any(size(r)==1) Wvr+y!F
error('zernpol:Rvector','R must be a vector.') VO9f~>`(
end R7aXR\ R
x0x $ 9
r = r(:); 0$Ff#8
length_r = length(r); K\sbt7~
u6_jnZGB
if nargin==4 k:0P+d
isnorm = ischar(nflag) & strcmpi(nflag,'norm'); ER<eX4oU
if ~isnorm 5#u.pu
error('zernpol:normalization','Unrecognized normalization flag.') 'O "kt T
end ec'tFL#u{
else {})y^L
isnorm = false; X%J%A-k]
end _7 `E[&v
@&:VKpu\
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% zz3 r<?#5
% Compute the Zernike Polynomials hZF(/4Z2
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% u9}!Gq
+ U5U.f%
% Determine the required powers of r: 3/tJDb5
% ----------------------------------- twv
lQ|
rpowers = []; {,v:
GMsm
for j = 1:length(n) 22IYrk
rpowers = [rpowers m(j):2:n(j)]; $h]NXC6J
end !rHx}n{rw
rpowers = unique(rpowers); PN9^[X
QZ0R :TY
% Pre-compute the values of r raised to the required powers, $B ?? Ip?P
% and compile them in a matrix: ?H0m<jO8~
% ----------------------------- `(T!>QVW+g
if rpowers(1)==0 [D9 :A
rpowern = arrayfun(@(p)r.^p,rpowers(2:end),'UniformOutput',false); |$Xf;N37t
rpowern = cat(2,rpowern{:}); [Pqn3I[
rpowern = [ones(length_r,1) rpowern]; }z{wQ\
else %#4 +!
rpowern = arrayfun(@(p)r.^p,rpowers,'UniformOutput',false); P8]ORQ6ZF
rpowern = cat(2,rpowern{:}); g
2#F_
end yjv&4pIc1
TMtI^mkB:
% Compute the values of the polynomials: mrReast
% -------------------------------------- aZxO/b^j
z = zeros(length_r,length_n); f@*>P_t
for j = 1:length_n rBD2Si=
s = 0:(n(j)-m(j))/2; KE#$+,?
pows = n(j):-2:m(j); :5<#X8>d
for k = length(s):-1:1 @:IL/o*
p = (1-2*mod(s(k),2))* ... H\f/n`@,G
prod(2:(n(j)-s(k)))/ ... 0w+5'lOg
prod(2:s(k))/ ... wJ(8}eI
prod(2:((n(j)-m(j))/2-s(k)))/ ... l }+Cdy9>
prod(2:((n(j)+m(j))/2-s(k))); 64b<0;~
idx = (pows(k)==rpowers); mOSCkp{<e
z(:,j) = z(:,j) + p*rpowern(:,idx); \086O9
end XP4jZCt9
jB/V{Y#y9@
if isnorm cyHhy_~R
z(:,j) = z(:,j)*sqrt(2*(n(j)+1)); E6JV}`hSk
end 0ZT 0
end [{/$9k-aF?
79a9L{gso
% EOF zernpol