function z = zernpol(n,m,r,nflag) %{W6PrY{
%ZERNPOL Radial Zernike polynomials of order N and frequency M. x}4q {P5$
% Z = ZERNPOL(N,M,R) returns the radial Zernike polynomials of w;M#c
Y
% order N and frequency M, evaluated at R. N is a vector of \bXa&Lq
% positive integers (including 0), and M is a vector with the &oNAv-m^GD
% same number of elements as N. Each element k of M must be a $xsd~L&
% positive integer, with possible values M(k) = 0,2,4,...,N(k) VbYdZCC
% for N(k) even, and M(k) = 1,3,5,...,N(k) for N(k) odd. R is 6tZI["\
% a vector of numbers between 0 and 1. The output Z is a matrix W9&=xs6
% with one column for every (N,M) pair, and one row for every *. t^MP
% element in R. ~%oR[B7=|
% g)-te+?6
% Z = ZERNPOL(N,M,R,'norm') returns the normalized Zernike poly- PCA4k.,T
% nomials. The normalization factor Nnm = sqrt(2*(n+1)) is mpyt5#f
% chosen so that the integral of (r * [Znm(r)]^2) from r=0 to h[ ZN+M
% r=1 is unity. For the non-normalized polynomials, Znm(r=1)=1 4euO1=
% for all [n,m]. gGYKEq{j(
% JF]JOI6.e
% The radial Zernike polynomials are the radial portion of the *CMx- _
% Zernike functions, which are an orthogonal basis on the unit bA 2pbjg=
% circle. The series representation of the radial Zernike ib m4fa
% polynomials is 7zMr:JmV
% :RYTL'hes
% (n-m)/2 ZSw.U:ep$s
% __ g(g& TO
% m \ s n-2s crCJrN=
% Z(r) = /__ (-1) [(n-s)!/(s!((n-m)/2-s)!((n+m)/2-s)!)] * r vO=fP_
% n s=0 +ZYn? #IQ
% ]e3Ax(i)
% The following table shows the first 12 polynomials. =4!mAo}
% KvSG;
% n m Zernike polynomial Normalization |Tw~@kT@
% --------------------------------------------- K3C <{#r
% 0 0 1 sqrt(2) x-c"%Z|
% 1 1 r 2 :UdF
% 2 0 2*r^2 - 1 sqrt(6) ICCc./l|
% 2 2 r^2 sqrt(6) ~&O%N
% 3 1 3*r^3 - 2*r sqrt(8) G}*hM$F
% 3 3 r^3 sqrt(8) ~[: 2I
% 4 0 6*r^4 - 6*r^2 + 1 sqrt(10) /reX{Y
% 4 2 4*r^4 - 3*r^2 sqrt(10) CLSK'+l
% 4 4 r^4 sqrt(10) Ac6=(B
% 5 1 10*r^5 - 12*r^3 + 3*r sqrt(12) :Tc^y%b0
% 5 3 5*r^5 - 4*r^3 sqrt(12) 1M-pr 8:6s
% 5 5 r^5 sqrt(12) 9uY'E'm*
% --------------------------------------------- 9Flb|G%
% E^PB)D(.
% Example: Z)!C'c b
%
c> af
% % Display three example Zernike radial polynomials 0x7'^Z>-oe
% r = 0:0.01:1; dx]>(e@(t{
% n = [3 2 5]; ^8tEach
% m = [1 2 1]; R]dg_Da
% z = zernpol(n,m,r); t)
+310w
% figure K,]=6Rj
% plot(r,z) n%-0V>
% grid on =;k|*Ny
% legend('Z_3^1(r)','Z_2^2(r)','Z_5^1(r)','Location','NorthWest') .hiSw
% J1kM\8%b\
% See also ZERNFUN, ZERNFUN2. !wNO8;(
<VcQ{F
% A note on the algorithm. d _
e WcI
% ------------------------ iE{&*.q_}>
% The radial Zernike polynomials are computed using the series @;kSx":b
% representation shown in the Help section above. For many special BY*Q_Et
% functions, direct evaluation using the series representation can >p/`;Kq@
% produce poor numerical results (floating point errors), because 8fb'yjIC
% the summation often involves computing small differences between 'S~5"6r
% large successive terms in the series. (In such cases, the functions #g=XUZ/"
% are often evaluated using alternative methods such as recurrence u>$t'
% relations: see the Legendre functions, for example). For the Zernike JRFtsio*
% polynomials, however, this problem does not arise, because the =xrv~
% polynomials are evaluated over the finite domain r = (0,1), and d3Rw!slIq
% because the coefficients for a given polynomial are generally all DJir { \F
% of similar magnitude. *A< 5*Db:F
% -8Xf0_
% ZERNPOL has been written using a vectorized implementation: multiple -N@|QK>
% Zernike polynomials can be computed (i.e., multiple sets of [N,M] &~!Wym
% values can be passed as inputs) for a vector of points R. To achieve _U0f=m
% this vectorization most efficiently, the algorithm in ZERNPOL S$3JMFA
% involves pre-determining all the powers p of R that are required to "j-CZ\]U|
% compute the outputs, and then compiling the {R^p} into a single q;U,s)Uz^
% matrix. This avoids any redundant computation of the R^p, and J;%Xfx]
% minimizes the sizes of certain intermediate variables. 3F0 N^)@
% 9cgUT@a
% Paul Fricker 11/13/2006 2%>FR4a
C7vxw-o|&p
Tr|JYLwF
% Check and prepare the inputs: R4@6G&2d>
% ----------------------------- AEuG v}#
if ( ~any(size(n)==1) ) || ( ~any(size(m)==1) ) q =Il|Nb>
error('zernpol:NMvectors','N and M must be vectors.') dd["dBIZ '
end [2koe.?(
fLVAKn
if length(n)~=length(m) DJ%PWlK5
error('zernpol:NMlength','N and M must be the same length.') {U1m.30n
end BD-AI
W`&hp6Jq
n = n(:); P&q7|ST%N
m = m(:);
9akH
length_n = length(n); m3ff;,
.G^YqJ 4
if any(mod(n-m,2)) +)?J#g
error('zernpol:NMmultiplesof2','All N and M must differ by multiples of 2 (including 0).') '!$%> ||S
end qa6,z.mQ
Q &t<Y^B
if any(m<0) ap~^Ty<>
error('zernpol:Mpositive','All M must be positive.') v@Ox:wl>
end SB7c.H,
mqJ_W[y7
if any(m>n) aoTP[Bp
error('zernpol:MlessthanN','Each M must be less than or equal to its corresponding N.') dTtSUA|V7"
end b6 M
8V(pugJ
if any( r>1 | r<0 ) Jo}eeJ;k
error('zernpol:Rlessthan1','All R must be between 0 and 1.') x`?3C"N:<
end @P"p+
L+QLLcS~EM
if ~any(size(r)==1) # [a*rD%m
error('zernpol:Rvector','R must be a vector.') kW (Bkuc)
end "\=U)CJ
d7i]FV
r = r(:); E E'!|N3
length_r = length(r); 4X$Qu6#i
j=J/x:w_e
if nargin==4 ;>YzEo
isnorm = ischar(nflag) & strcmpi(nflag,'norm'); ,(4K4pN
if ~isnorm \4#W xZ
error('zernpol:normalization','Unrecognized normalization flag.') v}x&?fU `
end '{`$#@a.
else |I|fMF2K
isnorm = false; d/Q%IeEL.
end y Wya&|D9
F>cv<l
=6l
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% X76e&~
% Compute the Zernike Polynomials PT9*)9<L
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% :eg4z )
{GO#.P"
% Determine the required powers of r: ;\l,5EG
% ----------------------------------- _~
&iq1
rpowers = []; JZ#[
2mLh
for j = 1:length(n) h@h! ,;
rpowers = [rpowers m(j):2:n(j)]; IMfqiH)
end m_l[MG\
rpowers = unique(rpowers); 5Dl/aHb
;'Nd~:-]
% Pre-compute the values of r raised to the required powers, m9A!D
% and compile them in a matrix: ow#1="G,=
% ----------------------------- ; Hd7*`$
if rpowers(1)==0 T5:G$-qL(
rpowern = arrayfun(@(p)r.^p,rpowers(2:end),'UniformOutput',false); 5^KWCS7@
rpowern = cat(2,rpowern{:}); T n}s*<=V
rpowern = [ones(length_r,1) rpowern]; eN~=*Mn(za
else ,{q;;b9
rpowern = arrayfun(@(p)r.^p,rpowers,'UniformOutput',false); AFfAtu
rpowern = cat(2,rpowern{:}); 5 BJmA2L
end 2[;_d;oB @
o+9j?|M
% Compute the values of the polynomials: #!m.!?
O
% -------------------------------------- 'Qo*y%{@5
z = zeros(length_r,length_n); B~du-Z22IZ
for j = 1:length_n XS BA$y
s = 0:(n(j)-m(j))/2; ))i }7chc
pows = n(j):-2:m(j); BRYHX.}h\A
for k = length(s):-1:1 \B
7tX
p = (1-2*mod(s(k),2))* ... Y)a^(!<H<
prod(2:(n(j)-s(k)))/ ... Y]5l.SV
prod(2:s(k))/ ...
v<:R#
prod(2:((n(j)-m(j))/2-s(k)))/ ... 0{[,E.
prod(2:((n(j)+m(j))/2-s(k))); lu6(C
idx = (pows(k)==rpowers); F*K_+
?m
z(:,j) = z(:,j) + p*rpowern(:,idx); Jdp3nzM^^@
end Z*2Vpnqh\
&(mR>
mT
if isnorm a -moI+y
z(:,j) = z(:,j)*sqrt(2*(n(j)+1)); WSY}d
Vr
end ;xs"j-r/
end Q?/o%`N
,-e{(L
% EOF zernpol