No BSD License  

Highlights from
basic paraxial optics toolkit

image thumbnail
from basic paraxial optics toolkit by Andri M. Gretarsson
A set of paraxial optics functions for beam propagation and modal decomposition. Numerous examples.

[coeffs,tmat]=decompose(z1,domain,type,terms,varargin);
%----------------------------------------------------------------------------------------------
% PROGRAM: decompose
% AUTHOR:  Andri M. Gretarsson
% DATE:    7/10/04
%
% SYNTAX: [coeffs,tmat]=decompose(z1,domain,type,terms,[q <,lambda,accuracy>]);
%           <...> indicates optional arguments
%
% Calculates the coefficients of the decomposition of the function z1 into
% Hermite Gaussian modes or Laguerre Gaussian modes.
%
% INPUT ARGUMENTS:
% ----------------
% z1        = The values of the function to be decomposed. 2D (nxn) matrix
% domain    = the domain values at which the values in z1 are specified. 
%             The domain is a nxmx2 array where domain(:,:,1) and
%             domain(:,:,2) are the x and y meshes corresponding to the
%             values in z1. (These meshes are often generated using meshgrid.m.)
% type      = 'hg' for a Hermite Gaussian mode decomposition
%             'lg' for a Laguerre Gaussian mode decomposition
% terms     = This argument can be specified either as a scalar or as a matrix.
%              If it is specified as a scalar,  it indicates the number of
%              terms out to which to calculate the decomposition.  Since the
%              Hermite and Laguerre bases are two dimensional and are specified
%              by a 2D argument (l,m) or (p,m), default rules are applied to
%              decide exactly which terms to calculate. The output  
%              matrix tmat indicates what terms were calculated. 
%
%              When terms is specified as a matrix, it indicates exactly which
%              terms to calculate. For Hermite Gaussian modes (type='hg')
%              terms is a LxM matrix where a 1 in the (i,j)th entry indicates
%              that the term TEM(l,m)=(i-1,j-1) will be calculated. A zero 
%              indicates it will not be calculated.  For example:
%
%                         1 0 0 
%              terms  =   0 1 0   
%                         0 1 0
%
%              indicates that the coefficients of the Hermite Gaussian modes 
%              (0,0), (1,1) and (2,1) will be calculated but no others.
%             
%              For Laguerre Gaussian modes (type='lg') the terms matrix is
%              interpreted similarly.  However, since the (p,m) mode can
%              have either positive or negative m terms the  terms matrix is now 
%              a PxMx2 matrix, where terms(:,:,1) indicates which positive-m
%              terms to calculate and terms(:,:,2) indicates which negative-m
%              terms to calculate.  However, note that since m=0 must not
%              be duplicated, the first column in terms(:,:,2) is always zero.
%              Thus for example:
%
%                              1 0 0
%              terms(:,:,1) =  0 1 0
%                              0 1 0
% 
%                              0 0 0
%              terms(:,:,2) =  0 1 0
%                              0 1 1
%
%              indicates that the coefficients of the Laguerre Gaussian modes
%              (0,0), (1,1), (2,1), (1,-1), (2,-1) and (2,-2) will be calculated.
%                 
% q         = the complex radius of curvature "q" of the Gaussian basis.
% lambda    = wavelength of the light in the Gaussian basis. Default is 1.064 microns
% accuracy  = only calculate the coefficients of the decomposition to the
%             specified accuracy.   Actually rounds each result to the nearest 
%             increment of accuracy.  For example, if accuracy=0.3, then a coefficient 
%             of 1.54 would be rounded to 1.5 while a coefficient of 1.56 would be 
%             rounded to 1.8.  Accuracy of 0 applies no rounding.  Specifying
%             accuracy other than "0" does not speed up the calculation.
%
% OUTPUT ARGUMENTS:
% -----------------
% coeffs    = the coefficients of the terms in the expansion. coeffs is a matrix
%             the same size a tmat.
% tmat      = coefficient request matrix.  Often this would be specified by the user
%             by the input argument "terms", in other words tmat=terms. However, as explained
%             under the definition of the input argument terms, this function 
%             allows the user to specify only how many terms he wants, in other words terms can be
%             a scalar and not a matrix.  In this case tmat must be calculated according to 
%             default rules.  In this case it is convenient to have the terms request matrix  
%             as an output argument. Each entry in the coefficient request matrix tmat correspond 
%             to a particular term of the expansion (as explained above).  If the tmat(i,j) is 1, 
%             the coefficient of that term is calculated and returned in coeffs(i,j).  If tmat(i,j)  
%             is 0, the corresponding coefficient was not calculated and coeffs(i,j) is set to 0 
%             regardless of whether the contribution of that term to z1 is really zero.
% 
% EXAMPLE 1 (Hermite Gaussian, only number of terms specified):
%       [x,y]=meshgrid([-pi/2:0.1:pi/2],[-pi/2:0.1:pi/2]); z1=cos(sqrt(x.^2+y.^2));
%       clear domain; domain(:,:,1)=x; domain(:,:,2)=y;
%       w=pi/4; R=1e3; lambda=1e-6; q=(1./R - i* lambda./pi./w.^2).^(-1);
%       [coeffs,tmat]=decompose(z1,domain,'hg',140,[q,lambda,1e-6])
%       z1recomposed=recompose(domain,'hg',coeffs,[q,lambda,1e-6]);
%       subplot(3,1,1); h=pcolor(x,y,abs(z1).^2); set(h,'EdgeColor','none'); axis square; colorbar
%       subplot(3,1,2); h=pcolor(x,y,abs(z1recomposed).^2); set(h,'EdgeColor','none'); axis square; colorbar
%       subplot(3,1,3); h=pcolor(x,y,abs(z1).^2-abs(z1recomposed).^2); set(h,'EdgeColor','none'); axis square; colorbar; shg;
%
% Last updated: July 18, 2004 by AMG
%----------------------------------------------------------------------------------------------
% SYNTAX: [coeffs,tmat]=decompose(z1,domain,type,terms,[q <,lambda,accuracy>]);
%----------------------------------------------------------------------------------------------
function [coeffs,tmat]=decompose(z1,domain,type,terms,varargin);

