TUNECHROM computes linear tunes and chromaticities for COUPLED or UNCOUPLED lattice TUNE = TUNECHROM(RING,DP) - quick calculation of fractional part of the tune from numerically computed transfer matrix, assuming NO X-Y coupling. If the tune is above half-integer TUNECHROM finds 1/2 - nu TUNE = TUNECHROM(RING,DP,TUNEGUESS) - resolves the integer and half-integer uncertainty using the TUNEGUESS value. TUNEGUESS = [NUX,NUY] [TUNE, CHROM] = TUNECHROM(RINGD,DP,TUNEGUESS,'chrom',DDP) - optionally computes chromaticity by numerical differentiation from the difference between tune values at momentums DP+DDP and DP [TUNE, CHROM] = TUNECHROM(RINGD,DP,TUNEGUESS,'chrom') same as above, only uses for DDP the value set in global structure NUMDIFPARAMS. If NUMDIFPARAMS is not defined, TUNECHROM uses the internal default value for DDP (1e-8). TUNECHROM(..., 'coupling') - when 'coupling' switch is added to any of the above syntax options, the tunes and chromaticities are calculated assuming COUPLED lattice for two transverse eigenmodes. Note: TUNECHROM computes tunes and chromaticities from the 4-by-4 transfer matrix. The transfer matrix is found in FINDM44 using numerical differentiation. The error of numerical differentiation is sensitive to the step size. (Reference: Numerical Recipes) Calculation of tunes in TUNECHROM involves one numerical differentiation to find the 4-by-4 transfer matrix. Calculation of chromaticity in TUNECHROM involves TWO!!! numerical differentiations. The error in calculated chromaticity from may be substantial (~ 1e-5). Use the DDP argument to control the step size in chromaticity calculations Another way to control the step size is NUMDIFPARAMS structure See also LINOPT, TWISSRING, TWISSLINE, NUMDIFPARAMS
0001 function [tune, varargout] = tunechrom(RING,DP,varargin) 0002 %TUNECHROM computes linear tunes and chromaticities for COUPLED or UNCOUPLED lattice 0003 % 0004 % TUNE = TUNECHROM(RING,DP) - quick calculation of fractional part of the tune 0005 % from numerically computed transfer matrix, assuming NO X-Y coupling. 0006 % If the tune is above half-integer TUNECHROM finds 1/2 - nu 0007 % 0008 % TUNE = TUNECHROM(RING,DP,TUNEGUESS) - resolves the integer and half-integer 0009 % uncertainty using the TUNEGUESS value. TUNEGUESS = [NUX,NUY] 0010 % 0011 % [TUNE, CHROM] = TUNECHROM(RINGD,DP,TUNEGUESS,'chrom',DDP) - optionally computes 0012 % chromaticity by numerical differentiation from the difference between tune 0013 % values at momentums DP+DDP and DP 0014 % 0015 % [TUNE, CHROM] = TUNECHROM(RINGD,DP,TUNEGUESS,'chrom') same as above, only uses 0016 % for DDP the value set in global structure NUMDIFPARAMS. 0017 % If NUMDIFPARAMS is not defined, TUNECHROM uses the internal default value for DDP (1e-8). 0018 % 0019 % TUNECHROM(..., 'coupling') - when 'coupling' switch is added to any of the above 0020 % syntax options, the tunes and chromaticities are calculated assuming 0021 % COUPLED lattice for two transverse eigenmodes. 0022 % 0023 % Note: TUNECHROM computes tunes and chromaticities from the 4-by-4 0024 % transfer matrix. The transfer matrix is found in FINDM44 using 0025 % numerical differentiation. The error of numerical differentiation 0026 % is sensitive to the step size. (Reference: Numerical Recipes) 0027 % Calculation of tunes in TUNECHROM involves one numerical differentiation 0028 % to find the 4-by-4 transfer matrix. 0029 % Calculation of chromaticity in TUNECHROM involves TWO!!! numerical differentiations. 0030 % The error in calculated chromaticity from may be substantial (~ 1e-5). 0031 % Use the DDP argument to control the step size in chromaticity calculations 0032 % Another way to control the step size is NUMDIFPARAMS structure 0033 % 0034 % 0035 % See also LINOPT, TWISSRING, TWISSLINE, NUMDIFPARAMS 0036 0037 DDP_default = 1e-8; 0038 0039 % Process input arguments 0040 if nargin>2 0041 % See if 'coupling' switch is thrown as the last argument 0042 if ischar(varargin{end}) & strncmp(lower(varargin{end}),'coupl',5) 0043 COUPLINGFLAG = 1; 0044 else 0045 COUPLINGFLAG = 0; 0046 end 0047 % See if TUNEGUESS is specified as the third argument 0048 if isnumeric(varargin{1}) & length(varargin{1})==2 0049 TUNEGUESSFLAG = 1; 0050 TUNEGUESS = varargin{1}; 0051 else 0052 TUNEGUESSFLAG = 0; 0053 TUNEGUESS = [0.25, 0.25]; % if no TUNEGUESS is specified 0054 end 0055 % See if any of the argument is 'chrom' ,then chech if the argument after 'chrom' is DDP 0056 CHROMFLAG = 0; 0057 for i = 1:nargin-2 0058 if strcmp(lower(varargin{i}),'chrom') 0059 CHROMFLAG = 1; 0060 if i<nargin-2 & isnumeric(varargin{i+1}) 0061 DDP = varargin{i+1}; 0062 else 0063 % Check if NUMDIFPARAMS is defined globally 0064 global NUMDIFPARAMS 0065 if isfield(NUMDIFPARAMS,'DPStep') 0066 DDP = NUMDIFPARAMS.DPStep; 0067 else % use default DDP 0068 DDP = DDP_default; 0069 end 0070 end 0071 break 0072 end 0073 end 0074 0075 0076 else 0077 COUPLINGFLAG = 0; 0078 CHROMFLAG = 0; 0079 TUNEGUESSFLAG = 0; 0080 TUNEGUESS = [0.25, 0.25]; % if no TUNEGUESS is specified 0081 end 0082 0083 M44 = findm44(RING,DP); 0084 0085 if COUPLINGFLAG 0086 M =M44(1:2,1:2); 0087 N =M44(3:4,3:4); 0088 m =M44(1:2,3:4); 0089 n =M44(3:4,1:2); 0090 0091 % 2-by-2 symplectic matrix 0092 S = [0 1; -1 0]; 0093 H = m + S*n'*S'; 0094 t = trace(M-N); 0095 0096 g = sqrt(1 + sqrt(t*t/(t*t+4*det(H))))/sqrt(2); 0097 G = diag([g g]); 0098 C = -H*sign(t)/(g*sqrt(t*t+4*det(H))); 0099 A = G*G*M - G*(m*S*C'*S' + C*n) + C*N*S*C'*S'; 0100 B = G*G*N + G*(S*C'*S'*m + n*C) + S*C'*S'*M*C; 0101 0102 cos_mu_x = trace(A)/2; 0103 cos_mu_y = trace(B)/2; 0104 0105 sin_mu_x = sign(A(1,2))*sqrt(-A(1,2)*A(2,1)-(A(1,1)-A(2,2))^2/4); 0106 sin_mu_y = sign(B(1,2))*sqrt(-B(1,2)*B(2,1)-(B(1,1)-B(2,2))^2/4); 0107 0108 else 0109 cos_mu_x = (M44(1,1)+M44(2,2))/2; 0110 cos_mu_y = (M44(3,3)+M44(4,4))/2; 0111 end 0112 TUNE = acos([cos_mu_x,cos_mu_y])/2/pi; 0113 0114 0115 if TUNEGUESSFLAG 0116 % Check if the TUNE is in the same quadrant as TUNEGUESS 0117 guess_quadrant = (TUNEGUESS-floor(TUNEGUESS))> 1/2; 0118 tune = floor(TUNEGUESS) + guess_quadrant + TUNE.*(sign(1/2 - guess_quadrant)); 0119 else 0120 tune = TUNE; 0121 end 0122 0123 if CHROMFLAG & nargout > 1 0124 if COUPLINGFLAG 0125 tune_DDP = tunechrom(RING,DP+DDP,TUNEGUESS,'coupling'); 0126 else 0127 tune_DDP = tunechrom(RING,DP+DDP,TUNEGUESS); 0128 end 0129 varargout{1} = (tune_DDP - tune)/DDP; 0130 end