function Output = LaplaceCoeffs(varargin) % LaplaceCoeff: get a Laplace coefficient (definition: Solar System % Dynamics, eq. 6.67) %Inputs: 'init' - calculate a table of the laplace coefficients and save it % in ~/Matlab/Data/LaplaceCoeffs.mat % 'load' = return all the table and the row/col values in a % structure % alph,s,j = return the laplace coefficient for the given alph,s,j. % alph can be a vector % alph,s,j,D = return the D order derivative of the laplace % coefficient for the given alph, s, j. % Yair Judkovsky, 6.4.2020 persistent jVec sVec DVec alphaVec bTable Nj Ns ND %return a specific laplace coeff if isnumeric(varargin{1}) alph = varargin{1}; s = varargin{2}; j = abs(varargin{3}); %b_s_j = b_s__-j, Solar System Dynamics eq. 6.69 %a recursive path of the function for the case there's a 4th input - %the laplace coeff derivative. if length(varargin)>3 D = varargin{4}; %derivative order else D = 0; end jInd = j+1; sInd = s+0.5; DInd = D+1; %if the requested derivative is too high, calculate by recursive method if DInd>ND %2nd and higher derivatives of the coeff, Solar System Dynamics eq. 6.71 Output = s*(LaplaceCoeffs(alph,s+1,j-1,D-1)-2*alph.*LaplaceCoeffs(alph,s+1,j,D-1)+LaplaceCoeffs(alph,s+1,j+1,D-1)-2*(D-1)*LaplaceCoeffs(alph,s+1,j,D-2)); return end row = sub2ind([Nj,Ns,ND],jInd,sInd,DInd); %find the column corresponding to the alpha given, currently by finding the %closest value in the table F = (length(alphaVec)); col = round(alph*F); if col==0 col = 1; end %return the value from the table Output = bTable(row,col); return end %perform the calculation. Table will be made such that each row %corresponds to some j,s combination, and each column corresponds to an %alpha value. if isequal(varargin{1},'init') %define the integrand function laplace_integrand=@(j1,s1,alph1) (@(phi) (cos(j1.*phi)./(1-2.*alph1.*cos(phi)+alph1.^2).^s1)); warning off %set range of j, s, D, alpha. Can also be read from varargin if %exists, where the 2,3,4,5 arguments will be Ns, Nj,ND and dalpha Ns =3; Nj = 5; ND = 4; dalpha = 1e-2; %set integration tolerance AbsTol = 1e-5; Path = '~/Matlab/Data/LaplaceCoeffs.mat'; %read inputs from varargin, if they exist if length(varargin)==5 Ns = varargin{2}; Nj = varargin{3}; ND = varargin{4}; dalpha = varargin{5}; end if length(varargin)>5 AbsTol = varargin{6}; end if length(varargin)>6 Path = varargin{7}; end %set a vector of s and j values sVec = (1:Ns)-0.5; jVec = (1:Nj)-1; DVec = (1:ND)-1; %define the alpha vector from dalpha alphaVec = dalpha:dalpha:1; %pre-allocate bTable = zeros(Nj*Ns*ND,length(alphaVec)); for jInd = 1:length(jVec) for sInd = 1:length(sVec) for DInd = 1:length(DVec) for alphaInd = 1:length(alphaVec) row = sub2ind([Nj,Ns,ND],jInd,sInd,DInd); val = CalculateSingleCoeff(jVec(jInd),sVec(sInd),alphaVec(alphaInd),DVec(DInd),AbsTol,laplace_integrand); bTable(row,alphaInd)=val; end end end end save(Path,'jVec','sVec','alphaVec','DVec','bTable','Nj','Ns','ND'); disp('calculated laplace coeffs'); Output = []; return end %load the table including the persistent variables for future use. Also %return the persistent variables in a structure as an output. if isequal(varargin{1},'load') Path = '~/Matlab/Data/LaplaceCoeffs.mat'; if nargin>1 Path = varargin{2}; end load(Path); Output = load(Path); return end % if D==0 % Output = LaplaceCoeffs(alph,s,j); % elseif D==1 %first derivative of the coeff, Solar System Dynamics eq. 6.70 % Output = s*(LaplaceCoeffs(alph,s+1,j-1)-2*alph.*LaplaceCoeffs(alph,s+1,j)+LaplaceCoeffs(alph,s+1,j+1)); % else %2nd and higher derivatives of the coeff, Solar System Dynamics eq. 6.71 % Output = s*(LaplaceCoeffs(alph,s+1,j-1,D-1)-2*alph.*LaplaceCoeffs(alph,s+1,j,D-1)+LaplaceCoeffs(alph,s+1,j+1,D-1)-2*(D-1)*LaplaceCoeffs(alph,s+1,j,D-2)); % end % return function val = CalculateSingleCoeff(j,s,alph,D,AbsTol,laplace_integrand) % %define the integrand function % laplace_integrand=@(j1,s1,alph1) (@(phi) (cos(j1.*phi)./(1-2.*alph1.*cos(phi)+alph1.^2).^s1)); if D==0 val = 1/pi*integral(laplace_integrand(j,s,alph),0,2*pi,'AbsTol',AbsTol); elseif D==1 %first derivative of the coeff, Solar System Dynamics eq. 6.70 val = s*(CalculateSingleCoeff(j-1,s+1,alph,D-1,AbsTol,laplace_integrand)... -2*alph.*CalculateSingleCoeff(j,s+1,alph,D-1,AbsTol,laplace_integrand)... +CalculateSingleCoeff(j+1,s+1,alph,D-1,AbsTol,laplace_integrand)); else %2nd and higher derivatives of the coeff, Solar System Dynamics eq. 6.71 val = s*(CalculateSingleCoeff(j-1,s+1,alph,D-1,AbsTol,laplace_integrand)... -2*alph.*CalculateSingleCoeff(j,s+1,alph,D-1,AbsTol,laplace_integrand)... +CalculateSingleCoeff(j+1,s+1,alph,D-1,AbsTol,laplace_integrand)... -2*(D-1)*CalculateSingleCoeff(j,s+1,alph,D-2,AbsTol,laplace_integrand)); end