应用于数组的Linspace

时间:2018-03-05 16:08:23

标签: matlab vectorization

给定像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

如何在不使用循环的情况下实现此目的?

3 个答案:

答案 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

然后时间是:

  • Wolfie:2.2243 s
  • 我的:0.3643 s
  • 标准循环:1.0953 s
  • 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)这样的大数组。)