Vectorizing a function looking for eigenvalues of a matrix

In short, I have a function that defines a matrix based on an input value, and then returns the eigenvalue of that matrix that is closest to 1. I want to plot this for different inputs, but I get the following warning:
'Warning: Function behaves unexpectedly on array inputs. To improve performance, properly vectorize your function to return an output with the same size and shape as the input arguments.'
Is it possible to vectorize this function in order to plot it properly (and without waiting a very long time)?
My code looks somewhat like this (if necessary I can post the entire code but it's pretty long).
eigenvalue = @eigenvalue_func
fplot(eigenvalue)
function eta = eigenvalue_func(z)
p = 1:1:100;
q = p;
weights = rand(100,1); %in reality I'm using a distribution for p, q and the weights based on Gaussian Quadrature
[Q, P] = meshgrid(q,p);
[W, ~] = meshgrid(weights, p);
v_0 = -30./(P.*Q.*(P.^2-Q.^2).*2.*pi.^2).*(Q.*cos(Q).*sin(P)-P.*cos(P).*sin(Q));
A = -4.*pi.*v_0.*(Q.^2 - z ).^(-1).*Q.^2.*W;
for j = 1:100 %the diagonal has to be defined differently since the above returns NaN/Inf (I take the limit here)
v_0(j,j) = -30./(2.*pi^2.*P(j,j).^2).*(0.5-(sin(2.*P(j,j)))./(4.*P(j,j)));
A(j,j) = -4.*pi.*v_0(j,j).*(Q(j,j).^2 - z).^(-1).*Q(j,j).^2.*W(j,j);
end
eta_full = eigs(A, 20);
[~, index_eigenvalue] = min(abs(eigs(A, 20)-1));
eta = eta_full(index_eigenvalue);
end

댓글 수: 6

At least you should show us which call to the function "eigenvalue_func" generated the error message you mention.
Torsen it is called internally by
fplot(eigenvalue)
I don't think you can: z in the context inside the function has to be a scalar, right? The error would come from fplot wanting to feed it vector z of arbitrary length, so it is not generally compatible to subtract from array of size(Q).
z is indeed a scalar. I was hoping there was some clever way of doing it but all I could think of would be to use a for loop to take the difference elementwise (for z as a vector) but I don't think that will speed things up at all
The bottleneg is probably calling EIGS (have you made any profiler of your code?) which cannot be vectorized at the moment, and possibly fplot waste a lot of time to find the interval and resolution to plot the function.
If you want faster plot, change fplot and eigs.
For instant it is totally iefficient to call twice eigs with 20 eigenvalues
eta_full = eigs(A, 20);
[~, index_eigenvalue] = min(abs(eigs(A, 20)-1));
eta = eta_full(index_eigenvalue)
where you can get the same result with
eta = eigs(A,1,1);
Since eigs is not internally vectorized, it might make sense to define a function that accepted a vector of z values, and used background pool to evaluate multiple z in parallel.

댓글을 달려면 로그인하십시오.

답변 (1개)

Walter Roberson
Walter Roberson 2022년 10월 25일
wrapper = @(z) arrayfun(eigenvalue, z)
fplot(wrapper)

카테고리

도움말 센터File Exchange에서 Linear Algebra에 대해 자세히 알아보기

제품

릴리스

R2019b

질문:

2022년 10월 25일

댓글:

2022년 10월 25일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by