What is the fastest way to apply a function in each row of a matrix?

I searched so far, and I know that there are several ways ( 1 , 2 , 3 , 4 ) so far I have used the following code:

Fv_calc(:,2) = arrayfun(@(n) MaxPositiveRoot2DegreePolynomial(QuadraticCoefficients(n,:)), 1:size(QuadraticCoefficients,1));  

Where MaxPositiveRoot2DegreePolynomial is the following function:

function root = MaxPositiveRoot2DegreePolynomial(c)
    d = c./c(1);
    root = eig([0 -d(3);1 -d(2)]);
    condition = root == abs(root);
    root = root(condition);
    if isempty(root)
        root = 0;
    end
    root = max(root);
end  

Where quadratic coefficients - 62271x3 matrix, each row contains the coefficients a, b, cgeneral quadratic equation. ax^2+bx+c As for the problem that I am solving, all the roots will be real, so I used the modified function to find the roots so as not to waste time checking if the root is real or not.
Having profiled the code, I found that each function run MaxPositiveRoot2DegreePolynomialtakes about 0.000047 seconds, which is about 2.914925371 seconds for 62271 runs. But the code

Fv_calc(:,2) = arrayfun(@(n) MaxPositiveRoot2DegreePolynomial(QuadraticCoefficients(n,:)), 1:size(QuadraticCoefficients,1));  

3.198597803 is running to run. Thus, about 0.283672431 is taken just arrayfun. I want to see if there is a way to reduce this time?

+4
1

, , . , .

Matlab, Matlab R2015b JIT -Compiler, , , .

[n,~] = size(C);
%// division
d = bsxfun(@rdivide,C,C(:,1));
%// create blocks for eigen matrix block procession
X = ( [zeros(n,1) ones(n,1) -d(:,3) -d(:,2)] ).'; %'
Y = reshape(X,2,[]);
%// use block processing to get eigenvalues of blocks
rt = blockproc(Y,[2 2],@(x) eig(x.data) ).'; %'
%// check if eigen values are real positives
condition = rt == abs(rt);
%// output filter
out = rt(condition);

Benchmark

function [t] = bench()
    %// load your data
    DATA = load('matlab');
    C = DATA.QuadraticCoefficients;

    % functions to compare
    fcns = {
        @() thewaywewalk(C);
        @() sepideh(C);
    };

    % timeit
    t = zeros(2,1);
    for ii = 1:10;
        t = t + cellfun(@timeit, fcns);
    end
end

function out = thewaywewalk(C)  %thewaywewalk
    [n,~] = size(C);
    d = bsxfun(@rdivide,C,C(:,1));
    X = ( [zeros(n,1) ones(n,1) -d(:,3) -d(:,2)] ).'; %'
    Y = reshape(X,2,[]);
    rt = blockproc(Y,[2 2],@(x) eig(x.data) ).'; %'
    condition = rt == abs(rt);
    out = rt(condition);
end
function out = sepideh(C)  %sepideh
    [n,~] = size(C);
    out = zeros(n,1);
    for ii = 1:n
        c = C(ii,:);
        d = c./c(1);
        rt = eig([0 -d(3);1 -d(2)]);
        condition = rt == abs(rt);
        rt = rt(condition);
        if isempty(rt)
            rt = 0;
        end
        rt = max(rt);
        out(ii) = rt;
    end
end

ans =

    12.2086  %// thewaywewalk
     9.2176  %// sepideh

if-.

0

All Articles