相关疑难解决方法(0)

arrayfun可能比matlab中的显式循环慢得多.为什么?

考虑以下简单的速度测试arrayfun:

T = 4000;
N = 500;
x = randn(T, N);
Func1 = @(a) (3*a^2 + 2*a - 1);

tic
Soln1 = ones(T, N);
for t = 1:T
    for n = 1:N
        Soln1(t, n) = Func1(x(t, n));
    end
end
toc

tic
Soln2 = arrayfun(Func1, x);
toc
Run Code Online (Sandbox Code Playgroud)

在我的机器上(Linux Mint 12上的Matlab 2011b),该测试的输出是:

Elapsed time is 1.020689 seconds.
Elapsed time is 9.248388 seconds.
Run Code Online (Sandbox Code Playgroud)

什么了?!?arrayfun虽然公认的解决方案更清洁,但速度要慢一个数量级.这里发生了什么?

此外,我做了类似的测试方式cellfun,发现它比显式循环慢约3倍.同样,这个结果与我的预期相反.

我的问题是:为什么是arrayfuncellfun这么多慢?鉴于此,有没有充分的理由使用它们(除了使代码看起来很好)?

注意:我说的是arrayfun这里的标准版本,而不是并行处理工具箱中的GPU版本.

编辑:为了清楚起见,我知道 …

arrays performance matlab

103
推荐指数
1
解决办法
2万
查看次数

对单元数组的每个元素执行算术运算的最快方法是什么?

假设我想将一个单元格数组的每个元素A与一个系数相乘k.我可以这样做:

A = cellfun(@(x) k*x, A, 'UniformOutput', false)
Run Code Online (Sandbox Code Playgroud)

但这非常缓慢.有更快更好的方法吗?单元阵列元素是可变长度向量,因此cell2num不适用.

编辑:基于fpe对for循环推荐,这是一个示例基准.从这些数据开始

A = arrayfun(@(n) rand(n,1), randi(5,1000,1000), 'UniformOutput',false);
Run Code Online (Sandbox Code Playgroud)

cellfun上面的调用需要9.45 seconds,而for循环:

A2 = cell(size(A));
for i = 1:size(A,1), for j = 1:size(A,2), A2{i,j} = A{i,j}*k; end; end
A = A2;
Run Code Online (Sandbox Code Playgroud)

需要1.67 seconds,这是一个重大的进步.我仍然更喜欢几个数量级的东西.(我也不明白为什么Matlab解释器无法像for循环一样快地进行cellfun调用.它们在语义上是相同的.)

编辑2: Amro建议制作一个单循环的速度要快得多:

for i = 1:numel(A), A{i} = A{i}*k; end
Run Code Online (Sandbox Code Playgroud)

需要1.11 seconds,如果我pack在它之前运行,只是调整内存0.88 seconds.

实现MEX函数实现这一点实际上并没有好多少:0.73 seconds,(0.53 seconds …

arrays performance matlab loops

5
推荐指数
1
解决办法
1255
查看次数

我何时以及为什么应该在 Matlab 中使用 cellfun?

我对cellfunMATLAB 中的函数有疑问。

我什么时候/为什么要使用它,什么时候我也可以放弃它?

一个简单的例子:假设我有一个 cell a,我想找到 中所有值的平均值a

a{1} = [1 2;3 4];
a{2} = [1 2 3;4 5 6; 7 8 9];
Run Code Online (Sandbox Code Playgroud)

我的方法是这样的:

mean([a{1}(:); a{2}(:)])
Run Code Online (Sandbox Code Playgroud)

什么是合适的cellfun版本,它会更好吗?

我试过做这样的事情,(显然不起作用):

mean_a = mean(cellfun(@mean, a,'UniformOutput',0))
Run Code Online (Sandbox Code Playgroud)

谢谢!

matlab cell

5
推荐指数
1
解决办法
1万
查看次数

通过来自另一个单元阵列的索引对数组求和

我有一个数组:

a = [109, 894, 566, 453, 342, 25]
Run Code Online (Sandbox Code Playgroud)

和另一个子索引的单元格数组a,表示为:

subs = { [1,3,4], [2,5,6], [1,3], [3,4], [2,3,4], [6] };    
Run Code Online (Sandbox Code Playgroud)

我想避免for循环通过MATLAB计算以下求和:

for i=1:6
    sums_a(i) = sum(a(subs{i}));
end
Run Code Online (Sandbox Code Playgroud)

有没有快速的方法arrayfun来实现这个?谢谢.

matlab vectorization matrix-indexing

5
推荐指数
2
解决办法
225
查看次数

在MATLAB中创建循环以找到方法

所以我在MATLAB中有2个矩阵.如果其中一个是100 X 2矩阵,如下所示:

[a b]
[13 19]
[21 39]
[35 45] 
Run Code Online (Sandbox Code Playgroud)

等.等.

另一个矩阵是NX 1矩阵,其值如下:

[1]
[3]
[5]
[7]
Run Code Online (Sandbox Code Playgroud)

等.等.

我要做的是找到第二个矩阵的'a'到'b'的所有元素的Mean值.

到目前为止我得到的是:(如果我的第一个矩阵被称为:MATRIX1

第二个矩阵称为:MATRIX2)

a= MATRIX1(1:1)
b= MATRIX1(1:2)
values = MATRIX2(a:b)
mean(values)
Run Code Online (Sandbox Code Playgroud)

这给了我我想要的,从a到b的值的平均值.但是如何创建循环以便我可以自动为MATRIX 1中的所有行执行此操作?

谢谢!

更新:我想出了如何获得循环,但现在我不知道如何获取所有值并使其成为100 X 1矩阵.这是我使用的代码:

c= size(MATRIX1,1);

for k= 1:c;
    a= MATRIX1(k,1);
    b= MATRIX1(k,2);
    values= MATRIX2(a:b);
    d= mean(values)
end
Run Code Online (Sandbox Code Playgroud)

有了这个,我得到100的d值.如何将这些值放入100 X 1矩阵?

matlab

1
推荐指数
1
解决办法
5795
查看次数

如何在Matlab中向单元格数组的每个单元格插入一个数字?

我有一个像这样的单元格数组:

    a = {[1 2 3]; [4 5]; [6 7 8 9]};
Run Code Online (Sandbox Code Playgroud)

并希望在每个单元格的开头插入10,以便:

    >> a{:}

    ans =

        10     1     2     3

    ans =

        10     4     5

    ans =

        10     6     7     8     9
Run Code Online (Sandbox Code Playgroud)

没有任何for循环可以做到吗?

matlab cell-array

1
推荐指数
1
解决办法
1247
查看次数