|
@@ -0,0 +1,107 @@
|
|
|
|
+%{
|
|
|
|
+Copyright © 2020 Alexey A. Shcherbakov. All rights reserved.
|
|
|
|
+
|
|
|
|
+This file is part of GratingFMM.
|
|
|
|
+
|
|
|
|
+GratingFMM is free software: you can redistribute it and/or modify
|
|
|
|
+it under the terms of the GNU General Public License as published by
|
|
|
|
+the Free Software Foundation, either version 2 of the License, or
|
|
|
|
+(at your option) any later version.
|
|
|
|
+
|
|
|
|
+GratingFMM is distributed in the hope that it will be useful,
|
|
|
|
+but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
+GNU General Public License for more details.
|
|
|
|
+
|
|
|
|
+You should have received a copy of the GNU General Public License
|
|
|
|
+along with GratingFMM. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
+%}
|
|
|
|
+%% description:
|
|
|
|
+% multiplication of two S-matrices
|
|
|
|
+%% input:
|
|
|
|
+% SM1, SM2: S-matrices of size (n,n,2,2) or (n,2,2)
|
|
|
|
+% the multiplication order is meaningful!
|
|
|
|
+%% output:
|
|
|
|
+% SM: S-matrix of size (n,n,2,2) or (n,2,2)
|
|
|
|
+%% implementation:
|
|
|
|
+function [SM] = mul_SM(SM1, SM2)
|
|
|
|
+ if (numel(size(SM1)) == 4) && (numel(size(SM2)) == 4) % both S-matrices are full
|
|
|
|
+ if ~isequal(size(SM1),size(SM2))
|
|
|
|
+ error("mul_SM: different size input");
|
|
|
|
+ end
|
|
|
|
+ n = size(SM1,1);
|
|
|
|
+ SM = zeros(n,n,2,2);
|
|
|
|
+
|
|
|
|
+ TM = -SM2(:,:,1,1)*SM1(:,:,2,2);
|
|
|
|
+ TM(1:n+1:end) = TM(1:n+1:end) + 1;
|
|
|
|
+ TM = SM1(:,:,1,2)/TM;
|
|
|
|
+ SM(:,:,1,2) = TM*SM2(:,:,1,2);
|
|
|
|
+ SM(:,:,1,1) = SM1(:,:,1,1) + TM*SM2(:,:,1,1)*SM1(:,:,2,1);
|
|
|
|
+
|
|
|
|
+ TM = -SM1(:,:,2,2)*SM2(:,:,1,1);
|
|
|
|
+ TM(1:n+1:end) = TM(1:n+1:end) + 1;
|
|
|
|
+ TM = SM2(:,:,2,1)/TM;
|
|
|
|
+ SM(:,:,2,1) = TM*SM1(:,:,2,1);
|
|
|
|
+ SM(:,:,2,2) = SM2(:,:,2,2) + TM*SM1(:,:,2,2)*SM2(:,:,1,2);
|
|
|
|
+
|
|
|
|
+ elseif (numel(size(SM1)) == 3) && (numel(size(SM2)) == 4) % first S-matrix is diagonal
|
|
|
|
+ if size(SM1,1) ~= size(SM2,1)
|
|
|
|
+ error("mul_SM: different size input");
|
|
|
|
+ end
|
|
|
|
+ n = size(SM1,1);
|
|
|
|
+ SM = zeros(n,n,2,2);
|
|
|
|
+
|
|
|
|
+ TM = -SM2(:,:,1,1).*transpose(SM1(:,2,2));
|
|
|
|
+ TM(1:n+1:end) = TM(1:n+1:end) + 1;
|
|
|
|
+ TM = diag(SM1(:,1,2))/TM;
|
|
|
|
+ SM(:,:,1,2) = TM*SM2(:,:,1,2);
|
|
|
|
+ SM(:,:,1,1) = diag(SM1(:,1,1)) + TM*(SM2(:,:,1,1).*transpose(SM1(:,2,1)));
|
|
|
|
+
|
|
|
|
+ TM = -SM1(:,2,2).*SM2(:,:,1,1);
|
|
|
|
+ TM(1:n+1:end) = TM(1:n+1:end) + 1;
|
|
|
|
+ TM = SM2(:,:,2,1)/TM;
|
|
|
|
+ SM(:,:,2,1) = TM.*transpose(SM1(:,2,1));
|
|
|
|
+ SM(:,:,2,2) = SM2(:,:,2,2) + TM*(SM1(:,2,2).*SM2(:,:,1,2));
|
|
|
|
+
|
|
|
|
+ elseif (numel(size(SM1)) == 4) && (numel(size(SM2)) == 3) % second S-matrix is diagonal
|
|
|
|
+ if size(SM1,2) ~= size(SM2,1)
|
|
|
|
+ error("mul_SM_SMD: different size input");
|
|
|
|
+ end
|
|
|
|
+ n = size(SM1,2);
|
|
|
|
+ SM = zeros(n,n,2,2);
|
|
|
|
+
|
|
|
|
+ TM = -SM2(:,1,1).*SM1(:,:,2,2);
|
|
|
|
+ TM(1:n+1:end) = TM(1:n+1:end) + 1;
|
|
|
|
+ TM = SM1(:,:,1,2)/TM;
|
|
|
|
+ SM(:,:,1,2) = TM.*transpose(SM2(:,1,2));
|
|
|
|
+ SM(:,:,1,1) = SM1(:,:,1,1) + TM*(SM2(:,1,1).*SM1(:,:,2,1));
|
|
|
|
+
|
|
|
|
+ TM = -SM1(:,:,2,2).*transpose(SM2(:,1,1));
|
|
|
|
+ TM(1:n+1:end) = TM(1:n+1:end) + 1;
|
|
|
|
+ TM = diag(SM2(:,2,1))/TM;
|
|
|
|
+ SM(:,:,2,1) = TM*SM1(:,:,2,1);
|
|
|
|
+ SM(:,:,2,2) = diag(SM2(:,2,2)) + TM*(SM1(:,:,2,2).*transpose(SM2(:,1,2)));
|
|
|
|
+
|
|
|
|
+ elseif (numel(size(SM1)) == 3) && (numel(size(SM2)) == 3) % both S-matrices are diagonal
|
|
|
|
+ if ~isequal(size(SM1),size(SM2))
|
|
|
|
+ error("mul_SM: different size input");
|
|
|
|
+ end
|
|
|
|
+ n = size(SM1,1);
|
|
|
|
+ SM = zeros(n,2,2);
|
|
|
|
+
|
|
|
|
+ TM = SM1(:,1,2)./(1 - SM1(:,2,2).*SM2(:,1,1));
|
|
|
|
+ SM(:,1,2) = SM2(:,1,2).*TM;
|
|
|
|
+ SM(:,1,1) = SM1(:,1,1) + TM.*SM2(:,1,1).*SM1(:,2,1);
|
|
|
|
+
|
|
|
|
+ TM = SM2(:,2,1)./(1 - SM2(:,1,1).*SM1(:,2,2));
|
|
|
|
+ SM(:,2,1) = SM1(:,2,1).*TM;
|
|
|
|
+ SM(:,2,2) = SM2(:,2,2) + SM2(:,1,2).*SM1(:,2,2).*TM;
|
|
|
|
+
|
|
|
|
+ else
|
|
|
|
+ error("mul_SM: incorrect input size");
|
|
|
|
+
|
|
|
|
+ end
|
|
|
|
+end
|
|
|
|
+%
|
|
|
|
+% end of mul_SM
|
|
|
|
+%
|