我有一个逻辑向量,我想在其中迭代每个n个元素。如果在任何给定的窗口中,至少有50%是1,那么我将每个元素都更改为1,否则我保持原样并移动到下一个窗口。例如
n = 4;
input = [0 0 0 1 0 1 1 0 0 0 0 1 0 1 0 1 0 0 0 1];
output = func(input,4);
output = [0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 0 0 0 1];
这个函数实现起来很简单,但是否可以使用逻辑索引应用矢量化实现?。我正在努力建立运用这项技术的直觉。
这里有一条单行线(适用于您的输入(:
func = @(input,n) input | kron(sum(reshape(input ,n,[]))>=n/2,ones(1,n));
当然,也有一些情况需要解决,但这并不能解决,如果输入的大小在n
中不相称怎么办?等我不确定这是否就是你所说的矢量化的意思,我也没有将其与for循环进行比较。。。
这里有一种方法。一旦理解,你可以用更少的行来压缩它,但为了清晰起见,我将详细介绍中间步骤。
%% The inputs
n = 4;
input = [0 0 0 1 0 1 1 0 0 0 0 1 0 1 0 1 0 0 0 1];
1( 将您的输入拆分为大小为n
的块(注意,您的最终函数必须检查input
中的元素数量是否为n
的整数倍(
c = reshape(input,n,[]) ;
给你一个矩阵,你的区块按列组织:
c =
0 0 0 0 0
0 1 0 1 0
0 1 0 0 0
1 0 1 1 1
2( 在每个块上执行您的测试条件。为此,我们将利用Matlab对sum
函数的逐列工作:
>> cr = sum(c) >= (n/2)
cr =
0 1 0 1 0
现在您有一个逻辑向量cr
,它包含与初始块一样多的元素。每个值都是块上测试条件的结果。0
块将保持不变,1
块将强制值为1
。
3( 强制1
列/块为值1
:
>> c(:,cr) = 1
c =
0 1 0 1 0
0 1 0 1 0
0 1 0 1 0
1 1 1 1 1
4( 现在剩下的就是展开你的矩阵了。你可以用几种方法:
res = c(:) ; %% will give you a column vector
或
>> res = reshape(c,1,[]) %% will give you a line vector
res =
0 0 0 1 1 1 1 1 0 0 0 1 1 1 1 1 0 0 0 1