% HERMITE GAUSSIAN EXPANSION --------------------------------------------------------------------------
if strcmp(lower(type),'hg')
    params=varargin{1};
    q=params(1);
    if length(params)>=2, lambda=params(2); else lambda=1.064e-6; end
    if length(params)>=3, accuracy=params(3); else accuracy=1e-4; end
    if size(terms,1)==1 & size(terms,2)==1                                  % Make terms request matrix
       n=ceil(sqrt(terms));
       tmat=ones(n,n);
       if n^2>terms
           tmat(end,end-ceil((n^2-terms)/2)+1:end)=0;
           tmat(end-floor((n^2-terms)/2):end-1,end)=0;       
       end
   else
       tmat=terms;
   end
    coeffs=zeros(size(tmat));
    for s=1:size(tmat,1)                                                    % Calculate the coefficients
        l=s-1;
        for t=1:size(tmat,2)
            m=t-1;
            if tmat(s,t)==1 
                z2=HermiteGaussianE([l,m,q,lambda],domain(:,:,1),domain(:,:,2));
                coeffs(s,t)=overlap(z1,conj(z2),domain,1,accuracy);
            else
                coeffs(s,t)=0;
            end
        end
   end
   
% LAGUERRE GAUSSIAN EXPANSION --------------------------------------------------------------------------   
elseif strcmp(lower(type),'lg')
    params=varargin{1};
    q=params(1);
    if length(params)>=2, lambda=params(2); else lambda=1.064e-6; end
    if length(params)>=3, accuracy=params(3); else accuracy=1e-4; end
    if size(terms,1)==1 & size(terms,2)==1                                  % Make terms request matrix
       n=ceil( (1+sqrt(1+8*terms))/4 );
       tmat=ones(n,n,2); tmat(:,1,2)=0;
       ndiff=2*n^2-n-terms;
       if ndiff>0
           rdiff=ceil(ndiff/2); ldiff=floor(ndiff/2);
           tmat(end,end-ceil(rdiff/2)+1:end,1)=0;
           tmat(end-floor(rdiff/2):end-1,end,1)=0;       
           tmat(end,end-ceil(ldiff/2)+1:end,2)=0;
           tmat(end-floor(ldiff/2):end-1,end,2)=0;  
       end
       %disp(' '); dispmat(tmat(:,:,1)); disp(' '); dispmat(tmat(:,:,2)); disp(' '); disp(num2str(sum(sum(sum(tmat)))));
   else
       tmat=terms;
   end
    clear coeffs;
    coeffs(:,:,1)=zeros(size(tmat,1),size(tmat,2));
    coeffs(:,:,2)=zeros(size(tmat,1),size(tmat,2));
    for s=1:size(tmat,1)                                                    % Calculate the coefficients
        p=s-1;
        for t=1:size(tmat,2)
            m=t-1;
            if tmat(s,t,1)==1                                               % coeff requested
                z2=LaguerreGaussianE([p,m,q,lambda],domain(:,:,1),domain(:,:,2),'pol');
                coeffs(s,t,1)=overlap(z1,conj(z2),domain,domain(:,:,1),accuracy);
            else
                coeffs(s,t,1)=0;
            end
            if tmat(s,t,2)==1                                               % coeff requested 
                z2=LaguerreGaussianE([p,-m,q,lambda],domain(:,:,1),domain(:,:,2),'pol');
                coeffs(s,t,2)=overlap(z1,conj(z2),domain,domain(:,:,1),accuracy);
            else
                coeffs(s,t,2)=0;
            end            
        end
   end
end

Contact us at files@mathworks.com