-2
k = linspace(0,0.5)'
h = 6.58212 * 10^-16

m_0 = 9.109383 * 10^-31
E_c = ( h^2 * k.^2 ) / ( 10^-5 * m_0 )
A = [E_c, 1, 2; 3, 4, 5; 6, 7, 8]

When I run this code, I get:

error: horizontal dimensions mismatch (100x1 vs 1x1)
error: called from
    physics at line 42 column 3

I would like to calculate the eigenvalues. But that requires first having a matrix which is not crashing. I realize E_c is a 100x1 vector which I'm trying to insert into the first slot of a 3x3 matrix A and this slot is of size 1x1. Do I need to use elementwise to do this?

We want to find the eigenvalues values where one of the matrix element is a function.

Joel
  • 665
  • 2
  • 9
  • 23
  • `k` is a `100x1` vector therefore `E_c` is also a `100x1` vector then you are trying to insert this `100x1` vector into the first slot of a `3x3` matrix `A` and this slot is of size `1x1`. What is `E_c` supposed to be in your equations? – StaticBeagle Jul 11 '18 at 03:29
  • 1
    Joel, you really should add your expected result. In this case you are just throwing some code at us: "Doesn't work, any ideas?". The code works exactly as you wrote it so there is a difference between how you think what the code would do and what it actually does. I hope you see that it's important to tell us what you would expect from that snippet? – Andy Jul 11 '18 at 04:17
  • @StaticBeagle , I updated with some more information – Joel Jul 12 '18 at 14:15
  • we want to find the eigenvalues values where one of the matrix element is a function. – Joel Jul 12 '18 at 15:27
  • 1
    "We want to find the eigenvalues values where one of the matrix element is a function." -- Do you mean that you want to find the eigenvalues of a matrix, and see those eigenvalues change as you change one of the values of the matrix? You'll need to loop for that, do a different value of `k` every time. Or you could do this symbolically, maybe? I mean you can write out the expressions for the eigenvalues of a 3x3 matrix. – Cris Luengo Jul 12 '18 at 16:15
  • @CrisLuengo, " Do you mean that you want to find the eigenvalues of a matrix, and see those eigenvalues change as you change one of the values of the matrix?" Yes, that is correct. Linspace will return a row vector with 100 linearly spaced elements between 0 and 0.5. I want to substitute all 100 of those elements into the matrix and get the eigenvalues for each. – Joel Jul 12 '18 at 17:45
  • 1
    Then write a loop. It's the easy approach. I know there is a strong aversion against loops, but I don't think 100 iterations is going to kill you. :) – Cris Luengo Jul 12 '18 at 17:47
  • Ahhh I see Once k is defined, i can iterate over the vector yeah? I'm not at home right now to try. – Joel Jul 12 '18 at 17:50

1 Answers1

0

Here are some possibilities, I added tic/toc to measure the execution time.

k = linspace(0,0.5)';

h = 6.58212 * 10^-16;   
m_0 = 9.109383 * 10^-31;
E_c = ( h^2 * k.^2 ) / ( 10^-5 * m_0 );

%% method 1
%% arrayfun, no explicit loop, explicit calculation
tic
ev1 = arrayfun(@(x)eig([x 1 2; 3 4 5; 6 7 8]), E_c', 'unif', false);
ev1 = cell2mat(ev1);
toc

%% method 2
%% arrayfun, no explicit loop, function handle
tic
funEigA = @(x)eig([x 1 2; 3 4 5; 6 7 8]);
ev2 = arrayfun(funEigA, E_c', 'unif', false);
ev2 = cell2mat(ev2);
toc

%% method 3
%% explicit loop, with pre allocation of matrix, explicit calculation, no function handle in loop
tic
ev3 = zeros(length(funEigA(0)),length(E_c)); % evaluate funEigA to determin the number of eigen values. In this case this is 3, because it's a 3x3 matrix.
for ik = 1:length(E_c)
    ev3(:,ik) = eig([E_c(ik) 1 2; 3 4 5; 6 7 8]);
end
toc

%% method 4
%% with pre allocation of matrix, explicit loop & call of function handle
tic
ev4 = zeros(length(funEigA(0)),length(E_c));
for ik = 1:length(E_c)
    ev4(:,ik) = funEigA(E_c(ik));
end
toc

%% method 5
%% without pre allocation, explicit loop, call of function handle
tic
ev5 = [];
for val = E_c' % k must be a column vector
    ev5(:,end+1) = funEigA(val);
end
toc

If you're interested in the performance of each method, here is my output (Lenovo T450, Core i7, 3.2 GHz):

Elapsed time is 0.010564 seconds.
Elapsed time is 0.007659 seconds.
Elapsed time is 0.008660 seconds.
Elapsed time is 0.008498 seconds.
Elapsed time is 0.009461 seconds.

Or, after 1000 runs: enter image description here

Personally, I like method #1 and #2, because it's short and clear what's happening. But indeed they are slower and for large k or big matrices using cell arrays could become even much less performant than usign preallocated matrices.

If you want to measure the execution speed a multiple times, please ensure you're using clear all beforehand, otherwise the results could be cached.

Jan
  • 310
  • 1
  • 7
  • Just stumbled across that answer. Here are some results on a recent laptop, i7-11850H @ 2.50 GHz, using Matlab 2032a. Method 1: 0.001473 seconds, method 3 and 4: 0.000512 seconds. So method 1 got a speedup of ~3.3, method 4 and 5 got a speedup of ~3.5 – Jan Apr 19 '23 at 14:14