假设我想将一个单元格数组的每个元素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 …
我有一个索引数组I和值X,并且想要生成一个单元格数组C,因此C {i} = X(I == i).计算C的最快和最好的方法是什么?
最直接的方法是评估C{i} = X(I==i)I中的所有唯一i(方法1):
for i = unique(I)
C{i} = X(I == i);
end
Run Code Online (Sandbox Code Playgroud)
另一个天真的方法是循环遍历I中的所有i并将相应的x追加到C(方法2):
C = cellfun(@(x)(zeros(1,0)),cell(1,max(indices)),'UniformOutput',false);
for j = 1:length(I)
i = I(j);
C{i} = cat(2,C{i},X(j));
end
Run Code Online (Sandbox Code Playgroud)
这两种方法都不是很快.要进行基准测试,让我们生成一些测试数据:
I = floor(rand(1,N)*M)+1;
X = rand(1,N);
Run Code Online (Sandbox Code Playgroud)
采用N = 1000000, M = 1000这两种方法:
方法1最好(仍然非常慢).更改问题的参数以N = 1000000, M = 10000显着改变事物:
基本上,这两种方法都是数量级太慢.评估C的最佳方法是什么?
编辑:正确答案显然是Jonas的下方.我附上基准测试结果供参考.与上述方法相比,C中元素的顺序不同.除此之外,以下给出相同的输出:
C = accumarray(I',X,[],@(x){x'})';
Run Code Online (Sandbox Code Playgroud)
N = 100000, M = 1000:0.0397秒N = 100000, M …所以我在这里有这个代码,(现在)只需将base1号码转换为基数为10的数字
/**
* This function is supposed to convert 'number' from base1 to a number in base2.
* It isn't fully implemented yet, and I've only converted base1 to a base 10 number.
*/
void base1_base2(int base1, int base2, int number) {
int num, place = 0;
int rem = number;
int i;
for (i = 0; i < num_digits(number); i++) {
int mod = rem % 10;
rem = floor(rem / 10);
int powerResult = pow(base1, place++);
num = …Run Code Online (Sandbox Code Playgroud)