analc_endsversion/AnalyticLC/LaplaceCoeffs.m
2022-04-11 15:28:22 +02:00

166 lines
5.5 KiB
Matlab

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