167 lines
5.5 KiB
Mathematica
167 lines
5.5 KiB
Mathematica
|
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
|