I can not say wether Eigs is giving expected results or not
56 次查看(过去 30 天)
显示 更早的评论
Hello,
I am building a little mode solver for optical fibers based on this article : "Jesper Riishede et al 2003 J. Opt. A: Pure Appl. Opt. 5 534". As explained in the article I need to get the eigenvalues and eigenvectors of my matrix Phi. Since it is a large sized one I turned Phi into a sparse matrix and used eigs on it. But when I compute a simple "Phi*eigenvectors-eigenvectors*eigenvalues" I do not get small values <<1. The flag says eigs converged toward the solution without issue? I know based on what I expect to get from the simulation that the result is completely false but I do not know yet what to blame in my code.
So here is my question : Is there a scaling factor in the Phi*eigenvectors-eigenvectors*eigenvalues based on how big the initial values were, and eigs indeed converged or did it simply failed to reach an accurate solution? Or is there another issue?
Here is a sample of my code (the loop does not make sense but I had to break it to look for where I might have gone wrong a little bit faster since it fails on every iteration).
%%Function topology for DCF design
format long
%%Define the space for the study-----------------------------------
sizeX=25e-6;
sizeY=25e-6;
l=100;
m=100;
d=sizeX/l;
x=-sizeX/2:d:sizeX/2;
y=-sizeY/2:d:sizeY/2;
[xx,yy]=meshgrid(x,y);
n=zeros(size(xx));
Phi=zeros(m*l);
dPhi=sizeX/(l*m);
xX=-sizeX/2:dPhi:sizeX/2;
yY=-sizeY/2:dPhi:sizeY/2;
%%%%%%%%%%%%%%%%%%%%%%%%Iterate over 3 wl%%%%%%%%%%%%%%%%%%%%%%%%%%
%Basic physical parameters-----------------------------------------
A=readmatrix("C:\Users\Tessonneau Hugo\Desktop\Sellmeier Du goat2.txt");
lambdac=1030e-9;
dlambda=0.5e-9;
rcoreIni=5e-6;
rclad=125e-6;
nbg=1;
neff=[];
lambdac0=1535e-9;
lambdacmax=1575e-9;
for lambda0=lambdac0:5e-9:lambdac0%lambdac-dlambda:dlambda:lambdac+dlambda
n_SiO2=interp1(A(:,1)*1e-9,A(:,9),lambda0,'spline');
k0=2*pi/lambda0;
lambda0
%Initial design guess----------------------------------------------
nmin=n_SiO2;
nmax=sqrt(0.14^2+n_SiO2^2);
gammaicore=1;
gammaiclad=0.25;
% nicore=nmin+gammaicore*(nmax-nmin);
% niclad=nmin+gammaiclad*(nmax-nmin);
nicore=n_SiO2+0.38;
niclad=n_SiO2;
n=n*0+nbg;
n(xx.^2+yy.^2<rclad^2)=niclad;
n(xx.^2+yy.^2<rcoreIni^2)=nicore;
% figure(1);
% surf(xx,yy,n,'EdgeColor','none')
%Define Phi based on Helmoltz equation---------------------------------
% N=zeros(size(Phi));
for ii=1:1:l*m
for jj=1:1:l*m
% N(ii,jj)=n(floor(ii/l)+1,floor(jj/m)+1);
if(ii==jj)
Phi(ii,jj)=-4/dPhi^2+n(floor(ii/l)+1,floor(jj/m)+1)^2*k0^2;
elseif(ii==jj+1 || ii==jj-1 || jj==ii-1 || jj==ii+1)
Phi(ii,jj)=1/dPhi^2;
end
end
end
%%Eigenvalues calc--------------------------------------------------
Atest=sparse(rand(l*m));
Phi=sparse(Phi);
[eigenvector,eigenvalues,flag]=eigs(Phi,100,'largestabs','MaxIterations',1000000);
beta2=diag(eigenvalues);
Psi=eigenvector;
neff=[neff sqrt(beta2)./k0];
end
Thanks!
3 个评论
Torsten
2025-9-4,19:51
The matrix A is missing.
Where do you test
Phi*eigenvectors-eigenvectors*eigenvalues = 0
in your code ?
采纳的回答
John D'Errico
2025-9-4,20:03
编辑:John D'Errico
2025-9-4,20:14
It is literally trivial to get large differences there. We need not even use eigs. Eig will suffice.
A0 = randn(6); A0 = A0 + A0'; % I'll be nice and make the eigenvalues at least real.
[V0,D0] = eig(A0);
I'm sure you would agree that this problem is easy to solve using eig.
A0*V0-V0*D0
And so we see tiny numbers for a difference.
The probem is, you have numbers with wide ranges of magnitudes. And that suggests it is very likely that your problem is not terribly well-scaled as is my A0. As such, I'll modify A0 by just a very simple scale factor.
A1 = A0*1e15;
[V1,D1] = eig(A1);
A1*V1-V1*D1
Note that now the differences are on the order of 1.
So look carefully at your matrix. Look at the eigenvalues it found.
diag(D1)
You might expect to see differences in there on the order of roughly
eps(sum(abs(diag(D1))))
For the original array, we had
eps(sum(abs(diag(D0))))
As such, you CANNOT just compare that difference to 1, and hope the result will be much smaller than 1. You need to consider the magnitude of what is in the array to choose a "tolerance". (I could arguably have used other similar measures, that arguaby would have also been reasonable. But in any case, 1 is not a reasonable value to compare to.)
In the case of a sparse matrix, you cannot compare to the eigenvalues themselves, but we might as well have used something like this:
tol = eps(sum(abs(A1),'all'))
And that would have given a reasonable comparison value, Probably a little conservative, but not by a lot.
3 个评论
John D'Errico
2025-9-4,23:19
But scaling Phi by some costant does not do anything meaningful. That scaling simply gets applied to the eigenvalues. The eigenvectors would stay the same. In a relative sense, it does nothing to improve anything about the problem.
It might suggest some questions. First, there may be a problem in the code, building the matrices incorrectly. Not like I've never made a mistake in code. :) So this is one thing you could check. Or possibly assumptions you made in the model may have been inadequate. I've not a clue as to what the code models.
Next, that you only got a limited subset of the eigensystem from eigs may be an issue. You got the 100 largest eigenvalues. Was that sufficient? Maybe, maybe not. So you might check to see if more eigenvalues from eigs would help.
更多回答(0 个)
另请参阅
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!