123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107 |
- %{
- 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
- %
|