Search code examples
matlabmatrixoctaveelementwise-operations

Octave error: horizontal dimensions mismatch - matrix elementwise matlab


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.


Solution

  • 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.