>假设我们想创建一个具有以下模式的向量:
[1 3 5 7 9]
我们可以很容易地写
1:2:10
但是如果我想拥有这种模式,我应该写什么:
[1 2 5 6 9 10 13 14 17 18 ....]
?
这背后的想法是我有一个长列矩阵:
[-0.41416 0.37756 -3.39666 -0.42352 0.83481 -0.66782 -0.75471 0.54008 -0.60284 -1.43141 -1.10128 -0.18244]
我想把它变成:
[-0.41416 0.37756 0 0 -3.39666 -0.42352 0 0 0.83481 -0.66782 0 0 -0.75471 0.54008 0 0 -0.60284 -1.43141 0 0 -1.10128 -0.18244 0 0]
对于每 2 个值,我想添加两个零。
如果我只想在每个值之间有 0 零,这就是我解决它的方法。
l = length(g);
nu = rows(g);
G = zeros(nu, l*nu);
for i = 1:nu
G(i, i:nu:l*nu-1+i) = g(i, 1:l);
end
g = G;
该代码将改变此模式
[1.4392e-04 5.6149e-07 1.4572e-04 -1.1104e-05 1.4720e-04 -3.3176e-05 1.4836e-04
2.4174e-04 6.5988e-06 2.7917e-04 5.3787e-06 3.1924e-04 1.0706e-06 3.6204e-04]
进入此模式:
[0.000221 0.000000 -0.000420 0.000000 0.000570 0.000000 -0.000418 0.000000
0.000000 0.017647 0.000000 -0.002033 0.000000 0.017248 0.000000 -0.001855]
您可以堆叠两个行向量(第二个等于 1 加上第一个),然后重新塑造它:
>> a=[1:4:17];
>> b=reshape(vertcat(a,a+1),1,[])
b =
1 2 5 6 9 10 13 14 17 18
同样的想法延伸到你的第二个"这背后的原因"的例子:
>> c=[-0.41416 0.37756 -3.39666 -0.42352 0.83481 -0.66782 -0.75471 0.54008 -0.60284 -1.43141 -1.10128 -0.18244];
>> d=reshape(c,2,[]);
>> e=reshape(vertcat(d,0*d),1,[])
e =
Columns 1 through 12
-0.4142 0.3776 0 0 -3.3967 -0.4235 0 0 0.8348 -0.6678 0 0
Columns 13 through 24
-0.7547 0.5401 0 0 -0.6028 -1.4314 0 0 -1.1013 -0.1824 0 0
我将展示如何完成您实际想要完成的任务,而不是回答标题中的问题:在每两个数据值后插入两个零。
为此,我们将向量重塑(这基本上是免费的,没有复制任何数据)以具有 2xN 元素。现在我们添加两行零,并再次将矩阵重塑为列向量:
M = [-0.41416 0.37756 -3.39666 -0.42352 0.83481 -0.66782 -0.75471 0.54008 -0.60284 -1.43141 -1.10128 -0.18244].';
M = reshape(M,2,[]);
M = [M;zeros(size(M))];
M = reshape(M,[],1);
M = M(1:end-2); % remove the last two zeros, which we don't want
当然,这仅适用于偶数大小的数组。对于奇数大小的数组,我们先添加一个零,然后在以下之后将其删除:
M = [-0.41416 0.37756 -3.39666 -0.42352 0.83481 -0.66782 -0.75471 0.54008 -0.60284 -1.43141 -1.10128].';
M = reshape([M;0],2,[]); % note we add a zero here
M = [M;zeros(size(M))];
M = reshape(M,[],1);
M = M(1:end-3); % remove the last three zeros, which we don't want
你不需要任何数学运算;你确实可以利用MATLAB的MAT部分,如下所示:
- 生成所需数组的奇数索引元素的数组,
- 将 1 加到它以获得偶数索引元素的数组, 垂直连接两行,
- 从而得到一个包含两行的矩阵,
- 逐列矢量化矩阵,
- 转置它,如果你真的需要一行。
n = 100;
x = 1:4:n;
x = [x; x + 1];
x = x(:)';
这会在出站向量中生成偶数个元素。如果需要奇数,请使用具有适当n
的相同代码,并将最后一行更改为:
x = x(1:end-1)';
一个试图解决任意长度的答案,而不是依赖于长度被 2 或 4 除以
。在处理此类任务时,我喜欢以简短的文本或数学方式描述模式,这通常会导致我可以实现的东西。这里"从 1 到 n 的所有数字,除以 4 时余数为 1 或 2">
>> n=9;
>> find(ismember(mod(1:n,4),[1,2]))
ans =
1 2 5 6 9
这允许您设置最大值n
.如果您想设置列表中的元素数量m
我将使用以下代码:
>> m = 7;
>> [1:m]*2-(mod([1:m],2)==0)-1
ans =
1 2 5 6 9 10 13
这背后的想法,你的模式是2 4 6 8,递减1,然后每个奇数位置再减1。这可能更适合您的索引操作:
x=rand(7,1);
m=numel(x);
pattern=[1:m]*2-(mod([1:m],2)==0)-1;
y(pattern)=x;
返回:
y =
0.9572 0.4854 0 0 0.8003 0.1419 0 0 0.4218 0.9157 0 0 0.7922
您可以查看
[1 2 5 6 9 10 13 14 17 18 ....]
总和如下:
[0 1 0 1 0 1 0 1 ...] + [1 1 5 5 9 9 13 13 ...]
= [0 1 0 1 0 1 0 1 ...] + [0 0 4 4 8 8 12 12 ...] + [1 1 1 1 1 1 1 1 ...]
= [0 1 0 1 0 1 0 1 ...] + 4*[0 0 1 1 2 2 3 3 ...] + [1 1 1 1 1 1 1 1 ...]
这些块中的每一个都应该更容易创建:
[0 1 0 1 0 1 0 1 ...] = mod(0:1:9, 2)
[0 0 1 1 2 2 3 3 ...] = floor(0.5 * (0:1:9))
[1 1 1 1 1 1 1 1 ...] = ones(1, 10)
把它放在一起:
>> mod(0:1:9, 2) + 4*floor(0.5*(0:1:9)) + ones(1,10)
ans =
1 2 5 6 9 10 13 14 17 18
但是转到问题的第二部分,如果您的目标是在每两个元素之后插入两个零,则有一种更简单的方法来解决它。首先将长数组重塑为 2×(n/2) 矩阵:
>> y = reshape(x, 2, 6)
y =
-0.41416 -3.39666 0.83481 -0.75471 -0.60284 -1.10128
0.37756 -0.42352 -0.66782 0.54008 -1.43141 -0.18244
现在插入两行零:
>> z = [y; zeros(2, 6)]
z
-0.41416 -3.39666 0.83481 -0.75471 -0.60284 -1.10128
0.37756 -0.42352 -0.66782 0.54008 -1.43141 -0.18244
0.00000 0.00000 0.00000 0.00000 0.00000 0.00000
0.00000 0.00000 0.00000 0.00000 0.00000 0.00000
然后将其重塑为一维数组:
>> w = reshape(z, 1, 24)
w =
Columns 1 through 7:
-0.41416 0.37756 0.00000 0.00000 -3.39666 -0.42352 0.00000
Columns 8 through 14:
0.00000 0.83481 -0.66782 0.00000 0.00000 -0.75471 0.54008
Columns 15 through 21:
0.00000 0.00000 -0.60284 -1.43141 0.00000 0.00000 -1.10128
Columns 22 through 24:
-0.18244 0.00000 0.00000