MATLAB中向量间冒号(:)值概念的向量化

vshtjzan  于 2023-01-21  发布在  Matlab
关注(0)|答案(4)|浏览(224)

我有两个向量idx1idx2,我想得到它们之间的值,如果idx1idx2是数字而不是向量,我可以用下面的方法来实现:

idx1=1;
idx2=5;
values=idx1:idx2 

% Result
 % values =
 % 
 %    1     2     3     4     5

但是在我的例子中,idx1idx2是可变长度的向量,例如,长度=2:

idx1=[5,9];
idx2=[9 11];

我可以使用冒号运算符直接获得中间的值吗?这是类似于下面的内容:

values = [5     6     7     8     9     9    10    11]

我知道我可以做idx1(1):idx2(1)idx1(2):idx2(2),也就是说,分别提取每列的值,所以如果没有其他的解决方案,我可以用一个for循环来做,但是也许Matlab可以更容易地做。

gfttwv5a

gfttwv5a1#

您的示例输出不法律的。矩阵中不能有不同长度的行。您只能使用arrayfun创建单元格数组:

values = arrayfun(@colon, idx1, idx2, 'Uniform', false)

要将生成的单元格数组转换为矢量,可以使用cell2mat

values = cell2mat(values);

或者,如果生成的单元格数组中的所有向量都具有相同的长度,则可以按如下方式构造输出矩阵:

values = vertcat(values{:});
3ks5zfa0

3ks5zfa02#

尝试取集合的并集。给定您提供的idx1idx2的值,运行

values = union(idx1(1):idx1(2), idx2(1):idx2(2));

这将根据需要产生具有值[5 6 7 8 9 10 11]的矢量。

djmepvbi

djmepvbi3#

我无法让@Eitan的解决方案工作,显然你需要指定冒号的参数。下面的小修改让它在我的R2010 b版本上工作:

step = 1; 
idx1 = [5, 9];
idx2 = [9, 11];
values = arrayfun(@(x,y)colon(x, step, y), idx1, idx2, 'UniformOutput', false);
values=vertcat(cell2mat(values));

请注意,step = 1实际上是colon中的默认值,并且可以使用Uniform代替UniformOutput,但是为了完整起见,我将它们包括在内。

vmdwslir

vmdwslir4#

  • Loren* 写了一篇很棒的博客文章,叫做Vectorizing the Notion of Colon (:),它给出的答案比使用arrayfunfor循环快5倍(对于大型数组),并且类似于游程解码:

我们的想法是扩展冒号序列。我知道每个序列的长度,所以我知道输出数组中的起始点。用1填充起始值之后的值。然后我计算出从一个序列的末尾跳到下一个序列的开头的距离。如果有重复的起始值,跳跃可能是负的。一旦这个数组被填充,输出仅仅是序列的累积和或Cumsum。

function x = coloncatrld(start, stop)
% COLONCAT Concatenate colon expressions
%    X = COLONCAT(START,STOP) returns a vector containing the values
%    [START(1):STOP(1) START(2):STOP(2) START(END):STOP(END)].

% Based on Peter Acklam's code for run length decoding.
len = stop - start + 1;

% keep only sequences whose length is positive
pos = len > 0;
start = start(pos);
stop = stop(pos);
len = len(pos);
if isempty(len)
    x = [];
    return;
end

% expand out the colon expressions
endlocs = cumsum(len);  
incr = ones(1, endlocs(end));  
jumps = start(2:end) - stop(1:end-1);  
incr(endlocs(1:end-1)+1) = jumps;
incr(1) = start(1);
x = cumsum(incr);

相关问题