符号向量上的迭代计数器(MATLAB)

符号向量上的迭代计数器(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];

假设我的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]; %// 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
    感到太兴奋了,但我没有看到这一要求谢谢大家的帮助!