Skip to content

Commit

Permalink
Optimized helper functions for divergence
Browse files Browse the repository at this point in the history
altPascal is now calculated in a single loop. Both divergence helper and extensionOperatorDivergence now create their outputs without inserting into a sparse matrix(which is slow).
  • Loading branch information
aneeshs1729 committed Mar 2, 2025
1 parent 81aaa9b commit 49ecc1d
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 39 deletions.
16 changes: 6 additions & 10 deletions src/matlab/alt_pascal.m
Original file line number Diff line number Diff line change
@@ -1,17 +1,13 @@
function [ A ] = alt_pascal( n )
% Calculates the alternating pascal triangle.
% Will give exact values for n<56
if(n>1030); error('Argument should be less than 1031'); end
% Calculates the alternating pascal triangle up to n rows.
% This is the change of basis matrix from the basis {i in {0,1,...,n-1}:(e^(h*D)-1)^i} to
% the standard basis. {i in {0,1,...,n-1}:(e^(i*h*D))}
A=eye(n);
A(:,1)=1;
A(:,1)=2*rem(1:n,2) - 1; %Alternating vector [1,-1,1,-1,...]
for i=2:n
A(i,2:end)=A(i-1,1:end-1)+A(i-1,2:end);
end
for i=1:n
for j=1:i
A(i,j)=A(i,j)*(-1)^(i+j);
end
A(i,2:end)=A(i-1,1:end-1)-A(i-1,2:end);
end



end
2 changes: 1 addition & 1 deletion src/matlab/calculateInteriorRow.m
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
% Our answer.
r=idivide(k,int32(2));
output(r)=-1.0;
output(r+1)=1.0;
output(r+1)=1.0; %our starting value for this series is (e^(h/2*d/dx)-e^(-h/2*d/dx))
if (k>2)
nextTerm=zeros([1,k]);% NextTerm in the series.
%Initially set to (e^(h/2*d/dx)-e^(-h/2*d/dx))^(3)
Expand Down
27 changes: 19 additions & 8 deletions src/matlab/divergencehelper.m
Original file line number Diff line number Diff line change
@@ -1,14 +1,25 @@
function D=divergencehelper(k,m)
%Calculates the mimetic divergence operator of order k,
% barring dividing by dx.
% k=order of accuracy
%
r=calculateInteriorRow(k);
A=sparse(m+2,m+k-1); %This matrix is just using the interior scheme.Since we've extended our vector field
%beyond the boundaries it'd normally have, we don't need to use
%seperate power series expansions for the stencils near the boundary.
% k :order of accuracy.
% m :number of cells.
interior=calculateInteriorRow(k); %The interior row of our matrix
numNonZeros=m*k; % The number of nonZeroElements in the interior stencil matrix
rowList=zeros([1,numNonZeros]);
columnList=zeros([1,numNonZeros]);
valueList=zeros([1,numNonZeros]);
elementsInserted=1;
for i=2:(m+1)
A(i,(i-1):(i+k-2))=r;
for j=1:(k)
rowList(elementsInserted)=i;
columnList(elementsInserted)=i+j-2;
valueList(elementsInserted)=interior(j);
elementsInserted=elementsInserted+1;
end
end
D=A*extensionOperatorDivergence(k,m);
interiorScheme=sparse(rowList,columnList,valueList,m+2,m+k-1);
% This matrix is just using the interior scheme.
% Since we've extended our vector field beyond the boundaries it'd normally have, we don't need to use
% seperate power series expansions for the stencils near the boundary.
D=interiorScheme*extensionOperatorDivergence(k,m);
end
48 changes: 28 additions & 20 deletions src/matlab/extensionOperatorDivergence.m
Original file line number Diff line number Diff line change
@@ -1,22 +1,24 @@
function E=extensionOperatorDivergence(k,m)
% Returns a m+k-1 by m+1 one matrix. Which pads an m+1` point vector field
% With k/2-1 additional points on each side. These points are
% approximations of what happens if you extrapolate
% approximations of
% f(-(k/2-1)h),f(-(k/2-2)h),....,f(-h),f(1+h),f(1+2h),...,f(1+(k/2-1)h),
% with O(h^(k+1)) error on each of the approximations.
%
%
% Parameters:
% k : Order of accuracy
% m : Number of cells

E=sparse(m+k-1,m+1);
numOfRows=m+k-1;
numOfColumns=m+1;
numNonZeros=(k-2)*(k+1)+m+1;%The number of nonzero elements in E.
rowList=zeros([1,numNonZeros]);%Row indices for non zero elements
columnList=zeros([1,numNonZeros]); %Column indices for non zero elements
valueList=zeros([1,numNonZeros]); %Values of non zero elements
elementsInserted=1; %Number of elements inserted into rowList,ColumnList
%and ValueList
r=idivide(k,int32(2));
for i=r:m+r
E(i,i+1-r)=1;
end
R=zeros(r-1,k+1);%calculates the matrix R_{i,j}=binom(i-k/2,j)
%Used in the fact that e^(-jh)=∑_{i=0}^(k)binom(-j,i)(exp(h*d/dx)-I)^i+O(h^(k+1)).
% This is how you approximate f(-jh) as a linear combo of
%f(0),f(h),...,f(kh) with O(h^(k+1)).
R=zeros(r-1,k+1);% Calculates the matrix R_{i,j}=binom(i-k/2,j-1)
R(:,1)=ones([r-1,1]);
currentTerm=(-1);
for i=2:(k+1)
Expand All @@ -28,18 +30,24 @@
R(i,j)=R(i+1,j)-R(i,j-1);
end
end

% A=[(-1)^(i+j)*binomial(i,j) for i=0:k,j=0:k]
R=R*alt_pascal(k+1)
for i=1:(r-1)
R=R*alt_pascal(k+1); %Converts R into the standard basis
for i=1:(r-1) %
for j=1:(k+1)
E(i,j)=R(i,j);
E(m+k-i,m+2-j)=R(i,j);
rowList(elementsInserted)=i;
columnList(elementsInserted)=j;
valueList(elementsInserted)=R(i,j);
rowList(elementsInserted+1)=m+k-i;
columnList(elementsInserted+1)=m+2-j;
valueList(elementsInserted+1)=R(i,j);
elementsInserted=elementsInserted+2;
end
end




for i=r:m+r
rowList(elementsInserted)=i;
columnList(elementsInserted)=i+1-r;
valueList(elementsInserted)=1;
elementsInserted=elementsInserted+1;
end
E=sparse(rowList,columnList,valueList,numOfRows,numOfColumns);

end

0 comments on commit 49ecc1d

Please sign in to comment.