给定像a = [ -1; 0; 1];
这样的数组。对于每个a(i)
,我需要计算一个带有linspace(min(a(i),0),max(a(i),0),3);
的线性间隔向量,其中每个linspace-vector应存储到一个矩阵中:
A = [-1 -0.5 0;
0 0 0;
0 0.5 1];
使用for循环,我可以这样做:
for i=1:3
A(i) = linspace(min(a(i),0),max(a(i),0),3);
end
如何在不使用循环的情况下实现此目的?
答案 0 :(得分:6)
我能想到的最快的方法是计算步长,使用隐式二进制扩展从中构造向量。
a = [ -1; 0; 1];
n = 3;
stepsizes = (max(a,0)-min(a,0))/(n-1);
A = min(a,0) + (0:(n-1)).*stepsizes;
<强> Timeit:强>
使用timeit
两个timeit(@SO)
结果(使用function SO()
n = 1e3;
m = 1e5;
a = randi(9,m,1)-4;
% %Wolfie
% aminmax = [min(a, 0), max(a,0)]';
% A = interp1( [0,1], aminmax, linspace(0,1,n) )';
% %Nicky
% stepsizes = (max(a,0)-min(a,0))/(n-1);
% A = min(a,0) + (0:(n-1)).*stepsizes;
% %Loop
% A = zeros(m,n);
% for i=1:m
% A(i,:) = linspace(min(a(i),0),max(a(i),0),n);
% end
%Arrayfun:
A = cell2mat(arrayfun(@(x) linspace(min(x,0),max(x,0),n),a,'UniformOutput',false));
并删除要定时的块中的注释):
arrayfun
然后时间是:
z.z.useParagraph()
:2.6298 s 答案 1 :(得分:4)
选择a = [ -1; 0; 1]
。创建最小/最大数组:
aminmax = [min(a, 0), max(a,0)].';
现在使用interp1
N = 3; % Number of interpolation points.
b = interp1( [0,1], aminmax, linspace(0,1,N) ).';
>> b =
-1.0000 -0.5000 0
0 0 0
0 0.5000 1.0000
答案 2 :(得分:0)
可能的解决方案之一是使用arrayfun
将函数应用于数组的每个元素。您还希望将结果转换为矩阵,因为输出位于单元数组中。由于arrayfun
的输出是非标量的,因此必须关闭统一输出。
cell2mat(arrayfun(@(x) linspace(min(x,0),max(x,0),3),a,'UniformOutput',false))
编辑:我在100000长阵列上使用tic-toc方法进行了一些测试。我发现,arrayfun
的解决方案需要大约。比你建议的循环时间长1.5倍。
最快的方法是使用矩阵向量运算来计算所需内容。例如,如果您只需要使用3个元素计算linspace
,则可以使用以下内容:
[min(a(:),0), (max(a(:),0)+min(a(:),0))/2 ,max(a(:),0)];
您可以将此方法概括为linspace函数中的任意数量的元素(不一定只是3)。请注意,随着代码量的增加,可读性将受到影响:
j=4; % number of elements in each linspace
b=zeros(size(a,1),j); % create a solution matrix of size Nxj
b(:,1)=min(a(:),0); %first row
b(:,end)=max(a(:),0); % last row
temp=b(:,1)+b(:,end); % sum of the first and the last row
for i=2:j-1
b(:,i)=temp*(i-1)/(j-1); % fill in intermediate rows
end
注意,在这个方法中,我遍历每个linspace中的元素数,但不是通过数组a
。对于小j(在你的例子中就像j = 3),与循环遍历数组a
的方法相比,这将更快地工作(如果你考虑像a=rand(100000,1)
这样的大数组。)