符号向量上的迭代计数器(MATLAB)
假设我的alpha-beta是'0','E'(E可以等于一个数字,即:E=0.5)和'1',我希望计数器如下所示:符号向量上的迭代计数器(MATLAB),matlab,Matlab,假设我的alpha-beta是'0','E'(E可以等于一个数字,即:E=0.5)和'1',我希望计数器如下所示: [ 0 0 0 ] [ 0 0 E ] [ 0 0 1 ] [ 0 E 0 ] [ 0 E E ] [ 0 E 1 ] [ 0 1 0 ] [ 0 1 E ] [ 0 1 1 ] [ E 0 0 ] [ E 0 E ] [ E 0 1 ] [ E E 0 ] ... n = 3; %// number of digits. Arbitrary vals = [0 .5 1];
[ 0 0 0 ]
[ 0 0 E ]
[ 0 0 1 ]
[ 0 E 0 ]
[ 0 E E ]
[ 0 E 1 ]
[ 0 1 0 ]
[ 0 1 E ]
[ 0 1 1 ]
[ E 0 0 ]
[ E 0 E ]
[ E 0 1 ]
[ E E 0 ]
...
n = 3; %// number of digits. Arbitrary
vals = [0 .5 1]; %// digits values. Arbitrary values and size
counter = cell(1,n); %// initiallize to appropriate size
[counter{:}] = ndgrid(vals); %// generate digits
counter = fliplr(counter); %// least-significant to the left
counter = cellfun(@(v) v(:), counter, 'uni', 0); %// convert arrays to vectors
counter = [counter{:}]; %// convert list of vectors to matrix
。。。依此类推,直到我们得到[1](在这个例子中是3^3个组合)。
开始时,我尝试了
combvec()
函数,但如果需要长度为16个符号的向量,它应该为3^16个组合分配3^16的矩阵。。所以我的内存不足
错误。这就是为什么我需要一个计数器,这样每次我都可以计算下一个向量并使用它,而无需像在combvec()
中那样一次获取所有组合。有什么想法吗?这些只是用数字0
、E
和1
写成的三元数。看看Matlab函数dec2base
,它将十进制数转换为表示其他基数中相同数字的字符串。Matlab还提供了反向函数base2dec
您需要对结果进行一些字符串转换,以将
1
更改为E
,并将2
更改为1
,但我将把这留给您。您想要做的事情与在基数3中计算数字非常相似,但您使用的是符号(0,E,1),而不是数字0,1,2。要以任意基数计数,可以将数字存储为其数字数组。计数意味着重复添加1,因此让我们实现一些小学风格的add_one
功能,在该功能中,您一次添加一列数字,并在溢出时继续将结转带到左边的列:
function num = add_one(num, base)
% num is an array with numbers 0..base-1, representing the digits of a number
i = length(num); % start in right column
while i > 0
num(i) = num(i) + 1; % add one
if num(i) == base % overflow?
num(i) = 0; % set digit to zero and add one to the column on the left
i = i - 1;
else
break % we are done
end
end
快速测试:
>> num = [0, 0, 0];
>> for i=1:10
disp(num)
num = add_one(num, 3);
end
结果:
0 0 0
0 0 1
0 0 2
0 1 0
0 1 1
0 1 2
0 2 0
0 2 1
0 2 2
1 0 0
0 0 0
0 0 E
0 0 1
0 E 0
0 E E
0 E 1
0 1 0
0 1 E
0 1 1
E 0 0
E 0 E
E 0 1
E E 0
...
1 E 1
1 1 0
1 1 E
1 1 1
就像在基数3中计数一样
现在,我们所要做的就是将这些数字转换为符号,这可以通过简单的查找来完成(请注意,matlab的数组使用基于1的索引,因此我们必须添加1):
结果:
0 0 0
0 0 1
0 0 2
0 1 0
0 1 1
0 1 2
0 2 0
0 2 1
0 2 2
1 0 0
0 0 0
0 0 E
0 0 1
0 E 0
0 E E
0 E 1
0 1 0
0 1 E
0 1 1
E 0 0
E 0 E
E 0 1
E E 0
...
1 E 1
1 1 0
1 1 E
1 1 1
您可以轻松地完成这项工作,并且具有很强的通用性:
- 使用(从单元格数组生成的)作为
的输出,可以任意设置位数ndgrid
- 数字值的数量是任意的
[ 0 0 0 ]
[ 0 0 E ]
[ 0 0 1 ]
[ 0 E 0 ]
[ 0 E E ]
[ 0 E 1 ]
[ 0 1 0 ]
[ 0 1 E ]
[ 0 1 1 ]
[ E 0 0 ]
[ E 0 E ]
[ E 0 1 ]
[ E E 0 ]
...
n = 3; %// number of digits. Arbitrary
vals = [0 .5 1]; %// digits values. Arbitrary values and size
counter = cell(1,n); %// initiallize to appropriate size
[counter{:}] = ndgrid(vals); %// generate digits
counter = fliplr(counter); %// least-significant to the left
counter = cellfun(@(v) v(:), counter, 'uni', 0); %// convert arrays to vectors
counter = [counter{:}]; %// convert list of vectors to matrix
示例:
n=3
,vals=[0.51]
:
0 0 0
0 0 0.5000
0 0 1.0000
0 0.5000 0
0 0.5000 0.5000
0 0.5000 1.0000
0 1.0000 0
0 1.0000 0.5000
0 1.0000 1.0000
0.5000 0 0
[...]
0 0
0 0.2500
0 0.7500
0 1.0000
0.2500 0
0.2500 0.2500
[...]
n=2
,vals=[0.25.75 1]
:
0 0 0
0 0 0.5000
0 0 1.0000
0 0.5000 0
0 0.5000 0.5000
0 0.5000 1.0000
0 1.0000 0
0 1.0000 0.5000
0 1.0000 1.0000
0.5000 0 0
[...]
0 0
0 0.2500
0 0.7500
0 1.0000
0.2500 0
0.2500 0.2500
[...]
使用
ndgrid
,您将生成大小为3^N
的N
矩阵,当N=16
时,这将消耗太多内存。问题是如何以增量方式生成序列(但很明显,这将花费永远的时间…@BasSwinckels你是对的。。。我对使用带有任意大小逗号分隔列表的ndgrid
感到太兴奋了,但我没有看到这一要求谢谢大家的帮助!